diff options
author | Mikael Pettersson <mikpe@it.uu.se> | 2007-03-11 16:20:43 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-04-28 14:15:59 -0400 |
commit | 724114a5738131997af9272f3c716dbe457c1690 (patch) | |
tree | 047726b640734419bf0477ddb08ae2ada72abf74 /drivers/ata/sata_promise.c | |
parent | 799331fda03f969b781553b786f38b83ec3bb608 (diff) |
sata_promise: separate SATA and PATA ops
This patch changes sata_promise so that the PATA ports
on TX2plus chips are bound to the pdc_pata_ops structure.
This means that operations called from the SATA ops
structures don't need any SATA-vs-PATA tests any more.
Instead, operations that depend on a port being SATA or
PATA are separated into different procedures.
* pdc_cable_type() is split into a PATA version and a
SATA version
* pdc_error_handler() is split into a PATA version and a
SATA version, that both call a common version after
setting up the `hardreset' function pointer
* pdc_old_check_atapi_dma() is now only used for SATAI
ports, so is renamed to pdc_old_sata_check_atapi_dma()
and simplified
* pdc_sata_scr_{read,write}() are now only used for SATA
ports, so their is-not-SATA tests are removed
* pdc_port_start() is split into three procedures: a wrapper
which performs the ->ops adjustment on TX2plus PATA ports,
a procedure with the common code, and a procedure with
the SATA-specific code (this bit might be cleaned up by
Tejun's new init model)
Tested on 20619, 20575, and 20775 chips.
Signed-off-by: Mikael Pettersson <mikpe@it.uu.se>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata/sata_promise.c')
-rw-r--r-- | drivers/ata/sata_promise.c | 107 |
1 files changed, 66 insertions, 41 deletions
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c index 04287c80d8e9..acc9913dd6dc 100644 --- a/drivers/ata/sata_promise.c +++ b/drivers/ata/sata_promise.c | |||
@@ -45,7 +45,7 @@ | |||
45 | #include "sata_promise.h" | 45 | #include "sata_promise.h" |
46 | 46 | ||
47 | #define DRV_NAME "sata_promise" | 47 | #define DRV_NAME "sata_promise" |
48 | #define DRV_VERSION "2.02" | 48 | #define DRV_VERSION "2.03" |
49 | 49 | ||
50 | 50 | ||
51 | enum { | 51 | enum { |
@@ -124,14 +124,16 @@ static void pdc_qc_prep(struct ata_queued_cmd *qc); | |||
124 | static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf); | 124 | static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf); |
125 | static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf); | 125 | static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf); |
126 | static int pdc_check_atapi_dma(struct ata_queued_cmd *qc); | 126 | static int pdc_check_atapi_dma(struct ata_queued_cmd *qc); |
127 | static int pdc_old_check_atapi_dma(struct ata_queued_cmd *qc); | 127 | static int pdc_old_sata_check_atapi_dma(struct ata_queued_cmd *qc); |
128 | static void pdc_irq_clear(struct ata_port *ap); | 128 | static void pdc_irq_clear(struct ata_port *ap); |
129 | static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc); | 129 | static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc); |
130 | static void pdc_freeze(struct ata_port *ap); | 130 | static void pdc_freeze(struct ata_port *ap); |
131 | static void pdc_thaw(struct ata_port *ap); | 131 | static void pdc_thaw(struct ata_port *ap); |
132 | static void pdc_error_handler(struct ata_port *ap); | 132 | static void pdc_pata_error_handler(struct ata_port *ap); |
133 | static void pdc_sata_error_handler(struct ata_port *ap); | ||
133 | static void pdc_post_internal_cmd(struct ata_queued_cmd *qc); | 134 | static void pdc_post_internal_cmd(struct ata_queued_cmd *qc); |
134 | static int pdc_cable_detect(struct ata_port *ap); | 135 | static int pdc_pata_cable_detect(struct ata_port *ap); |
136 | static int pdc_sata_cable_detect(struct ata_port *ap); | ||
135 | 137 | ||
136 | static struct scsi_host_template pdc_ata_sht = { | 138 | static struct scsi_host_template pdc_ata_sht = { |
137 | .module = THIS_MODULE, | 139 | .module = THIS_MODULE, |
@@ -164,9 +166,9 @@ static const struct ata_port_operations pdc_sata_ops = { | |||
164 | .qc_issue = pdc_qc_issue_prot, | 166 | .qc_issue = pdc_qc_issue_prot, |
165 | .freeze = pdc_freeze, | 167 | .freeze = pdc_freeze, |
166 | .thaw = pdc_thaw, | 168 | .thaw = pdc_thaw, |
167 | .error_handler = pdc_error_handler, | 169 | .error_handler = pdc_sata_error_handler, |
168 | .post_internal_cmd = pdc_post_internal_cmd, | 170 | .post_internal_cmd = pdc_post_internal_cmd, |
169 | .cable_detect = pdc_cable_detect, | 171 | .cable_detect = pdc_sata_cable_detect, |
170 | .data_xfer = ata_data_xfer, | 172 | .data_xfer = ata_data_xfer, |
171 | .irq_handler = pdc_interrupt, | 173 | .irq_handler = pdc_interrupt, |
172 | .irq_clear = pdc_irq_clear, | 174 | .irq_clear = pdc_irq_clear, |
@@ -186,15 +188,15 @@ static const struct ata_port_operations pdc_old_sata_ops = { | |||
186 | .check_status = ata_check_status, | 188 | .check_status = ata_check_status, |
187 | .exec_command = pdc_exec_command_mmio, | 189 | .exec_command = pdc_exec_command_mmio, |
188 | .dev_select = ata_std_dev_select, | 190 | .dev_select = ata_std_dev_select, |
189 | .check_atapi_dma = pdc_old_check_atapi_dma, | 191 | .check_atapi_dma = pdc_old_sata_check_atapi_dma, |
190 | 192 | ||
191 | .qc_prep = pdc_qc_prep, | 193 | .qc_prep = pdc_qc_prep, |
192 | .qc_issue = pdc_qc_issue_prot, | 194 | .qc_issue = pdc_qc_issue_prot, |
193 | .freeze = pdc_freeze, | 195 | .freeze = pdc_freeze, |
194 | .thaw = pdc_thaw, | 196 | .thaw = pdc_thaw, |
195 | .error_handler = pdc_error_handler, | 197 | .error_handler = pdc_sata_error_handler, |
196 | .post_internal_cmd = pdc_post_internal_cmd, | 198 | .post_internal_cmd = pdc_post_internal_cmd, |
197 | .cable_detect = pdc_cable_detect, | 199 | .cable_detect = pdc_sata_cable_detect, |
198 | .data_xfer = ata_data_xfer, | 200 | .data_xfer = ata_data_xfer, |
199 | .irq_handler = pdc_interrupt, | 201 | .irq_handler = pdc_interrupt, |
200 | .irq_clear = pdc_irq_clear, | 202 | .irq_clear = pdc_irq_clear, |
@@ -219,9 +221,9 @@ static const struct ata_port_operations pdc_pata_ops = { | |||
219 | .qc_issue = pdc_qc_issue_prot, | 221 | .qc_issue = pdc_qc_issue_prot, |
220 | .freeze = pdc_freeze, | 222 | .freeze = pdc_freeze, |
221 | .thaw = pdc_thaw, | 223 | .thaw = pdc_thaw, |
222 | .error_handler = pdc_error_handler, | 224 | .error_handler = pdc_pata_error_handler, |
223 | .post_internal_cmd = pdc_post_internal_cmd, | 225 | .post_internal_cmd = pdc_post_internal_cmd, |
224 | .cable_detect = pdc_cable_detect, | 226 | .cable_detect = pdc_pata_cable_detect, |
225 | .data_xfer = ata_data_xfer, | 227 | .data_xfer = ata_data_xfer, |
226 | .irq_handler = pdc_interrupt, | 228 | .irq_handler = pdc_interrupt, |
227 | .irq_clear = pdc_irq_clear, | 229 | .irq_clear = pdc_irq_clear, |
@@ -316,18 +318,12 @@ static struct pci_driver pdc_ata_pci_driver = { | |||
316 | }; | 318 | }; |
317 | 319 | ||
318 | 320 | ||
319 | static int pdc_port_start(struct ata_port *ap) | 321 | static int pdc_common_port_start(struct ata_port *ap) |
320 | { | 322 | { |
321 | struct device *dev = ap->host->dev; | 323 | struct device *dev = ap->host->dev; |
322 | struct pdc_host_priv *hp = ap->host->private_data; | ||
323 | struct pdc_port_priv *pp; | 324 | struct pdc_port_priv *pp; |
324 | int rc; | 325 | int rc; |
325 | 326 | ||
326 | /* fix up port flags and cable type for SATA+PATA chips */ | ||
327 | ap->flags |= hp->port_flags[ap->port_no]; | ||
328 | if (ap->flags & ATA_FLAG_SATA) | ||
329 | ap->cbl = ATA_CBL_SATA; | ||
330 | |||
331 | rc = ata_port_start(ap); | 327 | rc = ata_port_start(ap); |
332 | if (rc) | 328 | if (rc) |
333 | return rc; | 329 | return rc; |
@@ -342,8 +338,20 @@ static int pdc_port_start(struct ata_port *ap) | |||
342 | 338 | ||
343 | ap->private_data = pp; | 339 | ap->private_data = pp; |
344 | 340 | ||
341 | return 0; | ||
342 | } | ||
343 | |||
344 | static int pdc_sata_port_start(struct ata_port *ap) | ||
345 | { | ||
346 | struct pdc_host_priv *hp = ap->host->private_data; | ||
347 | int rc; | ||
348 | |||
349 | rc = pdc_common_port_start(ap); | ||
350 | if (rc) | ||
351 | return rc; | ||
352 | |||
345 | /* fix up PHYMODE4 align timing */ | 353 | /* fix up PHYMODE4 align timing */ |
346 | if ((hp->flags & PDC_FLAG_GEN_II) && sata_scr_valid(ap)) { | 354 | if (hp->flags & PDC_FLAG_GEN_II) { |
347 | void __iomem *mmio = (void __iomem *) ap->ioaddr.scr_addr; | 355 | void __iomem *mmio = (void __iomem *) ap->ioaddr.scr_addr; |
348 | unsigned int tmp; | 356 | unsigned int tmp; |
349 | 357 | ||
@@ -355,6 +363,21 @@ static int pdc_port_start(struct ata_port *ap) | |||
355 | return 0; | 363 | return 0; |
356 | } | 364 | } |
357 | 365 | ||
366 | static int pdc_port_start(struct ata_port *ap) | ||
367 | { | ||
368 | struct pdc_host_priv *hp = ap->host->private_data; | ||
369 | |||
370 | /* fix up port flags and cable type for SATA+PATA chips */ | ||
371 | ap->flags |= hp->port_flags[ap->port_no]; | ||
372 | if (ap->flags & ATA_FLAG_SATA) { | ||
373 | ap->cbl = ATA_CBL_SATA; | ||
374 | return pdc_sata_port_start(ap); | ||
375 | } else { | ||
376 | ap->ops = &pdc_pata_ops; | ||
377 | return pdc_common_port_start(ap); | ||
378 | } | ||
379 | } | ||
380 | |||
358 | static void pdc_reset_port(struct ata_port *ap) | 381 | static void pdc_reset_port(struct ata_port *ap) |
359 | { | 382 | { |
360 | void __iomem *mmio = ap->ioaddr.cmd_addr + PDC_CTLSTAT; | 383 | void __iomem *mmio = ap->ioaddr.cmd_addr + PDC_CTLSTAT; |
@@ -377,23 +400,25 @@ static void pdc_reset_port(struct ata_port *ap) | |||
377 | readl(mmio); /* flush */ | 400 | readl(mmio); /* flush */ |
378 | } | 401 | } |
379 | 402 | ||
380 | static int pdc_cable_detect(struct ata_port *ap) | 403 | static int pdc_pata_cable_detect(struct ata_port *ap) |
381 | { | 404 | { |
382 | u8 tmp; | 405 | u8 tmp; |
383 | void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr + PDC_CTLSTAT + 0x03; | 406 | void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr + PDC_CTLSTAT + 0x03; |
384 | 407 | ||
385 | if (!sata_scr_valid(ap)) { | 408 | tmp = readb(mmio); |
386 | tmp = readb(mmio); | 409 | if (tmp & 0x01) |
387 | if (tmp & 0x01) | 410 | return ATA_CBL_PATA40; |
388 | return ATA_CBL_PATA40; | 411 | return ATA_CBL_PATA80; |
389 | return ATA_CBL_PATA80; | 412 | } |
390 | } | 413 | |
414 | static int pdc_sata_cable_detect(struct ata_port *ap) | ||
415 | { | ||
391 | return ATA_CBL_SATA; | 416 | return ATA_CBL_SATA; |
392 | } | 417 | } |
393 | 418 | ||
394 | static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) | 419 | static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) |
395 | { | 420 | { |
396 | if (sc_reg > SCR_CONTROL || ap->cbl != ATA_CBL_SATA) | 421 | if (sc_reg > SCR_CONTROL) |
397 | return 0xffffffffU; | 422 | return 0xffffffffU; |
398 | return readl(ap->ioaddr.scr_addr + (sc_reg * 4)); | 423 | return readl(ap->ioaddr.scr_addr + (sc_reg * 4)); |
399 | } | 424 | } |
@@ -402,7 +427,7 @@ static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) | |||
402 | static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, | 427 | static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, |
403 | u32 val) | 428 | u32 val) |
404 | { | 429 | { |
405 | if (sc_reg > SCR_CONTROL || ap->cbl != ATA_CBL_SATA) | 430 | if (sc_reg > SCR_CONTROL) |
406 | return; | 431 | return; |
407 | writel(val, ap->ioaddr.scr_addr + (sc_reg * 4)); | 432 | writel(val, ap->ioaddr.scr_addr + (sc_reg * 4)); |
408 | } | 433 | } |
@@ -558,22 +583,26 @@ static void pdc_thaw(struct ata_port *ap) | |||
558 | readl(mmio + PDC_CTLSTAT); /* flush */ | 583 | readl(mmio + PDC_CTLSTAT); /* flush */ |
559 | } | 584 | } |
560 | 585 | ||
561 | static void pdc_error_handler(struct ata_port *ap) | 586 | static void pdc_common_error_handler(struct ata_port *ap, ata_reset_fn_t hardreset) |
562 | { | 587 | { |
563 | ata_reset_fn_t hardreset; | ||
564 | |||
565 | if (!(ap->pflags & ATA_PFLAG_FROZEN)) | 588 | if (!(ap->pflags & ATA_PFLAG_FROZEN)) |
566 | pdc_reset_port(ap); | 589 | pdc_reset_port(ap); |
567 | 590 | ||
568 | hardreset = NULL; | ||
569 | if (sata_scr_valid(ap)) | ||
570 | hardreset = sata_std_hardreset; | ||
571 | |||
572 | /* perform recovery */ | 591 | /* perform recovery */ |
573 | ata_do_eh(ap, ata_std_prereset, ata_std_softreset, hardreset, | 592 | ata_do_eh(ap, ata_std_prereset, ata_std_softreset, hardreset, |
574 | ata_std_postreset); | 593 | ata_std_postreset); |
575 | } | 594 | } |
576 | 595 | ||
596 | static void pdc_pata_error_handler(struct ata_port *ap) | ||
597 | { | ||
598 | pdc_common_error_handler(ap, NULL); | ||
599 | } | ||
600 | |||
601 | static void pdc_sata_error_handler(struct ata_port *ap) | ||
602 | { | ||
603 | pdc_common_error_handler(ap, sata_std_hardreset); | ||
604 | } | ||
605 | |||
577 | static void pdc_post_internal_cmd(struct ata_queued_cmd *qc) | 606 | static void pdc_post_internal_cmd(struct ata_queued_cmd *qc) |
578 | { | 607 | { |
579 | struct ata_port *ap = qc->ap; | 608 | struct ata_port *ap = qc->ap; |
@@ -763,14 +792,10 @@ static int pdc_check_atapi_dma(struct ata_queued_cmd *qc) | |||
763 | return pio; | 792 | return pio; |
764 | } | 793 | } |
765 | 794 | ||
766 | static int pdc_old_check_atapi_dma(struct ata_queued_cmd *qc) | 795 | static int pdc_old_sata_check_atapi_dma(struct ata_queued_cmd *qc) |
767 | { | 796 | { |
768 | struct ata_port *ap = qc->ap; | ||
769 | |||
770 | /* First generation chips cannot use ATAPI DMA on SATA ports */ | 797 | /* First generation chips cannot use ATAPI DMA on SATA ports */ |
771 | if (sata_scr_valid(ap)) | 798 | return 1; |
772 | return 1; | ||
773 | return pdc_check_atapi_dma(qc); | ||
774 | } | 799 | } |
775 | 800 | ||
776 | static void pdc_ata_setup_port(struct ata_ioports *port, void __iomem *base, | 801 | static void pdc_ata_setup_port(struct ata_ioports *port, void __iomem *base, |