diff options
-rw-r--r-- | drivers/scsi/iscsi_tcp.c | 45 | ||||
-rw-r--r-- | drivers/scsi/libiscsi.c | 90 | ||||
-rw-r--r-- | include/scsi/libiscsi.h | 10 |
3 files changed, 68 insertions, 77 deletions
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 88dafdf45c47..ab324d984b8d 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c | |||
@@ -185,11 +185,19 @@ iscsi_hdr_extract(struct iscsi_tcp_conn *tcp_conn) | |||
185 | * must be called with session lock | 185 | * must be called with session lock |
186 | */ | 186 | */ |
187 | static void | 187 | static void |
188 | __iscsi_ctask_cleanup(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | 188 | iscsi_tcp_cleanup_ctask(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) |
189 | { | 189 | { |
190 | struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; | 190 | struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; |
191 | struct iscsi_r2t_info *r2t; | ||
191 | struct scsi_cmnd *sc; | 192 | struct scsi_cmnd *sc; |
192 | 193 | ||
194 | /* flush ctask's r2t queues */ | ||
195 | while (__kfifo_get(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*))) { | ||
196 | __kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t, | ||
197 | sizeof(void*)); | ||
198 | debug_scsi("iscsi_tcp_cleanup_ctask pending r2t dropped\n"); | ||
199 | } | ||
200 | |||
193 | sc = ctask->sc; | 201 | sc = ctask->sc; |
194 | if (unlikely(!sc)) | 202 | if (unlikely(!sc)) |
195 | return; | 203 | return; |
@@ -374,6 +382,7 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
374 | spin_unlock(&session->lock); | 382 | spin_unlock(&session->lock); |
375 | return 0; | 383 | return 0; |
376 | } | 384 | } |
385 | |||
377 | rc = __kfifo_get(tcp_ctask->r2tpool.queue, (void*)&r2t, sizeof(void*)); | 386 | rc = __kfifo_get(tcp_ctask->r2tpool.queue, (void*)&r2t, sizeof(void*)); |
378 | BUG_ON(!rc); | 387 | BUG_ON(!rc); |
379 | 388 | ||
@@ -399,7 +408,7 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
399 | tcp_ctask->exp_r2tsn = r2tsn + 1; | 408 | tcp_ctask->exp_r2tsn = r2tsn + 1; |
400 | tcp_ctask->xmstate |= XMSTATE_SOL_HDR; | 409 | tcp_ctask->xmstate |= XMSTATE_SOL_HDR; |
401 | __kfifo_put(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*)); | 410 | __kfifo_put(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*)); |
402 | __kfifo_put(conn->xmitqueue, (void*)&ctask, sizeof(void*)); | 411 | list_move_tail(&ctask->running, &conn->xmitqueue); |
403 | 412 | ||
404 | scsi_queue_work(session->host, &conn->xmitwork); | 413 | scsi_queue_work(session->host, &conn->xmitwork); |
405 | conn->r2t_pdus_cnt++; | 414 | conn->r2t_pdus_cnt++; |
@@ -484,7 +493,7 @@ iscsi_tcp_hdr_recv(struct iscsi_conn *conn) | |||
484 | goto copy_hdr; | 493 | goto copy_hdr; |
485 | 494 | ||
486 | spin_lock(&session->lock); | 495 | spin_lock(&session->lock); |
487 | __iscsi_ctask_cleanup(conn, tcp_conn->in.ctask); | 496 | iscsi_tcp_cleanup_ctask(conn, tcp_conn->in.ctask); |
488 | rc = __iscsi_complete_pdu(conn, hdr, NULL, 0); | 497 | rc = __iscsi_complete_pdu(conn, hdr, NULL, 0); |
489 | spin_unlock(&session->lock); | 498 | spin_unlock(&session->lock); |
490 | break; | 499 | break; |
@@ -745,10 +754,11 @@ static int iscsi_scsi_data_in(struct iscsi_conn *conn) | |||
745 | done: | 754 | done: |
746 | /* check for non-exceptional status */ | 755 | /* check for non-exceptional status */ |
747 | if (tcp_conn->in.hdr->flags & ISCSI_FLAG_DATA_STATUS) { | 756 | if (tcp_conn->in.hdr->flags & ISCSI_FLAG_DATA_STATUS) { |
748 | debug_scsi("done [sc %lx res %d itt 0x%x]\n", | 757 | debug_scsi("done [sc %lx res %d itt 0x%x flags 0x%x]\n", |
749 | (long)sc, sc->result, ctask->itt); | 758 | (long)sc, sc->result, ctask->itt, |
759 | tcp_conn->in.hdr->flags); | ||
750 | spin_lock(&conn->session->lock); | 760 | spin_lock(&conn->session->lock); |
751 | __iscsi_ctask_cleanup(conn, ctask); | 761 | iscsi_tcp_cleanup_ctask(conn, ctask); |
752 | __iscsi_complete_pdu(conn, tcp_conn->in.hdr, NULL, 0); | 762 | __iscsi_complete_pdu(conn, tcp_conn->in.hdr, NULL, 0); |
753 | spin_unlock(&conn->session->lock); | 763 | spin_unlock(&conn->session->lock); |
754 | } | 764 | } |
@@ -769,7 +779,7 @@ iscsi_data_recv(struct iscsi_conn *conn) | |||
769 | break; | 779 | break; |
770 | case ISCSI_OP_SCSI_CMD_RSP: | 780 | case ISCSI_OP_SCSI_CMD_RSP: |
771 | spin_lock(&conn->session->lock); | 781 | spin_lock(&conn->session->lock); |
772 | __iscsi_ctask_cleanup(conn, tcp_conn->in.ctask); | 782 | iscsi_tcp_cleanup_ctask(conn, tcp_conn->in.ctask); |
773 | spin_unlock(&conn->session->lock); | 783 | spin_unlock(&conn->session->lock); |
774 | case ISCSI_OP_TEXT_RSP: | 784 | case ISCSI_OP_TEXT_RSP: |
775 | case ISCSI_OP_LOGIN_RSP: | 785 | case ISCSI_OP_LOGIN_RSP: |
@@ -1308,7 +1318,7 @@ iscsi_tcp_cmd_init(struct iscsi_cmd_task *ctask) | |||
1308 | ctask->imm_count - | 1318 | ctask->imm_count - |
1309 | ctask->unsol_count; | 1319 | ctask->unsol_count; |
1310 | 1320 | ||
1311 | debug_scsi("cmd [itt %x total %d imm %d imm_data %d " | 1321 | debug_scsi("cmd [itt 0x%x total %d imm %d imm_data %d " |
1312 | "r2t_data %d]\n", | 1322 | "r2t_data %d]\n", |
1313 | ctask->itt, ctask->total_length, ctask->imm_count, | 1323 | ctask->itt, ctask->total_length, ctask->imm_count, |
1314 | ctask->unsol_count, tcp_ctask->r2t_data_count); | 1324 | ctask->unsol_count, tcp_ctask->r2t_data_count); |
@@ -1636,7 +1646,7 @@ handle_xmstate_sol_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
1636 | } | 1646 | } |
1637 | solicit_again: | 1647 | solicit_again: |
1638 | /* | 1648 | /* |
1639 | * send Data-Out whitnin this R2T sequence. | 1649 | * send Data-Out within this R2T sequence. |
1640 | */ | 1650 | */ |
1641 | if (!r2t->data_count) | 1651 | if (!r2t->data_count) |
1642 | goto data_out_done; | 1652 | goto data_out_done; |
@@ -1731,7 +1741,7 @@ handle_xmstate_w_pad(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
1731 | struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; | 1741 | struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; |
1732 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; | 1742 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; |
1733 | struct iscsi_data_task *dtask = tcp_ctask->dtask; | 1743 | struct iscsi_data_task *dtask = tcp_ctask->dtask; |
1734 | int sent, rc; | 1744 | int sent = 0, rc; |
1735 | 1745 | ||
1736 | tcp_ctask->xmstate &= ~XMSTATE_W_PAD; | 1746 | tcp_ctask->xmstate &= ~XMSTATE_W_PAD; |
1737 | iscsi_buf_init_iov(&tcp_ctask->sendbuf, (char*)&tcp_ctask->pad, | 1747 | iscsi_buf_init_iov(&tcp_ctask->sendbuf, (char*)&tcp_ctask->pad, |
@@ -2002,20 +2012,6 @@ iscsi_tcp_conn_bind(struct iscsi_cls_session *cls_session, | |||
2002 | } | 2012 | } |
2003 | 2013 | ||
2004 | static void | 2014 | static void |
2005 | iscsi_tcp_cleanup_ctask(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | ||
2006 | { | ||
2007 | struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; | ||
2008 | struct iscsi_r2t_info *r2t; | ||
2009 | |||
2010 | /* flush ctask's r2t queues */ | ||
2011 | while (__kfifo_get(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*))) | ||
2012 | __kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t, | ||
2013 | sizeof(void*)); | ||
2014 | |||
2015 | __iscsi_ctask_cleanup(conn, ctask); | ||
2016 | } | ||
2017 | |||
2018 | static void | ||
2019 | iscsi_tcp_suspend_conn_rx(struct iscsi_conn *conn) | 2015 | iscsi_tcp_suspend_conn_rx(struct iscsi_conn *conn) |
2020 | { | 2016 | { |
2021 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; | 2017 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; |
@@ -2057,6 +2053,7 @@ iscsi_tcp_mgmt_init(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask, | |||
2057 | iscsi_buf_init_iov(&tcp_mtask->headbuf, (char*)mtask->hdr, | 2053 | iscsi_buf_init_iov(&tcp_mtask->headbuf, (char*)mtask->hdr, |
2058 | sizeof(struct iscsi_hdr)); | 2054 | sizeof(struct iscsi_hdr)); |
2059 | tcp_mtask->xmstate = XMSTATE_IMM_HDR; | 2055 | tcp_mtask->xmstate = XMSTATE_IMM_HDR; |
2056 | tcp_mtask->sent = 0; | ||
2060 | 2057 | ||
2061 | if (mtask->data_count) | 2058 | if (mtask->data_count) |
2062 | iscsi_buf_init_iov(&tcp_mtask->sendbuf, (char*)mtask->data, | 2059 | iscsi_buf_init_iov(&tcp_mtask->sendbuf, (char*)mtask->data, |
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) \ | 986 | static struct iscsi_mgmt_task * |
981 | static struct iscsi_##tasktype * \ | 987 | iscsi_remove_mgmt_task(struct kfifo *fifo, uint32_t itt) |
982 | iscsi_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 | ||
1003 | iscsi_remove_task(mgmt_task); | 1003 | __kfifo_put(fifo, (void*)&task, sizeof(void*)); |
1004 | iscsi_remove_task(cmd_task); | 1004 | } |
1005 | return NULL; | ||
1006 | } | ||
1005 | 1007 | ||
1006 | static int iscsi_ctask_mtask_cleanup(struct iscsi_cmd_task *ctask) | 1008 | static 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: | |||
1410 | mgmtqueue_alloc_fail: | 1399 | mgmtqueue_alloc_fail: |
1411 | kfifo_free(conn->immqueue); | 1400 | kfifo_free(conn->immqueue); |
1412 | immqueue_alloc_fail: | 1401 | immqueue_alloc_fail: |
1413 | kfifo_free(conn->xmitqueue); | ||
1414 | xmitqueue_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); |
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index ba2760802ded..e71d6e96eca6 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h | |||
@@ -83,6 +83,12 @@ struct iscsi_mgmt_task { | |||
83 | struct list_head running; | 83 | struct list_head running; |
84 | }; | 84 | }; |
85 | 85 | ||
86 | enum { | ||
87 | ISCSI_TASK_COMPLETED, | ||
88 | ISCSI_TASK_PENDING, | ||
89 | ISCSI_TASK_RUNNING, | ||
90 | }; | ||
91 | |||
86 | struct iscsi_cmd_task { | 92 | struct iscsi_cmd_task { |
87 | /* | 93 | /* |
88 | * Becuae LLDs allocate their hdr differently, this is a pointer to | 94 | * Becuae LLDs allocate their hdr differently, this is a pointer to |
@@ -101,6 +107,8 @@ struct iscsi_cmd_task { | |||
101 | struct iscsi_conn *conn; /* used connection */ | 107 | struct iscsi_conn *conn; /* used connection */ |
102 | struct iscsi_mgmt_task *mtask; /* tmf mtask in progr */ | 108 | struct iscsi_mgmt_task *mtask; /* tmf mtask in progr */ |
103 | 109 | ||
110 | /* state set/tested under session->lock */ | ||
111 | int state; | ||
104 | struct list_head running; /* running cmd list */ | 112 | struct list_head running; /* running cmd list */ |
105 | void *dd_data; /* driver/transport data */ | 113 | void *dd_data; /* driver/transport data */ |
106 | }; | 114 | }; |
@@ -134,7 +142,7 @@ struct iscsi_conn { | |||
134 | struct kfifo *immqueue; /* immediate xmit queue */ | 142 | struct kfifo *immqueue; /* immediate xmit queue */ |
135 | struct kfifo *mgmtqueue; /* mgmt (control) xmit queue */ | 143 | struct kfifo *mgmtqueue; /* mgmt (control) xmit queue */ |
136 | struct list_head mgmt_run_list; /* list of control tasks */ | 144 | struct list_head mgmt_run_list; /* list of control tasks */ |
137 | struct kfifo *xmitqueue; /* data-path cmd queue */ | 145 | struct list_head xmitqueue; /* data-path cmd queue */ |
138 | struct list_head run_list; /* list of cmds in progress */ | 146 | struct list_head run_list; /* list of cmds in progress */ |
139 | struct work_struct xmitwork; /* per-conn. xmit workqueue */ | 147 | struct work_struct xmitwork; /* per-conn. xmit workqueue */ |
140 | /* | 148 | /* |