From: Greg Kroah-Hartman Date: Mon, 14 Jan 2013 17:20:33 +0000 (-0800) Subject: 3.7-stable patches X-Git-Tag: v3.7.3~73 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=fe52074b6c4082042e04145ab6893ceff46587b5;p=thirdparty%2Fkernel%2Fstable-queue.git 3.7-stable patches added patches: iscsi-target-always-send-a-response-before-terminating-iscsi-connection.patch iscsi-target-fix-bug-in-handling-of-expstatsn-ack-during-u32-wrap-around.patch iscsit-use-gfp_atomic-under-spin-lock.patch qla2xxx-look-up-lun-for-abort-requests.patch sata_promise-fix-hardreset-lockdep-error.patch scsi-mvsas-fix-undefined-bit-shift.patch scsi-prevent-stack-buffer-overflow-in-host_reset.patch scsi-qla2xxx-change-in-setting-unloading-flag-and-fc-vports-logout-sequence-while-unloading-qla2xxx-driver.patch scsi-qla2xxx-free-rsp_data-even-on-error-in-qla2x00_process_loopback.patch scsi-qla2xxx-properly-set-result-field-of-bsg_job-reply-structure-for-success-and-failure.patch scsi-qla2xxx-test-and-clear-fcport_update_needed-atomically.patch --- diff --git a/queue-3.7/iscsi-target-always-send-a-response-before-terminating-iscsi-connection.patch b/queue-3.7/iscsi-target-always-send-a-response-before-terminating-iscsi-connection.patch new file mode 100644 index 00000000000..63a9cb12a59 --- /dev/null +++ b/queue-3.7/iscsi-target-always-send-a-response-before-terminating-iscsi-connection.patch @@ -0,0 +1,72 @@ +From 1c5c12c666fda27c7c494b34934a0a0631a48130 Mon Sep 17 00:00:00 2001 +From: Roland Dreier +Date: Mon, 5 Nov 2012 18:02:42 -0800 +Subject: iscsi-target: Always send a response before terminating iSCSI connection + +From: Roland Dreier + +commit 1c5c12c666fda27c7c494b34934a0a0631a48130 upstream. + +There are some cases, for example when the initiator sends an +out-of-bounds ErrorRecoveryLevel value, where the iSCSI target +terminates the connection without sending back any error. Audit the +login path and add appropriate iscsit_tx_login_rsp() calls to make +sure this doesn't happen. + +Signed-off-by: Roland Dreier +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/iscsi/iscsi_target_login.c | 8 ++++---- + drivers/target/iscsi/iscsi_target_nego.c | 10 ++++++++-- + 2 files changed, 12 insertions(+), 6 deletions(-) + +--- a/drivers/target/iscsi/iscsi_target_login.c ++++ b/drivers/target/iscsi/iscsi_target_login.c +@@ -127,13 +127,13 @@ int iscsi_check_for_session_reinstatemen + + initiatorname_param = iscsi_find_param_from_key( + INITIATORNAME, conn->param_list); +- if (!initiatorname_param) +- return -1; +- + sessiontype_param = iscsi_find_param_from_key( + SESSIONTYPE, conn->param_list); +- if (!sessiontype_param) ++ if (!initiatorname_param || !sessiontype_param) { ++ iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR, ++ ISCSI_LOGIN_STATUS_MISSING_FIELDS); + return -1; ++ } + + sessiontype = (strncmp(sessiontype_param->value, NORMAL, 6)) ? 1 : 0; + +--- a/drivers/target/iscsi/iscsi_target_nego.c ++++ b/drivers/target/iscsi/iscsi_target_nego.c +@@ -620,8 +620,11 @@ static int iscsi_target_handle_csg_one(s + login->req_buf, + payload_length, + conn); +- if (ret < 0) ++ if (ret < 0) { ++ iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR, ++ ISCSI_LOGIN_STATUS_INIT_ERR); + return -1; ++ } + + if (login->first_request) + if (iscsi_target_check_first_request(conn, login) < 0) +@@ -636,8 +639,11 @@ static int iscsi_target_handle_csg_one(s + login->rsp_buf, + &login->rsp_length, + conn->param_list); +- if (ret < 0) ++ if (ret < 0) { ++ iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR, ++ ISCSI_LOGIN_STATUS_INIT_ERR); + return -1; ++ } + + if (!login->auth_complete && + ISCSI_TPG_ATTRIB(ISCSI_TPG_C(conn))->authentication) { diff --git a/queue-3.7/iscsi-target-fix-bug-in-handling-of-expstatsn-ack-during-u32-wrap-around.patch b/queue-3.7/iscsi-target-fix-bug-in-handling-of-expstatsn-ack-during-u32-wrap-around.patch new file mode 100644 index 00000000000..e4d0996604c --- /dev/null +++ b/queue-3.7/iscsi-target-fix-bug-in-handling-of-expstatsn-ack-during-u32-wrap-around.patch @@ -0,0 +1,66 @@ +From 64c13330a38935120501b19c97a3e6095747c7a1 Mon Sep 17 00:00:00 2001 +From: Steve Hodgson +Date: Mon, 5 Nov 2012 18:02:41 -0800 +Subject: iscsi-target: Fix bug in handling of ExpStatSN ACK during u32 wrap-around + +From: Steve Hodgson + +commit 64c13330a38935120501b19c97a3e6095747c7a1 upstream. + +This patch fixes a bug in the hanlding of initiator provided ExpStatSN and +individual iscsi_cmd->stat_sn comparision during iscsi_conn->stat_sn +wrap-around within iscsit_ack_from_expstatsn() code. + +This bug would manifest itself as iscsi_cmd descriptors not being Acked +by a lower ExpStatSn, causing them to be leaked until an iSCSI connection +or session reinstatement event occurs to release all commands. + +Also fix up two other uses of incorrect CmdSN SNA comparison to use wrapper +usage from include/scsi/iscsi_proto.h. + +Signed-off-by: Steve Hodgson +Signed-off-by: Roland Dreier +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/iscsi/iscsi_target.c | 2 +- + drivers/target/iscsi/iscsi_target_erl2.c | 2 +- + drivers/target/iscsi/iscsi_target_tmr.c | 4 ++-- + 3 files changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/target/iscsi/iscsi_target.c ++++ b/drivers/target/iscsi/iscsi_target.c +@@ -735,7 +735,7 @@ static void iscsit_ack_from_expstatsn(st + list_for_each_entry(cmd, &conn->conn_cmd_list, i_conn_node) { + spin_lock(&cmd->istate_lock); + if ((cmd->i_state == ISTATE_SENT_STATUS) && +- (cmd->stat_sn < exp_statsn)) { ++ iscsi_sna_lt(cmd->stat_sn, exp_statsn)) { + cmd->i_state = ISTATE_REMOVE; + spin_unlock(&cmd->istate_lock); + iscsit_add_cmd_to_immediate_queue(cmd, conn, +--- a/drivers/target/iscsi/iscsi_target_erl2.c ++++ b/drivers/target/iscsi/iscsi_target_erl2.c +@@ -372,7 +372,7 @@ int iscsit_prepare_cmds_for_realligance( + * made generic here. + */ + if (!(cmd->cmd_flags & ICF_OOO_CMDSN) && !cmd->immediate_cmd && +- (cmd->cmd_sn >= conn->sess->exp_cmd_sn)) { ++ iscsi_sna_gte(cmd->stat_sn, conn->sess->exp_cmd_sn)) { + list_del(&cmd->i_conn_node); + spin_unlock_bh(&conn->cmd_lock); + iscsit_free_cmd(cmd); +--- a/drivers/target/iscsi/iscsi_target_tmr.c ++++ b/drivers/target/iscsi/iscsi_target_tmr.c +@@ -50,8 +50,8 @@ u8 iscsit_tmr_abort_task( + if (!ref_cmd) { + pr_err("Unable to locate RefTaskTag: 0x%08x on CID:" + " %hu.\n", hdr->rtt, conn->cid); +- return (be32_to_cpu(hdr->refcmdsn) >= conn->sess->exp_cmd_sn && +- be32_to_cpu(hdr->refcmdsn) <= conn->sess->max_cmd_sn) ? ++ return (iscsi_sna_gte(be32_to_cpu(hdr->refcmdsn), conn->sess->exp_cmd_sn) && ++ iscsi_sna_lte(be32_to_cpu(hdr->refcmdsn), conn->sess->max_cmd_sn)) ? + ISCSI_TMF_RSP_COMPLETE : ISCSI_TMF_RSP_NO_TASK; + } + if (ref_cmd->cmd_sn != be32_to_cpu(hdr->refcmdsn)) { diff --git a/queue-3.7/iscsit-use-gfp_atomic-under-spin-lock.patch b/queue-3.7/iscsit-use-gfp_atomic-under-spin-lock.patch new file mode 100644 index 00000000000..34d3c3ece8d --- /dev/null +++ b/queue-3.7/iscsit-use-gfp_atomic-under-spin-lock.patch @@ -0,0 +1,32 @@ +From 3c989d7603872bf878840f7ce3ea49b73bea4c6c Mon Sep 17 00:00:00 2001 +From: Wei Yongjun +Date: Fri, 23 Nov 2012 12:07:39 +0800 +Subject: iscsit: use GFP_ATOMIC under spin lock + +From: Wei Yongjun + +commit 3c989d7603872bf878840f7ce3ea49b73bea4c6c upstream. + +The function iscsit_build_conn_drop_async_message() is called +from iscsit_close_connection() with spin lock 'sess->conn_lock' +held, so we should use GFP_ATOMIC instead of GFP_KERNEL. + +Signed-off-by: Wei Yongjun +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/iscsi/iscsi_target.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/target/iscsi/iscsi_target.c ++++ b/drivers/target/iscsi/iscsi_target.c +@@ -2360,7 +2360,7 @@ static void iscsit_build_conn_drop_async + if (!conn_p) + return; + +- cmd = iscsit_allocate_cmd(conn_p, GFP_KERNEL); ++ cmd = iscsit_allocate_cmd(conn_p, GFP_ATOMIC); + if (!cmd) { + iscsit_dec_conn_usage_count(conn_p); + return; diff --git a/queue-3.7/qla2xxx-look-up-lun-for-abort-requests.patch b/queue-3.7/qla2xxx-look-up-lun-for-abort-requests.patch new file mode 100644 index 00000000000..ea61978e0a9 --- /dev/null +++ b/queue-3.7/qla2xxx-look-up-lun-for-abort-requests.patch @@ -0,0 +1,63 @@ +From 06e97b489006f28e23bb028febfa1c01c266d676 Mon Sep 17 00:00:00 2001 +From: Steve Hodgson +Date: Fri, 16 Nov 2012 08:06:17 -0800 +Subject: qla2xxx: Look up LUN for abort requests + +From: Steve Hodgson + +commit 06e97b489006f28e23bb028febfa1c01c266d676 upstream. + +Search through the list of pending commands on the session list to find +the command the initiator is actually aborting, so that we can pass the +correct LUN to the core TMR handling code. + +(nab: Allow abort requests to work to LUN=0 with mainline target code) + +Signed-off-by: Steve Hodgson +Signed-off-by: Roland Dreier +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/qla2xxx/qla_target.c | 21 ++++++++++++++++++++- + 1 file changed, 20 insertions(+), 1 deletion(-) + +--- a/drivers/scsi/qla2xxx/qla_target.c ++++ b/drivers/scsi/qla2xxx/qla_target.c +@@ -1264,8 +1264,27 @@ static int __qlt_24xx_handle_abts(struct + struct abts_recv_from_24xx *abts, struct qla_tgt_sess *sess) + { + struct qla_hw_data *ha = vha->hw; ++ struct se_session *se_sess = sess->se_sess; + struct qla_tgt_mgmt_cmd *mcmd; ++ struct se_cmd *se_cmd; ++ u32 lun = 0; + int rc; ++ bool found_lun = false; ++ ++ spin_lock(&se_sess->sess_cmd_lock); ++ list_for_each_entry(se_cmd, &se_sess->sess_cmd_list, se_cmd_list) { ++ struct qla_tgt_cmd *cmd = ++ container_of(se_cmd, struct qla_tgt_cmd, se_cmd); ++ if (cmd->tag == abts->exchange_addr_to_abort) { ++ lun = cmd->unpacked_lun; ++ found_lun = true; ++ break; ++ } ++ } ++ spin_unlock(&se_sess->sess_cmd_lock); ++ ++ if (!found_lun) ++ return -ENOENT; + + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf00f, + "qla_target(%d): task abort (tag=%d)\n", +@@ -1283,7 +1302,7 @@ static int __qlt_24xx_handle_abts(struct + mcmd->sess = sess; + memcpy(&mcmd->orig_iocb.abts, abts, sizeof(mcmd->orig_iocb.abts)); + +- rc = ha->tgt.tgt_ops->handle_tmr(mcmd, 0, TMR_ABORT_TASK, ++ rc = ha->tgt.tgt_ops->handle_tmr(mcmd, lun, TMR_ABORT_TASK, + abts->exchange_addr_to_abort); + if (rc != 0) { + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf052, diff --git a/queue-3.7/sata_promise-fix-hardreset-lockdep-error.patch b/queue-3.7/sata_promise-fix-hardreset-lockdep-error.patch new file mode 100644 index 00000000000..5ce62de0cc3 --- /dev/null +++ b/queue-3.7/sata_promise-fix-hardreset-lockdep-error.patch @@ -0,0 +1,84 @@ +From 3100d49d3cd236443faae9d81137c81b22d36003 Mon Sep 17 00:00:00 2001 +From: Mikael Pettersson +Date: Sun, 16 Sep 2012 20:53:43 +0200 +Subject: sata_promise: fix hardreset lockdep error + +From: Mikael Pettersson + +commit 3100d49d3cd236443faae9d81137c81b22d36003 upstream. + +sata_promise's pdc_hard_reset_port() needs to serialize because it +flips a port-specific bit in controller register that's shared by +all ports. The code takes the ata host lock for this, but that's +broken because an interrupt may arrive on our irq during the hard +reset sequence, and that too will take the ata host lock. With +lockdep enabled a big nasty warning is seen. + +Fixed by adding private state to the ata host structure, containing +a second lock used only for serializing the hard reset sequences. +This eliminated the lockdep warnings both on my test rig and on +the original reporter's machine. + +Signed-off-by: Mikael Pettersson +Tested-by: Adko Branil +Signed-off-by: Jeff Garzik +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/ata/sata_promise.c | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +--- a/drivers/ata/sata_promise.c ++++ b/drivers/ata/sata_promise.c +@@ -147,6 +147,10 @@ struct pdc_port_priv { + dma_addr_t pkt_dma; + }; + ++struct pdc_host_priv { ++ spinlock_t hard_reset_lock; ++}; ++ + static int pdc_sata_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val); + static int pdc_sata_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val); + static int pdc_ata_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); +@@ -801,9 +805,10 @@ static void pdc_hard_reset_port(struct a + void __iomem *host_mmio = ap->host->iomap[PDC_MMIO_BAR]; + void __iomem *pcictl_b1_mmio = host_mmio + PDC_PCI_CTL + 1; + unsigned int ata_no = pdc_ata_port_to_ata_no(ap); ++ struct pdc_host_priv *hpriv = ap->host->private_data; + u8 tmp; + +- spin_lock(&ap->host->lock); ++ spin_lock(&hpriv->hard_reset_lock); + + tmp = readb(pcictl_b1_mmio); + tmp &= ~(0x10 << ata_no); +@@ -814,7 +819,7 @@ static void pdc_hard_reset_port(struct a + writeb(tmp, pcictl_b1_mmio); + readb(pcictl_b1_mmio); /* flush */ + +- spin_unlock(&ap->host->lock); ++ spin_unlock(&hpriv->hard_reset_lock); + } + + static int pdc_sata_hardreset(struct ata_link *link, unsigned int *class, +@@ -1182,6 +1187,7 @@ static int pdc_ata_init_one(struct pci_d + const struct ata_port_info *pi = &pdc_port_info[ent->driver_data]; + const struct ata_port_info *ppi[PDC_MAX_PORTS]; + struct ata_host *host; ++ struct pdc_host_priv *hpriv; + void __iomem *host_mmio; + int n_ports, i, rc; + int is_sataii_tx4; +@@ -1218,6 +1224,11 @@ static int pdc_ata_init_one(struct pci_d + dev_err(&pdev->dev, "failed to allocate host\n"); + return -ENOMEM; + } ++ hpriv = devm_kzalloc(&pdev->dev, sizeof *hpriv, GFP_KERNEL); ++ if (!hpriv) ++ return -ENOMEM; ++ spin_lock_init(&hpriv->hard_reset_lock); ++ host->private_data = hpriv; + host->iomap = pcim_iomap_table(pdev); + + is_sataii_tx4 = pdc_is_sataii_tx4(pi->flags); diff --git a/queue-3.7/scsi-mvsas-fix-undefined-bit-shift.patch b/queue-3.7/scsi-mvsas-fix-undefined-bit-shift.patch new file mode 100644 index 00000000000..348134460d8 --- /dev/null +++ b/queue-3.7/scsi-mvsas-fix-undefined-bit-shift.patch @@ -0,0 +1,70 @@ +From beecadea1b8d67f591b13f7099559f32f3fd601d Mon Sep 17 00:00:00 2001 +From: Xi Wang +Date: Fri, 16 Nov 2012 14:40:03 -0500 +Subject: SCSI: mvsas: fix undefined bit shift + +From: Xi Wang + +commit beecadea1b8d67f591b13f7099559f32f3fd601d upstream. + +The macro bit(n) is defined as ((u32)1 << n), and thus it doesn't work +with n >= 32, such as in mvs_94xx_assign_reg_set(): + + if (i >= 32) { + mvi->sata_reg_set |= bit(i); + ... + } + +The shift ((u32)1 << n) with n >= 32 also leads to undefined behavior. +The result varies depending on the architecture. + +This patch changes bit(n) to do a 64-bit shift. It also simplifies +mv_ffc64() using __ffs64(), since invoking ffz() with ~0 is undefined. + +Signed-off-by: Xi Wang +Acked-by: Xiangliang Yu +Signed-off-by: James Bottomley +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/mvsas/mv_94xx.h | 14 ++------------ + drivers/scsi/mvsas/mv_sas.h | 2 +- + 2 files changed, 3 insertions(+), 13 deletions(-) + +--- a/drivers/scsi/mvsas/mv_94xx.h ++++ b/drivers/scsi/mvsas/mv_94xx.h +@@ -258,21 +258,11 @@ enum sas_sata_phy_regs { + #define SPI_ADDR_VLD_94XX (1U << 1) + #define SPI_CTRL_SpiStart_94XX (1U << 0) + +-#define mv_ffc(x) ffz(x) +- + static inline int + mv_ffc64(u64 v) + { +- int i; +- i = mv_ffc((u32)v); +- if (i >= 0) +- return i; +- i = mv_ffc((u32)(v>>32)); +- +- if (i != 0) +- return 32 + i; +- +- return -1; ++ u64 x = ~v; ++ return x ? __ffs64(x) : -1; + } + + #define r_reg_set_enable(i) \ +--- a/drivers/scsi/mvsas/mv_sas.h ++++ b/drivers/scsi/mvsas/mv_sas.h +@@ -69,7 +69,7 @@ extern struct kmem_cache *mvs_task_list_ + #define DEV_IS_EXPANDER(type) \ + ((type == EDGE_DEV) || (type == FANOUT_DEV)) + +-#define bit(n) ((u32)1 << n) ++#define bit(n) ((u64)1 << n) + + #define for_each_phy(__lseq_mask, __mc, __lseq) \ + for ((__mc) = (__lseq_mask), (__lseq) = 0; \ diff --git a/queue-3.7/scsi-prevent-stack-buffer-overflow-in-host_reset.patch b/queue-3.7/scsi-prevent-stack-buffer-overflow-in-host_reset.patch new file mode 100644 index 00000000000..de9222366ab --- /dev/null +++ b/queue-3.7/scsi-prevent-stack-buffer-overflow-in-host_reset.patch @@ -0,0 +1,79 @@ +From 072f19b4bea31cdd482d79f805413f2f9ac9e233 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 15 Nov 2012 15:51:46 -0500 +Subject: SCSI: prevent stack buffer overflow in host_reset + +From: Sasha Levin + +commit 072f19b4bea31cdd482d79f805413f2f9ac9e233 upstream. + +store_host_reset() has tried to re-invent the wheel to compare sysfs strings. +Unfortunately it did so poorly and never bothered to check the input from +userspace before overwriting stack with it, so something simple as: + +echo "WoopsieWoopsie" > +/sys/devices/pseudo_0/adapter0/host0/scsi_host/host0/host_reset + +would result in: + +[ 316.310101] Kernel panic - not syncing: stack-protector: Kernel stack is corrupted in: ffffffff81f5bac7 +[ 316.310101] +[ 316.320051] Pid: 6655, comm: sh Tainted: G W 3.7.0-rc5-next-20121114-sasha-00016-g5c9d68d-dirty #129 +[ 316.320051] Call Trace: +[ 316.340058] pps pps0: PPS event at 1352918752.620355751 +[ 316.340062] pps pps0: capture assert seq #303 +[ 316.320051] [] panic+0xcd/0x1f4 +[ 316.320051] [] ? store_host_reset+0xd7/0x100 +[ 316.320051] [] __stack_chk_fail+0x16/0x20 +[ 316.320051] [] store_host_reset+0xd7/0x100 +[ 316.320051] [] dev_attr_store+0x13/0x30 +[ 316.320051] [] sysfs_write_file+0x101/0x170 +[ 316.320051] [] vfs_write+0xb8/0x180 +[ 316.320051] [] sys_write+0x50/0xa0 +[ 316.320051] [] tracesys+0xe1/0xe6 + +Fix this by uninventing whatever was going on there and just use sysfs_streq. + +Bug introduced by 29443691 ("[SCSI] scsi: Added support for adapter and +firmware reset"). + +[jejb: added necessary const to prevent compile warnings] +Signed-off-by: Sasha Levin +Signed-off-by: James Bottomley +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/scsi_sysfs.c | 11 ++++------- + 1 file changed, 4 insertions(+), 7 deletions(-) + +--- a/drivers/scsi/scsi_sysfs.c ++++ b/drivers/scsi/scsi_sysfs.c +@@ -247,11 +247,11 @@ show_shost_active_mode(struct device *de + + static DEVICE_ATTR(active_mode, S_IRUGO | S_IWUSR, show_shost_active_mode, NULL); + +-static int check_reset_type(char *str) ++static int check_reset_type(const char *str) + { +- if (strncmp(str, "adapter", 10) == 0) ++ if (sysfs_streq(str, "adapter")) + return SCSI_ADAPTER_RESET; +- else if (strncmp(str, "firmware", 10) == 0) ++ else if (sysfs_streq(str, "firmware")) + return SCSI_FIRMWARE_RESET; + else + return 0; +@@ -264,12 +264,9 @@ store_host_reset(struct device *dev, str + struct Scsi_Host *shost = class_to_shost(dev); + struct scsi_host_template *sht = shost->hostt; + int ret = -EINVAL; +- char str[10]; + int type; + +- sscanf(buf, "%s", str); +- type = check_reset_type(str); +- ++ type = check_reset_type(buf); + if (!type) + goto exit_store_host_reset; + diff --git a/queue-3.7/scsi-qla2xxx-change-in-setting-unloading-flag-and-fc-vports-logout-sequence-while-unloading-qla2xxx-driver.patch b/queue-3.7/scsi-qla2xxx-change-in-setting-unloading-flag-and-fc-vports-logout-sequence-while-unloading-qla2xxx-driver.patch new file mode 100644 index 00000000000..60f7d2a125a --- /dev/null +++ b/queue-3.7/scsi-qla2xxx-change-in-setting-unloading-flag-and-fc-vports-logout-sequence-while-unloading-qla2xxx-driver.patch @@ -0,0 +1,50 @@ +From 220d36b4c2d96446e88d561714829ec5801b4fc7 Mon Sep 17 00:00:00 2001 +From: Giridhar Malavali +Date: Wed, 21 Nov 2012 02:39:55 -0500 +Subject: SCSI: qla2xxx: Change in setting UNLOADING flag and FC vports logout sequence while unloading qla2xxx driver. + +From: Giridhar Malavali + +commit 220d36b4c2d96446e88d561714829ec5801b4fc7 upstream. + +Signed-off-by: Giridhar Malavali +Signed-off-by: Saurav Kashyap +Signed-off-by: James Bottomley +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/qla2xxx/qla_attr.c | 3 +-- + drivers/scsi/qla2xxx/qla_os.c | 3 +-- + 2 files changed, 2 insertions(+), 4 deletions(-) + +--- a/drivers/scsi/qla2xxx/qla_attr.c ++++ b/drivers/scsi/qla2xxx/qla_attr.c +@@ -1615,8 +1615,7 @@ qla2x00_terminate_rport_io(struct fc_rpo + * At this point all fcport's software-states are cleared. Perform any + * final cleanup of firmware resources (PCBs and XCBs). + */ +- if (fcport->loop_id != FC_NO_LOOP_ID && +- !test_bit(UNLOADING, &fcport->vha->dpc_flags)) { ++ if (fcport->loop_id != FC_NO_LOOP_ID) { + if (IS_FWI2_CAPABLE(fcport->vha->hw)) + fcport->vha->hw->isp_ops->fabric_logout(fcport->vha, + fcport->loop_id, fcport->d_id.b.domain, +--- a/drivers/scsi/qla2xxx/qla_os.c ++++ b/drivers/scsi/qla2xxx/qla_os.c +@@ -2755,6 +2755,7 @@ qla2x00_remove_one(struct pci_dev *pdev) + + ha->flags.host_shutting_down = 1; + ++ set_bit(UNLOADING, &base_vha->dpc_flags); + mutex_lock(&ha->vport_lock); + while (ha->cur_vport_count) { + struct Scsi_Host *scsi_host; +@@ -2784,8 +2785,6 @@ qla2x00_remove_one(struct pci_dev *pdev) + "Error while clearing DRV-Presence.\n"); + } + +- set_bit(UNLOADING, &base_vha->dpc_flags); +- + qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16); + + qla2x00_dfs_remove(base_vha); diff --git a/queue-3.7/scsi-qla2xxx-free-rsp_data-even-on-error-in-qla2x00_process_loopback.patch b/queue-3.7/scsi-qla2xxx-free-rsp_data-even-on-error-in-qla2x00_process_loopback.patch new file mode 100644 index 00000000000..34cfcdccae5 --- /dev/null +++ b/queue-3.7/scsi-qla2xxx-free-rsp_data-even-on-error-in-qla2x00_process_loopback.patch @@ -0,0 +1,56 @@ +From 9bceab4e08c5e329e9def7fe1cab41c467236517 Mon Sep 17 00:00:00 2001 +From: Steve Hodgson +Date: Wed, 21 Nov 2012 02:39:56 -0500 +Subject: SCSI: qla2xxx: Free rsp_data even on error in qla2x00_process_loopback() + +From: Steve Hodgson + +commit 9bceab4e08c5e329e9def7fe1cab41c467236517 upstream. + +Signed-off-by: Steve Hodgson +Signed-off-by: Armen Baloyan +Signed-off-by: Saurav Kashyap +Signed-off-by: James Bottomley +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/qla2xxx/qla_bsg.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/drivers/scsi/qla2xxx/qla_bsg.c ++++ b/drivers/scsi/qla2xxx/qla_bsg.c +@@ -743,7 +743,7 @@ qla2x00_process_loopback(struct fc_bsg_j + ql_log(ql_log_warn, vha, 0x701f, + "Get port config failed.\n"); + rval = -EPERM; +- goto done_free_dma_req; ++ goto done_free_dma_rsp; + } + + ql_dbg(ql_dbg_user, vha, 0x70c0, +@@ -762,7 +762,7 @@ qla2x00_process_loopback(struct fc_bsg_j + + if (rval) { + rval = -EPERM; +- goto done_free_dma_req; ++ goto done_free_dma_rsp; + } + + type = "FC_BSG_HST_VENDOR_LOOPBACK"; +@@ -795,7 +795,7 @@ qla2x00_process_loopback(struct fc_bsg_j + } + + rval = -EIO; +- goto done_free_dma_req; ++ goto done_free_dma_rsp; + } + } else { + type = "FC_BSG_HST_VENDOR_LOOPBACK"; +@@ -830,6 +830,7 @@ qla2x00_process_loopback(struct fc_bsg_j + fw_sts_ptr += sizeof(response); + *fw_sts_ptr = command_sent; + ++done_free_dma_rsp: + dma_free_coherent(&ha->pdev->dev, rsp_data_len, + rsp_data, rsp_data_dma); + done_free_dma_req: diff --git a/queue-3.7/scsi-qla2xxx-properly-set-result-field-of-bsg_job-reply-structure-for-success-and-failure.patch b/queue-3.7/scsi-qla2xxx-properly-set-result-field-of-bsg_job-reply-structure-for-success-and-failure.patch new file mode 100644 index 00000000000..9c5bb0665c5 --- /dev/null +++ b/queue-3.7/scsi-qla2xxx-properly-set-result-field-of-bsg_job-reply-structure-for-success-and-failure.patch @@ -0,0 +1,235 @@ +From 63ea923a97cb0d78efcbbd229950e101588f0ddb Mon Sep 17 00:00:00 2001 +From: Armen Baloyan +Date: Wed, 21 Nov 2012 02:39:53 -0500 +Subject: SCSI: qla2xxx: Properly set result field of bsg_job reply structure for success and failure. + +From: Armen Baloyan + +commit 63ea923a97cb0d78efcbbd229950e101588f0ddb upstream. + +FC transport on receiving bsg_job submission failure, calls bsg_job->job_done() +and sets the bsg_job->reply->result the returned value. In contrast, when the +success code (0) is returned fc transport doesn't call bsg_job->job_done() and +doesn't populate bsg_job->reply->result. + +Signed-off-by: Steve Hodgson +Signed-off-by: Armen Baloyan +Signed-off-by: Saurav Kashyap +Signed-off-by: James Bottomley +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/qla2xxx/qla_bsg.c | 65 +++++++++++++++-------------------------- + 1 file changed, 24 insertions(+), 41 deletions(-) + +--- a/drivers/scsi/qla2xxx/qla_bsg.c ++++ b/drivers/scsi/qla2xxx/qla_bsg.c +@@ -219,7 +219,8 @@ qla24xx_proc_fcp_prio_cfg_cmd(struct fc_ + break; + } + exit_fcp_prio_cfg: +- bsg_job->job_done(bsg_job); ++ if (!ret) ++ bsg_job->job_done(bsg_job); + return ret; + } + +@@ -741,7 +742,6 @@ qla2x00_process_loopback(struct fc_bsg_j + if (qla81xx_get_port_config(vha, config)) { + ql_log(ql_log_warn, vha, 0x701f, + "Get port config failed.\n"); +- bsg_job->reply->result = (DID_ERROR << 16); + rval = -EPERM; + goto done_free_dma_req; + } +@@ -761,7 +761,6 @@ qla2x00_process_loopback(struct fc_bsg_j + new_config, elreq.options); + + if (rval) { +- bsg_job->reply->result = (DID_ERROR << 16); + rval = -EPERM; + goto done_free_dma_req; + } +@@ -795,7 +794,6 @@ qla2x00_process_loopback(struct fc_bsg_j + "MPI reset failed.\n"); + } + +- bsg_job->reply->result = (DID_ERROR << 16); + rval = -EIO; + goto done_free_dma_req; + } +@@ -812,33 +810,25 @@ qla2x00_process_loopback(struct fc_bsg_j + ql_log(ql_log_warn, vha, 0x702c, + "Vendor request %s failed.\n", type); + +- fw_sts_ptr = ((uint8_t *)bsg_job->req->sense) + +- sizeof(struct fc_bsg_reply); +- +- memcpy(fw_sts_ptr, response, sizeof(response)); +- fw_sts_ptr += sizeof(response); +- *fw_sts_ptr = command_sent; + rval = 0; + bsg_job->reply->result = (DID_ERROR << 16); ++ bsg_job->reply->reply_payload_rcv_len = 0; + } else { + ql_dbg(ql_dbg_user, vha, 0x702d, + "Vendor request %s completed.\n", type); +- +- bsg_job->reply_len = sizeof(struct fc_bsg_reply) + +- sizeof(response) + sizeof(uint8_t); +- bsg_job->reply->reply_payload_rcv_len = +- bsg_job->reply_payload.payload_len; +- fw_sts_ptr = ((uint8_t *)bsg_job->req->sense) + +- sizeof(struct fc_bsg_reply); +- memcpy(fw_sts_ptr, response, sizeof(response)); +- fw_sts_ptr += sizeof(response); +- *fw_sts_ptr = command_sent; +- bsg_job->reply->result = DID_OK; ++ bsg_job->reply->result = (DID_OK << 16); + sg_copy_from_buffer(bsg_job->reply_payload.sg_list, + bsg_job->reply_payload.sg_cnt, rsp_data, + rsp_data_len); + } +- bsg_job->job_done(bsg_job); ++ ++ bsg_job->reply_len = sizeof(struct fc_bsg_reply) + ++ sizeof(response) + sizeof(uint8_t); ++ fw_sts_ptr = ((uint8_t *)bsg_job->req->sense) + ++ sizeof(struct fc_bsg_reply); ++ memcpy(fw_sts_ptr, response, sizeof(response)); ++ fw_sts_ptr += sizeof(response); ++ *fw_sts_ptr = command_sent; + + dma_free_coherent(&ha->pdev->dev, rsp_data_len, + rsp_data, rsp_data_dma); +@@ -853,6 +843,8 @@ done_unmap_req_sg: + dma_unmap_sg(&ha->pdev->dev, + bsg_job->request_payload.sg_list, + bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE); ++ if (!rval) ++ bsg_job->job_done(bsg_job); + return rval; + } + +@@ -877,16 +869,15 @@ qla84xx_reset(struct fc_bsg_job *bsg_job + if (rval) { + ql_log(ql_log_warn, vha, 0x7030, + "Vendor request 84xx reset failed.\n"); +- rval = 0; +- bsg_job->reply->result = (DID_ERROR << 16); ++ rval = (DID_ERROR << 16); + + } else { + ql_dbg(ql_dbg_user, vha, 0x7031, + "Vendor request 84xx reset completed.\n"); + bsg_job->reply->result = DID_OK; ++ bsg_job->job_done(bsg_job); + } + +- bsg_job->job_done(bsg_job); + return rval; + } + +@@ -976,8 +967,7 @@ qla84xx_updatefw(struct fc_bsg_job *bsg_ + ql_log(ql_log_warn, vha, 0x7037, + "Vendor request 84xx updatefw failed.\n"); + +- rval = 0; +- bsg_job->reply->result = (DID_ERROR << 16); ++ rval = (DID_ERROR << 16); + } else { + ql_dbg(ql_dbg_user, vha, 0x7038, + "Vendor request 84xx updatefw completed.\n"); +@@ -986,7 +976,6 @@ qla84xx_updatefw(struct fc_bsg_job *bsg_ + bsg_job->reply->result = DID_OK; + } + +- bsg_job->job_done(bsg_job); + dma_pool_free(ha->s_dma_pool, mn, mn_dma); + + done_free_fw_buf: +@@ -996,6 +985,8 @@ done_unmap_sg: + dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list, + bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE); + ++ if (!rval) ++ bsg_job->job_done(bsg_job); + return rval; + } + +@@ -1163,8 +1154,7 @@ qla84xx_mgmt_cmd(struct fc_bsg_job *bsg_ + ql_log(ql_log_warn, vha, 0x7043, + "Vendor request 84xx mgmt failed.\n"); + +- rval = 0; +- bsg_job->reply->result = (DID_ERROR << 16); ++ rval = (DID_ERROR << 16); + + } else { + ql_dbg(ql_dbg_user, vha, 0x7044, +@@ -1184,8 +1174,6 @@ qla84xx_mgmt_cmd(struct fc_bsg_job *bsg_ + } + } + +- bsg_job->job_done(bsg_job); +- + done_unmap_sg: + if (mgmt_b) + dma_free_coherent(&ha->pdev->dev, data_len, mgmt_b, mgmt_dma); +@@ -1200,6 +1188,8 @@ done_unmap_sg: + exit_mgmt: + dma_pool_free(ha->s_dma_pool, mn, mn_dma); + ++ if (!rval) ++ bsg_job->job_done(bsg_job); + return rval; + } + +@@ -1276,9 +1266,7 @@ qla24xx_iidma(struct fc_bsg_job *bsg_job + fcport->port_name[3], fcport->port_name[4], + fcport->port_name[5], fcport->port_name[6], + fcport->port_name[7], rval, fcport->fp_speed, mb[0], mb[1]); +- rval = 0; +- bsg_job->reply->result = (DID_ERROR << 16); +- ++ rval = (DID_ERROR << 16); + } else { + if (!port_param->mode) { + bsg_job->reply_len = sizeof(struct fc_bsg_reply) + +@@ -1292,9 +1280,9 @@ qla24xx_iidma(struct fc_bsg_job *bsg_job + } + + bsg_job->reply->result = DID_OK; ++ bsg_job->job_done(bsg_job); + } + +- bsg_job->job_done(bsg_job); + return rval; + } + +@@ -1887,8 +1875,6 @@ qla2x00_process_vendor_specific(struct f + return qla24xx_process_bidir_cmd(bsg_job); + + default: +- bsg_job->reply->result = (DID_ERROR << 16); +- bsg_job->job_done(bsg_job); + return -ENOSYS; + } + } +@@ -1919,8 +1905,6 @@ qla24xx_bsg_request(struct fc_bsg_job *b + ql_dbg(ql_dbg_user, vha, 0x709f, + "BSG: ISP abort active/needed -- cmd=%d.\n", + bsg_job->request->msgcode); +- bsg_job->reply->result = (DID_ERROR << 16); +- bsg_job->job_done(bsg_job); + return -EBUSY; + } + +@@ -1943,7 +1927,6 @@ qla24xx_bsg_request(struct fc_bsg_job *b + case FC_BSG_RPT_CT: + default: + ql_log(ql_log_warn, vha, 0x705a, "Unsupported BSG request.\n"); +- bsg_job->reply->result = ret; + break; + } + return ret; diff --git a/queue-3.7/scsi-qla2xxx-test-and-clear-fcport_update_needed-atomically.patch b/queue-3.7/scsi-qla2xxx-test-and-clear-fcport_update_needed-atomically.patch new file mode 100644 index 00000000000..613f5822416 --- /dev/null +++ b/queue-3.7/scsi-qla2xxx-test-and-clear-fcport_update_needed-atomically.patch @@ -0,0 +1,55 @@ +From a394aac88506159e047630fc90dc2242568382d8 Mon Sep 17 00:00:00 2001 +From: David Jeffery +Date: Wed, 21 Nov 2012 02:39:54 -0500 +Subject: SCSI: qla2xxx: Test and clear FCPORT_UPDATE_NEEDED atomically. + +From: David Jeffery + +commit a394aac88506159e047630fc90dc2242568382d8 upstream. + +When the qla2xxx driver loses access to multiple, remote ports, there is a race +condition which can occur which will keep the request stuck on a scsi request +queue indefinitely. + +This bad state occurred do to a race condition with how the FCPORT_UPDATE_NEEDED +bit is set in qla2x00_schedule_rport_del(), and how it is cleared in +qla2x00_do_dpc(). The problem port has its drport pointer set, but it has never +been processed by the driver to inform the fc transport that the port has been +lost. qla2x00_schedule_rport_del() sets drport, and then sets the +FCPORT_UPDATE_NEEDED bit. In qla2x00_do_dpc(), the port lists are walked and +any drport pointer is handled and the fc transport informed of the port loss, +then the FCPORT_UPDATE_NEEDED bit is cleared. This leaves a race where the +dpc thread is processing one port removal, another port removal is marked +with a call to qla2x00_schedule_rport_del(), and the dpc thread clears the +bit for both removals, even though only the first removal was actually +handled. Until another event occurs to set FCPORT_UPDATE_NEEDED, the later +port removal is never finished and qla2xxx stays in a bad state which causes +requests to become stuck on request queues. + +This patch updates the driver to test and clear FCPORT_UPDATE_NEEDED +atomically. This ensures the port state changes are processed and not lost. + +Signed-off-by: David Jeffery +Signed-off-by: Chad Dupuis +Signed-off-by: Saurav Kashyap +Signed-off-by: James Bottomley +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/qla2xxx/qla_os.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/scsi/qla2xxx/qla_os.c ++++ b/drivers/scsi/qla2xxx/qla_os.c +@@ -4505,9 +4505,9 @@ qla2x00_do_dpc(void *data) + "ISP abort end.\n"); + } + +- if (test_bit(FCPORT_UPDATE_NEEDED, &base_vha->dpc_flags)) { ++ if (test_and_clear_bit(FCPORT_UPDATE_NEEDED, ++ &base_vha->dpc_flags)) { + qla2x00_update_fcports(base_vha); +- clear_bit(FCPORT_UPDATE_NEEDED, &base_vha->dpc_flags); + } + + if (test_bit(SCR_PENDING, &base_vha->dpc_flags)) { diff --git a/queue-3.7/series b/queue-3.7/series index cae04d08500..81c091229ea 100644 --- a/queue-3.7/series +++ b/queue-3.7/series @@ -28,3 +28,14 @@ watchdog-fix-disable-enable-regression.patch asoc-wm8994-use-the-same-dcs-codes-for-all-wm1811-variants.patch asoc-sigmadsp-fix-endianness-conversion-issue.patch regulator-s2mps11-fix-ramp-delay-value-shift-operation.patch +scsi-mvsas-fix-undefined-bit-shift.patch +scsi-prevent-stack-buffer-overflow-in-host_reset.patch +scsi-qla2xxx-properly-set-result-field-of-bsg_job-reply-structure-for-success-and-failure.patch +scsi-qla2xxx-test-and-clear-fcport_update_needed-atomically.patch +scsi-qla2xxx-change-in-setting-unloading-flag-and-fc-vports-logout-sequence-while-unloading-qla2xxx-driver.patch +scsi-qla2xxx-free-rsp_data-even-on-error-in-qla2x00_process_loopback.patch +iscsi-target-fix-bug-in-handling-of-expstatsn-ack-during-u32-wrap-around.patch +iscsi-target-always-send-a-response-before-terminating-iscsi-connection.patch +iscsit-use-gfp_atomic-under-spin-lock.patch +qla2xxx-look-up-lun-for-abort-requests.patch +sata_promise-fix-hardreset-lockdep-error.patch