]> err.no Git - linux-2.6/blobdiff - drivers/scsi/iscsi_tcp.c
[SCSI] qla2xxx: Update firmware-dump procedure for ISP24xx.
[linux-2.6] / drivers / scsi / iscsi_tcp.c
index 0acc4b235d9b8b1c7d6d270e223a59f31ce2a9a2..1b495afe6d1735fb67f9f87769ecc96212acd46a 100644 (file)
@@ -109,7 +109,7 @@ iscsi_buf_init_sg(struct iscsi_buf *ibuf, struct scatterlist *sg)
        /*
         * Fastpath: sg element fits into single page
         */
-       if (sg->length + sg->offset <= PAGE_SIZE && page_count(sg->page) >= 2)
+       if (sg->length + sg->offset <= PAGE_SIZE && !PageSlab(sg->page))
                ibuf->use_sendmsg = 0;
        else
                ibuf->use_sendmsg = 1;
@@ -525,7 +525,7 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
        __kfifo_put(ctask->r2tqueue, (void*)&r2t, sizeof(void*));
        __kfifo_put(conn->writequeue, (void*)&ctask, sizeof(void*));
 
-       schedule_work(&conn->xmitwork);
+       scsi_queue_work(session->host, &conn->xmitwork);
        conn->r2t_pdus_cnt++;
        spin_unlock(&session->lock);
 
@@ -1267,7 +1267,7 @@ iscsi_write_space(struct sock *sk)
        conn->old_write_space(sk);
        debug_tcp("iscsi_write_space: cid %d\n", conn->id);
        clear_bit(SUSPEND_BIT, &conn->suspend_tx);
-       schedule_work(&conn->xmitwork);
+       scsi_queue_work(conn->session->host, &conn->xmitwork);
 }
 
 static void
@@ -2275,7 +2275,7 @@ iscsi_xmitworker(void *data)
         */
        mutex_lock(&conn->xmitmutex);
        if (iscsi_data_xmit(conn))
-               schedule_work(&conn->xmitwork);
+               scsi_queue_work(conn->session->host, &conn->xmitwork);
        mutex_unlock(&conn->xmitmutex);
 }
 
@@ -2340,15 +2340,7 @@ iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
                session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1);
        spin_unlock(&session->lock);
 
-        if (!in_interrupt() && mutex_trylock(&conn->xmitmutex)) {
-               spin_unlock_irq(host->host_lock);
-               if (iscsi_data_xmit(conn))
-                       schedule_work(&conn->xmitwork);
-               mutex_unlock(&conn->xmitmutex);
-               spin_lock_irq(host->host_lock);
-       } else
-               schedule_work(&conn->xmitwork);
-
+       scsi_queue_work(host, &conn->xmitwork);
        return 0;
 
 reject:
@@ -2435,17 +2427,20 @@ iscsi_pool_free(struct iscsi_queue *q, void **items)
        kfree(items);
 }
 
-static iscsi_connh_t
-iscsi_conn_create(iscsi_sessionh_t sessionh, uint32_t conn_idx)
+static struct iscsi_cls_conn *
+iscsi_conn_create(struct Scsi_Host *shost, uint32_t conn_idx)
 {
-       struct iscsi_session *session = iscsi_ptr(sessionh);
-       struct iscsi_conn *conn = NULL;
+       struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
+       struct iscsi_conn *conn;
+       struct iscsi_cls_conn *cls_conn;
 
-       conn = kmalloc(sizeof(struct iscsi_conn), GFP_KERNEL);
-       if (conn == NULL)
-               goto conn_alloc_fail;
-       memset(conn, 0, sizeof(struct iscsi_conn));
+       cls_conn = iscsi_create_conn(hostdata_session(shost->hostdata),
+                                    conn_idx);
+       if (!cls_conn)
+               return NULL;
+       conn = cls_conn->dd_data;
 
+       memset(conn, 0, sizeof(struct iscsi_conn));
        conn->c_stage = ISCSI_CONN_INITIAL_STAGE;
        conn->in_progress = IN_PROGRESS_WAIT_HEADER;
        conn->id = conn_idx;
@@ -2507,7 +2502,7 @@ iscsi_conn_create(iscsi_sessionh_t sessionh, uint32_t conn_idx)
        mutex_init(&conn->xmitmutex);
        init_waitqueue_head(&conn->ehwait);
 
-       return iscsi_handle(conn);
+       return cls_conn;
 
 max_recv_dlenght_alloc_fail:
        spin_lock_bh(&session->lock);
@@ -2523,15 +2518,14 @@ immqueue_alloc_fail:
 writequeue_alloc_fail:
        kfifo_free(conn->xmitqueue);
 xmitqueue_alloc_fail:
-       kfree(conn);
-conn_alloc_fail:
-       return iscsi_handle(NULL);
+       iscsi_destroy_conn(cls_conn);
+       return NULL;
 }
 
 static void
-iscsi_conn_destroy(iscsi_connh_t connh)
+iscsi_conn_destroy(struct iscsi_cls_conn *cls_conn)
 {
-       struct iscsi_conn *conn = iscsi_ptr(connh);
+       struct iscsi_conn *conn = cls_conn->dd_data;
        struct iscsi_session *session = conn->session;
        unsigned long flags;
 
@@ -2626,7 +2620,8 @@ iscsi_conn_destroy(iscsi_connh_t connh)
        kfifo_free(conn->writequeue);
        kfifo_free(conn->immqueue);
        kfifo_free(conn->mgmtqueue);
-       kfree(conn);
+
+       iscsi_destroy_conn(cls_conn);
 }
 
 static int
@@ -2939,8 +2934,7 @@ iscsi_conn_send_generic(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
        else
                __kfifo_put(conn->mgmtqueue, (void*)&mtask, sizeof(void*));
 
-       schedule_work(&conn->xmitwork);
-
+       scsi_queue_work(session->host, &conn->xmitwork);
        return 0;
 }
 
@@ -3257,17 +3251,23 @@ static struct scsi_host_template iscsi_sht = {
        .this_id                = -1,
 };
 
-static iscsi_sessionh_t
-iscsi_session_create(uint32_t initial_cmdsn, struct Scsi_Host *host)
+static struct iscsi_transport iscsi_tcp_transport;
+
+static struct Scsi_Host *
+iscsi_session_create(struct scsi_transport_template *scsit,
+                    uint32_t initial_cmdsn)
 {
-       int cmd_i;
+       struct Scsi_Host *shost;
        struct iscsi_session *session;
+       int cmd_i;
 
-       session = iscsi_hostdata(host->hostdata);
-       memset(session, 0, sizeof(struct iscsi_session));
+       shost = iscsi_transport_create_session(scsit, &iscsi_tcp_transport);
+       if (!shost)
+               return NULL; 
 
-       session->host = host;
-       session->id = host->host_no;
+       session = iscsi_hostdata(shost->hostdata);
+       memset(session, 0, sizeof(struct iscsi_session));
+       session->host = shost;
        session->state = ISCSI_STATE_LOGGED_IN;
        session->mgmtpool_max = ISCSI_MGMT_CMDS_MAX;
        session->cmds_max = ISCSI_XMIT_CMDS_MAX;
@@ -3311,7 +3311,7 @@ iscsi_session_create(uint32_t initial_cmdsn, struct Scsi_Host *host)
        if (iscsi_r2tpool_alloc(session))
                goto r2tpool_alloc_fail;
 
-       return iscsi_handle(session);
+       return shost;
 
 r2tpool_alloc_fail:
        for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++)
@@ -3321,15 +3321,15 @@ immdata_alloc_fail:
 mgmtpool_alloc_fail:
        iscsi_pool_free(&session->cmdpool, (void**)session->cmds);
 cmdpool_alloc_fail:
-       return iscsi_handle(NULL);
+       return NULL;
 }
 
 static void
-iscsi_session_destroy(iscsi_sessionh_t sessionh)
+iscsi_session_destroy(struct Scsi_Host *shost)
 {
+       struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
        int cmd_i;
        struct iscsi_data_task *dtask, *n;
-       struct iscsi_session *session = iscsi_ptr(sessionh);
 
        for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) {
                struct iscsi_cmd_task *ctask = session->cmds[cmd_i];
@@ -3345,6 +3345,8 @@ iscsi_session_destroy(iscsi_sessionh_t sessionh)
        iscsi_r2tpool_free(session);
        iscsi_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds);
        iscsi_pool_free(&session->cmdpool, (void**)session->cmds);
+
+       iscsi_transport_destroy_session(shost);
 }
 
 static int
@@ -3493,25 +3495,12 @@ iscsi_conn_set_param(iscsi_connh_t connh, enum iscsi_param param,
 }
 
 static int
-iscsi_conn_get_param(iscsi_connh_t connh, enum iscsi_param param,
-                    uint32_t *value)
+iscsi_session_get_param(struct Scsi_Host *shost,
+                       enum iscsi_param param, uint32_t *value)
 {
-       struct iscsi_conn *conn = iscsi_ptr(connh);
-       struct iscsi_session *session = conn->session;
+       struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
 
        switch(param) {
-       case ISCSI_PARAM_MAX_RECV_DLENGTH:
-               *value = conn->max_recv_dlength;
-               break;
-       case ISCSI_PARAM_MAX_XMIT_DLENGTH:
-               *value = conn->max_xmit_dlength;
-               break;
-       case ISCSI_PARAM_HDRDGST_EN:
-               *value = conn->hdrdgst_en;
-               break;
-       case ISCSI_PARAM_DATADGST_EN:
-               *value = conn->datadgst_en;
-               break;
        case ISCSI_PARAM_INITIAL_R2T_EN:
                *value = session->initial_r2t_en;
                break;
@@ -3549,6 +3538,31 @@ iscsi_conn_get_param(iscsi_connh_t connh, enum iscsi_param param,
        return 0;
 }
 
+static int
+iscsi_conn_get_param(void *data, enum iscsi_param param, uint32_t *value)
+{
+       struct iscsi_conn *conn = data;
+
+       switch(param) {
+       case ISCSI_PARAM_MAX_RECV_DLENGTH:
+               *value = conn->max_recv_dlength;
+               break;
+       case ISCSI_PARAM_MAX_XMIT_DLENGTH:
+               *value = conn->max_xmit_dlength;
+               break;
+       case ISCSI_PARAM_HDRDGST_EN:
+               *value = conn->hdrdgst_en;
+               break;
+       case ISCSI_PARAM_DATADGST_EN:
+               *value = conn->datadgst_en;
+               break;
+       default:
+               return ISCSI_ERR_PARAM_NOT_FOUND;
+       }
+
+       return 0;
+}
+
 static void
 iscsi_conn_get_stats(iscsi_connh_t connh, struct iscsi_stats *stats)
 {
@@ -3593,6 +3607,7 @@ static struct iscsi_transport iscsi_tcp_transport = {
                                  | CAP_DATADGST,
        .host_template          = &iscsi_sht,
        .hostdata_size          = sizeof(struct iscsi_session),
+       .conndata_size          = sizeof(struct iscsi_conn),
        .max_conn               = 1,
        .max_cmd_len            = ISCSI_TCP_MAX_CMD_LEN,
        .create_session         = iscsi_session_create,
@@ -3601,7 +3616,8 @@ static struct iscsi_transport iscsi_tcp_transport = {
        .bind_conn              = iscsi_conn_bind,
        .destroy_conn           = iscsi_conn_destroy,
        .set_param              = iscsi_conn_set_param,
-       .get_param              = iscsi_conn_get_param,
+       .get_conn_param         = iscsi_conn_get_param,
+       .get_session_param      = iscsi_session_get_param,
        .start_conn             = iscsi_conn_start,
        .stop_conn              = iscsi_conn_stop,
        .send_pdu               = iscsi_conn_send_pdu,
@@ -3611,8 +3627,6 @@ static struct iscsi_transport iscsi_tcp_transport = {
 static int __init
 iscsi_tcp_init(void)
 {
-       int error;
-
        if (iscsi_max_lun < 1) {
                printk(KERN_ERR "Invalid max_lun value of %u\n", iscsi_max_lun);
                return -EINVAL;
@@ -3625,11 +3639,10 @@ iscsi_tcp_init(void)
        if (!taskcache)
                return -ENOMEM;
 
-       error = iscsi_register_transport(&iscsi_tcp_transport);
-       if (error)
+       if (!iscsi_register_transport(&iscsi_tcp_transport))
                kmem_cache_destroy(taskcache);
 
-       return error;
+       return 0;
 }
 
 static void __exit