-/**
- * vt6420_prereset - prereset for vt6420
- * @ap: target ATA port
- *
- * SCR registers on vt6420 are pieces of shit and may hang the
- * whole machine completely if accessed with the wrong timing.
- * To avoid such catastrophe, vt6420 doesn't provide generic SCR
- * access operations, but uses SStatus and SControl only during
- * boot probing in controlled way.
- *
- * As the old (pre EH update) probing code is proven to work, we
- * strictly follow the access pattern.
- *
- * LOCKING:
- * Kernel thread context (may sleep)
- *
- * RETURNS:
- * 0 on success, -errno otherwise.
- */
-static int vt6420_prereset(struct ata_port *ap)
-{
- struct ata_eh_context *ehc = &ap->eh_context;
- unsigned long timeout = jiffies + (HZ * 5);
- u32 sstatus, scontrol;
- int online;
-
- /* don't do any SCR stuff if we're not loading */
- if (!ATA_PFLAG_LOADING)
- goto skip_scr;
-
- /* Resume phy. This is the old resume sequence from
- * __sata_phy_reset().
- */
- svia_scr_write(ap, SCR_CONTROL, 0x300);
- svia_scr_read(ap, SCR_CONTROL); /* flush */
-
- /* wait for phy to become ready, if necessary */
- do {
- msleep(200);
- if ((svia_scr_read(ap, SCR_STATUS) & 0xf) != 1)
- break;
- } while (time_before(jiffies, timeout));
-
- /* open code sata_print_link_status() */
- sstatus = svia_scr_read(ap, SCR_STATUS);
- scontrol = svia_scr_read(ap, SCR_CONTROL);
-
- online = (sstatus & 0xf) == 0x3;
-
- ata_port_printk(ap, KERN_INFO,
- "SATA link %s 1.5 Gbps (SStatus %X SControl %X)\n",
- online ? "up" : "down", sstatus, scontrol);
-
- /* SStatus is read one more time */
- svia_scr_read(ap, SCR_STATUS);
-
- if (!online) {
- /* tell EH to bail */
- ehc->i.action &= ~ATA_EH_RESET_MASK;
- return 0;
- }
-
- skip_scr:
- /* wait for !BSY */
- ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
-
- return 0;
-}
-
-static void vt6420_error_handler(struct ata_port *ap)
-{
- return ata_bmdma_drive_eh(ap, vt6420_prereset, ata_std_softreset,
- NULL, ata_std_postreset);
-}
-