aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMikael Pettersson <mikpe@it.uu.se>2007-03-11 16:20:43 -0400
committerJeff Garzik <jeff@garzik.org>2007-04-28 14:15:59 -0400
commit724114a5738131997af9272f3c716dbe457c1690 (patch)
tree047726b640734419bf0477ddb08ae2ada72abf74
parent799331fda03f969b781553b786f38b83ec3bb608 (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>
-rw-r--r--drivers/ata/sata_promise.c107
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
51enum { 51enum {
@@ -124,14 +124,16 @@ static void pdc_qc_prep(struct ata_queued_cmd *qc);
124static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf); 124static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
125static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf); 125static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
126static int pdc_check_atapi_dma(struct ata_queued_cmd *qc); 126static int pdc_check_atapi_dma(struct ata_queued_cmd *qc);
127static int pdc_old_check_atapi_dma(struct ata_queued_cmd *qc); 127static int pdc_old_sata_check_atapi_dma(struct ata_queued_cmd *qc);
128static void pdc_irq_clear(struct ata_port *ap); 128static void pdc_irq_clear(struct ata_port *ap);
129static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc); 129static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc);
130static void pdc_freeze(struct ata_port *ap); 130static void pdc_freeze(struct ata_port *ap);
131static void pdc_thaw(struct ata_port *ap); 131static void pdc_thaw(struct ata_port *ap);
132static void pdc_error_handler(struct ata_port *ap); 132static void pdc_pata_error_handler(struct ata_port *ap);
133static void pdc_sata_error_handler(struct ata_port *ap);
133static void pdc_post_internal_cmd(struct ata_queued_cmd *qc); 134static void pdc_post_internal_cmd(struct ata_queued_cmd *qc);
134static int pdc_cable_detect(struct ata_port *ap); 135static int pdc_pata_cable_detect(struct ata_port *ap);
136static int pdc_sata_cable_detect(struct ata_port *ap);
135 137
136static struct scsi_host_template pdc_ata_sht = { 138static 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
319static int pdc_port_start(struct ata_port *ap) 321static 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
344static 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
366static 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
358static void pdc_reset_port(struct ata_port *ap) 381static 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
380static int pdc_cable_detect(struct ata_port *ap) 403static 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
414static int pdc_sata_cable_detect(struct ata_port *ap)
415{
391 return ATA_CBL_SATA; 416 return ATA_CBL_SATA;
392} 417}
393 418
394static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) 419static 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)
402static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, 427static 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
561static void pdc_error_handler(struct ata_port *ap) 586static 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
596static void pdc_pata_error_handler(struct ata_port *ap)
597{
598 pdc_common_error_handler(ap, NULL);
599}
600
601static void pdc_sata_error_handler(struct ata_port *ap)
602{
603 pdc_common_error_handler(ap, sata_std_hardreset);
604}
605
577static void pdc_post_internal_cmd(struct ata_queued_cmd *qc) 606static 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
766static int pdc_old_check_atapi_dma(struct ata_queued_cmd *qc) 795static 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
776static void pdc_ata_setup_port(struct ata_ioports *port, void __iomem *base, 801static void pdc_ata_setup_port(struct ata_ioports *port, void __iomem *base,