|
@@ -79,6 +79,9 @@ static u8 transport_cb_idx = -1;
|
|
|
static u8 config_cb_idx = -1;
|
|
|
static int mpt_ids;
|
|
|
|
|
|
+static u8 tm_tr_cb_idx = -1 ;
|
|
|
+static u8 tm_sas_control_cb_idx = -1;
|
|
|
+
|
|
|
/* command line options */
|
|
|
static u32 logging_level;
|
|
|
MODULE_PARM_DESC(logging_level, " bits for enabling additional logging info "
|
|
@@ -1641,17 +1644,18 @@ _scsih_response_code(struct MPT2SAS_ADAPTER *ioc, u8 response_code)
|
|
|
*
|
|
|
* The callback handler when using scsih_issue_tm.
|
|
|
*
|
|
|
- * Return nothing.
|
|
|
+ * Return 1 meaning mf should be freed from _base_interrupt
|
|
|
+ * 0 means the mf is freed from this function.
|
|
|
*/
|
|
|
-static void
|
|
|
+static u8
|
|
|
_scsih_tm_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
|
|
|
{
|
|
|
MPI2DefaultReply_t *mpi_reply;
|
|
|
|
|
|
if (ioc->tm_cmds.status == MPT2_CMD_NOT_USED)
|
|
|
- return;
|
|
|
+ return 1;
|
|
|
if (ioc->tm_cmds.smid != smid)
|
|
|
- return;
|
|
|
+ return 1;
|
|
|
ioc->tm_cmds.status |= MPT2_CMD_COMPLETE;
|
|
|
mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
|
|
|
if (mpi_reply) {
|
|
@@ -1660,6 +1664,7 @@ _scsih_tm_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
|
|
|
}
|
|
|
ioc->tm_cmds.status &= ~MPT2_CMD_PENDING;
|
|
|
complete(&ioc->tm_cmds.done);
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -2311,6 +2316,231 @@ _scsih_block_io_to_children_attached_directly(struct MPT2SAS_ADAPTER *ioc,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * _scsih_tm_tr_send - send task management request
|
|
|
+ * @ioc: per adapter object
|
|
|
+ * @handle: device handle
|
|
|
+ * Context: interrupt time.
|
|
|
+ *
|
|
|
+ * This code is to initiate the device removal handshake protocal
|
|
|
+ * with controller firmware. This function will issue target reset
|
|
|
+ * using high priority request queue. It will send a sas iounit
|
|
|
+ * controll request (MPI2_SAS_OP_REMOVE_DEVICE) from this completion.
|
|
|
+ *
|
|
|
+ * This is designed to send muliple task management request at the same
|
|
|
+ * time to the fifo. If the fifo is full, we will append the request,
|
|
|
+ * and process it in a future completion.
|
|
|
+ */
|
|
|
+static void
|
|
|
+_scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
|
|
|
+{
|
|
|
+ Mpi2SCSITaskManagementRequest_t *mpi_request;
|
|
|
+ struct MPT2SAS_TARGET *sas_target_priv_data;
|
|
|
+ u16 smid;
|
|
|
+ struct _sas_device *sas_device;
|
|
|
+ unsigned long flags;
|
|
|
+ struct _tr_list *delayed_tr;
|
|
|
+
|
|
|
+ if (ioc->shost_recovery) {
|
|
|
+ printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
|
|
|
+ __func__, ioc->name);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ spin_lock_irqsave(&ioc->sas_device_lock, flags);
|
|
|
+ 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);
|
|
|
+
|
|
|
+ /* skip is hidden raid component */
|
|
|
+ if (sas_device->hidden_raid_component)
|
|
|
+ return;
|
|
|
+
|
|
|
+ smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx);
|
|
|
+ if (!smid) {
|
|
|
+ delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC);
|
|
|
+ if (!delayed_tr)
|
|
|
+ return;
|
|
|
+ INIT_LIST_HEAD(&delayed_tr->list);
|
|
|
+ delayed_tr->handle = handle;
|
|
|
+ delayed_tr->state = MPT2SAS_REQ_SAS_CNTRL;
|
|
|
+ list_add_tail(&delayed_tr->list,
|
|
|
+ &ioc->delayed_tr_list);
|
|
|
+ if (sas_device->starget)
|
|
|
+ dewtprintk(ioc, starget_printk(KERN_INFO,
|
|
|
+ sas_device->starget, "DELAYED:tr:handle(0x%04x), "
|
|
|
+ "(open)\n", sas_device->handle));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (sas_device->starget && sas_device->starget->hostdata) {
|
|
|
+ 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", sas_device->handle));
|
|
|
+ }
|
|
|
+
|
|
|
+ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
|
|
|
+ memset(mpi_request, 0, sizeof(Mpi2SCSITaskManagementRequest_t));
|
|
|
+ mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
|
|
|
+ mpi_request->DevHandle = cpu_to_le16(handle);
|
|
|
+ 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);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ * _scsih_sas_control_complete - completion routine
|
|
|
+ * @ioc: per adapter object
|
|
|
+ * @smid: system request message index
|
|
|
+ * @msix_index: MSIX table index supplied by the OS
|
|
|
+ * @reply: reply message frame(lower 32bit addr)
|
|
|
+ * Context: interrupt time.
|
|
|
+ *
|
|
|
+ * This is the sas iounit controll completion routine.
|
|
|
+ * This code is part of the code to initiate the device removal
|
|
|
+ * handshake protocal with controller firmware.
|
|
|
+ *
|
|
|
+ * Return 1 meaning mf should be freed from _base_interrupt
|
|
|
+ * 0 means the mf is freed from this function.
|
|
|
+ */
|
|
|
+static u8
|
|
|
+_scsih_sas_control_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid,
|
|
|
+ u8 msix_index, u32 reply)
|
|
|
+{
|
|
|
+ unsigned long flags;
|
|
|
+ u16 handle;
|
|
|
+ struct _sas_device *sas_device;
|
|
|
+ Mpi2SasIoUnitControlReply_t *mpi_reply =
|
|
|
+ mpt2sas_base_get_reply_virt_addr(ioc, reply);
|
|
|
+
|
|
|
+ handle = le16_to_cpu(mpi_reply->DevHandle);
|
|
|
+
|
|
|
+ spin_lock_irqsave(&ioc->sas_device_lock, flags);
|
|
|
+ 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);
|
|
|
+
|
|
|
+ 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)));
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * _scsih_tm_tr_complete -
|
|
|
+ * @ioc: per adapter object
|
|
|
+ * @smid: system request message index
|
|
|
+ * @msix_index: MSIX table index supplied by the OS
|
|
|
+ * @reply: reply message frame(lower 32bit addr)
|
|
|
+ * Context: interrupt time.
|
|
|
+ *
|
|
|
+ * This is the target reset completion routine.
|
|
|
+ * This code is part of the code to initiate the device removal
|
|
|
+ * handshake protocal with controller firmware.
|
|
|
+ * It will send a sas iounit controll request (MPI2_SAS_OP_REMOVE_DEVICE)
|
|
|
+ *
|
|
|
+ * Return 1 meaning mf should be freed from _base_interrupt
|
|
|
+ * 0 means the mf is freed from this function.
|
|
|
+ */
|
|
|
+static u8
|
|
|
+_scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
|
|
|
+ u32 reply)
|
|
|
+{
|
|
|
+ unsigned long flags;
|
|
|
+ u16 handle;
|
|
|
+ struct _sas_device *sas_device;
|
|
|
+ Mpi2SCSITaskManagementReply_t *mpi_reply =
|
|
|
+ mpt2sas_base_get_reply_virt_addr(ioc, reply);
|
|
|
+ Mpi2SasIoUnitControlRequest_t *mpi_request;
|
|
|
+ u16 smid_sas_ctrl;
|
|
|
+ struct MPT2SAS_TARGET *sas_target_priv_data;
|
|
|
+ struct _tr_list *delayed_tr;
|
|
|
+ u8 rc;
|
|
|
+
|
|
|
+ handle = le16_to_cpu(mpi_reply->DevHandle);
|
|
|
+ spin_lock_irqsave(&ioc->sas_device_lock, flags);
|
|
|
+ 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);
|
|
|
+
|
|
|
+ if (sas_device->starget)
|
|
|
+ dewtprintk(ioc, starget_printk(KERN_INFO, sas_device->starget,
|
|
|
+ "tr_complete:handle(0x%04x), (%s) ioc_status(0x%04x), "
|
|
|
+ "loginfo(0x%08x), 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 && 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)) {
|
|
|
+ delayed_tr = list_entry(ioc->delayed_tr_list.next,
|
|
|
+ struct _tr_list, list);
|
|
|
+ mpt2sas_base_free_smid(ioc, smid);
|
|
|
+ if (delayed_tr->state & MPT2SAS_REQ_SAS_CNTRL)
|
|
|
+ _scsih_tm_tr_send(ioc, delayed_tr->handle);
|
|
|
+ list_del(&delayed_tr->list);
|
|
|
+ kfree(delayed_tr);
|
|
|
+ rc = 0; /* tells base_interrupt not to free mf */
|
|
|
+ } else
|
|
|
+ rc = 1;
|
|
|
+
|
|
|
+
|
|
|
+ if (!(sas_device->state & MPT2SAS_REQ_SAS_CNTRL))
|
|
|
+ return rc;
|
|
|
+
|
|
|
+ if (ioc->shost_recovery) {
|
|
|
+ printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
|
|
|
+ __func__, ioc->name);
|
|
|
+ return rc;
|
|
|
+ }
|
|
|
+
|
|
|
+ smid_sas_ctrl = mpt2sas_base_get_smid(ioc, ioc->tm_sas_control_cb_idx);
|
|
|
+ if (!smid_sas_ctrl) {
|
|
|
+ printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
|
|
|
+ ioc->name, __func__);
|
|
|
+ return rc;
|
|
|
+ }
|
|
|
+
|
|
|
+ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid_sas_ctrl);
|
|
|
+ memset(mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t));
|
|
|
+ mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
|
|
|
+ mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE;
|
|
|
+ mpi_request->DevHandle = mpi_reply->DevHandle;
|
|
|
+ sas_device->state |= MPTSAS_STATE_CNTRL_SEND;
|
|
|
+ mpt2sas_base_put_smid_default(ioc, smid_sas_ctrl);
|
|
|
+ return rc;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* _scsih_check_topo_delete_events - sanity check on topo events
|
|
|
* @ioc: per adapter object
|
|
@@ -2333,6 +2563,21 @@ _scsih_check_topo_delete_events(struct MPT2SAS_ADAPTER *ioc,
|
|
|
u16 expander_handle;
|
|
|
struct _sas_node *sas_expander;
|
|
|
unsigned long flags;
|
|
|
+ int i, reason_code;
|
|
|
+ u16 handle;
|
|
|
+
|
|
|
+ for (i = 0 ; i < event_data->NumEntries; i++) {
|
|
|
+ if (event_data->PHY[i].PhyStatus &
|
|
|
+ MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT)
|
|
|
+ continue;
|
|
|
+ handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle);
|
|
|
+ if (!handle)
|
|
|
+ continue;
|
|
|
+ reason_code = event_data->PHY[i].PhyStatus &
|
|
|
+ MPI2_EVENT_SAS_TOPO_RC_MASK;
|
|
|
+ if (reason_code == MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING)
|
|
|
+ _scsih_tm_tr_send(ioc, handle);
|
|
|
+ }
|
|
|
|
|
|
expander_handle = le16_to_cpu(event_data->ExpanderDevHandle);
|
|
|
if (expander_handle < ioc->sas_hba.num_phys) {
|
|
@@ -2915,11 +3160,12 @@ _scsih_smart_predicted_fault(struct MPT2SAS_ADAPTER *ioc, u16 handle)
|
|
|
* @msix_index: MSIX table index supplied by the OS
|
|
|
* @reply: reply message frame(lower 32bit addr)
|
|
|
*
|
|
|
- * Callback handler when using scsih_qcmd.
|
|
|
+ * Callback handler when using _scsih_qcmd.
|
|
|
*
|
|
|
- * Return nothing.
|
|
|
+ * Return 1 meaning mf should be freed from _base_interrupt
|
|
|
+ * 0 means the mf is freed from this function.
|
|
|
*/
|
|
|
-static void
|
|
|
+static u8
|
|
|
_scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
|
|
|
{
|
|
|
Mpi2SCSIIORequest_t *mpi_request;
|
|
@@ -2936,7 +3182,7 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
|
|
|
mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
|
|
|
scmd = _scsih_scsi_lookup_get(ioc, smid);
|
|
|
if (scmd == NULL)
|
|
|
- return;
|
|
|
+ return 1;
|
|
|
|
|
|
mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
|
|
|
|
|
@@ -3092,6 +3338,7 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
|
|
|
out:
|
|
|
scsi_dma_unmap(scmd);
|
|
|
scmd->scsi_done(scmd);
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -3623,6 +3870,12 @@ _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, u16 handle)
|
|
|
if (ioc->remove_host)
|
|
|
goto out;
|
|
|
|
|
|
+ if ((sas_device->state & MPTSAS_STATE_TR_COMPLETE)) {
|
|
|
+ dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "\tskip "
|
|
|
+ "target_reset handle(0x%04x)\n", ioc->name, handle));
|
|
|
+ goto skip_tr;
|
|
|
+ }
|
|
|
+
|
|
|
/* Target Reset to flush out all the outstanding IO */
|
|
|
device_handle = (sas_device->hidden_raid_component) ?
|
|
|
sas_device->volume_handle : handle;
|
|
@@ -3639,6 +3892,13 @@ _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, u16 handle)
|
|
|
if (ioc->shost_recovery)
|
|
|
goto out;
|
|
|
}
|
|
|
+ skip_tr:
|
|
|
+
|
|
|
+ if ((sas_device->state & MPTSAS_STATE_CNTRL_COMPLETE)) {
|
|
|
+ dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "\tskip "
|
|
|
+ "sas_cntrl handle(0x%04x)\n", ioc->name, handle));
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
|
|
|
/* SAS_IO_UNIT_CNTR - send REMOVE_DEVICE */
|
|
|
dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "sas_iounit: handle"
|
|
@@ -4829,6 +5089,10 @@ _scsih_mark_responding_sas_device(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
|
|
|
if (sas_device->sas_address == sas_address &&
|
|
|
sas_device->slot == slot && sas_device->starget) {
|
|
|
sas_device->responding = 1;
|
|
|
+ sas_device->state = 0;
|
|
|
+ starget = sas_device->starget;
|
|
|
+ sas_target_priv_data = starget->hostdata;
|
|
|
+ sas_target_priv_data->tm_busy = 0;
|
|
|
starget_printk(KERN_INFO, sas_device->starget,
|
|
|
"handle(0x%04x), sas_addr(0x%016llx), enclosure "
|
|
|
"logical id(0x%016llx), slot(%d)\n", handle,
|
|
@@ -4841,8 +5105,6 @@ _scsih_mark_responding_sas_device(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
|
|
|
printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n",
|
|
|
sas_device->handle);
|
|
|
sas_device->handle = handle;
|
|
|
- starget = sas_device->starget;
|
|
|
- sas_target_priv_data = starget->hostdata;
|
|
|
sas_target_priv_data->handle = handle;
|
|
|
goto out;
|
|
|
}
|
|
@@ -5235,9 +5497,10 @@ _firmware_event_work(struct work_struct *work)
|
|
|
* This function merely adds a new work task into ioc->firmware_event_thread.
|
|
|
* The tasks are worked from _firmware_event_work in user context.
|
|
|
*
|
|
|
- * Return nothing.
|
|
|
+ * Return 1 meaning mf should be freed from _base_interrupt
|
|
|
+ * 0 means the mf is freed from this function.
|
|
|
*/
|
|
|
-void
|
|
|
+u8
|
|
|
mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
|
|
|
u32 reply)
|
|
|
{
|
|
@@ -5250,11 +5513,11 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
|
|
|
spin_lock_irqsave(&ioc->fw_event_lock, flags);
|
|
|
if (ioc->fw_events_off || ioc->remove_host) {
|
|
|
spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
|
|
|
- return;
|
|
|
+ return 1;
|
|
|
}
|
|
|
spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
|
|
|
|
|
|
- mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
|
|
|
+ mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
|
|
|
event = le16_to_cpu(mpi_reply->Event);
|
|
|
|
|
|
switch (event) {
|
|
@@ -5268,7 +5531,7 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
|
|
|
if (baen_data->Primitive !=
|
|
|
MPI2_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT ||
|
|
|
ioc->broadcast_aen_busy)
|
|
|
- return;
|
|
|
+ return 1;
|
|
|
ioc->broadcast_aen_busy = 1;
|
|
|
break;
|
|
|
}
|
|
@@ -5290,14 +5553,14 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
|
|
|
break;
|
|
|
|
|
|
default: /* ignore the rest */
|
|
|
- return;
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC);
|
|
|
if (!fw_event) {
|
|
|
printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
|
|
|
ioc->name, __FILE__, __LINE__, __func__);
|
|
|
- return;
|
|
|
+ return 1;
|
|
|
}
|
|
|
fw_event->event_data =
|
|
|
kzalloc(mpi_reply->EventDataLength*4, GFP_ATOMIC);
|
|
@@ -5305,7 +5568,7 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
|
|
|
printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
|
|
|
ioc->name, __FILE__, __LINE__, __func__);
|
|
|
kfree(fw_event);
|
|
|
- return;
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
memcpy(fw_event->event_data, mpi_reply->EventData,
|
|
@@ -5315,6 +5578,7 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
|
|
|
fw_event->VP_ID = mpi_reply->VP_ID;
|
|
|
fw_event->event = event;
|
|
|
_scsih_fw_event_add(ioc, fw_event);
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
/* shost template */
|
|
@@ -5574,7 +5838,7 @@ _scsih_probe_raid(struct MPT2SAS_ADAPTER *ioc)
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * _scsih_probe_sas - reporting raid volumes to sas transport
|
|
|
+ * _scsih_probe_sas - reporting sas devices to sas transport
|
|
|
* @ioc: per adapter object
|
|
|
*
|
|
|
* Called during initial loading of the driver.
|
|
@@ -5671,6 +5935,8 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|
|
ioc->base_cb_idx = base_cb_idx;
|
|
|
ioc->transport_cb_idx = transport_cb_idx;
|
|
|
ioc->config_cb_idx = config_cb_idx;
|
|
|
+ ioc->tm_tr_cb_idx = tm_tr_cb_idx;
|
|
|
+ ioc->tm_sas_control_cb_idx = tm_sas_control_cb_idx;
|
|
|
ioc->logging_level = logging_level;
|
|
|
/* misc semaphores and spin locks */
|
|
|
spin_lock_init(&ioc->ioc_reset_in_progress_lock);
|
|
@@ -5686,6 +5952,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|
|
INIT_LIST_HEAD(&ioc->fw_event_list);
|
|
|
INIT_LIST_HEAD(&ioc->raid_device_list);
|
|
|
INIT_LIST_HEAD(&ioc->sas_hba.sas_port_list);
|
|
|
+ INIT_LIST_HEAD(&ioc->delayed_tr_list);
|
|
|
|
|
|
/* init shost parameters */
|
|
|
shost->max_cmd_len = 16;
|
|
@@ -5702,6 +5969,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|
|
|
|
|
scsi_host_set_prot(shost, SHOST_DIF_TYPE1_PROTECTION
|
|
|
| SHOST_DIF_TYPE3_PROTECTION);
|
|
|
+ scsi_host_set_guard(shost, SHOST_DIX_GUARD_CRC);
|
|
|
|
|
|
/* event thread */
|
|
|
snprintf(ioc->firmware_event_name, sizeof(ioc->firmware_event_name),
|
|
@@ -5851,6 +6119,11 @@ _scsih_init(void)
|
|
|
/* ctl module callback handler */
|
|
|
ctl_cb_idx = mpt2sas_base_register_callback_handler(mpt2sas_ctl_done);
|
|
|
|
|
|
+ tm_tr_cb_idx = mpt2sas_base_register_callback_handler(
|
|
|
+ _scsih_tm_tr_complete);
|
|
|
+ tm_sas_control_cb_idx = mpt2sas_base_register_callback_handler(
|
|
|
+ _scsih_sas_control_complete);
|
|
|
+
|
|
|
mpt2sas_ctl_init();
|
|
|
|
|
|
error = pci_register_driver(&scsih_driver);
|
|
@@ -5881,6 +6154,9 @@ _scsih_exit(void)
|
|
|
mpt2sas_base_release_callback_handler(config_cb_idx);
|
|
|
mpt2sas_base_release_callback_handler(ctl_cb_idx);
|
|
|
|
|
|
+ mpt2sas_base_release_callback_handler(tm_tr_cb_idx);
|
|
|
+ mpt2sas_base_release_callback_handler(tm_sas_control_cb_idx);
|
|
|
+
|
|
|
mpt2sas_ctl_exit();
|
|
|
}
|
|
|
|