Commit fe06e5f9b7c61dc567edace3f4909672067f7d7e
Committed by
Jeff Garzik
1 parent
c429137a67
Exists in
master
and in
39 other branches
libata-sff: separate out BMDMA EH
Some of error handling logic in ata_sff_error_handler() and all of ata_sff_post_internal_cmd() are for BMDMA. Create ata_bmdma_error_handler() and ata_bmdma_post_internal_cmd() and move BMDMA part into those. While at it, change DMA protocol check to ata_is_dma(), fix post_internal_cmd to call ap->ops->bmdma_stop instead of directly calling ata_bmdma_stop() and open code hardreset selection so that ata_std_error_handler() doesn't have to know about sff hardreset. As these two functions are BMDMA specific, there's no reason to check for bmdma_addr before calling bmdma methods if the protocol of the failed command is DMA. sata_mv and pata_mpc52xx now don't need to set .post_internal_cmd to ATA_OP_NULL and pata_icside and sata_qstor don't need to set it to their bmdma_stop routines. ata_sff_post_internal_cmd() becomes noop and is removed. This fixes p3 described in clean-up-BMDMA-initialization patch. Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Showing 10 changed files with 102 additions and 88 deletions Side-by-side Diff
drivers/ata/libata-eh.c
... | ... | @@ -3684,7 +3684,7 @@ |
3684 | 3684 | ata_reset_fn_t hardreset = ops->hardreset; |
3685 | 3685 | |
3686 | 3686 | /* ignore built-in hardreset if SCR access is not available */ |
3687 | - if (ata_is_builtin_hardreset(hardreset) && !sata_scr_valid(&ap->link)) | |
3687 | + if (hardreset == sata_std_hardreset && !sata_scr_valid(&ap->link)) | |
3688 | 3688 | hardreset = NULL; |
3689 | 3689 | |
3690 | 3690 | ata_do_eh(ap, ops->prereset, ops->softreset, hardreset, ops->postreset); |
drivers/ata/libata-sff.c
... | ... | @@ -56,7 +56,6 @@ |
56 | 56 | .hardreset = sata_sff_hardreset, |
57 | 57 | .postreset = ata_sff_postreset, |
58 | 58 | .error_handler = ata_sff_error_handler, |
59 | - .post_internal_cmd = ata_sff_post_internal_cmd, | |
60 | 59 | |
61 | 60 | .sff_dev_select = ata_sff_dev_select, |
62 | 61 | .sff_check_status = ata_sff_check_status, |
... | ... | @@ -2361,7 +2360,7 @@ |
2361 | 2360 | EXPORT_SYMBOL_GPL(ata_sff_drain_fifo); |
2362 | 2361 | |
2363 | 2362 | /** |
2364 | - * ata_sff_error_handler - Stock error handler for BMDMA controller | |
2363 | + * ata_sff_error_handler - Stock error handler for SFF controller | |
2365 | 2364 | * @ap: port to handle error for |
2366 | 2365 | * |
2367 | 2366 | * Stock error handler for SFF controller. It can handle both |
2368 | 2367 | |
2369 | 2368 | |
2370 | 2369 | |
2371 | 2370 | |
... | ... | @@ -2378,64 +2377,32 @@ |
2378 | 2377 | ata_reset_fn_t hardreset = ap->ops->hardreset; |
2379 | 2378 | struct ata_queued_cmd *qc; |
2380 | 2379 | unsigned long flags; |
2381 | - bool thaw = false; | |
2382 | 2380 | |
2383 | 2381 | qc = __ata_qc_from_tag(ap, ap->link.active_tag); |
2384 | 2382 | if (qc && !(qc->flags & ATA_QCFLAG_FAILED)) |
2385 | 2383 | qc = NULL; |
2386 | 2384 | |
2387 | - /* reset PIO HSM and stop DMA engine */ | |
2388 | 2385 | spin_lock_irqsave(ap->lock, flags); |
2389 | 2386 | |
2390 | - if (ap->ioaddr.bmdma_addr && | |
2391 | - qc && (qc->tf.protocol == ATA_PROT_DMA || | |
2392 | - qc->tf.protocol == ATAPI_PROT_DMA)) { | |
2393 | - u8 host_stat; | |
2394 | - | |
2395 | - host_stat = ap->ops->bmdma_status(ap); | |
2396 | - | |
2397 | - /* BMDMA controllers indicate host bus error by | |
2398 | - * setting DMA_ERR bit and timing out. As it wasn't | |
2399 | - * really a timeout event, adjust error mask and | |
2400 | - * cancel frozen state. | |
2401 | - */ | |
2402 | - if (qc->err_mask == AC_ERR_TIMEOUT | |
2403 | - && (host_stat & ATA_DMA_ERR)) { | |
2404 | - qc->err_mask = AC_ERR_HOST_BUS; | |
2405 | - thaw = true; | |
2406 | - } | |
2407 | - | |
2408 | - ap->ops->bmdma_stop(qc); | |
2409 | - | |
2410 | - /* if we're gonna thaw, make sure IRQ is clear */ | |
2411 | - if (thaw) { | |
2412 | - ap->ops->sff_check_status(ap); | |
2413 | - ap->ops->sff_irq_clear(ap); | |
2414 | - | |
2415 | - spin_unlock_irqrestore(ap->lock, flags); | |
2416 | - ata_eh_thaw_port(ap); | |
2417 | - spin_lock_irqsave(ap->lock, flags); | |
2418 | - } | |
2419 | - } | |
2420 | - | |
2421 | - /* We *MUST* do FIFO draining before we issue a reset as several | |
2422 | - * devices helpfully clear their internal state and will lock solid | |
2423 | - * if we touch the data port post reset. Pass qc in case anyone wants | |
2424 | - * to do different PIO/DMA recovery or has per command fixups | |
2387 | + /* | |
2388 | + * We *MUST* do FIFO draining before we issue a reset as | |
2389 | + * several devices helpfully clear their internal state and | |
2390 | + * will lock solid if we touch the data port post reset. Pass | |
2391 | + * qc in case anyone wants to do different PIO/DMA recovery or | |
2392 | + * has per command fixups | |
2425 | 2393 | */ |
2426 | 2394 | if (ap->ops->sff_drain_fifo) |
2427 | 2395 | ap->ops->sff_drain_fifo(qc); |
2428 | 2396 | |
2429 | 2397 | spin_unlock_irqrestore(ap->lock, flags); |
2430 | 2398 | |
2431 | - /* PIO and DMA engines have been stopped, perform recovery */ | |
2432 | - | |
2433 | - /* Ignore ata_sff_softreset if ctl isn't accessible and | |
2434 | - * built-in hardresets if SCR access isn't available. | |
2435 | - */ | |
2399 | + /* ignore ata_sff_softreset if ctl isn't accessible */ | |
2436 | 2400 | if (softreset == ata_sff_softreset && !ap->ioaddr.ctl_addr) |
2437 | 2401 | softreset = NULL; |
2438 | - if (ata_is_builtin_hardreset(hardreset) && !sata_scr_valid(&ap->link)) | |
2402 | + | |
2403 | + /* ignore built-in hardresets if SCR access is not available */ | |
2404 | + if ((hardreset == sata_std_hardreset || | |
2405 | + hardreset == sata_sff_hardreset) && !sata_scr_valid(&ap->link)) | |
2439 | 2406 | hardreset = NULL; |
2440 | 2407 | |
2441 | 2408 | ata_do_eh(ap, ap->ops->prereset, softreset, hardreset, |
... | ... | @@ -2444,27 +2411,6 @@ |
2444 | 2411 | EXPORT_SYMBOL_GPL(ata_sff_error_handler); |
2445 | 2412 | |
2446 | 2413 | /** |
2447 | - * ata_sff_post_internal_cmd - Stock post_internal_cmd for SFF controller | |
2448 | - * @qc: internal command to clean up | |
2449 | - * | |
2450 | - * LOCKING: | |
2451 | - * Kernel thread context (may sleep) | |
2452 | - */ | |
2453 | -void ata_sff_post_internal_cmd(struct ata_queued_cmd *qc) | |
2454 | -{ | |
2455 | - struct ata_port *ap = qc->ap; | |
2456 | - unsigned long flags; | |
2457 | - | |
2458 | - spin_lock_irqsave(ap->lock, flags); | |
2459 | - | |
2460 | - if (ap->ioaddr.bmdma_addr) | |
2461 | - ap->ops->bmdma_stop(qc); | |
2462 | - | |
2463 | - spin_unlock_irqrestore(ap->lock, flags); | |
2464 | -} | |
2465 | -EXPORT_SYMBOL_GPL(ata_sff_post_internal_cmd); | |
2466 | - | |
2467 | -/** | |
2468 | 2414 | * ata_sff_std_ports - initialize ioaddr with standard port offsets. |
2469 | 2415 | * @ioaddr: IO address structure to be initialized |
2470 | 2416 | * |
... | ... | @@ -2811,6 +2757,9 @@ |
2811 | 2757 | const struct ata_port_operations ata_bmdma_port_ops = { |
2812 | 2758 | .inherits = &ata_sff_port_ops, |
2813 | 2759 | |
2760 | + .error_handler = ata_bmdma_error_handler, | |
2761 | + .post_internal_cmd = ata_bmdma_post_internal_cmd, | |
2762 | + | |
2814 | 2763 | .bmdma_setup = ata_bmdma_setup, |
2815 | 2764 | .bmdma_start = ata_bmdma_start, |
2816 | 2765 | .bmdma_stop = ata_bmdma_stop, |
... | ... | @@ -2827,6 +2776,84 @@ |
2827 | 2776 | .port_start = ata_bmdma_port_start32, |
2828 | 2777 | }; |
2829 | 2778 | EXPORT_SYMBOL_GPL(ata_bmdma32_port_ops); |
2779 | + | |
2780 | +/** | |
2781 | + * ata_bmdma_error_handler - Stock error handler for BMDMA controller | |
2782 | + * @ap: port to handle error for | |
2783 | + * | |
2784 | + * Stock error handler for BMDMA controller. It can handle both | |
2785 | + * PATA and SATA controllers. Most BMDMA controllers should be | |
2786 | + * able to use this EH as-is or with some added handling before | |
2787 | + * and after. | |
2788 | + * | |
2789 | + * LOCKING: | |
2790 | + * Kernel thread context (may sleep) | |
2791 | + */ | |
2792 | +void ata_bmdma_error_handler(struct ata_port *ap) | |
2793 | +{ | |
2794 | + struct ata_queued_cmd *qc; | |
2795 | + unsigned long flags; | |
2796 | + bool thaw = false; | |
2797 | + | |
2798 | + qc = __ata_qc_from_tag(ap, ap->link.active_tag); | |
2799 | + if (qc && !(qc->flags & ATA_QCFLAG_FAILED)) | |
2800 | + qc = NULL; | |
2801 | + | |
2802 | + /* reset PIO HSM and stop DMA engine */ | |
2803 | + spin_lock_irqsave(ap->lock, flags); | |
2804 | + | |
2805 | + if (qc && ata_is_dma(qc->tf.protocol)) { | |
2806 | + u8 host_stat; | |
2807 | + | |
2808 | + host_stat = ap->ops->bmdma_status(ap); | |
2809 | + | |
2810 | + /* BMDMA controllers indicate host bus error by | |
2811 | + * setting DMA_ERR bit and timing out. As it wasn't | |
2812 | + * really a timeout event, adjust error mask and | |
2813 | + * cancel frozen state. | |
2814 | + */ | |
2815 | + if (qc->err_mask == AC_ERR_TIMEOUT && (host_stat & ATA_DMA_ERR)) { | |
2816 | + qc->err_mask = AC_ERR_HOST_BUS; | |
2817 | + thaw = true; | |
2818 | + } | |
2819 | + | |
2820 | + ap->ops->bmdma_stop(qc); | |
2821 | + | |
2822 | + /* if we're gonna thaw, make sure IRQ is clear */ | |
2823 | + if (thaw) { | |
2824 | + ap->ops->sff_check_status(ap); | |
2825 | + ap->ops->sff_irq_clear(ap); | |
2826 | + } | |
2827 | + } | |
2828 | + | |
2829 | + spin_unlock_irqrestore(ap->lock, flags); | |
2830 | + | |
2831 | + if (thaw) | |
2832 | + ata_eh_thaw_port(ap); | |
2833 | + | |
2834 | + ata_sff_error_handler(ap); | |
2835 | +} | |
2836 | +EXPORT_SYMBOL_GPL(ata_bmdma_error_handler); | |
2837 | + | |
2838 | +/** | |
2839 | + * ata_bmdma_post_internal_cmd - Stock post_internal_cmd for BMDMA | |
2840 | + * @qc: internal command to clean up | |
2841 | + * | |
2842 | + * LOCKING: | |
2843 | + * Kernel thread context (may sleep) | |
2844 | + */ | |
2845 | +void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc) | |
2846 | +{ | |
2847 | + struct ata_port *ap = qc->ap; | |
2848 | + unsigned long flags; | |
2849 | + | |
2850 | + if (ata_is_dma(qc->tf.protocol)) { | |
2851 | + spin_lock_irqsave(ap->lock, flags); | |
2852 | + ap->ops->bmdma_stop(qc); | |
2853 | + spin_unlock_irqrestore(ap->lock, flags); | |
2854 | + } | |
2855 | +} | |
2856 | +EXPORT_SYMBOL_GPL(ata_bmdma_post_internal_cmd); | |
2830 | 2857 | |
2831 | 2858 | /** |
2832 | 2859 | * ata_bmdma_setup - Set up PCI IDE BMDMA transaction |
drivers/ata/libata.h
... | ... | @@ -38,17 +38,6 @@ |
38 | 38 | void (*done)(struct scsi_cmnd *); |
39 | 39 | }; |
40 | 40 | |
41 | -static inline int ata_is_builtin_hardreset(ata_reset_fn_t reset) | |
42 | -{ | |
43 | - if (reset == sata_std_hardreset) | |
44 | - return 1; | |
45 | -#ifdef CONFIG_ATA_SFF | |
46 | - if (reset == sata_sff_hardreset) | |
47 | - return 1; | |
48 | -#endif | |
49 | - return 0; | |
50 | -} | |
51 | - | |
52 | 41 | /* libata-core.c */ |
53 | 42 | enum { |
54 | 43 | /* flags for ata_dev_read_id() */ |
drivers/ata/pata_icside.c
drivers/ata/pata_scc.c
drivers/ata/sata_nv.c
... | ... | @@ -1131,7 +1131,7 @@ |
1131 | 1131 | struct nv_adma_port_priv *pp = qc->ap->private_data; |
1132 | 1132 | |
1133 | 1133 | if (pp->flags & NV_ADMA_PORT_REGISTER_MODE) |
1134 | - ata_sff_post_internal_cmd(qc); | |
1134 | + ata_bmdma_post_internal_cmd(qc); | |
1135 | 1135 | } |
1136 | 1136 | |
1137 | 1137 | static int nv_adma_port_start(struct ata_port *ap) |
... | ... | @@ -1739,7 +1739,7 @@ |
1739 | 1739 | readw(mmio + NV_ADMA_CTL); /* flush posted write */ |
1740 | 1740 | } |
1741 | 1741 | |
1742 | - ata_sff_error_handler(ap); | |
1742 | + ata_bmdma_error_handler(ap); | |
1743 | 1743 | } |
1744 | 1744 | |
1745 | 1745 | static void nv_swncq_qc_to_dq(struct ata_port *ap, struct ata_queued_cmd *qc) |
... | ... | @@ -1865,7 +1865,7 @@ |
1865 | 1865 | ehc->i.action |= ATA_EH_RESET; |
1866 | 1866 | } |
1867 | 1867 | |
1868 | - ata_sff_error_handler(ap); | |
1868 | + ata_bmdma_error_handler(ap); | |
1869 | 1869 | } |
1870 | 1870 | |
1871 | 1871 | #ifdef CONFIG_PM |
drivers/ata/sata_promise.c
drivers/ata/sata_qstor.c
... | ... | @@ -147,7 +147,6 @@ |
147 | 147 | .prereset = qs_prereset, |
148 | 148 | .softreset = ATA_OP_NULL, |
149 | 149 | .error_handler = qs_error_handler, |
150 | - .post_internal_cmd = ATA_OP_NULL, | |
151 | 150 | .lost_interrupt = ATA_OP_NULL, |
152 | 151 | |
153 | 152 | .scr_read = qs_scr_read, |
... | ... | @@ -255,7 +254,7 @@ |
255 | 254 | static void qs_error_handler(struct ata_port *ap) |
256 | 255 | { |
257 | 256 | qs_enter_reg_mode(ap); |
258 | - ata_std_error_handler(ap); | |
257 | + ata_sff_error_handler(ap); | |
259 | 258 | } |
260 | 259 | |
261 | 260 | static int qs_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val) |
drivers/ata/sata_sx4.c
include/linux/libata.h
... | ... | @@ -1614,7 +1614,6 @@ |
1614 | 1614 | extern void ata_sff_postreset(struct ata_link *link, unsigned int *classes); |
1615 | 1615 | extern void ata_sff_drain_fifo(struct ata_queued_cmd *qc); |
1616 | 1616 | extern void ata_sff_error_handler(struct ata_port *ap); |
1617 | -extern void ata_sff_post_internal_cmd(struct ata_queued_cmd *qc); | |
1618 | 1617 | extern void ata_sff_std_ports(struct ata_ioports *ioaddr); |
1619 | 1618 | #ifdef CONFIG_PCI |
1620 | 1619 | extern int ata_pci_sff_init_host(struct ata_host *host); |
... | ... | @@ -1629,6 +1628,8 @@ |
1629 | 1628 | struct scsi_host_template *sht, void *host_priv, int hflags); |
1630 | 1629 | #endif /* CONFIG_PCI */ |
1631 | 1630 | |
1631 | +extern void ata_bmdma_error_handler(struct ata_port *ap); | |
1632 | +extern void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc); | |
1632 | 1633 | extern void ata_bmdma_setup(struct ata_queued_cmd *qc); |
1633 | 1634 | extern void ata_bmdma_start(struct ata_queued_cmd *qc); |
1634 | 1635 | extern void ata_bmdma_stop(struct ata_queued_cmd *qc); |