Merge tag 'tags/bcm2835-dt-next-2019-03-04' into devicetree/fixes
[linux-2.6-block.git] / drivers / scsi / libiscsi.c
index 120fc520f27a3b4bc1b9e6bd0642b139ad88b39d..e893949a3d118421481d3fb5de90f170a70440af 100644 (file)
@@ -228,32 +228,6 @@ static int iscsi_prep_ecdb_ahs(struct iscsi_task *task)
        return 0;
 }
 
-static int iscsi_prep_bidi_ahs(struct iscsi_task *task)
-{
-       struct scsi_cmnd *sc = task->sc;
-       struct iscsi_rlength_ahdr *rlen_ahdr;
-       int rc;
-
-       rlen_ahdr = iscsi_next_hdr(task);
-       rc = iscsi_add_hdr(task, sizeof(*rlen_ahdr));
-       if (rc)
-               return rc;
-
-       rlen_ahdr->ahslength =
-               cpu_to_be16(sizeof(rlen_ahdr->read_length) +
-                                                 sizeof(rlen_ahdr->reserved));
-       rlen_ahdr->ahstype = ISCSI_AHSTYPE_RLENGTH;
-       rlen_ahdr->reserved = 0;
-       rlen_ahdr->read_length = cpu_to_be32(scsi_in(sc)->length);
-
-       ISCSI_DBG_SESSION(task->conn->session,
-                         "bidi-in rlen_ahdr->read_length(%d) "
-                         "rlen_ahdr->ahslength(%d)\n",
-                         be32_to_cpu(rlen_ahdr->read_length),
-                         be16_to_cpu(rlen_ahdr->ahslength));
-       return 0;
-}
-
 /**
  * iscsi_check_tmf_restrictions - check if a task is affected by TMF
  * @task: iscsi task
@@ -392,13 +366,6 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task *task)
        memcpy(hdr->cdb, sc->cmnd, cmd_len);
 
        task->imm_count = 0;
-       if (scsi_bidi_cmnd(sc)) {
-               hdr->flags |= ISCSI_FLAG_CMD_READ;
-               rc = iscsi_prep_bidi_ahs(task);
-               if (rc)
-                       return rc;
-       }
-
        if (scsi_get_prot_op(sc) != SCSI_PROT_NORMAL)
                task->protected = true;
 
@@ -473,12 +440,10 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task *task)
 
        conn->scsicmd_pdus_cnt++;
        ISCSI_DBG_SESSION(session, "iscsi prep [%s cid %d sc %p cdb 0x%x "
-                         "itt 0x%x len %d bidi_len %d cmdsn %d win %d]\n",
-                         scsi_bidi_cmnd(sc) ? "bidirectional" :
+                         "itt 0x%x len %d cmdsn %d win %d]\n",
                          sc->sc_data_direction == DMA_TO_DEVICE ?
                          "write" : "read", conn->id, sc, sc->cmnd[0],
                          task->itt, transfer_length,
-                         scsi_bidi_cmnd(sc) ? scsi_in(sc)->length : 0,
                          session->cmdsn,
                          session->max_cmdsn - session->exp_cmdsn + 1);
        return 0;
@@ -647,12 +612,7 @@ static void fail_scsi_task(struct iscsi_task *task, int err)
                state = ISCSI_TASK_ABRT_TMF;
 
        sc->result = err << 16;
-       if (!scsi_bidi_cmnd(sc))
-               scsi_set_resid(sc, scsi_bufflen(sc));
-       else {
-               scsi_out(sc)->resid = scsi_out(sc)->length;
-               scsi_in(sc)->resid = scsi_in(sc)->length;
-       }
+       scsi_set_resid(sc, scsi_bufflen(sc));
 
        /* regular RX path uses back_lock */
        spin_lock_bh(&conn->session->back_lock);
@@ -838,7 +798,7 @@ EXPORT_SYMBOL_GPL(iscsi_conn_send_pdu);
  * @datalen: len of buffer
  *
  * iscsi_cmd_rsp sets up the scsi_cmnd fields based on the PDU and
- * then completes the command and task.
+ * then completes the command and task. called under back_lock
  **/
 static void iscsi_scsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
                               struct iscsi_task *task, char *data,
@@ -907,14 +867,7 @@ invalid_datalen:
 
        if (rhdr->flags & (ISCSI_FLAG_CMD_BIDI_UNDERFLOW |
                           ISCSI_FLAG_CMD_BIDI_OVERFLOW)) {
-               int res_count = be32_to_cpu(rhdr->bi_residual_count);
-
-               if (scsi_bidi_cmnd(sc) && res_count > 0 &&
-                               (rhdr->flags & ISCSI_FLAG_CMD_BIDI_OVERFLOW ||
-                                res_count <= scsi_in(sc)->length))
-                       scsi_in(sc)->resid = res_count;
-               else
-                       sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status;
+               sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status;
        }
 
        if (rhdr->flags & (ISCSI_FLAG_CMD_UNDERFLOW |
@@ -941,6 +894,9 @@ out:
  * @conn: iscsi connection
  * @hdr:  iscsi pdu
  * @task: scsi command task
+ *
+ * iscsi_data_in_rsp sets up the scsi_cmnd fields based on the data received
+ * then completes the command and task. called under back_lock
  **/
 static void
 iscsi_data_in_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
@@ -961,8 +917,8 @@ iscsi_data_in_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
 
                if (res_count > 0 &&
                    (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW ||
-                    res_count <= scsi_in(sc)->length))
-                       scsi_in(sc)->resid = res_count;
+                    res_count <= sc->sdb.length))
+                       scsi_set_resid(sc, res_count);
                else
                        sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status;
        }
@@ -1025,6 +981,16 @@ static int iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr)
        return 0;
 }
 
+/**
+ * iscsi_nop_out_rsp - SCSI NOP Response processing
+ * @task: scsi command task
+ * @nop: the nop structure
+ * @data: where to put the data
+ * @datalen: length of data
+ *
+ * iscsi_nop_out_rsp handles nop response from use or
+ * from user space. called under back_lock
+ **/
 static int iscsi_nop_out_rsp(struct iscsi_task *task,
                             struct iscsi_nopin *nop, char *data, int datalen)
 {
@@ -1797,7 +1763,9 @@ int iscsi_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc)
        return 0;
 
 prepd_reject:
+       spin_lock_bh(&session->back_lock);
        iscsi_complete_task(task, ISCSI_TASK_REQUEUE_SCSIQ);
+       spin_unlock_bh(&session->back_lock);
 reject:
        spin_unlock_bh(&session->frwd_lock);
        ISCSI_DBG_SESSION(session, "cmd 0x%x rejected (%d)\n",
@@ -1805,17 +1773,14 @@ reject:
        return SCSI_MLQUEUE_TARGET_BUSY;
 
 prepd_fault:
+       spin_lock_bh(&session->back_lock);
        iscsi_complete_task(task, ISCSI_TASK_REQUEUE_SCSIQ);
+       spin_unlock_bh(&session->back_lock);
 fault:
        spin_unlock_bh(&session->frwd_lock);
        ISCSI_DBG_SESSION(session, "iscsi: cmd 0x%x is not queued (%d)\n",
                          sc->cmnd[0], reason);
-       if (!scsi_bidi_cmnd(sc))
-               scsi_set_resid(sc, scsi_bufflen(sc));
-       else {
-               scsi_out(sc)->resid = scsi_out(sc)->length;
-               scsi_in(sc)->resid = scsi_in(sc)->length;
-       }
+       scsi_set_resid(sc, scsi_bufflen(sc));
        sc->scsi_done(sc);
        return 0;
 }
@@ -3127,8 +3092,9 @@ fail_mgmt_tasks(struct iscsi_session *session, struct iscsi_conn *conn)
                state = ISCSI_TASK_ABRT_SESS_RECOV;
                if (task->state == ISCSI_TASK_PENDING)
                        state = ISCSI_TASK_COMPLETED;
+               spin_lock_bh(&session->back_lock);
                iscsi_complete_task(task, state);
-
+               spin_unlock_bh(&session->back_lock);
        }
 }