diff options
author | nagalakshmi.nandigama@lsi.com <nagalakshmi.nandigama@lsi.com> | 2011-10-21 00:38:07 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2011-10-30 04:56:55 -0400 |
commit | 35116db95c42937061bfca93998291f6562e9e92 (patch) | |
tree | ca1c8d23186c78d8796c8786d8d566c7fc845f64 /drivers/scsi/mpt2sas/mpt2sas_scsih.c | |
parent | 6faace2a0e418b45728bcea6d3626922cf16b14b (diff) |
[SCSI] mpt2sas: Fix for Panic when inactive volume is tried deleting
The driver was setting the action to MPI2_CONFIG_ACTION_PAGE_READ_CURRENT,
which only returns active volumes. In order to get info on inactive volumes,
the driver needs to change the action to
MPI2_RAID_PGAD_FORM_GET_NEXT_CONFIGNUM, and traverse each config till the
iocstatus is MPI2_IOCSTATUS_CONFIG_INVALID_PAGE returned.
Added a change in the driver to remove the instance of
sas_device object when the driver returns "1" from the slave_configure callback.
Also fixed code to report the hot spares to the operating system with a /dev/sg
assigned.
Signed-off-by: Nagalakshmi Nandigama <nagalakshmi.nandigama@lsi.com>
Cc: stable@kernel.org
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_scsih.c')
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_scsih.c | 46 |
1 files changed, 38 insertions, 8 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index a8cb57723ff4..8889b1babcac 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c | |||
@@ -610,8 +610,15 @@ _scsih_sas_device_add(struct MPT2SAS_ADAPTER *ioc, | |||
610 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 610 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
611 | 611 | ||
612 | if (!mpt2sas_transport_port_add(ioc, sas_device->handle, | 612 | if (!mpt2sas_transport_port_add(ioc, sas_device->handle, |
613 | sas_device->sas_address_parent)) | 613 | sas_device->sas_address_parent)) { |
614 | _scsih_sas_device_remove(ioc, sas_device); | 614 | _scsih_sas_device_remove(ioc, sas_device); |
615 | } else if (!sas_device->starget) { | ||
616 | if (!ioc->is_driver_loading) | ||
617 | mpt2sas_transport_port_remove(ioc, | ||
618 | sas_device->sas_address, | ||
619 | sas_device->sas_address_parent); | ||
620 | _scsih_sas_device_remove(ioc, sas_device); | ||
621 | } | ||
615 | } | 622 | } |
616 | 623 | ||
617 | /** | 624 | /** |
@@ -1423,6 +1430,10 @@ _scsih_slave_destroy(struct scsi_device *sdev) | |||
1423 | { | 1430 | { |
1424 | struct MPT2SAS_TARGET *sas_target_priv_data; | 1431 | struct MPT2SAS_TARGET *sas_target_priv_data; |
1425 | struct scsi_target *starget; | 1432 | struct scsi_target *starget; |
1433 | struct Scsi_Host *shost; | ||
1434 | struct MPT2SAS_ADAPTER *ioc; | ||
1435 | struct _sas_device *sas_device; | ||
1436 | unsigned long flags; | ||
1426 | 1437 | ||
1427 | if (!sdev->hostdata) | 1438 | if (!sdev->hostdata) |
1428 | return; | 1439 | return; |
@@ -1430,6 +1441,19 @@ _scsih_slave_destroy(struct scsi_device *sdev) | |||
1430 | starget = scsi_target(sdev); | 1441 | starget = scsi_target(sdev); |
1431 | sas_target_priv_data = starget->hostdata; | 1442 | sas_target_priv_data = starget->hostdata; |
1432 | sas_target_priv_data->num_luns--; | 1443 | sas_target_priv_data->num_luns--; |
1444 | |||
1445 | shost = dev_to_shost(&starget->dev); | ||
1446 | ioc = shost_priv(shost); | ||
1447 | |||
1448 | if (!(sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) { | ||
1449 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | ||
1450 | sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, | ||
1451 | sas_target_priv_data->sas_address); | ||
1452 | if (sas_device) | ||
1453 | sas_device->starget = NULL; | ||
1454 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
1455 | } | ||
1456 | |||
1433 | kfree(sdev->hostdata); | 1457 | kfree(sdev->hostdata); |
1434 | sdev->hostdata = NULL; | 1458 | sdev->hostdata = NULL; |
1435 | } | 1459 | } |
@@ -2045,7 +2069,8 @@ _scsih_slave_configure(struct scsi_device *sdev) | |||
2045 | __FILE__, __LINE__, __func__)); | 2069 | __FILE__, __LINE__, __func__)); |
2046 | return 1; | 2070 | return 1; |
2047 | } | 2071 | } |
2048 | if (mpt2sas_config_get_volume_wwid(ioc, | 2072 | if (sas_device->volume_handle && |
2073 | mpt2sas_config_get_volume_wwid(ioc, | ||
2049 | sas_device->volume_handle, | 2074 | sas_device->volume_handle, |
2050 | &sas_device->volume_wwid)) { | 2075 | &sas_device->volume_wwid)) { |
2051 | dfailprintk(ioc, printk(MPT2SAS_WARN_FMT | 2076 | dfailprintk(ioc, printk(MPT2SAS_WARN_FMT |
@@ -5893,8 +5918,11 @@ _scsih_reprobe_lun(struct scsi_device *sdev, void *no_uld_attach) | |||
5893 | static void | 5918 | static void |
5894 | _scsih_reprobe_target(struct scsi_target *starget, int no_uld_attach) | 5919 | _scsih_reprobe_target(struct scsi_target *starget, int no_uld_attach) |
5895 | { | 5920 | { |
5896 | struct MPT2SAS_TARGET *sas_target_priv_data = starget->hostdata; | 5921 | struct MPT2SAS_TARGET *sas_target_priv_data; |
5897 | 5922 | ||
5923 | if (starget == NULL) | ||
5924 | return; | ||
5925 | sas_target_priv_data = starget->hostdata; | ||
5898 | if (no_uld_attach) | 5926 | if (no_uld_attach) |
5899 | sas_target_priv_data->flags |= MPT_TARGET_FLAGS_RAID_COMPONENT; | 5927 | sas_target_priv_data->flags |= MPT_TARGET_FLAGS_RAID_COMPONENT; |
5900 | else | 5928 | else |
@@ -7676,8 +7704,9 @@ _scsih_probe_boot_devices(struct MPT2SAS_ADAPTER *ioc) | |||
7676 | sas_device->sas_address_parent)) { | 7704 | sas_device->sas_address_parent)) { |
7677 | _scsih_sas_device_remove(ioc, sas_device); | 7705 | _scsih_sas_device_remove(ioc, sas_device); |
7678 | } else if (!sas_device->starget) { | 7706 | } else if (!sas_device->starget) { |
7679 | mpt2sas_transport_port_remove(ioc, sas_address, | 7707 | if (!ioc->is_driver_loading) |
7680 | sas_address_parent); | 7708 | mpt2sas_transport_port_remove(ioc, sas_address, |
7709 | sas_address_parent); | ||
7681 | _scsih_sas_device_remove(ioc, sas_device); | 7710 | _scsih_sas_device_remove(ioc, sas_device); |
7682 | } | 7711 | } |
7683 | } | 7712 | } |
@@ -7731,9 +7760,10 @@ _scsih_probe_sas(struct MPT2SAS_ADAPTER *ioc) | |||
7731 | kfree(sas_device); | 7760 | kfree(sas_device); |
7732 | continue; | 7761 | continue; |
7733 | } else if (!sas_device->starget) { | 7762 | } else if (!sas_device->starget) { |
7734 | mpt2sas_transport_port_remove(ioc, | 7763 | if (!ioc->is_driver_loading) |
7735 | sas_device->sas_address, | 7764 | mpt2sas_transport_port_remove(ioc, |
7736 | sas_device->sas_address_parent); | 7765 | sas_device->sas_address, |
7766 | sas_device->sas_address_parent); | ||
7737 | list_del(&sas_device->list); | 7767 | list_del(&sas_device->list); |
7738 | kfree(sas_device); | 7768 | kfree(sas_device); |
7739 | continue; | 7769 | continue; |