aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2008-05-21 16:54:07 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-07-12 09:22:19 -0400
commitfbc514b4e262bc0596faae8640ebc0b9142a1cdd (patch)
tree74910fb5c2b2475742d13f4ac44e5eddf7aad81a
parent3e5c28ad0391389959ccae81c938c7533efb3490 (diff)
[SCSI] iscsi_tcp: convert iscsi_tcp to support merged tasks
Convert iscsi_tcp to support merged tasks. Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r--drivers/scsi/iscsi_tcp.c130
-rw-r--r--drivers/scsi/iscsi_tcp.h5
2 files changed, 54 insertions, 81 deletions
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index f2a08f7ed902..517bad160bea 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -498,11 +498,15 @@ iscsi_tcp_data_recv_prep(struct iscsi_tcp_conn *tcp_conn)
498 * must be called with session lock 498 * must be called with session lock
499 */ 499 */
500static void 500static void
501iscsi_tcp_cleanup_ctask(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) 501iscsi_tcp_cleanup_task(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
502{ 502{
503 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; 503 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
504 struct iscsi_r2t_info *r2t; 504 struct iscsi_r2t_info *r2t;
505 505
506 /* nothing to do for mgmt ctasks */
507 if (!ctask->sc)
508 return;
509
506 /* flush ctask's r2t queues */ 510 /* flush ctask's r2t queues */
507 while (__kfifo_get(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*))) { 511 while (__kfifo_get(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*))) {
508 __kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t, 512 __kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t,
@@ -521,7 +525,7 @@ iscsi_tcp_cleanup_ctask(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
521/** 525/**
522 * iscsi_data_rsp - SCSI Data-In Response processing 526 * iscsi_data_rsp - SCSI Data-In Response processing
523 * @conn: iscsi connection 527 * @conn: iscsi connection
524 * @ctask: scsi command task 528 * @ctask: scsi command ctask
525 **/ 529 **/
526static int 530static int
527iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) 531iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
@@ -578,7 +582,7 @@ iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
578/** 582/**
579 * iscsi_solicit_data_init - initialize first Data-Out 583 * iscsi_solicit_data_init - initialize first Data-Out
580 * @conn: iscsi connection 584 * @conn: iscsi connection
581 * @ctask: scsi command task 585 * @ctask: scsi command ctask
582 * @r2t: R2T info 586 * @r2t: R2T info
583 * 587 *
584 * Notes: 588 * Notes:
@@ -620,7 +624,7 @@ iscsi_solicit_data_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
620/** 624/**
621 * iscsi_r2t_rsp - iSCSI R2T Response processing 625 * iscsi_r2t_rsp - iSCSI R2T Response processing
622 * @conn: iscsi connection 626 * @conn: iscsi connection
623 * @ctask: scsi command task 627 * @ctask: scsi command ctask
624 **/ 628 **/
625static int 629static int
626iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) 630iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
@@ -646,7 +650,7 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
646 return ISCSI_ERR_R2TSN; 650 return ISCSI_ERR_R2TSN;
647 } 651 }
648 652
649 /* fill-in new R2T associated with the task */ 653 /* fill-in new R2T associated with the ctask */
650 iscsi_update_cmdsn(session, (struct iscsi_nopin*)rhdr); 654 iscsi_update_cmdsn(session, (struct iscsi_nopin*)rhdr);
651 655
652 if (!ctask->sc || session->state != ISCSI_STATE_LOGGED_IN) { 656 if (!ctask->sc || session->state != ISCSI_STATE_LOGGED_IN) {
@@ -769,6 +773,8 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
769 ctask = iscsi_itt_to_ctask(conn, hdr->itt); 773 ctask = iscsi_itt_to_ctask(conn, hdr->itt);
770 if (!ctask) 774 if (!ctask)
771 return ISCSI_ERR_BAD_ITT; 775 return ISCSI_ERR_BAD_ITT;
776 if (!ctask->sc)
777 return ISCSI_ERR_NO_SCSI_CMD;
772 778
773 spin_lock(&conn->session->lock); 779 spin_lock(&conn->session->lock);
774 rc = iscsi_data_rsp(conn, ctask); 780 rc = iscsi_data_rsp(conn, ctask);
@@ -815,6 +821,8 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
815 ctask = iscsi_itt_to_ctask(conn, hdr->itt); 821 ctask = iscsi_itt_to_ctask(conn, hdr->itt);
816 if (!ctask) 822 if (!ctask)
817 return ISCSI_ERR_BAD_ITT; 823 return ISCSI_ERR_BAD_ITT;
824 if (!ctask->sc)
825 return ISCSI_ERR_NO_SCSI_CMD;
818 826
819 if (ahslen) 827 if (ahslen)
820 rc = ISCSI_ERR_AHSLEN; 828 rc = ISCSI_ERR_AHSLEN;
@@ -1194,7 +1202,7 @@ iscsi_tcp_send_hdr_prep(struct iscsi_conn *conn, void *hdr, size_t hdrlen)
1194 1202
1195 /* If header digest is enabled, compute the CRC and 1203 /* If header digest is enabled, compute the CRC and
1196 * place the digest into the same buffer. We make 1204 * place the digest into the same buffer. We make
1197 * sure that both iscsi_tcp_ctask and mtask have 1205 * sure that both iscsi_tcp_cmd_task and mctask have
1198 * sufficient room. 1206 * sufficient room.
1199 */ 1207 */
1200 if (conn->hdrdgst_en) { 1208 if (conn->hdrdgst_en) {
@@ -1269,7 +1277,7 @@ iscsi_tcp_send_linear_data_prepare(struct iscsi_conn *conn, void *data,
1269/** 1277/**
1270 * iscsi_solicit_data_cont - initialize next Data-Out 1278 * iscsi_solicit_data_cont - initialize next Data-Out
1271 * @conn: iscsi connection 1279 * @conn: iscsi connection
1272 * @ctask: scsi command task 1280 * @ctask: scsi command ctask
1273 * @r2t: R2T info 1281 * @r2t: R2T info
1274 * @left: bytes left to transfer 1282 * @left: bytes left to transfer
1275 * 1283 *
@@ -1316,19 +1324,37 @@ iscsi_solicit_data_cont(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
1316} 1324}
1317 1325
1318/** 1326/**
1319 * iscsi_tcp_ctask - Initialize iSCSI SCSI_READ or SCSI_WRITE commands 1327 * iscsi_tcp_task - Initialize iSCSI SCSI_READ or SCSI_WRITE commands
1320 * @conn: iscsi connection 1328 * @conn: iscsi connection
1321 * @ctask: scsi command task 1329 * @ctask: scsi command ctask
1322 * @sc: scsi command 1330 * @sc: scsi command
1323 **/ 1331 **/
1324static int 1332static int
1325iscsi_tcp_ctask_init(struct iscsi_cmd_task *ctask) 1333iscsi_tcp_task_init(struct iscsi_cmd_task *ctask)
1326{ 1334{
1327 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; 1335 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
1328 struct iscsi_conn *conn = ctask->conn; 1336 struct iscsi_conn *conn = ctask->conn;
1329 struct scsi_cmnd *sc = ctask->sc; 1337 struct scsi_cmnd *sc = ctask->sc;
1330 int err; 1338 int err;
1331 1339
1340 if (!sc) {
1341 /*
1342 * mgmt ctasks do not have a scatterlist since they come
1343 * in from the iscsi interface.
1344 */
1345 debug_scsi("mctask deq [cid %d itt 0x%x]\n", conn->id,
1346 ctask->itt);
1347
1348 /* Prepare PDU, optionally w/ immediate data */
1349 iscsi_tcp_send_hdr_prep(conn, ctask->hdr, sizeof(*ctask->hdr));
1350
1351 /* If we have immediate data, attach a payload */
1352 if (ctask->data_count)
1353 iscsi_tcp_send_linear_data_prepare(conn, ctask->data,
1354 ctask->data_count);
1355 return 0;
1356 }
1357
1332 BUG_ON(__kfifo_len(tcp_ctask->r2tqueue)); 1358 BUG_ON(__kfifo_len(tcp_ctask->r2tqueue));
1333 tcp_ctask->sent = 0; 1359 tcp_ctask->sent = 0;
1334 tcp_ctask->exp_datasn = 0; 1360 tcp_ctask->exp_datasn = 0;
@@ -1353,52 +1379,21 @@ iscsi_tcp_ctask_init(struct iscsi_cmd_task *ctask)
1353 return 0; 1379 return 0;
1354} 1380}
1355 1381
1356/**
1357 * iscsi_tcp_mtask_xmit - xmit management(immediate) task
1358 * @conn: iscsi connection
1359 * @mtask: task management task
1360 *
1361 * Notes:
1362 * The function can return -EAGAIN in which case caller must
1363 * call it again later, or recover. '0' return code means successful
1364 * xmit.
1365 **/
1366static int
1367iscsi_tcp_mtask_xmit(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask)
1368{
1369 int rc;
1370
1371 /* Flush any pending data first. */
1372 rc = iscsi_tcp_flush(conn);
1373 if (rc < 0)
1374 return rc;
1375
1376 if (mtask->hdr->itt == RESERVED_ITT) {
1377 struct iscsi_session *session = conn->session;
1378
1379 spin_lock_bh(&session->lock);
1380 iscsi_free_mgmt_task(conn, mtask);
1381 spin_unlock_bh(&session->lock);
1382 }
1383
1384 return 0;
1385}
1386
1387/* 1382/*
1388 * iscsi_tcp_ctask_xmit - xmit normal PDU task 1383 * iscsi_tcp_task_xmit - xmit normal PDU ctask
1389 * @conn: iscsi connection 1384 * @ctask: iscsi command ctask
1390 * @ctask: iscsi command task
1391 * 1385 *
1392 * We're expected to return 0 when everything was transmitted succesfully, 1386 * We're expected to return 0 when everything was transmitted succesfully,
1393 * -EAGAIN if there's still data in the queue, or != 0 for any other kind 1387 * -EAGAIN if there's still data in the queue, or != 0 for any other kind
1394 * of error. 1388 * of error.
1395 */ 1389 */
1396static int 1390static int
1397iscsi_tcp_ctask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) 1391iscsi_tcp_task_xmit(struct iscsi_cmd_task *ctask)
1398{ 1392{
1393 struct iscsi_conn *conn = ctask->conn;
1399 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; 1394 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
1400 struct scsi_cmnd *sc = ctask->sc; 1395 struct scsi_cmnd *sc = ctask->sc;
1401 struct scsi_data_buffer *sdb = scsi_out(sc); 1396 struct scsi_data_buffer *sdb;
1402 int rc = 0; 1397 int rc = 0;
1403 1398
1404flush: 1399flush:
@@ -1407,10 +1402,18 @@ flush:
1407 if (rc < 0) 1402 if (rc < 0)
1408 return rc; 1403 return rc;
1409 1404
1405 /* mgmt command */
1406 if (!sc) {
1407 if (ctask->hdr->itt == RESERVED_ITT)
1408 iscsi_put_ctask(ctask);
1409 return 0;
1410 }
1411
1410 /* Are we done already? */ 1412 /* Are we done already? */
1411 if (sc->sc_data_direction != DMA_TO_DEVICE) 1413 if (sc->sc_data_direction != DMA_TO_DEVICE)
1412 return 0; 1414 return 0;
1413 1415
1416 sdb = scsi_out(sc);
1414 if (ctask->unsol_count != 0) { 1417 if (ctask->unsol_count != 0) {
1415 struct iscsi_data *hdr = &tcp_ctask->unsol_dtask.hdr; 1418 struct iscsi_data *hdr = &tcp_ctask->unsol_dtask.hdr;
1416 1419
@@ -1688,21 +1691,6 @@ free_socket:
1688 return err; 1691 return err;
1689} 1692}
1690 1693
1691/* called with host lock */
1692static void
1693iscsi_tcp_mtask_init(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask)
1694{
1695 debug_scsi("mtask deq [cid %d itt 0x%x]\n", conn->id, mtask->itt);
1696
1697 /* Prepare PDU, optionally w/ immediate data */
1698 iscsi_tcp_send_hdr_prep(conn, mtask->hdr, sizeof(*mtask->hdr));
1699
1700 /* If we have immediate data, attach a payload */
1701 if (mtask->data_count)
1702 iscsi_tcp_send_linear_data_prepare(conn, mtask->data,
1703 mtask->data_count);
1704}
1705
1706static int 1694static int
1707iscsi_r2tpool_alloc(struct iscsi_session *session) 1695iscsi_r2tpool_alloc(struct iscsi_session *session)
1708{ 1696{
@@ -1710,7 +1698,7 @@ iscsi_r2tpool_alloc(struct iscsi_session *session)
1710 int cmd_i; 1698 int cmd_i;
1711 1699
1712 /* 1700 /*
1713 * initialize per-task: R2T pool and xmit queue 1701 * initialize per-ctask: R2T pool and xmit queue
1714 */ 1702 */
1715 for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) { 1703 for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) {
1716 struct iscsi_cmd_task *ctask = session->cmds[cmd_i]; 1704 struct iscsi_cmd_task *ctask = session->cmds[cmd_i];
@@ -1880,13 +1868,12 @@ iscsi_tcp_session_create(struct Scsi_Host *shost, uint16_t cmds_max,
1880 1868
1881 cls_session = iscsi_session_setup(&iscsi_tcp_transport, shost, cmds_max, 1869 cls_session = iscsi_session_setup(&iscsi_tcp_transport, shost, cmds_max,
1882 sizeof(struct iscsi_tcp_cmd_task), 1870 sizeof(struct iscsi_tcp_cmd_task),
1883 sizeof(struct iscsi_tcp_mgmt_task),
1884 initial_cmdsn); 1871 initial_cmdsn);
1885 if (!cls_session) 1872 if (!cls_session)
1886 goto remove_host; 1873 goto remove_host;
1887 session = cls_session->dd_data; 1874 session = cls_session->dd_data;
1888 1875
1889 shost->can_queue = session->cmds_max; 1876 shost->can_queue = session->scsi_cmds_max;
1890 for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) { 1877 for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) {
1891 struct iscsi_cmd_task *ctask = session->cmds[cmd_i]; 1878 struct iscsi_cmd_task *ctask = session->cmds[cmd_i];
1892 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; 1879 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
@@ -1895,13 +1882,6 @@ iscsi_tcp_session_create(struct Scsi_Host *shost, uint16_t cmds_max,
1895 ctask->hdr_max = sizeof(tcp_ctask->hdr) - ISCSI_DIGEST_SIZE; 1882 ctask->hdr_max = sizeof(tcp_ctask->hdr) - ISCSI_DIGEST_SIZE;
1896 } 1883 }
1897 1884
1898 for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++) {
1899 struct iscsi_mgmt_task *mtask = session->mgmt_cmds[cmd_i];
1900 struct iscsi_tcp_mgmt_task *tcp_mtask = mtask->dd_data;
1901
1902 mtask->hdr = (struct iscsi_hdr *) &tcp_mtask->hdr;
1903 }
1904
1905 if (iscsi_r2tpool_alloc(session)) 1885 if (iscsi_r2tpool_alloc(session))
1906 goto remove_session; 1886 goto remove_session;
1907 return cls_session; 1887 return cls_session;
@@ -1999,11 +1979,9 @@ static struct iscsi_transport iscsi_tcp_transport = {
1999 /* IO */ 1979 /* IO */
2000 .send_pdu = iscsi_conn_send_pdu, 1980 .send_pdu = iscsi_conn_send_pdu,
2001 .get_stats = iscsi_conn_get_stats, 1981 .get_stats = iscsi_conn_get_stats,
2002 .init_cmd_task = iscsi_tcp_ctask_init, 1982 .init_task = iscsi_tcp_task_init,
2003 .init_mgmt_task = iscsi_tcp_mtask_init, 1983 .xmit_task = iscsi_tcp_task_xmit,
2004 .xmit_cmd_task = iscsi_tcp_ctask_xmit, 1984 .cleanup_task = iscsi_tcp_cleanup_task,
2005 .xmit_mgmt_task = iscsi_tcp_mtask_xmit,
2006 .cleanup_cmd_task = iscsi_tcp_cleanup_ctask,
2007 /* recovery */ 1985 /* recovery */
2008 .session_recovery_timedout = iscsi_session_recovery_timedout, 1986 .session_recovery_timedout = iscsi_session_recovery_timedout,
2009}; 1987};
diff --git a/drivers/scsi/iscsi_tcp.h b/drivers/scsi/iscsi_tcp.h
index ed0b991d1e72..c9c8633c41a6 100644
--- a/drivers/scsi/iscsi_tcp.h
+++ b/drivers/scsi/iscsi_tcp.h
@@ -103,11 +103,6 @@ struct iscsi_data_task {
103 char hdrext[ISCSI_DIGEST_SIZE];/* Header-Digest */ 103 char hdrext[ISCSI_DIGEST_SIZE];/* Header-Digest */
104}; 104};
105 105
106struct iscsi_tcp_mgmt_task {
107 struct iscsi_hdr hdr;
108 char hdrext[ISCSI_DIGEST_SIZE]; /* Header-Digest */
109};
110
111struct iscsi_r2t_info { 106struct iscsi_r2t_info {
112 __be32 ttt; /* copied from R2T */ 107 __be32 ttt; /* copied from R2T */
113 __be32 exp_statsn; /* copied from R2T */ 108 __be32 exp_statsn; /* copied from R2T */