diff options
author | Tejun Heo <htejun@gmail.com> | 2006-01-22 23:09:37 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2006-01-26 22:36:28 -0500 |
commit | a72ec4ce6d3ae92e76baf5b2c65cc26e5e775e83 (patch) | |
tree | f5a177cc30c9b39d8ae7dcad29d03d27534b9f78 | |
parent | 041c5fc33cb7ed4fe5322585a611fb6e29a05d3a (diff) |
[PATCH] libata: implement and apply ata_eh_qc_complete/retry()
Implement ata_eh_qc_complete/retry() using scsi_eh_finish_cmd() and
scsi_eh_flush_done_q(). This removes all eh scsicmd finish hacks from
low level drivers.
This change was first suggested by Jeff Garzik.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
-rw-r--r-- | drivers/scsi/ahci.c | 12 | ||||
-rw-r--r-- | drivers/scsi/libata-core.c | 14 | ||||
-rw-r--r-- | drivers/scsi/libata-scsi.c | 59 | ||||
-rw-r--r-- | drivers/scsi/sata_mv.c | 12 | ||||
-rw-r--r-- | drivers/scsi/sata_promise.c | 12 | ||||
-rw-r--r-- | drivers/scsi/sata_sil24.c | 10 | ||||
-rw-r--r-- | drivers/scsi/sata_sx4.c | 12 | ||||
-rw-r--r-- | include/linux/libata.h | 3 |
8 files changed, 70 insertions, 64 deletions
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index 0f6e4dd22901..5a6b23009897 100644 --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c | |||
@@ -672,19 +672,13 @@ static void ahci_eng_timeout(struct ata_port *ap) | |||
672 | ap->id); | 672 | ap->id); |
673 | } else { | 673 | } else { |
674 | ahci_restart_port(ap, readl(port_mmio + PORT_IRQ_STAT)); | 674 | ahci_restart_port(ap, readl(port_mmio + PORT_IRQ_STAT)); |
675 | |||
676 | /* hack alert! We cannot use the supplied completion | ||
677 | * function from inside the ->eh_strategy_handler() thread. | ||
678 | * libata is the only user of ->eh_strategy_handler() in | ||
679 | * any kernel, so the default scsi_done() assumes it is | ||
680 | * not being called from the SCSI EH. | ||
681 | */ | ||
682 | qc->scsidone = scsi_finish_command; | ||
683 | qc->err_mask |= AC_ERR_TIMEOUT; | 675 | qc->err_mask |= AC_ERR_TIMEOUT; |
684 | ata_qc_complete(qc); | ||
685 | } | 676 | } |
686 | 677 | ||
687 | spin_unlock_irqrestore(&host_set->lock, flags); | 678 | spin_unlock_irqrestore(&host_set->lock, flags); |
679 | |||
680 | if (qc) | ||
681 | ata_eh_qc_complete(qc); | ||
688 | } | 682 | } |
689 | 683 | ||
690 | static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc) | 684 | static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc) |
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index b29bf0dc948a..93ae2dcc837c 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -3449,14 +3449,6 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc) | |||
3449 | 3449 | ||
3450 | spin_lock_irqsave(&host_set->lock, flags); | 3450 | spin_lock_irqsave(&host_set->lock, flags); |
3451 | 3451 | ||
3452 | /* hack alert! We cannot use the supplied completion | ||
3453 | * function from inside the ->eh_strategy_handler() thread. | ||
3454 | * libata is the only user of ->eh_strategy_handler() in | ||
3455 | * any kernel, so the default scsi_done() assumes it is | ||
3456 | * not being called from the SCSI EH. | ||
3457 | */ | ||
3458 | qc->scsidone = scsi_finish_command; | ||
3459 | |||
3460 | switch (qc->tf.protocol) { | 3452 | switch (qc->tf.protocol) { |
3461 | 3453 | ||
3462 | case ATA_PROT_DMA: | 3454 | case ATA_PROT_DMA: |
@@ -3480,12 +3472,13 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc) | |||
3480 | 3472 | ||
3481 | /* complete taskfile transaction */ | 3473 | /* complete taskfile transaction */ |
3482 | qc->err_mask |= ac_err_mask(drv_stat); | 3474 | qc->err_mask |= ac_err_mask(drv_stat); |
3483 | ata_qc_complete(qc); | ||
3484 | break; | 3475 | break; |
3485 | } | 3476 | } |
3486 | 3477 | ||
3487 | spin_unlock_irqrestore(&host_set->lock, flags); | 3478 | spin_unlock_irqrestore(&host_set->lock, flags); |
3488 | 3479 | ||
3480 | ata_eh_qc_complete(qc); | ||
3481 | |||
3489 | DPRINTK("EXIT\n"); | 3482 | DPRINTK("EXIT\n"); |
3490 | } | 3483 | } |
3491 | 3484 | ||
@@ -4422,6 +4415,7 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host, | |||
4422 | 4415 | ||
4423 | INIT_WORK(&ap->packet_task, atapi_packet_task, ap); | 4416 | INIT_WORK(&ap->packet_task, atapi_packet_task, ap); |
4424 | INIT_WORK(&ap->pio_task, ata_pio_task, ap); | 4417 | INIT_WORK(&ap->pio_task, ata_pio_task, ap); |
4418 | INIT_LIST_HEAD(&ap->eh_done_q); | ||
4425 | 4419 | ||
4426 | for (i = 0; i < ATA_MAX_DEVICES; i++) | 4420 | for (i = 0; i < ATA_MAX_DEVICES; i++) |
4427 | ap->device[i].devno = i; | 4421 | ap->device[i].devno = i; |
@@ -5165,6 +5159,8 @@ EXPORT_SYMBOL_GPL(ata_dev_classify); | |||
5165 | EXPORT_SYMBOL_GPL(ata_dev_id_string); | 5159 | EXPORT_SYMBOL_GPL(ata_dev_id_string); |
5166 | EXPORT_SYMBOL_GPL(ata_dev_config); | 5160 | EXPORT_SYMBOL_GPL(ata_dev_config); |
5167 | EXPORT_SYMBOL_GPL(ata_scsi_simulate); | 5161 | EXPORT_SYMBOL_GPL(ata_scsi_simulate); |
5162 | EXPORT_SYMBOL_GPL(ata_eh_qc_complete); | ||
5163 | EXPORT_SYMBOL_GPL(ata_eh_qc_retry); | ||
5168 | 5164 | ||
5169 | EXPORT_SYMBOL_GPL(ata_pio_need_iordy); | 5165 | EXPORT_SYMBOL_GPL(ata_pio_need_iordy); |
5170 | EXPORT_SYMBOL_GPL(ata_timing_compute); | 5166 | EXPORT_SYMBOL_GPL(ata_timing_compute); |
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index 95e3c278dd43..ab6b53349d6f 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c | |||
@@ -738,17 +738,64 @@ int ata_scsi_error(struct Scsi_Host *host) | |||
738 | ap = (struct ata_port *) &host->hostdata[0]; | 738 | ap = (struct ata_port *) &host->hostdata[0]; |
739 | ap->ops->eng_timeout(ap); | 739 | ap->ops->eng_timeout(ap); |
740 | 740 | ||
741 | /* TODO: this is per-command; when queueing is supported | 741 | assert(host->host_failed == 0 && list_empty(&host->eh_cmd_q)); |
742 | * this code will either change or move to a more | 742 | |
743 | * appropriate place | 743 | scsi_eh_flush_done_q(&ap->eh_done_q); |
744 | */ | ||
745 | host->host_failed--; | ||
746 | INIT_LIST_HEAD(&host->eh_cmd_q); | ||
747 | 744 | ||
748 | DPRINTK("EXIT\n"); | 745 | DPRINTK("EXIT\n"); |
749 | return 0; | 746 | return 0; |
750 | } | 747 | } |
751 | 748 | ||
749 | static void ata_eh_scsidone(struct scsi_cmnd *scmd) | ||
750 | { | ||
751 | /* nada */ | ||
752 | } | ||
753 | |||
754 | static void __ata_eh_qc_complete(struct ata_queued_cmd *qc) | ||
755 | { | ||
756 | struct ata_port *ap = qc->ap; | ||
757 | struct scsi_cmnd *scmd = qc->scsicmd; | ||
758 | unsigned long flags; | ||
759 | |||
760 | spin_lock_irqsave(&ap->host_set->lock, flags); | ||
761 | qc->scsidone = ata_eh_scsidone; | ||
762 | ata_qc_complete(qc); | ||
763 | assert(!ata_tag_valid(qc->tag)); | ||
764 | spin_unlock_irqrestore(&ap->host_set->lock, flags); | ||
765 | |||
766 | scsi_eh_finish_cmd(scmd, &ap->eh_done_q); | ||
767 | } | ||
768 | |||
769 | /** | ||
770 | * ata_eh_qc_complete - Complete an active ATA command from EH | ||
771 | * @qc: Command to complete | ||
772 | * | ||
773 | * Indicate to the mid and upper layers that an ATA command has | ||
774 | * completed. To be used from EH. | ||
775 | */ | ||
776 | void ata_eh_qc_complete(struct ata_queued_cmd *qc) | ||
777 | { | ||
778 | struct scsi_cmnd *scmd = qc->scsicmd; | ||
779 | scmd->retries = scmd->allowed; | ||
780 | __ata_eh_qc_complete(qc); | ||
781 | } | ||
782 | |||
783 | /** | ||
784 | * ata_eh_qc_retry - Tell midlayer to retry an ATA command after EH | ||
785 | * @qc: Command to retry | ||
786 | * | ||
787 | * Indicate to the mid and upper layers that an ATA command | ||
788 | * should be retried. To be used from EH. | ||
789 | * | ||
790 | * SCSI midlayer limits the number of retries to scmd->allowed. | ||
791 | * This function might need to adjust scmd->retries for commands | ||
792 | * which get retried due to unrelated NCQ failures. | ||
793 | */ | ||
794 | void ata_eh_qc_retry(struct ata_queued_cmd *qc) | ||
795 | { | ||
796 | __ata_eh_qc_complete(qc); | ||
797 | } | ||
798 | |||
752 | /** | 799 | /** |
753 | * ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command | 800 | * ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command |
754 | * @qc: Storage for translated ATA taskfile | 801 | * @qc: Storage for translated ATA taskfile |
diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c index 281223a0e45f..d9a554ca45c7 100644 --- a/drivers/scsi/sata_mv.c +++ b/drivers/scsi/sata_mv.c | |||
@@ -1839,7 +1839,6 @@ static void mv_phy_reset(struct ata_port *ap) | |||
1839 | static void mv_eng_timeout(struct ata_port *ap) | 1839 | static void mv_eng_timeout(struct ata_port *ap) |
1840 | { | 1840 | { |
1841 | struct ata_queued_cmd *qc; | 1841 | struct ata_queued_cmd *qc; |
1842 | unsigned long flags; | ||
1843 | 1842 | ||
1844 | printk(KERN_ERR "ata%u: Entering mv_eng_timeout\n",ap->id); | 1843 | printk(KERN_ERR "ata%u: Entering mv_eng_timeout\n",ap->id); |
1845 | DPRINTK("All regs @ start of eng_timeout\n"); | 1844 | DPRINTK("All regs @ start of eng_timeout\n"); |
@@ -1858,17 +1857,8 @@ static void mv_eng_timeout(struct ata_port *ap) | |||
1858 | printk(KERN_ERR "ata%u: BUG: timeout without command\n", | 1857 | printk(KERN_ERR "ata%u: BUG: timeout without command\n", |
1859 | ap->id); | 1858 | ap->id); |
1860 | } else { | 1859 | } else { |
1861 | /* hack alert! We cannot use the supplied completion | ||
1862 | * function from inside the ->eh_strategy_handler() thread. | ||
1863 | * libata is the only user of ->eh_strategy_handler() in | ||
1864 | * any kernel, so the default scsi_done() assumes it is | ||
1865 | * not being called from the SCSI EH. | ||
1866 | */ | ||
1867 | spin_lock_irqsave(&ap->host_set->lock, flags); | ||
1868 | qc->scsidone = scsi_finish_command; | ||
1869 | qc->err_mask |= AC_ERR_TIMEOUT; | 1860 | qc->err_mask |= AC_ERR_TIMEOUT; |
1870 | ata_qc_complete(qc); | 1861 | ata_eh_qc_complete(qc); |
1871 | spin_unlock_irqrestore(&ap->host_set->lock, flags); | ||
1872 | } | 1862 | } |
1873 | } | 1863 | } |
1874 | 1864 | ||
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c index bac36d5b7c3e..77ef646b0f92 100644 --- a/drivers/scsi/sata_promise.c +++ b/drivers/scsi/sata_promise.c | |||
@@ -400,21 +400,12 @@ static void pdc_eng_timeout(struct ata_port *ap) | |||
400 | goto out; | 400 | goto out; |
401 | } | 401 | } |
402 | 402 | ||
403 | /* hack alert! We cannot use the supplied completion | ||
404 | * function from inside the ->eh_strategy_handler() thread. | ||
405 | * libata is the only user of ->eh_strategy_handler() in | ||
406 | * any kernel, so the default scsi_done() assumes it is | ||
407 | * not being called from the SCSI EH. | ||
408 | */ | ||
409 | qc->scsidone = scsi_finish_command; | ||
410 | |||
411 | switch (qc->tf.protocol) { | 403 | switch (qc->tf.protocol) { |
412 | case ATA_PROT_DMA: | 404 | case ATA_PROT_DMA: |
413 | case ATA_PROT_NODATA: | 405 | case ATA_PROT_NODATA: |
414 | printk(KERN_ERR "ata%u: command timeout\n", ap->id); | 406 | printk(KERN_ERR "ata%u: command timeout\n", ap->id); |
415 | drv_stat = ata_wait_idle(ap); | 407 | drv_stat = ata_wait_idle(ap); |
416 | qc->err_mask |= __ac_err_mask(drv_stat); | 408 | qc->err_mask |= __ac_err_mask(drv_stat); |
417 | ata_qc_complete(qc); | ||
418 | break; | 409 | break; |
419 | 410 | ||
420 | default: | 411 | default: |
@@ -424,12 +415,13 @@ static void pdc_eng_timeout(struct ata_port *ap) | |||
424 | ap->id, qc->tf.command, drv_stat); | 415 | ap->id, qc->tf.command, drv_stat); |
425 | 416 | ||
426 | qc->err_mask |= ac_err_mask(drv_stat); | 417 | qc->err_mask |= ac_err_mask(drv_stat); |
427 | ata_qc_complete(qc); | ||
428 | break; | 418 | break; |
429 | } | 419 | } |
430 | 420 | ||
431 | out: | 421 | out: |
432 | spin_unlock_irqrestore(&host_set->lock, flags); | 422 | spin_unlock_irqrestore(&host_set->lock, flags); |
423 | if (qc) | ||
424 | ata_eh_qc_complete(qc); | ||
433 | DPRINTK("EXIT\n"); | 425 | DPRINTK("EXIT\n"); |
434 | } | 426 | } |
435 | 427 | ||
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c index 5a7a7b1d4add..7222fc7ff3fc 100644 --- a/drivers/scsi/sata_sil24.c +++ b/drivers/scsi/sata_sil24.c | |||
@@ -644,17 +644,9 @@ static void sil24_eng_timeout(struct ata_port *ap) | |||
644 | return; | 644 | return; |
645 | } | 645 | } |
646 | 646 | ||
647 | /* | ||
648 | * hack alert! We cannot use the supplied completion | ||
649 | * function from inside the ->eh_strategy_handler() thread. | ||
650 | * libata is the only user of ->eh_strategy_handler() in | ||
651 | * any kernel, so the default scsi_done() assumes it is | ||
652 | * not being called from the SCSI EH. | ||
653 | */ | ||
654 | printk(KERN_ERR "ata%u: command timeout\n", ap->id); | 647 | printk(KERN_ERR "ata%u: command timeout\n", ap->id); |
655 | qc->scsidone = scsi_finish_command; | ||
656 | qc->err_mask |= AC_ERR_TIMEOUT; | 648 | qc->err_mask |= AC_ERR_TIMEOUT; |
657 | ata_qc_complete(qc); | 649 | ata_eh_qc_complete(qc); |
658 | 650 | ||
659 | sil24_reset_controller(ap); | 651 | sil24_reset_controller(ap); |
660 | } | 652 | } |
diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c index 3175c6bb4fec..9f992fbcf2e7 100644 --- a/drivers/scsi/sata_sx4.c +++ b/drivers/scsi/sata_sx4.c | |||
@@ -872,20 +872,11 @@ static void pdc_eng_timeout(struct ata_port *ap) | |||
872 | goto out; | 872 | goto out; |
873 | } | 873 | } |
874 | 874 | ||
875 | /* hack alert! We cannot use the supplied completion | ||
876 | * function from inside the ->eh_strategy_handler() thread. | ||
877 | * libata is the only user of ->eh_strategy_handler() in | ||
878 | * any kernel, so the default scsi_done() assumes it is | ||
879 | * not being called from the SCSI EH. | ||
880 | */ | ||
881 | qc->scsidone = scsi_finish_command; | ||
882 | |||
883 | switch (qc->tf.protocol) { | 875 | switch (qc->tf.protocol) { |
884 | case ATA_PROT_DMA: | 876 | case ATA_PROT_DMA: |
885 | case ATA_PROT_NODATA: | 877 | case ATA_PROT_NODATA: |
886 | printk(KERN_ERR "ata%u: command timeout\n", ap->id); | 878 | printk(KERN_ERR "ata%u: command timeout\n", ap->id); |
887 | qc->err_mask |= __ac_err_mask(ata_wait_idle(ap)); | 879 | qc->err_mask |= __ac_err_mask(ata_wait_idle(ap)); |
888 | ata_qc_complete(qc); | ||
889 | break; | 880 | break; |
890 | 881 | ||
891 | default: | 882 | default: |
@@ -895,12 +886,13 @@ static void pdc_eng_timeout(struct ata_port *ap) | |||
895 | ap->id, qc->tf.command, drv_stat); | 886 | ap->id, qc->tf.command, drv_stat); |
896 | 887 | ||
897 | qc->err_mask |= ac_err_mask(drv_stat); | 888 | qc->err_mask |= ac_err_mask(drv_stat); |
898 | ata_qc_complete(qc); | ||
899 | break; | 889 | break; |
900 | } | 890 | } |
901 | 891 | ||
902 | out: | 892 | out: |
903 | spin_unlock_irqrestore(&host_set->lock, flags); | 893 | spin_unlock_irqrestore(&host_set->lock, flags); |
894 | if (qc) | ||
895 | ata_eh_qc_complete(qc); | ||
904 | DPRINTK("EXIT\n"); | 896 | DPRINTK("EXIT\n"); |
905 | } | 897 | } |
906 | 898 | ||
diff --git a/include/linux/libata.h b/include/linux/libata.h index b1ea2f98bfbb..576788de962a 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
@@ -398,6 +398,7 @@ struct ata_port { | |||
398 | unsigned long pio_task_timeout; | 398 | unsigned long pio_task_timeout; |
399 | 399 | ||
400 | u32 msg_enable; | 400 | u32 msg_enable; |
401 | struct list_head eh_done_q; | ||
401 | 402 | ||
402 | void *private_data; | 403 | void *private_data; |
403 | }; | 404 | }; |
@@ -490,6 +491,8 @@ extern int ata_scsi_detect(struct scsi_host_template *sht); | |||
490 | extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg); | 491 | extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg); |
491 | extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)); | 492 | extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)); |
492 | extern int ata_scsi_error(struct Scsi_Host *host); | 493 | extern int ata_scsi_error(struct Scsi_Host *host); |
494 | extern void ata_eh_qc_complete(struct ata_queued_cmd *qc); | ||
495 | extern void ata_eh_qc_retry(struct ata_queued_cmd *qc); | ||
493 | extern int ata_scsi_release(struct Scsi_Host *host); | 496 | extern int ata_scsi_release(struct Scsi_Host *host); |
494 | extern unsigned int ata_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc); | 497 | extern unsigned int ata_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc); |
495 | extern int ata_scsi_device_resume(struct scsi_device *); | 498 | extern int ata_scsi_device_resume(struct scsi_device *); |