libata: PATA-mode fixes for sis_sata
[sfrench/cifs-2.6.git] / drivers / ata / pata_sis.c
index a3fbcee6fb330185ebf97ba10ecf9cb711862530..cfe4ec6eb3d5d9955a1ac850dd22696a2711401d 100644 (file)
@@ -38,8 +38,8 @@
 #define DRV_VERSION    "0.5.1"
 
 struct sis_chipset {
-       u16 device;                     /* PCI host ID */
-       struct ata_port_info *info;     /* Info block */
+       u16 device;                             /* PCI host ID */
+       const struct ata_port_info *info;       /* Info block */
        /* Probably add family, cable detect type etc here to clean
           up code later */
 };
@@ -73,14 +73,14 @@ static int sis_short_ata40(struct pci_dev *dev)
 }
 
 /**
- *     sis_port_base           -       return PCI configuration base for dev
+ *     sis_old_port_base               -       return PCI configuration base for dev
  *     @adev: device
  *
  *     Returns the base of the PCI configuration registers for this port
  *     number.
  */
 
-static int sis_port_base(struct ata_device *adev)
+static int sis_old_port_base(struct ata_device *adev)
 {
        return  0x40 + (4 * adev->ap->port_no) +  (2 * adev->devno);
 }
@@ -88,6 +88,7 @@ static int sis_port_base(struct ata_device *adev)
 /**
  *     sis_133_cable_detect    -       check for 40/80 pin
  *     @ap: Port
+ *     @deadline: deadline jiffies for the operation
  *
  *     Perform cable detection for the later UDMA133 capable
  *     SiS chipset.
@@ -108,6 +109,7 @@ static int sis_133_cable_detect(struct ata_port *ap)
 /**
  *     sis_66_cable_detect     -       check for 40/80 pin
  *     @ap: Port
+ *     @deadline: deadline jiffies for the operation
  *
  *     Perform cable detection on the UDMA66, UDMA100 and early UDMA133
  *     SiS IDE controllers.
@@ -130,11 +132,12 @@ static int sis_66_cable_detect(struct ata_port *ap)
 /**
  *     sis_pre_reset           -       probe begin
  *     @ap: ATA port
+ *     @deadline: deadline jiffies for the operation
  *
  *     Set up cable type and use generic probe init
  */
 
-static int sis_pre_reset(struct ata_port *ap)
+static int sis_pre_reset(struct ata_port *ap, unsigned long deadline)
 {
        static const struct pci_bits sis_enable_bits[] = {
                { 0x4aU, 1U, 0x02UL, 0x02UL },  /* port 0 */
@@ -145,7 +148,8 @@ static int sis_pre_reset(struct ata_port *ap)
 
        if (!pci_test_config_bits(pdev, &sis_enable_bits[ap->port_no]))
                return -ENOENT;
-       return ata_std_prereset(ap);
+
+       return ata_std_prereset(ap, deadline);
 }
 
 
@@ -207,7 +211,7 @@ static void sis_set_fifo(struct ata_port *ap, struct ata_device *adev)
 static void sis_old_set_piomode (struct ata_port *ap, struct ata_device *adev)
 {
        struct pci_dev *pdev    = to_pci_dev(ap->host->dev);
-       int port = sis_port_base(adev);
+       int port = sis_old_port_base(adev);
        u8 t1, t2;
        int speed = adev->pio_mode - XFER_PIO_0;
 
@@ -244,7 +248,7 @@ static void sis_old_set_piomode (struct ata_port *ap, struct ata_device *adev)
 static void sis_100_set_piomode (struct ata_port *ap, struct ata_device *adev)
 {
        struct pci_dev *pdev    = to_pci_dev(ap->host->dev);
-       int port = sis_port_base(adev);
+       int port = sis_old_port_base(adev);
        int speed = adev->pio_mode - XFER_PIO_0;
 
        const u8 actrec[] = { 0x00, 0x67, 0x44, 0x33, 0x31 };
@@ -324,7 +328,7 @@ static void sis_old_set_dmamode (struct ata_port *ap, struct ata_device *adev)
 {
        struct pci_dev *pdev    = to_pci_dev(ap->host->dev);
        int speed = adev->dma_mode - XFER_MW_DMA_0;
-       int drive_pci = sis_port_base(adev);
+       int drive_pci = sis_old_port_base(adev);
        u16 timing;
 
        const u16 mwdma_bits[] = { 0x707, 0x202, 0x202 };
@@ -363,7 +367,7 @@ static void sis_66_set_dmamode (struct ata_port *ap, struct ata_device *adev)
 {
        struct pci_dev *pdev    = to_pci_dev(ap->host->dev);
        int speed = adev->dma_mode - XFER_MW_DMA_0;
-       int drive_pci = sis_port_base(adev);
+       int drive_pci = sis_old_port_base(adev);
        u16 timing;
 
        const u16 mwdma_bits[] = { 0x707, 0x202, 0x202 };
@@ -374,12 +378,12 @@ static void sis_66_set_dmamode (struct ata_port *ap, struct ata_device *adev)
        if (adev->dma_mode < XFER_UDMA_0) {
                /* bits 3-0 hold recovery timing bits 8-10 active timing and
                   the higer bits are dependant on the device, bit 15 udma */
-               timing &= ~ 0x870F;
+               timing &= ~0x870F;
                timing |= mwdma_bits[speed];
        } else {
                /* Bit 15 is UDMA on/off, bit 12-14 are cycle time */
                speed = adev->dma_mode - XFER_UDMA_0;
-               timing &= ~0x6000;
+               timing &= ~0xF000;
                timing |= udma_bits[speed];
        }
        pci_write_config_word(pdev, drive_pci, timing);
@@ -401,22 +405,22 @@ static void sis_100_set_dmamode (struct ata_port *ap, struct ata_device *adev)
 {
        struct pci_dev *pdev    = to_pci_dev(ap->host->dev);
        int speed = adev->dma_mode - XFER_MW_DMA_0;
-       int drive_pci = sis_port_base(adev);
-       u16 timing;
+       int drive_pci = sis_old_port_base(adev);
+       u8 timing;
 
-       const u16 udma_bits[]  = { 0x8B00, 0x8700, 0x8500, 0x8300, 0x8200, 0x8100};
+       const u8 udma_bits[]  = { 0x8B, 0x87, 0x85, 0x83, 0x82, 0x81};
 
-       pci_read_config_word(pdev, drive_pci, &timing);
+       pci_read_config_byte(pdev, drive_pci + 1, &timing);
 
        if (adev->dma_mode < XFER_UDMA_0) {
                /* NOT SUPPORTED YET: NEED DATA SHEET. DITTO IN OLD DRIVER */
        } else {
-               /* Bit 15 is UDMA on/off, bit 12-14 are cycle time */
+               /* Bit 7 is UDMA on/off, bit 0-3 are cycle time */
                speed = adev->dma_mode - XFER_UDMA_0;
-               timing &= ~0x0F00;
+               timing &= ~0x8F;
                timing |= udma_bits[speed];
        }
-       pci_write_config_word(pdev, drive_pci, timing);
+       pci_write_config_byte(pdev, drive_pci + 1, timing);
 }
 
 /**
@@ -436,22 +440,22 @@ static void sis_133_early_set_dmamode (struct ata_port *ap, struct ata_device *a
 {
        struct pci_dev *pdev    = to_pci_dev(ap->host->dev);
        int speed = adev->dma_mode - XFER_MW_DMA_0;
-       int drive_pci = sis_port_base(adev);
-       u16 timing;
-
-       static const u16 udma_bits[]  = { 0x8F00, 0x8A00, 0x8700, 0x8500, 0x8300, 0x8200, 0x8100};
+       int drive_pci = sis_old_port_base(adev);
+       u8 timing;
+       /* Low 4 bits are timing */
+       static const u8 udma_bits[]  = { 0x8F, 0x8A, 0x87, 0x85, 0x83, 0x82, 0x81};
 
-       pci_read_config_word(pdev, drive_pci, &timing);
+       pci_read_config_byte(pdev, drive_pci + 1, &timing);
 
        if (adev->dma_mode < XFER_UDMA_0) {
                /* NOT SUPPORTED YET: NEED DATA SHEET. DITTO IN OLD DRIVER */
        } else {
-               /* Bit 15 is UDMA on/off, bit 12-14 are cycle time */
+               /* Bit 7 is UDMA on/off, bit 0-3 are cycle time */
                speed = adev->dma_mode - XFER_UDMA_0;
-               timing &= ~0x0F00;
+               timing &= ~0x8F;
                timing |= udma_bits[speed];
        }
-       pci_write_config_word(pdev, drive_pci, timing);
+       pci_write_config_byte(pdev, drive_pci + 1, timing);
 }
 
 /**
@@ -520,10 +524,6 @@ static struct scsi_host_template sis_sht = {
        .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .resume                 = ata_scsi_device_resume,
-       .suspend                = ata_scsi_device_suspend,
-#endif
 };
 
 static const struct ata_port_operations sis_133_ops = {
@@ -560,6 +560,40 @@ static const struct ata_port_operations sis_133_ops = {
        .port_start             = ata_port_start,
 };
 
+static const struct ata_port_operations sis_133_for_sata_ops = {
+       .port_disable           = ata_port_disable,
+       .set_piomode            = sis_133_set_piomode,
+       .set_dmamode            = sis_133_set_dmamode,
+       .mode_filter            = ata_pci_default_filter,
+
+       .tf_load                = ata_tf_load,
+       .tf_read                = ata_tf_read,
+       .check_status           = ata_check_status,
+       .exec_command           = ata_exec_command,
+       .dev_select             = ata_std_dev_select,
+
+       .freeze                 = ata_bmdma_freeze,
+       .thaw                   = ata_bmdma_thaw,
+       .error_handler          = ata_bmdma_error_handler,
+       .post_internal_cmd      = ata_bmdma_post_internal_cmd,
+       .cable_detect           = sis_133_cable_detect,
+
+       .bmdma_setup            = ata_bmdma_setup,
+       .bmdma_start            = ata_bmdma_start,
+       .bmdma_stop             = ata_bmdma_stop,
+       .bmdma_status           = ata_bmdma_status,
+       .qc_prep                = ata_qc_prep,
+       .qc_issue               = ata_qc_issue_prot,
+       .data_xfer              = ata_data_xfer,
+
+       .irq_handler            = ata_interrupt,
+       .irq_clear              = ata_bmdma_irq_clear,
+       .irq_on                 = ata_irq_on,
+       .irq_ack                = ata_irq_ack,
+
+       .port_start             = ata_port_start,
+};
+
 static const struct ata_port_operations sis_133_early_ops = {
        .port_disable           = ata_port_disable,
        .set_piomode            = sis_100_set_piomode,
@@ -696,7 +730,7 @@ static const struct ata_port_operations sis_old_ops = {
        .port_start             = ata_port_start,
 };
 
-static struct ata_port_info sis_info = {
+static const struct ata_port_info sis_info = {
        .sht            = &sis_sht,
        .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
        .pio_mask       = 0x1f, /* pio0-4 */
@@ -704,7 +738,7 @@ static struct ata_port_info sis_info = {
        .udma_mask      = 0,
        .port_ops       = &sis_old_ops,
 };
-static struct ata_port_info sis_info33 = {
+static const struct ata_port_info sis_info33 = {
        .sht            = &sis_sht,
        .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
        .pio_mask       = 0x1f, /* pio0-4 */
@@ -712,35 +746,42 @@ static struct ata_port_info sis_info33 = {
        .udma_mask      = ATA_UDMA2,    /* UDMA 33 */
        .port_ops       = &sis_old_ops,
 };
-static struct ata_port_info sis_info66 = {
+static const struct ata_port_info sis_info66 = {
        .sht            = &sis_sht,
        .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
        .pio_mask       = 0x1f, /* pio0-4 */
        .udma_mask      = ATA_UDMA4,    /* UDMA 66 */
        .port_ops       = &sis_66_ops,
 };
-static struct ata_port_info sis_info100 = {
+static const struct ata_port_info sis_info100 = {
        .sht            = &sis_sht,
        .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
        .pio_mask       = 0x1f, /* pio0-4 */
        .udma_mask      = ATA_UDMA5,
        .port_ops       = &sis_100_ops,
 };
-static struct ata_port_info sis_info100_early = {
+static const struct ata_port_info sis_info100_early = {
        .sht            = &sis_sht,
        .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
        .udma_mask      = ATA_UDMA5,
        .pio_mask       = 0x1f, /* pio0-4 */
        .port_ops       = &sis_66_ops,
 };
-struct ata_port_info sis_info133 = {
+static const struct ata_port_info sis_info133 = {
        .sht            = &sis_sht,
        .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
        .pio_mask       = 0x1f, /* pio0-4 */
        .udma_mask      = ATA_UDMA6,
        .port_ops       = &sis_133_ops,
 };
-static struct ata_port_info sis_info133_early = {
+const struct ata_port_info sis_info133_for_sata = {
+       .sht            = &sis_sht,
+       .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+       .pio_mask       = 0x1f, /* pio0-4 */
+       .udma_mask      = ATA_UDMA6,
+       .port_ops       = &sis_133_for_sata_ops,
+};
+static const struct ata_port_info sis_info133_early = {
        .sht            = &sis_sht,
        .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
        .pio_mask       = 0x1f, /* pio0-4 */
@@ -749,7 +790,7 @@ static struct ata_port_info sis_info133_early = {
 };
 
 /* Privately shared with the SiS180 SATA driver, not for use elsewhere */
-EXPORT_SYMBOL_GPL(sis_info133);
+EXPORT_SYMBOL_GPL(sis_info133_for_sata);
 
 static void sis_fixup(struct pci_dev *pdev, struct sis_chipset *sis)
 {
@@ -823,8 +864,8 @@ static void sis_fixup(struct pci_dev *pdev, struct sis_chipset *sis)
 static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version;
-       static struct ata_port_info *port_info[2];
-       struct ata_port_info *port;
+       struct ata_port_info port;
+       const struct ata_port_info *ppi[] = { &port, NULL };
        struct pci_dev *host = NULL;
        struct sis_chipset *chipset = NULL;
        struct sis_chipset *sets;
@@ -964,18 +1005,18 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        if (chipset == NULL)
                return -ENODEV;
 
-       port = chipset->info;
-       port->private_data = chipset;
+       port = *chipset->info;
+       port.private_data = chipset;
 
        sis_fixup(pdev, chipset);
 
-       port_info[0] = port_info[1] = port;
-       return ata_pci_init_one(pdev, port_info, 2);
+       return ata_pci_init_one(pdev, ppi);
 }
 
 static const struct pci_device_id sis_pci_tbl[] = {
        { PCI_VDEVICE(SI, 0x5513), },   /* SiS 5513 */
        { PCI_VDEVICE(SI, 0x5518), },   /* SiS 5518 */
+       { PCI_VDEVICE(SI, 0x1180), },   /* SiS 1180 */
 
        { }
 };