diff options
author | nagalakshmi.nandigama@lsi.com <nagalakshmi.nandigama@lsi.com> | 2012-03-20 02:36:50 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-04-23 14:27:15 -0400 |
commit | 09da0b32d078a3b94aa6d948d053b84755712a2b (patch) | |
tree | a77b0732b2c20c918b428686c17176e127ff460b /drivers | |
parent | acafc892b0c71bba8cb5f83b8dd5df4a3000be36 (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.c | 10 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_base.h | 6 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_scsih.c | 538 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_transport.c | 46 |
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, | |||
1058 | void mpt2sas_scsih_set_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle); | 1059 | void mpt2sas_scsih_set_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle); |
1059 | void mpt2sas_scsih_clear_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle); | 1060 | void mpt2sas_scsih_clear_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle); |
1060 | void mpt2sas_expander_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address); | 1061 | void mpt2sas_expander_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address); |
1061 | void mpt2sas_device_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address); | 1062 | void mpt2sas_device_remove_by_sas_address(struct MPT2SAS_ADAPTER *ioc, |
1063 | u64 sas_address); | ||
1062 | struct _sas_node *mpt2sas_scsih_expander_find_by_handle(struct MPT2SAS_ADAPTER *ioc, | 1064 | struct _sas_node *mpt2sas_scsih_expander_find_by_handle(struct MPT2SAS_ADAPTER *ioc, |
1063 | u16 handle); | 1065 | u16 handle); |
1064 | struct _sas_node *mpt2sas_scsih_expander_find_by_sas_address(struct MPT2SAS_ADAPTER | 1066 | struct _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 | */ |
760 | static void | 757 | static 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 | */ |
1471 | static void | 1468 | static 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 | */ |
1625 | static void | 1638 | static 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 | */ | ||
5340 | static 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 | */ |
5329 | void | 5365 | void |
5330 | mpt2sas_device_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address) | 5366 | mpt2sas_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 | **/ | ||
5960 | static 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 */ |