* must be called with session lock
*/
static void
-iscsi_tcp_cleanup_ctask(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
+iscsi_tcp_cleanup_task(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
{
struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
struct iscsi_r2t_info *r2t;
+ /* nothing to do for mgmt ctasks */
+ if (!ctask->sc)
+ return;
+
/* flush ctask's r2t queues */
while (__kfifo_get(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*))) {
__kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t,
/**
* iscsi_data_rsp - SCSI Data-In Response processing
* @conn: iscsi connection
- * @ctask: scsi command task
+ * @ctask: scsi command ctask
**/
static int
iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
/**
* iscsi_solicit_data_init - initialize first Data-Out
* @conn: iscsi connection
- * @ctask: scsi command task
+ * @ctask: scsi command ctask
* @r2t: R2T info
*
* Notes:
/**
* iscsi_r2t_rsp - iSCSI R2T Response processing
* @conn: iscsi connection
- * @ctask: scsi command task
+ * @ctask: scsi command ctask
**/
static int
iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
return ISCSI_ERR_R2TSN;
}
- /* fill-in new R2T associated with the task */
+ /* fill-in new R2T associated with the ctask */
iscsi_update_cmdsn(session, (struct iscsi_nopin*)rhdr);
if (!ctask->sc || session->state != ISCSI_STATE_LOGGED_IN) {
ctask = iscsi_itt_to_ctask(conn, hdr->itt);
if (!ctask)
return ISCSI_ERR_BAD_ITT;
+ if (!ctask->sc)
+ return ISCSI_ERR_NO_SCSI_CMD;
spin_lock(&conn->session->lock);
rc = iscsi_data_rsp(conn, ctask);
ctask = iscsi_itt_to_ctask(conn, hdr->itt);
if (!ctask)
return ISCSI_ERR_BAD_ITT;
+ if (!ctask->sc)
+ return ISCSI_ERR_NO_SCSI_CMD;
if (ahslen)
rc = ISCSI_ERR_AHSLEN;
/* If header digest is enabled, compute the CRC and
* place the digest into the same buffer. We make
- * sure that both iscsi_tcp_ctask and mtask have
+ * sure that both iscsi_tcp_cmd_task and mctask have
* sufficient room.
*/
if (conn->hdrdgst_en) {
/**
* iscsi_solicit_data_cont - initialize next Data-Out
* @conn: iscsi connection
- * @ctask: scsi command task
+ * @ctask: scsi command ctask
* @r2t: R2T info
* @left: bytes left to transfer
*
}
/**
- * iscsi_tcp_ctask - Initialize iSCSI SCSI_READ or SCSI_WRITE commands
+ * iscsi_tcp_task - Initialize iSCSI SCSI_READ or SCSI_WRITE commands
* @conn: iscsi connection
- * @ctask: scsi command task
+ * @ctask: scsi command ctask
* @sc: scsi command
**/
static int
-iscsi_tcp_ctask_init(struct iscsi_cmd_task *ctask)
+iscsi_tcp_task_init(struct iscsi_cmd_task *ctask)
{
struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
struct iscsi_conn *conn = ctask->conn;
struct scsi_cmnd *sc = ctask->sc;
int err;
+ if (!sc) {
+ /*
+ * mgmt ctasks do not have a scatterlist since they come
+ * in from the iscsi interface.
+ */
+ debug_scsi("mctask deq [cid %d itt 0x%x]\n", conn->id,
+ ctask->itt);
+
+ /* Prepare PDU, optionally w/ immediate data */
+ iscsi_tcp_send_hdr_prep(conn, ctask->hdr, sizeof(*ctask->hdr));
+
+ /* If we have immediate data, attach a payload */
+ if (ctask->data_count)
+ iscsi_tcp_send_linear_data_prepare(conn, ctask->data,
+ ctask->data_count);
+ return 0;
+ }
+
BUG_ON(__kfifo_len(tcp_ctask->r2tqueue));
tcp_ctask->sent = 0;
tcp_ctask->exp_datasn = 0;
return 0;
}
-/**
- * iscsi_tcp_mtask_xmit - xmit management(immediate) task
- * @conn: iscsi connection
- * @mtask: task management task
- *
- * Notes:
- * The function can return -EAGAIN in which case caller must
- * call it again later, or recover. '0' return code means successful
- * xmit.
- **/
-static int
-iscsi_tcp_mtask_xmit(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask)
-{
- int rc;
-
- /* Flush any pending data first. */
- rc = iscsi_tcp_flush(conn);
- if (rc < 0)
- return rc;
-
- if (mtask->hdr->itt == RESERVED_ITT) {
- struct iscsi_session *session = conn->session;
-
- spin_lock_bh(&session->lock);
- iscsi_free_mgmt_task(conn, mtask);
- spin_unlock_bh(&session->lock);
- }
-
- return 0;
-}
-
/*
- * iscsi_tcp_ctask_xmit - xmit normal PDU task
- * @conn: iscsi connection
- * @ctask: iscsi command task
+ * iscsi_tcp_task_xmit - xmit normal PDU ctask
+ * @ctask: iscsi command ctask
*
* We're expected to return 0 when everything was transmitted succesfully,
* -EAGAIN if there's still data in the queue, or != 0 for any other kind
* of error.
*/
static int
-iscsi_tcp_ctask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
+iscsi_tcp_task_xmit(struct iscsi_cmd_task *ctask)
{
+ struct iscsi_conn *conn = ctask->conn;
struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
struct scsi_cmnd *sc = ctask->sc;
- struct scsi_data_buffer *sdb = scsi_out(sc);
+ struct scsi_data_buffer *sdb;
int rc = 0;
flush:
if (rc < 0)
return rc;
+ /* mgmt command */
+ if (!sc) {
+ if (ctask->hdr->itt == RESERVED_ITT)
+ iscsi_put_ctask(ctask);
+ return 0;
+ }
+
/* Are we done already? */
if (sc->sc_data_direction != DMA_TO_DEVICE)
return 0;
+ sdb = scsi_out(sc);
if (ctask->unsol_count != 0) {
struct iscsi_data *hdr = &tcp_ctask->unsol_dtask.hdr;
return err;
}
-/* called with host lock */
-static void
-iscsi_tcp_mtask_init(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask)
-{
- debug_scsi("mtask deq [cid %d itt 0x%x]\n", conn->id, mtask->itt);
-
- /* Prepare PDU, optionally w/ immediate data */
- iscsi_tcp_send_hdr_prep(conn, mtask->hdr, sizeof(*mtask->hdr));
-
- /* If we have immediate data, attach a payload */
- if (mtask->data_count)
- iscsi_tcp_send_linear_data_prepare(conn, mtask->data,
- mtask->data_count);
-}
-
static int
iscsi_r2tpool_alloc(struct iscsi_session *session)
{
int cmd_i;
/*
- * initialize per-task: R2T pool and xmit queue
+ * initialize per-ctask: R2T pool and xmit queue
*/
for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) {
struct iscsi_cmd_task *ctask = session->cmds[cmd_i];
cls_session = iscsi_session_setup(&iscsi_tcp_transport, shost, cmds_max,
sizeof(struct iscsi_tcp_cmd_task),
- sizeof(struct iscsi_tcp_mgmt_task),
initial_cmdsn);
if (!cls_session)
goto remove_host;
session = cls_session->dd_data;
- shost->can_queue = session->cmds_max;
+ shost->can_queue = session->scsi_cmds_max;
for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) {
struct iscsi_cmd_task *ctask = session->cmds[cmd_i];
struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
ctask->hdr_max = sizeof(tcp_ctask->hdr) - ISCSI_DIGEST_SIZE;
}
- for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++) {
- struct iscsi_mgmt_task *mtask = session->mgmt_cmds[cmd_i];
- struct iscsi_tcp_mgmt_task *tcp_mtask = mtask->dd_data;
-
- mtask->hdr = (struct iscsi_hdr *) &tcp_mtask->hdr;
- }
-
if (iscsi_r2tpool_alloc(session))
goto remove_session;
return cls_session;
/* IO */
.send_pdu = iscsi_conn_send_pdu,
.get_stats = iscsi_conn_get_stats,
- .init_cmd_task = iscsi_tcp_ctask_init,
- .init_mgmt_task = iscsi_tcp_mtask_init,
- .xmit_cmd_task = iscsi_tcp_ctask_xmit,
- .xmit_mgmt_task = iscsi_tcp_mtask_xmit,
- .cleanup_cmd_task = iscsi_tcp_cleanup_ctask,
+ .init_task = iscsi_tcp_task_init,
+ .xmit_task = iscsi_tcp_task_xmit,
+ .cleanup_task = iscsi_tcp_cleanup_task,
/* recovery */
.session_recovery_timedout = iscsi_session_recovery_timedout,
};