]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/scsi/libiscsi.c
tty_io: drag screaming into coding style compliance
[linux-2.6-omap-h63xx.git] / drivers / scsi / libiscsi.c
index 4461317e617f098ab476af65f84583fb4e21de8f..59f8445eab0daa7a5b138c278897da53aa4ca351 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/types.h>
 #include <linux/kfifo.h>
 #include <linux/delay.h>
+#include <linux/log2.h>
 #include <asm/unaligned.h>
 #include <net/tcp.h>
 #include <scsi/scsi_cmnd.h>
@@ -156,20 +157,19 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask)
        rc = iscsi_add_hdr(ctask, sizeof(*hdr));
        if (rc)
                return rc;
-        hdr->opcode = ISCSI_OP_SCSI_CMD;
-        hdr->flags = ISCSI_ATTR_SIMPLE;
-        int_to_scsilun(sc->device->lun, (struct scsi_lun *)hdr->lun);
-        hdr->itt = build_itt(ctask->itt, conn->id, session->age);
-        hdr->data_length = cpu_to_be32(scsi_bufflen(sc));
-        hdr->cmdsn = cpu_to_be32(session->cmdsn);
-        session->cmdsn++;
-        hdr->exp_statsn = cpu_to_be32(conn->exp_statsn);
-        memcpy(hdr->cdb, sc->cmnd, sc->cmd_len);
+       hdr->opcode = ISCSI_OP_SCSI_CMD;
+       hdr->flags = ISCSI_ATTR_SIMPLE;
+       int_to_scsilun(sc->device->lun, (struct scsi_lun *)hdr->lun);
+       hdr->itt = build_itt(ctask->itt, session->age);
+       hdr->data_length = cpu_to_be32(scsi_bufflen(sc));
+       hdr->cmdsn = cpu_to_be32(session->cmdsn);
+       session->cmdsn++;
+       hdr->exp_statsn = cpu_to_be32(conn->exp_statsn);
+       memcpy(hdr->cdb, sc->cmnd, sc->cmd_len);
        if (sc->cmd_len < MAX_COMMAND_SIZE)
                memset(&hdr->cdb[sc->cmd_len], 0,
                        MAX_COMMAND_SIZE - sc->cmd_len);
 
-       ctask->data_count = 0;
        ctask->imm_count = 0;
        if (sc->sc_data_direction == DMA_TO_DEVICE) {
                hdr->flags |= ISCSI_FLAG_CMD_WRITE;
@@ -198,9 +198,9 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask)
                        else
                                ctask->imm_count = min(scsi_bufflen(sc),
                                                        conn->max_xmit_dlength);
-                       hton24(ctask->hdr->dlength, ctask->imm_count);
+                       hton24(hdr->dlength, ctask->imm_count);
                } else
-                       zero_data(ctask->hdr->dlength);
+                       zero_data(hdr->dlength);
 
                if (!session->initial_r2t_en) {
                        ctask->unsol_count = min((session->first_burst),
@@ -210,7 +210,7 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask)
 
                if (!ctask->unsol_count)
                        /* No unsolicit Data-Out's */
-                       ctask->hdr->flags |= ISCSI_FLAG_CMD_FINAL;
+                       hdr->flags |= ISCSI_FLAG_CMD_FINAL;
        } else {
                hdr->flags |= ISCSI_FLAG_CMD_FINAL;
                zero_data(hdr->dlength);
@@ -228,13 +228,15 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask)
        WARN_ON(hdrlength >= 256);
        hdr->hlength = hdrlength & 0xFF;
 
-       conn->scsicmd_pdus_cnt++;
+       if (conn->session->tt->init_cmd_task(conn->ctask))
+               return EIO;
 
-        debug_scsi("iscsi prep [%s cid %d sc %p cdb 0x%x itt 0x%x len %d "
+       conn->scsicmd_pdus_cnt++;
+       debug_scsi("iscsi prep [%s cid %d sc %p cdb 0x%x itt 0x%x len %d "
                "cmdsn %d win %d]\n",
-                sc->sc_data_direction == DMA_TO_DEVICE ? "write" : "read",
+               sc->sc_data_direction == DMA_TO_DEVICE ? "write" : "read",
                conn->id, sc, sc->cmnd[0], ctask->itt, scsi_bufflen(sc),
-                session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1);
+               session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1);
        return 0;
 }
 
@@ -414,8 +416,9 @@ static void iscsi_scsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
 
                if (datalen < 2) {
 invalid_datalen:
-                       printk(KERN_ERR "iscsi: Got CHECK_CONDITION but "
-                              "invalid data buffer size of %d\n", datalen);
+                       iscsi_conn_printk(KERN_ERR,  conn,
+                                        "Got CHECK_CONDITION but invalid data "
+                                        "buffer size of %d\n", datalen);
                        sc->result = DID_BAD_TARGET << 16;
                        goto out;
                }
@@ -492,7 +495,7 @@ static void iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr)
 
        mtask = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)&hdr, NULL, 0);
        if (!mtask) {
-               printk(KERN_ERR "Could not send nopout\n");
+               iscsi_conn_printk(KERN_ERR, conn, "Could not send nopout\n");
                return;
        }
 
@@ -520,9 +523,10 @@ static int iscsi_handle_reject(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
                if (ntoh24(reject->dlength) >= sizeof(struct iscsi_hdr)) {
                        memcpy(&rejected_pdu, data, sizeof(struct iscsi_hdr));
                        itt = get_itt(rejected_pdu.itt);
-                       printk(KERN_ERR "itt 0x%x had pdu (op 0x%x) rejected "
-                               "due to DataDigest error.\n", itt,
-                               rejected_pdu.opcode);
+                       iscsi_conn_printk(KERN_ERR, conn,
+                                         "itt 0x%x had pdu (op 0x%x) rejected "
+                                         "due to DataDigest error.\n", itt,
+                                         rejected_pdu.opcode);
                }
        }
        return 0;
@@ -539,8 +543,8 @@ static int iscsi_handle_reject(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
  * queuecommand or send generic. session lock must be held and verify
  * itt must have been called.
  */
-int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
-                        char *data, int datalen)
+static int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
+                               char *data, int datalen)
 {
        struct iscsi_session *session = conn->session;
        int opcode = hdr->opcode & ISCSI_OPCODE_MASK, rc = 0;
@@ -670,7 +674,6 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
 
        return rc;
 }
-EXPORT_SYMBOL_GPL(__iscsi_complete_pdu);
 
 int iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
                       char *data, int datalen)
@@ -695,18 +698,13 @@ int iscsi_verify_itt(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
        if (hdr->itt != RESERVED_ITT) {
                if (((__force u32)hdr->itt & ISCSI_AGE_MASK) !=
                    (session->age << ISCSI_AGE_SHIFT)) {
-                       printk(KERN_ERR "iscsi: received itt %x expected "
-                               "session age (%x)\n", (__force u32)hdr->itt,
-                               session->age & ISCSI_AGE_MASK);
+                       iscsi_conn_printk(KERN_ERR, conn,
+                                         "received itt %x expected session "
+                                         "age (%x)\n", (__force u32)hdr->itt,
+                                         session->age & ISCSI_AGE_MASK);
                        return ISCSI_ERR_BAD_ITT;
                }
 
-               if (((__force u32)hdr->itt & ISCSI_CID_MASK) !=
-                   (conn->id << ISCSI_CID_SHIFT)) {
-                       printk(KERN_ERR "iscsi: received itt %x, expected "
-                               "CID (%x)\n", (__force u32)hdr->itt, conn->id);
-                       return ISCSI_ERR_BAD_ITT;
-               }
                itt = get_itt(hdr->itt);
        } else
                itt = ~0U;
@@ -715,16 +713,17 @@ int iscsi_verify_itt(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
                ctask = session->cmds[itt];
 
                if (!ctask->sc) {
-                       printk(KERN_INFO "iscsi: dropping ctask with "
-                              "itt 0x%x\n", ctask->itt);
+                       iscsi_conn_printk(KERN_INFO, conn, "dropping ctask "
+                                         "with itt 0x%x\n", ctask->itt);
                        /* force drop */
                        return ISCSI_ERR_NO_SCSI_CMD;
                }
 
                if (ctask->sc->SCp.phase != session->age) {
-                       printk(KERN_ERR "iscsi: ctask's session age %d, "
-                               "expected %d\n", ctask->sc->SCp.phase,
-                               session->age);
+                       iscsi_conn_printk(KERN_ERR, conn,
+                                         "iscsi: ctask's session age %d, "
+                                         "expected %d\n", ctask->sc->SCp.phase,
+                                         session->age);
                        return ISCSI_ERR_SESSION_FAILED;
                }
        }
@@ -769,7 +768,7 @@ static void iscsi_prep_mtask(struct iscsi_conn *conn,
         */
        nop->cmdsn = cpu_to_be32(session->cmdsn);
        if (hdr->itt != RESERVED_ITT) {
-               hdr->itt = build_itt(mtask->itt, conn->id, session->age);
+               hdr->itt = build_itt(mtask->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
@@ -927,7 +926,7 @@ check_mgmt:
                        fail_command(conn, conn->ctask, DID_ABORT << 16);
                        continue;
                }
-               conn->session->tt->init_cmd_task(conn->ctask);
+
                conn->ctask->state = ISCSI_TASK_RUNNING;
                list_move_tail(conn->xmitqueue.next, &conn->run_list);
                rc = iscsi_xmit_ctask(conn);
@@ -995,6 +994,7 @@ enum {
        FAILURE_SESSION_IN_RECOVERY,
        FAILURE_SESSION_RECOVERY_TIMEOUT,
        FAILURE_SESSION_LOGGING_OUT,
+       FAILURE_SESSION_NOT_READY,
 };
 
 int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
@@ -1010,10 +1010,17 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
        sc->SCp.ptr = NULL;
 
        host = sc->device->host;
-       session = iscsi_hostdata(host->hostdata);
+       spin_unlock(host->host_lock);
 
+       session = iscsi_hostdata(host->hostdata);
        spin_lock(&session->lock);
 
+       reason = iscsi_session_chkready(session_to_cls(session));
+       if (reason) {
+               sc->result = reason;
+               goto fault;
+       }
+
        /*
         * ISCSI_STATE_FAILED is a temp. state. The recovery
         * code will decide what is best to do with command queued
@@ -1030,18 +1037,23 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
                switch (session->state) {
                case ISCSI_STATE_IN_RECOVERY:
                        reason = FAILURE_SESSION_IN_RECOVERY;
-                       goto reject;
+                       sc->result = DID_IMM_RETRY << 16;
+                       break;
                case ISCSI_STATE_LOGGING_OUT:
                        reason = FAILURE_SESSION_LOGGING_OUT;
-                       goto reject;
+                       sc->result = DID_IMM_RETRY << 16;
+                       break;
                case ISCSI_STATE_RECOVERY_FAILED:
                        reason = FAILURE_SESSION_RECOVERY_TIMEOUT;
+                       sc->result = DID_NO_CONNECT << 16;
                        break;
                case ISCSI_STATE_TERMINATE:
                        reason = FAILURE_SESSION_TERMINATE;
+                       sc->result = DID_NO_CONNECT << 16;
                        break;
                default:
                        reason = FAILURE_SESSION_FREED;
+                       sc->result = DID_NO_CONNECT << 16;
                }
                goto fault;
        }
@@ -1049,6 +1061,7 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
        conn = session->leadconn;
        if (!conn) {
                reason = FAILURE_SESSION_FREED;
+               sc->result = DID_NO_CONNECT << 16;
                goto fault;
        }
 
@@ -1077,20 +1090,21 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
        spin_unlock(&session->lock);
 
        scsi_queue_work(host, &conn->xmitwork);
+       spin_lock(host->host_lock);
        return 0;
 
 reject:
        spin_unlock(&session->lock);
        debug_scsi("cmd 0x%x rejected (%d)\n", sc->cmnd[0], reason);
+       spin_lock(host->host_lock);
        return SCSI_MLQUEUE_HOST_BUSY;
 
 fault:
        spin_unlock(&session->lock);
-       printk(KERN_ERR "iscsi: cmd 0x%x is not queued (%d)\n",
-              sc->cmnd[0], reason);
-       sc->result = (DID_NO_CONNECT << 16);
+       debug_scsi("iscsi: cmd 0x%x is not queued (%d)\n", sc->cmnd[0], reason);
        scsi_set_resid(sc, scsi_bufflen(sc));
        sc->scsi_done(sc);
+       spin_lock(host->host_lock);
        return 0;
 }
 EXPORT_SYMBOL_GPL(iscsi_queuecommand);
@@ -1154,7 +1168,8 @@ failed:
        mutex_lock(&session->eh_mutex);
        spin_lock_bh(&session->lock);
        if (session->state == ISCSI_STATE_LOGGED_IN)
-               printk(KERN_INFO "iscsi: host reset succeeded\n");
+               iscsi_session_printk(KERN_INFO, session,
+                                    "host reset succeeded\n");
        else
                goto failed;
        spin_unlock_bh(&session->lock);
@@ -1233,7 +1248,8 @@ static int iscsi_exec_task_mgmt_fn(struct iscsi_conn *conn,
  * Fail commands. session lock held and recv side suspended and xmit
  * thread flushed
  */
-static void fail_all_commands(struct iscsi_conn *conn, unsigned lun)
+static void fail_all_commands(struct iscsi_conn *conn, unsigned lun,
+                             int error)
 {
        struct iscsi_cmd_task *ctask, *tmp;
 
@@ -1245,7 +1261,7 @@ static void fail_all_commands(struct iscsi_conn *conn, unsigned lun)
                if (lun == ctask->sc->device->lun || lun == -1) {
                        debug_scsi("failing pending sc %p itt 0x%x\n",
                                   ctask->sc, ctask->itt);
-                       fail_command(conn, ctask, DID_BUS_BUSY << 16);
+                       fail_command(conn, ctask, error << 16);
                }
        }
 
@@ -1253,7 +1269,7 @@ static void fail_all_commands(struct iscsi_conn *conn, unsigned lun)
                if (lun == ctask->sc->device->lun || lun == -1) {
                        debug_scsi("failing requeued sc %p itt 0x%x\n",
                                   ctask->sc, ctask->itt);
-                       fail_command(conn, ctask, DID_BUS_BUSY << 16);
+                       fail_command(conn, ctask, error << 16);
                }
        }
 
@@ -1351,10 +1367,10 @@ static void iscsi_check_transport_timeouts(unsigned long data)
        last_recv = conn->last_recv;
        if (time_before_eq(last_recv + timeout + (conn->ping_timeout * HZ),
                           jiffies)) {
-               printk(KERN_ERR "ping timeout of %d secs expired, "
-                      "last rx %lu, last ping %lu, now %lu\n",
-                      conn->ping_timeout, last_recv,
-                      conn->last_ping, jiffies);
+               iscsi_conn_printk(KERN_ERR, conn, "ping timeout of %d secs "
+                                 "expired, last rx %lu, last ping %lu, "
+                                 "now %lu\n", conn->ping_timeout, last_recv,
+                                 conn->last_ping, jiffies);
                spin_unlock(&session->lock);
                iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
                return;
@@ -1367,14 +1383,11 @@ static void iscsi_check_transport_timeouts(unsigned long data)
                        iscsi_send_nopout(conn, NULL);
                }
                next_timeout = last_recv + timeout + (conn->ping_timeout * HZ);
-       } else {
+       } else
                next_timeout = last_recv + timeout;
-       }
 
-       if (next_timeout) {
-               debug_scsi("Setting next tmo %lu\n", next_timeout);
-               mod_timer(&conn->transport_timer, next_timeout);
-       }
+       debug_scsi("Setting next tmo %lu\n", next_timeout);
+       mod_timer(&conn->transport_timer, next_timeout);
 done:
        spin_unlock(&session->lock);
 }
@@ -1567,7 +1580,7 @@ int iscsi_eh_device_reset(struct scsi_cmnd *sc)
        /* need to grab the recv lock then session lock */
        write_lock_bh(conn->recv_lock);
        spin_lock(&session->lock);
-       fail_all_commands(conn, sc->device->lun);
+       fail_all_commands(conn, sc->device->lun, DID_ERROR);
        conn->tmf_state = TMF_INITIAL;
        spin_unlock(&session->lock);
        write_unlock_bh(conn->recv_lock);
@@ -1695,7 +1708,7 @@ iscsi_session_setup(struct iscsi_transport *iscsit,
                qdepth = ISCSI_DEF_CMD_PER_LUN;
        }
 
-       if (cmds_max < 2 || (cmds_max & (cmds_max - 1)) ||
+       if (!is_power_of_2(cmds_max) ||
            cmds_max >= ISCSI_MGMT_ITT_OFFSET) {
                if (cmds_max != 0)
                        printk(KERN_ERR "iscsi: invalid can_queue of %d. "
@@ -1727,6 +1740,8 @@ iscsi_session_setup(struct iscsi_transport *iscsit,
        session->host = shost;
        session->state = ISCSI_STATE_FREE;
        session->fast_abort = 1;
+       session->lu_reset_timeout = 15;
+       session->abort_timeout = 10;
        session->mgmtpool_max = ISCSI_MGMT_CMDS_MAX;
        session->cmds_max = cmds_max;
        session->queued_cmdsn = session->cmdsn = initial_cmdsn;
@@ -1936,9 +1951,10 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
                }
                spin_unlock_irqrestore(session->host->host_lock, flags);
                msleep_interruptible(500);
-               printk(KERN_INFO "iscsi: scsi conn_destroy(): host_busy %d "
-                      "host_failed %d\n", session->host->host_busy,
-                      session->host->host_failed);
+               iscsi_conn_printk(KERN_INFO, conn, "iscsi conn_destroy(): "
+                                 "host_busy %d host_failed %d\n",
+                                 session->host->host_busy,
+                                 session->host->host_failed);
                /*
                 * force eh_abort() to unblock
                 */
@@ -1967,27 +1983,28 @@ int iscsi_conn_start(struct iscsi_cls_conn *cls_conn)
        struct iscsi_session *session = conn->session;
 
        if (!session) {
-               printk(KERN_ERR "iscsi: can't start unbound connection\n");
+               iscsi_conn_printk(KERN_ERR, conn,
+                                 "can't start unbound connection\n");
                return -EPERM;
        }
 
        if ((session->imm_data_en || !session->initial_r2t_en) &&
             session->first_burst > session->max_burst) {
-               printk("iscsi: invalid burst lengths: "
-                      "first_burst %d max_burst %d\n",
-                      session->first_burst, session->max_burst);
+               iscsi_conn_printk(KERN_INFO, conn, "invalid burst lengths: "
+                                 "first_burst %d max_burst %d\n",
+                                 session->first_burst, session->max_burst);
                return -EINVAL;
        }
 
        if (conn->ping_timeout && !conn->recv_timeout) {
-               printk(KERN_ERR "iscsi: invalid recv timeout of zero "
-                     "Using 5 seconds\n.");
+               iscsi_conn_printk(KERN_ERR, conn, "invalid recv timeout of "
+                                 "zero. Using 5 seconds\n.");
                conn->recv_timeout = 5;
        }
 
        if (conn->recv_timeout && !conn->ping_timeout) {
-               printk(KERN_ERR "iscsi: invalid ping timeout of zero "
-                     "Using 5 seconds.\n");
+               iscsi_conn_printk(KERN_ERR, conn, "invalid ping timeout of "
+                                 "zero. Using 5 seconds.\n");
                conn->ping_timeout = 5;
        }
 
@@ -2011,11 +2028,9 @@ int iscsi_conn_start(struct iscsi_cls_conn *cls_conn)
                conn->stop_stage = 0;
                conn->tmf_state = TMF_INITIAL;
                session->age++;
-               spin_unlock_bh(&session->lock);
-
-               iscsi_unblock_session(session_to_cls(session));
-               wake_up(&conn->ehwait);
-               return 0;
+               if (session->age == 16)
+                       session->age = 0;
+               break;
        case STOP_CONN_TERM:
                conn->stop_stage = 0;
                break;
@@ -2024,6 +2039,8 @@ int iscsi_conn_start(struct iscsi_cls_conn *cls_conn)
        }
        spin_unlock_bh(&session->lock);
 
+       iscsi_unblock_session(session_to_cls(session));
+       wake_up(&conn->ehwait);
        return 0;
 }
 EXPORT_SYMBOL_GPL(iscsi_conn_start);
@@ -2115,7 +2132,8 @@ static void iscsi_start_session_recovery(struct iscsi_session *session,
         * flush queues.
         */
        spin_lock_bh(&session->lock);
-       fail_all_commands(conn, -1);
+       fail_all_commands(conn, -1,
+                       STOP_CONN_RECOVER ? DID_BUS_BUSY : DID_ERROR);
        flush_control_queues(session, conn);
        spin_unlock_bh(&session->lock);
        mutex_unlock(&session->eh_mutex);
@@ -2132,7 +2150,8 @@ void iscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
                iscsi_start_session_recovery(session, conn, flag);
                break;
        default:
-               printk(KERN_ERR "iscsi: invalid stop flag %d\n", flag);
+               iscsi_conn_printk(KERN_ERR, conn,
+                                 "invalid stop flag %d\n", flag);
        }
 }
 EXPORT_SYMBOL_GPL(iscsi_conn_stop);