Commit e3054ea7 authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6:
  [SCSI] mpt2sas: fix config request and diag reset deadlock
  [SCSI] mpt2sas: Bump driver version 01.100.04.00
  [SCSI] mpt2sas: fix oops because drv data points to NULL on resume from hibernate
  [SCSI] mpt2sas: fix crash due to Watchdog is active while OS in standby mode
  [SCSI] mpt2sas: fix infinite loop inside config request
  [SCSI] mpt2sas: Excessive log info causes sas iounit page time out
  [SCSI] mpt2sas: Raid 10 Value is showing as Raid 1E in /va/log/messages
  [SCSI] mpt2sas: Expander fix oops saying "Already part of another port"
  [SCSI] mpt2sas: Introduced check for enclosure_handle to avoid crash
parents 422bef87 388ce4be
...@@ -119,6 +119,64 @@ _base_fault_reset_work(struct work_struct *work) ...@@ -119,6 +119,64 @@ _base_fault_reset_work(struct work_struct *work)
spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
} }
/**
* mpt2sas_base_start_watchdog - start the fault_reset_work_q
* @ioc: pointer to scsi command object
* Context: sleep.
*
* Return nothing.
*/
void
mpt2sas_base_start_watchdog(struct MPT2SAS_ADAPTER *ioc)
{
unsigned long flags;
if (ioc->fault_reset_work_q)
return;
/* initialize fault polling */
INIT_DELAYED_WORK(&ioc->fault_reset_work, _base_fault_reset_work);
snprintf(ioc->fault_reset_work_q_name,
sizeof(ioc->fault_reset_work_q_name), "poll_%d_status", ioc->id);
ioc->fault_reset_work_q =
create_singlethread_workqueue(ioc->fault_reset_work_q_name);
if (!ioc->fault_reset_work_q) {
printk(MPT2SAS_ERR_FMT "%s: failed (line=%d)\n",
ioc->name, __func__, __LINE__);
return;
}
spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
if (ioc->fault_reset_work_q)
queue_delayed_work(ioc->fault_reset_work_q,
&ioc->fault_reset_work,
msecs_to_jiffies(FAULT_POLLING_INTERVAL));
spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
}
/**
* mpt2sas_base_stop_watchdog - stop the fault_reset_work_q
* @ioc: pointer to scsi command object
* Context: sleep.
*
* Return nothing.
*/
void
mpt2sas_base_stop_watchdog(struct MPT2SAS_ADAPTER *ioc)
{
unsigned long flags;
struct workqueue_struct *wq;
spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
wq = ioc->fault_reset_work_q;
ioc->fault_reset_work_q = NULL;
spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
if (wq) {
if (!cancel_delayed_work(&ioc->fault_reset_work))
flush_workqueue(wq);
destroy_workqueue(wq);
}
}
#ifdef CONFIG_SCSI_MPT2SAS_LOGGING #ifdef CONFIG_SCSI_MPT2SAS_LOGGING
/** /**
* _base_sas_ioc_info - verbose translation of the ioc status * _base_sas_ioc_info - verbose translation of the ioc status
...@@ -440,6 +498,10 @@ _base_sas_log_info(struct MPT2SAS_ADAPTER *ioc , u32 log_info) ...@@ -440,6 +498,10 @@ _base_sas_log_info(struct MPT2SAS_ADAPTER *ioc , u32 log_info)
if (sas_loginfo.dw.bus_type != 3 /*SAS*/) if (sas_loginfo.dw.bus_type != 3 /*SAS*/)
return; return;
/* each nexus loss loginfo */
if (log_info == 0x31170000)
return;
/* eat the loginfos associated with task aborts */ /* eat the loginfos associated with task aborts */
if (ioc->ignore_loginfos && (log_info == 30050000 || log_info == if (ioc->ignore_loginfos && (log_info == 30050000 || log_info ==
0x31140000 || log_info == 0x31130000)) 0x31140000 || log_info == 0x31130000))
...@@ -1109,7 +1171,6 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc) ...@@ -1109,7 +1171,6 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc)
} }
} }
pci_set_drvdata(pdev, ioc->shost);
_base_mask_interrupts(ioc); _base_mask_interrupts(ioc);
r = _base_enable_msix(ioc); r = _base_enable_msix(ioc);
if (r) if (r)
...@@ -1132,7 +1193,6 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc) ...@@ -1132,7 +1193,6 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc)
ioc->pci_irq = -1; ioc->pci_irq = -1;
pci_release_selected_regions(ioc->pdev, ioc->bars); pci_release_selected_regions(ioc->pdev, ioc->bars);
pci_disable_device(pdev); pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
return r; return r;
} }
...@@ -3191,7 +3251,6 @@ mpt2sas_base_free_resources(struct MPT2SAS_ADAPTER *ioc) ...@@ -3191,7 +3251,6 @@ mpt2sas_base_free_resources(struct MPT2SAS_ADAPTER *ioc)
ioc->chip_phys = 0; ioc->chip_phys = 0;
pci_release_selected_regions(ioc->pdev, ioc->bars); pci_release_selected_regions(ioc->pdev, ioc->bars);
pci_disable_device(pdev); pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
return; return;
} }
...@@ -3205,7 +3264,6 @@ int ...@@ -3205,7 +3264,6 @@ int
mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
{ {
int r, i; int r, i;
unsigned long flags;
dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
__func__)); __func__));
...@@ -3214,6 +3272,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) ...@@ -3214,6 +3272,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
if (r) if (r)
return r; return r;
pci_set_drvdata(ioc->pdev, ioc->shost);
r = _base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET); r = _base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET);
if (r) if (r)
goto out_free_resources; goto out_free_resources;
...@@ -3288,23 +3347,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) ...@@ -3288,23 +3347,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
if (r) if (r)
goto out_free_resources; goto out_free_resources;
/* initialize fault polling */ mpt2sas_base_start_watchdog(ioc);
INIT_DELAYED_WORK(&ioc->fault_reset_work, _base_fault_reset_work);
snprintf(ioc->fault_reset_work_q_name,
sizeof(ioc->fault_reset_work_q_name), "poll_%d_status", ioc->id);
ioc->fault_reset_work_q =
create_singlethread_workqueue(ioc->fault_reset_work_q_name);
if (!ioc->fault_reset_work_q) {
printk(MPT2SAS_ERR_FMT "%s: failed (line=%d)\n",
ioc->name, __func__, __LINE__);
goto out_free_resources;
}
spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
if (ioc->fault_reset_work_q)
queue_delayed_work(ioc->fault_reset_work_q,
&ioc->fault_reset_work,
msecs_to_jiffies(FAULT_POLLING_INTERVAL));
spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
return 0; return 0;
out_free_resources: out_free_resources:
...@@ -3312,6 +3355,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) ...@@ -3312,6 +3355,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
ioc->remove_host = 1; ioc->remove_host = 1;
mpt2sas_base_free_resources(ioc); mpt2sas_base_free_resources(ioc);
_base_release_memory_pools(ioc); _base_release_memory_pools(ioc);
pci_set_drvdata(ioc->pdev, NULL);
kfree(ioc->tm_cmds.reply); kfree(ioc->tm_cmds.reply);
kfree(ioc->transport_cmds.reply); kfree(ioc->transport_cmds.reply);
kfree(ioc->config_cmds.reply); kfree(ioc->config_cmds.reply);
...@@ -3337,22 +3381,14 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) ...@@ -3337,22 +3381,14 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
void void
mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc) mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc)
{ {
unsigned long flags;
struct workqueue_struct *wq;
dexitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, dexitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
__func__)); __func__));
spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); mpt2sas_base_stop_watchdog(ioc);
wq = ioc->fault_reset_work_q;
ioc->fault_reset_work_q = NULL;
spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
if (!cancel_delayed_work(&ioc->fault_reset_work))
flush_workqueue(wq);
destroy_workqueue(wq);
mpt2sas_base_free_resources(ioc); mpt2sas_base_free_resources(ioc);
_base_release_memory_pools(ioc); _base_release_memory_pools(ioc);
pci_set_drvdata(ioc->pdev, NULL);
kfree(ioc->pfacts); kfree(ioc->pfacts);
kfree(ioc->ctl_cmds.reply); kfree(ioc->ctl_cmds.reply);
kfree(ioc->base_cmds.reply); kfree(ioc->base_cmds.reply);
......
...@@ -69,10 +69,10 @@ ...@@ -69,10 +69,10 @@
#define MPT2SAS_DRIVER_NAME "mpt2sas" #define MPT2SAS_DRIVER_NAME "mpt2sas"
#define MPT2SAS_AUTHOR "LSI Corporation <DL-MPTFusionLinux@lsi.com>" #define MPT2SAS_AUTHOR "LSI Corporation <DL-MPTFusionLinux@lsi.com>"
#define MPT2SAS_DESCRIPTION "LSI MPT Fusion SAS 2.0 Device Driver" #define MPT2SAS_DESCRIPTION "LSI MPT Fusion SAS 2.0 Device Driver"
#define MPT2SAS_DRIVER_VERSION "01.100.03.00" #define MPT2SAS_DRIVER_VERSION "01.100.04.00"
#define MPT2SAS_MAJOR_VERSION 01 #define MPT2SAS_MAJOR_VERSION 01
#define MPT2SAS_MINOR_VERSION 100 #define MPT2SAS_MINOR_VERSION 100
#define MPT2SAS_BUILD_VERSION 03 #define MPT2SAS_BUILD_VERSION 04
#define MPT2SAS_RELEASE_VERSION 00 #define MPT2SAS_RELEASE_VERSION 00
/* /*
...@@ -673,6 +673,8 @@ typedef void (*MPT_CALLBACK)(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, ...@@ -673,6 +673,8 @@ typedef void (*MPT_CALLBACK)(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID,
/* base shared API */ /* base shared API */
extern struct list_head mpt2sas_ioc_list; extern struct list_head mpt2sas_ioc_list;
void mpt2sas_base_start_watchdog(struct MPT2SAS_ADAPTER *ioc);
void mpt2sas_base_stop_watchdog(struct MPT2SAS_ADAPTER *ioc);
int mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc); int mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc);
void mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc); void mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc);
......
This diff is collapsed.
...@@ -2767,6 +2767,10 @@ _scsih_scsi_ioc_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, ...@@ -2767,6 +2767,10 @@ _scsih_scsi_ioc_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
char *desc_ioc_state = NULL; char *desc_ioc_state = NULL;
char *desc_scsi_status = NULL; char *desc_scsi_status = NULL;
char *desc_scsi_state = ioc->tmp_string; char *desc_scsi_state = ioc->tmp_string;
u32 log_info = le32_to_cpu(mpi_reply->IOCLogInfo);
if (log_info == 0x31170000)
return;
switch (ioc_status) { switch (ioc_status) {
case MPI2_IOCSTATUS_SUCCESS: case MPI2_IOCSTATUS_SUCCESS:
...@@ -3426,7 +3430,7 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle) ...@@ -3426,7 +3430,7 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle)
__le64 sas_address; __le64 sas_address;
int i; int i;
unsigned long flags; unsigned long flags;
struct _sas_port *mpt2sas_port; struct _sas_port *mpt2sas_port = NULL;
int rc = 0; int rc = 0;
if (!handle) if (!handle)
...@@ -3518,12 +3522,20 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle) ...@@ -3518,12 +3522,20 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle)
&expander_pg1, i, handle))) { &expander_pg1, i, handle))) {
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__);
continue; rc = -1;
goto out_fail;
} }
sas_expander->phy[i].handle = handle; sas_expander->phy[i].handle = handle;
sas_expander->phy[i].phy_id = i; sas_expander->phy[i].phy_id = i;
mpt2sas_transport_add_expander_phy(ioc, &sas_expander->phy[i],
expander_pg1, sas_expander->parent_dev); if ((mpt2sas_transport_add_expander_phy(ioc,
&sas_expander->phy[i], expander_pg1,
sas_expander->parent_dev))) {
printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
ioc->name, __FILE__, __LINE__, __func__);
rc = -1;
goto out_fail;
}
} }
if (sas_expander->enclosure_handle) { if (sas_expander->enclosure_handle) {
...@@ -3540,8 +3552,9 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle) ...@@ -3540,8 +3552,9 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle)
out_fail: out_fail:
if (sas_expander) if (mpt2sas_port)
kfree(sas_expander->phy); mpt2sas_transport_port_remove(ioc, sas_expander->sas_address,
sas_expander->parent_handle);
kfree(sas_expander); kfree(sas_expander);
return rc; return rc;
} }
...@@ -3663,12 +3676,11 @@ _scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd) ...@@ -3663,12 +3676,11 @@ _scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd)
sas_device->hidden_raid_component = is_pd; sas_device->hidden_raid_component = is_pd;
/* get enclosure_logical_id */ /* get enclosure_logical_id */
if (!(mpt2sas_config_get_enclosure_pg0(ioc, &mpi_reply, &enclosure_pg0, if (sas_device->enclosure_handle && !(mpt2sas_config_get_enclosure_pg0(
MPI2_SAS_ENCLOS_PGAD_FORM_HANDLE, ioc, &mpi_reply, &enclosure_pg0, MPI2_SAS_ENCLOS_PGAD_FORM_HANDLE,
sas_device->enclosure_handle))) { sas_device->enclosure_handle)))
sas_device->enclosure_logical_id = sas_device->enclosure_logical_id =
le64_to_cpu(enclosure_pg0.EnclosureLogicalID); le64_to_cpu(enclosure_pg0.EnclosureLogicalID);
}
/* 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);
...@@ -4250,12 +4262,6 @@ _scsih_sas_volume_add(struct MPT2SAS_ADAPTER *ioc, ...@@ -4250,12 +4262,6 @@ _scsih_sas_volume_add(struct MPT2SAS_ADAPTER *ioc,
u16 handle = le16_to_cpu(element->VolDevHandle); u16 handle = le16_to_cpu(element->VolDevHandle);
int rc; int rc;
#if 0 /* RAID_HACKS */
if (le32_to_cpu(event_data->Flags) &
MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG)
return;
#endif
mpt2sas_config_get_volume_wwid(ioc, handle, &wwid); mpt2sas_config_get_volume_wwid(ioc, handle, &wwid);
if (!wwid) { if (!wwid) {
printk(MPT2SAS_ERR_FMT printk(MPT2SAS_ERR_FMT
...@@ -4310,12 +4316,6 @@ _scsih_sas_volume_delete(struct MPT2SAS_ADAPTER *ioc, ...@@ -4310,12 +4316,6 @@ _scsih_sas_volume_delete(struct MPT2SAS_ADAPTER *ioc,
unsigned long flags; unsigned long flags;
struct MPT2SAS_TARGET *sas_target_priv_data; struct MPT2SAS_TARGET *sas_target_priv_data;
#if 0 /* RAID_HACKS */
if (le32_to_cpu(event_data->Flags) &
MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG)
return;
#endif
spin_lock_irqsave(&ioc->raid_device_lock, flags); spin_lock_irqsave(&ioc->raid_device_lock, flags);
raid_device = _scsih_raid_device_find_by_handle(ioc, handle); raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
spin_unlock_irqrestore(&ioc->raid_device_lock, flags); spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
...@@ -4428,13 +4428,37 @@ _scsih_sas_pd_add(struct MPT2SAS_ADAPTER *ioc, ...@@ -4428,13 +4428,37 @@ _scsih_sas_pd_add(struct MPT2SAS_ADAPTER *ioc,
struct _sas_device *sas_device; struct _sas_device *sas_device;
unsigned long flags; unsigned long flags;
u16 handle = le16_to_cpu(element->PhysDiskDevHandle); u16 handle = le16_to_cpu(element->PhysDiskDevHandle);
Mpi2ConfigReply_t mpi_reply;
Mpi2SasDevicePage0_t sas_device_pg0;
u32 ioc_status;
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);
spin_unlock_irqrestore(&ioc->sas_device_lock, flags); spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
if (sas_device) if (sas_device) {
sas_device->hidden_raid_component = 1; sas_device->hidden_raid_component = 1;
else return;
}
if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) {
printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
ioc->name, __FILE__, __LINE__, __func__);
return;
}
ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
MPI2_IOCSTATUS_MASK;
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
ioc->name, __FILE__, __LINE__, __func__);
return;
}
_scsih_link_change(ioc,
le16_to_cpu(sas_device_pg0.ParentDevHandle),
handle, sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5);
_scsih_add_device(ioc, handle, 0, 1); _scsih_add_device(ioc, handle, 0, 1);
} }
...@@ -4535,12 +4559,15 @@ _scsih_sas_ir_config_change_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, ...@@ -4535,12 +4559,15 @@ _scsih_sas_ir_config_change_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
{ {
Mpi2EventIrConfigElement_t *element; Mpi2EventIrConfigElement_t *element;
int i; int i;
u8 foreign_config;
#ifdef CONFIG_SCSI_MPT2SAS_LOGGING #ifdef CONFIG_SCSI_MPT2SAS_LOGGING
if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
_scsih_sas_ir_config_change_event_debug(ioc, event_data); _scsih_sas_ir_config_change_event_debug(ioc, event_data);
#endif #endif
foreign_config = (le32_to_cpu(event_data->Flags) &
MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) ? 1 : 0;
element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0]; element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0];
for (i = 0; i < event_data->NumElements; i++, element++) { for (i = 0; i < event_data->NumElements; i++, element++) {
...@@ -4548,10 +4575,12 @@ _scsih_sas_ir_config_change_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, ...@@ -4548,10 +4575,12 @@ _scsih_sas_ir_config_change_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
switch (element->ReasonCode) { switch (element->ReasonCode) {
case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED: case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED:
case MPI2_EVENT_IR_CHANGE_RC_ADDED: case MPI2_EVENT_IR_CHANGE_RC_ADDED:
if (!foreign_config)
_scsih_sas_volume_add(ioc, element); _scsih_sas_volume_add(ioc, element);
break; break;
case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED: case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED:
case MPI2_EVENT_IR_CHANGE_RC_REMOVED: case MPI2_EVENT_IR_CHANGE_RC_REMOVED:
if (!foreign_config)
_scsih_sas_volume_delete(ioc, element); _scsih_sas_volume_delete(ioc, element);
break; break;
case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED: case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED:
...@@ -4671,6 +4700,9 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, ...@@ -4671,6 +4700,9 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
u32 state; u32 state;
struct _sas_device *sas_device; struct _sas_device *sas_device;
unsigned long flags; unsigned long flags;
Mpi2ConfigReply_t mpi_reply;
Mpi2SasDevicePage0_t sas_device_pg0;
u32 ioc_status;
if (event_data->ReasonCode != MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED) if (event_data->ReasonCode != MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED)
return; return;
...@@ -4687,22 +4719,40 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, ...@@ -4687,22 +4719,40 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
spin_unlock_irqrestore(&ioc->sas_device_lock, flags); spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
switch (state) { switch (state) {
#if 0
case MPI2_RAID_PD_STATE_OFFLINE:
if (sas_device)
_scsih_remove_device(ioc, handle);
break;
#endif
case MPI2_RAID_PD_STATE_ONLINE: case MPI2_RAID_PD_STATE_ONLINE:
case MPI2_RAID_PD_STATE_DEGRADED: case MPI2_RAID_PD_STATE_DEGRADED:
case MPI2_RAID_PD_STATE_REBUILDING: case MPI2_RAID_PD_STATE_REBUILDING:
case MPI2_RAID_PD_STATE_OPTIMAL: case MPI2_RAID_PD_STATE_OPTIMAL:
if (sas_device) if (sas_device) {
sas_device->hidden_raid_component = 1; sas_device->hidden_raid_component = 1;
else return;
}
if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply,
&sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE,
handle))) {
printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
ioc->name, __FILE__, __LINE__, __func__);
return;
}
ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
MPI2_IOCSTATUS_MASK;
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
ioc->name, __FILE__, __LINE__, __func__);
return;
}
_scsih_link_change(ioc,
le16_to_cpu(sas_device_pg0.ParentDevHandle),
handle, sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5);
_scsih_add_device(ioc, handle, 0, 1); _scsih_add_device(ioc, handle, 0, 1);
break; break;
case MPI2_RAID_PD_STATE_OFFLINE:
case MPI2_RAID_PD_STATE_NOT_CONFIGURED: case MPI2_RAID_PD_STATE_NOT_CONFIGURED:
case MPI2_RAID_PD_STATE_NOT_COMPATIBLE: case MPI2_RAID_PD_STATE_NOT_COMPATIBLE:
case MPI2_RAID_PD_STATE_HOT_SPARE: case MPI2_RAID_PD_STATE_HOT_SPARE:
...@@ -5774,6 +5824,7 @@ _scsih_suspend(struct pci_dev *pdev, pm_message_t state) ...@@ -5774,6 +5824,7 @@ _scsih_suspend(struct pci_dev *pdev, pm_message_t state)
struct MPT2SAS_ADAPTER *ioc = shost_priv(shost); struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
u32 device_state; u32 device_state;
mpt2sas_base_stop_watchdog(ioc);
flush_scheduled_work(); flush_scheduled_work();
scsi_block_requests(shost); scsi_block_requests(shost);
device_state = pci_choose_state(pdev, state); device_state = pci_choose_state(pdev, state);
...@@ -5816,6 +5867,7 @@ _scsih_resume(struct pci_dev *pdev) ...@@ -5816,6 +5867,7 @@ _scsih_resume(struct pci_dev *pdev)
mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, SOFT_RESET); mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, SOFT_RESET);
scsi_unblock_requests(shost); scsi_unblock_requests(shost);
mpt2sas_base_start_watchdog(ioc);
return 0; return 0;
} }
#endif /* CONFIG_PM */ #endif /* CONFIG_PM */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment