aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authornagalakshmi.nandigama@lsi.com <nagalakshmi.nandigama@lsi.com>2012-03-20 02:36:50 -0400
committerJames Bottomley <JBottomley@Parallels.com>2012-04-23 14:27:15 -0400
commit09da0b32d078a3b94aa6d948d053b84755712a2b (patch)
treea77b0732b2c20c918b428686c17176e127ff460b /drivers
parentacafc892b0c71bba8cb5f83b8dd5df4a3000be36 (diff)
[SCSI] mpt2sas: Improvement were made to better protect the sas_device, raid_device, and expander_device lists
There were possible race conditions surrounding reading an object from the link list while from another context in the driver was removing it. The nature of this enhancement is to rearrange locking so the link lists are better protected. Change set: (1) numerous routines were rearranged so spin locks are held through the entire time a link list object is being read from or written to. (2) added new routines for object deletion from link list. Thus ensuring lock was held during the deletion of the link list object, then and memory for object freed outside the lock. The memory was freed outside the lock so driver had access to device object info which was required for notifying the scsi mid layer that a device was getting deleted. (3) added the ioc->blocking_handles parameter. This is a bitmask used to identify which devices need blocking when there is device loss. This was introduced so that lock can be held for the entire time traversing the link list objects, and the bitmask was set to indicate which device handles need blocking. Oustide the lock the ioc->blocking_handles bitmask is traversed, with the respective device handle the scsi mid layer is called for moving devices into blocking state. Signed-off-by: Nagalakshmi Nandigama <nagalakshmi.nandigama@lsi.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.c10
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.h6
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_scsih.c538
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_transport.c46
4 files changed, 329 insertions, 271 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c
index 8a59a772fdf2..30d540a05ad8 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.c
@@ -4279,7 +4279,6 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
4279 goto out_free_resources; 4279 goto out_free_resources;
4280 4280
4281 init_waitqueue_head(&ioc->reset_wq); 4281 init_waitqueue_head(&ioc->reset_wq);
4282
4283 /* allocate memory pd handle bitmask list */ 4282 /* allocate memory pd handle bitmask list */
4284 ioc->pd_handles_sz = (ioc->facts.MaxDevHandle / 8); 4283 ioc->pd_handles_sz = (ioc->facts.MaxDevHandle / 8);
4285 if (ioc->facts.MaxDevHandle % 8) 4284 if (ioc->facts.MaxDevHandle % 8)
@@ -4290,7 +4289,12 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
4290 r = -ENOMEM; 4289 r = -ENOMEM;
4291 goto out_free_resources; 4290 goto out_free_resources;
4292 } 4291 }
4293 4292 ioc->blocking_handles = kzalloc(ioc->pd_handles_sz,
4293 GFP_KERNEL);
4294 if (!ioc->blocking_handles) {
4295 r = -ENOMEM;
4296 goto out_free_resources;
4297 }
4294 ioc->fwfault_debug = mpt2sas_fwfault_debug; 4298 ioc->fwfault_debug = mpt2sas_fwfault_debug;
4295 4299
4296 /* base internal command bits */ 4300 /* base internal command bits */
@@ -4377,6 +4381,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
4377 if (ioc->is_warpdrive) 4381 if (ioc->is_warpdrive)
4378 kfree(ioc->reply_post_host_index); 4382 kfree(ioc->reply_post_host_index);
4379 kfree(ioc->pd_handles); 4383 kfree(ioc->pd_handles);
4384 kfree(ioc->blocking_handles);
4380 kfree(ioc->tm_cmds.reply); 4385 kfree(ioc->tm_cmds.reply);
4381 kfree(ioc->transport_cmds.reply); 4386 kfree(ioc->transport_cmds.reply);
4382 kfree(ioc->scsih_cmds.reply); 4387 kfree(ioc->scsih_cmds.reply);
@@ -4418,6 +4423,7 @@ mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc)
4418 if (ioc->is_warpdrive) 4423 if (ioc->is_warpdrive)
4419 kfree(ioc->reply_post_host_index); 4424 kfree(ioc->reply_post_host_index);
4420 kfree(ioc->pd_handles); 4425 kfree(ioc->pd_handles);
4426 kfree(ioc->blocking_handles);
4421 kfree(ioc->pfacts); 4427 kfree(ioc->pfacts);
4422 kfree(ioc->ctl_cmds.reply); 4428 kfree(ioc->ctl_cmds.reply);
4423 kfree(ioc->ctl_cmds.sense); 4429 kfree(ioc->ctl_cmds.sense);
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h
index c7459fdc06cc..5a0dc30ed41d 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.h
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.h
@@ -720,6 +720,7 @@ typedef void (*MPT2SAS_FLUSH_RUNNING_CMDS)(struct MPT2SAS_ADAPTER *ioc);
720 * @io_missing_delay: time for IO completed by fw when PDR enabled 720 * @io_missing_delay: time for IO completed by fw when PDR enabled
721 * @device_missing_delay: time for device missing by fw when PDR enabled 721 * @device_missing_delay: time for device missing by fw when PDR enabled
722 * @sas_id : used for setting volume target IDs 722 * @sas_id : used for setting volume target IDs
723 * @blocking_handles: bitmask used to identify which devices need blocking
723 * @pd_handles : bitmask for PD handles 724 * @pd_handles : bitmask for PD handles
724 * @pd_handles_sz : size of pd_handle bitmask 725 * @pd_handles_sz : size of pd_handle bitmask
725 * @config_page_sz: config page size 726 * @config_page_sz: config page size
@@ -889,7 +890,7 @@ struct MPT2SAS_ADAPTER {
889 u8 io_missing_delay; 890 u8 io_missing_delay;
890 u16 device_missing_delay; 891 u16 device_missing_delay;
891 int sas_id; 892 int sas_id;
892 893 void *blocking_handles;
893 void *pd_handles; 894 void *pd_handles;
894 u16 pd_handles_sz; 895 u16 pd_handles_sz;
895 896
@@ -1058,7 +1059,8 @@ int mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle,
1058void mpt2sas_scsih_set_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle); 1059void mpt2sas_scsih_set_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle);
1059void mpt2sas_scsih_clear_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle); 1060void mpt2sas_scsih_clear_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle);
1060void mpt2sas_expander_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address); 1061void mpt2sas_expander_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address);
1061void mpt2sas_device_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address); 1062void mpt2sas_device_remove_by_sas_address(struct MPT2SAS_ADAPTER *ioc,
1063 u64 sas_address);
1062struct _sas_node *mpt2sas_scsih_expander_find_by_handle(struct MPT2SAS_ADAPTER *ioc, 1064struct _sas_node *mpt2sas_scsih_expander_find_by_handle(struct MPT2SAS_ADAPTER *ioc,
1063 u16 handle); 1065 u16 handle);
1064struct _sas_node *mpt2sas_scsih_expander_find_by_sas_address(struct MPT2SAS_ADAPTER 1066struct _sas_node *mpt2sas_scsih_expander_find_by_sas_address(struct MPT2SAS_ADAPTER
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index d953a57e779d..9a739e6f2712 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -579,14 +579,12 @@ _scsih_sas_device_remove(struct MPT2SAS_ADAPTER *ioc,
579 return; 579 return;
580 580
581 spin_lock_irqsave(&ioc->sas_device_lock, flags); 581 spin_lock_irqsave(&ioc->sas_device_lock, flags);
582 if (mpt2sas_scsih_sas_device_find_by_sas_address(ioc, 582 list_del(&sas_device->list);
583 sas_device->sas_address)) { 583 kfree(sas_device);
584 list_del(&sas_device->list);
585 kfree(sas_device);
586 }
587 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 584 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
588} 585}
589 586
587
590/** 588/**
591 * _scsih_sas_device_add - insert sas_device to the list. 589 * _scsih_sas_device_add - insert sas_device to the list.
592 * @ioc: per adapter object 590 * @ioc: per adapter object
@@ -645,8 +643,8 @@ _scsih_sas_device_init_add(struct MPT2SAS_ADAPTER *ioc,
645 643
646 spin_lock_irqsave(&ioc->sas_device_lock, flags); 644 spin_lock_irqsave(&ioc->sas_device_lock, flags);
647 list_add_tail(&sas_device->list, &ioc->sas_device_init_list); 645 list_add_tail(&sas_device->list, &ioc->sas_device_init_list);
648 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
649 _scsih_determine_boot_device(ioc, sas_device, 0); 646 _scsih_determine_boot_device(ioc, sas_device, 0);
647 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
650} 648}
651 649
652/** 650/**
@@ -755,7 +753,6 @@ _scsih_raid_device_add(struct MPT2SAS_ADAPTER *ioc,
755 * @ioc: per adapter object 753 * @ioc: per adapter object
756 * @raid_device: raid_device object 754 * @raid_device: raid_device object
757 * 755 *
758 * This is removed from the raid_device_list link list.
759 */ 756 */
760static void 757static void
761_scsih_raid_device_remove(struct MPT2SAS_ADAPTER *ioc, 758_scsih_raid_device_remove(struct MPT2SAS_ADAPTER *ioc,
@@ -765,7 +762,6 @@ _scsih_raid_device_remove(struct MPT2SAS_ADAPTER *ioc,
765 762
766 spin_lock_irqsave(&ioc->raid_device_lock, flags); 763 spin_lock_irqsave(&ioc->raid_device_lock, flags);
767 list_del(&raid_device->list); 764 list_del(&raid_device->list);
768 memset(raid_device, 0, sizeof(struct _raid_device));
769 kfree(raid_device); 765 kfree(raid_device);
770 spin_unlock_irqrestore(&ioc->raid_device_lock, flags); 766 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
771} 767}
@@ -1199,10 +1195,10 @@ _scsih_adjust_queue_depth(struct scsi_device *sdev, int qdepth)
1199 spin_lock_irqsave(&ioc->sas_device_lock, flags); 1195 spin_lock_irqsave(&ioc->sas_device_lock, flags);
1200 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, 1196 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
1201 sas_device_priv_data->sas_target->sas_address); 1197 sas_device_priv_data->sas_target->sas_address);
1202 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
1203 if (sas_device && sas_device->device_info & 1198 if (sas_device && sas_device->device_info &
1204 MPI2_SAS_DEVICE_INFO_SATA_DEVICE) 1199 MPI2_SAS_DEVICE_INFO_SATA_DEVICE)
1205 max_depth = MPT2SAS_SATA_QUEUE_DEPTH; 1200 max_depth = MPT2SAS_SATA_QUEUE_DEPTH;
1201 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
1206 1202
1207 not_sata: 1203 not_sata:
1208 1204
@@ -1299,7 +1295,8 @@ _scsih_target_alloc(struct scsi_target *starget)
1299 sas_target_priv_data->handle = raid_device->handle; 1295 sas_target_priv_data->handle = raid_device->handle;
1300 sas_target_priv_data->sas_address = raid_device->wwid; 1296 sas_target_priv_data->sas_address = raid_device->wwid;
1301 sas_target_priv_data->flags |= MPT_TARGET_FLAGS_VOLUME; 1297 sas_target_priv_data->flags |= MPT_TARGET_FLAGS_VOLUME;
1302 sas_target_priv_data->raid_device = raid_device; 1298 if (ioc->is_warpdrive)
1299 sas_target_priv_data->raid_device = raid_device;
1303 raid_device->starget = starget; 1300 raid_device->starget = starget;
1304 } 1301 }
1305 spin_unlock_irqrestore(&ioc->raid_device_lock, flags); 1302 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
@@ -1465,12 +1462,12 @@ _scsih_slave_destroy(struct scsi_device *sdev)
1465/** 1462/**
1466 * _scsih_display_sata_capabilities - sata capabilities 1463 * _scsih_display_sata_capabilities - sata capabilities
1467 * @ioc: per adapter object 1464 * @ioc: per adapter object
1468 * @sas_device: the sas_device object 1465 * @handle: device handle
1469 * @sdev: scsi device struct 1466 * @sdev: scsi device struct
1470 */ 1467 */
1471static void 1468static void
1472_scsih_display_sata_capabilities(struct MPT2SAS_ADAPTER *ioc, 1469_scsih_display_sata_capabilities(struct MPT2SAS_ADAPTER *ioc,
1473 struct _sas_device *sas_device, struct scsi_device *sdev) 1470 u16 handle, struct scsi_device *sdev)
1474{ 1471{
1475 Mpi2ConfigReply_t mpi_reply; 1472 Mpi2ConfigReply_t mpi_reply;
1476 Mpi2SasDevicePage0_t sas_device_pg0; 1473 Mpi2SasDevicePage0_t sas_device_pg0;
@@ -1479,7 +1476,7 @@ _scsih_display_sata_capabilities(struct MPT2SAS_ADAPTER *ioc,
1479 u32 device_info; 1476 u32 device_info;
1480 1477
1481 if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, 1478 if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
1482 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, sas_device->handle))) { 1479 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) {
1483 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 1480 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1484 ioc->name, __FILE__, __LINE__, __func__); 1481 ioc->name, __FILE__, __LINE__, __func__);
1485 return; 1482 return;
@@ -1537,27 +1534,40 @@ _scsih_get_resync(struct device *dev)
1537 Mpi2RaidVolPage0_t vol_pg0; 1534 Mpi2RaidVolPage0_t vol_pg0;
1538 Mpi2ConfigReply_t mpi_reply; 1535 Mpi2ConfigReply_t mpi_reply;
1539 u32 volume_status_flags; 1536 u32 volume_status_flags;
1540 u8 percent_complete = 0; 1537 u8 percent_complete;
1538 u16 handle;
1539
1540 percent_complete = 0;
1541 handle = 0;
1542 if (ioc->is_warpdrive)
1543 goto out;
1541 1544
1542 spin_lock_irqsave(&ioc->raid_device_lock, flags); 1545 spin_lock_irqsave(&ioc->raid_device_lock, flags);
1543 raid_device = _scsih_raid_device_find_by_id(ioc, sdev->id, 1546 raid_device = _scsih_raid_device_find_by_id(ioc, sdev->id,
1544 sdev->channel); 1547 sdev->channel);
1548 if (raid_device) {
1549 handle = raid_device->handle;
1550 percent_complete = raid_device->percent_complete;
1551 }
1545 spin_unlock_irqrestore(&ioc->raid_device_lock, flags); 1552 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
1546 1553
1547 if (!raid_device || ioc->is_warpdrive) 1554 if (!handle)
1548 goto out; 1555 goto out;
1549 1556
1550 if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0, 1557 if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0,
1551 MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle, 1558 MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, handle,
1552 sizeof(Mpi2RaidVolPage0_t))) { 1559 sizeof(Mpi2RaidVolPage0_t))) {
1553 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 1560 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1554 ioc->name, __FILE__, __LINE__, __func__); 1561 ioc->name, __FILE__, __LINE__, __func__);
1562 percent_complete = 0;
1555 goto out; 1563 goto out;
1556 } 1564 }
1557 1565
1558 volume_status_flags = le32_to_cpu(vol_pg0.VolumeStatusFlags); 1566 volume_status_flags = le32_to_cpu(vol_pg0.VolumeStatusFlags);
1559 if (volume_status_flags & MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS) 1567 if (!(volume_status_flags &
1560 percent_complete = raid_device->percent_complete; 1568 MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS))
1569 percent_complete = 0;
1570
1561 out: 1571 out:
1562 raid_set_resync(mpt2sas_raid_template, dev, percent_complete); 1572 raid_set_resync(mpt2sas_raid_template, dev, percent_complete);
1563} 1573}
@@ -1577,17 +1587,20 @@ _scsih_get_state(struct device *dev)
1577 Mpi2ConfigReply_t mpi_reply; 1587 Mpi2ConfigReply_t mpi_reply;
1578 u32 volstate; 1588 u32 volstate;
1579 enum raid_state state = RAID_STATE_UNKNOWN; 1589 enum raid_state state = RAID_STATE_UNKNOWN;
1590 u16 handle = 0;
1580 1591
1581 spin_lock_irqsave(&ioc->raid_device_lock, flags); 1592 spin_lock_irqsave(&ioc->raid_device_lock, flags);
1582 raid_device = _scsih_raid_device_find_by_id(ioc, sdev->id, 1593 raid_device = _scsih_raid_device_find_by_id(ioc, sdev->id,
1583 sdev->channel); 1594 sdev->channel);
1595 if (raid_device)
1596 handle = raid_device->handle;
1584 spin_unlock_irqrestore(&ioc->raid_device_lock, flags); 1597 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
1585 1598
1586 if (!raid_device) 1599 if (!raid_device)
1587 goto out; 1600 goto out;
1588 1601
1589 if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0, 1602 if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0,
1590 MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle, 1603 MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, handle,
1591 sizeof(Mpi2RaidVolPage0_t))) { 1604 sizeof(Mpi2RaidVolPage0_t))) {
1592 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 1605 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1593 ioc->name, __FILE__, __LINE__, __func__); 1606 ioc->name, __FILE__, __LINE__, __func__);
@@ -1620,14 +1633,14 @@ _scsih_get_state(struct device *dev)
1620/** 1633/**
1621 * _scsih_set_level - set raid level 1634 * _scsih_set_level - set raid level
1622 * @sdev: scsi device struct 1635 * @sdev: scsi device struct
1623 * @raid_device: raid_device object 1636 * @volume_type: volume type
1624 */ 1637 */
1625static void 1638static void
1626_scsih_set_level(struct scsi_device *sdev, struct _raid_device *raid_device) 1639_scsih_set_level(struct scsi_device *sdev, u8 volume_type)
1627{ 1640{
1628 enum raid_level level = RAID_LEVEL_UNKNOWN; 1641 enum raid_level level = RAID_LEVEL_UNKNOWN;
1629 1642
1630 switch (raid_device->volume_type) { 1643 switch (volume_type) {
1631 case MPI2_RAID_VOL_TYPE_RAID0: 1644 case MPI2_RAID_VOL_TYPE_RAID0:
1632 level = RAID_LEVEL_0; 1645 level = RAID_LEVEL_0;
1633 break; 1646 break;
@@ -1722,6 +1735,7 @@ _scsih_disable_ddio(struct MPT2SAS_ADAPTER *ioc)
1722 struct _raid_device *raid_device; 1735 struct _raid_device *raid_device;
1723 u16 handle; 1736 u16 handle;
1724 u16 ioc_status; 1737 u16 ioc_status;
1738 unsigned long flags;
1725 1739
1726 handle = 0xFFFF; 1740 handle = 0xFFFF;
1727 while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply, 1741 while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
@@ -1731,9 +1745,11 @@ _scsih_disable_ddio(struct MPT2SAS_ADAPTER *ioc)
1731 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) 1745 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
1732 break; 1746 break;
1733 handle = le16_to_cpu(vol_pg1.DevHandle); 1747 handle = le16_to_cpu(vol_pg1.DevHandle);
1748 spin_lock_irqsave(&ioc->raid_device_lock, flags);
1734 raid_device = _scsih_raid_device_find_by_handle(ioc, handle); 1749 raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
1735 if (raid_device) 1750 if (raid_device)
1736 raid_device->direct_io_enabled = 0; 1751 raid_device->direct_io_enabled = 0;
1752 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
1737 } 1753 }
1738 return; 1754 return;
1739} 1755}
@@ -1968,19 +1984,21 @@ _scsih_slave_configure(struct scsi_device *sdev)
1968 u8 ssp_target = 0; 1984 u8 ssp_target = 0;
1969 char *ds = ""; 1985 char *ds = "";
1970 char *r_level = ""; 1986 char *r_level = "";
1987 u16 handle, volume_handle = 0;
1988 u64 volume_wwid = 0;
1971 1989
1972 qdepth = 1; 1990 qdepth = 1;
1973 sas_device_priv_data = sdev->hostdata; 1991 sas_device_priv_data = sdev->hostdata;
1974 sas_device_priv_data->configured_lun = 1; 1992 sas_device_priv_data->configured_lun = 1;
1975 sas_device_priv_data->flags &= ~MPT_DEVICE_FLAGS_INIT; 1993 sas_device_priv_data->flags &= ~MPT_DEVICE_FLAGS_INIT;
1976 sas_target_priv_data = sas_device_priv_data->sas_target; 1994 sas_target_priv_data = sas_device_priv_data->sas_target;
1995 handle = sas_target_priv_data->handle;
1977 1996
1978 /* raid volume handling */ 1997 /* raid volume handling */
1979 if (sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME) { 1998 if (sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME) {
1980 1999
1981 spin_lock_irqsave(&ioc->raid_device_lock, flags); 2000 spin_lock_irqsave(&ioc->raid_device_lock, flags);
1982 raid_device = _scsih_raid_device_find_by_handle(ioc, 2001 raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
1983 sas_target_priv_data->handle);
1984 spin_unlock_irqrestore(&ioc->raid_device_lock, flags); 2002 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
1985 if (!raid_device) { 2003 if (!raid_device) {
1986 dfailprintk(ioc, printk(MPT2SAS_WARN_FMT 2004 dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
@@ -1989,8 +2007,6 @@ _scsih_slave_configure(struct scsi_device *sdev)
1989 return 1; 2007 return 1;
1990 } 2008 }
1991 2009
1992 _scsih_get_volume_capabilities(ioc, raid_device);
1993
1994 if (_scsih_get_volume_capabilities(ioc, raid_device)) { 2010 if (_scsih_get_volume_capabilities(ioc, raid_device)) {
1995 dfailprintk(ioc, printk(MPT2SAS_WARN_FMT 2011 dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
1996 "failure at %s:%d/%s()!\n", ioc->name, __FILE__, 2012 "failure at %s:%d/%s()!\n", ioc->name, __FILE__,
@@ -2058,68 +2074,67 @@ _scsih_slave_configure(struct scsi_device *sdev)
2058 _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT); 2074 _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT);
2059 /* raid transport support */ 2075 /* raid transport support */
2060 if (!ioc->is_warpdrive) 2076 if (!ioc->is_warpdrive)
2061 _scsih_set_level(sdev, raid_device); 2077 _scsih_set_level(sdev, raid_device->volume_type);
2062 return 0; 2078 return 0;
2063 } 2079 }
2064 2080
2065 /* non-raid handling */ 2081 /* non-raid handling */
2066 spin_lock_irqsave(&ioc->sas_device_lock, flags); 2082 if (sas_target_priv_data->flags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
2067 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, 2083 if (mpt2sas_config_get_volume_handle(ioc, handle,
2068 sas_device_priv_data->sas_target->sas_address); 2084 &volume_handle)) {
2069 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 2085 dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
2070 if (sas_device) { 2086 "failure at %s:%d/%s()!\n", ioc->name,
2071 if (sas_target_priv_data->flags & 2087 __FILE__, __LINE__, __func__));
2072 MPT_TARGET_FLAGS_RAID_COMPONENT) { 2088 return 1;
2073 if (mpt2sas_config_get_volume_handle(ioc,
2074 sas_device->handle, &sas_device->volume_handle)) {
2075 dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
2076 "failure at %s:%d/%s()!\n", ioc->name,
2077 __FILE__, __LINE__, __func__));
2078 return 1;
2079 }
2080 if (sas_device->volume_handle &&
2081 mpt2sas_config_get_volume_wwid(ioc,
2082 sas_device->volume_handle,
2083 &sas_device->volume_wwid)) {
2084 dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
2085 "failure at %s:%d/%s()!\n", ioc->name,
2086 __FILE__, __LINE__, __func__));
2087 return 1;
2088 }
2089 } 2089 }
2090 if (sas_device->device_info & MPI2_SAS_DEVICE_INFO_SSP_TARGET) { 2090 if (volume_handle && mpt2sas_config_get_volume_wwid(ioc,
2091 qdepth = MPT2SAS_SAS_QUEUE_DEPTH; 2091 volume_handle, &volume_wwid)) {
2092 ssp_target = 1; 2092 dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
2093 ds = "SSP"; 2093 "failure at %s:%d/%s()!\n", ioc->name,
2094 } else { 2094 __FILE__, __LINE__, __func__));
2095 qdepth = MPT2SAS_SATA_QUEUE_DEPTH; 2095 return 1;
2096 if (sas_device->device_info &
2097 MPI2_SAS_DEVICE_INFO_STP_TARGET)
2098 ds = "STP";
2099 else if (sas_device->device_info &
2100 MPI2_SAS_DEVICE_INFO_SATA_DEVICE)
2101 ds = "SATA";
2102 } 2096 }
2097 }
2103 2098
2104 sdev_printk(KERN_INFO, sdev, "%s: handle(0x%04x), " 2099 spin_lock_irqsave(&ioc->sas_device_lock, flags);
2105 "sas_addr(0x%016llx), phy(%d), device_name(0x%016llx)\n", 2100 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
2106 ds, sas_device->handle, 2101 sas_device_priv_data->sas_target->sas_address);
2107 (unsigned long long)sas_device->sas_address, 2102 if (!sas_device) {
2108 sas_device->phy, 2103 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2109 (unsigned long long)sas_device->device_name);
2110 sdev_printk(KERN_INFO, sdev, "%s: "
2111 "enclosure_logical_id(0x%016llx), slot(%d)\n", ds,
2112 (unsigned long long) sas_device->enclosure_logical_id,
2113 sas_device->slot);
2114
2115 if (!ssp_target)
2116 _scsih_display_sata_capabilities(ioc, sas_device, sdev);
2117 } else {
2118 dfailprintk(ioc, printk(MPT2SAS_WARN_FMT 2104 dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
2119 "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, 2105 "failure at %s:%d/%s()!\n", ioc->name, __FILE__,
2120 __func__)); 2106 __LINE__, __func__));
2121 return 1; 2107 return 1;
2122 } 2108 }
2109 sas_device->volume_handle = volume_handle;
2110 sas_device->volume_wwid = volume_wwid;
2111 if (sas_device->device_info & MPI2_SAS_DEVICE_INFO_SSP_TARGET) {
2112 qdepth = MPT2SAS_SAS_QUEUE_DEPTH;
2113 ssp_target = 1;
2114 ds = "SSP";
2115 } else {
2116 qdepth = MPT2SAS_SATA_QUEUE_DEPTH;
2117 if (sas_device->device_info & MPI2_SAS_DEVICE_INFO_STP_TARGET)
2118 ds = "STP";
2119 else if (sas_device->device_info &
2120 MPI2_SAS_DEVICE_INFO_SATA_DEVICE)
2121 ds = "SATA";
2122 }
2123 sdev_printk(KERN_INFO, sdev, "%s: handle(0x%04x), "
2124 "sas_addr(0x%016llx), phy(%d), device_name(0x%016llx)\n",
2125 ds, sas_device->handle,
2126 (unsigned long long)sas_device->sas_address,
2127 sas_device->phy,
2128 (unsigned long long)sas_device->device_name);
2129 sdev_printk(KERN_INFO, sdev, "%s: "
2130 "enclosure_logical_id(0x%016llx), slot(%d)\n", ds,
2131 (unsigned long long) sas_device->enclosure_logical_id,
2132 sas_device->slot);
2133
2134 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2135 if (!ssp_target)
2136 _scsih_display_sata_capabilities(ioc, handle, sdev);
2137
2123 2138
2124 _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT); 2139 _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT);
2125 2140
@@ -3006,10 +3021,10 @@ _scsih_block_io_to_children_attached_to_ex(struct MPT2SAS_ADAPTER *ioc,
3006 sas_device = 3021 sas_device =
3007 mpt2sas_scsih_sas_device_find_by_sas_address(ioc, 3022 mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
3008 mpt2sas_port->remote_identify.sas_address); 3023 mpt2sas_port->remote_identify.sas_address);
3024 if (sas_device)
3025 set_bit(sas_device->handle,
3026 ioc->blocking_handles);
3009 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 3027 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
3010 if (!sas_device)
3011 continue;
3012 _scsih_block_io_device(ioc, sas_device->handle);
3013 } 3028 }
3014 } 3029 }
3015 3030
@@ -3020,12 +3035,9 @@ _scsih_block_io_to_children_attached_to_ex(struct MPT2SAS_ADAPTER *ioc,
3020 SAS_EDGE_EXPANDER_DEVICE || 3035 SAS_EDGE_EXPANDER_DEVICE ||
3021 mpt2sas_port->remote_identify.device_type == 3036 mpt2sas_port->remote_identify.device_type ==
3022 SAS_FANOUT_EXPANDER_DEVICE) { 3037 SAS_FANOUT_EXPANDER_DEVICE) {
3023
3024 spin_lock_irqsave(&ioc->sas_node_lock, flags);
3025 expander_sibling = 3038 expander_sibling =
3026 mpt2sas_scsih_expander_find_by_sas_address( 3039 mpt2sas_scsih_expander_find_by_sas_address(
3027 ioc, mpt2sas_port->remote_identify.sas_address); 3040 ioc, mpt2sas_port->remote_identify.sas_address);
3028 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
3029 _scsih_block_io_to_children_attached_to_ex(ioc, 3041 _scsih_block_io_to_children_attached_to_ex(ioc,
3030 expander_sibling); 3042 expander_sibling);
3031 } 3043 }
@@ -3441,14 +3453,20 @@ _scsih_check_topo_delete_events(struct MPT2SAS_ADAPTER *ioc,
3441 _scsih_block_io_to_children_attached_directly(ioc, event_data); 3453 _scsih_block_io_to_children_attached_directly(ioc, event_data);
3442 return; 3454 return;
3443 } 3455 }
3444 3456 if (event_data->ExpStatus ==
3445 if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING 3457 MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING) {
3446 || event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING) { 3458 /* put expander attached devices into blocking state */
3447 spin_lock_irqsave(&ioc->sas_node_lock, flags); 3459 spin_lock_irqsave(&ioc->sas_node_lock, flags);
3448 sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc, 3460 sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc,
3449 expander_handle); 3461 expander_handle);
3450 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
3451 _scsih_block_io_to_children_attached_to_ex(ioc, sas_expander); 3462 _scsih_block_io_to_children_attached_to_ex(ioc, sas_expander);
3463 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
3464 do {
3465 handle = find_first_bit(ioc->blocking_handles,
3466 ioc->facts.MaxDevHandle);
3467 if (handle < ioc->facts.MaxDevHandle)
3468 _scsih_block_io_device(ioc, handle);
3469 } while (test_and_clear_bit(handle, ioc->blocking_handles));
3452 } else if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_RESPONDING) 3470 } else if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_RESPONDING)
3453 _scsih_block_io_to_children_attached_directly(ioc, event_data); 3471 _scsih_block_io_to_children_attached_directly(ioc, event_data);
3454 3472
@@ -4446,8 +4464,8 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
4446 != MPI2_IOCSTATUS_SCSI_TASK_TERMINATED)) { 4464 != MPI2_IOCSTATUS_SCSI_TASK_TERMINATED)) {
4447 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); 4465 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
4448 ioc->scsi_lookup[smid - 1].scmd = scmd; 4466 ioc->scsi_lookup[smid - 1].scmd = scmd;
4449 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
4450 _scsih_scsi_direct_io_set(ioc, smid, 0); 4467 _scsih_scsi_direct_io_set(ioc, smid, 0);
4468 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
4451 memcpy(mpi_request->CDB.CDB32, scmd->cmnd, scmd->cmd_len); 4469 memcpy(mpi_request->CDB.CDB32, scmd->cmnd, scmd->cmd_len);
4452 mpi_request->DevHandle = 4470 mpi_request->DevHandle =
4453 cpu_to_le16(sas_device_priv_data->sas_target->handle); 4471 cpu_to_le16(sas_device_priv_data->sas_target->handle);
@@ -5020,13 +5038,11 @@ mpt2sas_expander_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address)
5020 spin_lock_irqsave(&ioc->sas_node_lock, flags); 5038 spin_lock_irqsave(&ioc->sas_node_lock, flags);
5021 sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc, 5039 sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc,
5022 sas_address); 5040 sas_address);
5023 if (!sas_expander) { 5041 if (sas_expander)
5024 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 5042 list_del(&sas_expander->list);
5025 return;
5026 }
5027 list_del(&sas_expander->list);
5028 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 5043 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
5029 _scsih_expander_node_remove(ioc, sas_expander); 5044 if (sas_expander)
5045 _scsih_expander_node_remove(ioc, sas_expander);
5030} 5046}
5031 5047
5032/** 5048/**
@@ -5106,6 +5122,7 @@ _scsih_check_device(struct MPT2SAS_ADAPTER *ioc, u16 handle)
5106 struct MPT2SAS_TARGET *sas_target_priv_data; 5122 struct MPT2SAS_TARGET *sas_target_priv_data;
5107 u32 device_info; 5123 u32 device_info;
5108 5124
5125
5109 if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, 5126 if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
5110 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) 5127 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle)))
5111 return; 5128 return;
@@ -5139,20 +5156,23 @@ _scsih_check_device(struct MPT2SAS_ADAPTER *ioc, u16 handle)
5139 sas_target_priv_data->handle = handle; 5156 sas_target_priv_data->handle = handle;
5140 sas_device->handle = handle; 5157 sas_device->handle = handle;
5141 } 5158 }
5142 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
5143 5159
5144 /* check if device is present */ 5160 /* check if device is present */
5145 if (!(le16_to_cpu(sas_device_pg0.Flags) & 5161 if (!(le16_to_cpu(sas_device_pg0.Flags) &
5146 MPI2_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)) { 5162 MPI2_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)) {
5147 printk(MPT2SAS_ERR_FMT "device is not present " 5163 printk(MPT2SAS_ERR_FMT "device is not present "
5148 "handle(0x%04x), flags!!!\n", ioc->name, handle); 5164 "handle(0x%04x), flags!!!\n", ioc->name, handle);
5165 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
5149 return; 5166 return;
5150 } 5167 }
5151 5168
5152 /* check if there were any issues with discovery */ 5169 /* check if there were any issues with discovery */
5153 if (_scsih_check_access_status(ioc, sas_address, handle, 5170 if (_scsih_check_access_status(ioc, sas_address, handle,
5154 sas_device_pg0.AccessStatus)) 5171 sas_device_pg0.AccessStatus)) {
5172 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
5155 return; 5173 return;
5174 }
5175 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
5156 _scsih_ublock_io_device(ioc, handle); 5176 _scsih_ublock_io_device(ioc, handle);
5157 5177
5158} 5178}
@@ -5280,54 +5300,71 @@ static void
5280_scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, 5300_scsih_remove_device(struct MPT2SAS_ADAPTER *ioc,
5281 struct _sas_device *sas_device) 5301 struct _sas_device *sas_device)
5282{ 5302{
5283 struct _sas_device sas_device_backup;
5284 struct MPT2SAS_TARGET *sas_target_priv_data; 5303 struct MPT2SAS_TARGET *sas_target_priv_data;
5285 5304
5286 if (!sas_device)
5287 return;
5288
5289 memcpy(&sas_device_backup, sas_device, sizeof(struct _sas_device));
5290 _scsih_sas_device_remove(ioc, sas_device);
5291
5292 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter: " 5305 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter: "
5293 "handle(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__, 5306 "handle(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__,
5294 sas_device_backup.handle, (unsigned long long) 5307 sas_device->handle, (unsigned long long)
5295 sas_device_backup.sas_address)); 5308 sas_device->sas_address));
5296 5309
5297 if (sas_device_backup.starget && sas_device_backup.starget->hostdata) { 5310 if (sas_device->starget && sas_device->starget->hostdata) {
5298 sas_target_priv_data = sas_device_backup.starget->hostdata; 5311 sas_target_priv_data = sas_device->starget->hostdata;
5299 sas_target_priv_data->deleted = 1; 5312 sas_target_priv_data->deleted = 1;
5300 _scsih_ublock_io_device(ioc, sas_device_backup.handle); 5313 _scsih_ublock_io_device(ioc, sas_device->handle);
5301 sas_target_priv_data->handle = 5314 sas_target_priv_data->handle =
5302 MPT2SAS_INVALID_DEVICE_HANDLE; 5315 MPT2SAS_INVALID_DEVICE_HANDLE;
5303 } 5316 }
5304 5317
5305 _scsih_ublock_io_device(ioc, sas_device_backup.handle);
5306
5307 if (!ioc->hide_drives) 5318 if (!ioc->hide_drives)
5308 mpt2sas_transport_port_remove(ioc, 5319 mpt2sas_transport_port_remove(ioc,
5309 sas_device_backup.sas_address, 5320 sas_device->sas_address,
5310 sas_device_backup.sas_address_parent); 5321 sas_device->sas_address_parent);
5311 5322
5312 printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), sas_addr" 5323 printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), sas_addr"
5313 "(0x%016llx)\n", ioc->name, sas_device_backup.handle, 5324 "(0x%016llx)\n", ioc->name, sas_device->handle,
5314 (unsigned long long) sas_device_backup.sas_address); 5325 (unsigned long long) sas_device->sas_address);
5315 5326
5316 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: exit: " 5327 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: exit: "
5317 "handle(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__, 5328 "handle(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__,
5318 sas_device_backup.handle, (unsigned long long) 5329 sas_device->handle, (unsigned long long)
5319 sas_device_backup.sas_address)); 5330 sas_device->sas_address));
5331 kfree(sas_device);
5332}
5333/**
5334 * _scsih_device_remove_by_handle - removing device object by handle
5335 * @ioc: per adapter object
5336 * @handle: device handle
5337 *
5338 * Return nothing.
5339 */
5340static void
5341_scsih_device_remove_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle)
5342{
5343 struct _sas_device *sas_device;
5344 unsigned long flags;
5345
5346 if (ioc->shost_recovery)
5347 return;
5348
5349 spin_lock_irqsave(&ioc->sas_device_lock, flags);
5350 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
5351 if (sas_device)
5352 list_del(&sas_device->list);
5353 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
5354 if (sas_device)
5355 _scsih_remove_device(ioc, sas_device);
5320} 5356}
5321 5357
5322/** 5358/**
5323 * mpt2sas_device_remove - removing device object 5359 * mpt2sas_device_remove_by_sas_address - removing device object by sas address
5324 * @ioc: per adapter object 5360 * @ioc: per adapter object
5325 * @sas_address: expander sas_address 5361 * @sas_address: device sas_address
5326 * 5362 *
5327 * Return nothing. 5363 * Return nothing.
5328 */ 5364 */
5329void 5365void
5330mpt2sas_device_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address) 5366mpt2sas_device_remove_by_sas_address(struct MPT2SAS_ADAPTER *ioc,
5367 u64 sas_address)
5331{ 5368{
5332 struct _sas_device *sas_device; 5369 struct _sas_device *sas_device;
5333 unsigned long flags; 5370 unsigned long flags;
@@ -5338,14 +5375,12 @@ mpt2sas_device_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address)
5338 spin_lock_irqsave(&ioc->sas_device_lock, flags); 5375 spin_lock_irqsave(&ioc->sas_device_lock, flags);
5339 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, 5376 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
5340 sas_address); 5377 sas_address);
5341 if (!sas_device) { 5378 if (sas_device)
5342 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 5379 list_del(&sas_device->list);
5343 return;
5344 }
5345 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 5380 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
5346 _scsih_remove_device(ioc, sas_device); 5381 if (sas_device)
5382 _scsih_remove_device(ioc, sas_device);
5347} 5383}
5348
5349#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 5384#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
5350/** 5385/**
5351 * _scsih_sas_topology_change_event_debug - debug for topology event 5386 * _scsih_sas_topology_change_event_debug - debug for topology event
@@ -5442,7 +5477,6 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
5442 u16 reason_code; 5477 u16 reason_code;
5443 u8 phy_number, max_phys; 5478 u8 phy_number, max_phys;
5444 struct _sas_node *sas_expander; 5479 struct _sas_node *sas_expander;
5445 struct _sas_device *sas_device;
5446 u64 sas_address; 5480 u64 sas_address;
5447 unsigned long flags; 5481 unsigned long flags;
5448 u8 link_rate, prev_link_rate; 5482 u8 link_rate, prev_link_rate;
@@ -5477,15 +5511,17 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
5477 spin_lock_irqsave(&ioc->sas_node_lock, flags); 5511 spin_lock_irqsave(&ioc->sas_node_lock, flags);
5478 sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc, 5512 sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc,
5479 parent_handle); 5513 parent_handle);
5480 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
5481 if (sas_expander) { 5514 if (sas_expander) {
5482 sas_address = sas_expander->sas_address; 5515 sas_address = sas_expander->sas_address;
5483 max_phys = sas_expander->num_phys; 5516 max_phys = sas_expander->num_phys;
5484 } else if (parent_handle < ioc->sas_hba.num_phys) { 5517 } else if (parent_handle < ioc->sas_hba.num_phys) {
5485 sas_address = ioc->sas_hba.sas_address; 5518 sas_address = ioc->sas_hba.sas_address;
5486 max_phys = ioc->sas_hba.num_phys; 5519 max_phys = ioc->sas_hba.num_phys;
5487 } else 5520 } else {
5521 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
5488 return; 5522 return;
5523 }
5524 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
5489 5525
5490 /* handle siblings events */ 5526 /* handle siblings events */
5491 for (i = 0; i < event_data->NumEntries; i++) { 5527 for (i = 0; i < event_data->NumEntries; i++) {
@@ -5540,16 +5576,7 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
5540 break; 5576 break;
5541 case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING: 5577 case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING:
5542 5578
5543 spin_lock_irqsave(&ioc->sas_device_lock, flags); 5579 _scsih_device_remove_by_handle(ioc, handle);
5544 sas_device = _scsih_sas_device_find_by_handle(ioc,
5545 handle);
5546 if (!sas_device) {
5547 spin_unlock_irqrestore(&ioc->sas_device_lock,
5548 flags);
5549 break;
5550 }
5551 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
5552 _scsih_remove_device(ioc, sas_device);
5553 break; 5580 break;
5554 } 5581 }
5555 } 5582 }
@@ -5672,20 +5699,24 @@ _scsih_sas_device_status_change_event(struct MPT2SAS_ADAPTER *ioc,
5672 sas_address = le64_to_cpu(event_data->SASAddress); 5699 sas_address = le64_to_cpu(event_data->SASAddress);
5673 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, 5700 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
5674 sas_address); 5701 sas_address);
5675 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
5676 5702
5677 if (!sas_device || !sas_device->starget) 5703 if (!sas_device || !sas_device->starget) {
5704 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
5678 return; 5705 return;
5706 }
5679 5707
5680 target_priv_data = sas_device->starget->hostdata; 5708 target_priv_data = sas_device->starget->hostdata;
5681 if (!target_priv_data) 5709 if (!target_priv_data) {
5710 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
5682 return; 5711 return;
5712 }
5683 5713
5684 if (event_data->ReasonCode == 5714 if (event_data->ReasonCode ==
5685 MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET) 5715 MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET)
5686 target_priv_data->tm_busy = 1; 5716 target_priv_data->tm_busy = 1;
5687 else 5717 else
5688 target_priv_data->tm_busy = 0; 5718 target_priv_data->tm_busy = 0;
5719 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
5689} 5720}
5690 5721
5691#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 5722#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
@@ -5950,30 +5981,6 @@ _scsih_reprobe_lun(struct scsi_device *sdev, void *no_uld_attach)
5950} 5981}
5951 5982
5952/** 5983/**
5953 * _scsih_reprobe_target - reprobing target
5954 * @starget: scsi target struct
5955 * @no_uld_attach: sdev->no_uld_attach flag setting
5956 *
5957 * Note: no_uld_attach flag determines whether the disk device is attached
5958 * to block layer. A value of `1` means to not attach.
5959 **/
5960static void
5961_scsih_reprobe_target(struct scsi_target *starget, int no_uld_attach)
5962{
5963 struct MPT2SAS_TARGET *sas_target_priv_data;
5964
5965 if (starget == NULL)
5966 return;
5967 sas_target_priv_data = starget->hostdata;
5968 if (no_uld_attach)
5969 sas_target_priv_data->flags |= MPT_TARGET_FLAGS_RAID_COMPONENT;
5970 else
5971 sas_target_priv_data->flags &= ~MPT_TARGET_FLAGS_RAID_COMPONENT;
5972
5973 starget_for_each_device(starget, no_uld_attach ? (void *)1 : NULL,
5974 _scsih_reprobe_lun);
5975}
5976/**
5977 * _scsih_sas_volume_add - add new volume 5984 * _scsih_sas_volume_add - add new volume
5978 * @ioc: per adapter object 5985 * @ioc: per adapter object
5979 * @element: IR config element data 5986 * @element: IR config element data
@@ -6024,8 +6031,11 @@ _scsih_sas_volume_add(struct MPT2SAS_ADAPTER *ioc,
6024 raid_device->id, 0); 6031 raid_device->id, 0);
6025 if (rc) 6032 if (rc)
6026 _scsih_raid_device_remove(ioc, raid_device); 6033 _scsih_raid_device_remove(ioc, raid_device);
6027 } else 6034 } else {
6035 spin_lock_irqsave(&ioc->raid_device_lock, flags);
6028 _scsih_determine_boot_device(ioc, raid_device, 1); 6036 _scsih_determine_boot_device(ioc, raid_device, 1);
6037 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
6038 }
6029} 6039}
6030 6040
6031/** 6041/**
@@ -6042,21 +6052,25 @@ _scsih_sas_volume_delete(struct MPT2SAS_ADAPTER *ioc, u16 handle)
6042 struct _raid_device *raid_device; 6052 struct _raid_device *raid_device;
6043 unsigned long flags; 6053 unsigned long flags;
6044 struct MPT2SAS_TARGET *sas_target_priv_data; 6054 struct MPT2SAS_TARGET *sas_target_priv_data;
6055 struct scsi_target *starget = NULL;
6045 6056
6046 spin_lock_irqsave(&ioc->raid_device_lock, flags); 6057 spin_lock_irqsave(&ioc->raid_device_lock, flags);
6047 raid_device = _scsih_raid_device_find_by_handle(ioc, handle); 6058 raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
6048 spin_unlock_irqrestore(&ioc->raid_device_lock, flags); 6059 if (raid_device) {
6049 if (!raid_device) 6060 if (raid_device->starget) {
6050 return; 6061 starget = raid_device->starget;
6051 if (raid_device->starget) { 6062 sas_target_priv_data = starget->hostdata;
6052 sas_target_priv_data = raid_device->starget->hostdata; 6063 sas_target_priv_data->deleted = 1;
6053 sas_target_priv_data->deleted = 1; 6064 }
6054 scsi_remove_target(&raid_device->starget->dev); 6065 printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), wwid"
6066 "(0x%016llx)\n", ioc->name, raid_device->handle,
6067 (unsigned long long) raid_device->wwid);
6068 list_del(&raid_device->list);
6069 kfree(raid_device);
6055 } 6070 }
6056 printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), wwid" 6071 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
6057 "(0x%016llx)\n", ioc->name, raid_device->handle, 6072 if (starget)
6058 (unsigned long long) raid_device->wwid); 6073 scsi_remove_target(&starget->dev);
6059 _scsih_raid_device_remove(ioc, raid_device);
6060} 6074}
6061 6075
6062/** 6076/**
@@ -6072,20 +6086,31 @@ _scsih_sas_pd_expose(struct MPT2SAS_ADAPTER *ioc,
6072 Mpi2EventIrConfigElement_t *element) 6086 Mpi2EventIrConfigElement_t *element)
6073{ 6087{
6074 struct _sas_device *sas_device; 6088 struct _sas_device *sas_device;
6089 struct scsi_target *starget = NULL;
6090 struct MPT2SAS_TARGET *sas_target_priv_data;
6075 unsigned long flags; 6091 unsigned long flags;
6076 u16 handle = le16_to_cpu(element->PhysDiskDevHandle); 6092 u16 handle = le16_to_cpu(element->PhysDiskDevHandle);
6077 6093
6078 spin_lock_irqsave(&ioc->sas_device_lock, flags); 6094 spin_lock_irqsave(&ioc->sas_device_lock, flags);
6079 sas_device = _scsih_sas_device_find_by_handle(ioc, handle); 6095 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
6096 if (sas_device) {
6097 sas_device->volume_handle = 0;
6098 sas_device->volume_wwid = 0;
6099 clear_bit(handle, ioc->pd_handles);
6100 if (sas_device->starget && sas_device->starget->hostdata) {
6101 starget = sas_device->starget;
6102 sas_target_priv_data = starget->hostdata;
6103 sas_target_priv_data->flags &=
6104 ~MPT_TARGET_FLAGS_RAID_COMPONENT;
6105 }
6106 }
6080 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 6107 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
6081 if (!sas_device) 6108 if (!sas_device)
6082 return; 6109 return;
6083 6110
6084 /* exposing raid component */ 6111 /* exposing raid component */
6085 sas_device->volume_handle = 0; 6112 if (starget)
6086 sas_device->volume_wwid = 0; 6113 starget_for_each_device(starget, NULL, _scsih_reprobe_lun);
6087 clear_bit(handle, ioc->pd_handles);
6088 _scsih_reprobe_target(sas_device->starget, 0);
6089} 6114}
6090 6115
6091/** 6116/**
@@ -6101,23 +6126,38 @@ _scsih_sas_pd_hide(struct MPT2SAS_ADAPTER *ioc,
6101 Mpi2EventIrConfigElement_t *element) 6126 Mpi2EventIrConfigElement_t *element)
6102{ 6127{
6103 struct _sas_device *sas_device; 6128 struct _sas_device *sas_device;
6129 struct scsi_target *starget = NULL;
6130 struct MPT2SAS_TARGET *sas_target_priv_data;
6104 unsigned long flags; 6131 unsigned long flags;
6105 u16 handle = le16_to_cpu(element->PhysDiskDevHandle); 6132 u16 handle = le16_to_cpu(element->PhysDiskDevHandle);
6133 u16 volume_handle = 0;
6134 u64 volume_wwid = 0;
6135
6136 mpt2sas_config_get_volume_handle(ioc, handle, &volume_handle);
6137 if (volume_handle)
6138 mpt2sas_config_get_volume_wwid(ioc, volume_handle,
6139 &volume_wwid);
6106 6140
6107 spin_lock_irqsave(&ioc->sas_device_lock, flags); 6141 spin_lock_irqsave(&ioc->sas_device_lock, flags);
6108 sas_device = _scsih_sas_device_find_by_handle(ioc, handle); 6142 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
6143 if (sas_device) {
6144 set_bit(handle, ioc->pd_handles);
6145 if (sas_device->starget && sas_device->starget->hostdata) {
6146 starget = sas_device->starget;
6147 sas_target_priv_data = starget->hostdata;
6148 sas_target_priv_data->flags |=
6149 MPT_TARGET_FLAGS_RAID_COMPONENT;
6150 sas_device->volume_handle = volume_handle;
6151 sas_device->volume_wwid = volume_wwid;
6152 }
6153 }
6109 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 6154 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
6110 if (!sas_device) 6155 if (!sas_device)
6111 return; 6156 return;
6112 6157
6113 /* hiding raid component */ 6158 /* hiding raid component */
6114 mpt2sas_config_get_volume_handle(ioc, handle, 6159 if (starget)
6115 &sas_device->volume_handle); 6160 starget_for_each_device(starget, (void *)1, _scsih_reprobe_lun);
6116 mpt2sas_config_get_volume_wwid(ioc, sas_device->volume_handle,
6117 &sas_device->volume_wwid);
6118 set_bit(handle, ioc->pd_handles);
6119 _scsih_reprobe_target(sas_device->starget, 1);
6120
6121} 6161}
6122 6162
6123/** 6163/**
@@ -6132,16 +6172,9 @@ static void
6132_scsih_sas_pd_delete(struct MPT2SAS_ADAPTER *ioc, 6172_scsih_sas_pd_delete(struct MPT2SAS_ADAPTER *ioc,
6133 Mpi2EventIrConfigElement_t *element) 6173 Mpi2EventIrConfigElement_t *element)
6134{ 6174{
6135 struct _sas_device *sas_device;
6136 unsigned long flags;
6137 u16 handle = le16_to_cpu(element->PhysDiskDevHandle); 6175 u16 handle = le16_to_cpu(element->PhysDiskDevHandle);
6138 6176
6139 spin_lock_irqsave(&ioc->sas_device_lock, flags); 6177 _scsih_device_remove_by_handle(ioc, handle);
6140 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
6141 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
6142 if (!sas_device)
6143 return;
6144 _scsih_remove_device(ioc, sas_device);
6145} 6178}
6146 6179
6147/** 6180/**
@@ -6583,18 +6616,13 @@ _scsih_sas_ir_operation_status_event(struct MPT2SAS_ADAPTER *ioc,
6583 /* code added for raid transport support */ 6616 /* code added for raid transport support */
6584 if (event_data->RAIDOperation == MPI2_EVENT_IR_RAIDOP_RESYNC) { 6617 if (event_data->RAIDOperation == MPI2_EVENT_IR_RAIDOP_RESYNC) {
6585 6618
6586 handle = le16_to_cpu(event_data->VolDevHandle);
6587
6588 spin_lock_irqsave(&ioc->raid_device_lock, flags); 6619 spin_lock_irqsave(&ioc->raid_device_lock, flags);
6620 handle = le16_to_cpu(event_data->VolDevHandle);
6589 raid_device = _scsih_raid_device_find_by_handle(ioc, handle); 6621 raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
6590 spin_unlock_irqrestore(&ioc->raid_device_lock, flags); 6622 if (raid_device)
6591
6592 if (!raid_device)
6593 return;
6594
6595 if (event_data->RAIDOperation == MPI2_EVENT_IR_RAIDOP_RESYNC)
6596 raid_device->percent_complete = 6623 raid_device->percent_complete =
6597 event_data->PercentComplete; 6624 event_data->PercentComplete;
6625 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
6598 } 6626 }
6599} 6627}
6600 6628
@@ -6761,13 +6789,18 @@ _scsih_mark_responding_raid_device(struct MPT2SAS_ADAPTER *ioc, u64 wwid,
6761 * required data for Direct IO 6789 * required data for Direct IO
6762 */ 6790 */
6763 _scsih_init_warpdrive_properties(ioc, raid_device); 6791 _scsih_init_warpdrive_properties(ioc, raid_device);
6764 if (raid_device->handle == handle) 6792 spin_lock_irqsave(&ioc->raid_device_lock, flags);
6793 if (raid_device->handle == handle) {
6794 spin_unlock_irqrestore(&ioc->raid_device_lock,
6795 flags);
6765 return; 6796 return;
6797 }
6766 printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n", 6798 printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n",
6767 raid_device->handle); 6799 raid_device->handle);
6768 raid_device->handle = handle; 6800 raid_device->handle = handle;
6769 if (sas_target_priv_data) 6801 if (sas_target_priv_data)
6770 sas_target_priv_data->handle = handle; 6802 sas_target_priv_data->handle = handle;
6803 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
6771 return; 6804 return;
6772 } 6805 }
6773 } 6806 }
@@ -6939,58 +6972,56 @@ static void
6939_scsih_remove_unresponding_sas_devices(struct MPT2SAS_ADAPTER *ioc) 6972_scsih_remove_unresponding_sas_devices(struct MPT2SAS_ADAPTER *ioc)
6940{ 6973{
6941 struct _sas_device *sas_device, *sas_device_next; 6974 struct _sas_device *sas_device, *sas_device_next;
6942 struct _sas_node *sas_expander; 6975 struct _sas_node *sas_expander, *sas_expander_next;
6943 struct _raid_device *raid_device, *raid_device_next; 6976 struct _raid_device *raid_device, *raid_device_next;
6977 struct list_head tmp_list;
6978 unsigned long flags;
6944 6979
6945 printk(MPT2SAS_INFO_FMT "removing unresponding devices: start\n", 6980 printk(MPT2SAS_INFO_FMT "removing unresponding devices: start\n",
6946 ioc->name); 6981 ioc->name);
6947 6982
6983 /* removing unresponding end devices */
6984 printk(MPT2SAS_INFO_FMT "removing unresponding devices: end-devices\n",
6985 ioc->name);
6948 list_for_each_entry_safe(sas_device, sas_device_next, 6986 list_for_each_entry_safe(sas_device, sas_device_next,
6949 &ioc->sas_device_list, list) { 6987 &ioc->sas_device_list, list) {
6950 if (sas_device->responding) { 6988 if (!sas_device->responding)
6989 _scsih_device_remove_by_handle(ioc,
6990 sas_device->handle);
6991 else
6951 sas_device->responding = 0; 6992 sas_device->responding = 0;
6952 continue;
6953 }
6954 if (sas_device->starget)
6955 starget_printk(KERN_INFO, sas_device->starget,
6956 "removing: handle(0x%04x), sas_addr(0x%016llx), "
6957 "enclosure logical id(0x%016llx), slot(%d)\n",
6958 sas_device->handle,
6959 (unsigned long long)sas_device->sas_address,
6960 (unsigned long long)
6961 sas_device->enclosure_logical_id,
6962 sas_device->slot);
6963 _scsih_remove_device(ioc, sas_device);
6964 } 6993 }
6965 6994
6966 if (!ioc->ir_firmware) 6995 /* removing unresponding volumes */
6967 goto retry_expander_search; 6996 if (ioc->ir_firmware) {
6968 6997 printk(MPT2SAS_INFO_FMT "removing unresponding devices: "
6969 list_for_each_entry_safe(raid_device, raid_device_next, 6998 "volumes\n", ioc->name);
6970 &ioc->raid_device_list, list) { 6999 list_for_each_entry_safe(raid_device, raid_device_next,
6971 if (raid_device->responding) { 7000 &ioc->raid_device_list, list) {
6972 raid_device->responding = 0; 7001 if (!raid_device->responding)
6973 continue; 7002 _scsih_sas_volume_delete(ioc,
6974 } 7003 raid_device->handle);
6975 if (raid_device->starget) { 7004 else
6976 starget_printk(KERN_INFO, raid_device->starget, 7005 raid_device->responding = 0;
6977 "removing: handle(0x%04x), wwid(0x%016llx)\n",
6978 raid_device->handle,
6979 (unsigned long long)raid_device->wwid);
6980 scsi_remove_target(&raid_device->starget->dev);
6981 } 7006 }
6982 _scsih_raid_device_remove(ioc, raid_device);
6983 } 7007 }
6984 7008 /* removing unresponding expanders */
6985 retry_expander_search: 7009 printk(MPT2SAS_INFO_FMT "removing unresponding devices: expanders\n",
6986 sas_expander = NULL; 7010 ioc->name);
6987 list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) { 7011 spin_lock_irqsave(&ioc->sas_node_lock, flags);
6988 if (sas_expander->responding) { 7012 INIT_LIST_HEAD(&tmp_list);
7013 list_for_each_entry_safe(sas_expander, sas_expander_next,
7014 &ioc->sas_expander_list, list) {
7015 if (!sas_expander->responding)
7016 list_move_tail(&sas_expander->list, &tmp_list);
7017 else
6989 sas_expander->responding = 0; 7018 sas_expander->responding = 0;
6990 continue; 7019 }
6991 } 7020 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
6992 mpt2sas_expander_remove(ioc, sas_expander->sas_address); 7021 list_for_each_entry_safe(sas_expander, sas_expander_next, &tmp_list,
6993 goto retry_expander_search; 7022 list) {
7023 list_del(&sas_expander->list);
7024 _scsih_expander_node_remove(ioc, sas_expander);
6994 } 7025 }
6995 printk(MPT2SAS_INFO_FMT "removing unresponding devices: complete\n", 7026 printk(MPT2SAS_INFO_FMT "removing unresponding devices: complete\n",
6996 ioc->name); 7027 ioc->name);
@@ -7043,6 +7074,7 @@ _scsih_scan_for_devices_after_reset(struct MPT2SAS_ADAPTER *ioc)
7043 struct _sas_device *sas_device; 7074 struct _sas_device *sas_device;
7044 struct _sas_node *expander_device; 7075 struct _sas_node *expander_device;
7045 static struct _raid_device *raid_device; 7076 static struct _raid_device *raid_device;
7077 unsigned long flags;
7046 7078
7047 printk(MPT2SAS_INFO_FMT "scan devices: start\n", ioc->name); 7079 printk(MPT2SAS_INFO_FMT "scan devices: start\n", ioc->name);
7048 7080
@@ -7057,8 +7089,10 @@ _scsih_scan_for_devices_after_reset(struct MPT2SAS_ADAPTER *ioc)
7057 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) 7089 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
7058 break; 7090 break;
7059 handle = le16_to_cpu(expander_pg0.DevHandle); 7091 handle = le16_to_cpu(expander_pg0.DevHandle);
7092 spin_lock_irqsave(&ioc->sas_node_lock, flags);
7060 expander_device = mpt2sas_scsih_expander_find_by_sas_address( 7093 expander_device = mpt2sas_scsih_expander_find_by_sas_address(
7061 ioc, le64_to_cpu(expander_pg0.SASAddress)); 7094 ioc, le64_to_cpu(expander_pg0.SASAddress));
7095 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
7062 if (expander_device) 7096 if (expander_device)
7063 _scsih_refresh_expander_links(ioc, expander_device, 7097 _scsih_refresh_expander_links(ioc, expander_device,
7064 handle); 7098 handle);
@@ -7080,7 +7114,9 @@ _scsih_scan_for_devices_after_reset(struct MPT2SAS_ADAPTER *ioc)
7080 break; 7114 break;
7081 phys_disk_num = pd_pg0.PhysDiskNum; 7115 phys_disk_num = pd_pg0.PhysDiskNum;
7082 handle = le16_to_cpu(pd_pg0.DevHandle); 7116 handle = le16_to_cpu(pd_pg0.DevHandle);
7117 spin_lock_irqsave(&ioc->sas_device_lock, flags);
7083 sas_device = _scsih_sas_device_find_by_handle(ioc, handle); 7118 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
7119 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
7084 if (sas_device) 7120 if (sas_device)
7085 continue; 7121 continue;
7086 if (mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, 7122 if (mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply,
@@ -7107,8 +7143,10 @@ _scsih_scan_for_devices_after_reset(struct MPT2SAS_ADAPTER *ioc)
7107 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) 7143 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
7108 break; 7144 break;
7109 handle = le16_to_cpu(volume_pg1.DevHandle); 7145 handle = le16_to_cpu(volume_pg1.DevHandle);
7146 spin_lock_irqsave(&ioc->raid_device_lock, flags);
7110 raid_device = _scsih_raid_device_find_by_wwid(ioc, 7147 raid_device = _scsih_raid_device_find_by_wwid(ioc,
7111 le64_to_cpu(volume_pg1.WWID)); 7148 le64_to_cpu(volume_pg1.WWID));
7149 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
7112 if (raid_device) 7150 if (raid_device)
7113 continue; 7151 continue;
7114 if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, 7152 if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply,
@@ -7140,8 +7178,10 @@ _scsih_scan_for_devices_after_reset(struct MPT2SAS_ADAPTER *ioc)
7140 if (!(_scsih_is_end_device( 7178 if (!(_scsih_is_end_device(
7141 le32_to_cpu(sas_device_pg0.DeviceInfo)))) 7179 le32_to_cpu(sas_device_pg0.DeviceInfo))))
7142 continue; 7180 continue;
7181 spin_lock_irqsave(&ioc->sas_device_lock, flags);
7143 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, 7182 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
7144 le64_to_cpu(sas_device_pg0.SASAddress)); 7183 le64_to_cpu(sas_device_pg0.SASAddress));
7184 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
7145 if (sas_device) 7185 if (sas_device)
7146 continue; 7186 continue;
7147 parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle); 7187 parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle);
@@ -7235,7 +7275,7 @@ _firmware_event_work(struct work_struct *work)
7235 7275
7236 switch (fw_event->event) { 7276 switch (fw_event->event) {
7237 case MPT2SAS_REMOVE_UNRESPONDING_DEVICES: 7277 case MPT2SAS_REMOVE_UNRESPONDING_DEVICES:
7238 while (scsi_host_in_recovery(ioc->shost)) 7278 while (scsi_host_in_recovery(ioc->shost) || ioc->shost_recovery)
7239 ssleep(1); 7279 ssleep(1);
7240 _scsih_remove_unresponding_sas_devices(ioc); 7280 _scsih_remove_unresponding_sas_devices(ioc);
7241 _scsih_scan_for_devices_after_reset(ioc); 7281 _scsih_scan_for_devices_after_reset(ioc);
@@ -7487,7 +7527,7 @@ _scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc,
7487 return; 7527 return;
7488 if (mpt2sas_port->remote_identify.device_type == 7528 if (mpt2sas_port->remote_identify.device_type ==
7489 SAS_END_DEVICE) 7529 SAS_END_DEVICE)
7490 mpt2sas_device_remove(ioc, 7530 mpt2sas_device_remove_by_sas_address(ioc,
7491 mpt2sas_port->remote_identify.sas_address); 7531 mpt2sas_port->remote_identify.sas_address);
7492 else if (mpt2sas_port->remote_identify.device_type == 7532 else if (mpt2sas_port->remote_identify.device_type ==
7493 SAS_EDGE_EXPANDER_DEVICE || 7533 SAS_EDGE_EXPANDER_DEVICE ||
@@ -7661,7 +7701,7 @@ _scsih_remove(struct pci_dev *pdev)
7661 &ioc->sas_hba.sas_port_list, port_list) { 7701 &ioc->sas_hba.sas_port_list, port_list) {
7662 if (mpt2sas_port->remote_identify.device_type == 7702 if (mpt2sas_port->remote_identify.device_type ==
7663 SAS_END_DEVICE) 7703 SAS_END_DEVICE)
7664 mpt2sas_device_remove(ioc, 7704 mpt2sas_device_remove_by_sas_address(ioc,
7665 mpt2sas_port->remote_identify.sas_address); 7705 mpt2sas_port->remote_identify.sas_address);
7666 else if (mpt2sas_port->remote_identify.device_type == 7706 else if (mpt2sas_port->remote_identify.device_type ==
7667 SAS_EDGE_EXPANDER_DEVICE || 7707 SAS_EDGE_EXPANDER_DEVICE ||
@@ -7733,11 +7773,11 @@ _scsih_probe_boot_devices(struct MPT2SAS_ADAPTER *ioc)
7733 if (rc) 7773 if (rc)
7734 _scsih_raid_device_remove(ioc, raid_device); 7774 _scsih_raid_device_remove(ioc, raid_device);
7735 } else { 7775 } else {
7776 spin_lock_irqsave(&ioc->sas_device_lock, flags);
7736 sas_device = device; 7777 sas_device = device;
7737 handle = sas_device->handle; 7778 handle = sas_device->handle;
7738 sas_address_parent = sas_device->sas_address_parent; 7779 sas_address_parent = sas_device->sas_address_parent;
7739 sas_address = sas_device->sas_address; 7780 sas_address = sas_device->sas_address;
7740 spin_lock_irqsave(&ioc->sas_device_lock, flags);
7741 list_move_tail(&sas_device->list, &ioc->sas_device_list); 7781 list_move_tail(&sas_device->list, &ioc->sas_device_list);
7742 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 7782 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
7743 7783
diff --git a/drivers/scsi/mpt2sas/mpt2sas_transport.c b/drivers/scsi/mpt2sas/mpt2sas_transport.c
index 8b2a3db9ea69..fed8b163afef 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_transport.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_transport.c
@@ -163,7 +163,7 @@ _transport_set_identify(struct MPT2SAS_ADAPTER *ioc, u16 handle,
163 return -EIO; 163 return -EIO;
164 } 164 }
165 165
166 memset(identify, 0, sizeof(*identify)); 166 memset(identify, 0, sizeof(struct sas_identify));
167 device_info = le32_to_cpu(sas_device_pg0.DeviceInfo); 167 device_info = le32_to_cpu(sas_device_pg0.DeviceInfo);
168 168
169 /* sas_address */ 169 /* sas_address */
@@ -484,7 +484,7 @@ _transport_delete_port(struct MPT2SAS_ADAPTER *ioc,
484 484
485 ioc->logging_level |= MPT_DEBUG_TRANSPORT; 485 ioc->logging_level |= MPT_DEBUG_TRANSPORT;
486 if (device_type == SAS_END_DEVICE) 486 if (device_type == SAS_END_DEVICE)
487 mpt2sas_device_remove(ioc, sas_address); 487 mpt2sas_device_remove_by_sas_address(ioc, sas_address);
488 else if (device_type == SAS_EDGE_EXPANDER_DEVICE || 488 else if (device_type == SAS_EDGE_EXPANDER_DEVICE ||
489 device_type == SAS_FANOUT_EXPANDER_DEVICE) 489 device_type == SAS_FANOUT_EXPANDER_DEVICE)
490 mpt2sas_expander_remove(ioc, sas_address); 490 mpt2sas_expander_remove(ioc, sas_address);
@@ -792,9 +792,10 @@ mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
792 spin_lock_irqsave(&ioc->sas_node_lock, flags); 792 spin_lock_irqsave(&ioc->sas_node_lock, flags);
793 sas_node = _transport_sas_node_find_by_sas_address(ioc, 793 sas_node = _transport_sas_node_find_by_sas_address(ioc,
794 sas_address_parent); 794 sas_address_parent);
795 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 795 if (!sas_node) {
796 if (!sas_node) 796 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
797 return; 797 return;
798 }
798 list_for_each_entry_safe(mpt2sas_port, next, &sas_node->sas_port_list, 799 list_for_each_entry_safe(mpt2sas_port, next, &sas_node->sas_port_list,
799 port_list) { 800 port_list) {
800 if (mpt2sas_port->remote_identify.sas_address != sas_address) 801 if (mpt2sas_port->remote_identify.sas_address != sas_address)
@@ -804,8 +805,10 @@ mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
804 goto out; 805 goto out;
805 } 806 }
806 out: 807 out:
807 if (!found) 808 if (!found) {
809 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
808 return; 810 return;
811 }
809 812
810 for (i = 0; i < sas_node->num_phys; i++) { 813 for (i = 0; i < sas_node->num_phys; i++) {
811 if (sas_node->phy[i].remote_identify.sas_address == sas_address) 814 if (sas_node->phy[i].remote_identify.sas_address == sas_address)
@@ -813,6 +816,7 @@ mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
813 sizeof(struct sas_identify)); 816 sizeof(struct sas_identify));
814 } 817 }
815 818
819 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
816 list_for_each_entry_safe(mpt2sas_phy, next_phy, 820 list_for_each_entry_safe(mpt2sas_phy, next_phy,
817 &mpt2sas_port->phy_list, port_siblings) { 821 &mpt2sas_port->phy_list, port_siblings) {
818 if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) 822 if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
@@ -986,12 +990,14 @@ mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc,
986 990
987 spin_lock_irqsave(&ioc->sas_node_lock, flags); 991 spin_lock_irqsave(&ioc->sas_node_lock, flags);
988 sas_node = _transport_sas_node_find_by_sas_address(ioc, sas_address); 992 sas_node = _transport_sas_node_find_by_sas_address(ioc, sas_address);
989 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 993 if (!sas_node) {
990 if (!sas_node) 994 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
991 return; 995 return;
996 }
992 997
993 mpt2sas_phy = &sas_node->phy[phy_number]; 998 mpt2sas_phy = &sas_node->phy[phy_number];
994 mpt2sas_phy->attached_handle = handle; 999 mpt2sas_phy->attached_handle = handle;
1000 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
995 if (handle && (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)) { 1001 if (handle && (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)) {
996 _transport_set_identify(ioc, handle, 1002 _transport_set_identify(ioc, handle,
997 &mpt2sas_phy->remote_identify); 1003 &mpt2sas_phy->remote_identify);
@@ -1310,17 +1316,20 @@ _transport_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
1310 struct MPT2SAS_ADAPTER *ioc = rphy_to_ioc(rphy); 1316 struct MPT2SAS_ADAPTER *ioc = rphy_to_ioc(rphy);
1311 struct _sas_device *sas_device; 1317 struct _sas_device *sas_device;
1312 unsigned long flags; 1318 unsigned long flags;
1319 int rc;
1313 1320
1314 spin_lock_irqsave(&ioc->sas_device_lock, flags); 1321 spin_lock_irqsave(&ioc->sas_device_lock, flags);
1315 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, 1322 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
1316 rphy->identify.sas_address); 1323 rphy->identify.sas_address);
1324 if (sas_device) {
1325 *identifier = sas_device->enclosure_logical_id;
1326 rc = 0;
1327 } else {
1328 *identifier = 0;
1329 rc = -ENXIO;
1330 }
1317 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 1331 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
1318 1332 return rc;
1319 if (!sas_device)
1320 return -ENXIO;
1321
1322 *identifier = sas_device->enclosure_logical_id;
1323 return 0;
1324} 1333}
1325 1334
1326/** 1335/**
@@ -1335,16 +1344,17 @@ _transport_get_bay_identifier(struct sas_rphy *rphy)
1335 struct MPT2SAS_ADAPTER *ioc = rphy_to_ioc(rphy); 1344 struct MPT2SAS_ADAPTER *ioc = rphy_to_ioc(rphy);
1336 struct _sas_device *sas_device; 1345 struct _sas_device *sas_device;
1337 unsigned long flags; 1346 unsigned long flags;
1347 int rc;
1338 1348
1339 spin_lock_irqsave(&ioc->sas_device_lock, flags); 1349 spin_lock_irqsave(&ioc->sas_device_lock, flags);
1340 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, 1350 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
1341 rphy->identify.sas_address); 1351 rphy->identify.sas_address);
1352 if (sas_device)
1353 rc = sas_device->slot;
1354 else
1355 rc = -ENXIO;
1342 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 1356 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
1343 1357 return rc;
1344 if (!sas_device)
1345 return -ENXIO;
1346
1347 return sas_device->slot;
1348} 1358}
1349 1359
1350/* phy control request structure */ 1360/* phy control request structure */