summaryrefslogtreecommitdiff
path: root/drivers/scsi/mpi3mr/mpi3mr_transport.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/mpi3mr/mpi3mr_transport.c')
-rw-r--r--drivers/scsi/mpi3mr/mpi3mr_transport.c169
1 files changed, 116 insertions, 53 deletions
diff --git a/drivers/scsi/mpi3mr/mpi3mr_transport.c b/drivers/scsi/mpi3mr/mpi3mr_transport.c
index 3fc897336b5e..d70f002d6487 100644
--- a/drivers/scsi/mpi3mr/mpi3mr_transport.c
+++ b/drivers/scsi/mpi3mr/mpi3mr_transport.c
@@ -2,15 +2,14 @@
/*
* Driver for Broadcom MPI3 Storage Controllers
*
- * Copyright (C) 2017-2022 Broadcom Inc.
+ * Copyright (C) 2017-2023 Broadcom Inc.
* (mailto: mpi3mr-linuxdrv.pdl@broadcom.com)
*
*/
-#include "mpi3mr.h"
+#include <linux/vmalloc.h>
-static void mpi3mr_expander_node_remove(struct mpi3mr_ioc *mrioc,
- struct mpi3mr_sas_node *sas_expander);
+#include "mpi3mr.h"
/**
* mpi3mr_post_transport_req - Issue transport requests and wait
@@ -106,10 +105,10 @@ struct rep_manu_reply {
u8 reserved0[2];
u8 sas_format;
u8 reserved2[3];
- u8 vendor_id[SAS_EXPANDER_VENDOR_ID_LEN];
- u8 product_id[SAS_EXPANDER_PRODUCT_ID_LEN];
- u8 product_rev[SAS_EXPANDER_PRODUCT_REV_LEN];
- u8 component_vendor_id[SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN];
+ u8 vendor_id[SAS_EXPANDER_VENDOR_ID_LEN] __nonstring;
+ u8 product_id[SAS_EXPANDER_PRODUCT_ID_LEN] __nonstring;
+ u8 product_rev[SAS_EXPANDER_PRODUCT_REV_LEN] __nonstring;
+ u8 component_vendor_id[SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN] __nonstring;
u16 component_id;
u8 component_revision_id;
u8 reserved3;
@@ -152,6 +151,11 @@ static int mpi3mr_report_manufacture(struct mpi3mr_ioc *mrioc,
return -EFAULT;
}
+ if (mrioc->pci_err_recovery) {
+ ioc_err(mrioc, "%s: pci error recovery in progress!\n", __func__);
+ return -EFAULT;
+ }
+
data_out_sz = sizeof(struct rep_manu_request);
data_in_sz = sizeof(struct rep_manu_reply);
data_out = dma_alloc_coherent(&mrioc->pdev->dev,
@@ -212,17 +216,13 @@ static int mpi3mr_report_manufacture(struct mpi3mr_ioc *mrioc,
goto out;
}
- strscpy(edev->vendor_id, manufacture_reply->vendor_id,
- SAS_EXPANDER_VENDOR_ID_LEN);
- strscpy(edev->product_id, manufacture_reply->product_id,
- SAS_EXPANDER_PRODUCT_ID_LEN);
- strscpy(edev->product_rev, manufacture_reply->product_rev,
- SAS_EXPANDER_PRODUCT_REV_LEN);
+ memtostr(edev->vendor_id, manufacture_reply->vendor_id);
+ memtostr(edev->product_id, manufacture_reply->product_id);
+ memtostr(edev->product_rev, manufacture_reply->product_rev);
edev->level = manufacture_reply->sas_format & 1;
if (edev->level) {
- strscpy(edev->component_vendor_id,
- manufacture_reply->component_vendor_id,
- SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN);
+ memtostr(edev->component_vendor_id,
+ manufacture_reply->component_vendor_id);
tmp = (u8 *)&manufacture_reply->component_id;
edev->component_id = tmp[0] << 8 | tmp[1];
edev->component_revision_id =
@@ -413,9 +413,11 @@ static void mpi3mr_remove_device_by_sas_address(struct mpi3mr_ioc *mrioc,
sas_address, hba_port);
if (tgtdev) {
if (!list_empty(&tgtdev->list)) {
- list_del_init(&tgtdev->list);
was_on_tgtdev_list = 1;
- mpi3mr_tgtdev_put(tgtdev);
+ if (tgtdev->state == MPI3MR_DEV_REMOVE_HS_STARTED) {
+ list_del_init(&tgtdev->list);
+ mpi3mr_tgtdev_put(tgtdev);
+ }
}
}
spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags);
@@ -590,12 +592,13 @@ static enum sas_linkrate mpi3mr_convert_phy_link_rate(u8 link_rate)
* @mrioc: Adapter instance reference
* @mr_sas_port: Internal Port object
* @mr_sas_phy: Internal Phy object
+ * @host_node: Flag to indicate this is a host_node
*
* Return: None.
*/
static void mpi3mr_delete_sas_phy(struct mpi3mr_ioc *mrioc,
struct mpi3mr_sas_port *mr_sas_port,
- struct mpi3mr_sas_phy *mr_sas_phy)
+ struct mpi3mr_sas_phy *mr_sas_phy, u8 host_node)
{
u64 sas_address = mr_sas_port->remote_identify.sas_address;
@@ -605,9 +608,13 @@ static void mpi3mr_delete_sas_phy(struct mpi3mr_ioc *mrioc,
list_del(&mr_sas_phy->port_siblings);
mr_sas_port->num_phys--;
- mr_sas_port->phy_mask &= ~(1 << mr_sas_phy->phy_id);
- if (mr_sas_port->lowest_phy == mr_sas_phy->phy_id)
- mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1;
+
+ if (host_node) {
+ mr_sas_port->phy_mask &= ~(1 << mr_sas_phy->phy_id);
+
+ if (mr_sas_port->lowest_phy == mr_sas_phy->phy_id)
+ mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1;
+ }
sas_port_delete_phy(mr_sas_port->port, mr_sas_phy->phy);
mr_sas_phy->phy_belongs_to_port = 0;
}
@@ -617,12 +624,13 @@ static void mpi3mr_delete_sas_phy(struct mpi3mr_ioc *mrioc,
* @mrioc: Adapter instance reference
* @mr_sas_port: Internal Port object
* @mr_sas_phy: Internal Phy object
+ * @host_node: Flag to indicate this is a host_node
*
* Return: None.
*/
static void mpi3mr_add_sas_phy(struct mpi3mr_ioc *mrioc,
struct mpi3mr_sas_port *mr_sas_port,
- struct mpi3mr_sas_phy *mr_sas_phy)
+ struct mpi3mr_sas_phy *mr_sas_phy, u8 host_node)
{
u64 sas_address = mr_sas_port->remote_identify.sas_address;
@@ -632,9 +640,12 @@ static void mpi3mr_add_sas_phy(struct mpi3mr_ioc *mrioc,
list_add_tail(&mr_sas_phy->port_siblings, &mr_sas_port->phy_list);
mr_sas_port->num_phys++;
- mr_sas_port->phy_mask |= (1 << mr_sas_phy->phy_id);
- if (mr_sas_phy->phy_id < mr_sas_port->lowest_phy)
- mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1;
+ if (host_node) {
+ mr_sas_port->phy_mask |= (1 << mr_sas_phy->phy_id);
+
+ if (mr_sas_phy->phy_id < mr_sas_port->lowest_phy)
+ mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1;
+ }
sas_port_add_phy(mr_sas_port->port, mr_sas_phy->phy);
mr_sas_phy->phy_belongs_to_port = 1;
}
@@ -675,7 +686,7 @@ static void mpi3mr_add_phy_to_an_existing_port(struct mpi3mr_ioc *mrioc,
if (srch_phy == mr_sas_phy)
return;
}
- mpi3mr_add_sas_phy(mrioc, mr_sas_port, mr_sas_phy);
+ mpi3mr_add_sas_phy(mrioc, mr_sas_port, mr_sas_phy, mr_sas_node->host_node);
return;
}
}
@@ -736,7 +747,7 @@ static void mpi3mr_del_phy_from_an_existing_port(struct mpi3mr_ioc *mrioc,
mpi3mr_delete_sas_port(mrioc, mr_sas_port);
else
mpi3mr_delete_sas_phy(mrioc, mr_sas_port,
- mr_sas_phy);
+ mr_sas_phy, mr_sas_node->host_node);
return;
}
}
@@ -795,6 +806,12 @@ static int mpi3mr_set_identify(struct mpi3mr_ioc *mrioc, u16 handle,
return -EFAULT;
}
+ if (mrioc->pci_err_recovery) {
+ ioc_err(mrioc, "%s: pci error recovery in progress!\n",
+ __func__);
+ return -EFAULT;
+ }
+
if ((mpi3mr_cfg_get_dev_pg0(mrioc, &ioc_status, &device_pg0,
sizeof(device_pg0), MPI3_DEVICE_PGAD_FORM_HANDLE, handle))) {
ioc_err(mrioc, "%s: device page0 read failed\n", __func__);
@@ -1012,6 +1029,9 @@ mpi3mr_alloc_hba_port(struct mpi3mr_ioc *mrioc, u16 port_id)
hba_port->port_id = port_id;
ioc_info(mrioc, "hba_port entry: %p, port: %d is added to hba_port list\n",
hba_port, hba_port->port_id);
+ if (mrioc->reset_in_progress ||
+ mrioc->pci_err_recovery)
+ hba_port->flags = MPI3MR_HBA_PORT_FLAG_NEW;
list_add_tail(&hba_port->list, &mrioc->hba_port_table_list);
return hba_port;
}
@@ -1019,7 +1039,7 @@ mpi3mr_alloc_hba_port(struct mpi3mr_ioc *mrioc, u16 port_id)
/**
* mpi3mr_get_hba_port_by_id - find hba port by id
* @mrioc: Adapter instance reference
- * @port_id - Port ID to search
+ * @port_id: Port ID to search
*
* Return: mpi3mr_hba_port reference for the matched port
*/
@@ -1060,7 +1080,7 @@ void mpi3mr_update_links(struct mpi3mr_ioc *mrioc,
struct mpi3mr_sas_node *mr_sas_node;
struct mpi3mr_sas_phy *mr_sas_phy;
- if (mrioc->reset_in_progress)
+ if (mrioc->reset_in_progress || mrioc->pci_err_recovery)
return;
spin_lock_irqsave(&mrioc->sas_node_lock, flags);
@@ -1280,7 +1300,7 @@ void mpi3mr_sas_host_add(struct mpi3mr_ioc *mrioc)
if (mrioc->sas_hba.enclosure_handle) {
if (!(mpi3mr_cfg_get_enclosure_pg0(mrioc, &ioc_status,
- &encl_pg0, sizeof(dev_pg0),
+ &encl_pg0, sizeof(encl_pg0),
MPI3_ENCLOS_PGAD_FORM_HANDLE,
mrioc->sas_hba.enclosure_handle)) &&
(ioc_status == MPI3_IOCSTATUS_SUCCESS))
@@ -1358,15 +1378,27 @@ static struct mpi3mr_sas_port *mpi3mr_sas_port_add(struct mpi3mr_ioc *mrioc,
mpi3mr_sas_port_sanity_check(mrioc, mr_sas_node,
mr_sas_port->remote_identify.sas_address, hba_port);
+ if (mr_sas_node->host_node && mr_sas_node->num_phys >=
+ sizeof(mr_sas_port->phy_mask) * 8)
+ ioc_info(mrioc, "max port count %u could be too high\n",
+ mr_sas_node->num_phys);
+
for (i = 0; i < mr_sas_node->num_phys; i++) {
if ((mr_sas_node->phy[i].remote_identify.sas_address !=
mr_sas_port->remote_identify.sas_address) ||
(mr_sas_node->phy[i].hba_port != hba_port))
continue;
+
+ if (mr_sas_node->host_node && (i >= sizeof(mr_sas_port->phy_mask) * 8)) {
+ ioc_warn(mrioc, "skipping port %u, max allowed value is %zu\n",
+ i, sizeof(mr_sas_port->phy_mask) * 8);
+ goto out_fail;
+ }
list_add_tail(&mr_sas_node->phy[i].port_siblings,
&mr_sas_port->phy_list);
mr_sas_port->num_phys++;
- mr_sas_port->phy_mask |= (1 << i);
+ if (mr_sas_node->host_node)
+ mr_sas_port->phy_mask |= (1 << i);
}
if (!mr_sas_port->num_phys) {
@@ -1375,7 +1407,8 @@ static struct mpi3mr_sas_port *mpi3mr_sas_port_add(struct mpi3mr_ioc *mrioc,
goto out_fail;
}
- mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1;
+ if (mr_sas_node->host_node)
+ mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1;
if (mr_sas_port->remote_identify.device_type == SAS_END_DEVICE) {
tgtdev = mpi3mr_get_tgtdev_by_addr(mrioc,
@@ -1552,7 +1585,8 @@ static void mpi3mr_sas_port_remove(struct mpi3mr_ioc *mrioc, u64 sas_address,
list_for_each_entry_safe(mr_sas_phy, next_phy,
&mr_sas_port->phy_list, port_siblings) {
- if ((mrioc->logging_level & MPI3_DEBUG_TRANSPORT_INFO))
+ if ((!mrioc->stop_drv_processing) &&
+ (mrioc->logging_level & MPI3_DEBUG_TRANSPORT_INFO))
dev_info(&mr_sas_port->port->dev,
"remove: sas_address(0x%016llx), phy(%d)\n",
(unsigned long long)
@@ -1589,7 +1623,7 @@ static void mpi3mr_sas_port_remove(struct mpi3mr_ioc *mrioc, u64 sas_address,
*/
struct host_port {
u64 sas_address;
- u32 phy_mask;
+ u64 phy_mask;
u16 handle;
u8 iounit_port_id;
u8 used;
@@ -1613,7 +1647,7 @@ mpi3mr_update_mr_sas_port(struct mpi3mr_ioc *mrioc, struct host_port *h_port,
struct mpi3mr_sas_port *mr_sas_port)
{
struct mpi3mr_sas_phy *mr_sas_phy;
- u32 phy_mask_xor;
+ u64 phy_mask_xor;
u64 phys_to_be_added, phys_to_be_removed;
int i;
@@ -1621,7 +1655,7 @@ mpi3mr_update_mr_sas_port(struct mpi3mr_ioc *mrioc, struct host_port *h_port,
mr_sas_port->marked_responding = 1;
dev_info(&mr_sas_port->port->dev,
- "sas_address(0x%016llx), old: port_id %d phy_mask 0x%x, new: port_id %d phy_mask:0x%x\n",
+ "sas_address(0x%016llx), old: port_id %d phy_mask 0x%llx, new: port_id %d phy_mask:0x%llx\n",
mr_sas_port->remote_identify.sas_address,
mr_sas_port->hba_port->port_id, mr_sas_port->phy_mask,
h_port->iounit_port_id, h_port->phy_mask);
@@ -1639,7 +1673,7 @@ mpi3mr_update_mr_sas_port(struct mpi3mr_ioc *mrioc, struct host_port *h_port,
* if these phys are previously registered with another port
* then delete these phys from that port first.
*/
- for_each_set_bit(i, (ulong *) &phys_to_be_added, BITS_PER_TYPE(u32)) {
+ for_each_set_bit(i, (ulong *) &phys_to_be_added, BITS_PER_TYPE(u64)) {
mr_sas_phy = &mrioc->sas_hba.phy[i];
if (mr_sas_phy->phy_belongs_to_port)
mpi3mr_del_phy_from_an_existing_port(mrioc,
@@ -1651,7 +1685,7 @@ mpi3mr_update_mr_sas_port(struct mpi3mr_ioc *mrioc, struct host_port *h_port,
}
/* Delete the phys which are not part of current mr_sas_port's port. */
- for_each_set_bit(i, (ulong *) &phys_to_be_removed, BITS_PER_TYPE(u32)) {
+ for_each_set_bit(i, (ulong *) &phys_to_be_removed, BITS_PER_TYPE(u64)) {
mr_sas_phy = &mrioc->sas_hba.phy[i];
if (mr_sas_phy->phy_belongs_to_port)
mpi3mr_del_phy_from_an_existing_port(mrioc,
@@ -1673,7 +1707,7 @@ mpi3mr_update_mr_sas_port(struct mpi3mr_ioc *mrioc, struct host_port *h_port,
void
mpi3mr_refresh_sas_ports(struct mpi3mr_ioc *mrioc)
{
- struct host_port h_port[32];
+ struct host_port *h_port = NULL;
int i, j, found, host_port_count = 0, port_idx;
u16 sz, attached_handle, ioc_status;
struct mpi3_sas_io_unit_page0 *sas_io_unit_pg0 = NULL;
@@ -1687,6 +1721,10 @@ mpi3mr_refresh_sas_ports(struct mpi3mr_ioc *mrioc)
sas_io_unit_pg0 = kzalloc(sz, GFP_KERNEL);
if (!sas_io_unit_pg0)
return;
+ h_port = kcalloc(64, sizeof(struct host_port), GFP_KERNEL);
+ if (!h_port)
+ goto out;
+
if (mpi3mr_cfg_get_sas_io_unit_pg0(mrioc, sas_io_unit_pg0, sz)) {
ioc_err(mrioc, "failure at %s:%d/%s()!\n",
__FILE__, __LINE__, __func__);
@@ -1744,7 +1782,7 @@ mpi3mr_refresh_sas_ports(struct mpi3mr_ioc *mrioc)
list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list,
port_list) {
ioc_info(mrioc,
- "port_id:%d, sas_address:(0x%016llx), phy_mask:(0x%x), lowest phy id:%d\n",
+ "port_id:%d, sas_address:(0x%016llx), phy_mask:(0x%llx), lowest phy id:%d\n",
mr_sas_port->hba_port->port_id,
mr_sas_port->remote_identify.sas_address,
mr_sas_port->phy_mask, mr_sas_port->lowest_phy);
@@ -1753,7 +1791,7 @@ mpi3mr_refresh_sas_ports(struct mpi3mr_ioc *mrioc)
ioc_info(mrioc, "Host port details after reset\n");
for (i = 0; i < host_port_count; i++) {
ioc_info(mrioc,
- "port_id:%d, sas_address:(0x%016llx), phy_mask:(0x%x), lowest phy id:%d\n",
+ "port_id:%d, sas_address:(0x%016llx), phy_mask:(0x%llx), lowest phy id:%d\n",
h_port[i].iounit_port_id, h_port[i].sas_address,
h_port[i].phy_mask, h_port[i].lowest_phy);
}
@@ -1816,6 +1854,7 @@ mpi3mr_refresh_sas_ports(struct mpi3mr_ioc *mrioc)
}
}
out:
+ kfree(h_port);
kfree(sas_io_unit_pg0);
}
@@ -1967,7 +2006,7 @@ int mpi3mr_expander_add(struct mpi3mr_ioc *mrioc, u16 handle)
if (!handle)
return -1;
- if (mrioc->reset_in_progress)
+ if (mrioc->reset_in_progress || mrioc->pci_err_recovery)
return -1;
if ((mpi3mr_cfg_get_sas_exp_pg0(mrioc, &ioc_status, &expander_pg0,
@@ -2042,6 +2081,8 @@ int mpi3mr_expander_add(struct mpi3mr_ioc *mrioc, u16 handle)
link_rate = (expander_pg1.negotiated_link_rate &
MPI3_SAS_NEG_LINK_RATE_LOGICAL_MASK) >>
MPI3_SAS_NEG_LINK_RATE_LOGICAL_SHIFT;
+ if (link_rate < MPI3_SAS_NEG_LINK_RATE_1_5)
+ link_rate = MPI3_SAS_NEG_LINK_RATE_1_5;
mpi3mr_update_links(mrioc, sas_address_parent,
handle, i, link_rate, hba_port);
}
@@ -2060,7 +2101,7 @@ int mpi3mr_expander_add(struct mpi3mr_ioc *mrioc, u16 handle)
sas_expander = kzalloc(sizeof(struct mpi3mr_sas_node),
GFP_KERNEL);
if (!sas_expander)
- return -1;
+ return -ENOMEM;
sas_expander->handle = handle;
sas_expander->num_phys = expander_pg0.num_phys;
@@ -2163,7 +2204,7 @@ out_fail:
*
* Return nothing.
*/
-static void mpi3mr_expander_node_remove(struct mpi3mr_ioc *mrioc,
+void mpi3mr_expander_node_remove(struct mpi3mr_ioc *mrioc,
struct mpi3mr_sas_node *sas_expander)
{
struct mpi3mr_sas_port *mr_sas_port, *next;
@@ -2173,7 +2214,7 @@ static void mpi3mr_expander_node_remove(struct mpi3mr_ioc *mrioc,
/* remove sibling ports attached to this expander */
list_for_each_entry_safe(mr_sas_port, next,
&sas_expander->sas_port_list, port_list) {
- if (mrioc->reset_in_progress)
+ if (mrioc->reset_in_progress || mrioc->pci_err_recovery)
return;
if (mr_sas_port->remote_identify.device_type ==
SAS_END_DEVICE)
@@ -2223,7 +2264,7 @@ void mpi3mr_expander_remove(struct mpi3mr_ioc *mrioc, u64 sas_address,
struct mpi3mr_sas_node *sas_expander;
unsigned long flags;
- if (mrioc->reset_in_progress)
+ if (mrioc->reset_in_progress || mrioc->pci_err_recovery)
return;
if (!hba_port)
@@ -2351,21 +2392,25 @@ int mpi3mr_report_tgtdev_to_sas_transport(struct mpi3mr_ioc *mrioc,
link_rate = mpi3mr_get_sas_negotiated_logical_linkrate(mrioc, tgtdev);
+ if (link_rate < MPI3_SAS_NEG_LINK_RATE_1_5)
+ link_rate = MPI3_SAS_NEG_LINK_RATE_1_5;
+
mpi3mr_update_links(mrioc, sas_address_parent, tgtdev->dev_handle,
parent_phy_number, link_rate, hba_port);
tgtdev->host_exposed = 1;
if (!mpi3mr_sas_port_add(mrioc, tgtdev->dev_handle,
sas_address_parent, hba_port)) {
- tgtdev->host_exposed = 0;
retval = -1;
- } else if ((!tgtdev->starget)) {
- if (!mrioc->is_driver_loading)
+ } else if ((!tgtdev->starget) && (!mrioc->is_driver_loading)) {
mpi3mr_sas_port_remove(mrioc, sas_address,
sas_address_parent, hba_port);
- tgtdev->host_exposed = 0;
retval = -1;
}
+ if (retval) {
+ tgtdev->dev_spec.sas_sata_inf.hba_port = NULL;
+ tgtdev->host_exposed = 0;
+ }
return retval;
}
@@ -2394,6 +2439,7 @@ void mpi3mr_remove_tgtdev_from_sas_transport(struct mpi3mr_ioc *mrioc,
mpi3mr_sas_port_remove(mrioc, sas_address, sas_address_parent,
hba_port);
tgtdev->host_exposed = 0;
+ tgtdev->dev_spec.sas_sata_inf.hba_port = NULL;
}
/**
@@ -2450,7 +2496,7 @@ static u8 mpi3mr_get_port_id_by_rphy(struct mpi3mr_ioc *mrioc, struct sas_rphy *
tgtdev = __mpi3mr_get_tgtdev_by_addr_and_rphy(mrioc,
rphy->identify.sas_address, rphy);
- if (tgtdev) {
+ if (tgtdev && tgtdev->dev_spec.sas_sata_inf.hba_port) {
port_id =
tgtdev->dev_spec.sas_sata_inf.hba_port->port_id;
mpi3mr_tgtdev_put(tgtdev);
@@ -2532,6 +2578,11 @@ static int mpi3mr_get_expander_phy_error_log(struct mpi3mr_ioc *mrioc,
return -EFAULT;
}
+ if (mrioc->pci_err_recovery) {
+ ioc_err(mrioc, "%s: pci error recovery in progress!\n", __func__);
+ return -EFAULT;
+ }
+
data_out_sz = sizeof(struct phy_error_log_request);
data_in_sz = sizeof(struct phy_error_log_reply);
sz = data_out_sz + data_in_sz;
@@ -2791,6 +2842,12 @@ mpi3mr_expander_phy_control(struct mpi3mr_ioc *mrioc,
return -EFAULT;
}
+ if (mrioc->pci_err_recovery) {
+ ioc_err(mrioc, "%s: pci error recovery in progress!\n",
+ __func__);
+ return -EFAULT;
+ }
+
data_out_sz = sizeof(struct phy_control_request);
data_in_sz = sizeof(struct phy_control_reply);
sz = data_out_sz + data_in_sz;
@@ -3214,6 +3271,12 @@ mpi3mr_transport_smp_handler(struct bsg_job *job, struct Scsi_Host *shost,
goto out;
}
+ if (mrioc->pci_err_recovery) {
+ ioc_err(mrioc, "%s: pci error recovery in progress!\n", __func__);
+ rc = -EFAULT;
+ goto out;
+ }
+
rc = mpi3mr_map_smp_buffer(&mrioc->pdev->dev, &job->request_payload,
&dma_addr_out, &dma_len_out, &addr_out);
if (rc)