diff options
Diffstat (limited to 'drivers/scsi/libiscsi.c')
-rw-r--r-- | drivers/scsi/libiscsi.c | 29 |
1 files changed, 15 insertions, 14 deletions
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 7c75771c77ff..3f5b9b445b29 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/mutex.h> | 25 | #include <linux/mutex.h> |
26 | #include <linux/kfifo.h> | 26 | #include <linux/kfifo.h> |
27 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
28 | #include <asm/unaligned.h> | ||
28 | #include <net/tcp.h> | 29 | #include <net/tcp.h> |
29 | #include <scsi/scsi_cmnd.h> | 30 | #include <scsi/scsi_cmnd.h> |
30 | #include <scsi/scsi_device.h> | 31 | #include <scsi/scsi_device.h> |
@@ -269,14 +270,14 @@ invalid_datalen: | |||
269 | goto out; | 270 | goto out; |
270 | } | 271 | } |
271 | 272 | ||
272 | senselen = be16_to_cpu(*(__be16 *)data); | 273 | senselen = be16_to_cpu(get_unaligned((__be16 *) data)); |
273 | if (datalen < senselen) | 274 | if (datalen < senselen) |
274 | goto invalid_datalen; | 275 | goto invalid_datalen; |
275 | 276 | ||
276 | memcpy(sc->sense_buffer, data + 2, | 277 | memcpy(sc->sense_buffer, data + 2, |
277 | min_t(uint16_t, senselen, SCSI_SENSE_BUFFERSIZE)); | 278 | min_t(uint16_t, senselen, SCSI_SENSE_BUFFERSIZE)); |
278 | debug_scsi("copied %d bytes of sense\n", | 279 | debug_scsi("copied %d bytes of sense\n", |
279 | min(senselen, SCSI_SENSE_BUFFERSIZE)); | 280 | min_t(uint16_t, senselen, SCSI_SENSE_BUFFERSIZE)); |
280 | } | 281 | } |
281 | 282 | ||
282 | if (sc->sc_data_direction == DMA_TO_DEVICE) | 283 | if (sc->sc_data_direction == DMA_TO_DEVICE) |
@@ -577,7 +578,7 @@ void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err) | |||
577 | } | 578 | } |
578 | EXPORT_SYMBOL_GPL(iscsi_conn_failure); | 579 | EXPORT_SYMBOL_GPL(iscsi_conn_failure); |
579 | 580 | ||
580 | static int iscsi_xmit_imm_task(struct iscsi_conn *conn) | 581 | static int iscsi_xmit_mtask(struct iscsi_conn *conn) |
581 | { | 582 | { |
582 | struct iscsi_hdr *hdr = conn->mtask->hdr; | 583 | struct iscsi_hdr *hdr = conn->mtask->hdr; |
583 | int rc, was_logout = 0; | 584 | int rc, was_logout = 0; |
@@ -591,6 +592,9 @@ static int iscsi_xmit_imm_task(struct iscsi_conn *conn) | |||
591 | if (rc) | 592 | if (rc) |
592 | return rc; | 593 | return rc; |
593 | 594 | ||
595 | /* done with this in-progress mtask */ | ||
596 | conn->mtask = NULL; | ||
597 | |||
594 | if (was_logout) { | 598 | if (was_logout) { |
595 | set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); | 599 | set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); |
596 | return -ENODATA; | 600 | return -ENODATA; |
@@ -643,11 +647,9 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) | |||
643 | conn->ctask = NULL; | 647 | conn->ctask = NULL; |
644 | } | 648 | } |
645 | if (conn->mtask) { | 649 | if (conn->mtask) { |
646 | rc = iscsi_xmit_imm_task(conn); | 650 | rc = iscsi_xmit_mtask(conn); |
647 | if (rc) | 651 | if (rc) |
648 | goto again; | 652 | goto again; |
649 | /* done with this in-progress mtask */ | ||
650 | conn->mtask = NULL; | ||
651 | } | 653 | } |
652 | 654 | ||
653 | /* process immediate first */ | 655 | /* process immediate first */ |
@@ -658,12 +660,10 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) | |||
658 | list_add_tail(&conn->mtask->running, | 660 | list_add_tail(&conn->mtask->running, |
659 | &conn->mgmt_run_list); | 661 | &conn->mgmt_run_list); |
660 | spin_unlock_bh(&conn->session->lock); | 662 | spin_unlock_bh(&conn->session->lock); |
661 | rc = iscsi_xmit_imm_task(conn); | 663 | rc = iscsi_xmit_mtask(conn); |
662 | if (rc) | 664 | if (rc) |
663 | goto again; | 665 | goto again; |
664 | } | 666 | } |
665 | /* done with this mtask */ | ||
666 | conn->mtask = NULL; | ||
667 | } | 667 | } |
668 | 668 | ||
669 | /* process command queue */ | 669 | /* process command queue */ |
@@ -701,12 +701,10 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) | |||
701 | list_add_tail(&conn->mtask->running, | 701 | list_add_tail(&conn->mtask->running, |
702 | &conn->mgmt_run_list); | 702 | &conn->mgmt_run_list); |
703 | spin_unlock_bh(&conn->session->lock); | 703 | spin_unlock_bh(&conn->session->lock); |
704 | rc = tt->xmit_mgmt_task(conn, conn->mtask); | 704 | rc = iscsi_xmit_mtask(conn); |
705 | if (rc) | 705 | if (rc) |
706 | goto again; | 706 | goto again; |
707 | } | 707 | } |
708 | /* done with this mtask */ | ||
709 | conn->mtask = NULL; | ||
710 | } | 708 | } |
711 | 709 | ||
712 | return -ENODATA; | 710 | return -ENODATA; |
@@ -1523,7 +1521,7 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, uint32_t conn_idx) | |||
1523 | } | 1521 | } |
1524 | spin_unlock_bh(&session->lock); | 1522 | spin_unlock_bh(&session->lock); |
1525 | 1523 | ||
1526 | data = kmalloc(DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH, GFP_KERNEL); | 1524 | data = kmalloc(ISCSI_DEF_MAX_RECV_SEG_LEN, GFP_KERNEL); |
1527 | if (!data) | 1525 | if (!data) |
1528 | goto login_mtask_data_alloc_fail; | 1526 | goto login_mtask_data_alloc_fail; |
1529 | conn->login_mtask->data = conn->data = data; | 1527 | conn->login_mtask->data = conn->data = data; |
@@ -1597,6 +1595,9 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn) | |||
1597 | wake_up(&conn->ehwait); | 1595 | wake_up(&conn->ehwait); |
1598 | } | 1596 | } |
1599 | 1597 | ||
1598 | /* flush queued up work because we free the connection below */ | ||
1599 | scsi_flush_work(session->host); | ||
1600 | |||
1600 | spin_lock_bh(&session->lock); | 1601 | spin_lock_bh(&session->lock); |
1601 | kfree(conn->data); | 1602 | kfree(conn->data); |
1602 | kfree(conn->persistent_address); | 1603 | kfree(conn->persistent_address); |