mirror of
https://github.com/torvalds/linux.git
synced 2024-11-15 00:21:59 +00:00
[SCSI] mpt2sas: Expander remove fails when it is processing another expander add.
This handles the case where driver receives a expander removal event while it is in the middle of processing an expander add event. The existing implementation will stop processing futher device adds when a expander delete arrives on top of add expander add. Due to a sanity check in the driver, the devices there were not added, were never handshaked to firmware with the device removal handshake protocal. Since the driver didnt' do the handshake, the controller never provide further add events. To fix this issue, the sanity check was removed so the driver will always do the device removal handshake protocal. Signed-off-by: Kashyap Desai <kashyap.desai@lsi.com> Signed-off-by: Eric Moore <Eric.moore@lsi.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
This commit is contained in:
parent
c5e039be7e
commit
a28eb222e3
@ -2386,16 +2386,10 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
|
|||||||
|
|
||||||
spin_lock_irqsave(&ioc->sas_device_lock, flags);
|
spin_lock_irqsave(&ioc->sas_device_lock, flags);
|
||||||
sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
|
sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
|
||||||
if (!sas_device) {
|
|
||||||
spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
|
|
||||||
printk(MPT2SAS_ERR_FMT "%s: failed finding sas_device\n",
|
|
||||||
ioc->name, __func__);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
|
spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
|
||||||
|
|
||||||
/* skip is hidden raid component */
|
/* skip is hidden raid component */
|
||||||
if (sas_device->hidden_raid_component)
|
if (sas_device && sas_device->hidden_raid_component)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx);
|
smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx);
|
||||||
@ -2408,18 +2402,31 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
|
|||||||
delayed_tr->state = MPT2SAS_REQ_SAS_CNTRL;
|
delayed_tr->state = MPT2SAS_REQ_SAS_CNTRL;
|
||||||
list_add_tail(&delayed_tr->list,
|
list_add_tail(&delayed_tr->list,
|
||||||
&ioc->delayed_tr_list);
|
&ioc->delayed_tr_list);
|
||||||
if (sas_device->starget)
|
if (sas_device && sas_device->starget) {
|
||||||
dewtprintk(ioc, starget_printk(KERN_INFO,
|
dewtprintk(ioc, starget_printk(KERN_INFO,
|
||||||
sas_device->starget, "DELAYED:tr:handle(0x%04x), "
|
sas_device->starget, "DELAYED:tr:handle(0x%04x), "
|
||||||
"(open)\n", sas_device->handle));
|
"(open)\n", handle));
|
||||||
|
} else {
|
||||||
|
dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
|
||||||
|
"DELAYED:tr:handle(0x%04x), (open)\n",
|
||||||
|
ioc->name, handle));
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sas_device->starget && sas_device->starget->hostdata) {
|
if (sas_device) {
|
||||||
sas_target_priv_data = sas_device->starget->hostdata;
|
sas_device->state |= MPTSAS_STATE_TR_SEND;
|
||||||
sas_target_priv_data->tm_busy = 1;
|
sas_device->state |= MPT2SAS_REQ_SAS_CNTRL;
|
||||||
dewtprintk(ioc, starget_printk(KERN_INFO, sas_device->starget,
|
if (sas_device->starget && sas_device->starget->hostdata) {
|
||||||
"tr:handle(0x%04x), (open)\n", sas_device->handle));
|
sas_target_priv_data = sas_device->starget->hostdata;
|
||||||
|
sas_target_priv_data->tm_busy = 1;
|
||||||
|
dewtprintk(ioc, starget_printk(KERN_INFO,
|
||||||
|
sas_device->starget, "tr:handle(0x%04x), (open)\n",
|
||||||
|
handle));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
|
||||||
|
"tr:handle(0x%04x), (open)\n", ioc->name, handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
|
mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
|
||||||
@ -2427,8 +2434,6 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
|
|||||||
mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
|
mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
|
||||||
mpi_request->DevHandle = cpu_to_le16(handle);
|
mpi_request->DevHandle = cpu_to_le16(handle);
|
||||||
mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
|
mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
|
||||||
sas_device->state |= MPTSAS_STATE_TR_SEND;
|
|
||||||
sas_device->state |= MPT2SAS_REQ_SAS_CNTRL;
|
|
||||||
mpt2sas_base_put_smid_hi_priority(ioc, smid);
|
mpt2sas_base_put_smid_hi_priority(ioc, smid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2463,21 +2468,25 @@ _scsih_sas_control_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid,
|
|||||||
|
|
||||||
spin_lock_irqsave(&ioc->sas_device_lock, flags);
|
spin_lock_irqsave(&ioc->sas_device_lock, flags);
|
||||||
sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
|
sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
|
||||||
if (!sas_device) {
|
|
||||||
spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
|
|
||||||
printk(MPT2SAS_ERR_FMT "%s: failed finding sas_device\n",
|
|
||||||
ioc->name, __func__);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
sas_device->state |= MPTSAS_STATE_CNTRL_COMPLETE;
|
|
||||||
spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
|
spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
|
||||||
|
|
||||||
if (sas_device->starget)
|
if (sas_device) {
|
||||||
dewtprintk(ioc, starget_printk(KERN_INFO, sas_device->starget,
|
sas_device->state |= MPTSAS_STATE_CNTRL_COMPLETE;
|
||||||
|
if (sas_device->starget)
|
||||||
|
dewtprintk(ioc, starget_printk(KERN_INFO,
|
||||||
|
sas_device->starget,
|
||||||
|
"sc_complete:handle(0x%04x), "
|
||||||
|
"ioc_status(0x%04x), loginfo(0x%08x)\n",
|
||||||
|
handle, le16_to_cpu(mpi_reply->IOCStatus),
|
||||||
|
le32_to_cpu(mpi_reply->IOCLogInfo)));
|
||||||
|
} else {
|
||||||
|
dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
|
||||||
"sc_complete:handle(0x%04x), "
|
"sc_complete:handle(0x%04x), "
|
||||||
"ioc_status(0x%04x), loginfo(0x%08x)\n",
|
"ioc_status(0x%04x), loginfo(0x%08x)\n",
|
||||||
handle, le16_to_cpu(mpi_reply->IOCStatus),
|
ioc->name, handle, le16_to_cpu(mpi_reply->IOCStatus),
|
||||||
le32_to_cpu(mpi_reply->IOCLogInfo)));
|
le32_to_cpu(mpi_reply->IOCLogInfo)));
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2515,28 +2524,33 @@ _scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
|
|||||||
handle = le16_to_cpu(mpi_reply->DevHandle);
|
handle = le16_to_cpu(mpi_reply->DevHandle);
|
||||||
spin_lock_irqsave(&ioc->sas_device_lock, flags);
|
spin_lock_irqsave(&ioc->sas_device_lock, flags);
|
||||||
sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
|
sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
|
||||||
if (!sas_device) {
|
|
||||||
spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
|
|
||||||
printk(MPT2SAS_ERR_FMT "%s: failed finding sas_device\n",
|
|
||||||
ioc->name, __func__);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
sas_device->state |= MPTSAS_STATE_TR_COMPLETE;
|
|
||||||
spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
|
spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
|
||||||
|
|
||||||
if (sas_device->starget)
|
if (sas_device) {
|
||||||
dewtprintk(ioc, starget_printk(KERN_INFO, sas_device->starget,
|
sas_device->state |= MPTSAS_STATE_TR_COMPLETE;
|
||||||
"tr_complete:handle(0x%04x), (%s) ioc_status(0x%04x), "
|
if (sas_device->starget) {
|
||||||
"loginfo(0x%08x), completed(%d)\n",
|
dewtprintk(ioc, starget_printk(KERN_INFO,
|
||||||
sas_device->handle, (sas_device->state &
|
sas_device->starget, "tr_complete:handle(0x%04x), "
|
||||||
MPT2SAS_REQ_SAS_CNTRL) ? "open" : "active",
|
"(%s) ioc_status(0x%04x), loginfo(0x%08x), "
|
||||||
le16_to_cpu(mpi_reply->IOCStatus),
|
"completed(%d)\n", sas_device->handle,
|
||||||
|
(sas_device->state & MPT2SAS_REQ_SAS_CNTRL) ?
|
||||||
|
"open" : "active",
|
||||||
|
le16_to_cpu(mpi_reply->IOCStatus),
|
||||||
|
le32_to_cpu(mpi_reply->IOCLogInfo),
|
||||||
|
le32_to_cpu(mpi_reply->TerminationCount)));
|
||||||
|
if (sas_device->starget->hostdata) {
|
||||||
|
sas_target_priv_data =
|
||||||
|
sas_device->starget->hostdata;
|
||||||
|
sas_target_priv_data->tm_busy = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
|
||||||
|
"tr_complete:handle(0x%04x), (open) ioc_status(0x%04x), "
|
||||||
|
"loginfo(0x%08x), completed(%d)\n", ioc->name,
|
||||||
|
handle, le16_to_cpu(mpi_reply->IOCStatus),
|
||||||
le32_to_cpu(mpi_reply->IOCLogInfo),
|
le32_to_cpu(mpi_reply->IOCLogInfo),
|
||||||
le32_to_cpu(mpi_reply->TerminationCount)));
|
le32_to_cpu(mpi_reply->TerminationCount)));
|
||||||
|
|
||||||
if (sas_device->starget && sas_device->starget->hostdata) {
|
|
||||||
sas_target_priv_data = sas_device->starget->hostdata;
|
|
||||||
sas_target_priv_data->tm_busy = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!list_empty(&ioc->delayed_tr_list)) {
|
if (!list_empty(&ioc->delayed_tr_list)) {
|
||||||
@ -2551,8 +2565,7 @@ _scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
|
|||||||
} else
|
} else
|
||||||
rc = 1;
|
rc = 1;
|
||||||
|
|
||||||
|
if (sas_device && !(sas_device->state & MPT2SAS_REQ_SAS_CNTRL))
|
||||||
if (!(sas_device->state & MPT2SAS_REQ_SAS_CNTRL))
|
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
if (ioc->shost_recovery) {
|
if (ioc->shost_recovery) {
|
||||||
@ -2568,12 +2581,14 @@ _scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sas_device)
|
||||||
|
sas_device->state |= MPTSAS_STATE_CNTRL_SEND;
|
||||||
|
|
||||||
mpi_request = mpt2sas_base_get_msg_frame(ioc, smid_sas_ctrl);
|
mpi_request = mpt2sas_base_get_msg_frame(ioc, smid_sas_ctrl);
|
||||||
memset(mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t));
|
memset(mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t));
|
||||||
mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
|
mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
|
||||||
mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE;
|
mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE;
|
||||||
mpi_request->DevHandle = mpi_reply->DevHandle;
|
mpi_request->DevHandle = mpi_reply->DevHandle;
|
||||||
sas_device->state |= MPTSAS_STATE_CNTRL_SEND;
|
|
||||||
mpt2sas_base_put_smid_default(ioc, smid_sas_ctrl);
|
mpt2sas_base_put_smid_default(ioc, smid_sas_ctrl);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user