]> err.no Git - linux-2.6/blobdiff - drivers/scsi/iscsi_tcp.c
[Blackfin] arch: Add proper SW System Reset delay sequence
[linux-2.6] / drivers / scsi / iscsi_tcp.c
index 7212fe95a66df2da9cb29bc34149470029e7e54f..e5be5fd4ef583f10ba907721da19249999d609bb 100644 (file)
@@ -641,13 +641,11 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
        }
 
        /* fill-in new R2T associated with the task */
-       spin_lock(&session->lock);
        iscsi_update_cmdsn(session, (struct iscsi_nopin*)rhdr);
 
        if (!ctask->sc || session->state != ISCSI_STATE_LOGGED_IN) {
                printk(KERN_INFO "iscsi_tcp: dropping R2T itt %d in "
                       "recovery...\n", ctask->itt);
-               spin_unlock(&session->lock);
                return 0;
        }
 
@@ -658,7 +656,8 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
        r2t->data_length = be32_to_cpu(rhdr->data_length);
        if (r2t->data_length == 0) {
                printk(KERN_ERR "iscsi_tcp: invalid R2T with zero data len\n");
-               spin_unlock(&session->lock);
+               __kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t,
+                           sizeof(void*));
                return ISCSI_ERR_DATALEN;
        }
 
@@ -669,10 +668,11 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
 
        r2t->data_offset = be32_to_cpu(rhdr->data_offset);
        if (r2t->data_offset + r2t->data_length > scsi_bufflen(ctask->sc)) {
-               spin_unlock(&session->lock);
                printk(KERN_ERR "iscsi_tcp: invalid R2T with data len %u at "
                       "offset %u and total length %d\n", r2t->data_length,
                       r2t->data_offset, scsi_bufflen(ctask->sc));
+               __kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t,
+                           sizeof(void*));
                return ISCSI_ERR_DATALEN;
        }
 
@@ -686,8 +686,6 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
        conn->r2t_pdus_cnt++;
 
        iscsi_requeue_ctask(ctask);
-       spin_unlock(&session->lock);
-
        return 0;
 }
 
@@ -751,11 +749,7 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
        opcode = hdr->opcode & ISCSI_OPCODE_MASK;
        /* verify itt (itt encoding: age+cid+itt) */
        rc = iscsi_verify_itt(conn, hdr, &itt);
-       if (rc == ISCSI_ERR_NO_SCSI_CMD) {
-               /* XXX: what does this do? */
-               tcp_conn->in.datalen = 0; /* force drop */
-               return 0;
-       } else if (rc)
+       if (rc)
                return rc;
 
        debug_tcp("opcode 0x%x ahslen %d datalen %d\n",
@@ -764,7 +758,9 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
        switch(opcode) {
        case ISCSI_OP_SCSI_DATA_IN:
                ctask = session->cmds[itt];
+               spin_lock(&conn->session->lock);
                rc = iscsi_data_rsp(conn, ctask);
+               spin_unlock(&conn->session->lock);
                if (rc)
                        return rc;
                if (tcp_conn->in.datalen) {
@@ -806,9 +802,11 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
                ctask = session->cmds[itt];
                if (ahslen)
                        rc = ISCSI_ERR_AHSLEN;
-               else if (ctask->sc->sc_data_direction == DMA_TO_DEVICE)
+               else if (ctask->sc->sc_data_direction == DMA_TO_DEVICE) {
+                       spin_lock(&session->lock);
                        rc = iscsi_r2t_rsp(conn, ctask);
-               else
+                       spin_unlock(&session->lock);
+               } else
                        rc = ISCSI_ERR_PROTO;
                break;
        case ISCSI_OP_LOGIN_RSP:
@@ -1776,12 +1774,12 @@ iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param,
                break;
        case ISCSI_PARAM_MAX_R2T:
                sscanf(buf, "%d", &value);
-               if (session->max_r2t == roundup_pow_of_two(value))
+               if (value <= 0 || !is_power_of_2(value))
+                       return -EINVAL;
+               if (session->max_r2t == value)
                        break;
                iscsi_r2tpool_free(session);
                iscsi_set_param(cls_conn, param, buf, buflen);
-               if (session->max_r2t & (session->max_r2t - 1))
-                       session->max_r2t = roundup_pow_of_two(session->max_r2t);
                if (iscsi_r2tpool_alloc(session))
                        return -ENOMEM;
                break;
@@ -1928,13 +1926,14 @@ static struct scsi_host_template iscsi_sht = {
        .queuecommand           = iscsi_queuecommand,
        .change_queue_depth     = iscsi_change_queue_depth,
        .can_queue              = ISCSI_DEF_XMIT_CMDS_MAX - 1,
-       .sg_tablesize           = ISCSI_SG_TABLESIZE,
+       .sg_tablesize           = 4096,
        .max_sectors            = 0xFFFF,
        .cmd_per_lun            = ISCSI_DEF_CMD_PER_LUN,
        .eh_abort_handler       = iscsi_eh_abort,
        .eh_device_reset_handler= iscsi_eh_device_reset,
        .eh_host_reset_handler  = iscsi_eh_host_reset,
        .use_clustering         = DISABLE_CLUSTERING,
+       .use_sg_chaining        = ENABLE_SG_CHAINING,
        .slave_configure        = iscsi_tcp_slave_configure,
        .proc_name              = "iscsi_tcp",
        .this_id                = -1,
@@ -1974,7 +1973,7 @@ static struct iscsi_transport iscsi_tcp_transport = {
        .host_template          = &iscsi_sht,
        .conndata_size          = sizeof(struct iscsi_conn),
        .max_conn               = 1,
-       .max_cmd_len            = ISCSI_TCP_MAX_CMD_LEN,
+       .max_cmd_len            = 16,
        /* session management */
        .create_session         = iscsi_tcp_session_create,
        .destroy_session        = iscsi_tcp_session_destroy,