aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libiscsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/libiscsi.c')
-rw-r--r--drivers/scsi/libiscsi.c90
1 files changed, 38 insertions, 52 deletions
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 7e6e031cc41b..1a8cd20f484f 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -189,6 +189,7 @@ static void iscsi_complete_command(struct iscsi_session *session,
189{ 189{
190 struct scsi_cmnd *sc = ctask->sc; 190 struct scsi_cmnd *sc = ctask->sc;
191 191
192 ctask->state = ISCSI_TASK_COMPLETED;
192 ctask->sc = NULL; 193 ctask->sc = NULL;
193 list_del_init(&ctask->running); 194 list_del_init(&ctask->running);
194 __kfifo_put(session->cmdpool.queue, (void*)&ctask, sizeof(void*)); 195 __kfifo_put(session->cmdpool.queue, (void*)&ctask, sizeof(void*));
@@ -568,20 +569,24 @@ static int iscsi_data_xmit(struct iscsi_conn *conn)
568 } 569 }
569 570
570 /* process command queue */ 571 /* process command queue */
571 while (__kfifo_get(conn->xmitqueue, (void*)&conn->ctask, 572 spin_lock_bh(&conn->session->lock);
572 sizeof(void*))) { 573 while (!list_empty(&conn->xmitqueue)) {
573 /* 574 /*
574 * iscsi tcp may readd the task to the xmitqueue to send 575 * iscsi tcp may readd the task to the xmitqueue to send
575 * write data 576 * write data
576 */ 577 */
577 spin_lock_bh(&conn->session->lock); 578 conn->ctask = list_entry(conn->xmitqueue.next,
578 if (list_empty(&conn->ctask->running)) 579 struct iscsi_cmd_task, running);
579 list_add_tail(&conn->ctask->running, &conn->run_list); 580 conn->ctask->state = ISCSI_TASK_RUNNING;
581 list_move_tail(conn->xmitqueue.next, &conn->run_list);
580 spin_unlock_bh(&conn->session->lock); 582 spin_unlock_bh(&conn->session->lock);
583
581 rc = tt->xmit_cmd_task(conn, conn->ctask); 584 rc = tt->xmit_cmd_task(conn, conn->ctask);
582 if (rc) 585 if (rc)
583 goto again; 586 goto again;
587 spin_lock_bh(&conn->session->lock);
584 } 588 }
589 spin_unlock_bh(&conn->session->lock);
585 /* done with this ctask */ 590 /* done with this ctask */
586 conn->ctask = NULL; 591 conn->ctask = NULL;
587 592
@@ -691,6 +696,7 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
691 sc->SCp.phase = session->age; 696 sc->SCp.phase = session->age;
692 sc->SCp.ptr = (char *)ctask; 697 sc->SCp.ptr = (char *)ctask;
693 698
699 ctask->state = ISCSI_TASK_PENDING;
694 ctask->mtask = NULL; 700 ctask->mtask = NULL;
695 ctask->conn = conn; 701 ctask->conn = conn;
696 ctask->sc = sc; 702 ctask->sc = sc;
@@ -700,7 +706,7 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
700 706
701 session->tt->init_cmd_task(ctask); 707 session->tt->init_cmd_task(ctask);
702 708
703 __kfifo_put(conn->xmitqueue, (void*)&ctask, sizeof(void*)); 709 list_add_tail(&ctask->running, &conn->xmitqueue);
704 debug_scsi( 710 debug_scsi(
705 "ctask enq [%s cid %d sc %lx itt 0x%x len %d cmdsn %d win %d]\n", 711 "ctask enq [%s cid %d sc %lx itt 0x%x len %d cmdsn %d win %d]\n",
706 sc->sc_data_direction == DMA_TO_DEVICE ? "write" : "read", 712 sc->sc_data_direction == DMA_TO_DEVICE ? "write" : "read",
@@ -977,31 +983,27 @@ static int iscsi_exec_abort_task(struct scsi_cmnd *sc,
977/* 983/*
978 * xmit mutex and session lock must be held 984 * xmit mutex and session lock must be held
979 */ 985 */
980#define iscsi_remove_task(tasktype) \ 986static struct iscsi_mgmt_task *
981static struct iscsi_##tasktype * \ 987iscsi_remove_mgmt_task(struct kfifo *fifo, uint32_t itt)
982iscsi_remove_##tasktype(struct kfifo *fifo, uint32_t itt) \ 988{
983{ \ 989 int i, nr_tasks = __kfifo_len(fifo) / sizeof(void*);
984 int i, nr_tasks = __kfifo_len(fifo) / sizeof(void*); \ 990 struct iscsi_mgmt_task *task;
985 struct iscsi_##tasktype *task; \ 991
986 \ 992 debug_scsi("searching %d tasks\n", nr_tasks);
987 debug_scsi("searching %d tasks\n", nr_tasks); \ 993
988 \ 994 for (i = 0; i < nr_tasks; i++) {
989 for (i = 0; i < nr_tasks; i++) { \ 995 __kfifo_get(fifo, (void*)&task, sizeof(void*));
990 __kfifo_get(fifo, (void*)&task, sizeof(void*)); \ 996 debug_scsi("check task %u\n", task->itt);
991 debug_scsi("check task %u\n", task->itt); \ 997
992 \ 998 if (task->itt == itt) {
993 if (task->itt == itt) { \ 999 debug_scsi("matched task\n");
994 debug_scsi("matched task\n"); \ 1000 return task;
995 return task; \ 1001 }
996 } \
997 \
998 __kfifo_put(fifo, (void*)&task, sizeof(void*)); \
999 } \
1000 return NULL; \
1001}
1002 1002
1003iscsi_remove_task(mgmt_task); 1003 __kfifo_put(fifo, (void*)&task, sizeof(void*));
1004iscsi_remove_task(cmd_task); 1004 }
1005 return NULL;
1006}
1005 1007
1006static int iscsi_ctask_mtask_cleanup(struct iscsi_cmd_task *ctask) 1008static int iscsi_ctask_mtask_cleanup(struct iscsi_cmd_task *ctask)
1007{ 1009{
@@ -1043,7 +1045,6 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
1043 struct iscsi_cmd_task *ctask = (struct iscsi_cmd_task *)sc->SCp.ptr; 1045 struct iscsi_cmd_task *ctask = (struct iscsi_cmd_task *)sc->SCp.ptr;
1044 struct iscsi_conn *conn = ctask->conn; 1046 struct iscsi_conn *conn = ctask->conn;
1045 struct iscsi_session *session = conn->session; 1047 struct iscsi_session *session = conn->session;
1046 struct iscsi_cmd_task *pending_ctask;
1047 int rc; 1048 int rc;
1048 1049
1049 conn->eh_abort_cnt++; 1050 conn->eh_abort_cnt++;
@@ -1071,17 +1072,8 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
1071 goto failed; 1072 goto failed;
1072 } 1073 }
1073 1074
1074 /* check for the easy pending cmd abort */ 1075 if (ctask->state == ISCSI_TASK_PENDING)
1075 pending_ctask = iscsi_remove_cmd_task(conn->xmitqueue, ctask->itt); 1076 goto success;
1076 if (pending_ctask) {
1077 /* iscsi_tcp queues write transfers on the xmitqueue */
1078 if (list_empty(&pending_ctask->running)) {
1079 debug_scsi("found pending task\n");
1080 goto success;
1081 } else
1082 __kfifo_put(conn->xmitqueue, (void*)&pending_ctask,
1083 sizeof(void*));
1084 }
1085 1077
1086 conn->tmabort_state = TMABORT_INITIAL; 1078 conn->tmabort_state = TMABORT_INITIAL;
1087 1079
@@ -1263,6 +1255,7 @@ iscsi_session_setup(struct iscsi_transport *iscsit,
1263 if (cmd_task_size) 1255 if (cmd_task_size)
1264 ctask->dd_data = &ctask[1]; 1256 ctask->dd_data = &ctask[1];
1265 ctask->itt = cmd_i; 1257 ctask->itt = cmd_i;
1258 INIT_LIST_HEAD(&ctask->running);
1266 } 1259 }
1267 1260
1268 spin_lock_init(&session->lock); 1261 spin_lock_init(&session->lock);
@@ -1282,6 +1275,7 @@ iscsi_session_setup(struct iscsi_transport *iscsit,
1282 if (mgmt_task_size) 1275 if (mgmt_task_size)
1283 mtask->dd_data = &mtask[1]; 1276 mtask->dd_data = &mtask[1];
1284 mtask->itt = ISCSI_MGMT_ITT_OFFSET + cmd_i; 1277 mtask->itt = ISCSI_MGMT_ITT_OFFSET + cmd_i;
1278 INIT_LIST_HEAD(&mtask->running);
1285 } 1279 }
1286 1280
1287 if (scsi_add_host(shost, NULL)) 1281 if (scsi_add_host(shost, NULL))
@@ -1361,12 +1355,7 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, uint32_t conn_idx)
1361 conn->tmabort_state = TMABORT_INITIAL; 1355 conn->tmabort_state = TMABORT_INITIAL;
1362 INIT_LIST_HEAD(&conn->run_list); 1356 INIT_LIST_HEAD(&conn->run_list);
1363 INIT_LIST_HEAD(&conn->mgmt_run_list); 1357 INIT_LIST_HEAD(&conn->mgmt_run_list);
1364 1358 INIT_LIST_HEAD(&conn->xmitqueue);
1365 /* initialize general xmit PDU commands queue */
1366 conn->xmitqueue = kfifo_alloc(session->cmds_max * sizeof(void*),
1367 GFP_KERNEL, NULL);
1368 if (conn->xmitqueue == ERR_PTR(-ENOMEM))
1369 goto xmitqueue_alloc_fail;
1370 1359
1371 /* initialize general immediate & non-immediate PDU commands queue */ 1360 /* initialize general immediate & non-immediate PDU commands queue */
1372 conn->immqueue = kfifo_alloc(session->mgmtpool_max * sizeof(void*), 1361 conn->immqueue = kfifo_alloc(session->mgmtpool_max * sizeof(void*),
@@ -1410,8 +1399,6 @@ login_mtask_alloc_fail:
1410mgmtqueue_alloc_fail: 1399mgmtqueue_alloc_fail:
1411 kfifo_free(conn->immqueue); 1400 kfifo_free(conn->immqueue);
1412immqueue_alloc_fail: 1401immqueue_alloc_fail:
1413 kfifo_free(conn->xmitqueue);
1414xmitqueue_alloc_fail:
1415 iscsi_destroy_conn(cls_conn); 1402 iscsi_destroy_conn(cls_conn);
1416 return NULL; 1403 return NULL;
1417} 1404}
@@ -1489,7 +1476,6 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
1489 session->cmdsn = session->max_cmdsn = session->exp_cmdsn = 1; 1476 session->cmdsn = session->max_cmdsn = session->exp_cmdsn = 1;
1490 spin_unlock_bh(&session->lock); 1477 spin_unlock_bh(&session->lock);
1491 1478
1492 kfifo_free(conn->xmitqueue);
1493 kfifo_free(conn->immqueue); 1479 kfifo_free(conn->immqueue);
1494 kfifo_free(conn->mgmtqueue); 1480 kfifo_free(conn->mgmtqueue);
1495 1481
@@ -1572,7 +1558,7 @@ static void fail_all_commands(struct iscsi_conn *conn)
1572 struct iscsi_cmd_task *ctask, *tmp; 1558 struct iscsi_cmd_task *ctask, *tmp;
1573 1559
1574 /* flush pending */ 1560 /* flush pending */
1575 while (__kfifo_get(conn->xmitqueue, (void*)&ctask, sizeof(void*))) { 1561 list_for_each_entry_safe(ctask, tmp, &conn->xmitqueue, running) {
1576 debug_scsi("failing pending sc %p itt 0x%x\n", ctask->sc, 1562 debug_scsi("failing pending sc %p itt 0x%x\n", ctask->sc,
1577 ctask->itt); 1563 ctask->itt);
1578 fail_command(conn, ctask, DID_BUS_BUSY << 16); 1564 fail_command(conn, ctask, DID_BUS_BUSY << 16);