aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mpt2sas/mpt2sas_scsih.c
diff options
context:
space:
mode:
authornagalakshmi.nandigama@lsi.com <nagalakshmi.nandigama@lsi.com>2011-10-21 00:38:07 -0400
committerJames Bottomley <JBottomley@Parallels.com>2011-10-30 04:56:55 -0400
commit35116db95c42937061bfca93998291f6562e9e92 (patch)
treeca1c8d23186c78d8796c8786d8d566c7fc845f64 /drivers/scsi/mpt2sas/mpt2sas_scsih.c
parent6faace2a0e418b45728bcea6d3626922cf16b14b (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.c46
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)
5893static void 5918static 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;