diff options
43 files changed, 424 insertions, 391 deletions
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index 8d12017b9893..4470630dd545 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c | |||
@@ -2687,6 +2687,8 @@ mptctl_hp_targetinfo(unsigned long arg) | |||
2687 | __FILE__, __LINE__, iocnum); | 2687 | __FILE__, __LINE__, iocnum); |
2688 | return -ENODEV; | 2688 | return -ENODEV; |
2689 | } | 2689 | } |
2690 | if (karg.hdr.id >= MPT_MAX_FC_DEVICES) | ||
2691 | return -EINVAL; | ||
2690 | dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_hp_targetinfo called.\n", | 2692 | dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_hp_targetinfo called.\n", |
2691 | ioc->name)); | 2693 | ioc->name)); |
2692 | 2694 | ||
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index d5135efbf9cd..e29f9b8fd66d 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile | |||
@@ -180,7 +180,6 @@ ncr53c8xx-flags-$(CONFIG_SCSI_ZALON) \ | |||
180 | CFLAGS_ncr53c8xx.o := $(ncr53c8xx-flags-y) $(ncr53c8xx-flags-m) | 180 | CFLAGS_ncr53c8xx.o := $(ncr53c8xx-flags-y) $(ncr53c8xx-flags-m) |
181 | zalon7xx-objs := zalon.o ncr53c8xx.o | 181 | zalon7xx-objs := zalon.o ncr53c8xx.o |
182 | NCR_Q720_mod-objs := NCR_Q720.o ncr53c8xx.o | 182 | NCR_Q720_mod-objs := NCR_Q720.o ncr53c8xx.o |
183 | oktagon_esp_mod-objs := oktagon_esp.o oktagon_io.o | ||
184 | 183 | ||
185 | # Files generated that shall be removed upon make clean | 184 | # Files generated that shall be removed upon make clean |
186 | clean-files := 53c700_d.h 53c700_u.h | 185 | clean-files := 53c700_d.h 53c700_u.h |
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index b3b931ab77eb..2664ea0df35f 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c | |||
@@ -1693,8 +1693,10 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1693 | * Map in the registers from the adapter. | 1693 | * Map in the registers from the adapter. |
1694 | */ | 1694 | */ |
1695 | aac->base_size = AAC_MIN_FOOTPRINT_SIZE; | 1695 | aac->base_size = AAC_MIN_FOOTPRINT_SIZE; |
1696 | if ((*aac_drivers[index].init)(aac)) | 1696 | if ((*aac_drivers[index].init)(aac)) { |
1697 | error = -ENODEV; | ||
1697 | goto out_unmap; | 1698 | goto out_unmap; |
1699 | } | ||
1698 | 1700 | ||
1699 | if (aac->sync_mode) { | 1701 | if (aac->sync_mode) { |
1700 | if (aac_sync_mode) | 1702 | if (aac_sync_mode) |
diff --git a/drivers/scsi/aic7xxx/aiclib.c b/drivers/scsi/aic7xxx/aiclib.c deleted file mode 100644 index 828ae3d9a510..000000000000 --- a/drivers/scsi/aic7xxx/aiclib.c +++ /dev/null | |||
@@ -1,34 +0,0 @@ | |||
1 | /* | ||
2 | * Implementation of Utility functions for all SCSI device types. | ||
3 | * | ||
4 | * Copyright (c) 1997, 1998, 1999 Justin T. Gibbs. | ||
5 | * Copyright (c) 1997, 1998 Kenneth D. Merry. | ||
6 | * All rights reserved. | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions | ||
10 | * are met: | ||
11 | * 1. Redistributions of source code must retain the above copyright | ||
12 | * notice, this list of conditions, and the following disclaimer, | ||
13 | * without modification, immediately at the beginning of the file. | ||
14 | * 2. The name of the author may not be used to endorse or promote products | ||
15 | * derived from this software without specific prior written permission. | ||
16 | * | ||
17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | ||
18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR | ||
21 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
27 | * SUCH DAMAGE. | ||
28 | * | ||
29 | * $FreeBSD: src/sys/cam/scsi/scsi_all.c,v 1.38 2002/09/23 04:56:35 mjacob Exp $ | ||
30 | * $Id$ | ||
31 | */ | ||
32 | |||
33 | #include "aiclib.h" | ||
34 | |||
diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c index 8e2f767147cb..5a645b8b9af1 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_io.c +++ b/drivers/scsi/bnx2fc/bnx2fc_io.c | |||
@@ -1889,6 +1889,7 @@ void bnx2fc_process_scsi_cmd_compl(struct bnx2fc_cmd *io_req, | |||
1889 | /* we will not receive ABTS response for this IO */ | 1889 | /* we will not receive ABTS response for this IO */ |
1890 | BNX2FC_IO_DBG(io_req, "Timer context finished processing " | 1890 | BNX2FC_IO_DBG(io_req, "Timer context finished processing " |
1891 | "this scsi cmd\n"); | 1891 | "this scsi cmd\n"); |
1892 | return; | ||
1892 | } | 1893 | } |
1893 | 1894 | ||
1894 | /* Cancel the timeout_work, as we received IO completion */ | 1895 | /* Cancel the timeout_work, as we received IO completion */ |
diff --git a/drivers/scsi/csiostor/csio_lnode.c b/drivers/scsi/csiostor/csio_lnode.c index 1c53179523b8..cc5611efc7a9 100644 --- a/drivers/scsi/csiostor/csio_lnode.c +++ b/drivers/scsi/csiostor/csio_lnode.c | |||
@@ -114,7 +114,7 @@ static enum csio_ln_ev fwevt_to_lnevt[] = { | |||
114 | static struct csio_lnode * | 114 | static struct csio_lnode * |
115 | csio_ln_lookup_by_portid(struct csio_hw *hw, uint8_t portid) | 115 | csio_ln_lookup_by_portid(struct csio_hw *hw, uint8_t portid) |
116 | { | 116 | { |
117 | struct csio_lnode *ln = hw->rln; | 117 | struct csio_lnode *ln; |
118 | struct list_head *tmp; | 118 | struct list_head *tmp; |
119 | 119 | ||
120 | /* Match siblings lnode with portid */ | 120 | /* Match siblings lnode with portid */ |
diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index acd7fb356f01..12dc7100bb4c 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c | |||
@@ -876,6 +876,11 @@ static void alua_rtpg_work(struct work_struct *work) | |||
876 | 876 | ||
877 | /** | 877 | /** |
878 | * alua_rtpg_queue() - cause RTPG to be submitted asynchronously | 878 | * alua_rtpg_queue() - cause RTPG to be submitted asynchronously |
879 | * @pg: ALUA port group associated with @sdev. | ||
880 | * @sdev: SCSI device for which to submit an RTPG. | ||
881 | * @qdata: Information about the callback to invoke after the RTPG. | ||
882 | * @force: Whether or not to submit an RTPG if a work item that will submit an | ||
883 | * RTPG already has been scheduled. | ||
879 | * | 884 | * |
880 | * Returns true if and only if alua_rtpg_work() will be called asynchronously. | 885 | * Returns true if and only if alua_rtpg_work() will be called asynchronously. |
881 | * That function is responsible for calling @qdata->fn(). | 886 | * That function is responsible for calling @qdata->fn(). |
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index ffd1030b6c91..7649d63a1b8d 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c | |||
@@ -333,8 +333,6 @@ static void scsi_host_dev_release(struct device *dev) | |||
333 | if (shost->work_q) | 333 | if (shost->work_q) |
334 | destroy_workqueue(shost->work_q); | 334 | destroy_workqueue(shost->work_q); |
335 | 335 | ||
336 | destroy_rcu_head(&shost->rcu); | ||
337 | |||
338 | if (shost->shost_state == SHOST_CREATED) { | 336 | if (shost->shost_state == SHOST_CREATED) { |
339 | /* | 337 | /* |
340 | * Free the shost_dev device name here if scsi_host_alloc() | 338 | * Free the shost_dev device name here if scsi_host_alloc() |
@@ -403,7 +401,6 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) | |||
403 | INIT_LIST_HEAD(&shost->starved_list); | 401 | INIT_LIST_HEAD(&shost->starved_list); |
404 | init_waitqueue_head(&shost->host_wait); | 402 | init_waitqueue_head(&shost->host_wait); |
405 | mutex_init(&shost->scan_mutex); | 403 | mutex_init(&shost->scan_mutex); |
406 | init_rcu_head(&shost->rcu); | ||
407 | 404 | ||
408 | index = ida_simple_get(&host_index_ida, 0, 0, GFP_KERNEL); | 405 | index = ida_simple_get(&host_index_ida, 0, 0, GFP_KERNEL); |
409 | if (index < 0) | 406 | if (index < 0) |
@@ -476,6 +473,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) | |||
476 | shost->dma_boundary = 0xffffffff; | 473 | shost->dma_boundary = 0xffffffff; |
477 | 474 | ||
478 | shost->use_blk_mq = scsi_use_blk_mq; | 475 | shost->use_blk_mq = scsi_use_blk_mq; |
476 | shost->use_blk_mq = scsi_use_blk_mq || shost->hostt->force_blk_mq; | ||
479 | 477 | ||
480 | device_initialize(&shost->shost_gendev); | 478 | device_initialize(&shost->shost_gendev); |
481 | dev_set_name(&shost->shost_gendev, "host%d", shost->host_no); | 479 | dev_set_name(&shost->shost_gendev, "host%d", shost->host_no); |
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 5293e6827ce5..3a9eca163db8 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c | |||
@@ -1045,11 +1045,7 @@ static void set_performant_mode(struct ctlr_info *h, struct CommandList *c, | |||
1045 | c->busaddr |= 1 | (h->blockFetchTable[c->Header.SGList] << 1); | 1045 | c->busaddr |= 1 | (h->blockFetchTable[c->Header.SGList] << 1); |
1046 | if (unlikely(!h->msix_vectors)) | 1046 | if (unlikely(!h->msix_vectors)) |
1047 | return; | 1047 | return; |
1048 | if (likely(reply_queue == DEFAULT_REPLY_QUEUE)) | 1048 | c->Header.ReplyQueue = reply_queue; |
1049 | c->Header.ReplyQueue = | ||
1050 | raw_smp_processor_id() % h->nreply_queues; | ||
1051 | else | ||
1052 | c->Header.ReplyQueue = reply_queue % h->nreply_queues; | ||
1053 | } | 1049 | } |
1054 | } | 1050 | } |
1055 | 1051 | ||
@@ -1063,10 +1059,7 @@ static void set_ioaccel1_performant_mode(struct ctlr_info *h, | |||
1063 | * Tell the controller to post the reply to the queue for this | 1059 | * Tell the controller to post the reply to the queue for this |
1064 | * processor. This seems to give the best I/O throughput. | 1060 | * processor. This seems to give the best I/O throughput. |
1065 | */ | 1061 | */ |
1066 | if (likely(reply_queue == DEFAULT_REPLY_QUEUE)) | 1062 | cp->ReplyQueue = reply_queue; |
1067 | cp->ReplyQueue = smp_processor_id() % h->nreply_queues; | ||
1068 | else | ||
1069 | cp->ReplyQueue = reply_queue % h->nreply_queues; | ||
1070 | /* | 1063 | /* |
1071 | * Set the bits in the address sent down to include: | 1064 | * Set the bits in the address sent down to include: |
1072 | * - performant mode bit (bit 0) | 1065 | * - performant mode bit (bit 0) |
@@ -1087,10 +1080,7 @@ static void set_ioaccel2_tmf_performant_mode(struct ctlr_info *h, | |||
1087 | /* Tell the controller to post the reply to the queue for this | 1080 | /* Tell the controller to post the reply to the queue for this |
1088 | * processor. This seems to give the best I/O throughput. | 1081 | * processor. This seems to give the best I/O throughput. |
1089 | */ | 1082 | */ |
1090 | if (likely(reply_queue == DEFAULT_REPLY_QUEUE)) | 1083 | cp->reply_queue = reply_queue; |
1091 | cp->reply_queue = smp_processor_id() % h->nreply_queues; | ||
1092 | else | ||
1093 | cp->reply_queue = reply_queue % h->nreply_queues; | ||
1094 | /* Set the bits in the address sent down to include: | 1084 | /* Set the bits in the address sent down to include: |
1095 | * - performant mode bit not used in ioaccel mode 2 | 1085 | * - performant mode bit not used in ioaccel mode 2 |
1096 | * - pull count (bits 0-3) | 1086 | * - pull count (bits 0-3) |
@@ -1109,10 +1099,7 @@ static void set_ioaccel2_performant_mode(struct ctlr_info *h, | |||
1109 | * Tell the controller to post the reply to the queue for this | 1099 | * Tell the controller to post the reply to the queue for this |
1110 | * processor. This seems to give the best I/O throughput. | 1100 | * processor. This seems to give the best I/O throughput. |
1111 | */ | 1101 | */ |
1112 | if (likely(reply_queue == DEFAULT_REPLY_QUEUE)) | 1102 | cp->reply_queue = reply_queue; |
1113 | cp->reply_queue = smp_processor_id() % h->nreply_queues; | ||
1114 | else | ||
1115 | cp->reply_queue = reply_queue % h->nreply_queues; | ||
1116 | /* | 1103 | /* |
1117 | * Set the bits in the address sent down to include: | 1104 | * Set the bits in the address sent down to include: |
1118 | * - performant mode bit not used in ioaccel mode 2 | 1105 | * - performant mode bit not used in ioaccel mode 2 |
@@ -1157,6 +1144,8 @@ static void __enqueue_cmd_and_start_io(struct ctlr_info *h, | |||
1157 | { | 1144 | { |
1158 | dial_down_lockup_detection_during_fw_flash(h, c); | 1145 | dial_down_lockup_detection_during_fw_flash(h, c); |
1159 | atomic_inc(&h->commands_outstanding); | 1146 | atomic_inc(&h->commands_outstanding); |
1147 | |||
1148 | reply_queue = h->reply_map[raw_smp_processor_id()]; | ||
1160 | switch (c->cmd_type) { | 1149 | switch (c->cmd_type) { |
1161 | case CMD_IOACCEL1: | 1150 | case CMD_IOACCEL1: |
1162 | set_ioaccel1_performant_mode(h, c, reply_queue); | 1151 | set_ioaccel1_performant_mode(h, c, reply_queue); |
@@ -7376,6 +7365,26 @@ static void hpsa_disable_interrupt_mode(struct ctlr_info *h) | |||
7376 | h->msix_vectors = 0; | 7365 | h->msix_vectors = 0; |
7377 | } | 7366 | } |
7378 | 7367 | ||
7368 | static void hpsa_setup_reply_map(struct ctlr_info *h) | ||
7369 | { | ||
7370 | const struct cpumask *mask; | ||
7371 | unsigned int queue, cpu; | ||
7372 | |||
7373 | for (queue = 0; queue < h->msix_vectors; queue++) { | ||
7374 | mask = pci_irq_get_affinity(h->pdev, queue); | ||
7375 | if (!mask) | ||
7376 | goto fallback; | ||
7377 | |||
7378 | for_each_cpu(cpu, mask) | ||
7379 | h->reply_map[cpu] = queue; | ||
7380 | } | ||
7381 | return; | ||
7382 | |||
7383 | fallback: | ||
7384 | for_each_possible_cpu(cpu) | ||
7385 | h->reply_map[cpu] = 0; | ||
7386 | } | ||
7387 | |||
7379 | /* If MSI/MSI-X is supported by the kernel we will try to enable it on | 7388 | /* If MSI/MSI-X is supported by the kernel we will try to enable it on |
7380 | * controllers that are capable. If not, we use legacy INTx mode. | 7389 | * controllers that are capable. If not, we use legacy INTx mode. |
7381 | */ | 7390 | */ |
@@ -7771,6 +7780,10 @@ static int hpsa_pci_init(struct ctlr_info *h) | |||
7771 | err = hpsa_interrupt_mode(h); | 7780 | err = hpsa_interrupt_mode(h); |
7772 | if (err) | 7781 | if (err) |
7773 | goto clean1; | 7782 | goto clean1; |
7783 | |||
7784 | /* setup mapping between CPU and reply queue */ | ||
7785 | hpsa_setup_reply_map(h); | ||
7786 | |||
7774 | err = hpsa_pci_find_memory_BAR(h->pdev, &h->paddr); | 7787 | err = hpsa_pci_find_memory_BAR(h->pdev, &h->paddr); |
7775 | if (err) | 7788 | if (err) |
7776 | goto clean2; /* intmode+region, pci */ | 7789 | goto clean2; /* intmode+region, pci */ |
@@ -8480,6 +8493,28 @@ static struct workqueue_struct *hpsa_create_controller_wq(struct ctlr_info *h, | |||
8480 | return wq; | 8493 | return wq; |
8481 | } | 8494 | } |
8482 | 8495 | ||
8496 | static void hpda_free_ctlr_info(struct ctlr_info *h) | ||
8497 | { | ||
8498 | kfree(h->reply_map); | ||
8499 | kfree(h); | ||
8500 | } | ||
8501 | |||
8502 | static struct ctlr_info *hpda_alloc_ctlr_info(void) | ||
8503 | { | ||
8504 | struct ctlr_info *h; | ||
8505 | |||
8506 | h = kzalloc(sizeof(*h), GFP_KERNEL); | ||
8507 | if (!h) | ||
8508 | return NULL; | ||
8509 | |||
8510 | h->reply_map = kzalloc(sizeof(*h->reply_map) * nr_cpu_ids, GFP_KERNEL); | ||
8511 | if (!h->reply_map) { | ||
8512 | kfree(h); | ||
8513 | return NULL; | ||
8514 | } | ||
8515 | return h; | ||
8516 | } | ||
8517 | |||
8483 | static int hpsa_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | 8518 | static int hpsa_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
8484 | { | 8519 | { |
8485 | int dac, rc; | 8520 | int dac, rc; |
@@ -8517,7 +8552,7 @@ reinit_after_soft_reset: | |||
8517 | * the driver. See comments in hpsa.h for more info. | 8552 | * the driver. See comments in hpsa.h for more info. |
8518 | */ | 8553 | */ |
8519 | BUILD_BUG_ON(sizeof(struct CommandList) % COMMANDLIST_ALIGNMENT); | 8554 | BUILD_BUG_ON(sizeof(struct CommandList) % COMMANDLIST_ALIGNMENT); |
8520 | h = kzalloc(sizeof(*h), GFP_KERNEL); | 8555 | h = hpda_alloc_ctlr_info(); |
8521 | if (!h) { | 8556 | if (!h) { |
8522 | dev_err(&pdev->dev, "Failed to allocate controller head\n"); | 8557 | dev_err(&pdev->dev, "Failed to allocate controller head\n"); |
8523 | return -ENOMEM; | 8558 | return -ENOMEM; |
@@ -8916,7 +8951,7 @@ static void hpsa_remove_one(struct pci_dev *pdev) | |||
8916 | h->lockup_detected = NULL; /* init_one 2 */ | 8951 | h->lockup_detected = NULL; /* init_one 2 */ |
8917 | /* (void) pci_disable_pcie_error_reporting(pdev); */ /* init_one 1 */ | 8952 | /* (void) pci_disable_pcie_error_reporting(pdev); */ /* init_one 1 */ |
8918 | 8953 | ||
8919 | kfree(h); /* init_one 1 */ | 8954 | hpda_free_ctlr_info(h); /* init_one 1 */ |
8920 | } | 8955 | } |
8921 | 8956 | ||
8922 | static int hpsa_suspend(__attribute__((unused)) struct pci_dev *pdev, | 8957 | static int hpsa_suspend(__attribute__((unused)) struct pci_dev *pdev, |
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h index 018f980a701c..fb9f5e7f8209 100644 --- a/drivers/scsi/hpsa.h +++ b/drivers/scsi/hpsa.h | |||
@@ -158,6 +158,7 @@ struct bmic_controller_parameters { | |||
158 | #pragma pack() | 158 | #pragma pack() |
159 | 159 | ||
160 | struct ctlr_info { | 160 | struct ctlr_info { |
161 | unsigned int *reply_map; | ||
161 | int ctlr; | 162 | int ctlr; |
162 | char devname[8]; | 163 | char devname[8]; |
163 | char *product_name; | 164 | char *product_name; |
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index b1b1d3a3b173..daefe8172b04 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c | |||
@@ -3579,11 +3579,9 @@ static void ibmvfc_tgt_implicit_logout(struct ibmvfc_target *tgt) | |||
3579 | static int ibmvfc_adisc_needs_plogi(struct ibmvfc_passthru_mad *mad, | 3579 | static int ibmvfc_adisc_needs_plogi(struct ibmvfc_passthru_mad *mad, |
3580 | struct ibmvfc_target *tgt) | 3580 | struct ibmvfc_target *tgt) |
3581 | { | 3581 | { |
3582 | if (memcmp(&mad->fc_iu.response[2], &tgt->ids.port_name, | 3582 | if (wwn_to_u64((u8 *)&mad->fc_iu.response[2]) != tgt->ids.port_name) |
3583 | sizeof(tgt->ids.port_name))) | ||
3584 | return 1; | 3583 | return 1; |
3585 | if (memcmp(&mad->fc_iu.response[4], &tgt->ids.node_name, | 3584 | if (wwn_to_u64((u8 *)&mad->fc_iu.response[4]) != tgt->ids.node_name) |
3586 | sizeof(tgt->ids.node_name))) | ||
3587 | return 1; | 3585 | return 1; |
3588 | if (be32_to_cpu(mad->fc_iu.response[6]) != tgt->scsi_id) | 3586 | if (be32_to_cpu(mad->fc_iu.response[6]) != tgt->scsi_id) |
3589 | return 1; | 3587 | return 1; |
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.h b/drivers/scsi/ibmvscsi/ibmvfc.h index 9a0696f68f37..b81a53c4a9a8 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.h +++ b/drivers/scsi/ibmvscsi/ibmvfc.h | |||
@@ -367,7 +367,7 @@ enum ibmvfc_fcp_rsp_info_codes { | |||
367 | }; | 367 | }; |
368 | 368 | ||
369 | struct ibmvfc_fcp_rsp_info { | 369 | struct ibmvfc_fcp_rsp_info { |
370 | __be16 reserved; | 370 | u8 reserved[3]; |
371 | u8 rsp_code; | 371 | u8 rsp_code; |
372 | u8 reserved2[4]; | 372 | u8 reserved2[4]; |
373 | }__attribute__((packed, aligned (2))); | 373 | }__attribute__((packed, aligned (2))); |
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 6198559abbd8..dd66c11399a2 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/kfifo.h> | 37 | #include <linux/kfifo.h> |
38 | #include <linux/scatterlist.h> | 38 | #include <linux/scatterlist.h> |
39 | #include <linux/module.h> | 39 | #include <linux/module.h> |
40 | #include <linux/backing-dev.h> | ||
40 | #include <net/tcp.h> | 41 | #include <net/tcp.h> |
41 | #include <scsi/scsi_cmnd.h> | 42 | #include <scsi/scsi_cmnd.h> |
42 | #include <scsi/scsi_device.h> | 43 | #include <scsi/scsi_device.h> |
@@ -954,6 +955,13 @@ static int iscsi_sw_tcp_slave_alloc(struct scsi_device *sdev) | |||
954 | 955 | ||
955 | static int iscsi_sw_tcp_slave_configure(struct scsi_device *sdev) | 956 | static int iscsi_sw_tcp_slave_configure(struct scsi_device *sdev) |
956 | { | 957 | { |
958 | struct iscsi_sw_tcp_host *tcp_sw_host = iscsi_host_priv(sdev->host); | ||
959 | struct iscsi_session *session = tcp_sw_host->session; | ||
960 | struct iscsi_conn *conn = session->leadconn; | ||
961 | |||
962 | if (conn->datadgst_en) | ||
963 | sdev->request_queue->backing_dev_info->capabilities | ||
964 | |= BDI_CAP_STABLE_WRITES; | ||
957 | blk_queue_bounce_limit(sdev->request_queue, BLK_BOUNCE_ANY); | 965 | blk_queue_bounce_limit(sdev->request_queue, BLK_BOUNCE_ANY); |
958 | blk_queue_dma_alignment(sdev->request_queue, 0); | 966 | blk_queue_dma_alignment(sdev->request_queue, 0); |
959 | return 0; | 967 | return 0; |
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index 6de9681ace82..ceab5e5c41c2 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c | |||
@@ -223,6 +223,7 @@ out_done: | |||
223 | static void sas_eh_finish_cmd(struct scsi_cmnd *cmd) | 223 | static void sas_eh_finish_cmd(struct scsi_cmnd *cmd) |
224 | { | 224 | { |
225 | struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(cmd->device->host); | 225 | struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(cmd->device->host); |
226 | struct domain_device *dev = cmd_to_domain_dev(cmd); | ||
226 | struct sas_task *task = TO_SAS_TASK(cmd); | 227 | struct sas_task *task = TO_SAS_TASK(cmd); |
227 | 228 | ||
228 | /* At this point, we only get called following an actual abort | 229 | /* At this point, we only get called following an actual abort |
@@ -231,6 +232,14 @@ static void sas_eh_finish_cmd(struct scsi_cmnd *cmd) | |||
231 | */ | 232 | */ |
232 | sas_end_task(cmd, task); | 233 | sas_end_task(cmd, task); |
233 | 234 | ||
235 | if (dev_is_sata(dev)) { | ||
236 | /* defer commands to libata so that libata EH can | ||
237 | * handle ata qcs correctly | ||
238 | */ | ||
239 | list_move_tail(&cmd->eh_entry, &sas_ha->eh_ata_q); | ||
240 | return; | ||
241 | } | ||
242 | |||
234 | /* now finish the command and move it on to the error | 243 | /* now finish the command and move it on to the error |
235 | * handler done list, this also takes it off the | 244 | * handler done list, this also takes it off the |
236 | * error handler pending list. | 245 | * error handler pending list. |
@@ -238,22 +247,6 @@ static void sas_eh_finish_cmd(struct scsi_cmnd *cmd) | |||
238 | scsi_eh_finish_cmd(cmd, &sas_ha->eh_done_q); | 247 | scsi_eh_finish_cmd(cmd, &sas_ha->eh_done_q); |
239 | } | 248 | } |
240 | 249 | ||
241 | static void sas_eh_defer_cmd(struct scsi_cmnd *cmd) | ||
242 | { | ||
243 | struct domain_device *dev = cmd_to_domain_dev(cmd); | ||
244 | struct sas_ha_struct *ha = dev->port->ha; | ||
245 | struct sas_task *task = TO_SAS_TASK(cmd); | ||
246 | |||
247 | if (!dev_is_sata(dev)) { | ||
248 | sas_eh_finish_cmd(cmd); | ||
249 | return; | ||
250 | } | ||
251 | |||
252 | /* report the timeout to libata */ | ||
253 | sas_end_task(cmd, task); | ||
254 | list_move_tail(&cmd->eh_entry, &ha->eh_ata_q); | ||
255 | } | ||
256 | |||
257 | static void sas_scsi_clear_queue_lu(struct list_head *error_q, struct scsi_cmnd *my_cmd) | 250 | static void sas_scsi_clear_queue_lu(struct list_head *error_q, struct scsi_cmnd *my_cmd) |
258 | { | 251 | { |
259 | struct scsi_cmnd *cmd, *n; | 252 | struct scsi_cmnd *cmd, *n; |
@@ -261,7 +254,7 @@ static void sas_scsi_clear_queue_lu(struct list_head *error_q, struct scsi_cmnd | |||
261 | list_for_each_entry_safe(cmd, n, error_q, eh_entry) { | 254 | list_for_each_entry_safe(cmd, n, error_q, eh_entry) { |
262 | if (cmd->device->sdev_target == my_cmd->device->sdev_target && | 255 | if (cmd->device->sdev_target == my_cmd->device->sdev_target && |
263 | cmd->device->lun == my_cmd->device->lun) | 256 | cmd->device->lun == my_cmd->device->lun) |
264 | sas_eh_defer_cmd(cmd); | 257 | sas_eh_finish_cmd(cmd); |
265 | } | 258 | } |
266 | } | 259 | } |
267 | 260 | ||
@@ -631,12 +624,12 @@ static void sas_eh_handle_sas_errors(struct Scsi_Host *shost, struct list_head * | |||
631 | case TASK_IS_DONE: | 624 | case TASK_IS_DONE: |
632 | SAS_DPRINTK("%s: task 0x%p is done\n", __func__, | 625 | SAS_DPRINTK("%s: task 0x%p is done\n", __func__, |
633 | task); | 626 | task); |
634 | sas_eh_defer_cmd(cmd); | 627 | sas_eh_finish_cmd(cmd); |
635 | continue; | 628 | continue; |
636 | case TASK_IS_ABORTED: | 629 | case TASK_IS_ABORTED: |
637 | SAS_DPRINTK("%s: task 0x%p is aborted\n", | 630 | SAS_DPRINTK("%s: task 0x%p is aborted\n", |
638 | __func__, task); | 631 | __func__, task); |
639 | sas_eh_defer_cmd(cmd); | 632 | sas_eh_finish_cmd(cmd); |
640 | continue; | 633 | continue; |
641 | case TASK_IS_AT_LU: | 634 | case TASK_IS_AT_LU: |
642 | SAS_DPRINTK("task 0x%p is at LU: lu recover\n", task); | 635 | SAS_DPRINTK("task 0x%p is at LU: lu recover\n", task); |
@@ -647,7 +640,7 @@ static void sas_eh_handle_sas_errors(struct Scsi_Host *shost, struct list_head * | |||
647 | "recovered\n", | 640 | "recovered\n", |
648 | SAS_ADDR(task->dev), | 641 | SAS_ADDR(task->dev), |
649 | cmd->device->lun); | 642 | cmd->device->lun); |
650 | sas_eh_defer_cmd(cmd); | 643 | sas_eh_finish_cmd(cmd); |
651 | sas_scsi_clear_queue_lu(work_q, cmd); | 644 | sas_scsi_clear_queue_lu(work_q, cmd); |
652 | goto Again; | 645 | goto Again; |
653 | } | 646 | } |
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index ba6503f37756..27fab8235ea5 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h | |||
@@ -2128,6 +2128,7 @@ enum MR_PD_TYPE { | |||
2128 | 2128 | ||
2129 | struct megasas_instance { | 2129 | struct megasas_instance { |
2130 | 2130 | ||
2131 | unsigned int *reply_map; | ||
2131 | __le32 *producer; | 2132 | __le32 *producer; |
2132 | dma_addr_t producer_h; | 2133 | dma_addr_t producer_h; |
2133 | __le32 *consumer; | 2134 | __le32 *consumer; |
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 905ea36da646..2ca9b25095da 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c | |||
@@ -5164,6 +5164,26 @@ skip_alloc: | |||
5164 | instance->use_seqnum_jbod_fp = false; | 5164 | instance->use_seqnum_jbod_fp = false; |
5165 | } | 5165 | } |
5166 | 5166 | ||
5167 | static void megasas_setup_reply_map(struct megasas_instance *instance) | ||
5168 | { | ||
5169 | const struct cpumask *mask; | ||
5170 | unsigned int queue, cpu; | ||
5171 | |||
5172 | for (queue = 0; queue < instance->msix_vectors; queue++) { | ||
5173 | mask = pci_irq_get_affinity(instance->pdev, queue); | ||
5174 | if (!mask) | ||
5175 | goto fallback; | ||
5176 | |||
5177 | for_each_cpu(cpu, mask) | ||
5178 | instance->reply_map[cpu] = queue; | ||
5179 | } | ||
5180 | return; | ||
5181 | |||
5182 | fallback: | ||
5183 | for_each_possible_cpu(cpu) | ||
5184 | instance->reply_map[cpu] = cpu % instance->msix_vectors; | ||
5185 | } | ||
5186 | |||
5167 | /** | 5187 | /** |
5168 | * megasas_init_fw - Initializes the FW | 5188 | * megasas_init_fw - Initializes the FW |
5169 | * @instance: Adapter soft state | 5189 | * @instance: Adapter soft state |
@@ -5342,6 +5362,8 @@ static int megasas_init_fw(struct megasas_instance *instance) | |||
5342 | goto fail_setup_irqs; | 5362 | goto fail_setup_irqs; |
5343 | } | 5363 | } |
5344 | 5364 | ||
5365 | megasas_setup_reply_map(instance); | ||
5366 | |||
5345 | dev_info(&instance->pdev->dev, | 5367 | dev_info(&instance->pdev->dev, |
5346 | "firmware supports msix\t: (%d)", fw_msix_count); | 5368 | "firmware supports msix\t: (%d)", fw_msix_count); |
5347 | dev_info(&instance->pdev->dev, | 5369 | dev_info(&instance->pdev->dev, |
@@ -6122,20 +6144,29 @@ static inline int megasas_alloc_mfi_ctrl_mem(struct megasas_instance *instance) | |||
6122 | */ | 6144 | */ |
6123 | static int megasas_alloc_ctrl_mem(struct megasas_instance *instance) | 6145 | static int megasas_alloc_ctrl_mem(struct megasas_instance *instance) |
6124 | { | 6146 | { |
6147 | instance->reply_map = kzalloc(sizeof(unsigned int) * nr_cpu_ids, | ||
6148 | GFP_KERNEL); | ||
6149 | if (!instance->reply_map) | ||
6150 | return -ENOMEM; | ||
6151 | |||
6125 | switch (instance->adapter_type) { | 6152 | switch (instance->adapter_type) { |
6126 | case MFI_SERIES: | 6153 | case MFI_SERIES: |
6127 | if (megasas_alloc_mfi_ctrl_mem(instance)) | 6154 | if (megasas_alloc_mfi_ctrl_mem(instance)) |
6128 | return -ENOMEM; | 6155 | goto fail; |
6129 | break; | 6156 | break; |
6130 | case VENTURA_SERIES: | 6157 | case VENTURA_SERIES: |
6131 | case THUNDERBOLT_SERIES: | 6158 | case THUNDERBOLT_SERIES: |
6132 | case INVADER_SERIES: | 6159 | case INVADER_SERIES: |
6133 | if (megasas_alloc_fusion_context(instance)) | 6160 | if (megasas_alloc_fusion_context(instance)) |
6134 | return -ENOMEM; | 6161 | goto fail; |
6135 | break; | 6162 | break; |
6136 | } | 6163 | } |
6137 | 6164 | ||
6138 | return 0; | 6165 | return 0; |
6166 | fail: | ||
6167 | kfree(instance->reply_map); | ||
6168 | instance->reply_map = NULL; | ||
6169 | return -ENOMEM; | ||
6139 | } | 6170 | } |
6140 | 6171 | ||
6141 | /* | 6172 | /* |
@@ -6147,6 +6178,7 @@ static int megasas_alloc_ctrl_mem(struct megasas_instance *instance) | |||
6147 | */ | 6178 | */ |
6148 | static inline void megasas_free_ctrl_mem(struct megasas_instance *instance) | 6179 | static inline void megasas_free_ctrl_mem(struct megasas_instance *instance) |
6149 | { | 6180 | { |
6181 | kfree(instance->reply_map); | ||
6150 | if (instance->adapter_type == MFI_SERIES) { | 6182 | if (instance->adapter_type == MFI_SERIES) { |
6151 | if (instance->producer) | 6183 | if (instance->producer) |
6152 | pci_free_consistent(instance->pdev, sizeof(u32), | 6184 | pci_free_consistent(instance->pdev, sizeof(u32), |
@@ -6539,7 +6571,6 @@ fail_io_attach: | |||
6539 | pci_free_irq_vectors(instance->pdev); | 6571 | pci_free_irq_vectors(instance->pdev); |
6540 | fail_init_mfi: | 6572 | fail_init_mfi: |
6541 | scsi_host_put(host); | 6573 | scsi_host_put(host); |
6542 | |||
6543 | fail_alloc_instance: | 6574 | fail_alloc_instance: |
6544 | pci_disable_device(pdev); | 6575 | pci_disable_device(pdev); |
6545 | 6576 | ||
@@ -6745,6 +6776,8 @@ megasas_resume(struct pci_dev *pdev) | |||
6745 | if (rval < 0) | 6776 | if (rval < 0) |
6746 | goto fail_reenable_msix; | 6777 | goto fail_reenable_msix; |
6747 | 6778 | ||
6779 | megasas_setup_reply_map(instance); | ||
6780 | |||
6748 | if (instance->adapter_type != MFI_SERIES) { | 6781 | if (instance->adapter_type != MFI_SERIES) { |
6749 | megasas_reset_reply_desc(instance); | 6782 | megasas_reset_reply_desc(instance); |
6750 | if (megasas_ioc_init_fusion(instance)) { | 6783 | if (megasas_ioc_init_fusion(instance)) { |
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 073ced07e662..5ec3b74e8aed 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c | |||
@@ -216,36 +216,30 @@ inline void megasas_return_cmd_fusion(struct megasas_instance *instance, | |||
216 | /** | 216 | /** |
217 | * megasas_fire_cmd_fusion - Sends command to the FW | 217 | * megasas_fire_cmd_fusion - Sends command to the FW |
218 | * @instance: Adapter soft state | 218 | * @instance: Adapter soft state |
219 | * @req_desc: 32bit or 64bit Request descriptor | 219 | * @req_desc: 64bit Request descriptor |
220 | * | 220 | * |
221 | * Perform PCI Write. Ventura supports 32 bit Descriptor. | 221 | * Perform PCI Write. |
222 | * Prior to Ventura (12G) MR controller supports 64 bit Descriptor. | ||
223 | */ | 222 | */ |
224 | 223 | ||
225 | static void | 224 | static void |
226 | megasas_fire_cmd_fusion(struct megasas_instance *instance, | 225 | megasas_fire_cmd_fusion(struct megasas_instance *instance, |
227 | union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc) | 226 | union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc) |
228 | { | 227 | { |
229 | if (instance->adapter_type == VENTURA_SERIES) | ||
230 | writel(le32_to_cpu(req_desc->u.low), | ||
231 | &instance->reg_set->inbound_single_queue_port); | ||
232 | else { | ||
233 | #if defined(writeq) && defined(CONFIG_64BIT) | 228 | #if defined(writeq) && defined(CONFIG_64BIT) |
234 | u64 req_data = (((u64)le32_to_cpu(req_desc->u.high) << 32) | | 229 | u64 req_data = (((u64)le32_to_cpu(req_desc->u.high) << 32) | |
235 | le32_to_cpu(req_desc->u.low)); | 230 | le32_to_cpu(req_desc->u.low)); |
236 | 231 | ||
237 | writeq(req_data, &instance->reg_set->inbound_low_queue_port); | 232 | writeq(req_data, &instance->reg_set->inbound_low_queue_port); |
238 | #else | 233 | #else |
239 | unsigned long flags; | 234 | unsigned long flags; |
240 | spin_lock_irqsave(&instance->hba_lock, flags); | 235 | spin_lock_irqsave(&instance->hba_lock, flags); |
241 | writel(le32_to_cpu(req_desc->u.low), | 236 | writel(le32_to_cpu(req_desc->u.low), |
242 | &instance->reg_set->inbound_low_queue_port); | 237 | &instance->reg_set->inbound_low_queue_port); |
243 | writel(le32_to_cpu(req_desc->u.high), | 238 | writel(le32_to_cpu(req_desc->u.high), |
244 | &instance->reg_set->inbound_high_queue_port); | 239 | &instance->reg_set->inbound_high_queue_port); |
245 | mmiowb(); | 240 | mmiowb(); |
246 | spin_unlock_irqrestore(&instance->hba_lock, flags); | 241 | spin_unlock_irqrestore(&instance->hba_lock, flags); |
247 | #endif | 242 | #endif |
248 | } | ||
249 | } | 243 | } |
250 | 244 | ||
251 | /** | 245 | /** |
@@ -982,7 +976,6 @@ megasas_ioc_init_fusion(struct megasas_instance *instance) | |||
982 | const char *sys_info; | 976 | const char *sys_info; |
983 | MFI_CAPABILITIES *drv_ops; | 977 | MFI_CAPABILITIES *drv_ops; |
984 | u32 scratch_pad_2; | 978 | u32 scratch_pad_2; |
985 | unsigned long flags; | ||
986 | ktime_t time; | 979 | ktime_t time; |
987 | bool cur_fw_64bit_dma_capable; | 980 | bool cur_fw_64bit_dma_capable; |
988 | 981 | ||
@@ -1121,14 +1114,7 @@ megasas_ioc_init_fusion(struct megasas_instance *instance) | |||
1121 | break; | 1114 | break; |
1122 | } | 1115 | } |
1123 | 1116 | ||
1124 | /* For Ventura also IOC INIT required 64 bit Descriptor write. */ | 1117 | megasas_fire_cmd_fusion(instance, &req_desc); |
1125 | spin_lock_irqsave(&instance->hba_lock, flags); | ||
1126 | writel(le32_to_cpu(req_desc.u.low), | ||
1127 | &instance->reg_set->inbound_low_queue_port); | ||
1128 | writel(le32_to_cpu(req_desc.u.high), | ||
1129 | &instance->reg_set->inbound_high_queue_port); | ||
1130 | mmiowb(); | ||
1131 | spin_unlock_irqrestore(&instance->hba_lock, flags); | ||
1132 | 1118 | ||
1133 | wait_and_poll(instance, cmd, MFI_POLL_TIMEOUT_SECS); | 1119 | wait_and_poll(instance, cmd, MFI_POLL_TIMEOUT_SECS); |
1134 | 1120 | ||
@@ -2655,11 +2641,8 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, | |||
2655 | fp_possible = (io_info.fpOkForIo > 0) ? true : false; | 2641 | fp_possible = (io_info.fpOkForIo > 0) ? true : false; |
2656 | } | 2642 | } |
2657 | 2643 | ||
2658 | /* Use raw_smp_processor_id() for now until cmd->request->cpu is CPU | 2644 | cmd->request_desc->SCSIIO.MSIxIndex = |
2659 | id by default, not CPU group id, otherwise all MSI-X queues won't | 2645 | instance->reply_map[raw_smp_processor_id()]; |
2660 | be utilized */ | ||
2661 | cmd->request_desc->SCSIIO.MSIxIndex = instance->msix_vectors ? | ||
2662 | raw_smp_processor_id() % instance->msix_vectors : 0; | ||
2663 | 2646 | ||
2664 | praid_context = &io_request->RaidContext; | 2647 | praid_context = &io_request->RaidContext; |
2665 | 2648 | ||
@@ -2985,10 +2968,9 @@ megasas_build_syspd_fusion(struct megasas_instance *instance, | |||
2985 | } | 2968 | } |
2986 | 2969 | ||
2987 | cmd->request_desc->SCSIIO.DevHandle = io_request->DevHandle; | 2970 | cmd->request_desc->SCSIIO.DevHandle = io_request->DevHandle; |
2988 | cmd->request_desc->SCSIIO.MSIxIndex = | ||
2989 | instance->msix_vectors ? | ||
2990 | (raw_smp_processor_id() % instance->msix_vectors) : 0; | ||
2991 | 2971 | ||
2972 | cmd->request_desc->SCSIIO.MSIxIndex = | ||
2973 | instance->reply_map[raw_smp_processor_id()]; | ||
2992 | 2974 | ||
2993 | if (!fp_possible) { | 2975 | if (!fp_possible) { |
2994 | /* system pd firmware path */ | 2976 | /* system pd firmware path */ |
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index 0a0e7aad0ca4..61f93a134956 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c | |||
@@ -2774,8 +2774,11 @@ _base_assign_reply_queues(struct MPT3SAS_ADAPTER *ioc) | |||
2774 | continue; | 2774 | continue; |
2775 | } | 2775 | } |
2776 | 2776 | ||
2777 | for_each_cpu(cpu, mask) | 2777 | for_each_cpu_and(cpu, mask, cpu_online_mask) { |
2778 | if (cpu >= ioc->cpu_msix_table_sz) | ||
2779 | break; | ||
2778 | ioc->cpu_msix_table[cpu] = reply_q->msix_index; | 2780 | ioc->cpu_msix_table[cpu] = reply_q->msix_index; |
2781 | } | ||
2779 | } | 2782 | } |
2780 | return; | 2783 | return; |
2781 | } | 2784 | } |
@@ -6637,14 +6640,14 @@ _base_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase) | |||
6637 | } | 6640 | } |
6638 | 6641 | ||
6639 | /** | 6642 | /** |
6640 | * _wait_for_commands_to_complete - reset controller | 6643 | * mpt3sas_wait_for_commands_to_complete - reset controller |
6641 | * @ioc: Pointer to MPT_ADAPTER structure | 6644 | * @ioc: Pointer to MPT_ADAPTER structure |
6642 | * | 6645 | * |
6643 | * This function is waiting 10s for all pending commands to complete | 6646 | * This function is waiting 10s for all pending commands to complete |
6644 | * prior to putting controller in reset. | 6647 | * prior to putting controller in reset. |
6645 | */ | 6648 | */ |
6646 | static void | 6649 | void |
6647 | _wait_for_commands_to_complete(struct MPT3SAS_ADAPTER *ioc) | 6650 | mpt3sas_wait_for_commands_to_complete(struct MPT3SAS_ADAPTER *ioc) |
6648 | { | 6651 | { |
6649 | u32 ioc_state; | 6652 | u32 ioc_state; |
6650 | 6653 | ||
@@ -6717,7 +6720,7 @@ mpt3sas_base_hard_reset_handler(struct MPT3SAS_ADAPTER *ioc, | |||
6717 | is_fault = 1; | 6720 | is_fault = 1; |
6718 | } | 6721 | } |
6719 | _base_reset_handler(ioc, MPT3_IOC_PRE_RESET); | 6722 | _base_reset_handler(ioc, MPT3_IOC_PRE_RESET); |
6720 | _wait_for_commands_to_complete(ioc); | 6723 | mpt3sas_wait_for_commands_to_complete(ioc); |
6721 | _base_mask_interrupts(ioc); | 6724 | _base_mask_interrupts(ioc); |
6722 | r = _base_make_ioc_ready(ioc, type); | 6725 | r = _base_make_ioc_ready(ioc, type); |
6723 | if (r) | 6726 | if (r) |
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h index 4de0251e158e..ae36d8fb2f2b 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.h +++ b/drivers/scsi/mpt3sas/mpt3sas_base.h | |||
@@ -1440,6 +1440,9 @@ void mpt3sas_base_update_missing_delay(struct MPT3SAS_ADAPTER *ioc, | |||
1440 | 1440 | ||
1441 | int mpt3sas_port_enable(struct MPT3SAS_ADAPTER *ioc); | 1441 | int mpt3sas_port_enable(struct MPT3SAS_ADAPTER *ioc); |
1442 | 1442 | ||
1443 | void | ||
1444 | mpt3sas_wait_for_commands_to_complete(struct MPT3SAS_ADAPTER *ioc); | ||
1445 | |||
1443 | 1446 | ||
1444 | /* scsih shared API */ | 1447 | /* scsih shared API */ |
1445 | struct scsi_cmnd *mpt3sas_scsih_scsi_lookup_get(struct MPT3SAS_ADAPTER *ioc, | 1448 | struct scsi_cmnd *mpt3sas_scsih_scsi_lookup_get(struct MPT3SAS_ADAPTER *ioc, |
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index 50efccd73cb1..89be0170aef6 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c | |||
@@ -2835,7 +2835,8 @@ scsih_abort(struct scsi_cmnd *scmd) | |||
2835 | _scsih_tm_display_info(ioc, scmd); | 2835 | _scsih_tm_display_info(ioc, scmd); |
2836 | 2836 | ||
2837 | sas_device_priv_data = scmd->device->hostdata; | 2837 | sas_device_priv_data = scmd->device->hostdata; |
2838 | if (!sas_device_priv_data || !sas_device_priv_data->sas_target) { | 2838 | if (!sas_device_priv_data || !sas_device_priv_data->sas_target || |
2839 | ioc->remove_host) { | ||
2839 | sdev_printk(KERN_INFO, scmd->device, | 2840 | sdev_printk(KERN_INFO, scmd->device, |
2840 | "device been deleted! scmd(%p)\n", scmd); | 2841 | "device been deleted! scmd(%p)\n", scmd); |
2841 | scmd->result = DID_NO_CONNECT << 16; | 2842 | scmd->result = DID_NO_CONNECT << 16; |
@@ -2898,7 +2899,8 @@ scsih_dev_reset(struct scsi_cmnd *scmd) | |||
2898 | _scsih_tm_display_info(ioc, scmd); | 2899 | _scsih_tm_display_info(ioc, scmd); |
2899 | 2900 | ||
2900 | sas_device_priv_data = scmd->device->hostdata; | 2901 | sas_device_priv_data = scmd->device->hostdata; |
2901 | if (!sas_device_priv_data || !sas_device_priv_data->sas_target) { | 2902 | if (!sas_device_priv_data || !sas_device_priv_data->sas_target || |
2903 | ioc->remove_host) { | ||
2902 | sdev_printk(KERN_INFO, scmd->device, | 2904 | sdev_printk(KERN_INFO, scmd->device, |
2903 | "device been deleted! scmd(%p)\n", scmd); | 2905 | "device been deleted! scmd(%p)\n", scmd); |
2904 | scmd->result = DID_NO_CONNECT << 16; | 2906 | scmd->result = DID_NO_CONNECT << 16; |
@@ -2961,7 +2963,8 @@ scsih_target_reset(struct scsi_cmnd *scmd) | |||
2961 | _scsih_tm_display_info(ioc, scmd); | 2963 | _scsih_tm_display_info(ioc, scmd); |
2962 | 2964 | ||
2963 | sas_device_priv_data = scmd->device->hostdata; | 2965 | sas_device_priv_data = scmd->device->hostdata; |
2964 | if (!sas_device_priv_data || !sas_device_priv_data->sas_target) { | 2966 | if (!sas_device_priv_data || !sas_device_priv_data->sas_target || |
2967 | ioc->remove_host) { | ||
2965 | starget_printk(KERN_INFO, starget, "target been deleted! scmd(%p)\n", | 2968 | starget_printk(KERN_INFO, starget, "target been deleted! scmd(%p)\n", |
2966 | scmd); | 2969 | scmd); |
2967 | scmd->result = DID_NO_CONNECT << 16; | 2970 | scmd->result = DID_NO_CONNECT << 16; |
@@ -3019,7 +3022,7 @@ scsih_host_reset(struct scsi_cmnd *scmd) | |||
3019 | ioc->name, scmd); | 3022 | ioc->name, scmd); |
3020 | scsi_print_command(scmd); | 3023 | scsi_print_command(scmd); |
3021 | 3024 | ||
3022 | if (ioc->is_driver_loading) { | 3025 | if (ioc->is_driver_loading || ioc->remove_host) { |
3023 | pr_info(MPT3SAS_FMT "Blocking the host reset\n", | 3026 | pr_info(MPT3SAS_FMT "Blocking the host reset\n", |
3024 | ioc->name); | 3027 | ioc->name); |
3025 | r = FAILED; | 3028 | r = FAILED; |
@@ -4453,7 +4456,7 @@ _scsih_flush_running_cmds(struct MPT3SAS_ADAPTER *ioc) | |||
4453 | st = scsi_cmd_priv(scmd); | 4456 | st = scsi_cmd_priv(scmd); |
4454 | mpt3sas_base_clear_st(ioc, st); | 4457 | mpt3sas_base_clear_st(ioc, st); |
4455 | scsi_dma_unmap(scmd); | 4458 | scsi_dma_unmap(scmd); |
4456 | if (ioc->pci_error_recovery) | 4459 | if (ioc->pci_error_recovery || ioc->remove_host) |
4457 | scmd->result = DID_NO_CONNECT << 16; | 4460 | scmd->result = DID_NO_CONNECT << 16; |
4458 | else | 4461 | else |
4459 | scmd->result = DID_RESET << 16; | 4462 | scmd->result = DID_RESET << 16; |
@@ -9739,6 +9742,10 @@ static void scsih_remove(struct pci_dev *pdev) | |||
9739 | unsigned long flags; | 9742 | unsigned long flags; |
9740 | 9743 | ||
9741 | ioc->remove_host = 1; | 9744 | ioc->remove_host = 1; |
9745 | |||
9746 | mpt3sas_wait_for_commands_to_complete(ioc); | ||
9747 | _scsih_flush_running_cmds(ioc); | ||
9748 | |||
9742 | _scsih_fw_event_cleanup_queue(ioc); | 9749 | _scsih_fw_event_cleanup_queue(ioc); |
9743 | 9750 | ||
9744 | spin_lock_irqsave(&ioc->fw_event_lock, flags); | 9751 | spin_lock_irqsave(&ioc->fw_event_lock, flags); |
@@ -9815,6 +9822,10 @@ scsih_shutdown(struct pci_dev *pdev) | |||
9815 | unsigned long flags; | 9822 | unsigned long flags; |
9816 | 9823 | ||
9817 | ioc->remove_host = 1; | 9824 | ioc->remove_host = 1; |
9825 | |||
9826 | mpt3sas_wait_for_commands_to_complete(ioc); | ||
9827 | _scsih_flush_running_cmds(ioc); | ||
9828 | |||
9818 | _scsih_fw_event_cleanup_queue(ioc); | 9829 | _scsih_fw_event_cleanup_queue(ioc); |
9819 | 9830 | ||
9820 | spin_lock_irqsave(&ioc->fw_event_lock, flags); | 9831 | spin_lock_irqsave(&ioc->fw_event_lock, flags); |
@@ -10563,7 +10574,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
10563 | snprintf(ioc->firmware_event_name, sizeof(ioc->firmware_event_name), | 10574 | snprintf(ioc->firmware_event_name, sizeof(ioc->firmware_event_name), |
10564 | "fw_event_%s%d", ioc->driver_name, ioc->id); | 10575 | "fw_event_%s%d", ioc->driver_name, ioc->id); |
10565 | ioc->firmware_event_thread = alloc_ordered_workqueue( | 10576 | ioc->firmware_event_thread = alloc_ordered_workqueue( |
10566 | ioc->firmware_event_name, WQ_MEM_RECLAIM); | 10577 | ioc->firmware_event_name, 0); |
10567 | if (!ioc->firmware_event_thread) { | 10578 | if (!ioc->firmware_event_thread) { |
10568 | pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", | 10579 | pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", |
10569 | ioc->name, __FILE__, __LINE__, __func__); | 10580 | ioc->name, __FILE__, __LINE__, __func__); |
diff --git a/drivers/scsi/qedi/qedi_fw.c b/drivers/scsi/qedi/qedi_fw.c index 667d7697ba01..d09afe1b567d 100644 --- a/drivers/scsi/qedi/qedi_fw.c +++ b/drivers/scsi/qedi/qedi_fw.c | |||
@@ -762,6 +762,11 @@ static void qedi_process_cmd_cleanup_resp(struct qedi_ctx *qedi, | |||
762 | 762 | ||
763 | iscsi_cid = cqe->conn_id; | 763 | iscsi_cid = cqe->conn_id; |
764 | qedi_conn = qedi->cid_que.conn_cid_tbl[iscsi_cid]; | 764 | qedi_conn = qedi->cid_que.conn_cid_tbl[iscsi_cid]; |
765 | if (!qedi_conn) { | ||
766 | QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO, | ||
767 | "icid not found 0x%x\n", cqe->conn_id); | ||
768 | return; | ||
769 | } | ||
765 | 770 | ||
766 | /* Based on this itt get the corresponding qedi_cmd */ | 771 | /* Based on this itt get the corresponding qedi_cmd */ |
767 | spin_lock_bh(&qedi_conn->tmf_work_lock); | 772 | spin_lock_bh(&qedi_conn->tmf_work_lock); |
diff --git a/drivers/scsi/qedi/qedi_main.c b/drivers/scsi/qedi/qedi_main.c index e992f9d3ef00..4da3592aec0f 100644 --- a/drivers/scsi/qedi/qedi_main.c +++ b/drivers/scsi/qedi/qedi_main.c | |||
@@ -1724,7 +1724,6 @@ static ssize_t qedi_show_boot_eth_info(void *data, int type, char *buf) | |||
1724 | { | 1724 | { |
1725 | struct qedi_ctx *qedi = data; | 1725 | struct qedi_ctx *qedi = data; |
1726 | struct nvm_iscsi_initiator *initiator; | 1726 | struct nvm_iscsi_initiator *initiator; |
1727 | char *str = buf; | ||
1728 | int rc = 1; | 1727 | int rc = 1; |
1729 | u32 ipv6_en, dhcp_en, ip_len; | 1728 | u32 ipv6_en, dhcp_en, ip_len; |
1730 | struct nvm_iscsi_block *block; | 1729 | struct nvm_iscsi_block *block; |
@@ -1758,32 +1757,32 @@ static ssize_t qedi_show_boot_eth_info(void *data, int type, char *buf) | |||
1758 | 1757 | ||
1759 | switch (type) { | 1758 | switch (type) { |
1760 | case ISCSI_BOOT_ETH_IP_ADDR: | 1759 | case ISCSI_BOOT_ETH_IP_ADDR: |
1761 | rc = snprintf(str, ip_len, fmt, ip); | 1760 | rc = snprintf(buf, ip_len, fmt, ip); |
1762 | break; | 1761 | break; |
1763 | case ISCSI_BOOT_ETH_SUBNET_MASK: | 1762 | case ISCSI_BOOT_ETH_SUBNET_MASK: |
1764 | rc = snprintf(str, ip_len, fmt, sub); | 1763 | rc = snprintf(buf, ip_len, fmt, sub); |
1765 | break; | 1764 | break; |
1766 | case ISCSI_BOOT_ETH_GATEWAY: | 1765 | case ISCSI_BOOT_ETH_GATEWAY: |
1767 | rc = snprintf(str, ip_len, fmt, gw); | 1766 | rc = snprintf(buf, ip_len, fmt, gw); |
1768 | break; | 1767 | break; |
1769 | case ISCSI_BOOT_ETH_FLAGS: | 1768 | case ISCSI_BOOT_ETH_FLAGS: |
1770 | rc = snprintf(str, 3, "%hhd\n", | 1769 | rc = snprintf(buf, 3, "%hhd\n", |
1771 | SYSFS_FLAG_FW_SEL_BOOT); | 1770 | SYSFS_FLAG_FW_SEL_BOOT); |
1772 | break; | 1771 | break; |
1773 | case ISCSI_BOOT_ETH_INDEX: | 1772 | case ISCSI_BOOT_ETH_INDEX: |
1774 | rc = snprintf(str, 3, "0\n"); | 1773 | rc = snprintf(buf, 3, "0\n"); |
1775 | break; | 1774 | break; |
1776 | case ISCSI_BOOT_ETH_MAC: | 1775 | case ISCSI_BOOT_ETH_MAC: |
1777 | rc = sysfs_format_mac(str, qedi->mac, ETH_ALEN); | 1776 | rc = sysfs_format_mac(buf, qedi->mac, ETH_ALEN); |
1778 | break; | 1777 | break; |
1779 | case ISCSI_BOOT_ETH_VLAN: | 1778 | case ISCSI_BOOT_ETH_VLAN: |
1780 | rc = snprintf(str, 12, "%d\n", | 1779 | rc = snprintf(buf, 12, "%d\n", |
1781 | GET_FIELD2(initiator->generic_cont0, | 1780 | GET_FIELD2(initiator->generic_cont0, |
1782 | NVM_ISCSI_CFG_INITIATOR_VLAN)); | 1781 | NVM_ISCSI_CFG_INITIATOR_VLAN)); |
1783 | break; | 1782 | break; |
1784 | case ISCSI_BOOT_ETH_ORIGIN: | 1783 | case ISCSI_BOOT_ETH_ORIGIN: |
1785 | if (dhcp_en) | 1784 | if (dhcp_en) |
1786 | rc = snprintf(str, 3, "3\n"); | 1785 | rc = snprintf(buf, 3, "3\n"); |
1787 | break; | 1786 | break; |
1788 | default: | 1787 | default: |
1789 | rc = 0; | 1788 | rc = 0; |
@@ -1819,7 +1818,6 @@ static ssize_t qedi_show_boot_ini_info(void *data, int type, char *buf) | |||
1819 | { | 1818 | { |
1820 | struct qedi_ctx *qedi = data; | 1819 | struct qedi_ctx *qedi = data; |
1821 | struct nvm_iscsi_initiator *initiator; | 1820 | struct nvm_iscsi_initiator *initiator; |
1822 | char *str = buf; | ||
1823 | int rc; | 1821 | int rc; |
1824 | struct nvm_iscsi_block *block; | 1822 | struct nvm_iscsi_block *block; |
1825 | 1823 | ||
@@ -1831,8 +1829,8 @@ static ssize_t qedi_show_boot_ini_info(void *data, int type, char *buf) | |||
1831 | 1829 | ||
1832 | switch (type) { | 1830 | switch (type) { |
1833 | case ISCSI_BOOT_INI_INITIATOR_NAME: | 1831 | case ISCSI_BOOT_INI_INITIATOR_NAME: |
1834 | rc = snprintf(str, NVM_ISCSI_CFG_ISCSI_NAME_MAX_LEN, "%s\n", | 1832 | rc = sprintf(buf, "%.*s\n", NVM_ISCSI_CFG_ISCSI_NAME_MAX_LEN, |
1835 | initiator->initiator_name.byte); | 1833 | initiator->initiator_name.byte); |
1836 | break; | 1834 | break; |
1837 | default: | 1835 | default: |
1838 | rc = 0; | 1836 | rc = 0; |
@@ -1860,7 +1858,6 @@ static ssize_t | |||
1860 | qedi_show_boot_tgt_info(struct qedi_ctx *qedi, int type, | 1858 | qedi_show_boot_tgt_info(struct qedi_ctx *qedi, int type, |
1861 | char *buf, enum qedi_nvm_tgts idx) | 1859 | char *buf, enum qedi_nvm_tgts idx) |
1862 | { | 1860 | { |
1863 | char *str = buf; | ||
1864 | int rc = 1; | 1861 | int rc = 1; |
1865 | u32 ctrl_flags, ipv6_en, chap_en, mchap_en, ip_len; | 1862 | u32 ctrl_flags, ipv6_en, chap_en, mchap_en, ip_len; |
1866 | struct nvm_iscsi_block *block; | 1863 | struct nvm_iscsi_block *block; |
@@ -1899,48 +1896,48 @@ qedi_show_boot_tgt_info(struct qedi_ctx *qedi, int type, | |||
1899 | 1896 | ||
1900 | switch (type) { | 1897 | switch (type) { |
1901 | case ISCSI_BOOT_TGT_NAME: | 1898 | case ISCSI_BOOT_TGT_NAME: |
1902 | rc = snprintf(str, NVM_ISCSI_CFG_ISCSI_NAME_MAX_LEN, "%s\n", | 1899 | rc = sprintf(buf, "%.*s\n", NVM_ISCSI_CFG_ISCSI_NAME_MAX_LEN, |
1903 | block->target[idx].target_name.byte); | 1900 | block->target[idx].target_name.byte); |
1904 | break; | 1901 | break; |
1905 | case ISCSI_BOOT_TGT_IP_ADDR: | 1902 | case ISCSI_BOOT_TGT_IP_ADDR: |
1906 | if (ipv6_en) | 1903 | if (ipv6_en) |
1907 | rc = snprintf(str, ip_len, "%pI6\n", | 1904 | rc = snprintf(buf, ip_len, "%pI6\n", |
1908 | block->target[idx].ipv6_addr.byte); | 1905 | block->target[idx].ipv6_addr.byte); |
1909 | else | 1906 | else |
1910 | rc = snprintf(str, ip_len, "%pI4\n", | 1907 | rc = snprintf(buf, ip_len, "%pI4\n", |
1911 | block->target[idx].ipv4_addr.byte); | 1908 | block->target[idx].ipv4_addr.byte); |
1912 | break; | 1909 | break; |
1913 | case ISCSI_BOOT_TGT_PORT: | 1910 | case ISCSI_BOOT_TGT_PORT: |
1914 | rc = snprintf(str, 12, "%d\n", | 1911 | rc = snprintf(buf, 12, "%d\n", |
1915 | GET_FIELD2(block->target[idx].generic_cont0, | 1912 | GET_FIELD2(block->target[idx].generic_cont0, |
1916 | NVM_ISCSI_CFG_TARGET_TCP_PORT)); | 1913 | NVM_ISCSI_CFG_TARGET_TCP_PORT)); |
1917 | break; | 1914 | break; |
1918 | case ISCSI_BOOT_TGT_LUN: | 1915 | case ISCSI_BOOT_TGT_LUN: |
1919 | rc = snprintf(str, 22, "%.*d\n", | 1916 | rc = snprintf(buf, 22, "%.*d\n", |
1920 | block->target[idx].lun.value[1], | 1917 | block->target[idx].lun.value[1], |
1921 | block->target[idx].lun.value[0]); | 1918 | block->target[idx].lun.value[0]); |
1922 | break; | 1919 | break; |
1923 | case ISCSI_BOOT_TGT_CHAP_NAME: | 1920 | case ISCSI_BOOT_TGT_CHAP_NAME: |
1924 | rc = snprintf(str, NVM_ISCSI_CFG_CHAP_NAME_MAX_LEN, "%s\n", | 1921 | rc = sprintf(buf, "%.*s\n", NVM_ISCSI_CFG_CHAP_NAME_MAX_LEN, |
1925 | chap_name); | 1922 | chap_name); |
1926 | break; | 1923 | break; |
1927 | case ISCSI_BOOT_TGT_CHAP_SECRET: | 1924 | case ISCSI_BOOT_TGT_CHAP_SECRET: |
1928 | rc = snprintf(str, NVM_ISCSI_CFG_CHAP_PWD_MAX_LEN, "%s\n", | 1925 | rc = sprintf(buf, "%.*s\n", NVM_ISCSI_CFG_CHAP_NAME_MAX_LEN, |
1929 | chap_secret); | 1926 | chap_secret); |
1930 | break; | 1927 | break; |
1931 | case ISCSI_BOOT_TGT_REV_CHAP_NAME: | 1928 | case ISCSI_BOOT_TGT_REV_CHAP_NAME: |
1932 | rc = snprintf(str, NVM_ISCSI_CFG_CHAP_NAME_MAX_LEN, "%s\n", | 1929 | rc = sprintf(buf, "%.*s\n", NVM_ISCSI_CFG_CHAP_NAME_MAX_LEN, |
1933 | mchap_name); | 1930 | mchap_name); |
1934 | break; | 1931 | break; |
1935 | case ISCSI_BOOT_TGT_REV_CHAP_SECRET: | 1932 | case ISCSI_BOOT_TGT_REV_CHAP_SECRET: |
1936 | rc = snprintf(str, NVM_ISCSI_CFG_CHAP_PWD_MAX_LEN, "%s\n", | 1933 | rc = sprintf(buf, "%.*s\n", NVM_ISCSI_CFG_CHAP_NAME_MAX_LEN, |
1937 | mchap_secret); | 1934 | mchap_secret); |
1938 | break; | 1935 | break; |
1939 | case ISCSI_BOOT_TGT_FLAGS: | 1936 | case ISCSI_BOOT_TGT_FLAGS: |
1940 | rc = snprintf(str, 3, "%hhd\n", SYSFS_FLAG_FW_SEL_BOOT); | 1937 | rc = snprintf(buf, 3, "%hhd\n", SYSFS_FLAG_FW_SEL_BOOT); |
1941 | break; | 1938 | break; |
1942 | case ISCSI_BOOT_TGT_NIC_ASSOC: | 1939 | case ISCSI_BOOT_TGT_NIC_ASSOC: |
1943 | rc = snprintf(str, 3, "0\n"); | 1940 | rc = snprintf(buf, 3, "0\n"); |
1944 | break; | 1941 | break; |
1945 | default: | 1942 | default: |
1946 | rc = 0; | 1943 | rc = 0; |
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index 1abc8a9064b3..5fd44c50bbac 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c | |||
@@ -14,7 +14,7 @@ | |||
14 | * | Module Init and Probe | 0x0193 | 0x0146 | | 14 | * | Module Init and Probe | 0x0193 | 0x0146 | |
15 | * | | | 0x015b-0x0160 | | 15 | * | | | 0x015b-0x0160 | |
16 | * | | | 0x016e | | 16 | * | | | 0x016e | |
17 | * | Mailbox commands | 0x1205 | 0x11a2-0x11ff | | 17 | * | Mailbox commands | 0x1206 | 0x11a2-0x11ff | |
18 | * | Device Discovery | 0x2134 | 0x210e-0x2116 | | 18 | * | Device Discovery | 0x2134 | 0x210e-0x2116 | |
19 | * | | | 0x211a | | 19 | * | | | 0x211a | |
20 | * | | | 0x211c-0x2128 | | 20 | * | | | 0x211c-0x2128 | |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 54625eb2904f..eb2ec1fb07cb 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -261,9 +261,9 @@ | |||
261 | struct name_list_extended { | 261 | struct name_list_extended { |
262 | struct get_name_list_extended *l; | 262 | struct get_name_list_extended *l; |
263 | dma_addr_t ldma; | 263 | dma_addr_t ldma; |
264 | struct list_head fcports; /* protect by sess_list */ | 264 | struct list_head fcports; |
265 | spinlock_t fcports_lock; | ||
265 | u32 size; | 266 | u32 size; |
266 | u8 sent; | ||
267 | }; | 267 | }; |
268 | /* | 268 | /* |
269 | * Timeout timer counts in seconds | 269 | * Timeout timer counts in seconds |
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index 39dd62b8c649..2288757b5c9e 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c | |||
@@ -3177,6 +3177,7 @@ done_free_sp: | |||
3177 | sp->free(sp); | 3177 | sp->free(sp); |
3178 | fcport->flags &= ~FCF_ASYNC_SENT; | 3178 | fcport->flags &= ~FCF_ASYNC_SENT; |
3179 | done: | 3179 | done: |
3180 | fcport->flags &= ~FCF_ASYNC_ACTIVE; | ||
3180 | return rval; | 3181 | return rval; |
3181 | } | 3182 | } |
3182 | 3183 | ||
@@ -3368,6 +3369,7 @@ done_free_sp: | |||
3368 | sp->free(sp); | 3369 | sp->free(sp); |
3369 | fcport->flags &= ~FCF_ASYNC_SENT; | 3370 | fcport->flags &= ~FCF_ASYNC_SENT; |
3370 | done: | 3371 | done: |
3372 | fcport->flags &= ~FCF_ASYNC_ACTIVE; | ||
3371 | return rval; | 3373 | return rval; |
3372 | } | 3374 | } |
3373 | 3375 | ||
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 77c9177d0c25..8aeb0ed524a1 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -59,8 +59,6 @@ qla2x00_sp_timeout(struct timer_list *t) | |||
59 | req->outstanding_cmds[sp->handle] = NULL; | 59 | req->outstanding_cmds[sp->handle] = NULL; |
60 | iocb = &sp->u.iocb_cmd; | 60 | iocb = &sp->u.iocb_cmd; |
61 | iocb->timeout(sp); | 61 | iocb->timeout(sp); |
62 | if (sp->type != SRB_ELS_DCMD) | ||
63 | sp->free(sp); | ||
64 | spin_unlock_irqrestore(&vha->hw->hardware_lock, flags); | 62 | spin_unlock_irqrestore(&vha->hw->hardware_lock, flags); |
65 | } | 63 | } |
66 | 64 | ||
@@ -102,7 +100,6 @@ qla2x00_async_iocb_timeout(void *data) | |||
102 | srb_t *sp = data; | 100 | srb_t *sp = data; |
103 | fc_port_t *fcport = sp->fcport; | 101 | fc_port_t *fcport = sp->fcport; |
104 | struct srb_iocb *lio = &sp->u.iocb_cmd; | 102 | struct srb_iocb *lio = &sp->u.iocb_cmd; |
105 | struct event_arg ea; | ||
106 | 103 | ||
107 | if (fcport) { | 104 | if (fcport) { |
108 | ql_dbg(ql_dbg_disc, fcport->vha, 0x2071, | 105 | ql_dbg(ql_dbg_disc, fcport->vha, 0x2071, |
@@ -117,25 +114,13 @@ qla2x00_async_iocb_timeout(void *data) | |||
117 | 114 | ||
118 | switch (sp->type) { | 115 | switch (sp->type) { |
119 | case SRB_LOGIN_CMD: | 116 | case SRB_LOGIN_CMD: |
120 | if (!fcport) | ||
121 | break; | ||
122 | /* Retry as needed. */ | 117 | /* Retry as needed. */ |
123 | lio->u.logio.data[0] = MBS_COMMAND_ERROR; | 118 | lio->u.logio.data[0] = MBS_COMMAND_ERROR; |
124 | lio->u.logio.data[1] = lio->u.logio.flags & SRB_LOGIN_RETRIED ? | 119 | lio->u.logio.data[1] = lio->u.logio.flags & SRB_LOGIN_RETRIED ? |
125 | QLA_LOGIO_LOGIN_RETRIED : 0; | 120 | QLA_LOGIO_LOGIN_RETRIED : 0; |
126 | memset(&ea, 0, sizeof(ea)); | 121 | sp->done(sp, QLA_FUNCTION_TIMEOUT); |
127 | ea.event = FCME_PLOGI_DONE; | ||
128 | ea.fcport = sp->fcport; | ||
129 | ea.data[0] = lio->u.logio.data[0]; | ||
130 | ea.data[1] = lio->u.logio.data[1]; | ||
131 | ea.sp = sp; | ||
132 | qla24xx_handle_plogi_done_event(fcport->vha, &ea); | ||
133 | break; | 122 | break; |
134 | case SRB_LOGOUT_CMD: | 123 | case SRB_LOGOUT_CMD: |
135 | if (!fcport) | ||
136 | break; | ||
137 | qlt_logo_completion_handler(fcport, QLA_FUNCTION_TIMEOUT); | ||
138 | break; | ||
139 | case SRB_CT_PTHRU_CMD: | 124 | case SRB_CT_PTHRU_CMD: |
140 | case SRB_MB_IOCB: | 125 | case SRB_MB_IOCB: |
141 | case SRB_NACK_PLOGI: | 126 | case SRB_NACK_PLOGI: |
@@ -228,6 +213,7 @@ done_free_sp: | |||
228 | sp->free(sp); | 213 | sp->free(sp); |
229 | fcport->flags &= ~FCF_ASYNC_SENT; | 214 | fcport->flags &= ~FCF_ASYNC_SENT; |
230 | done: | 215 | done: |
216 | fcport->flags &= ~FCF_ASYNC_ACTIVE; | ||
231 | return rval; | 217 | return rval; |
232 | } | 218 | } |
233 | 219 | ||
@@ -235,12 +221,10 @@ static void | |||
235 | qla2x00_async_logout_sp_done(void *ptr, int res) | 221 | qla2x00_async_logout_sp_done(void *ptr, int res) |
236 | { | 222 | { |
237 | srb_t *sp = ptr; | 223 | srb_t *sp = ptr; |
238 | struct srb_iocb *lio = &sp->u.iocb_cmd; | ||
239 | 224 | ||
240 | sp->fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); | 225 | sp->fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); |
241 | if (!test_bit(UNLOADING, &sp->vha->dpc_flags)) | 226 | sp->fcport->login_gen++; |
242 | qla2x00_post_async_logout_done_work(sp->vha, sp->fcport, | 227 | qlt_logo_completion_handler(sp->fcport, res); |
243 | lio->u.logio.data); | ||
244 | sp->free(sp); | 228 | sp->free(sp); |
245 | } | 229 | } |
246 | 230 | ||
@@ -280,7 +264,7 @@ qla2x00_async_logout(struct scsi_qla_host *vha, fc_port_t *fcport) | |||
280 | done_free_sp: | 264 | done_free_sp: |
281 | sp->free(sp); | 265 | sp->free(sp); |
282 | done: | 266 | done: |
283 | fcport->flags &= ~FCF_ASYNC_SENT; | 267 | fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); |
284 | return rval; | 268 | return rval; |
285 | } | 269 | } |
286 | 270 | ||
@@ -288,6 +272,7 @@ void | |||
288 | qla2x00_async_prlo_done(struct scsi_qla_host *vha, fc_port_t *fcport, | 272 | qla2x00_async_prlo_done(struct scsi_qla_host *vha, fc_port_t *fcport, |
289 | uint16_t *data) | 273 | uint16_t *data) |
290 | { | 274 | { |
275 | fcport->flags &= ~FCF_ASYNC_ACTIVE; | ||
291 | /* Don't re-login in target mode */ | 276 | /* Don't re-login in target mode */ |
292 | if (!fcport->tgt_session) | 277 | if (!fcport->tgt_session) |
293 | qla2x00_mark_device_lost(vha, fcport, 1, 0); | 278 | qla2x00_mark_device_lost(vha, fcport, 1, 0); |
@@ -301,6 +286,7 @@ qla2x00_async_prlo_sp_done(void *s, int res) | |||
301 | struct srb_iocb *lio = &sp->u.iocb_cmd; | 286 | struct srb_iocb *lio = &sp->u.iocb_cmd; |
302 | struct scsi_qla_host *vha = sp->vha; | 287 | struct scsi_qla_host *vha = sp->vha; |
303 | 288 | ||
289 | sp->fcport->flags &= ~FCF_ASYNC_ACTIVE; | ||
304 | if (!test_bit(UNLOADING, &vha->dpc_flags)) | 290 | if (!test_bit(UNLOADING, &vha->dpc_flags)) |
305 | qla2x00_post_async_prlo_done_work(sp->fcport->vha, sp->fcport, | 291 | qla2x00_post_async_prlo_done_work(sp->fcport->vha, sp->fcport, |
306 | lio->u.logio.data); | 292 | lio->u.logio.data); |
@@ -339,6 +325,7 @@ qla2x00_async_prlo(struct scsi_qla_host *vha, fc_port_t *fcport) | |||
339 | done_free_sp: | 325 | done_free_sp: |
340 | sp->free(sp); | 326 | sp->free(sp); |
341 | done: | 327 | done: |
328 | fcport->flags &= ~FCF_ASYNC_ACTIVE; | ||
342 | return rval; | 329 | return rval; |
343 | } | 330 | } |
344 | 331 | ||
@@ -392,6 +379,8 @@ qla2x00_async_adisc_sp_done(void *ptr, int res) | |||
392 | "Async done-%s res %x %8phC\n", | 379 | "Async done-%s res %x %8phC\n", |
393 | sp->name, res, sp->fcport->port_name); | 380 | sp->name, res, sp->fcport->port_name); |
394 | 381 | ||
382 | sp->fcport->flags &= ~FCF_ASYNC_SENT; | ||
383 | |||
395 | memset(&ea, 0, sizeof(ea)); | 384 | memset(&ea, 0, sizeof(ea)); |
396 | ea.event = FCME_ADISC_DONE; | 385 | ea.event = FCME_ADISC_DONE; |
397 | ea.rc = res; | 386 | ea.rc = res; |
@@ -442,7 +431,7 @@ qla2x00_async_adisc(struct scsi_qla_host *vha, fc_port_t *fcport, | |||
442 | done_free_sp: | 431 | done_free_sp: |
443 | sp->free(sp); | 432 | sp->free(sp); |
444 | done: | 433 | done: |
445 | fcport->flags &= ~FCF_ASYNC_SENT; | 434 | fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); |
446 | qla2x00_post_async_adisc_work(vha, fcport, data); | 435 | qla2x00_post_async_adisc_work(vha, fcport, data); |
447 | return rval; | 436 | return rval; |
448 | } | 437 | } |
@@ -660,8 +649,7 @@ qla24xx_async_gnl_sp_done(void *s, int res) | |||
660 | (loop_id & 0x7fff)); | 649 | (loop_id & 0x7fff)); |
661 | } | 650 | } |
662 | 651 | ||
663 | spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); | 652 | spin_lock_irqsave(&vha->gnl.fcports_lock, flags); |
664 | vha->gnl.sent = 0; | ||
665 | 653 | ||
666 | INIT_LIST_HEAD(&h); | 654 | INIT_LIST_HEAD(&h); |
667 | fcport = tf = NULL; | 655 | fcport = tf = NULL; |
@@ -670,12 +658,16 @@ qla24xx_async_gnl_sp_done(void *s, int res) | |||
670 | 658 | ||
671 | list_for_each_entry_safe(fcport, tf, &h, gnl_entry) { | 659 | list_for_each_entry_safe(fcport, tf, &h, gnl_entry) { |
672 | list_del_init(&fcport->gnl_entry); | 660 | list_del_init(&fcport->gnl_entry); |
661 | spin_lock(&vha->hw->tgt.sess_lock); | ||
673 | fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); | 662 | fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); |
663 | spin_unlock(&vha->hw->tgt.sess_lock); | ||
674 | ea.fcport = fcport; | 664 | ea.fcport = fcport; |
675 | 665 | ||
676 | qla2x00_fcport_event_handler(vha, &ea); | 666 | qla2x00_fcport_event_handler(vha, &ea); |
677 | } | 667 | } |
668 | spin_unlock_irqrestore(&vha->gnl.fcports_lock, flags); | ||
678 | 669 | ||
670 | spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); | ||
679 | /* create new fcport if fw has knowledge of new sessions */ | 671 | /* create new fcport if fw has knowledge of new sessions */ |
680 | for (i = 0; i < n; i++) { | 672 | for (i = 0; i < n; i++) { |
681 | port_id_t id; | 673 | port_id_t id; |
@@ -727,18 +719,21 @@ int qla24xx_async_gnl(struct scsi_qla_host *vha, fc_port_t *fcport) | |||
727 | ql_dbg(ql_dbg_disc, vha, 0x20d9, | 719 | ql_dbg(ql_dbg_disc, vha, 0x20d9, |
728 | "Async-gnlist WWPN %8phC \n", fcport->port_name); | 720 | "Async-gnlist WWPN %8phC \n", fcport->port_name); |
729 | 721 | ||
730 | spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); | 722 | spin_lock_irqsave(&vha->gnl.fcports_lock, flags); |
723 | if (!list_empty(&fcport->gnl_entry)) { | ||
724 | spin_unlock_irqrestore(&vha->gnl.fcports_lock, flags); | ||
725 | rval = QLA_SUCCESS; | ||
726 | goto done; | ||
727 | } | ||
728 | |||
729 | spin_lock(&vha->hw->tgt.sess_lock); | ||
731 | fcport->disc_state = DSC_GNL; | 730 | fcport->disc_state = DSC_GNL; |
732 | fcport->last_rscn_gen = fcport->rscn_gen; | 731 | fcport->last_rscn_gen = fcport->rscn_gen; |
733 | fcport->last_login_gen = fcport->login_gen; | 732 | fcport->last_login_gen = fcport->login_gen; |
733 | spin_unlock(&vha->hw->tgt.sess_lock); | ||
734 | 734 | ||
735 | list_add_tail(&fcport->gnl_entry, &vha->gnl.fcports); | 735 | list_add_tail(&fcport->gnl_entry, &vha->gnl.fcports); |
736 | if (vha->gnl.sent) { | 736 | spin_unlock_irqrestore(&vha->gnl.fcports_lock, flags); |
737 | spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); | ||
738 | return QLA_SUCCESS; | ||
739 | } | ||
740 | vha->gnl.sent = 1; | ||
741 | spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); | ||
742 | 737 | ||
743 | sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); | 738 | sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); |
744 | if (!sp) | 739 | if (!sp) |
@@ -1065,6 +1060,7 @@ void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea) | |||
1065 | fc_port_t *fcport = ea->fcport; | 1060 | fc_port_t *fcport = ea->fcport; |
1066 | struct port_database_24xx *pd; | 1061 | struct port_database_24xx *pd; |
1067 | struct srb *sp = ea->sp; | 1062 | struct srb *sp = ea->sp; |
1063 | uint8_t ls; | ||
1068 | 1064 | ||
1069 | pd = (struct port_database_24xx *)sp->u.iocb_cmd.u.mbx.in; | 1065 | pd = (struct port_database_24xx *)sp->u.iocb_cmd.u.mbx.in; |
1070 | 1066 | ||
@@ -1077,7 +1073,12 @@ void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea) | |||
1077 | if (fcport->disc_state == DSC_DELETE_PEND) | 1073 | if (fcport->disc_state == DSC_DELETE_PEND) |
1078 | return; | 1074 | return; |
1079 | 1075 | ||
1080 | switch (pd->current_login_state) { | 1076 | if (fcport->fc4f_nvme) |
1077 | ls = pd->current_login_state >> 4; | ||
1078 | else | ||
1079 | ls = pd->current_login_state & 0xf; | ||
1080 | |||
1081 | switch (ls) { | ||
1081 | case PDS_PRLI_COMPLETE: | 1082 | case PDS_PRLI_COMPLETE: |
1082 | __qla24xx_parse_gpdb(vha, fcport, pd); | 1083 | __qla24xx_parse_gpdb(vha, fcport, pd); |
1083 | break; | 1084 | break; |
@@ -1167,8 +1168,9 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport) | |||
1167 | if (fcport->scan_state != QLA_FCPORT_FOUND) | 1168 | if (fcport->scan_state != QLA_FCPORT_FOUND) |
1168 | return 0; | 1169 | return 0; |
1169 | 1170 | ||
1170 | if ((fcport->fw_login_state == DSC_LS_PLOGI_PEND) || | 1171 | if ((fcport->loop_id != FC_NO_LOOP_ID) && |
1171 | (fcport->fw_login_state == DSC_LS_PRLI_PEND)) | 1172 | ((fcport->fw_login_state == DSC_LS_PLOGI_PEND) || |
1173 | (fcport->fw_login_state == DSC_LS_PRLI_PEND))) | ||
1172 | return 0; | 1174 | return 0; |
1173 | 1175 | ||
1174 | if (fcport->fw_login_state == DSC_LS_PLOGI_COMP) { | 1176 | if (fcport->fw_login_state == DSC_LS_PLOGI_COMP) { |
@@ -1548,6 +1550,7 @@ qla24xx_abort_sp_done(void *ptr, int res) | |||
1548 | srb_t *sp = ptr; | 1550 | srb_t *sp = ptr; |
1549 | struct srb_iocb *abt = &sp->u.iocb_cmd; | 1551 | struct srb_iocb *abt = &sp->u.iocb_cmd; |
1550 | 1552 | ||
1553 | del_timer(&sp->u.iocb_cmd.timer); | ||
1551 | complete(&abt->u.abt.comp); | 1554 | complete(&abt->u.abt.comp); |
1552 | } | 1555 | } |
1553 | 1556 | ||
@@ -1727,7 +1730,6 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea) | |||
1727 | 1730 | ||
1728 | set_bit(ea->fcport->loop_id, vha->hw->loop_id_map); | 1731 | set_bit(ea->fcport->loop_id, vha->hw->loop_id_map); |
1729 | spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); | 1732 | spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); |
1730 | ea->fcport->loop_id = FC_NO_LOOP_ID; | ||
1731 | ea->fcport->chip_reset = vha->hw->base_qpair->chip_reset; | 1733 | ea->fcport->chip_reset = vha->hw->base_qpair->chip_reset; |
1732 | ea->fcport->logout_on_delete = 1; | 1734 | ea->fcport->logout_on_delete = 1; |
1733 | ea->fcport->send_els_logo = 0; | 1735 | ea->fcport->send_els_logo = 0; |
@@ -1819,6 +1821,7 @@ qla2x00_async_logout_done(struct scsi_qla_host *vha, fc_port_t *fcport, | |||
1819 | qla2x00_mark_device_lost(vha, fcport, 1, 0); | 1821 | qla2x00_mark_device_lost(vha, fcport, 1, 0); |
1820 | qlt_logo_completion_handler(fcport, data[0]); | 1822 | qlt_logo_completion_handler(fcport, data[0]); |
1821 | fcport->login_gen++; | 1823 | fcport->login_gen++; |
1824 | fcport->flags &= ~FCF_ASYNC_ACTIVE; | ||
1822 | return; | 1825 | return; |
1823 | } | 1826 | } |
1824 | 1827 | ||
@@ -1826,6 +1829,7 @@ void | |||
1826 | qla2x00_async_adisc_done(struct scsi_qla_host *vha, fc_port_t *fcport, | 1829 | qla2x00_async_adisc_done(struct scsi_qla_host *vha, fc_port_t *fcport, |
1827 | uint16_t *data) | 1830 | uint16_t *data) |
1828 | { | 1831 | { |
1832 | fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); | ||
1829 | if (data[0] == MBS_COMMAND_COMPLETE) { | 1833 | if (data[0] == MBS_COMMAND_COMPLETE) { |
1830 | qla2x00_update_fcport(vha, fcport); | 1834 | qla2x00_update_fcport(vha, fcport); |
1831 | 1835 | ||
@@ -1833,7 +1837,6 @@ qla2x00_async_adisc_done(struct scsi_qla_host *vha, fc_port_t *fcport, | |||
1833 | } | 1837 | } |
1834 | 1838 | ||
1835 | /* Retry login. */ | 1839 | /* Retry login. */ |
1836 | fcport->flags &= ~FCF_ASYNC_SENT; | ||
1837 | if (data[1] & QLA_LOGIO_LOGIN_RETRIED) | 1840 | if (data[1] & QLA_LOGIO_LOGIN_RETRIED) |
1838 | set_bit(RELOGIN_NEEDED, &vha->dpc_flags); | 1841 | set_bit(RELOGIN_NEEDED, &vha->dpc_flags); |
1839 | else | 1842 | else |
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index a4edbecfaf96..f74ff7b550b6 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c | |||
@@ -3276,12 +3276,11 @@ qla24xx_abort_iocb(srb_t *sp, struct abort_entry_24xx *abt_iocb) | |||
3276 | memset(abt_iocb, 0, sizeof(struct abort_entry_24xx)); | 3276 | memset(abt_iocb, 0, sizeof(struct abort_entry_24xx)); |
3277 | abt_iocb->entry_type = ABORT_IOCB_TYPE; | 3277 | abt_iocb->entry_type = ABORT_IOCB_TYPE; |
3278 | abt_iocb->entry_count = 1; | 3278 | abt_iocb->entry_count = 1; |
3279 | abt_iocb->handle = | 3279 | abt_iocb->handle = cpu_to_le32(MAKE_HANDLE(req->id, sp->handle)); |
3280 | cpu_to_le32(MAKE_HANDLE(aio->u.abt.req_que_no, | ||
3281 | aio->u.abt.cmd_hndl)); | ||
3282 | abt_iocb->nport_handle = cpu_to_le16(sp->fcport->loop_id); | 3280 | abt_iocb->nport_handle = cpu_to_le16(sp->fcport->loop_id); |
3283 | abt_iocb->handle_to_abort = | 3281 | abt_iocb->handle_to_abort = |
3284 | cpu_to_le32(MAKE_HANDLE(req->id, aio->u.abt.cmd_hndl)); | 3282 | cpu_to_le32(MAKE_HANDLE(aio->u.abt.req_que_no, |
3283 | aio->u.abt.cmd_hndl)); | ||
3285 | abt_iocb->port_id[0] = sp->fcport->d_id.b.al_pa; | 3284 | abt_iocb->port_id[0] = sp->fcport->d_id.b.al_pa; |
3286 | abt_iocb->port_id[1] = sp->fcport->d_id.b.area; | 3285 | abt_iocb->port_id[1] = sp->fcport->d_id.b.area; |
3287 | abt_iocb->port_id[2] = sp->fcport->d_id.b.domain; | 3286 | abt_iocb->port_id[2] = sp->fcport->d_id.b.domain; |
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 5fbb8f4b4dc7..7cacdc3408fa 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -272,7 +272,8 @@ qla2x00_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0) | |||
272 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | 272 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; |
273 | 273 | ||
274 | /* Read all mbox registers? */ | 274 | /* Read all mbox registers? */ |
275 | mboxes = (1 << ha->mbx_count) - 1; | 275 | WARN_ON_ONCE(ha->mbx_count > 32); |
276 | mboxes = (1ULL << ha->mbx_count) - 1; | ||
276 | if (!ha->mcp) | 277 | if (!ha->mcp) |
277 | ql_dbg(ql_dbg_async, vha, 0x5001, "MBX pointer ERROR.\n"); | 278 | ql_dbg(ql_dbg_async, vha, 0x5001, "MBX pointer ERROR.\n"); |
278 | else | 279 | else |
@@ -2862,7 +2863,8 @@ qla24xx_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0) | |||
2862 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | 2863 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
2863 | 2864 | ||
2864 | /* Read all mbox registers? */ | 2865 | /* Read all mbox registers? */ |
2865 | mboxes = (1 << ha->mbx_count) - 1; | 2866 | WARN_ON_ONCE(ha->mbx_count > 32); |
2867 | mboxes = (1ULL << ha->mbx_count) - 1; | ||
2866 | if (!ha->mcp) | 2868 | if (!ha->mcp) |
2867 | ql_dbg(ql_dbg_async, vha, 0x504e, "MBX pointer ERROR.\n"); | 2869 | ql_dbg(ql_dbg_async, vha, 0x504e, "MBX pointer ERROR.\n"); |
2868 | else | 2870 | else |
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index c9a134ae0d2b..5db0262d5c94 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
@@ -503,11 +503,19 @@ mbx_done: | |||
503 | } | 503 | } |
504 | pr_warn(" cmd=%x ****\n", command); | 504 | pr_warn(" cmd=%x ****\n", command); |
505 | } | 505 | } |
506 | ql_dbg(ql_dbg_mbx, vha, 0x1198, | 506 | if (IS_FWI2_CAPABLE(ha) && !(IS_P3P_TYPE(ha))) { |
507 | "host_status=%#x intr_ctrl=%#x intr_status=%#x\n", | 507 | ql_dbg(ql_dbg_mbx, vha, 0x1198, |
508 | RD_REG_DWORD(®->isp24.host_status), | 508 | "host_status=%#x intr_ctrl=%#x intr_status=%#x\n", |
509 | RD_REG_DWORD(®->isp24.ictrl), | 509 | RD_REG_DWORD(®->isp24.host_status), |
510 | RD_REG_DWORD(®->isp24.istatus)); | 510 | RD_REG_DWORD(®->isp24.ictrl), |
511 | RD_REG_DWORD(®->isp24.istatus)); | ||
512 | } else { | ||
513 | ql_dbg(ql_dbg_mbx, vha, 0x1206, | ||
514 | "ctrl_status=%#x ictrl=%#x istatus=%#x\n", | ||
515 | RD_REG_WORD(®->isp.ctrl_status), | ||
516 | RD_REG_WORD(®->isp.ictrl), | ||
517 | RD_REG_WORD(®->isp.istatus)); | ||
518 | } | ||
511 | } else { | 519 | } else { |
512 | ql_dbg(ql_dbg_mbx, base_vha, 0x1021, "Done %s.\n", __func__); | 520 | ql_dbg(ql_dbg_mbx, base_vha, 0x1021, "Done %s.\n", __func__); |
513 | } | 521 | } |
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 6fa2467e2a16..fb35d9e94912 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -453,7 +453,7 @@ static int qla2x00_alloc_queues(struct qla_hw_data *ha, struct req_que *req, | |||
453 | ha->req_q_map[0] = req; | 453 | ha->req_q_map[0] = req; |
454 | set_bit(0, ha->rsp_qid_map); | 454 | set_bit(0, ha->rsp_qid_map); |
455 | set_bit(0, ha->req_qid_map); | 455 | set_bit(0, ha->req_qid_map); |
456 | return 1; | 456 | return 0; |
457 | 457 | ||
458 | fail_qpair_map: | 458 | fail_qpair_map: |
459 | kfree(ha->base_qpair); | 459 | kfree(ha->base_qpair); |
@@ -470,6 +470,9 @@ fail_req_map: | |||
470 | 470 | ||
471 | static void qla2x00_free_req_que(struct qla_hw_data *ha, struct req_que *req) | 471 | static void qla2x00_free_req_que(struct qla_hw_data *ha, struct req_que *req) |
472 | { | 472 | { |
473 | if (!ha->req_q_map) | ||
474 | return; | ||
475 | |||
473 | if (IS_QLAFX00(ha)) { | 476 | if (IS_QLAFX00(ha)) { |
474 | if (req && req->ring_fx00) | 477 | if (req && req->ring_fx00) |
475 | dma_free_coherent(&ha->pdev->dev, | 478 | dma_free_coherent(&ha->pdev->dev, |
@@ -480,16 +483,19 @@ static void qla2x00_free_req_que(struct qla_hw_data *ha, struct req_que *req) | |||
480 | (req->length + 1) * sizeof(request_t), | 483 | (req->length + 1) * sizeof(request_t), |
481 | req->ring, req->dma); | 484 | req->ring, req->dma); |
482 | 485 | ||
483 | if (req) | 486 | if (req) { |
484 | kfree(req->outstanding_cmds); | 487 | kfree(req->outstanding_cmds); |
485 | 488 | kfree(req); | |
486 | kfree(req); | 489 | } |
487 | } | 490 | } |
488 | 491 | ||
489 | static void qla2x00_free_rsp_que(struct qla_hw_data *ha, struct rsp_que *rsp) | 492 | static void qla2x00_free_rsp_que(struct qla_hw_data *ha, struct rsp_que *rsp) |
490 | { | 493 | { |
494 | if (!ha->rsp_q_map) | ||
495 | return; | ||
496 | |||
491 | if (IS_QLAFX00(ha)) { | 497 | if (IS_QLAFX00(ha)) { |
492 | if (rsp && rsp->ring) | 498 | if (rsp && rsp->ring_fx00) |
493 | dma_free_coherent(&ha->pdev->dev, | 499 | dma_free_coherent(&ha->pdev->dev, |
494 | (rsp->length_fx00 + 1) * sizeof(request_t), | 500 | (rsp->length_fx00 + 1) * sizeof(request_t), |
495 | rsp->ring_fx00, rsp->dma_fx00); | 501 | rsp->ring_fx00, rsp->dma_fx00); |
@@ -498,7 +504,8 @@ static void qla2x00_free_rsp_que(struct qla_hw_data *ha, struct rsp_que *rsp) | |||
498 | (rsp->length + 1) * sizeof(response_t), | 504 | (rsp->length + 1) * sizeof(response_t), |
499 | rsp->ring, rsp->dma); | 505 | rsp->ring, rsp->dma); |
500 | } | 506 | } |
501 | kfree(rsp); | 507 | if (rsp) |
508 | kfree(rsp); | ||
502 | } | 509 | } |
503 | 510 | ||
504 | static void qla2x00_free_queues(struct qla_hw_data *ha) | 511 | static void qla2x00_free_queues(struct qla_hw_data *ha) |
@@ -1722,6 +1729,8 @@ __qla2x00_abort_all_cmds(struct qla_qpair *qp, int res) | |||
1722 | struct qla_tgt_cmd *cmd; | 1729 | struct qla_tgt_cmd *cmd; |
1723 | uint8_t trace = 0; | 1730 | uint8_t trace = 0; |
1724 | 1731 | ||
1732 | if (!ha->req_q_map) | ||
1733 | return; | ||
1725 | spin_lock_irqsave(qp->qp_lock_ptr, flags); | 1734 | spin_lock_irqsave(qp->qp_lock_ptr, flags); |
1726 | req = qp->req; | 1735 | req = qp->req; |
1727 | for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) { | 1736 | for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) { |
@@ -3094,14 +3103,14 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
3094 | /* Set up the irqs */ | 3103 | /* Set up the irqs */ |
3095 | ret = qla2x00_request_irqs(ha, rsp); | 3104 | ret = qla2x00_request_irqs(ha, rsp); |
3096 | if (ret) | 3105 | if (ret) |
3097 | goto probe_hw_failed; | 3106 | goto probe_failed; |
3098 | 3107 | ||
3099 | /* Alloc arrays of request and response ring ptrs */ | 3108 | /* Alloc arrays of request and response ring ptrs */ |
3100 | if (!qla2x00_alloc_queues(ha, req, rsp)) { | 3109 | if (qla2x00_alloc_queues(ha, req, rsp)) { |
3101 | ql_log(ql_log_fatal, base_vha, 0x003d, | 3110 | ql_log(ql_log_fatal, base_vha, 0x003d, |
3102 | "Failed to allocate memory for queue pointers..." | 3111 | "Failed to allocate memory for queue pointers..." |
3103 | "aborting.\n"); | 3112 | "aborting.\n"); |
3104 | goto probe_init_failed; | 3113 | goto probe_failed; |
3105 | } | 3114 | } |
3106 | 3115 | ||
3107 | if (ha->mqenable && shost_use_blk_mq(host)) { | 3116 | if (ha->mqenable && shost_use_blk_mq(host)) { |
@@ -3386,15 +3395,6 @@ skip_dpc: | |||
3386 | 3395 | ||
3387 | return 0; | 3396 | return 0; |
3388 | 3397 | ||
3389 | probe_init_failed: | ||
3390 | qla2x00_free_req_que(ha, req); | ||
3391 | ha->req_q_map[0] = NULL; | ||
3392 | clear_bit(0, ha->req_qid_map); | ||
3393 | qla2x00_free_rsp_que(ha, rsp); | ||
3394 | ha->rsp_q_map[0] = NULL; | ||
3395 | clear_bit(0, ha->rsp_qid_map); | ||
3396 | ha->max_req_queues = ha->max_rsp_queues = 0; | ||
3397 | |||
3398 | probe_failed: | 3398 | probe_failed: |
3399 | if (base_vha->timer_active) | 3399 | if (base_vha->timer_active) |
3400 | qla2x00_stop_timer(base_vha); | 3400 | qla2x00_stop_timer(base_vha); |
@@ -3624,6 +3624,8 @@ qla2x00_remove_one(struct pci_dev *pdev) | |||
3624 | } | 3624 | } |
3625 | qla2x00_wait_for_hba_ready(base_vha); | 3625 | qla2x00_wait_for_hba_ready(base_vha); |
3626 | 3626 | ||
3627 | qla2x00_wait_for_sess_deletion(base_vha); | ||
3628 | |||
3627 | /* | 3629 | /* |
3628 | * if UNLOAD flag is already set, then continue unload, | 3630 | * if UNLOAD flag is already set, then continue unload, |
3629 | * where it was set first. | 3631 | * where it was set first. |
@@ -4505,11 +4507,17 @@ qla2x00_mem_free(struct qla_hw_data *ha) | |||
4505 | if (ha->init_cb) | 4507 | if (ha->init_cb) |
4506 | dma_free_coherent(&ha->pdev->dev, ha->init_cb_size, | 4508 | dma_free_coherent(&ha->pdev->dev, ha->init_cb_size, |
4507 | ha->init_cb, ha->init_cb_dma); | 4509 | ha->init_cb, ha->init_cb_dma); |
4508 | vfree(ha->optrom_buffer); | 4510 | |
4509 | kfree(ha->nvram); | 4511 | if (ha->optrom_buffer) |
4510 | kfree(ha->npiv_info); | 4512 | vfree(ha->optrom_buffer); |
4511 | kfree(ha->swl); | 4513 | if (ha->nvram) |
4512 | kfree(ha->loop_id_map); | 4514 | kfree(ha->nvram); |
4515 | if (ha->npiv_info) | ||
4516 | kfree(ha->npiv_info); | ||
4517 | if (ha->swl) | ||
4518 | kfree(ha->swl); | ||
4519 | if (ha->loop_id_map) | ||
4520 | kfree(ha->loop_id_map); | ||
4513 | 4521 | ||
4514 | ha->srb_mempool = NULL; | 4522 | ha->srb_mempool = NULL; |
4515 | ha->ctx_mempool = NULL; | 4523 | ha->ctx_mempool = NULL; |
@@ -4525,6 +4533,15 @@ qla2x00_mem_free(struct qla_hw_data *ha) | |||
4525 | ha->ex_init_cb_dma = 0; | 4533 | ha->ex_init_cb_dma = 0; |
4526 | ha->async_pd = NULL; | 4534 | ha->async_pd = NULL; |
4527 | ha->async_pd_dma = 0; | 4535 | ha->async_pd_dma = 0; |
4536 | ha->loop_id_map = NULL; | ||
4537 | ha->npiv_info = NULL; | ||
4538 | ha->optrom_buffer = NULL; | ||
4539 | ha->swl = NULL; | ||
4540 | ha->nvram = NULL; | ||
4541 | ha->mctp_dump = NULL; | ||
4542 | ha->dcbx_tlv = NULL; | ||
4543 | ha->xgmac_data = NULL; | ||
4544 | ha->sfp_data = NULL; | ||
4528 | 4545 | ||
4529 | ha->s_dma_pool = NULL; | 4546 | ha->s_dma_pool = NULL; |
4530 | ha->dl_dma_pool = NULL; | 4547 | ha->dl_dma_pool = NULL; |
@@ -4574,6 +4591,7 @@ struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht, | |||
4574 | 4591 | ||
4575 | spin_lock_init(&vha->work_lock); | 4592 | spin_lock_init(&vha->work_lock); |
4576 | spin_lock_init(&vha->cmd_list_lock); | 4593 | spin_lock_init(&vha->cmd_list_lock); |
4594 | spin_lock_init(&vha->gnl.fcports_lock); | ||
4577 | init_waitqueue_head(&vha->fcport_waitQ); | 4595 | init_waitqueue_head(&vha->fcport_waitQ); |
4578 | init_waitqueue_head(&vha->vref_waitq); | 4596 | init_waitqueue_head(&vha->vref_waitq); |
4579 | 4597 | ||
@@ -4879,6 +4897,8 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e) | |||
4879 | } | 4897 | } |
4880 | qlt_plogi_ack_unref(vha, pla); | 4898 | qlt_plogi_ack_unref(vha, pla); |
4881 | } else { | 4899 | } else { |
4900 | fc_port_t *dfcp = NULL; | ||
4901 | |||
4882 | spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); | 4902 | spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); |
4883 | tfcp = qla2x00_find_fcport_by_nportid(vha, | 4903 | tfcp = qla2x00_find_fcport_by_nportid(vha, |
4884 | &e->u.new_sess.id, 1); | 4904 | &e->u.new_sess.id, 1); |
@@ -4901,11 +4921,13 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e) | |||
4901 | default: | 4921 | default: |
4902 | fcport->login_pause = 1; | 4922 | fcport->login_pause = 1; |
4903 | tfcp->conflict = fcport; | 4923 | tfcp->conflict = fcport; |
4904 | qlt_schedule_sess_for_deletion(tfcp); | 4924 | dfcp = tfcp; |
4905 | break; | 4925 | break; |
4906 | } | 4926 | } |
4907 | } | 4927 | } |
4908 | spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); | 4928 | spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); |
4929 | if (dfcp) | ||
4930 | qlt_schedule_sess_for_deletion(tfcp); | ||
4909 | 4931 | ||
4910 | wwn = wwn_to_u64(fcport->node_name); | 4932 | wwn = wwn_to_u64(fcport->node_name); |
4911 | 4933 | ||
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index ead6813ea9b3..5546ac9c3d9d 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c | |||
@@ -1227,10 +1227,10 @@ static void qla24xx_chk_fcp_state(struct fc_port *sess) | |||
1227 | } | 1227 | } |
1228 | } | 1228 | } |
1229 | 1229 | ||
1230 | /* ha->tgt.sess_lock supposed to be held on entry */ | ||
1231 | void qlt_schedule_sess_for_deletion(struct fc_port *sess) | 1230 | void qlt_schedule_sess_for_deletion(struct fc_port *sess) |
1232 | { | 1231 | { |
1233 | struct qla_tgt *tgt = sess->tgt; | 1232 | struct qla_tgt *tgt = sess->tgt; |
1233 | struct qla_hw_data *ha = sess->vha->hw; | ||
1234 | unsigned long flags; | 1234 | unsigned long flags; |
1235 | 1235 | ||
1236 | if (sess->disc_state == DSC_DELETE_PEND) | 1236 | if (sess->disc_state == DSC_DELETE_PEND) |
@@ -1247,16 +1247,16 @@ void qlt_schedule_sess_for_deletion(struct fc_port *sess) | |||
1247 | return; | 1247 | return; |
1248 | } | 1248 | } |
1249 | 1249 | ||
1250 | spin_lock_irqsave(&ha->tgt.sess_lock, flags); | ||
1250 | if (sess->deleted == QLA_SESS_DELETED) | 1251 | if (sess->deleted == QLA_SESS_DELETED) |
1251 | sess->logout_on_delete = 0; | 1252 | sess->logout_on_delete = 0; |
1252 | 1253 | ||
1253 | spin_lock_irqsave(&sess->vha->work_lock, flags); | ||
1254 | if (sess->deleted == QLA_SESS_DELETION_IN_PROGRESS) { | 1254 | if (sess->deleted == QLA_SESS_DELETION_IN_PROGRESS) { |
1255 | spin_unlock_irqrestore(&sess->vha->work_lock, flags); | 1255 | spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); |
1256 | return; | 1256 | return; |
1257 | } | 1257 | } |
1258 | sess->deleted = QLA_SESS_DELETION_IN_PROGRESS; | 1258 | sess->deleted = QLA_SESS_DELETION_IN_PROGRESS; |
1259 | spin_unlock_irqrestore(&sess->vha->work_lock, flags); | 1259 | spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); |
1260 | 1260 | ||
1261 | sess->disc_state = DSC_DELETE_PEND; | 1261 | sess->disc_state = DSC_DELETE_PEND; |
1262 | 1262 | ||
@@ -1265,13 +1265,10 @@ void qlt_schedule_sess_for_deletion(struct fc_port *sess) | |||
1265 | ql_dbg(ql_dbg_tgt, sess->vha, 0xe001, | 1265 | ql_dbg(ql_dbg_tgt, sess->vha, 0xe001, |
1266 | "Scheduling sess %p for deletion\n", sess); | 1266 | "Scheduling sess %p for deletion\n", sess); |
1267 | 1267 | ||
1268 | /* use cancel to push work element through before re-queue */ | ||
1269 | cancel_work_sync(&sess->del_work); | ||
1270 | INIT_WORK(&sess->del_work, qla24xx_delete_sess_fn); | 1268 | INIT_WORK(&sess->del_work, qla24xx_delete_sess_fn); |
1271 | queue_work(sess->vha->hw->wq, &sess->del_work); | 1269 | WARN_ON(!queue_work(sess->vha->hw->wq, &sess->del_work)); |
1272 | } | 1270 | } |
1273 | 1271 | ||
1274 | /* ha->tgt.sess_lock supposed to be held on entry */ | ||
1275 | static void qlt_clear_tgt_db(struct qla_tgt *tgt) | 1272 | static void qlt_clear_tgt_db(struct qla_tgt *tgt) |
1276 | { | 1273 | { |
1277 | struct fc_port *sess; | 1274 | struct fc_port *sess; |
@@ -1454,8 +1451,8 @@ qlt_fc_port_deleted(struct scsi_qla_host *vha, fc_port_t *fcport, int max_gen) | |||
1454 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf008, "qla_tgt_fc_port_deleted %p", sess); | 1451 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf008, "qla_tgt_fc_port_deleted %p", sess); |
1455 | 1452 | ||
1456 | sess->local = 1; | 1453 | sess->local = 1; |
1457 | qlt_schedule_sess_for_deletion(sess); | ||
1458 | spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); | 1454 | spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); |
1455 | qlt_schedule_sess_for_deletion(sess); | ||
1459 | } | 1456 | } |
1460 | 1457 | ||
1461 | static inline int test_tgt_sess_count(struct qla_tgt *tgt) | 1458 | static inline int test_tgt_sess_count(struct qla_tgt *tgt) |
@@ -1515,10 +1512,8 @@ int qlt_stop_phase1(struct qla_tgt *tgt) | |||
1515 | * Lock is needed, because we still can get an incoming packet. | 1512 | * Lock is needed, because we still can get an incoming packet. |
1516 | */ | 1513 | */ |
1517 | mutex_lock(&vha->vha_tgt.tgt_mutex); | 1514 | mutex_lock(&vha->vha_tgt.tgt_mutex); |
1518 | spin_lock_irqsave(&ha->tgt.sess_lock, flags); | ||
1519 | tgt->tgt_stop = 1; | 1515 | tgt->tgt_stop = 1; |
1520 | qlt_clear_tgt_db(tgt); | 1516 | qlt_clear_tgt_db(tgt); |
1521 | spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); | ||
1522 | mutex_unlock(&vha->vha_tgt.tgt_mutex); | 1517 | mutex_unlock(&vha->vha_tgt.tgt_mutex); |
1523 | mutex_unlock(&qla_tgt_mutex); | 1518 | mutex_unlock(&qla_tgt_mutex); |
1524 | 1519 | ||
@@ -4869,8 +4864,6 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha, | |||
4869 | sess); | 4864 | sess); |
4870 | qlt_send_term_imm_notif(vha, iocb, 1); | 4865 | qlt_send_term_imm_notif(vha, iocb, 1); |
4871 | res = 0; | 4866 | res = 0; |
4872 | spin_lock_irqsave(&tgt->ha->tgt.sess_lock, | ||
4873 | flags); | ||
4874 | break; | 4867 | break; |
4875 | } | 4868 | } |
4876 | 4869 | ||
diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h index fc233717355f..817f312023a9 100644 --- a/drivers/scsi/qla4xxx/ql4_def.h +++ b/drivers/scsi/qla4xxx/ql4_def.h | |||
@@ -168,6 +168,8 @@ | |||
168 | #define DEV_DB_NON_PERSISTENT 0 | 168 | #define DEV_DB_NON_PERSISTENT 0 |
169 | #define DEV_DB_PERSISTENT 1 | 169 | #define DEV_DB_PERSISTENT 1 |
170 | 170 | ||
171 | #define QL4_ISP_REG_DISCONNECT 0xffffffffU | ||
172 | |||
171 | #define COPY_ISID(dst_isid, src_isid) { \ | 173 | #define COPY_ISID(dst_isid, src_isid) { \ |
172 | int i, j; \ | 174 | int i, j; \ |
173 | for (i = 0, j = ISID_SIZE - 1; i < ISID_SIZE;) \ | 175 | for (i = 0, j = ISID_SIZE - 1; i < ISID_SIZE;) \ |
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 589634358c83..94c14ce94da2 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c | |||
@@ -262,6 +262,24 @@ static struct iscsi_transport qla4xxx_iscsi_transport = { | |||
262 | 262 | ||
263 | static struct scsi_transport_template *qla4xxx_scsi_transport; | 263 | static struct scsi_transport_template *qla4xxx_scsi_transport; |
264 | 264 | ||
265 | static int qla4xxx_isp_check_reg(struct scsi_qla_host *ha) | ||
266 | { | ||
267 | u32 reg_val = 0; | ||
268 | int rval = QLA_SUCCESS; | ||
269 | |||
270 | if (is_qla8022(ha)) | ||
271 | reg_val = readl(&ha->qla4_82xx_reg->host_status); | ||
272 | else if (is_qla8032(ha) || is_qla8042(ha)) | ||
273 | reg_val = qla4_8xxx_rd_direct(ha, QLA8XXX_PEG_ALIVE_COUNTER); | ||
274 | else | ||
275 | reg_val = readw(&ha->reg->ctrl_status); | ||
276 | |||
277 | if (reg_val == QL4_ISP_REG_DISCONNECT) | ||
278 | rval = QLA_ERROR; | ||
279 | |||
280 | return rval; | ||
281 | } | ||
282 | |||
265 | static int qla4xxx_send_ping(struct Scsi_Host *shost, uint32_t iface_num, | 283 | static int qla4xxx_send_ping(struct Scsi_Host *shost, uint32_t iface_num, |
266 | uint32_t iface_type, uint32_t payload_size, | 284 | uint32_t iface_type, uint32_t payload_size, |
267 | uint32_t pid, struct sockaddr *dst_addr) | 285 | uint32_t pid, struct sockaddr *dst_addr) |
@@ -9184,10 +9202,17 @@ static int qla4xxx_eh_abort(struct scsi_cmnd *cmd) | |||
9184 | struct srb *srb = NULL; | 9202 | struct srb *srb = NULL; |
9185 | int ret = SUCCESS; | 9203 | int ret = SUCCESS; |
9186 | int wait = 0; | 9204 | int wait = 0; |
9205 | int rval; | ||
9187 | 9206 | ||
9188 | ql4_printk(KERN_INFO, ha, "scsi%ld:%d:%llu: Abort command issued cmd=%p, cdb=0x%x\n", | 9207 | ql4_printk(KERN_INFO, ha, "scsi%ld:%d:%llu: Abort command issued cmd=%p, cdb=0x%x\n", |
9189 | ha->host_no, id, lun, cmd, cmd->cmnd[0]); | 9208 | ha->host_no, id, lun, cmd, cmd->cmnd[0]); |
9190 | 9209 | ||
9210 | rval = qla4xxx_isp_check_reg(ha); | ||
9211 | if (rval != QLA_SUCCESS) { | ||
9212 | ql4_printk(KERN_INFO, ha, "PCI/Register disconnect, exiting.\n"); | ||
9213 | return FAILED; | ||
9214 | } | ||
9215 | |||
9191 | spin_lock_irqsave(&ha->hardware_lock, flags); | 9216 | spin_lock_irqsave(&ha->hardware_lock, flags); |
9192 | srb = (struct srb *) CMD_SP(cmd); | 9217 | srb = (struct srb *) CMD_SP(cmd); |
9193 | if (!srb) { | 9218 | if (!srb) { |
@@ -9239,6 +9264,7 @@ static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd) | |||
9239 | struct scsi_qla_host *ha = to_qla_host(cmd->device->host); | 9264 | struct scsi_qla_host *ha = to_qla_host(cmd->device->host); |
9240 | struct ddb_entry *ddb_entry = cmd->device->hostdata; | 9265 | struct ddb_entry *ddb_entry = cmd->device->hostdata; |
9241 | int ret = FAILED, stat; | 9266 | int ret = FAILED, stat; |
9267 | int rval; | ||
9242 | 9268 | ||
9243 | if (!ddb_entry) | 9269 | if (!ddb_entry) |
9244 | return ret; | 9270 | return ret; |
@@ -9258,6 +9284,12 @@ static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd) | |||
9258 | cmd, jiffies, cmd->request->timeout / HZ, | 9284 | cmd, jiffies, cmd->request->timeout / HZ, |
9259 | ha->dpc_flags, cmd->result, cmd->allowed)); | 9285 | ha->dpc_flags, cmd->result, cmd->allowed)); |
9260 | 9286 | ||
9287 | rval = qla4xxx_isp_check_reg(ha); | ||
9288 | if (rval != QLA_SUCCESS) { | ||
9289 | ql4_printk(KERN_INFO, ha, "PCI/Register disconnect, exiting.\n"); | ||
9290 | return FAILED; | ||
9291 | } | ||
9292 | |||
9261 | /* FIXME: wait for hba to go online */ | 9293 | /* FIXME: wait for hba to go online */ |
9262 | stat = qla4xxx_reset_lun(ha, ddb_entry, cmd->device->lun); | 9294 | stat = qla4xxx_reset_lun(ha, ddb_entry, cmd->device->lun); |
9263 | if (stat != QLA_SUCCESS) { | 9295 | if (stat != QLA_SUCCESS) { |
@@ -9301,6 +9333,7 @@ static int qla4xxx_eh_target_reset(struct scsi_cmnd *cmd) | |||
9301 | struct scsi_qla_host *ha = to_qla_host(cmd->device->host); | 9333 | struct scsi_qla_host *ha = to_qla_host(cmd->device->host); |
9302 | struct ddb_entry *ddb_entry = cmd->device->hostdata; | 9334 | struct ddb_entry *ddb_entry = cmd->device->hostdata; |
9303 | int stat, ret; | 9335 | int stat, ret; |
9336 | int rval; | ||
9304 | 9337 | ||
9305 | if (!ddb_entry) | 9338 | if (!ddb_entry) |
9306 | return FAILED; | 9339 | return FAILED; |
@@ -9318,6 +9351,12 @@ static int qla4xxx_eh_target_reset(struct scsi_cmnd *cmd) | |||
9318 | ha->host_no, cmd, jiffies, cmd->request->timeout / HZ, | 9351 | ha->host_no, cmd, jiffies, cmd->request->timeout / HZ, |
9319 | ha->dpc_flags, cmd->result, cmd->allowed)); | 9352 | ha->dpc_flags, cmd->result, cmd->allowed)); |
9320 | 9353 | ||
9354 | rval = qla4xxx_isp_check_reg(ha); | ||
9355 | if (rval != QLA_SUCCESS) { | ||
9356 | ql4_printk(KERN_INFO, ha, "PCI/Register disconnect, exiting.\n"); | ||
9357 | return FAILED; | ||
9358 | } | ||
9359 | |||
9321 | stat = qla4xxx_reset_target(ha, ddb_entry); | 9360 | stat = qla4xxx_reset_target(ha, ddb_entry); |
9322 | if (stat != QLA_SUCCESS) { | 9361 | if (stat != QLA_SUCCESS) { |
9323 | starget_printk(KERN_INFO, scsi_target(cmd->device), | 9362 | starget_printk(KERN_INFO, scsi_target(cmd->device), |
@@ -9372,9 +9411,16 @@ static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd) | |||
9372 | { | 9411 | { |
9373 | int return_status = FAILED; | 9412 | int return_status = FAILED; |
9374 | struct scsi_qla_host *ha; | 9413 | struct scsi_qla_host *ha; |
9414 | int rval; | ||
9375 | 9415 | ||
9376 | ha = to_qla_host(cmd->device->host); | 9416 | ha = to_qla_host(cmd->device->host); |
9377 | 9417 | ||
9418 | rval = qla4xxx_isp_check_reg(ha); | ||
9419 | if (rval != QLA_SUCCESS) { | ||
9420 | ql4_printk(KERN_INFO, ha, "PCI/Register disconnect, exiting.\n"); | ||
9421 | return FAILED; | ||
9422 | } | ||
9423 | |||
9378 | if ((is_qla8032(ha) || is_qla8042(ha)) && ql4xdontresethba) | 9424 | if ((is_qla8032(ha) || is_qla8042(ha)) && ql4xdontresethba) |
9379 | qla4_83xx_set_idc_dontreset(ha); | 9425 | qla4_83xx_set_idc_dontreset(ha); |
9380 | 9426 | ||
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index ac3b1c36c478..946039117bf4 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -229,7 +229,8 @@ static void scsi_eh_reset(struct scsi_cmnd *scmd) | |||
229 | 229 | ||
230 | static void scsi_eh_inc_host_failed(struct rcu_head *head) | 230 | static void scsi_eh_inc_host_failed(struct rcu_head *head) |
231 | { | 231 | { |
232 | struct Scsi_Host *shost = container_of(head, typeof(*shost), rcu); | 232 | struct scsi_cmnd *scmd = container_of(head, typeof(*scmd), rcu); |
233 | struct Scsi_Host *shost = scmd->device->host; | ||
233 | unsigned long flags; | 234 | unsigned long flags; |
234 | 235 | ||
235 | spin_lock_irqsave(shost->host_lock, flags); | 236 | spin_lock_irqsave(shost->host_lock, flags); |
@@ -265,7 +266,7 @@ void scsi_eh_scmd_add(struct scsi_cmnd *scmd) | |||
265 | * Ensure that all tasks observe the host state change before the | 266 | * Ensure that all tasks observe the host state change before the |
266 | * host_failed change. | 267 | * host_failed change. |
267 | */ | 268 | */ |
268 | call_rcu(&shost->rcu, scsi_eh_inc_host_failed); | 269 | call_rcu(&scmd->rcu, scsi_eh_inc_host_failed); |
269 | } | 270 | } |
270 | 271 | ||
271 | /** | 272 | /** |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 393f9db8f41b..1d83f29aee74 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -683,6 +683,7 @@ static bool scsi_end_request(struct request *req, blk_status_t error, | |||
683 | if (!blk_rq_is_scsi(req)) { | 683 | if (!blk_rq_is_scsi(req)) { |
684 | WARN_ON_ONCE(!(cmd->flags & SCMD_INITIALIZED)); | 684 | WARN_ON_ONCE(!(cmd->flags & SCMD_INITIALIZED)); |
685 | cmd->flags &= ~SCMD_INITIALIZED; | 685 | cmd->flags &= ~SCMD_INITIALIZED; |
686 | destroy_rcu_head(&cmd->rcu); | ||
686 | } | 687 | } |
687 | 688 | ||
688 | if (req->mq_ctx) { | 689 | if (req->mq_ctx) { |
@@ -732,6 +733,8 @@ static blk_status_t __scsi_error_from_host_byte(struct scsi_cmnd *cmd, | |||
732 | int result) | 733 | int result) |
733 | { | 734 | { |
734 | switch (host_byte(result)) { | 735 | switch (host_byte(result)) { |
736 | case DID_OK: | ||
737 | return BLK_STS_OK; | ||
735 | case DID_TRANSPORT_FAILFAST: | 738 | case DID_TRANSPORT_FAILFAST: |
736 | return BLK_STS_TRANSPORT; | 739 | return BLK_STS_TRANSPORT; |
737 | case DID_TARGET_FAILURE: | 740 | case DID_TARGET_FAILURE: |
@@ -1174,6 +1177,7 @@ static void scsi_initialize_rq(struct request *rq) | |||
1174 | struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq); | 1177 | struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq); |
1175 | 1178 | ||
1176 | scsi_req_init(&cmd->req); | 1179 | scsi_req_init(&cmd->req); |
1180 | init_rcu_head(&cmd->rcu); | ||
1177 | cmd->jiffies_at_alloc = jiffies; | 1181 | cmd->jiffies_at_alloc = jiffies; |
1178 | cmd->retries = 0; | 1182 | cmd->retries = 0; |
1179 | } | 1183 | } |
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index bff21e636ddd..1fa84d6a0f8b 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -2484,6 +2484,8 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer) | |||
2484 | sector_size = old_sector_size; | 2484 | sector_size = old_sector_size; |
2485 | goto got_data; | 2485 | goto got_data; |
2486 | } | 2486 | } |
2487 | /* Remember that READ CAPACITY(16) succeeded */ | ||
2488 | sdp->try_rc_10_first = 0; | ||
2487 | } | 2489 | } |
2488 | } | 2490 | } |
2489 | 2491 | ||
@@ -2595,6 +2597,7 @@ sd_read_write_protect_flag(struct scsi_disk *sdkp, unsigned char *buffer) | |||
2595 | int res; | 2597 | int res; |
2596 | struct scsi_device *sdp = sdkp->device; | 2598 | struct scsi_device *sdp = sdkp->device; |
2597 | struct scsi_mode_data data; | 2599 | struct scsi_mode_data data; |
2600 | int disk_ro = get_disk_ro(sdkp->disk); | ||
2598 | int old_wp = sdkp->write_prot; | 2601 | int old_wp = sdkp->write_prot; |
2599 | 2602 | ||
2600 | set_disk_ro(sdkp->disk, 0); | 2603 | set_disk_ro(sdkp->disk, 0); |
@@ -2635,7 +2638,7 @@ sd_read_write_protect_flag(struct scsi_disk *sdkp, unsigned char *buffer) | |||
2635 | "Test WP failed, assume Write Enabled\n"); | 2638 | "Test WP failed, assume Write Enabled\n"); |
2636 | } else { | 2639 | } else { |
2637 | sdkp->write_prot = ((data.device_specific & 0x80) != 0); | 2640 | sdkp->write_prot = ((data.device_specific & 0x80) != 0); |
2638 | set_disk_ro(sdkp->disk, sdkp->write_prot); | 2641 | set_disk_ro(sdkp->disk, sdkp->write_prot || disk_ro); |
2639 | if (sdkp->first_scan || old_wp != sdkp->write_prot) { | 2642 | if (sdkp->first_scan || old_wp != sdkp->write_prot) { |
2640 | sd_printk(KERN_NOTICE, sdkp, "Write Protect is %s\n", | 2643 | sd_printk(KERN_NOTICE, sdkp, "Write Protect is %s\n", |
2641 | sdkp->write_prot ? "on" : "off"); | 2644 | sdkp->write_prot ? "on" : "off"); |
diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c index 8f3669fd490d..41df75eea57b 100644 --- a/drivers/scsi/sd_zbc.c +++ b/drivers/scsi/sd_zbc.c | |||
@@ -403,7 +403,7 @@ static int sd_zbc_check_capacity(struct scsi_disk *sdkp, unsigned char *buf) | |||
403 | */ | 403 | */ |
404 | static int sd_zbc_check_zone_size(struct scsi_disk *sdkp) | 404 | static int sd_zbc_check_zone_size(struct scsi_disk *sdkp) |
405 | { | 405 | { |
406 | u64 zone_blocks; | 406 | u64 zone_blocks = 0; |
407 | sector_t block = 0; | 407 | sector_t block = 0; |
408 | unsigned char *buf; | 408 | unsigned char *buf; |
409 | unsigned char *rec; | 409 | unsigned char *rec; |
@@ -421,10 +421,8 @@ static int sd_zbc_check_zone_size(struct scsi_disk *sdkp) | |||
421 | 421 | ||
422 | /* Do a report zone to get the same field */ | 422 | /* Do a report zone to get the same field */ |
423 | ret = sd_zbc_report_zones(sdkp, buf, SD_ZBC_BUF_SIZE, 0); | 423 | ret = sd_zbc_report_zones(sdkp, buf, SD_ZBC_BUF_SIZE, 0); |
424 | if (ret) { | 424 | if (ret) |
425 | zone_blocks = 0; | 425 | goto out_free; |
426 | goto out; | ||
427 | } | ||
428 | 426 | ||
429 | same = buf[4] & 0x0f; | 427 | same = buf[4] & 0x0f; |
430 | if (same > 0) { | 428 | if (same > 0) { |
@@ -464,7 +462,7 @@ static int sd_zbc_check_zone_size(struct scsi_disk *sdkp) | |||
464 | ret = sd_zbc_report_zones(sdkp, buf, | 462 | ret = sd_zbc_report_zones(sdkp, buf, |
465 | SD_ZBC_BUF_SIZE, block); | 463 | SD_ZBC_BUF_SIZE, block); |
466 | if (ret) | 464 | if (ret) |
467 | return ret; | 465 | goto out_free; |
468 | } | 466 | } |
469 | 467 | ||
470 | } while (block < sdkp->capacity); | 468 | } while (block < sdkp->capacity); |
@@ -472,35 +470,32 @@ static int sd_zbc_check_zone_size(struct scsi_disk *sdkp) | |||
472 | zone_blocks = sdkp->zone_blocks; | 470 | zone_blocks = sdkp->zone_blocks; |
473 | 471 | ||
474 | out: | 472 | out: |
475 | kfree(buf); | ||
476 | |||
477 | if (!zone_blocks) { | 473 | if (!zone_blocks) { |
478 | if (sdkp->first_scan) | 474 | if (sdkp->first_scan) |
479 | sd_printk(KERN_NOTICE, sdkp, | 475 | sd_printk(KERN_NOTICE, sdkp, |
480 | "Devices with non constant zone " | 476 | "Devices with non constant zone " |
481 | "size are not supported\n"); | 477 | "size are not supported\n"); |
482 | return -ENODEV; | 478 | ret = -ENODEV; |
483 | } | 479 | } else if (!is_power_of_2(zone_blocks)) { |
484 | |||
485 | if (!is_power_of_2(zone_blocks)) { | ||
486 | if (sdkp->first_scan) | 480 | if (sdkp->first_scan) |
487 | sd_printk(KERN_NOTICE, sdkp, | 481 | sd_printk(KERN_NOTICE, sdkp, |
488 | "Devices with non power of 2 zone " | 482 | "Devices with non power of 2 zone " |
489 | "size are not supported\n"); | 483 | "size are not supported\n"); |
490 | return -ENODEV; | 484 | ret = -ENODEV; |
491 | } | 485 | } else if (logical_to_sectors(sdkp->device, zone_blocks) > UINT_MAX) { |
492 | |||
493 | if (logical_to_sectors(sdkp->device, zone_blocks) > UINT_MAX) { | ||
494 | if (sdkp->first_scan) | 486 | if (sdkp->first_scan) |
495 | sd_printk(KERN_NOTICE, sdkp, | 487 | sd_printk(KERN_NOTICE, sdkp, |
496 | "Zone size too large\n"); | 488 | "Zone size too large\n"); |
497 | return -ENODEV; | 489 | ret = -ENODEV; |
490 | } else { | ||
491 | sdkp->zone_blocks = zone_blocks; | ||
492 | sdkp->zone_shift = ilog2(zone_blocks); | ||
498 | } | 493 | } |
499 | 494 | ||
500 | sdkp->zone_blocks = zone_blocks; | 495 | out_free: |
501 | sdkp->zone_shift = ilog2(zone_blocks); | 496 | kfree(buf); |
502 | 497 | ||
503 | return 0; | 498 | return ret; |
504 | } | 499 | } |
505 | 500 | ||
506 | /** | 501 | /** |
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 40fc7a590e81..8c51d628b52e 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c | |||
@@ -1311,7 +1311,8 @@ static int storvsc_do_io(struct hv_device *device, | |||
1311 | */ | 1311 | */ |
1312 | cpumask_and(&alloced_mask, &stor_device->alloced_cpus, | 1312 | cpumask_and(&alloced_mask, &stor_device->alloced_cpus, |
1313 | cpumask_of_node(cpu_to_node(q_num))); | 1313 | cpumask_of_node(cpu_to_node(q_num))); |
1314 | for_each_cpu(tgt_cpu, &alloced_mask) { | 1314 | for_each_cpu_wrap(tgt_cpu, &alloced_mask, |
1315 | outgoing_channel->target_cpu + 1) { | ||
1315 | if (tgt_cpu != outgoing_channel->target_cpu) { | 1316 | if (tgt_cpu != outgoing_channel->target_cpu) { |
1316 | outgoing_channel = | 1317 | outgoing_channel = |
1317 | stor_device->stor_chns[tgt_cpu]; | 1318 | stor_device->stor_chns[tgt_cpu]; |
@@ -1657,7 +1658,7 @@ static struct scsi_host_template scsi_driver = { | |||
1657 | .eh_timed_out = storvsc_eh_timed_out, | 1658 | .eh_timed_out = storvsc_eh_timed_out, |
1658 | .slave_alloc = storvsc_device_alloc, | 1659 | .slave_alloc = storvsc_device_alloc, |
1659 | .slave_configure = storvsc_device_configure, | 1660 | .slave_configure = storvsc_device_configure, |
1660 | .cmd_per_lun = 255, | 1661 | .cmd_per_lun = 2048, |
1661 | .this_id = -1, | 1662 | .this_id = -1, |
1662 | .use_clustering = ENABLE_CLUSTERING, | 1663 | .use_clustering = ENABLE_CLUSTERING, |
1663 | /* Make sure we dont get a sg segment crosses a page boundary */ | 1664 | /* Make sure we dont get a sg segment crosses a page boundary */ |
diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c index ca360daa6a25..378af306fda1 100644 --- a/drivers/scsi/sym53c8xx_2/sym_hipd.c +++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c | |||
@@ -536,7 +536,7 @@ sym_getsync(struct sym_hcb *np, u_char dt, u_char sfac, u_char *divp, u_char *fa | |||
536 | * Look for the greatest clock divisor that allows an | 536 | * Look for the greatest clock divisor that allows an |
537 | * input speed faster than the period. | 537 | * input speed faster than the period. |
538 | */ | 538 | */ |
539 | while (div-- > 0) | 539 | while (--div > 0) |
540 | if (kpc >= (div_10M[div] << 2)) break; | 540 | if (kpc >= (div_10M[div] << 2)) break; |
541 | 541 | ||
542 | /* | 542 | /* |
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index facee2b97926..c5b1bf1cadcb 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c | |||
@@ -4331,6 +4331,8 @@ static int ufshcd_slave_alloc(struct scsi_device *sdev) | |||
4331 | /* REPORT SUPPORTED OPERATION CODES is not supported */ | 4331 | /* REPORT SUPPORTED OPERATION CODES is not supported */ |
4332 | sdev->no_report_opcodes = 1; | 4332 | sdev->no_report_opcodes = 1; |
4333 | 4333 | ||
4334 | /* WRITE_SAME command is not supported */ | ||
4335 | sdev->no_write_same = 1; | ||
4334 | 4336 | ||
4335 | ufshcd_set_queue_depth(sdev); | 4337 | ufshcd_set_queue_depth(sdev); |
4336 | 4338 | ||
diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c index 7c28e8d4955a..45d04631888a 100644 --- a/drivers/scsi/virtio_scsi.c +++ b/drivers/scsi/virtio_scsi.c | |||
@@ -91,9 +91,6 @@ struct virtio_scsi_vq { | |||
91 | struct virtio_scsi_target_state { | 91 | struct virtio_scsi_target_state { |
92 | seqcount_t tgt_seq; | 92 | seqcount_t tgt_seq; |
93 | 93 | ||
94 | /* Count of outstanding requests. */ | ||
95 | atomic_t reqs; | ||
96 | |||
97 | /* Currently active virtqueue for requests sent to this target. */ | 94 | /* Currently active virtqueue for requests sent to this target. */ |
98 | struct virtio_scsi_vq *req_vq; | 95 | struct virtio_scsi_vq *req_vq; |
99 | }; | 96 | }; |
@@ -152,8 +149,6 @@ static void virtscsi_complete_cmd(struct virtio_scsi *vscsi, void *buf) | |||
152 | struct virtio_scsi_cmd *cmd = buf; | 149 | struct virtio_scsi_cmd *cmd = buf; |
153 | struct scsi_cmnd *sc = cmd->sc; | 150 | struct scsi_cmnd *sc = cmd->sc; |
154 | struct virtio_scsi_cmd_resp *resp = &cmd->resp.cmd; | 151 | struct virtio_scsi_cmd_resp *resp = &cmd->resp.cmd; |
155 | struct virtio_scsi_target_state *tgt = | ||
156 | scsi_target(sc->device)->hostdata; | ||
157 | 152 | ||
158 | dev_dbg(&sc->device->sdev_gendev, | 153 | dev_dbg(&sc->device->sdev_gendev, |
159 | "cmd %p response %u status %#02x sense_len %u\n", | 154 | "cmd %p response %u status %#02x sense_len %u\n", |
@@ -210,8 +205,6 @@ static void virtscsi_complete_cmd(struct virtio_scsi *vscsi, void *buf) | |||
210 | } | 205 | } |
211 | 206 | ||
212 | sc->scsi_done(sc); | 207 | sc->scsi_done(sc); |
213 | |||
214 | atomic_dec(&tgt->reqs); | ||
215 | } | 208 | } |
216 | 209 | ||
217 | static void virtscsi_vq_done(struct virtio_scsi *vscsi, | 210 | static void virtscsi_vq_done(struct virtio_scsi *vscsi, |
@@ -529,11 +522,20 @@ static void virtio_scsi_init_hdr_pi(struct virtio_device *vdev, | |||
529 | } | 522 | } |
530 | #endif | 523 | #endif |
531 | 524 | ||
532 | static int virtscsi_queuecommand(struct virtio_scsi *vscsi, | 525 | static struct virtio_scsi_vq *virtscsi_pick_vq_mq(struct virtio_scsi *vscsi, |
533 | struct virtio_scsi_vq *req_vq, | 526 | struct scsi_cmnd *sc) |
527 | { | ||
528 | u32 tag = blk_mq_unique_tag(sc->request); | ||
529 | u16 hwq = blk_mq_unique_tag_to_hwq(tag); | ||
530 | |||
531 | return &vscsi->req_vqs[hwq]; | ||
532 | } | ||
533 | |||
534 | static int virtscsi_queuecommand(struct Scsi_Host *shost, | ||
534 | struct scsi_cmnd *sc) | 535 | struct scsi_cmnd *sc) |
535 | { | 536 | { |
536 | struct Scsi_Host *shost = virtio_scsi_host(vscsi->vdev); | 537 | struct virtio_scsi *vscsi = shost_priv(shost); |
538 | struct virtio_scsi_vq *req_vq = virtscsi_pick_vq_mq(vscsi, sc); | ||
537 | struct virtio_scsi_cmd *cmd = scsi_cmd_priv(sc); | 539 | struct virtio_scsi_cmd *cmd = scsi_cmd_priv(sc); |
538 | unsigned long flags; | 540 | unsigned long flags; |
539 | int req_size; | 541 | int req_size; |
@@ -576,79 +578,6 @@ static int virtscsi_queuecommand(struct virtio_scsi *vscsi, | |||
576 | return 0; | 578 | return 0; |
577 | } | 579 | } |
578 | 580 | ||
579 | static int virtscsi_queuecommand_single(struct Scsi_Host *sh, | ||
580 | struct scsi_cmnd *sc) | ||
581 | { | ||
582 | struct virtio_scsi *vscsi = shost_priv(sh); | ||
583 | struct virtio_scsi_target_state *tgt = | ||
584 | scsi_target(sc->device)->hostdata; | ||
585 | |||
586 | atomic_inc(&tgt->reqs); | ||
587 | return virtscsi_queuecommand(vscsi, &vscsi->req_vqs[0], sc); | ||
588 | } | ||
589 | |||
590 | static struct virtio_scsi_vq *virtscsi_pick_vq_mq(struct virtio_scsi *vscsi, | ||
591 | struct scsi_cmnd *sc) | ||
592 | { | ||
593 | u32 tag = blk_mq_unique_tag(sc->request); | ||
594 | u16 hwq = blk_mq_unique_tag_to_hwq(tag); | ||
595 | |||
596 | return &vscsi->req_vqs[hwq]; | ||
597 | } | ||
598 | |||
599 | static struct virtio_scsi_vq *virtscsi_pick_vq(struct virtio_scsi *vscsi, | ||
600 | struct virtio_scsi_target_state *tgt) | ||
601 | { | ||
602 | struct virtio_scsi_vq *vq; | ||
603 | unsigned long flags; | ||
604 | u32 queue_num; | ||
605 | |||
606 | local_irq_save(flags); | ||
607 | if (atomic_inc_return(&tgt->reqs) > 1) { | ||
608 | unsigned long seq; | ||
609 | |||
610 | do { | ||
611 | seq = read_seqcount_begin(&tgt->tgt_seq); | ||
612 | vq = tgt->req_vq; | ||
613 | } while (read_seqcount_retry(&tgt->tgt_seq, seq)); | ||
614 | } else { | ||
615 | /* no writes can be concurrent because of atomic_t */ | ||
616 | write_seqcount_begin(&tgt->tgt_seq); | ||
617 | |||
618 | /* keep previous req_vq if a reader just arrived */ | ||
619 | if (unlikely(atomic_read(&tgt->reqs) > 1)) { | ||
620 | vq = tgt->req_vq; | ||
621 | goto unlock; | ||
622 | } | ||
623 | |||
624 | queue_num = smp_processor_id(); | ||
625 | while (unlikely(queue_num >= vscsi->num_queues)) | ||
626 | queue_num -= vscsi->num_queues; | ||
627 | tgt->req_vq = vq = &vscsi->req_vqs[queue_num]; | ||
628 | unlock: | ||
629 | write_seqcount_end(&tgt->tgt_seq); | ||
630 | } | ||
631 | local_irq_restore(flags); | ||
632 | |||
633 | return vq; | ||
634 | } | ||
635 | |||
636 | static int virtscsi_queuecommand_multi(struct Scsi_Host *sh, | ||
637 | struct scsi_cmnd *sc) | ||
638 | { | ||
639 | struct virtio_scsi *vscsi = shost_priv(sh); | ||
640 | struct virtio_scsi_target_state *tgt = | ||
641 | scsi_target(sc->device)->hostdata; | ||
642 | struct virtio_scsi_vq *req_vq; | ||
643 | |||
644 | if (shost_use_blk_mq(sh)) | ||
645 | req_vq = virtscsi_pick_vq_mq(vscsi, sc); | ||
646 | else | ||
647 | req_vq = virtscsi_pick_vq(vscsi, tgt); | ||
648 | |||
649 | return virtscsi_queuecommand(vscsi, req_vq, sc); | ||
650 | } | ||
651 | |||
652 | static int virtscsi_tmf(struct virtio_scsi *vscsi, struct virtio_scsi_cmd *cmd) | 581 | static int virtscsi_tmf(struct virtio_scsi *vscsi, struct virtio_scsi_cmd *cmd) |
653 | { | 582 | { |
654 | DECLARE_COMPLETION_ONSTACK(comp); | 583 | DECLARE_COMPLETION_ONSTACK(comp); |
@@ -775,7 +704,6 @@ static int virtscsi_target_alloc(struct scsi_target *starget) | |||
775 | return -ENOMEM; | 704 | return -ENOMEM; |
776 | 705 | ||
777 | seqcount_init(&tgt->tgt_seq); | 706 | seqcount_init(&tgt->tgt_seq); |
778 | atomic_set(&tgt->reqs, 0); | ||
779 | tgt->req_vq = &vscsi->req_vqs[0]; | 707 | tgt->req_vq = &vscsi->req_vqs[0]; |
780 | 708 | ||
781 | starget->hostdata = tgt; | 709 | starget->hostdata = tgt; |
@@ -805,33 +733,13 @@ static enum blk_eh_timer_return virtscsi_eh_timed_out(struct scsi_cmnd *scmnd) | |||
805 | return BLK_EH_RESET_TIMER; | 733 | return BLK_EH_RESET_TIMER; |
806 | } | 734 | } |
807 | 735 | ||
808 | static struct scsi_host_template virtscsi_host_template_single = { | 736 | static struct scsi_host_template virtscsi_host_template = { |
809 | .module = THIS_MODULE, | ||
810 | .name = "Virtio SCSI HBA", | ||
811 | .proc_name = "virtio_scsi", | ||
812 | .this_id = -1, | ||
813 | .cmd_size = sizeof(struct virtio_scsi_cmd), | ||
814 | .queuecommand = virtscsi_queuecommand_single, | ||
815 | .change_queue_depth = virtscsi_change_queue_depth, | ||
816 | .eh_abort_handler = virtscsi_abort, | ||
817 | .eh_device_reset_handler = virtscsi_device_reset, | ||
818 | .eh_timed_out = virtscsi_eh_timed_out, | ||
819 | .slave_alloc = virtscsi_device_alloc, | ||
820 | |||
821 | .dma_boundary = UINT_MAX, | ||
822 | .use_clustering = ENABLE_CLUSTERING, | ||
823 | .target_alloc = virtscsi_target_alloc, | ||
824 | .target_destroy = virtscsi_target_destroy, | ||
825 | .track_queue_depth = 1, | ||
826 | }; | ||
827 | |||
828 | static struct scsi_host_template virtscsi_host_template_multi = { | ||
829 | .module = THIS_MODULE, | 737 | .module = THIS_MODULE, |
830 | .name = "Virtio SCSI HBA", | 738 | .name = "Virtio SCSI HBA", |
831 | .proc_name = "virtio_scsi", | 739 | .proc_name = "virtio_scsi", |
832 | .this_id = -1, | 740 | .this_id = -1, |
833 | .cmd_size = sizeof(struct virtio_scsi_cmd), | 741 | .cmd_size = sizeof(struct virtio_scsi_cmd), |
834 | .queuecommand = virtscsi_queuecommand_multi, | 742 | .queuecommand = virtscsi_queuecommand, |
835 | .change_queue_depth = virtscsi_change_queue_depth, | 743 | .change_queue_depth = virtscsi_change_queue_depth, |
836 | .eh_abort_handler = virtscsi_abort, | 744 | .eh_abort_handler = virtscsi_abort, |
837 | .eh_device_reset_handler = virtscsi_device_reset, | 745 | .eh_device_reset_handler = virtscsi_device_reset, |
@@ -844,6 +752,7 @@ static struct scsi_host_template virtscsi_host_template_multi = { | |||
844 | .target_destroy = virtscsi_target_destroy, | 752 | .target_destroy = virtscsi_target_destroy, |
845 | .map_queues = virtscsi_map_queues, | 753 | .map_queues = virtscsi_map_queues, |
846 | .track_queue_depth = 1, | 754 | .track_queue_depth = 1, |
755 | .force_blk_mq = 1, | ||
847 | }; | 756 | }; |
848 | 757 | ||
849 | #define virtscsi_config_get(vdev, fld) \ | 758 | #define virtscsi_config_get(vdev, fld) \ |
@@ -936,7 +845,6 @@ static int virtscsi_probe(struct virtio_device *vdev) | |||
936 | u32 sg_elems, num_targets; | 845 | u32 sg_elems, num_targets; |
937 | u32 cmd_per_lun; | 846 | u32 cmd_per_lun; |
938 | u32 num_queues; | 847 | u32 num_queues; |
939 | struct scsi_host_template *hostt; | ||
940 | 848 | ||
941 | if (!vdev->config->get) { | 849 | if (!vdev->config->get) { |
942 | dev_err(&vdev->dev, "%s failure: config access disabled\n", | 850 | dev_err(&vdev->dev, "%s failure: config access disabled\n", |
@@ -949,12 +857,7 @@ static int virtscsi_probe(struct virtio_device *vdev) | |||
949 | 857 | ||
950 | num_targets = virtscsi_config_get(vdev, max_target) + 1; | 858 | num_targets = virtscsi_config_get(vdev, max_target) + 1; |
951 | 859 | ||
952 | if (num_queues == 1) | 860 | shost = scsi_host_alloc(&virtscsi_host_template, |
953 | hostt = &virtscsi_host_template_single; | ||
954 | else | ||
955 | hostt = &virtscsi_host_template_multi; | ||
956 | |||
957 | shost = scsi_host_alloc(hostt, | ||
958 | sizeof(*vscsi) + sizeof(vscsi->req_vqs[0]) * num_queues); | 861 | sizeof(*vscsi) + sizeof(vscsi->req_vqs[0]) * num_queues); |
959 | if (!shost) | 862 | if (!shost) |
960 | return -ENOMEM; | 863 | return -ENOMEM; |
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index d8d4a902a88d..2280b2351739 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h | |||
@@ -68,6 +68,9 @@ struct scsi_cmnd { | |||
68 | struct list_head list; /* scsi_cmnd participates in queue lists */ | 68 | struct list_head list; /* scsi_cmnd participates in queue lists */ |
69 | struct list_head eh_entry; /* entry for the host eh_cmd_q */ | 69 | struct list_head eh_entry; /* entry for the host eh_cmd_q */ |
70 | struct delayed_work abort_work; | 70 | struct delayed_work abort_work; |
71 | |||
72 | struct rcu_head rcu; | ||
73 | |||
71 | int eh_eflags; /* Used by error handlr */ | 74 | int eh_eflags; /* Used by error handlr */ |
72 | 75 | ||
73 | /* | 76 | /* |
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index 4e418fb539f8..12f454cb6f61 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h | |||
@@ -437,6 +437,9 @@ struct scsi_host_template { | |||
437 | /* True if the controller does not support WRITE SAME */ | 437 | /* True if the controller does not support WRITE SAME */ |
438 | unsigned no_write_same:1; | 438 | unsigned no_write_same:1; |
439 | 439 | ||
440 | /* True if the low-level driver supports blk-mq only */ | ||
441 | unsigned force_blk_mq:1; | ||
442 | |||
440 | /* | 443 | /* |
441 | * Countdown for host blocking with no commands outstanding. | 444 | * Countdown for host blocking with no commands outstanding. |
442 | */ | 445 | */ |
@@ -553,8 +556,6 @@ struct Scsi_Host { | |||
553 | struct blk_mq_tag_set tag_set; | 556 | struct blk_mq_tag_set tag_set; |
554 | }; | 557 | }; |
555 | 558 | ||
556 | struct rcu_head rcu; | ||
557 | |||
558 | atomic_t host_busy; /* commands actually active on low-level */ | 559 | atomic_t host_busy; /* commands actually active on low-level */ |
559 | atomic_t host_blocked; | 560 | atomic_t host_blocked; |
560 | 561 | ||