aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mpt2sas/mpt2sas_base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_base.c')
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.c172
1 files changed, 122 insertions, 50 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c
index 0ec1ed389c20..57bcd5c9dcff 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.c
@@ -95,6 +95,10 @@ int mpt2sas_fwfault_debug;
MODULE_PARM_DESC(mpt2sas_fwfault_debug, " enable detection of firmware fault "
"and halt firmware - (default=0)");
+static int disable_discovery = -1;
+module_param(disable_discovery, int, 0);
+MODULE_PARM_DESC(disable_discovery, " disable discovery ");
+
/**
* _scsih_set_fwfault_debug - global setting of ioc->fwfault_debug.
*
@@ -1238,7 +1242,7 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc)
u64 pio_chip = 0;
u64 chip_phys = 0;
- dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n",
+ dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n",
ioc->name, __func__));
ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM);
@@ -1307,6 +1311,9 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc)
printk(MPT2SAS_INFO_FMT "ioport(0x%016llx), size(%d)\n",
ioc->name, (unsigned long long)pio_chip, pio_sz);
+ /* Save PCI configuration state for recovery from PCI AER/EEH errors */
+ pci_save_state(pdev);
+
return 0;
out_fail:
@@ -1861,7 +1868,7 @@ _base_static_config_pages(struct MPT2SAS_ADAPTER *ioc)
static void
_base_release_memory_pools(struct MPT2SAS_ADAPTER *ioc)
{
- dexitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
+ dexitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
__func__));
if (ioc->request) {
@@ -1947,7 +1954,7 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
u32 retry_sz;
u16 max_request_credit;
- dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
+ dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
__func__));
retry_sz = 0;
@@ -2374,7 +2381,7 @@ _base_wait_for_doorbell_int(struct MPT2SAS_ADAPTER *ioc, int timeout,
do {
int_status = readl(&ioc->chip->HostInterruptStatus);
if (int_status & MPI2_HIS_IOC2SYS_DB_STATUS) {
- dhsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
+ dhsprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
"successfull count(%d), timeout(%d)\n", ioc->name,
__func__, count, timeout));
return 0;
@@ -2415,7 +2422,7 @@ _base_wait_for_doorbell_ack(struct MPT2SAS_ADAPTER *ioc, int timeout,
do {
int_status = readl(&ioc->chip->HostInterruptStatus);
if (!(int_status & MPI2_HIS_SYS2IOC_DB_STATUS)) {
- dhsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
+ dhsprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
"successfull count(%d), timeout(%d)\n", ioc->name,
__func__, count, timeout));
return 0;
@@ -2463,7 +2470,7 @@ _base_wait_for_doorbell_not_used(struct MPT2SAS_ADAPTER *ioc, int timeout,
do {
doorbell_reg = readl(&ioc->chip->Doorbell);
if (!(doorbell_reg & MPI2_DOORBELL_USED)) {
- dhsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
+ dhsprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
"successfull count(%d), timeout(%d)\n", ioc->name,
__func__, count, timeout));
return 0;
@@ -2637,9 +2644,9 @@ _base_handshake_req_reply_wait(struct MPT2SAS_ADAPTER *ioc, int request_bytes,
if (ioc->logging_level & MPT_DEBUG_INIT) {
mfp = (u32 *)reply;
- printk(KERN_DEBUG "\toffset:data\n");
+ printk(KERN_INFO "\toffset:data\n");
for (i = 0; i < reply_bytes/4; i++)
- printk(KERN_DEBUG "\t[0x%02x]:%08x\n", i*4,
+ printk(KERN_INFO "\t[0x%02x]:%08x\n", i*4,
le32_to_cpu(mfp[i]));
}
return 0;
@@ -2672,7 +2679,7 @@ mpt2sas_base_sas_iounit_control(struct MPT2SAS_ADAPTER *ioc,
void *request;
u16 wait_state_count;
- dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
+ dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
__func__));
mutex_lock(&ioc->base_cmds.mutex);
@@ -2777,7 +2784,7 @@ mpt2sas_base_scsi_enclosure_processor(struct MPT2SAS_ADAPTER *ioc,
void *request;
u16 wait_state_count;
- dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
+ dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
__func__));
mutex_lock(&ioc->base_cmds.mutex);
@@ -2865,7 +2872,7 @@ _base_get_port_facts(struct MPT2SAS_ADAPTER *ioc, int port, int sleep_flag)
Mpi2PortFactsReply_t mpi_reply, *pfacts;
int mpi_reply_sz, mpi_request_sz, r;
- dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
+ dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
__func__));
mpi_reply_sz = sizeof(Mpi2PortFactsReply_t);
@@ -2907,7 +2914,7 @@ _base_get_ioc_facts(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
Mpi2IOCFactsReply_t mpi_reply, *facts;
int mpi_reply_sz, mpi_request_sz, r;
- dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
+ dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
__func__));
mpi_reply_sz = sizeof(Mpi2IOCFactsReply_t);
@@ -2979,7 +2986,7 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
struct timeval current_time;
u16 ioc_status;
- dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
+ dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
__func__));
memset(&mpi_request, 0, sizeof(Mpi2IOCInitRequest_t));
@@ -3040,9 +3047,9 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
int i;
mfp = (u32 *)&mpi_request;
- printk(KERN_DEBUG "\toffset:data\n");
+ printk(KERN_INFO "\toffset:data\n");
for (i = 0; i < sizeof(Mpi2IOCInitRequest_t)/4; i++)
- printk(KERN_DEBUG "\t[0x%02x]:%08x\n", i*4,
+ printk(KERN_INFO "\t[0x%02x]:%08x\n", i*4,
le32_to_cpu(mfp[i]));
}
@@ -3121,7 +3128,7 @@ _base_send_port_enable(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
r = -ETIME;
goto out;
} else
- dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: complete\n",
+ dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: complete\n",
ioc->name, __func__));
ioc_state = _base_wait_on_iocstate(ioc, MPI2_IOC_STATE_OPERATIONAL,
@@ -3181,7 +3188,7 @@ _base_event_notification(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
int r = 0;
int i;
- dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
+ dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
__func__));
if (ioc->base_cmds.status & MPT2_CMD_PENDING) {
@@ -3219,7 +3226,7 @@ _base_event_notification(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
else
r = -ETIME;
} else
- dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: complete\n",
+ dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: complete\n",
ioc->name, __func__));
ioc->base_cmds.status = MPT2_CMD_NOT_USED;
return r;
@@ -3281,7 +3288,7 @@ _base_diag_reset(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
_base_save_msix_table(ioc);
- drsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "clear interrupts\n",
+ drsprintk(ioc, printk(MPT2SAS_INFO_FMT "clear interrupts\n",
ioc->name));
count = 0;
@@ -3289,7 +3296,7 @@ _base_diag_reset(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
/* Write magic sequence to WriteSequence register
* Loop until in diagnostic mode
*/
- drsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "write magic "
+ drsprintk(ioc, printk(MPT2SAS_INFO_FMT "write magic "
"sequence\n", ioc->name));
writel(MPI2_WRSEQ_FLUSH_KEY_VALUE, &ioc->chip->WriteSequence);
writel(MPI2_WRSEQ_1ST_KEY_VALUE, &ioc->chip->WriteSequence);
@@ -3309,7 +3316,7 @@ _base_diag_reset(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
goto out;
host_diagnostic = readl(&ioc->chip->HostDiagnostic);
- drsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "wrote magic "
+ drsprintk(ioc, printk(MPT2SAS_INFO_FMT "wrote magic "
"sequence: count(%d), host_diagnostic(0x%08x)\n",
ioc->name, count, host_diagnostic));
@@ -3317,7 +3324,7 @@ _base_diag_reset(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
hcb_size = readl(&ioc->chip->HCBSize);
- drsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "diag reset: issued\n",
+ drsprintk(ioc, printk(MPT2SAS_INFO_FMT "diag reset: issued\n",
ioc->name));
writel(host_diagnostic | MPI2_DIAG_RESET_ADAPTER,
&ioc->chip->HostDiagnostic);
@@ -3344,29 +3351,29 @@ _base_diag_reset(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
if (host_diagnostic & MPI2_DIAG_HCB_MODE) {
- drsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "restart the adapter "
+ drsprintk(ioc, printk(MPT2SAS_INFO_FMT "restart the adapter "
"assuming the HCB Address points to good F/W\n",
ioc->name));
host_diagnostic &= ~MPI2_DIAG_BOOT_DEVICE_SELECT_MASK;
host_diagnostic |= MPI2_DIAG_BOOT_DEVICE_SELECT_HCDW;
writel(host_diagnostic, &ioc->chip->HostDiagnostic);
- drsprintk(ioc, printk(MPT2SAS_DEBUG_FMT
+ drsprintk(ioc, printk(MPT2SAS_INFO_FMT
"re-enable the HCDW\n", ioc->name));
writel(hcb_size | MPI2_HCB_SIZE_HCB_ENABLE,
&ioc->chip->HCBSize);
}
- drsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "restart the adapter\n",
+ drsprintk(ioc, printk(MPT2SAS_INFO_FMT "restart the adapter\n",
ioc->name));
writel(host_diagnostic & ~MPI2_DIAG_HOLD_IOC_RESET,
&ioc->chip->HostDiagnostic);
- drsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "disable writes to the "
+ drsprintk(ioc, printk(MPT2SAS_INFO_FMT "disable writes to the "
"diagnostic register\n", ioc->name));
writel(MPI2_WRSEQ_FLUSH_KEY_VALUE, &ioc->chip->WriteSequence);
- drsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "Wait for FW to go to the "
+ drsprintk(ioc, printk(MPT2SAS_INFO_FMT "Wait for FW to go to the "
"READY state\n", ioc->name));
ioc_state = _base_wait_on_iocstate(ioc, MPI2_IOC_STATE_READY, 20,
sleep_flag);
@@ -3398,19 +3405,23 @@ _base_make_ioc_ready(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,
enum reset_type type)
{
u32 ioc_state;
+ int rc;
- dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
+ dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
__func__));
+ if (ioc->pci_error_recovery)
+ return 0;
+
ioc_state = mpt2sas_base_get_iocstate(ioc, 0);
- dhsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: ioc_state(0x%08x)\n",
+ dhsprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: ioc_state(0x%08x)\n",
ioc->name, __func__, ioc_state));
if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_READY)
return 0;
if (ioc_state & MPI2_DOORBELL_USED) {
- dhsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "unexpected doorbell "
+ dhsprintk(ioc, printk(MPT2SAS_INFO_FMT "unexpected doorbell "
"active!\n", ioc->name));
goto issue_diag_reset;
}
@@ -3426,11 +3437,15 @@ _base_make_ioc_ready(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,
if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_OPERATIONAL)
if (!(_base_send_ioc_reset(ioc,
- MPI2_FUNCTION_IOC_MESSAGE_UNIT_RESET, 15, CAN_SLEEP)))
+ MPI2_FUNCTION_IOC_MESSAGE_UNIT_RESET, 15, CAN_SLEEP))) {
+ ioc->ioc_reset_count++;
return 0;
+ }
issue_diag_reset:
- return _base_diag_reset(ioc, CAN_SLEEP);
+ rc = _base_diag_reset(ioc, CAN_SLEEP);
+ ioc->ioc_reset_count++;
+ return rc;
}
/**
@@ -3449,7 +3464,7 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
u16 smid;
struct _tr_list *delayed_tr, *delayed_tr_next;
- dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
+ dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
__func__));
/* clean the delayed target reset list */
@@ -3459,6 +3474,12 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
kfree(delayed_tr);
}
+ list_for_each_entry_safe(delayed_tr, delayed_tr_next,
+ &ioc->delayed_tr_volume_list, list) {
+ list_del(&delayed_tr->list);
+ kfree(delayed_tr);
+ }
+
/* initialize the scsi lookup free list */
spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
INIT_LIST_HEAD(&ioc->free_list);
@@ -3520,6 +3541,13 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
if (sleep_flag == CAN_SLEEP)
_base_static_config_pages(ioc);
+ if (ioc->wait_for_port_enable_to_complete) {
+ if (diag_buffer_enable != 0)
+ mpt2sas_enable_diag_buffer(ioc, diag_buffer_enable);
+ if (disable_discovery > 0)
+ return r;
+ }
+
r = _base_send_port_enable(ioc, sleep_flag);
if (r)
return r;
@@ -3538,7 +3566,7 @@ mpt2sas_base_free_resources(struct MPT2SAS_ADAPTER *ioc)
{
struct pci_dev *pdev = ioc->pdev;
- dexitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
+ dexitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
__func__));
_base_mask_interrupts(ioc);
@@ -3571,7 +3599,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
{
int r, i;
- dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
+ dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
__func__));
r = mpt2sas_base_map_resources(ioc);
@@ -3606,6 +3634,17 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
init_waitqueue_head(&ioc->reset_wq);
+ /* allocate memory pd handle bitmask list */
+ ioc->pd_handles_sz = (ioc->facts.MaxDevHandle / 8);
+ if (ioc->facts.MaxDevHandle % 8)
+ ioc->pd_handles_sz++;
+ ioc->pd_handles = kzalloc(ioc->pd_handles_sz,
+ GFP_KERNEL);
+ if (!ioc->pd_handles) {
+ r = -ENOMEM;
+ goto out_free_resources;
+ }
+
ioc->fwfault_debug = mpt2sas_fwfault_debug;
/* base internal command bits */
@@ -3635,11 +3674,20 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
/* ctl module internal command bits */
ioc->ctl_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL);
+ ioc->ctl_cmds.sense = kzalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL);
ioc->ctl_cmds.status = MPT2_CMD_NOT_USED;
mutex_init(&ioc->ctl_cmds.mutex);
if (!ioc->base_cmds.reply || !ioc->transport_cmds.reply ||
!ioc->scsih_cmds.reply || !ioc->tm_cmds.reply ||
+ !ioc->config_cmds.reply || !ioc->ctl_cmds.reply ||
+ !ioc->ctl_cmds.sense) {
+ r = -ENOMEM;
+ goto out_free_resources;
+ }
+
+ if (!ioc->base_cmds.reply || !ioc->transport_cmds.reply ||
+ !ioc->scsih_cmds.reply || !ioc->tm_cmds.reply ||
!ioc->config_cmds.reply || !ioc->ctl_cmds.reply) {
r = -ENOMEM;
goto out_free_resources;
@@ -3667,8 +3715,6 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
goto out_free_resources;
mpt2sas_base_start_watchdog(ioc);
- if (diag_buffer_enable != 0)
- mpt2sas_enable_diag_buffer(ioc, diag_buffer_enable);
return 0;
out_free_resources:
@@ -3677,12 +3723,14 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
mpt2sas_base_free_resources(ioc);
_base_release_memory_pools(ioc);
pci_set_drvdata(ioc->pdev, NULL);
+ kfree(ioc->pd_handles);
kfree(ioc->tm_cmds.reply);
kfree(ioc->transport_cmds.reply);
kfree(ioc->scsih_cmds.reply);
kfree(ioc->config_cmds.reply);
kfree(ioc->base_cmds.reply);
kfree(ioc->ctl_cmds.reply);
+ kfree(ioc->ctl_cmds.sense);
kfree(ioc->pfacts);
ioc->ctl_cmds.reply = NULL;
ioc->base_cmds.reply = NULL;
@@ -3705,15 +3753,17 @@ void
mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc)
{
- dexitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
+ dexitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
__func__));
mpt2sas_base_stop_watchdog(ioc);
mpt2sas_base_free_resources(ioc);
_base_release_memory_pools(ioc);
pci_set_drvdata(ioc->pdev, NULL);
+ kfree(ioc->pd_handles);
kfree(ioc->pfacts);
kfree(ioc->ctl_cmds.reply);
+ kfree(ioc->ctl_cmds.sense);
kfree(ioc->base_cmds.reply);
kfree(ioc->tm_cmds.reply);
kfree(ioc->transport_cmds.reply);
@@ -3738,11 +3788,11 @@ _base_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
{
switch (reset_phase) {
case MPT2_IOC_PRE_RESET:
- dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
+ dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
"MPT2_IOC_PRE_RESET\n", ioc->name, __func__));
break;
case MPT2_IOC_AFTER_RESET:
- dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
+ dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
"MPT2_IOC_AFTER_RESET\n", ioc->name, __func__));
if (ioc->transport_cmds.status & MPT2_CMD_PENDING) {
ioc->transport_cmds.status |= MPT2_CMD_RESET;
@@ -3762,7 +3812,7 @@ _base_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
}
break;
case MPT2_IOC_DONE_RESET:
- dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
+ dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
"MPT2_IOC_DONE_RESET\n", ioc->name, __func__));
break;
}
@@ -3804,7 +3854,7 @@ _wait_for_commands_to_complete(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
return;
/* wait for pending commands to complete */
- wait_event_timeout(ioc->reset_wq, ioc->pending_io_count == 0, 3 * HZ);
+ wait_event_timeout(ioc->reset_wq, ioc->pending_io_count == 0, 10 * HZ);
}
/**
@@ -3822,19 +3872,37 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,
int r;
unsigned long flags;
- dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: enter\n", ioc->name,
+ dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name,
__func__));
+ if (ioc->pci_error_recovery) {
+ printk(MPT2SAS_ERR_FMT "%s: pci error recovery reset\n",
+ ioc->name, __func__);
+ r = 0;
+ goto out;
+ }
+
if (mpt2sas_fwfault_debug)
mpt2sas_halt_firmware(ioc);
- spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
- if (ioc->shost_recovery) {
- spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
- printk(MPT2SAS_ERR_FMT "%s: busy\n",
- ioc->name, __func__);
- return -EBUSY;
+ /* TODO - What we really should be doing is pulling
+ * out all the code associated with NO_SLEEP; its never used.
+ * That is legacy code from mpt fusion driver, ported over.
+ * I will leave this BUG_ON here for now till its been resolved.
+ */
+ BUG_ON(sleep_flag == NO_SLEEP);
+
+ /* wait for an active reset in progress to complete */
+ if (!mutex_trylock(&ioc->reset_in_progress_mutex)) {
+ do {
+ ssleep(1);
+ } while (ioc->shost_recovery == 1);
+ dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: exit\n", ioc->name,
+ __func__));
+ return ioc->ioc_reset_in_progress_status;
}
+
+ spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
ioc->shost_recovery = 1;
spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
@@ -3849,13 +3917,17 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,
if (!r)
_base_reset_handler(ioc, MPT2_IOC_DONE_RESET);
out:
- dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: %s\n",
+ dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: %s\n",
ioc->name, __func__, ((r == 0) ? "SUCCESS" : "FAILED")));
spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
+ ioc->ioc_reset_in_progress_status = r;
ioc->shost_recovery = 0;
complete(&ioc->shost_recovery_done);
spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
+ mutex_unlock(&ioc->reset_in_progress_mutex);
+ dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: exit\n", ioc->name,
+ __func__));
return r;
}