diff options
Diffstat (limited to 'drivers/ata/pata_sis.c')
-rw-r--r-- | drivers/ata/pata_sis.c | 70 |
1 files changed, 51 insertions, 19 deletions
diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c index 916cedb..560103d 100644 --- a/drivers/ata/pata_sis.c +++ b/drivers/ata/pata_sis.c @@ -32,7 +32,9 @@ #include <scsi/scsi_host.h> #include <linux/libata.h> #include <linux/ata.h> +#include "libata.h" +#undef DRV_NAME /* already defined in libata.h, for libata-core */ #define DRV_NAME "pata_sis" #define DRV_VERSION "0.4.5" @@ -43,6 +45,34 @@ struct sis_chipset { up code later */ }; +struct sis_laptop { + u16 device; + u16 subvendor; + u16 subdevice; +}; + +static const struct sis_laptop sis_laptop[] = { + /* devid, subvendor, subdev */ + { 0x5513, 0x1043, 0x1107 }, /* ASUS A6K */ + /* end marker */ + { 0, } +}; + +static int sis_short_ata40(struct pci_dev *dev) +{ + const struct sis_laptop *lap = &sis_laptop[0]; + + while (lap->device) { + if (lap->device == dev->device && + lap->subvendor == dev->subsystem_vendor && + lap->subdevice == dev->subsystem_device) + return 1; + lap++; + } + + return 0; +} + /** * sis_port_base - return PCI configuration base for dev * @adev: device @@ -79,7 +109,7 @@ static int sis_133_pre_reset(struct ata_port *ap) /* The top bit of this register is the cable detect bit */ pci_read_config_word(pdev, 0x50 + 2 * ap->port_no, &tmp); - if (tmp & 0x8000) + if ((tmp & 0x8000) && !sis_short_ata40(pdev)) ap->cbl = ATA_CBL_PATA40; else ap->cbl = ATA_CBL_PATA80; @@ -127,7 +157,7 @@ static int sis_66_pre_reset(struct ata_port *ap) /* Older chips keep cable detect in bits 4/5 of reg 0x48 */ pci_read_config_byte(pdev, 0x48, &tmp); tmp >>= ap->port_no; - if (tmp & 0x10) + if ((tmp & 0x10) && !sis_short_ata40(pdev)) ap->cbl = ATA_CBL_PATA40; else ap->cbl = ATA_CBL_PATA80; @@ -573,14 +603,14 @@ static const struct ata_port_operations sis_133_ops = { .bmdma_status = ata_bmdma_status, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - .data_xfer = ata_pio_data_xfer, + .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, - .port_stop = ata_port_stop, - .host_stop = ata_host_stop, }; static const struct ata_port_operations sis_133_early_ops = { @@ -606,14 +636,14 @@ static const struct ata_port_operations sis_133_early_ops = { .bmdma_status = ata_bmdma_status, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - .data_xfer = ata_pio_data_xfer, + .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, - .port_stop = ata_port_stop, - .host_stop = ata_host_stop, }; static const struct ata_port_operations sis_100_ops = { @@ -640,14 +670,14 @@ static const struct ata_port_operations sis_100_ops = { .bmdma_status = ata_bmdma_status, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - .data_xfer = ata_pio_data_xfer, + .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, - .port_stop = ata_port_stop, - .host_stop = ata_host_stop, }; static const struct ata_port_operations sis_66_ops = { @@ -673,14 +703,14 @@ static const struct ata_port_operations sis_66_ops = { .bmdma_status = ata_bmdma_status, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - .data_xfer = ata_pio_data_xfer, + .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, - .port_stop = ata_port_stop, - .host_stop = ata_host_stop, }; static const struct ata_port_operations sis_old_ops = { @@ -706,14 +736,14 @@ static const struct ata_port_operations sis_old_ops = { .bmdma_status = ata_bmdma_status, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - .data_xfer = ata_pio_data_xfer, + .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, - .port_stop = ata_port_stop, - .host_stop = ata_host_stop, }; static struct ata_port_info sis_info = { @@ -753,7 +783,7 @@ static struct ata_port_info sis_info100_early = { .pio_mask = 0x1f, /* pio0-4 */ .port_ops = &sis_66_ops, }; -static struct ata_port_info sis_info133 = { +struct ata_port_info sis_info133 = { .sht = &sis_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .pio_mask = 0x1f, /* pio0-4 */ @@ -768,6 +798,8 @@ static struct ata_port_info sis_info133_early = { .port_ops = &sis_133_early_ops, }; +/* Privately shared with the SiS180 SATA driver, not for use elsewhere */ +EXPORT_SYMBOL_GPL(sis_info133); static void sis_fixup(struct pci_dev *pdev, struct sis_chipset *sis) { @@ -847,7 +879,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) struct sis_chipset *chipset = NULL; static struct sis_chipset sis_chipsets[] = { - + { 0x0968, &sis_info133 }, { 0x0966, &sis_info133 }, { 0x0965, &sis_info133 }, |