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 | /* |
