libata: introduce sff_set_devctl() method
[safe/jmp/linux-2.6] / drivers / ata / libata-sff.c
index b313896..31b495f 100644 (file)
@@ -446,6 +446,27 @@ int ata_sff_wait_ready(struct ata_link *link, unsigned long deadline)
 EXPORT_SYMBOL_GPL(ata_sff_wait_ready);
 
 /**
+ *     ata_sff_set_devctl - Write device control reg
+ *     @ap: port where the device is
+ *     @ctl: value to write
+ *
+ *     Writes ATA taskfile device control register.
+ *
+ *     Note: may NOT be used as the sff_set_devctl() entry in
+ *     ata_port_operations.
+ *
+ *     LOCKING:
+ *     Inherited from caller.
+ */
+static void ata_sff_set_devctl(struct ata_port *ap, u8 ctl)
+{
+       if (ap->ops->sff_set_devctl)
+               ap->ops->sff_set_devctl(ap, ctl);
+       else
+               iowrite8(ctl, ap->ioaddr.ctl_addr);
+}
+
+/**
  *     ata_sff_dev_select - Select device 0/1 on ATA bus
  *     @ap: ATA channel to manipulate
  *     @device: ATA device (numbered from zero) to select
@@ -1895,13 +1916,11 @@ EXPORT_SYMBOL_GPL(ata_sff_lost_interrupt);
  */
 void ata_sff_freeze(struct ata_port *ap)
 {
-       struct ata_ioports *ioaddr = &ap->ioaddr;
-
        ap->ctl |= ATA_NIEN;
        ap->last_ctl = ap->ctl;
 
-       if (ioaddr->ctl_addr)
-               iowrite8(ap->ctl, ioaddr->ctl_addr);
+       if (ap->ops->sff_set_devctl || ap->ioaddr.ctl_addr)
+               ata_sff_set_devctl(ap, ap->ctl);
 
        /* Under certain circumstances, some controllers raise IRQ on
         * ATA_NIEN manipulation.  Also, many controllers fail to mask
@@ -2301,8 +2320,8 @@ void ata_sff_postreset(struct ata_link *link, unsigned int *classes)
        }
 
        /* set up device control */
-       if (ap->ioaddr.ctl_addr) {
-               iowrite8(ap->ctl, ap->ioaddr.ctl_addr);
+       if (ap->ops->sff_set_devctl || ap->ioaddr.ctl_addr) {
+               ata_sff_set_devctl(ap, ap->ctl);
                ap->last_ctl = ap->ctl;
        }
 }