diff options
Diffstat (limited to 'drivers/scsi/libsas/sas_ata.c')
-rw-r--r-- | drivers/scsi/libsas/sas_ata.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index 03930a04a679..4beca66728b4 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c | |||
@@ -23,6 +23,7 @@ | |||
23 | 23 | ||
24 | #include <linux/scatterlist.h> | 24 | #include <linux/scatterlist.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/async.h> | ||
26 | 27 | ||
27 | #include <scsi/sas_ata.h> | 28 | #include <scsi/sas_ata.h> |
28 | #include "sas_internal.h" | 29 | #include "sas_internal.h" |
@@ -605,10 +606,21 @@ int sas_discover_sata(struct domain_device *dev) | |||
605 | return 0; | 606 | return 0; |
606 | } | 607 | } |
607 | 608 | ||
609 | static void async_sas_ata_eh(void *data, async_cookie_t cookie) | ||
610 | { | ||
611 | struct domain_device *dev = data; | ||
612 | struct ata_port *ap = dev->sata_dev.ap; | ||
613 | struct sas_ha_struct *ha = dev->port->ha; | ||
614 | |||
615 | ata_port_printk(ap, KERN_DEBUG, "sas eh calling libata port error handler"); | ||
616 | ata_scsi_port_error_handler(ha->core.shost, ap); | ||
617 | } | ||
618 | |||
608 | void sas_ata_strategy_handler(struct Scsi_Host *shost) | 619 | void sas_ata_strategy_handler(struct Scsi_Host *shost) |
609 | { | 620 | { |
610 | struct scsi_device *sdev; | 621 | struct scsi_device *sdev; |
611 | struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost); | 622 | struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost); |
623 | LIST_HEAD(async); | ||
612 | 624 | ||
613 | /* it's ok to defer revalidation events during ata eh, these | 625 | /* it's ok to defer revalidation events during ata eh, these |
614 | * disks are in one of three states: | 626 | * disks are in one of three states: |
@@ -622,14 +634,13 @@ void sas_ata_strategy_handler(struct Scsi_Host *shost) | |||
622 | 634 | ||
623 | shost_for_each_device(sdev, shost) { | 635 | shost_for_each_device(sdev, shost) { |
624 | struct domain_device *ddev = sdev_to_domain_dev(sdev); | 636 | struct domain_device *ddev = sdev_to_domain_dev(sdev); |
625 | struct ata_port *ap = ddev->sata_dev.ap; | ||
626 | 637 | ||
627 | if (!dev_is_sata(ddev)) | 638 | if (!dev_is_sata(ddev)) |
628 | continue; | 639 | continue; |
629 | 640 | ||
630 | ata_port_printk(ap, KERN_DEBUG, "sas eh calling libata port error handler"); | 641 | async_schedule_domain(async_sas_ata_eh, ddev, &async); |
631 | ata_scsi_port_error_handler(shost, ap); | ||
632 | } | 642 | } |
643 | async_synchronize_full_domain(&async); | ||
633 | 644 | ||
634 | sas_enable_revalidation(sas_ha); | 645 | sas_enable_revalidation(sas_ha); |
635 | } | 646 | } |