diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-02 22:01:32 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-02 22:01:32 -0400 |
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 @@ | |||
24 | 24 | ||
25 | #include <linux/scatterlist.h> | 25 | #include <linux/scatterlist.h> |
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <linux/async.h> | ||
27 | #include <scsi/scsi_host.h> | 28 | #include <scsi/scsi_host.h> |
28 | #include <scsi/scsi_eh.h> | 29 | #include <scsi/scsi_eh.h> |
29 | #include "sas_internal.h" | 30 | #include "sas_internal.h" |
@@ -180,16 +181,18 @@ int sas_notify_lldd_dev_found(struct domain_device *dev) | |||
180 | struct Scsi_Host *shost = sas_ha->core.shost; | 181 | struct Scsi_Host *shost = sas_ha->core.shost; |
181 | struct sas_internal *i = to_sas_internal(shost->transportt); | 182 | struct sas_internal *i = to_sas_internal(shost->transportt); |
182 | 183 | ||
183 | if (i->dft->lldd_dev_found) { | 184 | if (!i->dft->lldd_dev_found) |
184 | res = i->dft->lldd_dev_found(dev); | 185 | return 0; |
185 | if (res) { | 186 | |
186 | printk("sas: driver on pcidev %s cannot handle " | 187 | res = i->dft->lldd_dev_found(dev); |
187 | "device %llx, error:%d\n", | 188 | if (res) { |
188 | dev_name(sas_ha->dev), | 189 | printk("sas: driver on pcidev %s cannot handle " |
189 | SAS_ADDR(dev->sas_addr), res); | 190 | "device %llx, error:%d\n", |
190 | } | 191 | dev_name(sas_ha->dev), |
191 | kref_get(&dev->kref); | 192 | SAS_ADDR(dev->sas_addr), res); |
192 | } | 193 | } |
194 | set_bit(SAS_DEV_FOUND, &dev->state); | ||
195 | kref_get(&dev->kref); | ||
193 | return res; | 196 | return res; |
194 | } | 197 | } |
195 | 198 | ||
@@ -200,7 +203,10 @@ void sas_notify_lldd_dev_gone(struct domain_device *dev) | |||
200 | struct Scsi_Host *shost = sas_ha->core.shost; | 203 | struct Scsi_Host *shost = sas_ha->core.shost; |
201 | struct sas_internal *i = to_sas_internal(shost->transportt); | 204 | struct sas_internal *i = to_sas_internal(shost->transportt); |
202 | 205 | ||
203 | if (i->dft->lldd_dev_gone) { | 206 | if (!i->dft->lldd_dev_gone) |
207 | return; | ||
208 | |||
209 | if (test_and_clear_bit(SAS_DEV_FOUND, &dev->state)) { | ||
204 | i->dft->lldd_dev_gone(dev); | 210 | i->dft->lldd_dev_gone(dev); |
205 | sas_put_device(dev); | 211 | sas_put_device(dev); |
206 | } | 212 | } |
@@ -234,6 +240,47 @@ static void sas_probe_devices(struct work_struct *work) | |||
234 | } | 240 | } |
235 | } | 241 | } |
236 | 242 | ||
243 | static void sas_suspend_devices(struct work_struct *work) | ||
244 | { | ||
245 | struct asd_sas_phy *phy; | ||
246 | struct domain_device *dev; | ||
247 | struct sas_discovery_event *ev = to_sas_discovery_event(work); | ||
248 | struct asd_sas_port *port = ev->port; | ||
249 | struct Scsi_Host *shost = port->ha->core.shost; | ||
250 | struct sas_internal *si = to_sas_internal(shost->transportt); | ||
251 | |||
252 | clear_bit(DISCE_SUSPEND, &port->disc.pending); | ||
253 | |||
254 | sas_suspend_sata(port); | ||
255 | |||
256 | /* lldd is free to forget the domain_device across the | ||
257 | * suspension, we force the issue here to keep the reference | ||
258 | * counts aligned | ||
259 | */ | ||
260 | list_for_each_entry(dev, &port->dev_list, dev_list_node) | ||
261 | sas_notify_lldd_dev_gone(dev); | ||
262 | |||
263 | /* we are suspending, so we know events are disabled and | ||
264 | * phy_list is not being mutated | ||
265 | */ | ||
266 | list_for_each_entry(phy, &port->phy_list, port_phy_el) { | ||
267 | if (si->dft->lldd_port_formed) | ||
268 | si->dft->lldd_port_deformed(phy); | ||
269 | phy->suspended = 1; | ||
270 | port->suspended = 1; | ||
271 | } | ||
272 | } | ||
273 | |||
274 | static void sas_resume_devices(struct work_struct *work) | ||
275 | { | ||
276 | struct sas_discovery_event *ev = to_sas_discovery_event(work); | ||
277 | struct asd_sas_port *port = ev->port; | ||
278 | |||
279 | clear_bit(DISCE_RESUME, &port->disc.pending); | ||
280 | |||
281 | sas_resume_sata(port); | ||
282 | } | ||
283 | |||
237 | /** | 284 | /** |
238 | * sas_discover_end_dev -- discover an end device (SSP, etc) | 285 | * sas_discover_end_dev -- discover an end device (SSP, etc) |
239 | * @end: pointer to domain device of interest | 286 | * @end: pointer to domain device of interest |
@@ -530,6 +577,8 @@ void sas_init_disc(struct sas_discovery *disc, struct asd_sas_port *port) | |||
530 | [DISCE_DISCOVER_DOMAIN] = sas_discover_domain, | 577 | [DISCE_DISCOVER_DOMAIN] = sas_discover_domain, |
531 | [DISCE_REVALIDATE_DOMAIN] = sas_revalidate_domain, | 578 | [DISCE_REVALIDATE_DOMAIN] = sas_revalidate_domain, |
532 | [DISCE_PROBE] = sas_probe_devices, | 579 | [DISCE_PROBE] = sas_probe_devices, |
580 | [DISCE_SUSPEND] = sas_suspend_devices, | ||
581 | [DISCE_RESUME] = sas_resume_devices, | ||
533 | [DISCE_DESTRUCT] = sas_destruct_devices, | 582 | [DISCE_DESTRUCT] = sas_destruct_devices, |
534 | }; | 583 | }; |
535 | 584 | ||