aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2010-05-10 15:41:39 -0400
committerJeff Garzik <jgarzik@redhat.com>2010-05-19 13:36:46 -0400
commitfe06e5f9b7c61dc567edace3f4909672067f7d7e (patch)
treeb2242169e8e3b32c63925ed9901fff9d49c26192
parentc429137a67b82788d24682153bb9c96501a9ef34 (diff)
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>
-rw-r--r--drivers/ata/libata-eh.c2
-rw-r--r--drivers/ata/libata-sff.c159
-rw-r--r--drivers/ata/libata.h11
-rw-r--r--drivers/ata/pata_icside.c1
-rw-r--r--drivers/ata/pata_scc.c1
-rw-r--r--drivers/ata/sata_nv.c6
-rw-r--r--drivers/ata/sata_promise.c2
-rw-r--r--drivers/ata/sata_qstor.c3
-rw-r--r--drivers/ata/sata_sx4.c2
-rw-r--r--include/linux/libata.h3
10 files changed, 102 insertions, 88 deletions
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index d6e67488174c..f77a67303f8b 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -3684,7 +3684,7 @@ void ata_std_error_handler(struct ata_port *ap)
3684 ata_reset_fn_t hardreset = ops->hardreset; 3684 ata_reset_fn_t hardreset = ops->hardreset;
3685 3685
3686 /* ignore built-in hardreset if SCR access is not available */ 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 hardreset = NULL; 3688 hardreset = NULL;
3689 3689
3690 ata_do_eh(ap, ops->prereset, ops->softreset, hardreset, ops->postreset); 3690 ata_do_eh(ap, ops->prereset, ops->softreset, hardreset, ops->postreset);
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index e78ad76861f4..aa378c04ed87 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -56,7 +56,6 @@ const struct ata_port_operations ata_sff_port_ops = {
56 .hardreset = sata_sff_hardreset, 56 .hardreset = sata_sff_hardreset,
57 .postreset = ata_sff_postreset, 57 .postreset = ata_sff_postreset,
58 .error_handler = ata_sff_error_handler, 58 .error_handler = ata_sff_error_handler,
59 .post_internal_cmd = ata_sff_post_internal_cmd,
60 59
61 .sff_dev_select = ata_sff_dev_select, 60 .sff_dev_select = ata_sff_dev_select,
62 .sff_check_status = ata_sff_check_status, 61 .sff_check_status = ata_sff_check_status,
@@ -2361,7 +2360,7 @@ void ata_sff_drain_fifo(struct ata_queued_cmd *qc)
2361EXPORT_SYMBOL_GPL(ata_sff_drain_fifo); 2360EXPORT_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 * @ap: port to handle error for 2364 * @ap: port to handle error for
2366 * 2365 *
2367 * Stock error handler for SFF controller. It can handle both 2366 * Stock error handler for SFF controller. It can handle both
@@ -2378,64 +2377,32 @@ void ata_sff_error_handler(struct ata_port *ap)
2378 ata_reset_fn_t hardreset = ap->ops->hardreset; 2377 ata_reset_fn_t hardreset = ap->ops->hardreset;
2379 struct ata_queued_cmd *qc; 2378 struct ata_queued_cmd *qc;
2380 unsigned long flags; 2379 unsigned long flags;
2381 bool thaw = false;
2382 2380
2383 qc = __ata_qc_from_tag(ap, ap->link.active_tag); 2381 qc = __ata_qc_from_tag(ap, ap->link.active_tag);
2384 if (qc && !(qc->flags & ATA_QCFLAG_FAILED)) 2382 if (qc && !(qc->flags & ATA_QCFLAG_FAILED))
2385 qc = NULL; 2383 qc = NULL;
2386 2384
2387 /* reset PIO HSM and stop DMA engine */
2388 spin_lock_irqsave(ap->lock, flags); 2385 spin_lock_irqsave(ap->lock, flags);
2389 2386
2390 if (ap->ioaddr.bmdma_addr && 2387 /*
2391 qc && (qc->tf.protocol == ATA_PROT_DMA || 2388 * We *MUST* do FIFO draining before we issue a reset as
2392 qc->tf.protocol == ATAPI_PROT_DMA)) { 2389 * several devices helpfully clear their internal state and
2393 u8 host_stat; 2390 * will lock solid if we touch the data port post reset. Pass
2394 2391 * qc in case anyone wants to do different PIO/DMA recovery or
2395 host_stat = ap->ops->bmdma_status(ap); 2392 * has per command fixups
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
2425 */ 2393 */
2426 if (ap->ops->sff_drain_fifo) 2394 if (ap->ops->sff_drain_fifo)
2427 ap->ops->sff_drain_fifo(qc); 2395 ap->ops->sff_drain_fifo(qc);
2428 2396
2429 spin_unlock_irqrestore(ap->lock, flags); 2397 spin_unlock_irqrestore(ap->lock, flags);
2430 2398
2431 /* PIO and DMA engines have been stopped, perform recovery */ 2399 /* ignore ata_sff_softreset if ctl isn't accessible */
2432
2433 /* Ignore ata_sff_softreset if ctl isn't accessible and
2434 * built-in hardresets if SCR access isn't available.
2435 */
2436 if (softreset == ata_sff_softreset && !ap->ioaddr.ctl_addr) 2400 if (softreset == ata_sff_softreset && !ap->ioaddr.ctl_addr)
2437 softreset = NULL; 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 hardreset = NULL; 2406 hardreset = NULL;
2440 2407
2441 ata_do_eh(ap, ap->ops->prereset, softreset, hardreset, 2408 ata_do_eh(ap, ap->ops->prereset, softreset, hardreset,
@@ -2444,27 +2411,6 @@ void ata_sff_error_handler(struct ata_port *ap)
2444EXPORT_SYMBOL_GPL(ata_sff_error_handler); 2411EXPORT_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 */
2453void 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}
2465EXPORT_SYMBOL_GPL(ata_sff_post_internal_cmd);
2466
2467/**
2468 * ata_sff_std_ports - initialize ioaddr with standard port offsets. 2414 * ata_sff_std_ports - initialize ioaddr with standard port offsets.
2469 * @ioaddr: IO address structure to be initialized 2415 * @ioaddr: IO address structure to be initialized
2470 * 2416 *
@@ -2811,6 +2757,9 @@ EXPORT_SYMBOL_GPL(ata_pci_sff_init_one);
2811const struct ata_port_operations ata_bmdma_port_ops = { 2757const struct ata_port_operations ata_bmdma_port_ops = {
2812 .inherits = &ata_sff_port_ops, 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 .bmdma_setup = ata_bmdma_setup, 2763 .bmdma_setup = ata_bmdma_setup,
2815 .bmdma_start = ata_bmdma_start, 2764 .bmdma_start = ata_bmdma_start,
2816 .bmdma_stop = ata_bmdma_stop, 2765 .bmdma_stop = ata_bmdma_stop,
@@ -2829,6 +2778,84 @@ const struct ata_port_operations ata_bmdma32_port_ops = {
2829EXPORT_SYMBOL_GPL(ata_bmdma32_port_ops); 2778EXPORT_SYMBOL_GPL(ata_bmdma32_port_ops);
2830 2779
2831/** 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 */
2792void 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}
2836EXPORT_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 */
2845void 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}
2856EXPORT_SYMBOL_GPL(ata_bmdma_post_internal_cmd);
2857
2858/**
2832 * ata_bmdma_setup - Set up PCI IDE BMDMA transaction 2859 * ata_bmdma_setup - Set up PCI IDE BMDMA transaction
2833 * @qc: Info associated with this ATA transaction. 2860 * @qc: Info associated with this ATA transaction.
2834 * 2861 *
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index 002390cdc041..4b84ed60324a 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -38,17 +38,6 @@ struct ata_scsi_args {
38 void (*done)(struct scsi_cmnd *); 38 void (*done)(struct scsi_cmnd *);
39}; 39};
40 40
41static 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/* libata-core.c */ 41/* libata-core.c */
53enum { 42enum {
54 /* flags for ata_dev_read_id() */ 43 /* flags for ata_dev_read_id() */
diff --git a/drivers/ata/pata_icside.c b/drivers/ata/pata_icside.c
index ee85a9ce0a11..b56e8f722d20 100644
--- a/drivers/ata/pata_icside.c
+++ b/drivers/ata/pata_icside.c
@@ -333,7 +333,6 @@ static struct ata_port_operations pata_icside_port_ops = {
333 .cable_detect = ata_cable_40wire, 333 .cable_detect = ata_cable_40wire,
334 .set_dmamode = pata_icside_set_dmamode, 334 .set_dmamode = pata_icside_set_dmamode,
335 .postreset = pata_icside_postreset, 335 .postreset = pata_icside_postreset,
336 .post_internal_cmd = pata_icside_bmdma_stop,
337 336
338 .port_start = ATA_OP_NULL, /* don't need PRD table */ 337 .port_start = ATA_OP_NULL, /* don't need PRD table */
339}; 338};
diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c
index 70d549e28f0f..93f690e51a79 100644
--- a/drivers/ata/pata_scc.c
+++ b/drivers/ata/pata_scc.c
@@ -951,7 +951,6 @@ static struct ata_port_operations scc_pata_ops = {
951 .prereset = scc_pata_prereset, 951 .prereset = scc_pata_prereset,
952 .softreset = scc_softreset, 952 .softreset = scc_softreset,
953 .postreset = scc_postreset, 953 .postreset = scc_postreset,
954 .post_internal_cmd = scc_bmdma_stop,
955 954
956 .sff_irq_clear = scc_irq_clear, 955 .sff_irq_clear = scc_irq_clear,
957 956
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index a007b20c1991..64e99824d8c1 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -1131,7 +1131,7 @@ static void nv_adma_post_internal_cmd(struct ata_queued_cmd *qc)
1131 struct nv_adma_port_priv *pp = qc->ap->private_data; 1131 struct nv_adma_port_priv *pp = qc->ap->private_data;
1132 1132
1133 if (pp->flags & NV_ADMA_PORT_REGISTER_MODE) 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
1137static int nv_adma_port_start(struct ata_port *ap) 1137static int nv_adma_port_start(struct ata_port *ap)
@@ -1739,7 +1739,7 @@ static void nv_adma_error_handler(struct ata_port *ap)
1739 readw(mmio + NV_ADMA_CTL); /* flush posted write */ 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
1745static void nv_swncq_qc_to_dq(struct ata_port *ap, struct ata_queued_cmd *qc) 1745static void nv_swncq_qc_to_dq(struct ata_port *ap, struct ata_queued_cmd *qc)
@@ -1865,7 +1865,7 @@ static void nv_swncq_error_handler(struct ata_port *ap)
1865 ehc->i.action |= ATA_EH_RESET; 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#ifdef CONFIG_PM 1871#ifdef CONFIG_PM
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c
index e80628a77669..09a6179f5de3 100644
--- a/drivers/ata/sata_promise.c
+++ b/drivers/ata/sata_promise.c
@@ -839,7 +839,7 @@ static void pdc_error_handler(struct ata_port *ap)
839 if (!(ap->pflags & ATA_PFLAG_FROZEN)) 839 if (!(ap->pflags & ATA_PFLAG_FROZEN))
840 pdc_reset_port(ap); 840 pdc_reset_port(ap);
841 841
842 ata_std_error_handler(ap); 842 ata_sff_error_handler(ap);
843} 843}
844 844
845static void pdc_post_internal_cmd(struct ata_queued_cmd *qc) 845static void pdc_post_internal_cmd(struct ata_queued_cmd *qc)
diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c
index da84ea9e4fb0..d3a22f2ae7b6 100644
--- a/drivers/ata/sata_qstor.c
+++ b/drivers/ata/sata_qstor.c
@@ -147,7 +147,6 @@ static struct ata_port_operations qs_ata_ops = {
147 .prereset = qs_prereset, 147 .prereset = qs_prereset,
148 .softreset = ATA_OP_NULL, 148 .softreset = ATA_OP_NULL,
149 .error_handler = qs_error_handler, 149 .error_handler = qs_error_handler,
150 .post_internal_cmd = ATA_OP_NULL,
151 .lost_interrupt = ATA_OP_NULL, 150 .lost_interrupt = ATA_OP_NULL,
152 151
153 .scr_read = qs_scr_read, 152 .scr_read = qs_scr_read,
@@ -255,7 +254,7 @@ static int qs_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val)
255static void qs_error_handler(struct ata_port *ap) 254static void qs_error_handler(struct ata_port *ap)
256{ 255{
257 qs_enter_reg_mode(ap); 256 qs_enter_reg_mode(ap);
258 ata_std_error_handler(ap); 257 ata_sff_error_handler(ap);
259} 258}
260 259
261static int qs_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val) 260static int qs_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val)
diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c
index a4e552a325b0..bedd5188e5b0 100644
--- a/drivers/ata/sata_sx4.c
+++ b/drivers/ata/sata_sx4.c
@@ -921,7 +921,7 @@ static void pdc_error_handler(struct ata_port *ap)
921 if (!(ap->pflags & ATA_PFLAG_FROZEN)) 921 if (!(ap->pflags & ATA_PFLAG_FROZEN))
922 pdc_reset_port(ap); 922 pdc_reset_port(ap);
923 923
924 ata_std_error_handler(ap); 924 ata_sff_error_handler(ap);
925} 925}
926 926
927static void pdc_post_internal_cmd(struct ata_queued_cmd *qc) 927static void pdc_post_internal_cmd(struct ata_queued_cmd *qc)
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 6888b5c36e0f..1d3859016aec 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -1614,7 +1614,6 @@ extern int sata_sff_hardreset(struct ata_link *link, unsigned int *class,
1614extern void ata_sff_postreset(struct ata_link *link, unsigned int *classes); 1614extern void ata_sff_postreset(struct ata_link *link, unsigned int *classes);
1615extern void ata_sff_drain_fifo(struct ata_queued_cmd *qc); 1615extern void ata_sff_drain_fifo(struct ata_queued_cmd *qc);
1616extern void ata_sff_error_handler(struct ata_port *ap); 1616extern void ata_sff_error_handler(struct ata_port *ap);
1617extern void ata_sff_post_internal_cmd(struct ata_queued_cmd *qc);
1618extern void ata_sff_std_ports(struct ata_ioports *ioaddr); 1617extern void ata_sff_std_ports(struct ata_ioports *ioaddr);
1619#ifdef CONFIG_PCI 1618#ifdef CONFIG_PCI
1620extern int ata_pci_sff_init_host(struct ata_host *host); 1619extern int ata_pci_sff_init_host(struct ata_host *host);
@@ -1629,6 +1628,8 @@ extern int ata_pci_sff_init_one(struct pci_dev *pdev,
1629 struct scsi_host_template *sht, void *host_priv, int hflags); 1628 struct scsi_host_template *sht, void *host_priv, int hflags);
1630#endif /* CONFIG_PCI */ 1629#endif /* CONFIG_PCI */
1631 1630
1631extern void ata_bmdma_error_handler(struct ata_port *ap);
1632extern void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc);
1632extern void ata_bmdma_setup(struct ata_queued_cmd *qc); 1633extern void ata_bmdma_setup(struct ata_queued_cmd *qc);
1633extern void ata_bmdma_start(struct ata_queued_cmd *qc); 1634extern void ata_bmdma_start(struct ata_queued_cmd *qc);
1634extern void ata_bmdma_stop(struct ata_queued_cmd *qc); 1635extern void ata_bmdma_stop(struct ata_queued_cmd *qc);