|
@@ -71,6 +71,9 @@ static void _firmware_event_work(struct work_struct *work);
|
|
|
|
|
|
static u8 _scsih_check_for_pending_tm(struct MPT2SAS_ADAPTER *ioc, u16 smid);
|
|
static u8 _scsih_check_for_pending_tm(struct MPT2SAS_ADAPTER *ioc, u16 smid);
|
|
|
|
|
|
|
|
+static void _scsih_scan_start(struct Scsi_Host *shost);
|
|
|
|
+static int _scsih_scan_finished(struct Scsi_Host *shost, unsigned long time);
|
|
|
|
+
|
|
/* global parameters */
|
|
/* global parameters */
|
|
LIST_HEAD(mpt2sas_ioc_list);
|
|
LIST_HEAD(mpt2sas_ioc_list);
|
|
|
|
|
|
@@ -79,6 +82,7 @@ static u8 scsi_io_cb_idx = -1;
|
|
static u8 tm_cb_idx = -1;
|
|
static u8 tm_cb_idx = -1;
|
|
static u8 ctl_cb_idx = -1;
|
|
static u8 ctl_cb_idx = -1;
|
|
static u8 base_cb_idx = -1;
|
|
static u8 base_cb_idx = -1;
|
|
|
|
+static u8 port_enable_cb_idx = -1;
|
|
static u8 transport_cb_idx = -1;
|
|
static u8 transport_cb_idx = -1;
|
|
static u8 scsih_cb_idx = -1;
|
|
static u8 scsih_cb_idx = -1;
|
|
static u8 config_cb_idx = -1;
|
|
static u8 config_cb_idx = -1;
|
|
@@ -103,6 +107,18 @@ static int max_lun = MPT2SAS_MAX_LUN;
|
|
module_param(max_lun, int, 0);
|
|
module_param(max_lun, int, 0);
|
|
MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
|
|
MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
|
|
|
|
|
|
|
|
+/* diag_buffer_enable is bitwise
|
|
|
|
+ * bit 0 set = TRACE
|
|
|
|
+ * bit 1 set = SNAPSHOT
|
|
|
|
+ * bit 2 set = EXTENDED
|
|
|
|
+ *
|
|
|
|
+ * Either bit can be set, or both
|
|
|
|
+ */
|
|
|
|
+static int diag_buffer_enable = -1;
|
|
|
|
+module_param(diag_buffer_enable, int, 0);
|
|
|
|
+MODULE_PARM_DESC(diag_buffer_enable, " post diag buffers "
|
|
|
|
+ "(TRACE=1/SNAPSHOT=2/EXTENDED=4/default=0)");
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* struct sense_info - common structure for obtaining sense keys
|
|
* struct sense_info - common structure for obtaining sense keys
|
|
* @skey: sense key
|
|
* @skey: sense key
|
|
@@ -117,8 +133,8 @@ struct sense_info {
|
|
|
|
|
|
|
|
|
|
#define MPT2SAS_TURN_ON_FAULT_LED (0xFFFC)
|
|
#define MPT2SAS_TURN_ON_FAULT_LED (0xFFFC)
|
|
-#define MPT2SAS_RESCAN_AFTER_HOST_RESET (0xFFFF)
|
|
|
|
-
|
|
|
|
|
|
+#define MPT2SAS_PORT_ENABLE_COMPLETE (0xFFFD)
|
|
|
|
+#define MPT2SAS_REMOVE_UNRESPONDING_DEVICES (0xFFFF)
|
|
/**
|
|
/**
|
|
* struct fw_event_work - firmware event struct
|
|
* struct fw_event_work - firmware event struct
|
|
* @list: link list framework
|
|
* @list: link list framework
|
|
@@ -424,7 +440,11 @@ _scsih_determine_boot_device(struct MPT2SAS_ADAPTER *ioc,
|
|
u16 slot;
|
|
u16 slot;
|
|
|
|
|
|
/* only process this function when driver loads */
|
|
/* only process this function when driver loads */
|
|
- if (!ioc->wait_for_port_enable_to_complete)
|
|
|
|
|
|
+ if (!ioc->is_driver_loading)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ /* no Bios, return immediately */
|
|
|
|
+ if (!ioc->bios_pg3.BiosVersion)
|
|
return;
|
|
return;
|
|
|
|
|
|
if (!is_raid) {
|
|
if (!is_raid) {
|
|
@@ -2714,22 +2734,38 @@ _scsih_fw_event_free(struct MPT2SAS_ADAPTER *ioc, struct fw_event_work
|
|
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
- * _scsih_queue_rescan - queue a topology rescan from user context
|
|
|
|
|
|
+ * _scsih_error_recovery_delete_devices - remove devices not responding
|
|
* @ioc: per adapter object
|
|
* @ioc: per adapter object
|
|
*
|
|
*
|
|
* Return nothing.
|
|
* Return nothing.
|
|
*/
|
|
*/
|
|
static void
|
|
static void
|
|
-_scsih_queue_rescan(struct MPT2SAS_ADAPTER *ioc)
|
|
|
|
|
|
+_scsih_error_recovery_delete_devices(struct MPT2SAS_ADAPTER *ioc)
|
|
{
|
|
{
|
|
struct fw_event_work *fw_event;
|
|
struct fw_event_work *fw_event;
|
|
|
|
|
|
- if (ioc->wait_for_port_enable_to_complete)
|
|
|
|
|
|
+ if (ioc->is_driver_loading)
|
|
return;
|
|
return;
|
|
|
|
+ fw_event->event = MPT2SAS_REMOVE_UNRESPONDING_DEVICES;
|
|
|
|
+ fw_event->ioc = ioc;
|
|
|
|
+ _scsih_fw_event_add(ioc, fw_event);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * mpt2sas_port_enable_complete - port enable completed (fake event)
|
|
|
|
+ * @ioc: per adapter object
|
|
|
|
+ *
|
|
|
|
+ * Return nothing.
|
|
|
|
+ */
|
|
|
|
+void
|
|
|
|
+mpt2sas_port_enable_complete(struct MPT2SAS_ADAPTER *ioc)
|
|
|
|
+{
|
|
|
|
+ struct fw_event_work *fw_event;
|
|
|
|
+
|
|
fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC);
|
|
fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC);
|
|
if (!fw_event)
|
|
if (!fw_event)
|
|
return;
|
|
return;
|
|
- fw_event->event = MPT2SAS_RESCAN_AFTER_HOST_RESET;
|
|
|
|
|
|
+ fw_event->event = MPT2SAS_PORT_ENABLE_COMPLETE;
|
|
fw_event->ioc = ioc;
|
|
fw_event->ioc = ioc;
|
|
_scsih_fw_event_add(ioc, fw_event);
|
|
_scsih_fw_event_add(ioc, fw_event);
|
|
}
|
|
}
|
|
@@ -5099,7 +5135,7 @@ _scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd)
|
|
/* get device name */
|
|
/* get device name */
|
|
sas_device->device_name = le64_to_cpu(sas_device_pg0.DeviceName);
|
|
sas_device->device_name = le64_to_cpu(sas_device_pg0.DeviceName);
|
|
|
|
|
|
- if (ioc->wait_for_port_enable_to_complete)
|
|
|
|
|
|
+ if (ioc->wait_for_discovery_to_complete)
|
|
_scsih_sas_device_init_add(ioc, sas_device);
|
|
_scsih_sas_device_init_add(ioc, sas_device);
|
|
else
|
|
else
|
|
_scsih_sas_device_add(ioc, sas_device);
|
|
_scsih_sas_device_add(ioc, sas_device);
|
|
@@ -5622,7 +5658,7 @@ broadcast_aen_retry:
|
|
termination_count = 0;
|
|
termination_count = 0;
|
|
query_count = 0;
|
|
query_count = 0;
|
|
for (smid = 1; smid <= ioc->scsiio_depth; smid++) {
|
|
for (smid = 1; smid <= ioc->scsiio_depth; smid++) {
|
|
- if (ioc->ioc_reset_in_progress_status)
|
|
|
|
|
|
+ if (ioc->shost_recovery)
|
|
goto out;
|
|
goto out;
|
|
scmd = _scsih_scsi_lookup_get(ioc, smid);
|
|
scmd = _scsih_scsi_lookup_get(ioc, smid);
|
|
if (!scmd)
|
|
if (!scmd)
|
|
@@ -5644,7 +5680,7 @@ broadcast_aen_retry:
|
|
lun = sas_device_priv_data->lun;
|
|
lun = sas_device_priv_data->lun;
|
|
query_count++;
|
|
query_count++;
|
|
|
|
|
|
- if (ioc->ioc_reset_in_progress_status)
|
|
|
|
|
|
+ if (ioc->shost_recovery)
|
|
goto out;
|
|
goto out;
|
|
|
|
|
|
spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
|
|
spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
|
|
@@ -5686,7 +5722,7 @@ broadcast_aen_retry:
|
|
goto broadcast_aen_retry;
|
|
goto broadcast_aen_retry;
|
|
}
|
|
}
|
|
|
|
|
|
- if (ioc->ioc_reset_in_progress_status)
|
|
|
|
|
|
+ if (ioc->shost_recovery)
|
|
goto out_no_lock;
|
|
goto out_no_lock;
|
|
|
|
|
|
r = mpt2sas_scsih_issue_tm(ioc, handle, sdev->channel, sdev->id,
|
|
r = mpt2sas_scsih_issue_tm(ioc, handle, sdev->channel, sdev->id,
|
|
@@ -5725,7 +5761,7 @@ broadcast_aen_retry:
|
|
ioc->name, __func__, query_count, termination_count));
|
|
ioc->name, __func__, query_count, termination_count));
|
|
|
|
|
|
ioc->broadcast_aen_busy = 0;
|
|
ioc->broadcast_aen_busy = 0;
|
|
- if (!ioc->ioc_reset_in_progress_status)
|
|
|
|
|
|
+ if (!ioc->shost_recovery)
|
|
_scsih_ublock_io_all_device(ioc);
|
|
_scsih_ublock_io_all_device(ioc);
|
|
mutex_unlock(&ioc->tm_cmds.mutex);
|
|
mutex_unlock(&ioc->tm_cmds.mutex);
|
|
}
|
|
}
|
|
@@ -5845,7 +5881,7 @@ _scsih_sas_volume_add(struct MPT2SAS_ADAPTER *ioc,
|
|
raid_device->handle = handle;
|
|
raid_device->handle = handle;
|
|
raid_device->wwid = wwid;
|
|
raid_device->wwid = wwid;
|
|
_scsih_raid_device_add(ioc, raid_device);
|
|
_scsih_raid_device_add(ioc, raid_device);
|
|
- if (!ioc->wait_for_port_enable_to_complete) {
|
|
|
|
|
|
+ if (!ioc->wait_for_discovery_to_complete) {
|
|
rc = scsi_add_device(ioc->shost, RAID_CHANNEL,
|
|
rc = scsi_add_device(ioc->shost, RAID_CHANNEL,
|
|
raid_device->id, 0);
|
|
raid_device->id, 0);
|
|
if (rc)
|
|
if (rc)
|
|
@@ -6127,6 +6163,10 @@ _scsih_sas_ir_config_change_event(struct MPT2SAS_ADAPTER *ioc,
|
|
_scsih_sas_ir_config_change_event_debug(ioc, event_data);
|
|
_scsih_sas_ir_config_change_event_debug(ioc, event_data);
|
|
|
|
|
|
#endif
|
|
#endif
|
|
|
|
+
|
|
|
|
+ if (ioc->shost_recovery)
|
|
|
|
+ return;
|
|
|
|
+
|
|
foreign_config = (le32_to_cpu(event_data->Flags) &
|
|
foreign_config = (le32_to_cpu(event_data->Flags) &
|
|
MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) ? 1 : 0;
|
|
MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) ? 1 : 0;
|
|
|
|
|
|
@@ -6185,6 +6225,9 @@ _scsih_sas_ir_volume_event(struct MPT2SAS_ADAPTER *ioc,
|
|
int rc;
|
|
int rc;
|
|
Mpi2EventDataIrVolume_t *event_data = fw_event->event_data;
|
|
Mpi2EventDataIrVolume_t *event_data = fw_event->event_data;
|
|
|
|
|
|
|
|
+ if (ioc->shost_recovery)
|
|
|
|
+ return;
|
|
|
|
+
|
|
if (event_data->ReasonCode != MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED)
|
|
if (event_data->ReasonCode != MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED)
|
|
return;
|
|
return;
|
|
|
|
|
|
@@ -6267,6 +6310,9 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc,
|
|
Mpi2EventDataIrPhysicalDisk_t *event_data = fw_event->event_data;
|
|
Mpi2EventDataIrPhysicalDisk_t *event_data = fw_event->event_data;
|
|
u64 sas_address;
|
|
u64 sas_address;
|
|
|
|
|
|
|
|
+ if (ioc->shost_recovery)
|
|
|
|
+ return;
|
|
|
|
+
|
|
if (event_data->ReasonCode != MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED)
|
|
if (event_data->ReasonCode != MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED)
|
|
return;
|
|
return;
|
|
|
|
|
|
@@ -6510,10 +6556,10 @@ _scsih_search_responding_sas_devices(struct MPT2SAS_ADAPTER *ioc)
|
|
u32 device_info;
|
|
u32 device_info;
|
|
u16 slot;
|
|
u16 slot;
|
|
|
|
|
|
- printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, __func__);
|
|
|
|
|
|
+ printk(MPT2SAS_INFO_FMT "search for end-devices: start\n", ioc->name);
|
|
|
|
|
|
if (list_empty(&ioc->sas_device_list))
|
|
if (list_empty(&ioc->sas_device_list))
|
|
- return;
|
|
|
|
|
|
+ goto out;
|
|
|
|
|
|
handle = 0xFFFF;
|
|
handle = 0xFFFF;
|
|
while (!(mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply,
|
|
while (!(mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply,
|
|
@@ -6532,6 +6578,9 @@ _scsih_search_responding_sas_devices(struct MPT2SAS_ADAPTER *ioc)
|
|
_scsih_mark_responding_sas_device(ioc, sas_address, slot,
|
|
_scsih_mark_responding_sas_device(ioc, sas_address, slot,
|
|
handle);
|
|
handle);
|
|
}
|
|
}
|
|
|
|
+out:
|
|
|
|
+ printk(MPT2SAS_INFO_FMT "search for end-devices: complete\n",
|
|
|
|
+ ioc->name);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -6607,10 +6656,14 @@ _scsih_search_responding_raid_devices(struct MPT2SAS_ADAPTER *ioc)
|
|
u16 handle;
|
|
u16 handle;
|
|
u8 phys_disk_num;
|
|
u8 phys_disk_num;
|
|
|
|
|
|
- printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, __func__);
|
|
|
|
|
|
+ if (!ioc->ir_firmware)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ printk(MPT2SAS_INFO_FMT "search for raid volumes: start\n",
|
|
|
|
+ ioc->name);
|
|
|
|
|
|
if (list_empty(&ioc->raid_device_list))
|
|
if (list_empty(&ioc->raid_device_list))
|
|
- return;
|
|
|
|
|
|
+ goto out;
|
|
|
|
|
|
handle = 0xFFFF;
|
|
handle = 0xFFFF;
|
|
while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
|
|
while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
|
|
@@ -6649,6 +6702,9 @@ _scsih_search_responding_raid_devices(struct MPT2SAS_ADAPTER *ioc)
|
|
set_bit(handle, ioc->pd_handles);
|
|
set_bit(handle, ioc->pd_handles);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+out:
|
|
|
|
+ printk(MPT2SAS_INFO_FMT "search for responding raid volumes: "
|
|
|
|
+ "complete\n", ioc->name);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -6708,10 +6764,10 @@ _scsih_search_responding_expanders(struct MPT2SAS_ADAPTER *ioc)
|
|
u64 sas_address;
|
|
u64 sas_address;
|
|
u16 handle;
|
|
u16 handle;
|
|
|
|
|
|
- printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, __func__);
|
|
|
|
|
|
+ printk(MPT2SAS_INFO_FMT "search for expanders: start\n", ioc->name);
|
|
|
|
|
|
if (list_empty(&ioc->sas_expander_list))
|
|
if (list_empty(&ioc->sas_expander_list))
|
|
- return;
|
|
|
|
|
|
+ goto out;
|
|
|
|
|
|
handle = 0xFFFF;
|
|
handle = 0xFFFF;
|
|
while (!(mpt2sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0,
|
|
while (!(mpt2sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0,
|
|
@@ -6730,6 +6786,8 @@ _scsih_search_responding_expanders(struct MPT2SAS_ADAPTER *ioc)
|
|
_scsih_mark_responding_expander(ioc, sas_address, handle);
|
|
_scsih_mark_responding_expander(ioc, sas_address, handle);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ out:
|
|
|
|
+ printk(MPT2SAS_INFO_FMT "search for expanders: complete\n", ioc->name);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -6745,6 +6803,8 @@ _scsih_remove_unresponding_sas_devices(struct MPT2SAS_ADAPTER *ioc)
|
|
struct _sas_node *sas_expander;
|
|
struct _sas_node *sas_expander;
|
|
struct _raid_device *raid_device, *raid_device_next;
|
|
struct _raid_device *raid_device, *raid_device_next;
|
|
|
|
|
|
|
|
+ printk(MPT2SAS_INFO_FMT "removing unresponding devices: start\n",
|
|
|
|
+ ioc->name);
|
|
|
|
|
|
list_for_each_entry_safe(sas_device, sas_device_next,
|
|
list_for_each_entry_safe(sas_device, sas_device_next,
|
|
&ioc->sas_device_list, list) {
|
|
&ioc->sas_device_list, list) {
|
|
@@ -6764,6 +6824,9 @@ _scsih_remove_unresponding_sas_devices(struct MPT2SAS_ADAPTER *ioc)
|
|
_scsih_remove_device(ioc, sas_device);
|
|
_scsih_remove_device(ioc, sas_device);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (!ioc->ir_firmware)
|
|
|
|
+ goto retry_expander_search;
|
|
|
|
+
|
|
list_for_each_entry_safe(raid_device, raid_device_next,
|
|
list_for_each_entry_safe(raid_device, raid_device_next,
|
|
&ioc->raid_device_list, list) {
|
|
&ioc->raid_device_list, list) {
|
|
if (raid_device->responding) {
|
|
if (raid_device->responding) {
|
|
@@ -6790,52 +6853,170 @@ _scsih_remove_unresponding_sas_devices(struct MPT2SAS_ADAPTER *ioc)
|
|
mpt2sas_expander_remove(ioc, sas_expander->sas_address);
|
|
mpt2sas_expander_remove(ioc, sas_expander->sas_address);
|
|
goto retry_expander_search;
|
|
goto retry_expander_search;
|
|
}
|
|
}
|
|
|
|
+ printk(MPT2SAS_INFO_FMT "removing unresponding devices: complete\n",
|
|
|
|
+ ioc->name);
|
|
|
|
+ /* unblock devices */
|
|
|
|
+ _scsih_ublock_io_all_device(ioc);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void
|
|
|
|
+_scsih_refresh_expander_links(struct MPT2SAS_ADAPTER *ioc,
|
|
|
|
+ struct _sas_node *sas_expander, u16 handle)
|
|
|
|
+{
|
|
|
|
+ Mpi2ExpanderPage1_t expander_pg1;
|
|
|
|
+ Mpi2ConfigReply_t mpi_reply;
|
|
|
|
+ int i;
|
|
|
|
+
|
|
|
|
+ for (i = 0 ; i < sas_expander->num_phys ; i++) {
|
|
|
|
+ if ((mpt2sas_config_get_expander_pg1(ioc, &mpi_reply,
|
|
|
|
+ &expander_pg1, i, handle))) {
|
|
|
|
+ printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
|
|
|
|
+ ioc->name, __FILE__, __LINE__, __func__);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ mpt2sas_transport_update_links(ioc, sas_expander->sas_address,
|
|
|
|
+ le16_to_cpu(expander_pg1.AttachedDevHandle), i,
|
|
|
|
+ expander_pg1.NegotiatedLinkRate >> 4);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * _scsih_hide_unhide_sas_devices - add/remove device to/from OS
|
|
|
|
|
|
+ * _scsih_scan_for_devices_after_reset - scan for devices after host reset
|
|
* @ioc: per adapter object
|
|
* @ioc: per adapter object
|
|
*
|
|
*
|
|
* Return nothing.
|
|
* Return nothing.
|
|
*/
|
|
*/
|
|
static void
|
|
static void
|
|
-_scsih_hide_unhide_sas_devices(struct MPT2SAS_ADAPTER *ioc)
|
|
|
|
|
|
+_scsih_scan_for_devices_after_reset(struct MPT2SAS_ADAPTER *ioc)
|
|
{
|
|
{
|
|
- struct _sas_device *sas_device, *sas_device_next;
|
|
|
|
|
|
+ Mpi2ExpanderPage0_t expander_pg0;
|
|
|
|
+ Mpi2SasDevicePage0_t sas_device_pg0;
|
|
|
|
+ Mpi2RaidVolPage1_t volume_pg1;
|
|
|
|
+ Mpi2RaidVolPage0_t volume_pg0;
|
|
|
|
+ Mpi2RaidPhysDiskPage0_t pd_pg0;
|
|
|
|
+ Mpi2EventIrConfigElement_t element;
|
|
|
|
+ Mpi2ConfigReply_t mpi_reply;
|
|
|
|
+ u8 phys_disk_num;
|
|
|
|
+ u16 ioc_status;
|
|
|
|
+ u16 handle, parent_handle;
|
|
|
|
+ u64 sas_address;
|
|
|
|
+ struct _sas_device *sas_device;
|
|
|
|
+ struct _sas_node *expander_device;
|
|
|
|
+ static struct _raid_device *raid_device;
|
|
|
|
|
|
- if (!ioc->is_warpdrive || ioc->mfg_pg10_hide_flag !=
|
|
|
|
- MFG_PAGE10_HIDE_IF_VOL_PRESENT)
|
|
|
|
- return;
|
|
|
|
|
|
+ printk(MPT2SAS_INFO_FMT "scan devices: start\n", ioc->name);
|
|
|
|
|
|
- if (ioc->hide_drives) {
|
|
|
|
- if (_scsih_get_num_volumes(ioc))
|
|
|
|
- return;
|
|
|
|
- ioc->hide_drives = 0;
|
|
|
|
- list_for_each_entry_safe(sas_device, sas_device_next,
|
|
|
|
- &ioc->sas_device_list, list) {
|
|
|
|
- if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
|
|
|
|
- sas_device->sas_address_parent)) {
|
|
|
|
- _scsih_sas_device_remove(ioc, sas_device);
|
|
|
|
- } else if (!sas_device->starget) {
|
|
|
|
- mpt2sas_transport_port_remove(ioc,
|
|
|
|
- sas_device->sas_address,
|
|
|
|
- sas_device->sas_address_parent);
|
|
|
|
- _scsih_sas_device_remove(ioc, sas_device);
|
|
|
|
- }
|
|
|
|
|
|
+ _scsih_sas_host_refresh(ioc);
|
|
|
|
+
|
|
|
|
+ /* expanders */
|
|
|
|
+ handle = 0xFFFF;
|
|
|
|
+ while (!(mpt2sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0,
|
|
|
|
+ MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL, handle))) {
|
|
|
|
+ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
|
|
|
|
+ MPI2_IOCSTATUS_MASK;
|
|
|
|
+ if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
|
|
|
|
+ break;
|
|
|
|
+ handle = le16_to_cpu(expander_pg0.DevHandle);
|
|
|
|
+ expander_device = mpt2sas_scsih_expander_find_by_sas_address(
|
|
|
|
+ ioc, le64_to_cpu(expander_pg0.SASAddress));
|
|
|
|
+ if (expander_device)
|
|
|
|
+ _scsih_refresh_expander_links(ioc, expander_device,
|
|
|
|
+ handle);
|
|
|
|
+ else
|
|
|
|
+ _scsih_expander_add(ioc, handle);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!ioc->ir_firmware)
|
|
|
|
+ goto skip_to_sas;
|
|
|
|
+
|
|
|
|
+ /* phys disk */
|
|
|
|
+ phys_disk_num = 0xFF;
|
|
|
|
+ while (!(mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply,
|
|
|
|
+ &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_GET_NEXT_PHYSDISKNUM,
|
|
|
|
+ phys_disk_num))) {
|
|
|
|
+ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
|
|
|
|
+ MPI2_IOCSTATUS_MASK;
|
|
|
|
+ if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
|
|
|
|
+ break;
|
|
|
|
+ phys_disk_num = pd_pg0.PhysDiskNum;
|
|
|
|
+ handle = le16_to_cpu(pd_pg0.DevHandle);
|
|
|
|
+ sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
|
|
|
|
+ if (sas_device)
|
|
|
|
+ continue;
|
|
|
|
+ if (mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply,
|
|
|
|
+ &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE,
|
|
|
|
+ handle) != 0)
|
|
|
|
+ continue;
|
|
|
|
+ parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle);
|
|
|
|
+ if (!_scsih_get_sas_address(ioc, parent_handle,
|
|
|
|
+ &sas_address)) {
|
|
|
|
+ mpt2sas_transport_update_links(ioc, sas_address,
|
|
|
|
+ handle, sas_device_pg0.PhyNum,
|
|
|
|
+ MPI2_SAS_NEG_LINK_RATE_1_5);
|
|
|
|
+ set_bit(handle, ioc->pd_handles);
|
|
|
|
+ _scsih_add_device(ioc, handle, 0, 1);
|
|
}
|
|
}
|
|
- } else {
|
|
|
|
- if (!_scsih_get_num_volumes(ioc))
|
|
|
|
- return;
|
|
|
|
- ioc->hide_drives = 1;
|
|
|
|
- list_for_each_entry_safe(sas_device, sas_device_next,
|
|
|
|
- &ioc->sas_device_list, list) {
|
|
|
|
- mpt2sas_transport_port_remove(ioc,
|
|
|
|
- sas_device->sas_address,
|
|
|
|
- sas_device->sas_address_parent);
|
|
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* volumes */
|
|
|
|
+ handle = 0xFFFF;
|
|
|
|
+ while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
|
|
|
|
+ &volume_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
|
|
|
|
+ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
|
|
|
|
+ MPI2_IOCSTATUS_MASK;
|
|
|
|
+ if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
|
|
|
|
+ break;
|
|
|
|
+ handle = le16_to_cpu(volume_pg1.DevHandle);
|
|
|
|
+ raid_device = _scsih_raid_device_find_by_wwid(ioc,
|
|
|
|
+ le64_to_cpu(volume_pg1.WWID));
|
|
|
|
+ if (raid_device)
|
|
|
|
+ continue;
|
|
|
|
+ if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply,
|
|
|
|
+ &volume_pg0, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, handle,
|
|
|
|
+ sizeof(Mpi2RaidVolPage0_t)))
|
|
|
|
+ continue;
|
|
|
|
+ if (volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_OPTIMAL ||
|
|
|
|
+ volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_ONLINE ||
|
|
|
|
+ volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_DEGRADED) {
|
|
|
|
+ memset(&element, 0, sizeof(Mpi2EventIrConfigElement_t));
|
|
|
|
+ element.ReasonCode = MPI2_EVENT_IR_CHANGE_RC_ADDED;
|
|
|
|
+ element.VolDevHandle = volume_pg1.DevHandle;
|
|
|
|
+ _scsih_sas_volume_add(ioc, &element);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ skip_to_sas:
|
|
|
|
+
|
|
|
|
+ /* sas devices */
|
|
|
|
+ handle = 0xFFFF;
|
|
|
|
+ while (!(mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply,
|
|
|
|
+ &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE,
|
|
|
|
+ handle))) {
|
|
|
|
+ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
|
|
|
|
+ MPI2_IOCSTATUS_MASK;
|
|
|
|
+ if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
|
|
|
|
+ break;
|
|
|
|
+ handle = le16_to_cpu(sas_device_pg0.DevHandle);
|
|
|
|
+ if (!(_scsih_is_end_device(
|
|
|
|
+ le32_to_cpu(sas_device_pg0.DeviceInfo))))
|
|
|
|
+ continue;
|
|
|
|
+ sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
|
|
|
|
+ le64_to_cpu(sas_device_pg0.SASAddress));
|
|
|
|
+ if (sas_device)
|
|
|
|
+ continue;
|
|
|
|
+ parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle);
|
|
|
|
+ if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address)) {
|
|
|
|
+ mpt2sas_transport_update_links(ioc, sas_address, handle,
|
|
|
|
+ sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5);
|
|
|
|
+ _scsih_add_device(ioc, handle, 0, 0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ printk(MPT2SAS_INFO_FMT "scan devices: complete\n", ioc->name);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* mpt2sas_scsih_reset_handler - reset callback handler (for scsih)
|
|
* mpt2sas_scsih_reset_handler - reset callback handler (for scsih)
|
|
* @ioc: per adapter object
|
|
* @ioc: per adapter object
|
|
@@ -6871,7 +7052,6 @@ mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
|
|
}
|
|
}
|
|
_scsih_fw_event_cleanup_queue(ioc);
|
|
_scsih_fw_event_cleanup_queue(ioc);
|
|
_scsih_flush_running_cmds(ioc);
|
|
_scsih_flush_running_cmds(ioc);
|
|
- _scsih_queue_rescan(ioc);
|
|
|
|
break;
|
|
break;
|
|
case MPT2_IOC_DONE_RESET:
|
|
case MPT2_IOC_DONE_RESET:
|
|
dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
|
|
dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
|
|
@@ -6881,6 +7061,7 @@ mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
|
|
_scsih_search_responding_sas_devices(ioc);
|
|
_scsih_search_responding_sas_devices(ioc);
|
|
_scsih_search_responding_raid_devices(ioc);
|
|
_scsih_search_responding_raid_devices(ioc);
|
|
_scsih_search_responding_expanders(ioc);
|
|
_scsih_search_responding_expanders(ioc);
|
|
|
|
+ _scsih_error_recovery_delete_devices(ioc);
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -6898,7 +7079,6 @@ _firmware_event_work(struct work_struct *work)
|
|
{
|
|
{
|
|
struct fw_event_work *fw_event = container_of(work,
|
|
struct fw_event_work *fw_event = container_of(work,
|
|
struct fw_event_work, delayed_work.work);
|
|
struct fw_event_work, delayed_work.work);
|
|
- unsigned long flags;
|
|
|
|
struct MPT2SAS_ADAPTER *ioc = fw_event->ioc;
|
|
struct MPT2SAS_ADAPTER *ioc = fw_event->ioc;
|
|
|
|
|
|
/* the queue is being flushed so ignore this event */
|
|
/* the queue is being flushed so ignore this event */
|
|
@@ -6908,23 +7088,31 @@ _firmware_event_work(struct work_struct *work)
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- if (fw_event->event == MPT2SAS_RESCAN_AFTER_HOST_RESET) {
|
|
|
|
- _scsih_fw_event_free(ioc, fw_event);
|
|
|
|
- spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
|
|
|
|
- if (ioc->shost_recovery) {
|
|
|
|
- init_completion(&ioc->shost_recovery_done);
|
|
|
|
- spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock,
|
|
|
|
- flags);
|
|
|
|
- wait_for_completion(&ioc->shost_recovery_done);
|
|
|
|
- } else
|
|
|
|
- spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock,
|
|
|
|
- flags);
|
|
|
|
|
|
+ switch (fw_event->event) {
|
|
|
|
+ case MPT2SAS_REMOVE_UNRESPONDING_DEVICES:
|
|
|
|
+ while (scsi_host_in_recovery(ioc->shost))
|
|
|
|
+ ssleep(1);
|
|
_scsih_remove_unresponding_sas_devices(ioc);
|
|
_scsih_remove_unresponding_sas_devices(ioc);
|
|
- _scsih_hide_unhide_sas_devices(ioc);
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
|
|
+ _scsih_scan_for_devices_after_reset(ioc);
|
|
|
|
+ break;
|
|
|
|
+ case MPT2SAS_PORT_ENABLE_COMPLETE:
|
|
|
|
+ if (!ioc->is_driver_loading && ioc->shost_recovery) {
|
|
|
|
+ _scsih_prep_device_scan(ioc);
|
|
|
|
+ _scsih_search_responding_sas_devices(ioc);
|
|
|
|
+ _scsih_search_responding_raid_devices(ioc);
|
|
|
|
+ _scsih_search_responding_expanders(ioc);
|
|
|
|
+ }
|
|
|
|
|
|
- switch (fw_event->event) {
|
|
|
|
|
|
+ if (ioc->start_scan)
|
|
|
|
+ ioc->start_scan = 0;
|
|
|
|
+ else
|
|
|
|
+ complete(&ioc->port_enable_done);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "port enable: complete "
|
|
|
|
+ "from worker thread\n", ioc->name));
|
|
|
|
+ break;
|
|
case MPT2SAS_TURN_ON_FAULT_LED:
|
|
case MPT2SAS_TURN_ON_FAULT_LED:
|
|
_scsih_turn_on_fault_led(ioc, fw_event->device_handle);
|
|
_scsih_turn_on_fault_led(ioc, fw_event->device_handle);
|
|
break;
|
|
break;
|
|
@@ -7121,6 +7309,8 @@ static struct scsi_host_template scsih_driver_template = {
|
|
.slave_configure = _scsih_slave_configure,
|
|
.slave_configure = _scsih_slave_configure,
|
|
.target_destroy = _scsih_target_destroy,
|
|
.target_destroy = _scsih_target_destroy,
|
|
.slave_destroy = _scsih_slave_destroy,
|
|
.slave_destroy = _scsih_slave_destroy,
|
|
|
|
+ .scan_finished = _scsih_scan_finished,
|
|
|
|
+ .scan_start = _scsih_scan_start,
|
|
.change_queue_depth = _scsih_change_queue_depth,
|
|
.change_queue_depth = _scsih_change_queue_depth,
|
|
.change_queue_type = _scsih_change_queue_type,
|
|
.change_queue_type = _scsih_change_queue_type,
|
|
.eh_abort_handler = _scsih_abort,
|
|
.eh_abort_handler = _scsih_abort,
|
|
@@ -7381,7 +7571,12 @@ _scsih_probe_boot_devices(struct MPT2SAS_ADAPTER *ioc)
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
int rc;
|
|
int rc;
|
|
|
|
|
|
|
|
+ /* no Bios, return immediately */
|
|
|
|
+ if (!ioc->bios_pg3.BiosVersion)
|
|
|
|
+ return;
|
|
|
|
+
|
|
device = NULL;
|
|
device = NULL;
|
|
|
|
+ is_raid = 0;
|
|
if (ioc->req_boot_device.device) {
|
|
if (ioc->req_boot_device.device) {
|
|
device = ioc->req_boot_device.device;
|
|
device = ioc->req_boot_device.device;
|
|
is_raid = ioc->req_boot_device.is_raid;
|
|
is_raid = ioc->req_boot_device.is_raid;
|
|
@@ -7490,9 +7685,7 @@ _scsih_probe_sas(struct MPT2SAS_ADAPTER *ioc)
|
|
static void
|
|
static void
|
|
_scsih_probe_devices(struct MPT2SAS_ADAPTER *ioc)
|
|
_scsih_probe_devices(struct MPT2SAS_ADAPTER *ioc)
|
|
{
|
|
{
|
|
- u16 volume_mapping_flags =
|
|
|
|
- le16_to_cpu(ioc->ioc_pg8.IRVolumeMappingFlags) &
|
|
|
|
- MPI2_IOCPAGE8_IRFLAGS_MASK_VOLUME_MAPPING_MODE;
|
|
|
|
|
|
+ u16 volume_mapping_flags;
|
|
|
|
|
|
if (!(ioc->facts.ProtocolFlags & MPI2_IOCFACTS_PROTOCOL_SCSI_INITIATOR))
|
|
if (!(ioc->facts.ProtocolFlags & MPI2_IOCFACTS_PROTOCOL_SCSI_INITIATOR))
|
|
return; /* return when IOC doesn't support initiator mode */
|
|
return; /* return when IOC doesn't support initiator mode */
|
|
@@ -7500,18 +7693,93 @@ _scsih_probe_devices(struct MPT2SAS_ADAPTER *ioc)
|
|
_scsih_probe_boot_devices(ioc);
|
|
_scsih_probe_boot_devices(ioc);
|
|
|
|
|
|
if (ioc->ir_firmware) {
|
|
if (ioc->ir_firmware) {
|
|
- if ((volume_mapping_flags &
|
|
|
|
- MPI2_IOCPAGE8_IRFLAGS_HIGH_VOLUME_MAPPING)) {
|
|
|
|
- _scsih_probe_sas(ioc);
|
|
|
|
|
|
+ volume_mapping_flags =
|
|
|
|
+ le16_to_cpu(ioc->ioc_pg8.IRVolumeMappingFlags) &
|
|
|
|
+ MPI2_IOCPAGE8_IRFLAGS_MASK_VOLUME_MAPPING_MODE;
|
|
|
|
+ if (volume_mapping_flags ==
|
|
|
|
+ MPI2_IOCPAGE8_IRFLAGS_LOW_VOLUME_MAPPING) {
|
|
_scsih_probe_raid(ioc);
|
|
_scsih_probe_raid(ioc);
|
|
|
|
+ _scsih_probe_sas(ioc);
|
|
} else {
|
|
} else {
|
|
- _scsih_probe_raid(ioc);
|
|
|
|
_scsih_probe_sas(ioc);
|
|
_scsih_probe_sas(ioc);
|
|
|
|
+ _scsih_probe_raid(ioc);
|
|
}
|
|
}
|
|
} else
|
|
} else
|
|
_scsih_probe_sas(ioc);
|
|
_scsih_probe_sas(ioc);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * _scsih_scan_start - scsi lld callback for .scan_start
|
|
|
|
+ * @shost: SCSI host pointer
|
|
|
|
+ *
|
|
|
|
+ * The shost has the ability to discover targets on its own instead
|
|
|
|
+ * of scanning the entire bus. In our implemention, we will kick off
|
|
|
|
+ * firmware discovery.
|
|
|
|
+ */
|
|
|
|
+static void
|
|
|
|
+_scsih_scan_start(struct Scsi_Host *shost)
|
|
|
|
+{
|
|
|
|
+ struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
|
|
|
|
+ int rc;
|
|
|
|
+
|
|
|
|
+ if (diag_buffer_enable != -1 && diag_buffer_enable != 0)
|
|
|
|
+ mpt2sas_enable_diag_buffer(ioc, diag_buffer_enable);
|
|
|
|
+
|
|
|
|
+ ioc->start_scan = 1;
|
|
|
|
+ rc = mpt2sas_port_enable(ioc);
|
|
|
|
+
|
|
|
|
+ if (rc != 0)
|
|
|
|
+ printk(MPT2SAS_INFO_FMT "port enable: FAILED\n", ioc->name);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * _scsih_scan_finished - scsi lld callback for .scan_finished
|
|
|
|
+ * @shost: SCSI host pointer
|
|
|
|
+ * @time: elapsed time of the scan in jiffies
|
|
|
|
+ *
|
|
|
|
+ * This function will be called periodically until it returns 1 with the
|
|
|
|
+ * scsi_host and the elapsed time of the scan in jiffies. In our implemention,
|
|
|
|
+ * we wait for firmware discovery to complete, then return 1.
|
|
|
|
+ */
|
|
|
|
+static int
|
|
|
|
+_scsih_scan_finished(struct Scsi_Host *shost, unsigned long time)
|
|
|
|
+{
|
|
|
|
+ struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
|
|
|
|
+
|
|
|
|
+ if (time >= (300 * HZ)) {
|
|
|
|
+ ioc->base_cmds.status = MPT2_CMD_NOT_USED;
|
|
|
|
+ printk(MPT2SAS_INFO_FMT "port enable: FAILED with timeout "
|
|
|
|
+ "(timeout=300s)\n", ioc->name);
|
|
|
|
+ ioc->is_driver_loading = 0;
|
|
|
|
+ return 1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (ioc->start_scan)
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ if (ioc->start_scan_failed) {
|
|
|
|
+ printk(MPT2SAS_INFO_FMT "port enable: FAILED with "
|
|
|
|
+ "(ioc_status=0x%08x)\n", ioc->name, ioc->start_scan_failed);
|
|
|
|
+ ioc->is_driver_loading = 0;
|
|
|
|
+ ioc->wait_for_discovery_to_complete = 0;
|
|
|
|
+ ioc->remove_host = 1;
|
|
|
|
+ return 1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ printk(MPT2SAS_INFO_FMT "port enable: SUCCESS\n", ioc->name);
|
|
|
|
+ ioc->base_cmds.status = MPT2_CMD_NOT_USED;
|
|
|
|
+
|
|
|
|
+ if (ioc->wait_for_discovery_to_complete) {
|
|
|
|
+ ioc->wait_for_discovery_to_complete = 0;
|
|
|
|
+ _scsih_probe_devices(ioc);
|
|
|
|
+ }
|
|
|
|
+ mpt2sas_base_start_watchdog(ioc);
|
|
|
|
+ ioc->is_driver_loading = 0;
|
|
|
|
+ return 1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* _scsih_probe - attach and add scsi host
|
|
* _scsih_probe - attach and add scsi host
|
|
* @pdev: PCI device struct
|
|
* @pdev: PCI device struct
|
|
@@ -7548,6 +7816,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|
ioc->tm_cb_idx = tm_cb_idx;
|
|
ioc->tm_cb_idx = tm_cb_idx;
|
|
ioc->ctl_cb_idx = ctl_cb_idx;
|
|
ioc->ctl_cb_idx = ctl_cb_idx;
|
|
ioc->base_cb_idx = base_cb_idx;
|
|
ioc->base_cb_idx = base_cb_idx;
|
|
|
|
+ ioc->port_enable_cb_idx = port_enable_cb_idx;
|
|
ioc->transport_cb_idx = transport_cb_idx;
|
|
ioc->transport_cb_idx = transport_cb_idx;
|
|
ioc->scsih_cb_idx = scsih_cb_idx;
|
|
ioc->scsih_cb_idx = scsih_cb_idx;
|
|
ioc->config_cb_idx = config_cb_idx;
|
|
ioc->config_cb_idx = config_cb_idx;
|
|
@@ -7620,14 +7889,14 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|
goto out_thread_fail;
|
|
goto out_thread_fail;
|
|
}
|
|
}
|
|
|
|
|
|
- ioc->wait_for_port_enable_to_complete = 1;
|
|
|
|
|
|
+ ioc->is_driver_loading = 1;
|
|
if ((mpt2sas_base_attach(ioc))) {
|
|
if ((mpt2sas_base_attach(ioc))) {
|
|
printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
|
|
printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
|
|
ioc->name, __FILE__, __LINE__, __func__);
|
|
ioc->name, __FILE__, __LINE__, __func__);
|
|
goto out_attach_fail;
|
|
goto out_attach_fail;
|
|
}
|
|
}
|
|
|
|
|
|
- ioc->wait_for_port_enable_to_complete = 0;
|
|
|
|
|
|
+ scsi_scan_host(shost);
|
|
if (ioc->is_warpdrive) {
|
|
if (ioc->is_warpdrive) {
|
|
if (ioc->mfg_pg10_hide_flag == MFG_PAGE10_EXPOSE_ALL_DISKS)
|
|
if (ioc->mfg_pg10_hide_flag == MFG_PAGE10_EXPOSE_ALL_DISKS)
|
|
ioc->hide_drives = 0;
|
|
ioc->hide_drives = 0;
|
|
@@ -7650,6 +7919,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|
out_thread_fail:
|
|
out_thread_fail:
|
|
list_del(&ioc->list);
|
|
list_del(&ioc->list);
|
|
scsi_remove_host(shost);
|
|
scsi_remove_host(shost);
|
|
|
|
+ scsi_host_put(shost);
|
|
out_add_shost_fail:
|
|
out_add_shost_fail:
|
|
return -ENODEV;
|
|
return -ENODEV;
|
|
}
|
|
}
|
|
@@ -7896,6 +8166,8 @@ _scsih_init(void)
|
|
|
|
|
|
/* base internal commands callback handler */
|
|
/* base internal commands callback handler */
|
|
base_cb_idx = mpt2sas_base_register_callback_handler(mpt2sas_base_done);
|
|
base_cb_idx = mpt2sas_base_register_callback_handler(mpt2sas_base_done);
|
|
|
|
+ port_enable_cb_idx = mpt2sas_base_register_callback_handler(
|
|
|
|
+ mpt2sas_port_enable_done);
|
|
|
|
|
|
/* transport internal commands callback handler */
|
|
/* transport internal commands callback handler */
|
|
transport_cb_idx = mpt2sas_base_register_callback_handler(
|
|
transport_cb_idx = mpt2sas_base_register_callback_handler(
|
|
@@ -7950,6 +8222,7 @@ _scsih_exit(void)
|
|
mpt2sas_base_release_callback_handler(scsi_io_cb_idx);
|
|
mpt2sas_base_release_callback_handler(scsi_io_cb_idx);
|
|
mpt2sas_base_release_callback_handler(tm_cb_idx);
|
|
mpt2sas_base_release_callback_handler(tm_cb_idx);
|
|
mpt2sas_base_release_callback_handler(base_cb_idx);
|
|
mpt2sas_base_release_callback_handler(base_cb_idx);
|
|
|
|
+ mpt2sas_base_release_callback_handler(port_enable_cb_idx);
|
|
mpt2sas_base_release_callback_handler(transport_cb_idx);
|
|
mpt2sas_base_release_callback_handler(transport_cb_idx);
|
|
mpt2sas_base_release_callback_handler(scsih_cb_idx);
|
|
mpt2sas_base_release_callback_handler(scsih_cb_idx);
|
|
mpt2sas_base_release_callback_handler(config_cb_idx);
|
|
mpt2sas_base_release_callback_handler(config_cb_idx);
|