diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-02 19:01:32 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-02 19:01:32 -0700 |
commit | 3151367f8778a1789d6f6e6f6c642681b6cd6d64 (patch) | |
tree | 1869d5429a25abd994ae94079808b8db060ec6f3 /drivers/scsi/libsas/sas_discover.c | |
parent | 16642a2e7be23bbda013fc32d8f6c68982eab603 (diff) | |
parent | fe709ed827d370e6b0c0a9f9456da1c22bdcd118 (diff) |
Merge tag 'scsi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull first round of SCSI updates from James Bottomley:
"This is a large set of updates, mostly for drivers (qla2xxx [including
support for new 83xx based card], qla4xxx, mpt2sas, bfa, zfcp, hpsa,
be2iscsi, isci, lpfc, ipr, ibmvfc, ibmvscsi, megaraid_sas).
There's also a rework for tape adding virtually unlimited numbers of
tape drives plus a set of dif fixes for sd and a fix for a live lock
on hot remove of SCSI devices.
This round includes a signed tag pull of isci-for-3.6
Signed-off-by: James Bottomley <JBottomley@Parallels.com>"
Fix up trivial conflict in drivers/scsi/qla2xxx/qla_nx.c due to new PCI
helper function use in a function that was removed by this pull.
* tag 'scsi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (198 commits)
[SCSI] st: remove st_mutex
[SCSI] sd: Ensure we correctly disable devices with unknown protection type
[SCSI] hpsa: gen8plus Smart Array IDs
[SCSI] qla4xxx: Update driver version to 5.03.00-k1
[SCSI] qla4xxx: Disable generating pause frames for ISP83XX
[SCSI] qla4xxx: Fix double clearing of risc_intr for ISP83XX
[SCSI] qla4xxx: IDC implementation for Loopback
[SCSI] qla4xxx: update copyrights in LICENSE.qla4xxx
[SCSI] qla4xxx: Fix panic while rmmod
[SCSI] qla4xxx: Fail probe_adapter if IRQ allocation fails
[SCSI] qla4xxx: Prevent MSI/MSI-X falling back to INTx for ISP82XX
[SCSI] qla4xxx: Update idc reg in case of PCI AER
[SCSI] qla4xxx: Fix double IDC locking in qla4_8xxx_error_recovery
[SCSI] qla4xxx: Clear interrupt while unloading driver for ISP83XX
[SCSI] qla4xxx: Print correct IDC version
[SCSI] qla4xxx: Added new mbox cmd to pass driver version to FW
[SCSI] scsi_dh_alua: Enable STPG for unavailable ports
[SCSI] scsi_remove_target: fix softlockup regression on hot remove
[SCSI] ibmvscsi: Fix host config length field overflow
[SCSI] ibmvscsi: Remove backend abstraction
...
Diffstat (limited to 'drivers/scsi/libsas/sas_discover.c')
-rw-r--r-- | drivers/scsi/libsas/sas_discover.c | 69 |
1 files changed, 59 insertions, 10 deletions
diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c index 3e9dc1a84358..a0c3003e0c7d 100644 --- a/drivers/scsi/libsas/sas_discover.c +++ b/drivers/scsi/libsas/sas_discover.c @@ -24,6 +24,7 @@ #include <linux/scatterlist.h> #include <linux/slab.h> +#include <linux/async.h> #include <scsi/scsi_host.h> #include <scsi/scsi_eh.h> #include "sas_internal.h" @@ -180,16 +181,18 @@ int sas_notify_lldd_dev_found(struct domain_device *dev) struct Scsi_Host *shost = sas_ha->core.shost; struct sas_internal *i = to_sas_internal(shost->transportt); - if (i->dft->lldd_dev_found) { - res = i->dft->lldd_dev_found(dev); - if (res) { - printk("sas: driver on pcidev %s cannot handle " - "device %llx, error:%d\n", - dev_name(sas_ha->dev), - SAS_ADDR(dev->sas_addr), res); - } - kref_get(&dev->kref); + if (!i->dft->lldd_dev_found) + return 0; + + res = i->dft->lldd_dev_found(dev); + if (res) { + printk("sas: driver on pcidev %s cannot handle " + "device %llx, error:%d\n", + dev_name(sas_ha->dev), + SAS_ADDR(dev->sas_addr), res); } + set_bit(SAS_DEV_FOUND, &dev->state); + kref_get(&dev->kref); return res; } @@ -200,7 +203,10 @@ void sas_notify_lldd_dev_gone(struct domain_device *dev) struct Scsi_Host *shost = sas_ha->core.shost; struct sas_internal *i = to_sas_internal(shost->transportt); - if (i->dft->lldd_dev_gone) { + if (!i->dft->lldd_dev_gone) + return; + + if (test_and_clear_bit(SAS_DEV_FOUND, &dev->state)) { i->dft->lldd_dev_gone(dev); sas_put_device(dev); } @@ -234,6 +240,47 @@ static void sas_probe_devices(struct work_struct *work) } } +static void sas_suspend_devices(struct work_struct *work) +{ + struct asd_sas_phy *phy; + struct domain_device *dev; + struct sas_discovery_event *ev = to_sas_discovery_event(work); + struct asd_sas_port *port = ev->port; + struct Scsi_Host *shost = port->ha->core.shost; + struct sas_internal *si = to_sas_internal(shost->transportt); + + clear_bit(DISCE_SUSPEND, &port->disc.pending); + + sas_suspend_sata(port); + + /* lldd is free to forget the domain_device across the + * suspension, we force the issue here to keep the reference + * counts aligned + */ + list_for_each_entry(dev, &port->dev_list, dev_list_node) + sas_notify_lldd_dev_gone(dev); + + /* we are suspending, so we know events are disabled and + * phy_list is not being mutated + */ + list_for_each_entry(phy, &port->phy_list, port_phy_el) { + if (si->dft->lldd_port_formed) + si->dft->lldd_port_deformed(phy); + phy->suspended = 1; + port->suspended = 1; + } +} + +static void sas_resume_devices(struct work_struct *work) +{ + struct sas_discovery_event *ev = to_sas_discovery_event(work); + struct asd_sas_port *port = ev->port; + + clear_bit(DISCE_RESUME, &port->disc.pending); + + sas_resume_sata(port); +} + /** * sas_discover_end_dev -- discover an end device (SSP, etc) * @end: pointer to domain device of interest @@ -530,6 +577,8 @@ void sas_init_disc(struct sas_discovery *disc, struct asd_sas_port *port) [DISCE_DISCOVER_DOMAIN] = sas_discover_domain, [DISCE_REVALIDATE_DOMAIN] = sas_revalidate_domain, [DISCE_PROBE] = sas_probe_devices, + [DISCE_SUSPEND] = sas_suspend_devices, + [DISCE_RESUME] = sas_resume_devices, [DISCE_DESTRUCT] = sas_destruct_devices, }; |