aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/iscsi_tcp.c
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2008-12-02 01:32:07 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-12-29 12:24:21 -0500
commite5a7efeffdcc3062ade5208d16c278d8d484f82a (patch)
treead9433d07322ddc9b0c8e9c4a988c38e12cf4d8b /drivers/scsi/iscsi_tcp.c
parent0f9c7449ce050759d10424048b96d1bd0d59dcc1 (diff)
[SCSI] iscsi_tcp: convert to new alloc_hdr api
This converts iscsi_tcp to the new api and modifies how it handles r2ts. Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/iscsi_tcp.c')
-rw-r--r--drivers/scsi/iscsi_tcp.c249
1 files changed, 119 insertions, 130 deletions
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 464de780d953..97bad5ce5834 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -57,13 +57,6 @@ MODULE_LICENSE("GPL");
57#define debug_tcp(fmt...) 57#define debug_tcp(fmt...)
58#endif 58#endif
59 59
60#ifndef DEBUG_ASSERT
61#ifdef BUG_ON
62#undef BUG_ON
63#endif
64#define BUG_ON(expr)
65#endif
66
67static struct scsi_transport_template *iscsi_tcp_scsi_transport; 60static struct scsi_transport_template *iscsi_tcp_scsi_transport;
68static struct scsi_host_template iscsi_sht; 61static struct scsi_host_template iscsi_sht;
69static struct iscsi_transport iscsi_tcp_transport; 62static struct iscsi_transport iscsi_tcp_transport;
@@ -498,14 +491,13 @@ iscsi_tcp_data_recv_prep(struct iscsi_tcp_conn *tcp_conn)
498/* 491/*
499 * must be called with session lock 492 * must be called with session lock
500 */ 493 */
501static void 494static void iscsi_tcp_cleanup_task(struct iscsi_task *task)
502iscsi_tcp_cleanup_task(struct iscsi_conn *conn, struct iscsi_task *task)
503{ 495{
504 struct iscsi_tcp_task *tcp_task = task->dd_data; 496 struct iscsi_tcp_task *tcp_task = task->dd_data;
505 struct iscsi_r2t_info *r2t; 497 struct iscsi_r2t_info *r2t;
506 498
507 /* nothing to do for mgmt tasks */ 499 /* nothing to do for mgmt or pending tasks */
508 if (!task->sc) 500 if (!task->sc || task->state == ISCSI_TASK_PENDING)
509 return; 501 return;
510 502
511 /* flush task's r2t queues */ 503 /* flush task's r2t queues */
@@ -611,11 +603,11 @@ iscsi_solicit_data_init(struct iscsi_conn *conn, struct iscsi_task *task,
611static int 603static int
612iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_task *task) 604iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_task *task)
613{ 605{
614 struct iscsi_r2t_info *r2t;
615 struct iscsi_session *session = conn->session; 606 struct iscsi_session *session = conn->session;
616 struct iscsi_tcp_task *tcp_task = task->dd_data; 607 struct iscsi_tcp_task *tcp_task = task->dd_data;
617 struct iscsi_tcp_conn *tcp_conn = conn->dd_data; 608 struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
618 struct iscsi_r2t_rsp *rhdr = (struct iscsi_r2t_rsp *)tcp_conn->in.hdr; 609 struct iscsi_r2t_rsp *rhdr = (struct iscsi_r2t_rsp *)tcp_conn->in.hdr;
610 struct iscsi_r2t_info *r2t;
619 int r2tsn = be32_to_cpu(rhdr->r2tsn); 611 int r2tsn = be32_to_cpu(rhdr->r2tsn);
620 int rc; 612 int rc;
621 613
@@ -643,7 +635,12 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_task *task)
643 } 635 }
644 636
645 rc = __kfifo_get(tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*)); 637 rc = __kfifo_get(tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*));
646 BUG_ON(!rc); 638 if (!rc) {
639 iscsi_conn_printk(KERN_ERR, conn, "Could not allocate R2T. "
640 "Target has sent more R2Ts than it "
641 "negotiated for or driver has has leaked.\n");
642 return ISCSI_ERR_PROTO;
643 }
647 644
648 r2t->exp_statsn = rhdr->statsn; 645 r2t->exp_statsn = rhdr->statsn;
649 r2t->data_length = be32_to_cpu(rhdr->data_length); 646 r2t->data_length = be32_to_cpu(rhdr->data_length);
@@ -672,9 +669,8 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_task *task)
672 } 669 }
673 670
674 r2t->ttt = rhdr->ttt; /* no flip */ 671 r2t->ttt = rhdr->ttt; /* no flip */
675 r2t->solicit_datasn = 0; 672 r2t->datasn = 0;
676 673 r2t->sent = 0;
677 iscsi_solicit_data_init(conn, task, r2t);
678 674
679 tcp_task->exp_datasn = r2tsn + 1; 675 tcp_task->exp_datasn = r2tsn + 1;
680 __kfifo_put(tcp_task->r2tqueue, (void*)&r2t, sizeof(void*)); 676 __kfifo_put(tcp_task->r2tqueue, (void*)&r2t, sizeof(void*));
@@ -1199,9 +1195,9 @@ iscsi_tcp_xmit_qlen(struct iscsi_conn *conn)
1199 return segment->total_copied - segment->total_size; 1195 return segment->total_copied - segment->total_size;
1200} 1196}
1201 1197
1202static inline int 1198static int iscsi_tcp_flush(struct iscsi_task *task)
1203iscsi_tcp_flush(struct iscsi_conn *conn)
1204{ 1199{
1200 struct iscsi_conn *conn = task->conn;
1205 int rc; 1201 int rc;
1206 1202
1207 while (iscsi_tcp_xmit_qlen(conn)) { 1203 while (iscsi_tcp_xmit_qlen(conn)) {
@@ -1364,14 +1360,49 @@ iscsi_solicit_data_cont(struct iscsi_conn *conn, struct iscsi_task *task,
1364 return 1; 1360 return 1;
1365} 1361}
1366 1362
1363static int iscsi_tcp_pdu_init(struct iscsi_task *task,
1364 unsigned int offset, unsigned int count)
1365{
1366 struct iscsi_conn *conn = task->conn;
1367 int err = 0;
1368
1369 iscsi_tcp_send_hdr_prep(conn, task->hdr, task->hdr_len);
1370
1371 if (!count)
1372 return 0;
1373
1374 if (!task->sc)
1375 iscsi_tcp_send_linear_data_prepare(conn, task->data, count);
1376 else {
1377 struct scsi_data_buffer *sdb = scsi_out(task->sc);
1378
1379 err = iscsi_tcp_send_data_prep(conn, sdb->table.sgl,
1380 sdb->table.nents, offset, count);
1381 }
1382
1383 if (err) {
1384 iscsi_conn_failure(conn, err);
1385 return -EIO;
1386 }
1387 return 0;
1388}
1389
1390static int iscsi_tcp_pdu_alloc(struct iscsi_task *task)
1391{
1392 struct iscsi_tcp_task *tcp_task = task->dd_data;
1393
1394 task->hdr = &tcp_task->hdr.hdrbuf;
1395 task->hdr_max = sizeof(tcp_task->hdr) - ISCSI_DIGEST_SIZE;
1396 return 0;
1397}
1398
1367/** 1399/**
1368 * iscsi_tcp_task - Initialize iSCSI SCSI_READ or SCSI_WRITE commands 1400 * iscsi_tcp_task - Initialize iSCSI SCSI_READ or SCSI_WRITE commands
1369 * @conn: iscsi connection 1401 * @conn: iscsi connection
1370 * @task: scsi command task 1402 * @task: scsi command task
1371 * @sc: scsi command 1403 * @sc: scsi command
1372 **/ 1404 **/
1373static int 1405static int iscsi_tcp_task_init(struct iscsi_task *task)
1374iscsi_tcp_task_init(struct iscsi_task *task)
1375{ 1406{
1376 struct iscsi_tcp_task *tcp_task = task->dd_data; 1407 struct iscsi_tcp_task *tcp_task = task->dd_data;
1377 struct iscsi_conn *conn = task->conn; 1408 struct iscsi_conn *conn = task->conn;
@@ -1386,40 +1417,57 @@ iscsi_tcp_task_init(struct iscsi_task *task)
1386 debug_scsi("mtask deq [cid %d itt 0x%x]\n", conn->id, 1417 debug_scsi("mtask deq [cid %d itt 0x%x]\n", conn->id,
1387 task->itt); 1418 task->itt);
1388 1419
1389 /* Prepare PDU, optionally w/ immediate data */ 1420 return conn->session->tt->init_pdu(task, 0, task->data_count);
1390 iscsi_tcp_send_hdr_prep(conn, task->hdr, sizeof(*task->hdr));
1391
1392 /* If we have immediate data, attach a payload */
1393 if (task->data_count)
1394 iscsi_tcp_send_linear_data_prepare(conn, task->data,
1395 task->data_count);
1396 return 0;
1397 } 1421 }
1398 1422
1399 BUG_ON(__kfifo_len(tcp_task->r2tqueue)); 1423 BUG_ON(__kfifo_len(tcp_task->r2tqueue));
1400 tcp_task->sent = 0;
1401 tcp_task->exp_datasn = 0; 1424 tcp_task->exp_datasn = 0;
1402 1425
1403 /* Prepare PDU, optionally w/ immediate data */ 1426 /* Prepare PDU, optionally w/ immediate data */
1404 debug_scsi("task deq [cid %d itt 0x%x imm %d unsol %d]\n", 1427 debug_scsi("task deq [cid %d itt 0x%x imm %d unsol %d]\n",
1405 conn->id, task->itt, task->imm_count, 1428 conn->id, task->itt, task->imm_count,
1406 task->unsol_count); 1429 task->unsol_r2t.data_length);
1407 iscsi_tcp_send_hdr_prep(conn, task->hdr, task->hdr_len);
1408 1430
1409 if (!task->imm_count) 1431 err = conn->session->tt->init_pdu(task, 0, task->imm_count);
1410 return 0;
1411
1412 /* If we have immediate data, attach a payload */
1413 err = iscsi_tcp_send_data_prep(conn, scsi_out(sc)->table.sgl,
1414 scsi_out(sc)->table.nents,
1415 0, task->imm_count);
1416 if (err) 1432 if (err)
1417 return err; 1433 return err;
1418 tcp_task->sent += task->imm_count;
1419 task->imm_count = 0; 1434 task->imm_count = 0;
1420 return 0; 1435 return 0;
1421} 1436}
1422 1437
1438static struct iscsi_r2t_info *iscsi_tcp_get_curr_r2t(struct iscsi_task *task)
1439{
1440 struct iscsi_session *session = task->conn->session;
1441 struct iscsi_tcp_task *tcp_task = task->dd_data;
1442 struct iscsi_r2t_info *r2t = NULL;
1443
1444 if (iscsi_task_has_unsol_data(task))
1445 r2t = &task->unsol_r2t;
1446 else {
1447 spin_lock_bh(&session->lock);
1448 if (tcp_task->r2t) {
1449 r2t = tcp_task->r2t;
1450 /* Continue with this R2T? */
1451 if (r2t->data_length <= r2t->sent) {
1452 debug_scsi(" done with r2t %p\n", r2t);
1453 __kfifo_put(tcp_task->r2tpool.queue,
1454 (void *)&tcp_task->r2t,
1455 sizeof(void *));
1456 tcp_task->r2t = r2t = NULL;
1457 }
1458 }
1459
1460 if (r2t == NULL) {
1461 __kfifo_get(tcp_task->r2tqueue,
1462 (void *)&tcp_task->r2t, sizeof(void *));
1463 r2t = tcp_task->r2t;
1464 }
1465 spin_unlock_bh(&session->lock);
1466 }
1467
1468 return r2t;
1469}
1470
1423/* 1471/*
1424 * iscsi_tcp_task_xmit - xmit normal PDU task 1472 * iscsi_tcp_task_xmit - xmit normal PDU task
1425 * @task: iscsi command task 1473 * @task: iscsi command task
@@ -1428,108 +1476,52 @@ iscsi_tcp_task_init(struct iscsi_task *task)
1428 * -EAGAIN if there's still data in the queue, or != 0 for any other kind 1476 * -EAGAIN if there's still data in the queue, or != 0 for any other kind
1429 * of error. 1477 * of error.
1430 */ 1478 */
1431static int 1479static int iscsi_tcp_task_xmit(struct iscsi_task *task)
1432iscsi_tcp_task_xmit(struct iscsi_task *task)
1433{ 1480{
1434 struct iscsi_conn *conn = task->conn; 1481 struct iscsi_conn *conn = task->conn;
1435 struct iscsi_tcp_task *tcp_task = task->dd_data; 1482 struct iscsi_session *session = conn->session;
1436 struct scsi_cmnd *sc = task->sc; 1483 struct iscsi_r2t_info *r2t;
1437 struct scsi_data_buffer *sdb;
1438 int rc = 0; 1484 int rc = 0;
1439 1485
1440flush: 1486flush:
1441 /* Flush any pending data first. */ 1487 /* Flush any pending data first. */
1442 rc = iscsi_tcp_flush(conn); 1488 rc = session->tt->xmit_pdu(task);
1443 if (rc < 0) 1489 if (rc < 0)
1444 return rc; 1490 return rc;
1445 1491
1446 /* mgmt command */ 1492 /* mgmt command */
1447 if (!sc) { 1493 if (!task->sc) {
1448 if (task->hdr->itt == RESERVED_ITT) 1494 if (task->hdr->itt == RESERVED_ITT)
1449 iscsi_put_task(task); 1495 iscsi_put_task(task);
1450 return 0; 1496 return 0;
1451 } 1497 }
1452 1498
1453 /* Are we done already? */ 1499 /* Are we done already? */
1454 if (sc->sc_data_direction != DMA_TO_DEVICE) 1500 if (task->sc->sc_data_direction != DMA_TO_DEVICE)
1455 return 0; 1501 return 0;
1456 1502
1457 sdb = scsi_out(sc); 1503 r2t = iscsi_tcp_get_curr_r2t(task);
1458 if (task->unsol_count != 0) { 1504 if (r2t == NULL) {
1459 struct iscsi_data *hdr = &tcp_task->unsol_dtask.hdr;
1460
1461 /* Prepare a header for the unsolicited PDU.
1462 * The amount of data we want to send will be
1463 * in task->data_count.
1464 * FIXME: return the data count instead.
1465 */
1466 iscsi_prep_unsolicit_data_pdu(task, hdr);
1467
1468 debug_tcp("unsol dout [itt 0x%x doff %d dlen %d]\n",
1469 task->itt, tcp_task->sent, task->data_count);
1470
1471 iscsi_tcp_send_hdr_prep(conn, hdr, sizeof(*hdr));
1472 rc = iscsi_tcp_send_data_prep(conn, sdb->table.sgl,
1473 sdb->table.nents, tcp_task->sent,
1474 task->data_count);
1475 if (rc)
1476 goto fail;
1477 tcp_task->sent += task->data_count;
1478 task->unsol_count -= task->data_count;
1479 goto flush;
1480 } else {
1481 struct iscsi_session *session = conn->session;
1482 struct iscsi_r2t_info *r2t;
1483
1484 /* All unsolicited PDUs sent. Check for solicited PDUs.
1485 */
1486 spin_lock_bh(&session->lock);
1487 r2t = tcp_task->r2t;
1488 if (r2t != NULL) {
1489 /* Continue with this R2T? */
1490 if (!iscsi_solicit_data_cont(conn, task, r2t)) {
1491 debug_scsi(" done with r2t %p\n", r2t);
1492
1493 __kfifo_put(tcp_task->r2tpool.queue,
1494 (void*)&r2t, sizeof(void*));
1495 tcp_task->r2t = r2t = NULL;
1496 }
1497 }
1498
1499 if (r2t == NULL) {
1500 __kfifo_get(tcp_task->r2tqueue, (void*)&tcp_task->r2t,
1501 sizeof(void*));
1502 r2t = tcp_task->r2t;
1503 }
1504 spin_unlock_bh(&session->lock);
1505
1506 /* Waiting for more R2Ts to arrive. */ 1505 /* Waiting for more R2Ts to arrive. */
1507 if (r2t == NULL) { 1506 debug_tcp("no R2Ts yet\n");
1508 debug_tcp("no R2Ts yet\n"); 1507 return 0;
1509 return 0; 1508 }
1510 }
1511 1509
1512 debug_scsi("sol dout %p [dsn %d itt 0x%x doff %d dlen %d]\n", 1510 rc = conn->session->tt->alloc_pdu(task);
1513 r2t, r2t->solicit_datasn - 1, task->itt, 1511 if (rc)
1514 r2t->data_offset + r2t->sent, r2t->data_count); 1512 return rc;
1513 iscsi_prep_data_out_pdu(task, r2t, (struct iscsi_data *) task->hdr);
1515 1514
1516 iscsi_tcp_send_hdr_prep(conn, &r2t->dtask.hdr, 1515 debug_scsi("sol dout %p [dsn %d itt 0x%x doff %d dlen %d]\n",
1517 sizeof(struct iscsi_hdr)); 1516 r2t, r2t->datasn - 1, task->hdr->itt,
1517 r2t->data_offset + r2t->sent, r2t->data_count);
1518 1518
1519 rc = iscsi_tcp_send_data_prep(conn, sdb->table.sgl, 1519 rc = conn->session->tt->init_pdu(task, r2t->data_offset + r2t->sent,
1520 sdb->table.nents, 1520 r2t->data_count);
1521 r2t->data_offset + r2t->sent, 1521 if (rc)
1522 r2t->data_count); 1522 return rc;
1523 if (rc) 1523 r2t->sent += r2t->data_count;
1524 goto fail; 1524 goto flush;
1525 tcp_task->sent += r2t->data_count;
1526 r2t->sent += r2t->data_count;
1527 goto flush;
1528 }
1529 return 0;
1530fail:
1531 iscsi_conn_failure(conn, rc);
1532 return -EIO;
1533} 1525}
1534 1526
1535static struct iscsi_cls_conn * 1527static struct iscsi_cls_conn *
@@ -1751,13 +1743,14 @@ iscsi_r2tpool_alloc(struct iscsi_session *session)
1751 struct iscsi_tcp_task *tcp_task = task->dd_data; 1743 struct iscsi_tcp_task *tcp_task = task->dd_data;
1752 1744
1753 /* 1745 /*
1754 * pre-allocated x4 as much r2ts to handle race when 1746 * pre-allocated x2 as much r2ts to handle race when
1755 * target acks DataOut faster than we data_xmit() queues 1747 * target acks DataOut faster than we data_xmit() queues
1756 * could replenish r2tqueue. 1748 * could replenish r2tqueue.
1757 */ 1749 */
1758 1750
1759 /* R2T pool */ 1751 /* R2T pool */
1760 if (iscsi_pool_init(&tcp_task->r2tpool, session->max_r2t * 4, NULL, 1752 if (iscsi_pool_init(&tcp_task->r2tpool,
1753 session->max_r2t * 2, NULL,
1761 sizeof(struct iscsi_r2t_info))) { 1754 sizeof(struct iscsi_r2t_info))) {
1762 goto r2t_alloc_fail; 1755 goto r2t_alloc_fail;
1763 } 1756 }
@@ -1891,7 +1884,6 @@ iscsi_tcp_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max,
1891 struct iscsi_cls_session *cls_session; 1884 struct iscsi_cls_session *cls_session;
1892 struct iscsi_session *session; 1885 struct iscsi_session *session;
1893 struct Scsi_Host *shost; 1886 struct Scsi_Host *shost;
1894 int cmd_i;
1895 1887
1896 if (ep) { 1888 if (ep) {
1897 printk(KERN_ERR "iscsi_tcp: invalid ep %p.\n", ep); 1889 printk(KERN_ERR "iscsi_tcp: invalid ep %p.\n", ep);
@@ -1919,14 +1911,6 @@ iscsi_tcp_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max,
1919 session = cls_session->dd_data; 1911 session = cls_session->dd_data;
1920 1912
1921 shost->can_queue = session->scsi_cmds_max; 1913 shost->can_queue = session->scsi_cmds_max;
1922 for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) {
1923 struct iscsi_task *task = session->cmds[cmd_i];
1924 struct iscsi_tcp_task *tcp_task = task->dd_data;
1925
1926 task->hdr = &tcp_task->hdr.cmd_hdr;
1927 task->hdr_max = sizeof(tcp_task->hdr) - ISCSI_DIGEST_SIZE;
1928 }
1929
1930 if (iscsi_r2tpool_alloc(session)) 1914 if (iscsi_r2tpool_alloc(session))
1931 goto remove_session; 1915 goto remove_session;
1932 return cls_session; 1916 return cls_session;
@@ -2026,9 +2010,14 @@ static struct iscsi_transport iscsi_tcp_transport = {
2026 /* IO */ 2010 /* IO */
2027 .send_pdu = iscsi_conn_send_pdu, 2011 .send_pdu = iscsi_conn_send_pdu,
2028 .get_stats = iscsi_conn_get_stats, 2012 .get_stats = iscsi_conn_get_stats,
2013 /* iscsi task/cmd helpers */
2029 .init_task = iscsi_tcp_task_init, 2014 .init_task = iscsi_tcp_task_init,
2030 .xmit_task = iscsi_tcp_task_xmit, 2015 .xmit_task = iscsi_tcp_task_xmit,
2031 .cleanup_task = iscsi_tcp_cleanup_task, 2016 .cleanup_task = iscsi_tcp_cleanup_task,
2017 /* low level pdu helpers */
2018 .xmit_pdu = iscsi_tcp_flush,
2019 .init_pdu = iscsi_tcp_pdu_init,
2020 .alloc_pdu = iscsi_tcp_pdu_alloc,
2032 /* recovery */ 2021 /* recovery */
2033 .session_recovery_timedout = iscsi_session_recovery_timedout, 2022 .session_recovery_timedout = iscsi_session_recovery_timedout,
2034}; 2023};