You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'fixes' into misc
Somewhat nasty merge due to conflicts between "33b28357dd00 scsi: qla2xxx: Fix Async GPN_FT for FCP and FC-NVMe scan" and "2b5b96473efc scsi: qla2xxx: Fix FC-NVMe LUN discovery" Merge is non-trivial and has been verified by Qlogic (Cavium) Signed-off-by: James E.J. Bottomley <jejb@linux.vnet.ibm.com>
This commit is contained in:
@@ -2687,6 +2687,8 @@ mptctl_hp_targetinfo(unsigned long arg)
|
||||
__FILE__, __LINE__, iocnum);
|
||||
return -ENODEV;
|
||||
}
|
||||
if (karg.hdr.id >= MPT_MAX_FC_DEVICES)
|
||||
return -EINVAL;
|
||||
dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_hp_targetinfo called.\n",
|
||||
ioc->name));
|
||||
|
||||
|
||||
@@ -180,7 +180,6 @@ ncr53c8xx-flags-$(CONFIG_SCSI_ZALON) \
|
||||
CFLAGS_ncr53c8xx.o := $(ncr53c8xx-flags-y) $(ncr53c8xx-flags-m)
|
||||
zalon7xx-objs := zalon.o ncr53c8xx.o
|
||||
NCR_Q720_mod-objs := NCR_Q720.o ncr53c8xx.o
|
||||
oktagon_esp_mod-objs := oktagon_esp.o oktagon_io.o
|
||||
|
||||
# Files generated that shall be removed upon make clean
|
||||
clean-files := 53c700_d.h 53c700_u.h
|
||||
|
||||
@@ -1693,8 +1693,10 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
* Map in the registers from the adapter.
|
||||
*/
|
||||
aac->base_size = AAC_MIN_FOOTPRINT_SIZE;
|
||||
if ((*aac_drivers[index].init)(aac))
|
||||
if ((*aac_drivers[index].init)(aac)) {
|
||||
error = -ENODEV;
|
||||
goto out_unmap;
|
||||
}
|
||||
|
||||
if (aac->sync_mode) {
|
||||
if (aac_sync_mode)
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Implementation of Utility functions for all SCSI device types.
|
||||
*
|
||||
* Copyright (c) 1997, 1998, 1999 Justin T. Gibbs.
|
||||
* Copyright (c) 1997, 1998 Kenneth D. Merry.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions, and the following disclaimer,
|
||||
* without modification, immediately at the beginning of the file.
|
||||
* 2. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD: src/sys/cam/scsi/scsi_all.c,v 1.38 2002/09/23 04:56:35 mjacob Exp $
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "aiclib.h"
|
||||
|
||||
@@ -1889,6 +1889,7 @@ void bnx2fc_process_scsi_cmd_compl(struct bnx2fc_cmd *io_req,
|
||||
/* we will not receive ABTS response for this IO */
|
||||
BNX2FC_IO_DBG(io_req, "Timer context finished processing "
|
||||
"this scsi cmd\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Cancel the timeout_work, as we received IO completion */
|
||||
|
||||
@@ -114,7 +114,7 @@ static enum csio_ln_ev fwevt_to_lnevt[] = {
|
||||
static struct csio_lnode *
|
||||
csio_ln_lookup_by_portid(struct csio_hw *hw, uint8_t portid)
|
||||
{
|
||||
struct csio_lnode *ln = hw->rln;
|
||||
struct csio_lnode *ln;
|
||||
struct list_head *tmp;
|
||||
|
||||
/* Match siblings lnode with portid */
|
||||
|
||||
@@ -876,6 +876,11 @@ static void alua_rtpg_work(struct work_struct *work)
|
||||
|
||||
/**
|
||||
* alua_rtpg_queue() - cause RTPG to be submitted asynchronously
|
||||
* @pg: ALUA port group associated with @sdev.
|
||||
* @sdev: SCSI device for which to submit an RTPG.
|
||||
* @qdata: Information about the callback to invoke after the RTPG.
|
||||
* @force: Whether or not to submit an RTPG if a work item that will submit an
|
||||
* RTPG already has been scheduled.
|
||||
*
|
||||
* Returns true if and only if alua_rtpg_work() will be called asynchronously.
|
||||
* That function is responsible for calling @qdata->fn().
|
||||
|
||||
@@ -333,8 +333,6 @@ static void scsi_host_dev_release(struct device *dev)
|
||||
if (shost->work_q)
|
||||
destroy_workqueue(shost->work_q);
|
||||
|
||||
destroy_rcu_head(&shost->rcu);
|
||||
|
||||
if (shost->shost_state == SHOST_CREATED) {
|
||||
/*
|
||||
* 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)
|
||||
INIT_LIST_HEAD(&shost->starved_list);
|
||||
init_waitqueue_head(&shost->host_wait);
|
||||
mutex_init(&shost->scan_mutex);
|
||||
init_rcu_head(&shost->rcu);
|
||||
|
||||
index = ida_simple_get(&host_index_ida, 0, 0, GFP_KERNEL);
|
||||
if (index < 0)
|
||||
@@ -476,6 +473,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
|
||||
shost->dma_boundary = 0xffffffff;
|
||||
|
||||
shost->use_blk_mq = scsi_use_blk_mq;
|
||||
shost->use_blk_mq = scsi_use_blk_mq || shost->hostt->force_blk_mq;
|
||||
|
||||
device_initialize(&shost->shost_gendev);
|
||||
dev_set_name(&shost->shost_gendev, "host%d", shost->host_no);
|
||||
|
||||
+54
-19
@@ -1045,11 +1045,7 @@ static void set_performant_mode(struct ctlr_info *h, struct CommandList *c,
|
||||
c->busaddr |= 1 | (h->blockFetchTable[c->Header.SGList] << 1);
|
||||
if (unlikely(!h->msix_vectors))
|
||||
return;
|
||||
if (likely(reply_queue == DEFAULT_REPLY_QUEUE))
|
||||
c->Header.ReplyQueue =
|
||||
raw_smp_processor_id() % h->nreply_queues;
|
||||
else
|
||||
c->Header.ReplyQueue = reply_queue % h->nreply_queues;
|
||||
c->Header.ReplyQueue = reply_queue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1063,10 +1059,7 @@ static void set_ioaccel1_performant_mode(struct ctlr_info *h,
|
||||
* Tell the controller to post the reply to the queue for this
|
||||
* processor. This seems to give the best I/O throughput.
|
||||
*/
|
||||
if (likely(reply_queue == DEFAULT_REPLY_QUEUE))
|
||||
cp->ReplyQueue = smp_processor_id() % h->nreply_queues;
|
||||
else
|
||||
cp->ReplyQueue = reply_queue % h->nreply_queues;
|
||||
cp->ReplyQueue = reply_queue;
|
||||
/*
|
||||
* Set the bits in the address sent down to include:
|
||||
* - performant mode bit (bit 0)
|
||||
@@ -1087,10 +1080,7 @@ static void set_ioaccel2_tmf_performant_mode(struct ctlr_info *h,
|
||||
/* Tell the controller to post the reply to the queue for this
|
||||
* processor. This seems to give the best I/O throughput.
|
||||
*/
|
||||
if (likely(reply_queue == DEFAULT_REPLY_QUEUE))
|
||||
cp->reply_queue = smp_processor_id() % h->nreply_queues;
|
||||
else
|
||||
cp->reply_queue = reply_queue % h->nreply_queues;
|
||||
cp->reply_queue = reply_queue;
|
||||
/* Set the bits in the address sent down to include:
|
||||
* - performant mode bit not used in ioaccel mode 2
|
||||
* - pull count (bits 0-3)
|
||||
@@ -1109,10 +1099,7 @@ static void set_ioaccel2_performant_mode(struct ctlr_info *h,
|
||||
* Tell the controller to post the reply to the queue for this
|
||||
* processor. This seems to give the best I/O throughput.
|
||||
*/
|
||||
if (likely(reply_queue == DEFAULT_REPLY_QUEUE))
|
||||
cp->reply_queue = smp_processor_id() % h->nreply_queues;
|
||||
else
|
||||
cp->reply_queue = reply_queue % h->nreply_queues;
|
||||
cp->reply_queue = reply_queue;
|
||||
/*
|
||||
* Set the bits in the address sent down to include:
|
||||
* - performant mode bit not used in ioaccel mode 2
|
||||
@@ -1157,6 +1144,8 @@ static void __enqueue_cmd_and_start_io(struct ctlr_info *h,
|
||||
{
|
||||
dial_down_lockup_detection_during_fw_flash(h, c);
|
||||
atomic_inc(&h->commands_outstanding);
|
||||
|
||||
reply_queue = h->reply_map[raw_smp_processor_id()];
|
||||
switch (c->cmd_type) {
|
||||
case CMD_IOACCEL1:
|
||||
set_ioaccel1_performant_mode(h, c, reply_queue);
|
||||
@@ -7376,6 +7365,26 @@ static void hpsa_disable_interrupt_mode(struct ctlr_info *h)
|
||||
h->msix_vectors = 0;
|
||||
}
|
||||
|
||||
static void hpsa_setup_reply_map(struct ctlr_info *h)
|
||||
{
|
||||
const struct cpumask *mask;
|
||||
unsigned int queue, cpu;
|
||||
|
||||
for (queue = 0; queue < h->msix_vectors; queue++) {
|
||||
mask = pci_irq_get_affinity(h->pdev, queue);
|
||||
if (!mask)
|
||||
goto fallback;
|
||||
|
||||
for_each_cpu(cpu, mask)
|
||||
h->reply_map[cpu] = queue;
|
||||
}
|
||||
return;
|
||||
|
||||
fallback:
|
||||
for_each_possible_cpu(cpu)
|
||||
h->reply_map[cpu] = 0;
|
||||
}
|
||||
|
||||
/* If MSI/MSI-X is supported by the kernel we will try to enable it on
|
||||
* controllers that are capable. If not, we use legacy INTx mode.
|
||||
*/
|
||||
@@ -7771,6 +7780,10 @@ static int hpsa_pci_init(struct ctlr_info *h)
|
||||
err = hpsa_interrupt_mode(h);
|
||||
if (err)
|
||||
goto clean1;
|
||||
|
||||
/* setup mapping between CPU and reply queue */
|
||||
hpsa_setup_reply_map(h);
|
||||
|
||||
err = hpsa_pci_find_memory_BAR(h->pdev, &h->paddr);
|
||||
if (err)
|
||||
goto clean2; /* intmode+region, pci */
|
||||
@@ -8480,6 +8493,28 @@ static struct workqueue_struct *hpsa_create_controller_wq(struct ctlr_info *h,
|
||||
return wq;
|
||||
}
|
||||
|
||||
static void hpda_free_ctlr_info(struct ctlr_info *h)
|
||||
{
|
||||
kfree(h->reply_map);
|
||||
kfree(h);
|
||||
}
|
||||
|
||||
static struct ctlr_info *hpda_alloc_ctlr_info(void)
|
||||
{
|
||||
struct ctlr_info *h;
|
||||
|
||||
h = kzalloc(sizeof(*h), GFP_KERNEL);
|
||||
if (!h)
|
||||
return NULL;
|
||||
|
||||
h->reply_map = kzalloc(sizeof(*h->reply_map) * nr_cpu_ids, GFP_KERNEL);
|
||||
if (!h->reply_map) {
|
||||
kfree(h);
|
||||
return NULL;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
static int hpsa_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
{
|
||||
int dac, rc;
|
||||
@@ -8517,7 +8552,7 @@ reinit_after_soft_reset:
|
||||
* the driver. See comments in hpsa.h for more info.
|
||||
*/
|
||||
BUILD_BUG_ON(sizeof(struct CommandList) % COMMANDLIST_ALIGNMENT);
|
||||
h = kzalloc(sizeof(*h), GFP_KERNEL);
|
||||
h = hpda_alloc_ctlr_info();
|
||||
if (!h) {
|
||||
dev_err(&pdev->dev, "Failed to allocate controller head\n");
|
||||
return -ENOMEM;
|
||||
@@ -8916,7 +8951,7 @@ static void hpsa_remove_one(struct pci_dev *pdev)
|
||||
h->lockup_detected = NULL; /* init_one 2 */
|
||||
/* (void) pci_disable_pcie_error_reporting(pdev); */ /* init_one 1 */
|
||||
|
||||
kfree(h); /* init_one 1 */
|
||||
hpda_free_ctlr_info(h); /* init_one 1 */
|
||||
}
|
||||
|
||||
static int hpsa_suspend(__attribute__((unused)) struct pci_dev *pdev,
|
||||
|
||||
@@ -158,6 +158,7 @@ struct bmic_controller_parameters {
|
||||
#pragma pack()
|
||||
|
||||
struct ctlr_info {
|
||||
unsigned int *reply_map;
|
||||
int ctlr;
|
||||
char devname[8];
|
||||
char *product_name;
|
||||
|
||||
@@ -3579,11 +3579,9 @@ static void ibmvfc_tgt_implicit_logout(struct ibmvfc_target *tgt)
|
||||
static int ibmvfc_adisc_needs_plogi(struct ibmvfc_passthru_mad *mad,
|
||||
struct ibmvfc_target *tgt)
|
||||
{
|
||||
if (memcmp(&mad->fc_iu.response[2], &tgt->ids.port_name,
|
||||
sizeof(tgt->ids.port_name)))
|
||||
if (wwn_to_u64((u8 *)&mad->fc_iu.response[2]) != tgt->ids.port_name)
|
||||
return 1;
|
||||
if (memcmp(&mad->fc_iu.response[4], &tgt->ids.node_name,
|
||||
sizeof(tgt->ids.node_name)))
|
||||
if (wwn_to_u64((u8 *)&mad->fc_iu.response[4]) != tgt->ids.node_name)
|
||||
return 1;
|
||||
if (be32_to_cpu(mad->fc_iu.response[6]) != tgt->scsi_id)
|
||||
return 1;
|
||||
|
||||
@@ -367,7 +367,7 @@ enum ibmvfc_fcp_rsp_info_codes {
|
||||
};
|
||||
|
||||
struct ibmvfc_fcp_rsp_info {
|
||||
__be16 reserved;
|
||||
u8 reserved[3];
|
||||
u8 rsp_code;
|
||||
u8 reserved2[4];
|
||||
}__attribute__((packed, aligned (2)));
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <linux/kfifo.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/backing-dev.h>
|
||||
#include <net/tcp.h>
|
||||
#include <scsi/scsi_cmnd.h>
|
||||
#include <scsi/scsi_device.h>
|
||||
@@ -954,6 +955,13 @@ static int iscsi_sw_tcp_slave_alloc(struct scsi_device *sdev)
|
||||
|
||||
static int iscsi_sw_tcp_slave_configure(struct scsi_device *sdev)
|
||||
{
|
||||
struct iscsi_sw_tcp_host *tcp_sw_host = iscsi_host_priv(sdev->host);
|
||||
struct iscsi_session *session = tcp_sw_host->session;
|
||||
struct iscsi_conn *conn = session->leadconn;
|
||||
|
||||
if (conn->datadgst_en)
|
||||
sdev->request_queue->backing_dev_info->capabilities
|
||||
|= BDI_CAP_STABLE_WRITES;
|
||||
blk_queue_bounce_limit(sdev->request_queue, BLK_BOUNCE_ANY);
|
||||
blk_queue_dma_alignment(sdev->request_queue, 0);
|
||||
return 0;
|
||||
|
||||
@@ -223,6 +223,7 @@ out_done:
|
||||
static void sas_eh_finish_cmd(struct scsi_cmnd *cmd)
|
||||
{
|
||||
struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(cmd->device->host);
|
||||
struct domain_device *dev = cmd_to_domain_dev(cmd);
|
||||
struct sas_task *task = TO_SAS_TASK(cmd);
|
||||
|
||||
/* 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)
|
||||
*/
|
||||
sas_end_task(cmd, task);
|
||||
|
||||
if (dev_is_sata(dev)) {
|
||||
/* defer commands to libata so that libata EH can
|
||||
* handle ata qcs correctly
|
||||
*/
|
||||
list_move_tail(&cmd->eh_entry, &sas_ha->eh_ata_q);
|
||||
return;
|
||||
}
|
||||
|
||||
/* now finish the command and move it on to the error
|
||||
* handler done list, this also takes it off the
|
||||
* error handler pending list.
|
||||
@@ -238,22 +247,6 @@ static void sas_eh_finish_cmd(struct scsi_cmnd *cmd)
|
||||
scsi_eh_finish_cmd(cmd, &sas_ha->eh_done_q);
|
||||
}
|
||||
|
||||
static void sas_eh_defer_cmd(struct scsi_cmnd *cmd)
|
||||
{
|
||||
struct domain_device *dev = cmd_to_domain_dev(cmd);
|
||||
struct sas_ha_struct *ha = dev->port->ha;
|
||||
struct sas_task *task = TO_SAS_TASK(cmd);
|
||||
|
||||
if (!dev_is_sata(dev)) {
|
||||
sas_eh_finish_cmd(cmd);
|
||||
return;
|
||||
}
|
||||
|
||||
/* report the timeout to libata */
|
||||
sas_end_task(cmd, task);
|
||||
list_move_tail(&cmd->eh_entry, &ha->eh_ata_q);
|
||||
}
|
||||
|
||||
static void sas_scsi_clear_queue_lu(struct list_head *error_q, struct scsi_cmnd *my_cmd)
|
||||
{
|
||||
struct scsi_cmnd *cmd, *n;
|
||||
@@ -261,7 +254,7 @@ static void sas_scsi_clear_queue_lu(struct list_head *error_q, struct scsi_cmnd
|
||||
list_for_each_entry_safe(cmd, n, error_q, eh_entry) {
|
||||
if (cmd->device->sdev_target == my_cmd->device->sdev_target &&
|
||||
cmd->device->lun == my_cmd->device->lun)
|
||||
sas_eh_defer_cmd(cmd);
|
||||
sas_eh_finish_cmd(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -631,12 +624,12 @@ static void sas_eh_handle_sas_errors(struct Scsi_Host *shost, struct list_head *
|
||||
case TASK_IS_DONE:
|
||||
SAS_DPRINTK("%s: task 0x%p is done\n", __func__,
|
||||
task);
|
||||
sas_eh_defer_cmd(cmd);
|
||||
sas_eh_finish_cmd(cmd);
|
||||
continue;
|
||||
case TASK_IS_ABORTED:
|
||||
SAS_DPRINTK("%s: task 0x%p is aborted\n",
|
||||
__func__, task);
|
||||
sas_eh_defer_cmd(cmd);
|
||||
sas_eh_finish_cmd(cmd);
|
||||
continue;
|
||||
case TASK_IS_AT_LU:
|
||||
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 *
|
||||
"recovered\n",
|
||||
SAS_ADDR(task->dev),
|
||||
cmd->device->lun);
|
||||
sas_eh_defer_cmd(cmd);
|
||||
sas_eh_finish_cmd(cmd);
|
||||
sas_scsi_clear_queue_lu(work_q, cmd);
|
||||
goto Again;
|
||||
}
|
||||
|
||||
@@ -2128,6 +2128,7 @@ enum MR_PD_TYPE {
|
||||
|
||||
struct megasas_instance {
|
||||
|
||||
unsigned int *reply_map;
|
||||
__le32 *producer;
|
||||
dma_addr_t producer_h;
|
||||
__le32 *consumer;
|
||||
|
||||
@@ -5164,6 +5164,26 @@ skip_alloc:
|
||||
instance->use_seqnum_jbod_fp = false;
|
||||
}
|
||||
|
||||
static void megasas_setup_reply_map(struct megasas_instance *instance)
|
||||
{
|
||||
const struct cpumask *mask;
|
||||
unsigned int queue, cpu;
|
||||
|
||||
for (queue = 0; queue < instance->msix_vectors; queue++) {
|
||||
mask = pci_irq_get_affinity(instance->pdev, queue);
|
||||
if (!mask)
|
||||
goto fallback;
|
||||
|
||||
for_each_cpu(cpu, mask)
|
||||
instance->reply_map[cpu] = queue;
|
||||
}
|
||||
return;
|
||||
|
||||
fallback:
|
||||
for_each_possible_cpu(cpu)
|
||||
instance->reply_map[cpu] = cpu % instance->msix_vectors;
|
||||
}
|
||||
|
||||
/**
|
||||
* megasas_init_fw - Initializes the FW
|
||||
* @instance: Adapter soft state
|
||||
@@ -5342,6 +5362,8 @@ static int megasas_init_fw(struct megasas_instance *instance)
|
||||
goto fail_setup_irqs;
|
||||
}
|
||||
|
||||
megasas_setup_reply_map(instance);
|
||||
|
||||
dev_info(&instance->pdev->dev,
|
||||
"firmware supports msix\t: (%d)", fw_msix_count);
|
||||
dev_info(&instance->pdev->dev,
|
||||
@@ -6122,20 +6144,29 @@ static inline int megasas_alloc_mfi_ctrl_mem(struct megasas_instance *instance)
|
||||
*/
|
||||
static int megasas_alloc_ctrl_mem(struct megasas_instance *instance)
|
||||
{
|
||||
instance->reply_map = kzalloc(sizeof(unsigned int) * nr_cpu_ids,
|
||||
GFP_KERNEL);
|
||||
if (!instance->reply_map)
|
||||
return -ENOMEM;
|
||||
|
||||
switch (instance->adapter_type) {
|
||||
case MFI_SERIES:
|
||||
if (megasas_alloc_mfi_ctrl_mem(instance))
|
||||
return -ENOMEM;
|
||||
goto fail;
|
||||
break;
|
||||
case VENTURA_SERIES:
|
||||
case THUNDERBOLT_SERIES:
|
||||
case INVADER_SERIES:
|
||||
if (megasas_alloc_fusion_context(instance))
|
||||
return -ENOMEM;
|
||||
goto fail;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
fail:
|
||||
kfree(instance->reply_map);
|
||||
instance->reply_map = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -6147,6 +6178,7 @@ static int megasas_alloc_ctrl_mem(struct megasas_instance *instance)
|
||||
*/
|
||||
static inline void megasas_free_ctrl_mem(struct megasas_instance *instance)
|
||||
{
|
||||
kfree(instance->reply_map);
|
||||
if (instance->adapter_type == MFI_SERIES) {
|
||||
if (instance->producer)
|
||||
pci_free_consistent(instance->pdev, sizeof(u32),
|
||||
@@ -6539,7 +6571,6 @@ fail_io_attach:
|
||||
pci_free_irq_vectors(instance->pdev);
|
||||
fail_init_mfi:
|
||||
scsi_host_put(host);
|
||||
|
||||
fail_alloc_instance:
|
||||
pci_disable_device(pdev);
|
||||
|
||||
@@ -6745,6 +6776,8 @@ megasas_resume(struct pci_dev *pdev)
|
||||
if (rval < 0)
|
||||
goto fail_reenable_msix;
|
||||
|
||||
megasas_setup_reply_map(instance);
|
||||
|
||||
if (instance->adapter_type != MFI_SERIES) {
|
||||
megasas_reset_reply_desc(instance);
|
||||
if (megasas_ioc_init_fusion(instance)) {
|
||||
|
||||
@@ -216,36 +216,30 @@ inline void megasas_return_cmd_fusion(struct megasas_instance *instance,
|
||||
/**
|
||||
* megasas_fire_cmd_fusion - Sends command to the FW
|
||||
* @instance: Adapter soft state
|
||||
* @req_desc: 32bit or 64bit Request descriptor
|
||||
* @req_desc: 64bit Request descriptor
|
||||
*
|
||||
* Perform PCI Write. Ventura supports 32 bit Descriptor.
|
||||
* Prior to Ventura (12G) MR controller supports 64 bit Descriptor.
|
||||
* Perform PCI Write.
|
||||
*/
|
||||
|
||||
static void
|
||||
megasas_fire_cmd_fusion(struct megasas_instance *instance,
|
||||
union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc)
|
||||
{
|
||||
if (instance->adapter_type == VENTURA_SERIES)
|
||||
writel(le32_to_cpu(req_desc->u.low),
|
||||
&instance->reg_set->inbound_single_queue_port);
|
||||
else {
|
||||
#if defined(writeq) && defined(CONFIG_64BIT)
|
||||
u64 req_data = (((u64)le32_to_cpu(req_desc->u.high) << 32) |
|
||||
le32_to_cpu(req_desc->u.low));
|
||||
u64 req_data = (((u64)le32_to_cpu(req_desc->u.high) << 32) |
|
||||
le32_to_cpu(req_desc->u.low));
|
||||
|
||||
writeq(req_data, &instance->reg_set->inbound_low_queue_port);
|
||||
writeq(req_data, &instance->reg_set->inbound_low_queue_port);
|
||||
#else
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&instance->hba_lock, flags);
|
||||
writel(le32_to_cpu(req_desc->u.low),
|
||||
&instance->reg_set->inbound_low_queue_port);
|
||||
writel(le32_to_cpu(req_desc->u.high),
|
||||
&instance->reg_set->inbound_high_queue_port);
|
||||
mmiowb();
|
||||
spin_unlock_irqrestore(&instance->hba_lock, flags);
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&instance->hba_lock, flags);
|
||||
writel(le32_to_cpu(req_desc->u.low),
|
||||
&instance->reg_set->inbound_low_queue_port);
|
||||
writel(le32_to_cpu(req_desc->u.high),
|
||||
&instance->reg_set->inbound_high_queue_port);
|
||||
mmiowb();
|
||||
spin_unlock_irqrestore(&instance->hba_lock, flags);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -982,7 +976,6 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
|
||||
const char *sys_info;
|
||||
MFI_CAPABILITIES *drv_ops;
|
||||
u32 scratch_pad_2;
|
||||
unsigned long flags;
|
||||
ktime_t time;
|
||||
bool cur_fw_64bit_dma_capable;
|
||||
|
||||
@@ -1121,14 +1114,7 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
|
||||
break;
|
||||
}
|
||||
|
||||
/* For Ventura also IOC INIT required 64 bit Descriptor write. */
|
||||
spin_lock_irqsave(&instance->hba_lock, flags);
|
||||
writel(le32_to_cpu(req_desc.u.low),
|
||||
&instance->reg_set->inbound_low_queue_port);
|
||||
writel(le32_to_cpu(req_desc.u.high),
|
||||
&instance->reg_set->inbound_high_queue_port);
|
||||
mmiowb();
|
||||
spin_unlock_irqrestore(&instance->hba_lock, flags);
|
||||
megasas_fire_cmd_fusion(instance, &req_desc);
|
||||
|
||||
wait_and_poll(instance, cmd, MFI_POLL_TIMEOUT_SECS);
|
||||
|
||||
@@ -2655,11 +2641,8 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
|
||||
fp_possible = (io_info.fpOkForIo > 0) ? true : false;
|
||||
}
|
||||
|
||||
/* Use raw_smp_processor_id() for now until cmd->request->cpu is CPU
|
||||
id by default, not CPU group id, otherwise all MSI-X queues won't
|
||||
be utilized */
|
||||
cmd->request_desc->SCSIIO.MSIxIndex = instance->msix_vectors ?
|
||||
raw_smp_processor_id() % instance->msix_vectors : 0;
|
||||
cmd->request_desc->SCSIIO.MSIxIndex =
|
||||
instance->reply_map[raw_smp_processor_id()];
|
||||
|
||||
praid_context = &io_request->RaidContext;
|
||||
|
||||
@@ -2985,10 +2968,9 @@ megasas_build_syspd_fusion(struct megasas_instance *instance,
|
||||
}
|
||||
|
||||
cmd->request_desc->SCSIIO.DevHandle = io_request->DevHandle;
|
||||
cmd->request_desc->SCSIIO.MSIxIndex =
|
||||
instance->msix_vectors ?
|
||||
(raw_smp_processor_id() % instance->msix_vectors) : 0;
|
||||
|
||||
cmd->request_desc->SCSIIO.MSIxIndex =
|
||||
instance->reply_map[raw_smp_processor_id()];
|
||||
|
||||
if (!fp_possible) {
|
||||
/* system pd firmware path */
|
||||
|
||||
@@ -2774,8 +2774,11 @@ _base_assign_reply_queues(struct MPT3SAS_ADAPTER *ioc)
|
||||
continue;
|
||||
}
|
||||
|
||||
for_each_cpu(cpu, mask)
|
||||
for_each_cpu_and(cpu, mask, cpu_online_mask) {
|
||||
if (cpu >= ioc->cpu_msix_table_sz)
|
||||
break;
|
||||
ioc->cpu_msix_table[cpu] = reply_q->msix_index;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -6637,14 +6640,14 @@ _base_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase)
|
||||
}
|
||||
|
||||
/**
|
||||
* _wait_for_commands_to_complete - reset controller
|
||||
* mpt3sas_wait_for_commands_to_complete - reset controller
|
||||
* @ioc: Pointer to MPT_ADAPTER structure
|
||||
*
|
||||
* This function is waiting 10s for all pending commands to complete
|
||||
* prior to putting controller in reset.
|
||||
*/
|
||||
static void
|
||||
_wait_for_commands_to_complete(struct MPT3SAS_ADAPTER *ioc)
|
||||
void
|
||||
mpt3sas_wait_for_commands_to_complete(struct MPT3SAS_ADAPTER *ioc)
|
||||
{
|
||||
u32 ioc_state;
|
||||
|
||||
@@ -6717,7 +6720,7 @@ mpt3sas_base_hard_reset_handler(struct MPT3SAS_ADAPTER *ioc,
|
||||
is_fault = 1;
|
||||
}
|
||||
_base_reset_handler(ioc, MPT3_IOC_PRE_RESET);
|
||||
_wait_for_commands_to_complete(ioc);
|
||||
mpt3sas_wait_for_commands_to_complete(ioc);
|
||||
_base_mask_interrupts(ioc);
|
||||
r = _base_make_ioc_ready(ioc, type);
|
||||
if (r)
|
||||
|
||||
@@ -1440,6 +1440,9 @@ void mpt3sas_base_update_missing_delay(struct MPT3SAS_ADAPTER *ioc,
|
||||
|
||||
int mpt3sas_port_enable(struct MPT3SAS_ADAPTER *ioc);
|
||||
|
||||
void
|
||||
mpt3sas_wait_for_commands_to_complete(struct MPT3SAS_ADAPTER *ioc);
|
||||
|
||||
|
||||
/* scsih shared API */
|
||||
struct scsi_cmnd *mpt3sas_scsih_scsi_lookup_get(struct MPT3SAS_ADAPTER *ioc,
|
||||
|
||||
@@ -2835,7 +2835,8 @@ scsih_abort(struct scsi_cmnd *scmd)
|
||||
_scsih_tm_display_info(ioc, scmd);
|
||||
|
||||
sas_device_priv_data = scmd->device->hostdata;
|
||||
if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
|
||||
if (!sas_device_priv_data || !sas_device_priv_data->sas_target ||
|
||||
ioc->remove_host) {
|
||||
sdev_printk(KERN_INFO, scmd->device,
|
||||
"device been deleted! scmd(%p)\n", scmd);
|
||||
scmd->result = DID_NO_CONNECT << 16;
|
||||
@@ -2898,7 +2899,8 @@ scsih_dev_reset(struct scsi_cmnd *scmd)
|
||||
_scsih_tm_display_info(ioc, scmd);
|
||||
|
||||
sas_device_priv_data = scmd->device->hostdata;
|
||||
if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
|
||||
if (!sas_device_priv_data || !sas_device_priv_data->sas_target ||
|
||||
ioc->remove_host) {
|
||||
sdev_printk(KERN_INFO, scmd->device,
|
||||
"device been deleted! scmd(%p)\n", scmd);
|
||||
scmd->result = DID_NO_CONNECT << 16;
|
||||
@@ -2961,7 +2963,8 @@ scsih_target_reset(struct scsi_cmnd *scmd)
|
||||
_scsih_tm_display_info(ioc, scmd);
|
||||
|
||||
sas_device_priv_data = scmd->device->hostdata;
|
||||
if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
|
||||
if (!sas_device_priv_data || !sas_device_priv_data->sas_target ||
|
||||
ioc->remove_host) {
|
||||
starget_printk(KERN_INFO, starget, "target been deleted! scmd(%p)\n",
|
||||
scmd);
|
||||
scmd->result = DID_NO_CONNECT << 16;
|
||||
@@ -3019,7 +3022,7 @@ scsih_host_reset(struct scsi_cmnd *scmd)
|
||||
ioc->name, scmd);
|
||||
scsi_print_command(scmd);
|
||||
|
||||
if (ioc->is_driver_loading) {
|
||||
if (ioc->is_driver_loading || ioc->remove_host) {
|
||||
pr_info(MPT3SAS_FMT "Blocking the host reset\n",
|
||||
ioc->name);
|
||||
r = FAILED;
|
||||
@@ -4453,7 +4456,7 @@ _scsih_flush_running_cmds(struct MPT3SAS_ADAPTER *ioc)
|
||||
st = scsi_cmd_priv(scmd);
|
||||
mpt3sas_base_clear_st(ioc, st);
|
||||
scsi_dma_unmap(scmd);
|
||||
if (ioc->pci_error_recovery)
|
||||
if (ioc->pci_error_recovery || ioc->remove_host)
|
||||
scmd->result = DID_NO_CONNECT << 16;
|
||||
else
|
||||
scmd->result = DID_RESET << 16;
|
||||
@@ -9739,6 +9742,10 @@ static void scsih_remove(struct pci_dev *pdev)
|
||||
unsigned long flags;
|
||||
|
||||
ioc->remove_host = 1;
|
||||
|
||||
mpt3sas_wait_for_commands_to_complete(ioc);
|
||||
_scsih_flush_running_cmds(ioc);
|
||||
|
||||
_scsih_fw_event_cleanup_queue(ioc);
|
||||
|
||||
spin_lock_irqsave(&ioc->fw_event_lock, flags);
|
||||
@@ -9815,6 +9822,10 @@ scsih_shutdown(struct pci_dev *pdev)
|
||||
unsigned long flags;
|
||||
|
||||
ioc->remove_host = 1;
|
||||
|
||||
mpt3sas_wait_for_commands_to_complete(ioc);
|
||||
_scsih_flush_running_cmds(ioc);
|
||||
|
||||
_scsih_fw_event_cleanup_queue(ioc);
|
||||
|
||||
spin_lock_irqsave(&ioc->fw_event_lock, flags);
|
||||
@@ -10563,7 +10574,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
snprintf(ioc->firmware_event_name, sizeof(ioc->firmware_event_name),
|
||||
"fw_event_%s%d", ioc->driver_name, ioc->id);
|
||||
ioc->firmware_event_thread = alloc_ordered_workqueue(
|
||||
ioc->firmware_event_name, WQ_MEM_RECLAIM);
|
||||
ioc->firmware_event_name, 0);
|
||||
if (!ioc->firmware_event_thread) {
|
||||
pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
|
||||
ioc->name, __FILE__, __LINE__, __func__);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user