[SCSI] iscsi: data under/over flow fix
[cascardo/linux.git] / drivers / scsi / iscsi_tcp.c
index 10bcf42..550ff66 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/delay.h>
 #include <linux/kfifo.h>
 #include <linux/scatterlist.h>
+#include <linux/mutex.h>
 #include <net/tcp.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
@@ -356,7 +357,7 @@ iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
                struct scsi_cmnd *sc = ctask->sc;
 
                conn->exp_statsn = be32_to_cpu(rhdr->statsn) + 1;
-               if (rhdr->flags & ISCSI_FLAG_CMD_UNDERFLOW) {
+               if (rhdr->flags & ISCSI_FLAG_DATA_UNDERFLOW) {
                        int res_count = be32_to_cpu(rhdr->residual_count);
 
                        if (res_count > 0 &&
@@ -366,9 +367,7 @@ iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
                        } else
                                sc->result = (DID_BAD_TARGET << 16) |
                                        rhdr->cmd_status;
-               } else if (rhdr->flags & ISCSI_FLAG_CMD_BIDI_UNDERFLOW)
-                       sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status;
-               else if (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW) {
+               } else if (rhdr->flags & ISCSI_FLAG_DATA_OVERFLOW) {
                        sc->resid = be32_to_cpu(rhdr->residual_count);
                        sc->result = (DID_OK << 16) | rhdr->cmd_status;
                } else
@@ -686,7 +685,7 @@ iscsi_hdr_recv(struct iscsi_conn *conn)
                switch(conn->in.opcode) {
                case ISCSI_OP_LOGIN_RSP:
                case ISCSI_OP_TEXT_RSP:
-               case ISCSI_OP_LOGOUT_RSP: 
+               case ISCSI_OP_LOGOUT_RSP:
                        rc = iscsi_check_assign_cmdsn(session,
                                                 (struct iscsi_nopin*)hdr);
                        if (rc)
@@ -727,12 +726,12 @@ iscsi_hdr_recv(struct iscsi_conn *conn)
                        }
                        spin_unlock(&session->lock);
                        break;
-               case ISCSI_OP_NOOP_IN: 
+               case ISCSI_OP_NOOP_IN:
                        if (hdr->ttt != ISCSI_RESERVED_TAG) {
                                rc = ISCSI_ERR_PROTO;
                                break;
                        }
-                       rc = iscsi_check_assign_cmdsn(session, 
+                       rc = iscsi_check_assign_cmdsn(session,
                                                (struct iscsi_nopin*)hdr);
                        if (rc)
                                break;
@@ -767,7 +766,7 @@ iscsi_hdr_recv(struct iscsi_conn *conn)
                                if (!rc && hdr->ttt != ISCSI_RESERVED_TAG)
                                        rc = iscsi_recv_pdu(iscsi_handle(conn),
                                                            hdr, NULL, 0);
-                       } else 
+                       } else
                                rc = ISCSI_ERR_PROTO;
                        break;
                case ISCSI_OP_REJECT:
@@ -929,7 +928,7 @@ static int iscsi_scsi_data_in(struct iscsi_conn *conn)
                                      sc->request_bufflen, ctask->data_offset);
                if (rc == -EAGAIN)
                        return rc;
-               if (conn->datadgst_en) 
+               if (conn->datadgst_en)
                        iscsi_recv_digest_update(conn, sc->request_buffer, i);
                rc = 0;
                goto done;
@@ -1024,7 +1023,7 @@ iscsi_data_recv(struct iscsi_conn *conn)
                conn->in.hdr = &conn->hdr;
                conn->senselen = (conn->data[0] << 8) | conn->data[1];
                rc = iscsi_cmd_rsp(conn, conn->in.ctask);
-               if (!rc && conn->datadgst_en) 
+               if (!rc && conn->datadgst_en)
                        iscsi_recv_digest_update(conn, conn->data,
                                                 conn->in.datalen);
        }
@@ -1051,7 +1050,7 @@ iscsi_data_recv(struct iscsi_conn *conn)
                rc = iscsi_recv_pdu(iscsi_handle(conn), conn->in.hdr,
                                    conn->data, conn->in.datalen);
 
-               if (!rc && conn->datadgst_en && 
+               if (!rc && conn->datadgst_en &&
                        conn->in.opcode != ISCSI_OP_LOGIN_RSP)
                        iscsi_recv_digest_update(conn, conn->data,
                                                conn->in.datalen);
@@ -1680,7 +1679,7 @@ iscsi_cmd_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
                zero_data(ctask->hdr.dlength);
        }
 
-       iscsi_buf_init_virt(&ctask->headbuf, (char*)&ctask->hdr, 
+       iscsi_buf_init_virt(&ctask->headbuf, (char*)&ctask->hdr,
                            sizeof(struct iscsi_hdr));
        conn->scsicmd_pdus_cnt++;
 }
@@ -1746,7 +1745,7 @@ static inline int
 handle_xmstate_r_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
 {
        ctask->xmstate &= ~XMSTATE_R_HDR;
-       if (conn->hdrdgst_en) 
+       if (conn->hdrdgst_en)
                iscsi_hdr_digest(conn, &ctask->headbuf, (u8*)ctask->hdrext);
        if (!iscsi_sendhdr(conn, &ctask->headbuf, 0)) {
                BUG_ON(ctask->xmstate != XMSTATE_IDLE);
@@ -1760,7 +1759,7 @@ static inline int
 handle_xmstate_w_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
 {
        ctask->xmstate &= ~XMSTATE_W_HDR;
-       if (conn->hdrdgst_en) 
+       if (conn->hdrdgst_en)
                iscsi_hdr_digest(conn, &ctask->headbuf, (u8*)ctask->hdrext);
        if (iscsi_sendhdr(conn, &ctask->headbuf, ctask->imm_count)) {
                ctask->xmstate |= XMSTATE_W_HDR;
@@ -2148,7 +2147,7 @@ unsolicit_head_again:
 solicit_head_again:
                r2t = ctask->r2t;
                if (conn->hdrdgst_en)
-                       iscsi_hdr_digest(conn, &r2t->headbuf, 
+                       iscsi_hdr_digest(conn, &r2t->headbuf,
                                        (u8*)r2t->dtask->hdrext);
                if (iscsi_sendhdr(conn, &r2t->headbuf, r2t->data_count)) {
                        ctask->xmstate &= ~XMSTATE_SOL_DATA;
@@ -2300,10 +2299,10 @@ iscsi_xmitworker(void *data)
        /*
         * serialize Xmit worker on a per-connection basis.
         */
-       down(&conn->xmitsema);
+       mutex_lock(&conn->xmitmutex);
        if (iscsi_data_xmit(conn))
                schedule_work(&conn->xmitwork);
-       up(&conn->xmitsema);
+       mutex_unlock(&conn->xmitmutex);
 }
 
 #define FAILURE_BAD_HOST               1
@@ -2367,11 +2366,11 @@ 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() && !down_trylock(&conn->xmitsema)) {
+        if (!in_interrupt() && mutex_trylock(&conn->xmitmutex)) {
                spin_unlock_irq(host->host_lock);
                if (iscsi_data_xmit(conn))
                        schedule_work(&conn->xmitwork);
-               up(&conn->xmitsema);
+               mutex_unlock(&conn->xmitmutex);
                spin_lock_irq(host->host_lock);
        } else
                schedule_work(&conn->xmitwork);
@@ -2531,7 +2530,7 @@ iscsi_conn_create(iscsi_sessionh_t sessionh, uint32_t conn_idx)
                goto max_recv_dlenght_alloc_fail;
 
        init_timer(&conn->tmabort_timer);
-       init_MUTEX(&conn->xmitsema);
+       mutex_init(&conn->xmitmutex);
        init_waitqueue_head(&conn->ehwait);
 
        return iscsi_handle(conn);
@@ -2561,7 +2560,7 @@ iscsi_conn_destroy(iscsi_connh_t connh)
        struct iscsi_conn *conn = iscsi_ptr(connh);
        struct iscsi_session *session = conn->session;
 
-       down(&conn->xmitsema);
+       mutex_lock(&conn->xmitmutex);
        set_bit(SUSPEND_BIT, &conn->suspend_tx);
        if (conn->c_stage == ISCSI_CONN_INITIAL_STAGE && conn->sock) {
                struct sock *sk = conn->sock->sk;
@@ -2592,7 +2591,7 @@ iscsi_conn_destroy(iscsi_connh_t connh)
        }
        spin_unlock_bh(&session->lock);
 
-       up(&conn->xmitsema);
+       mutex_unlock(&conn->xmitmutex);
 
        /*
         * Block until all in-progress commands for this connection
@@ -2796,7 +2795,7 @@ iscsi_conn_stop(iscsi_connh_t connh, int flag)
        set_bit(SUSPEND_BIT, &conn->suspend_rx);
        write_unlock_bh(&sk->sk_callback_lock);
 
-       down(&conn->xmitsema);
+       mutex_lock(&conn->xmitmutex);
 
        spin_lock_irqsave(session->host->host_lock, flags);
        spin_lock(&session->lock);
@@ -2878,7 +2877,7 @@ iscsi_conn_stop(iscsi_connh_t connh, int flag)
                        conn->datadgst_en = 0;
                }
        }
-       up(&conn->xmitsema);
+       mutex_unlock(&conn->xmitmutex);
 }
 
 static int
@@ -3029,12 +3028,12 @@ iscsi_eh_abort(struct scsi_cmnd *sc)
         * 1) connection-level failure;
         * 2) recovery due protocol error;
         */
-       down(&conn->xmitsema);
+       mutex_lock(&conn->xmitmutex);
        spin_lock_bh(&session->lock);
        if (session->state != ISCSI_STATE_LOGGED_IN) {
                if (session->state == ISCSI_STATE_TERMINATE) {
                        spin_unlock_bh(&session->lock);
-                       up(&conn->xmitsema);
+                       mutex_unlock(&conn->xmitmutex);
                        goto failed;
                }
                spin_unlock_bh(&session->lock);
@@ -3052,7 +3051,7 @@ iscsi_eh_abort(struct scsi_cmnd *sc)
                         * 2) session was re-open during time out of ctask.
                         */
                        spin_unlock_bh(&session->lock);
-                       up(&conn->xmitsema);
+                       mutex_unlock(&conn->xmitmutex);
                        goto success;
                }
                conn->tmabort_state = TMABORT_INITIAL;
@@ -3107,7 +3106,7 @@ iscsi_eh_abort(struct scsi_cmnd *sc)
                                    conn->tmabort_state == TMABORT_SUCCESS) {
                                        conn->tmabort_state = TMABORT_INITIAL;
                                        spin_unlock_bh(&session->lock);
-                                       up(&conn->xmitsema);
+                                       mutex_unlock(&conn->xmitmutex);
                                        goto success;
                                }
                                conn->tmabort_state = TMABORT_INITIAL;
@@ -3116,7 +3115,7 @@ iscsi_eh_abort(struct scsi_cmnd *sc)
                        spin_unlock_bh(&session->lock);
                }
        }
-       up(&conn->xmitsema);
+       mutex_unlock(&conn->xmitmutex);
 
 
        /*
@@ -3182,7 +3181,7 @@ failed:
 exit:
        del_timer_sync(&conn->tmabort_timer);
 
-       down(&conn->xmitsema);
+       mutex_lock(&conn->xmitmutex);
        if (conn->sock) {
                struct sock *sk = conn->sock->sk;
 
@@ -3190,7 +3189,7 @@ exit:
                iscsi_ctask_cleanup(conn, ctask);
                write_unlock_bh(&sk->sk_callback_lock);
        }
-       up(&conn->xmitsema);
+       mutex_unlock(&conn->xmitmutex);
        return rc;
 }
 
@@ -3601,9 +3600,9 @@ iscsi_conn_send_pdu(iscsi_connh_t connh, struct iscsi_hdr *hdr, char *data,
        struct iscsi_conn *conn = iscsi_ptr(connh);
        int rc;
 
-       down(&conn->xmitsema);
+       mutex_lock(&conn->xmitmutex);
        rc = iscsi_conn_send_generic(conn, hdr, data, data_size);
-       up(&conn->xmitsema);
+       mutex_unlock(&conn->xmitmutex);
 
        return rc;
 }