diff options
| -rw-r--r-- | drivers/ata/sata_promise.c | 80 | 
1 files changed, 68 insertions, 12 deletions
| diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c index 6f7bc5b0ef4a..f055874a6ec5 100644 --- a/drivers/ata/sata_promise.c +++ b/drivers/ata/sata_promise.c | |||
| @@ -71,9 +71,12 @@ enum { | |||
| 71 | 71 | ||
| 72 | PDC_HAS_PATA = (1 << 1), /* PDC20375/20575 has PATA */ | 72 | PDC_HAS_PATA = (1 << 1), /* PDC20375/20575 has PATA */ | 
| 73 | 73 | ||
| 74 | /* PDC_CTLSTAT bit definitions */ | ||
| 75 | PDC_DMA_ENABLE = (1 << 7), | ||
| 76 | PDC_IRQ_DISABLE = (1 << 10), | ||
| 74 | PDC_RESET = (1 << 11), /* HDMA reset */ | 77 | PDC_RESET = (1 << 11), /* HDMA reset */ | 
| 75 | 78 | ||
| 76 | PDC_COMMON_FLAGS = ATA_FLAG_NO_LEGACY | ATA_FLAG_SRST | | 79 | PDC_COMMON_FLAGS = ATA_FLAG_NO_LEGACY | | 
| 77 | ATA_FLAG_MMIO | ATA_FLAG_NO_ATAPI | | 80 | ATA_FLAG_MMIO | ATA_FLAG_NO_ATAPI | | 
| 78 | ATA_FLAG_PIO_POLLING, | 81 | ATA_FLAG_PIO_POLLING, | 
| 79 | 82 | ||
| @@ -99,13 +102,16 @@ static void pdc_eng_timeout(struct ata_port *ap); | |||
| 99 | static int pdc_port_start(struct ata_port *ap); | 102 | static int pdc_port_start(struct ata_port *ap); | 
| 100 | static void pdc_port_stop(struct ata_port *ap); | 103 | static void pdc_port_stop(struct ata_port *ap); | 
| 101 | static void pdc_pata_phy_reset(struct ata_port *ap); | 104 | static void pdc_pata_phy_reset(struct ata_port *ap); | 
| 102 | static void pdc_sata_phy_reset(struct ata_port *ap); | ||
| 103 | static void pdc_qc_prep(struct ata_queued_cmd *qc); | 105 | static void pdc_qc_prep(struct ata_queued_cmd *qc); | 
| 104 | static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf); | 106 | static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf); | 
| 105 | static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf); | 107 | static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf); | 
| 106 | static void pdc_irq_clear(struct ata_port *ap); | 108 | static void pdc_irq_clear(struct ata_port *ap); | 
| 107 | static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc); | 109 | static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc); | 
| 108 | static void pdc_host_stop(struct ata_host *host); | 110 | static void pdc_host_stop(struct ata_host *host); | 
| 111 | static void pdc_freeze(struct ata_port *ap); | ||
| 112 | static void pdc_thaw(struct ata_port *ap); | ||
| 113 | static void pdc_error_handler(struct ata_port *ap); | ||
| 114 | static void pdc_post_internal_cmd(struct ata_queued_cmd *qc); | ||
| 109 | 115 | ||
| 110 | 116 | ||
| 111 | static struct scsi_host_template pdc_ata_sht = { | 117 | static struct scsi_host_template pdc_ata_sht = { | 
| @@ -134,11 +140,12 @@ static const struct ata_port_operations pdc_sata_ops = { | |||
| 134 | .exec_command = pdc_exec_command_mmio, | 140 | .exec_command = pdc_exec_command_mmio, | 
| 135 | .dev_select = ata_std_dev_select, | 141 | .dev_select = ata_std_dev_select, | 
| 136 | 142 | ||
| 137 | .phy_reset = pdc_sata_phy_reset, | ||
| 138 | |||
| 139 | .qc_prep = pdc_qc_prep, | 143 | .qc_prep = pdc_qc_prep, | 
| 140 | .qc_issue = pdc_qc_issue_prot, | 144 | .qc_issue = pdc_qc_issue_prot, | 
| 141 | .eng_timeout = pdc_eng_timeout, | 145 | .freeze = pdc_freeze, | 
| 146 | .thaw = pdc_thaw, | ||
| 147 | .error_handler = pdc_error_handler, | ||
| 148 | .post_internal_cmd = pdc_post_internal_cmd, | ||
| 142 | .data_xfer = ata_mmio_data_xfer, | 149 | .data_xfer = ata_mmio_data_xfer, | 
| 143 | .irq_handler = pdc_interrupt, | 150 | .irq_handler = pdc_interrupt, | 
| 144 | .irq_clear = pdc_irq_clear, | 151 | .irq_clear = pdc_irq_clear, | 
| @@ -196,7 +203,7 @@ static const struct ata_port_info pdc_port_info[] = { | |||
| 196 | /* board_20619 */ | 203 | /* board_20619 */ | 
| 197 | { | 204 | { | 
| 198 | .sht = &pdc_ata_sht, | 205 | .sht = &pdc_ata_sht, | 
| 199 | .flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS, | 206 | .flags = PDC_COMMON_FLAGS | ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, | 
| 200 | .pio_mask = 0x1f, /* pio0-4 */ | 207 | .pio_mask = 0x1f, /* pio0-4 */ | 
| 201 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 208 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 
| 202 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ | 209 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ | 
| @@ -346,12 +353,6 @@ static void pdc_reset_port(struct ata_port *ap) | |||
| 346 | readl(mmio); /* flush */ | 353 | readl(mmio); /* flush */ | 
| 347 | } | 354 | } | 
| 348 | 355 | ||
| 349 | static void pdc_sata_phy_reset(struct ata_port *ap) | ||
| 350 | { | ||
| 351 | pdc_reset_port(ap); | ||
| 352 | sata_phy_reset(ap); | ||
| 353 | } | ||
| 354 | |||
| 355 | static void pdc_pata_cbl_detect(struct ata_port *ap) | 356 | static void pdc_pata_cbl_detect(struct ata_port *ap) | 
| 356 | { | 357 | { | 
| 357 | u8 tmp; | 358 | u8 tmp; | 
| @@ -419,6 +420,61 @@ static void pdc_qc_prep(struct ata_queued_cmd *qc) | |||
| 419 | } | 420 | } | 
| 420 | } | 421 | } | 
| 421 | 422 | ||
| 423 | static void pdc_freeze(struct ata_port *ap) | ||
| 424 | { | ||
| 425 | void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr; | ||
| 426 | u32 tmp; | ||
| 427 | |||
| 428 | tmp = readl(mmio + PDC_CTLSTAT); | ||
| 429 | tmp |= PDC_IRQ_DISABLE; | ||
| 430 | tmp &= ~PDC_DMA_ENABLE; | ||
| 431 | writel(tmp, mmio + PDC_CTLSTAT); | ||
| 432 | readl(mmio + PDC_CTLSTAT); /* flush */ | ||
| 433 | } | ||
| 434 | |||
| 435 | static void pdc_thaw(struct ata_port *ap) | ||
| 436 | { | ||
| 437 | void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr; | ||
| 438 | u32 tmp; | ||
| 439 | |||
| 440 | /* clear IRQ */ | ||
| 441 | readl(mmio + PDC_INT_SEQMASK); | ||
| 442 | |||
| 443 | /* turn IRQ back on */ | ||
| 444 | tmp = readl(mmio + PDC_CTLSTAT); | ||
| 445 | tmp &= ~PDC_IRQ_DISABLE; | ||
| 446 | writel(tmp, mmio + PDC_CTLSTAT); | ||
| 447 | readl(mmio + PDC_CTLSTAT); /* flush */ | ||
| 448 | } | ||
| 449 | |||
| 450 | static void pdc_error_handler(struct ata_port *ap) | ||
| 451 | { | ||
| 452 | ata_reset_fn_t hardreset; | ||
| 453 | |||
| 454 | if (!(ap->pflags & ATA_PFLAG_FROZEN)) | ||
| 455 | pdc_reset_port(ap); | ||
| 456 | |||
| 457 | hardreset = NULL; | ||
| 458 | if (sata_scr_valid(ap)) | ||
| 459 | hardreset = sata_std_hardreset; | ||
| 460 | |||
| 461 | /* perform recovery */ | ||
| 462 | ata_do_eh(ap, ata_std_prereset, ata_std_softreset, hardreset, | ||
| 463 | ata_std_postreset); | ||
| 464 | } | ||
| 465 | |||
| 466 | static void pdc_post_internal_cmd(struct ata_queued_cmd *qc) | ||
| 467 | { | ||
| 468 | struct ata_port *ap = qc->ap; | ||
| 469 | |||
| 470 | if (qc->flags & ATA_QCFLAG_FAILED) | ||
| 471 | qc->err_mask |= AC_ERR_OTHER; | ||
| 472 | |||
| 473 | /* make DMA engine forget about the failed command */ | ||
| 474 | if (qc->err_mask) | ||
| 475 | pdc_reset_port(ap); | ||
| 476 | } | ||
| 477 | |||
| 422 | static void pdc_eng_timeout(struct ata_port *ap) | 478 | static void pdc_eng_timeout(struct ata_port *ap) | 
| 423 | { | 479 | { | 
| 424 | struct ata_host *host = ap->host; | 480 | struct ata_host *host = ap->host; | 
