--- /dev/null
+From 1c5c12c666fda27c7c494b34934a0a0631a48130 Mon Sep 17 00:00:00 2001
+From: Roland Dreier <roland@purestorage.com>
+Date: Mon, 5 Nov 2012 18:02:42 -0800
+Subject: iscsi-target: Always send a response before terminating iSCSI connection
+
+From: Roland Dreier <roland@purestorage.com>
+
+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 <roland@purestorage.com>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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) {
--- /dev/null
+From 64c13330a38935120501b19c97a3e6095747c7a1 Mon Sep 17 00:00:00 2001
+From: Steve Hodgson <steve@purestorage.com>
+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 <steve@purestorage.com>
+
+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 <steve@purestorage.com>
+Signed-off-by: Roland Dreier <roland@purestorage.com>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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)) {
--- /dev/null
+From 3c989d7603872bf878840f7ce3ea49b73bea4c6c Mon Sep 17 00:00:00 2001
+From: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
+Date: Fri, 23 Nov 2012 12:07:39 +0800
+Subject: iscsit: use GFP_ATOMIC under spin lock
+
+From: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
+
+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 <yongjun_wei@trendmicro.com.cn>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
--- /dev/null
+From 06e97b489006f28e23bb028febfa1c01c266d676 Mon Sep 17 00:00:00 2001
+From: Steve Hodgson <steve@purestorage.com>
+Date: Fri, 16 Nov 2012 08:06:17 -0800
+Subject: qla2xxx: Look up LUN for abort requests
+
+From: Steve Hodgson <steve@purestorage.com>
+
+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 <steve@purestorage.com>
+Signed-off-by: Roland Dreier <roland@purestorage.com>
+Signed-off-by: Nicholas Bellinger <nab@risingtidesystems.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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,
--- /dev/null
+From 3100d49d3cd236443faae9d81137c81b22d36003 Mon Sep 17 00:00:00 2001
+From: Mikael Pettersson <mikpe@it.uu.se>
+Date: Sun, 16 Sep 2012 20:53:43 +0200
+Subject: sata_promise: fix hardreset lockdep error
+
+From: Mikael Pettersson <mikpe@it.uu.se>
+
+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 <mikpe@it.uu.se>
+Tested-by: Adko Branil <adkobranil@yahoo.com>
+Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);
--- /dev/null
+From beecadea1b8d67f591b13f7099559f32f3fd601d Mon Sep 17 00:00:00 2001
+From: Xi Wang <xi.wang@gmail.com>
+Date: Fri, 16 Nov 2012 14:40:03 -0500
+Subject: SCSI: mvsas: fix undefined bit shift
+
+From: Xi Wang <xi.wang@gmail.com>
+
+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 <xi.wang@gmail.com>
+Acked-by: Xiangliang Yu <yuxiangl@marvell.com>
+Signed-off-by: James Bottomley <JBottomley@Parallels.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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; \
--- /dev/null
+From 072f19b4bea31cdd482d79f805413f2f9ac9e233 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sasha.levin@oracle.com>
+Date: Thu, 15 Nov 2012 15:51:46 -0500
+Subject: SCSI: prevent stack buffer overflow in host_reset
+
+From: Sasha Levin <sasha.levin@oracle.com>
+
+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] [<ffffffff83b3856b>] panic+0xcd/0x1f4
+[ 316.320051] [<ffffffff81f5bac7>] ? store_host_reset+0xd7/0x100
+[ 316.320051] [<ffffffff8110b996>] __stack_chk_fail+0x16/0x20
+[ 316.320051] [<ffffffff81f5bac7>] store_host_reset+0xd7/0x100
+[ 316.320051] [<ffffffff81e55bb3>] dev_attr_store+0x13/0x30
+[ 316.320051] [<ffffffff812f7db1>] sysfs_write_file+0x101/0x170
+[ 316.320051] [<ffffffff8127acc8>] vfs_write+0xb8/0x180
+[ 316.320051] [<ffffffff8127ae80>] sys_write+0x50/0xa0
+[ 316.320051] [<ffffffff83c03418>] 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 <sasha.levin@oracle.com>
+Signed-off-by: James Bottomley <JBottomley@Parallels.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
+
--- /dev/null
+From 220d36b4c2d96446e88d561714829ec5801b4fc7 Mon Sep 17 00:00:00 2001
+From: Giridhar Malavali <giridhar.malavali@qlogic.com>
+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 <giridhar.malavali@qlogic.com>
+
+commit 220d36b4c2d96446e88d561714829ec5801b4fc7 upstream.
+
+Signed-off-by: Giridhar Malavali <giridhar.malavali@qlogic.com>
+Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
+Signed-off-by: James Bottomley <JBottomley@Parallels.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);
--- /dev/null
+From 9bceab4e08c5e329e9def7fe1cab41c467236517 Mon Sep 17 00:00:00 2001
+From: Steve Hodgson <steve@purestorage.com>
+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 <steve@purestorage.com>
+
+commit 9bceab4e08c5e329e9def7fe1cab41c467236517 upstream.
+
+Signed-off-by: Steve Hodgson <steve@purestorage.com>
+Signed-off-by: Armen Baloyan <armen.baloyan@qlogic.com>
+Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
+Signed-off-by: James Bottomley <JBottomley@Parallels.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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:
--- /dev/null
+From 63ea923a97cb0d78efcbbd229950e101588f0ddb Mon Sep 17 00:00:00 2001
+From: Armen Baloyan <armen.baloyan@qlogic.com>
+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 <armen.baloyan@qlogic.com>
+
+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 <steve@purestorage.com>
+Signed-off-by: Armen Baloyan <armen.baloyan@qlogic.com>
+Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
+Signed-off-by: James Bottomley <JBottomley@Parallels.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
--- /dev/null
+From a394aac88506159e047630fc90dc2242568382d8 Mon Sep 17 00:00:00 2001
+From: David Jeffery <djeffery@redhat.com>
+Date: Wed, 21 Nov 2012 02:39:54 -0500
+Subject: SCSI: qla2xxx: Test and clear FCPORT_UPDATE_NEEDED atomically.
+
+From: David Jeffery <djeffery@redhat.com>
+
+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 <djeffery@redhat.com>
+Signed-off-by: Chad Dupuis <chad.dupuis@qlogic.com>
+Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
+Signed-off-by: James Bottomley <JBottomley@Parallels.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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)) {
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