struct scsi_cmnd *sc = task->sc;
struct iscsi_cmd *hdr;
unsigned hdrlength, cmd_len;
+ itt_t itt;
int rc;
- rc = conn->session->tt->alloc_pdu(task);
+ rc = conn->session->tt->alloc_pdu(task, ISCSI_OP_SCSI_CMD);
if (rc)
return rc;
hdr = (struct iscsi_cmd *) task->hdr;
+ itt = hdr->itt;
memset(hdr, 0, sizeof(*hdr));
+ if (session->tt->parse_pdu_itt)
+ hdr->itt = task->hdr_itt = itt;
+ else
+ hdr->itt = task->hdr_itt = build_itt(task->itt,
+ task->conn->session->age);
task->hdr_len = 0;
rc = iscsi_add_hdr(task, sizeof(*hdr));
if (rc)
hdr->flags = ISCSI_ATTR_SIMPLE;
int_to_scsilun(sc->device->lun, (struct scsi_lun *)hdr->lun);
memcpy(task->lun, hdr->lun, sizeof(task->lun));
- hdr->itt = task->hdr_itt = build_itt(task->itt, session->age);
hdr->cmdsn = task->cmdsn = cpu_to_be32(session->cmdsn);
session->cmdsn++;
hdr->exp_statsn = cpu_to_be32(conn->exp_statsn);
*/
nop->cmdsn = cpu_to_be32(session->cmdsn);
if (hdr->itt != RESERVED_ITT) {
- hdr->itt = build_itt(task->itt, session->age);
/*
* TODO: We always use immediate, so we never hit this.
* If we start to send tmfs or nops as non-immediate then
}
}
- if (session->tt->init_task)
- session->tt->init_task(task);
+ if (session->tt->init_task && session->tt->init_task(task))
+ return -EIO;
if ((hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGOUT)
session->state = ISCSI_STATE_LOGGING_OUT;
{
struct iscsi_session *session = conn->session;
struct iscsi_task *task;
+ itt_t itt;
if (session->state == ISCSI_STATE_TERMINATE)
return NULL;
} else
task->data_count = 0;
- if (conn->session->tt->alloc_pdu(task)) {
+ if (conn->session->tt->alloc_pdu(task, hdr->opcode)) {
iscsi_conn_printk(KERN_ERR, conn, "Could not allocate "
"pdu for mgmt task.\n");
goto requeue_task;
}
+ itt = task->hdr->itt;
task->hdr_len = sizeof(struct iscsi_hdr);
-
memcpy(task->hdr, hdr, sizeof(struct iscsi_hdr));
+
+ if (hdr->itt != RESERVED_ITT) {
+ if (session->tt->parse_pdu_itt)
+ task->hdr->itt = itt;
+ else
+ task->hdr->itt = build_itt(task->itt,
+ task->conn->session->age);
+ }
+
INIT_LIST_HEAD(&task->running);
list_add_tail(&task->running, &conn->mgmtqueue);
{
struct iscsi_reject *reject = (struct iscsi_reject *)hdr;
struct iscsi_hdr rejected_pdu;
- uint32_t itt;
conn->exp_statsn = be32_to_cpu(reject->statsn) + 1;
if (ntoh24(reject->dlength) >= sizeof(struct iscsi_hdr)) {
memcpy(&rejected_pdu, data, sizeof(struct iscsi_hdr));
- itt = get_itt(rejected_pdu.itt);
iscsi_conn_printk(KERN_ERR, conn,
- "itt 0x%x had pdu (op 0x%x) rejected "
- "due to DataDigest error.\n", itt,
+ "pdu (op 0x%x) rejected "
+ "due to DataDigest error.\n",
rejected_pdu.opcode);
}
}
static struct iscsi_task *iscsi_itt_to_task(struct iscsi_conn *conn, itt_t itt)
{
struct iscsi_session *session = conn->session;
- uint32_t i;
+ int i;
if (itt == RESERVED_ITT)
return NULL;
- i = get_itt(itt);
+ if (session->tt->parse_pdu_itt)
+ session->tt->parse_pdu_itt(conn, itt, &i, NULL);
+ else
+ i = get_itt(itt);
if (i >= session->cmds_max)
return NULL;
int iscsi_verify_itt(struct iscsi_conn *conn, itt_t itt)
{
struct iscsi_session *session = conn->session;
- uint32_t i;
+ int age = 0, i = 0;
if (itt == RESERVED_ITT)
return 0;
- if (((__force u32)itt & ISCSI_AGE_MASK) !=
- (session->age << ISCSI_AGE_SHIFT)) {
+ if (session->tt->parse_pdu_itt)
+ session->tt->parse_pdu_itt(conn, itt, &i, &age);
+ else {
+ i = get_itt(itt);
+ age = ((__force u32)itt >> ISCSI_AGE_SHIFT) & ISCSI_AGE_MASK;
+ }
+
+ if (age != session->age) {
iscsi_conn_printk(KERN_ERR, conn,
"received itt %x expected session age (%x)\n",
(__force u32)itt, session->age);
return ISCSI_ERR_BAD_ITT;
}
- i = get_itt(itt);
if (i >= session->cmds_max) {
iscsi_conn_printk(KERN_ERR, conn,
"received invalid itt index %u (max cmds "
kfree(q->pool[i]);
if (q->pool)
kfree(q->pool);
+ kfree(q->queue);
}
EXPORT_SYMBOL_GPL(iscsi_pool_free);
if (!shost->can_queue)
shost->can_queue = ISCSI_DEF_XMIT_CMDS_MAX;
+ if (!shost->transportt->eh_timed_out)
+ shost->transportt->eh_timed_out = iscsi_eh_cmd_timed_out;
return scsi_add_host(shost, pdev);
}
EXPORT_SYMBOL_GPL(iscsi_host_add);
shost = scsi_host_alloc(sht, sizeof(struct iscsi_host) + dd_data_size);
if (!shost)
return NULL;
- shost->transportt->eh_timed_out = iscsi_eh_cmd_timed_out;
if (qdepth > ISCSI_MAX_CMD_PER_LUN || qdepth < 1) {
if (qdepth != 0)
}
spin_unlock_bh(&session->lock);
- data = kmalloc(ISCSI_DEF_MAX_RECV_SEG_LEN, GFP_KERNEL);
+ data = (char *) __get_free_pages(GFP_KERNEL,
+ get_order(ISCSI_DEF_MAX_RECV_SEG_LEN));
if (!data)
goto login_task_data_alloc_fail;
conn->login_task->data = conn->data = data;
iscsi_suspend_tx(conn);
spin_lock_bh(&session->lock);
- kfree(conn->data);
+ free_pages((unsigned long) conn->data,
+ get_order(ISCSI_DEF_MAX_RECV_SEG_LEN));
kfree(conn->persistent_address);
__kfifo_put(session->cmdpool.queue, (void*)&conn->login_task,
sizeof(void*));