diff options
Diffstat (limited to 'drivers/scsi/ahci.c')
-rw-r--r-- | drivers/scsi/ahci.c | 46 |
1 files changed, 29 insertions, 17 deletions
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index 72bdd434159e..86bccb7128f9 100644 --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c | |||
@@ -190,7 +190,7 @@ static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); | |||
190 | static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); | 190 | static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); |
191 | static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc); | 191 | static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc); |
192 | static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs *regs); | 192 | static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs *regs); |
193 | static void ahci_phy_reset(struct ata_port *ap); | 193 | static int ahci_probe_reset(struct ata_port *ap, unsigned int *classes); |
194 | static void ahci_irq_clear(struct ata_port *ap); | 194 | static void ahci_irq_clear(struct ata_port *ap); |
195 | static void ahci_eng_timeout(struct ata_port *ap); | 195 | static void ahci_eng_timeout(struct ata_port *ap); |
196 | static int ahci_port_start(struct ata_port *ap); | 196 | static int ahci_port_start(struct ata_port *ap); |
@@ -230,7 +230,7 @@ static const struct ata_port_operations ahci_ops = { | |||
230 | 230 | ||
231 | .tf_read = ahci_tf_read, | 231 | .tf_read = ahci_tf_read, |
232 | 232 | ||
233 | .phy_reset = ahci_phy_reset, | 233 | .probe_reset = ahci_probe_reset, |
234 | 234 | ||
235 | .qc_prep = ahci_qc_prep, | 235 | .qc_prep = ahci_qc_prep, |
236 | .qc_issue = ahci_qc_issue, | 236 | .qc_issue = ahci_qc_issue, |
@@ -252,8 +252,7 @@ static const struct ata_port_info ahci_port_info[] = { | |||
252 | { | 252 | { |
253 | .sht = &ahci_sht, | 253 | .sht = &ahci_sht, |
254 | .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 254 | .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
255 | ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO | | 255 | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA, |
256 | ATA_FLAG_PIO_DMA, | ||
257 | .pio_mask = 0x1f, /* pio0-4 */ | 256 | .pio_mask = 0x1f, /* pio0-4 */ |
258 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ | 257 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ |
259 | .port_ops = &ahci_ops, | 258 | .port_ops = &ahci_ops, |
@@ -515,28 +514,35 @@ static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, u32 opts) | |||
515 | pp->cmd_slot[0].tbl_addr_hi = cpu_to_le32((pp->cmd_tbl_dma >> 16) >> 16); | 514 | pp->cmd_slot[0].tbl_addr_hi = cpu_to_le32((pp->cmd_tbl_dma >> 16) >> 16); |
516 | } | 515 | } |
517 | 516 | ||
518 | static void ahci_phy_reset(struct ata_port *ap) | 517 | static int ahci_hardreset(struct ata_port *ap, int verbose, unsigned int *class) |
519 | { | 518 | { |
520 | void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; | 519 | int rc; |
521 | struct ata_device *dev = &ap->device[0]; | 520 | |
522 | u32 new_tmp, tmp; | 521 | DPRINTK("ENTER\n"); |
523 | 522 | ||
524 | ahci_stop_engine(ap); | 523 | ahci_stop_engine(ap); |
525 | __sata_phy_reset(ap); | 524 | rc = sata_std_hardreset(ap, verbose, class); |
526 | ahci_start_engine(ap); | 525 | ahci_start_engine(ap); |
527 | 526 | ||
528 | if (ap->flags & ATA_FLAG_PORT_DISABLED) | 527 | if (rc == 0) |
529 | return; | 528 | *class = ahci_dev_classify(ap); |
529 | if (*class == ATA_DEV_UNKNOWN) | ||
530 | *class = ATA_DEV_NONE; | ||
530 | 531 | ||
531 | dev->class = ahci_dev_classify(ap); | 532 | DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class); |
532 | if (!ata_dev_present(dev)) { | 533 | return rc; |
533 | ata_port_disable(ap); | 534 | } |
534 | return; | 535 | |
535 | } | 536 | static void ahci_postreset(struct ata_port *ap, unsigned int *class) |
537 | { | ||
538 | void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; | ||
539 | u32 new_tmp, tmp; | ||
540 | |||
541 | ata_std_postreset(ap, class); | ||
536 | 542 | ||
537 | /* Make sure port's ATAPI bit is set appropriately */ | 543 | /* Make sure port's ATAPI bit is set appropriately */ |
538 | new_tmp = tmp = readl(port_mmio + PORT_CMD); | 544 | new_tmp = tmp = readl(port_mmio + PORT_CMD); |
539 | if (dev->class == ATA_DEV_ATAPI) | 545 | if (*class == ATA_DEV_ATAPI) |
540 | new_tmp |= PORT_CMD_ATAPI; | 546 | new_tmp |= PORT_CMD_ATAPI; |
541 | else | 547 | else |
542 | new_tmp &= ~PORT_CMD_ATAPI; | 548 | new_tmp &= ~PORT_CMD_ATAPI; |
@@ -546,6 +552,12 @@ static void ahci_phy_reset(struct ata_port *ap) | |||
546 | } | 552 | } |
547 | } | 553 | } |
548 | 554 | ||
555 | static int ahci_probe_reset(struct ata_port *ap, unsigned int *classes) | ||
556 | { | ||
557 | return ata_drive_probe_reset(ap, NULL, NULL, ahci_hardreset, | ||
558 | ahci_postreset, classes); | ||
559 | } | ||
560 | |||
549 | static u8 ahci_check_status(struct ata_port *ap) | 561 | static u8 ahci_check_status(struct ata_port *ap) |
550 | { | 562 | { |
551 | void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr; | 563 | void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr; |