+ struct ahci_port_priv *pp = ap->private_data;
+ void __iomem *mmio = ap->host_set->mmio_base;
+ void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
+ const u32 cmd_fis_len = 5; /* five dwords */
+ const char *reason = NULL;
+ struct ata_taskfile tf;
+ u32 tmp;
+ u8 *fis;
+ int rc;
+
+ DPRINTK("ENTER\n");
+
+ if (ata_port_offline(ap)) {
+ DPRINTK("PHY reports no device\n");
+ *class = ATA_DEV_NONE;
+ return 0;
+ }
+
+ /* prepare for SRST (AHCI-1.1 10.4.1) */
+ rc = ahci_stop_engine(ap);
+ if (rc) {
+ reason = "failed to stop engine";
+ goto fail_restart;
+ }
+
+ /* check BUSY/DRQ, perform Command List Override if necessary */
+ ahci_tf_read(ap, &tf);
+ if (tf.command & (ATA_BUSY | ATA_DRQ)) {
+ rc = ahci_clo(ap);
+
+ if (rc == -EOPNOTSUPP) {
+ reason = "port busy but CLO unavailable";
+ goto fail_restart;
+ } else if (rc) {
+ reason = "port busy but CLO failed";
+ goto fail_restart;
+ }
+ }
+
+ /* restart engine */
+ ahci_start_engine(ap);
+
+ ata_tf_init(ap->device, &tf);
+ fis = pp->cmd_tbl;
+
+ /* issue the first D2H Register FIS */
+ ahci_fill_cmd_slot(pp, 0,
+ cmd_fis_len | AHCI_CMD_RESET | AHCI_CMD_CLR_BUSY);
+
+ tf.ctl |= ATA_SRST;
+ ata_tf_to_fis(&tf, fis, 0);
+ fis[1] &= ~(1 << 7); /* turn off Command FIS bit */
+
+ writel(1, port_mmio + PORT_CMD_ISSUE);
+
+ tmp = ata_wait_register(port_mmio + PORT_CMD_ISSUE, 0x1, 0x1, 1, 500);
+ if (tmp & 0x1) {
+ rc = -EIO;
+ reason = "1st FIS failed";
+ goto fail;
+ }
+
+ /* spec says at least 5us, but be generous and sleep for 1ms */
+ msleep(1);
+
+ /* issue the second D2H Register FIS */
+ ahci_fill_cmd_slot(pp, 0, cmd_fis_len);
+
+ tf.ctl &= ~ATA_SRST;
+ ata_tf_to_fis(&tf, fis, 0);
+ fis[1] &= ~(1 << 7); /* turn off Command FIS bit */
+
+ writel(1, port_mmio + PORT_CMD_ISSUE);
+ readl(port_mmio + PORT_CMD_ISSUE); /* flush */
+
+ /* spec mandates ">= 2ms" before checking status.
+ * We wait 150ms, because that was the magic delay used for
+ * ATAPI devices in Hale Landis's ATADRVR, for the period of time
+ * between when the ATA command register is written, and then
+ * status is checked. Because waiting for "a while" before
+ * checking status is fine, post SRST, we perform this magic
+ * delay here as well.
+ */
+ msleep(150);
+
+ *class = ATA_DEV_NONE;
+ if (ata_port_online(ap)) {
+ if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) {
+ rc = -EIO;
+ reason = "device not ready";
+ goto fail;
+ }
+ *class = ahci_dev_classify(ap);
+ }
+
+ DPRINTK("EXIT, class=%u\n", *class);
+ return 0;
+
+ fail_restart:
+ ahci_start_engine(ap);
+ fail:
+ ata_port_printk(ap, KERN_ERR, "softreset failed (%s)\n", reason);
+ return rc;
+}
+
+static int ahci_hardreset(struct ata_port *ap, unsigned int *class)
+{
+ struct ahci_port_priv *pp = ap->private_data;
+ u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
+ struct ata_taskfile tf;