[libata sata_via] add support for VT6421 SATA
Linux Kernel Mailing List <[email protected]> Sun, 13 Feb 2005 18:27:08 +0000
| Newsgroups | gmane.linux.kernel.commits.2-4 |
|---|---|
| Message-ID | <[email protected]> |
ChangeSet 1.1537.6.2, 2005/02/13 13:27:08-05:00, [email protected] [libata sata_via] add support for VT6421 SATA sata_via.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 files changed, 84 insertions(+), 10 deletions(-) diff -Nru a/drivers/scsi/sata_via.c b/drivers/scsi/sata_via.c --- a/drivers/scsi/sata_via.c 2005-03-04 12:02:07 -08:00 +++ b/drivers/scsi/sata_via.c 2005-03-04 12:02:07 -08:00 @@ -24,6 +24,11 @@ If you do not delete the provisions above, a recipient may use your version of this file under either the OSL or the GPL. + ---------------------------------------------------------------------- + + To-do list: + * VT6421 PATA support + */ #include <linux/kernel.h> @@ -38,10 +43,11 @@ #include <asm/io.h> #define DRV_NAME "sata_via" -#define DRV_VERSION "1.0" +#define DRV_VERSION "1.1" enum board_ids_enum { vt6420, + vt6421, }; enum { @@ -67,6 +73,7 @@ static struct pci_device_id svia_pci_tbl[] = { { 0x1106, 0x3149, PCI_ANY_ID, PCI_ANY_ID, 0, 0, vt6420 }, + { 0x1106, 0x3249, PCI_ANY_ID, PCI_ANY_ID, 0, 0, vt6421 }, { } /* terminate list */ }; @@ -159,11 +166,39 @@ 8, 4, 8, 4, 16, 256 }; +static const unsigned int vt6421_bar_sizes[] = { + 16, 16, 16, 16, 32, 128 +}; + static unsigned long svia_scr_addr(unsigned long addr, unsigned int port) { return addr + (port * 128); } +static unsigned long vt6421_scr_addr(unsigned long addr, unsigned int port) +{ + return addr + (port * 64); +} + +static void vt6421_init_addrs(struct ata_probe_ent *probe_ent, + struct pci_dev *pdev, + unsigned int port) +{ + unsigned long reg_addr = pci_resource_start(pdev, port); + unsigned long bmdma_addr = pci_resource_start(pdev, 4) + (port * 8); + unsigned long scr_addr; + + probe_ent->port[port].cmd_addr = reg_addr; + probe_ent->port[port].altstatus_addr = + probe_ent->port[port].ctl_addr = (reg_addr + 8) | ATA_PCI_CTL_OFS; + probe_ent->port[port].bmdma_addr = bmdma_addr; + + scr_addr = vt6421_scr_addr(pci_resource_start(pdev, 5), port); + probe_ent->port[port].scr_addr = scr_addr; + + ata_std_ports(&probe_ent->port[port]); +} + static struct ata_probe_ent *vt6420_init_probe_ent(struct pci_dev *pdev) { struct ata_probe_ent *probe_ent; @@ -181,6 +216,36 @@ return probe_ent; } +static struct ata_probe_ent *vt6421_init_probe_ent(struct pci_dev *pdev) +{ + struct ata_probe_ent *probe_ent; + unsigned int i; + + probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL); + if (!probe_ent) + return NULL; + + memset(probe_ent, 0, sizeof(*probe_ent)); + probe_ent->dev = pci_dev_to_dev(pdev); + INIT_LIST_HEAD(&probe_ent->node); + + probe_ent->sht = &svia_sht; + probe_ent->host_flags = ATA_FLAG_SATA | ATA_FLAG_SATA_RESET | + ATA_FLAG_NO_LEGACY; + probe_ent->port_ops = &svia_sata_ops; + probe_ent->n_ports = N_PORTS; + probe_ent->irq = pdev->irq; + probe_ent->irq_flags = SA_SHIRQ; + probe_ent->pio_mask = 0x1f; + probe_ent->mwdma_mask = 0x07; + probe_ent->udma_mask = 0x7f; + + for (i = 0; i < N_PORTS; i++) + vt6421_init_addrs(probe_ent, pdev, i); + + return probe_ent; +} + static void svia_configure(struct pci_dev *pdev) { u8 tmp8; @@ -224,6 +289,7 @@ unsigned int i; int rc; struct ata_probe_ent *probe_ent; + int board_id = (int) ent->driver_data; const int *bar_sizes; u8 tmp8; @@ -238,15 +304,19 @@ if (rc) goto err_out; - pci_read_config_byte(pdev, SATA_PATA_SHARING, &tmp8); - if (tmp8 & SATA_2DEV) { - printk(KERN_ERR DRV_NAME "(%s): SATA master/slave not supported (0x%x)\n", - pci_name(pdev), (int) tmp8); - rc = -EIO; - goto err_out_regions; - } + if (board_id == vt6420) { + pci_read_config_byte(pdev, SATA_PATA_SHARING, &tmp8); + if (tmp8 & SATA_2DEV) { + printk(KERN_ERR DRV_NAME "(%s): SATA master/slave not supported (0x%x)\n", + pci_name(pdev), (int) tmp8); + rc = -EIO; + goto err_out_regions; + } - bar_sizes = &svia_bar_sizes[0]; + bar_sizes = &svia_bar_sizes[0]; + } else { + bar_sizes = &vt6421_bar_sizes[0]; + } for (i = 0; i < ARRAY_SIZE(svia_bar_sizes); i++) if ((pci_resource_start(pdev, i) == 0) || @@ -263,7 +333,11 @@ if (rc) goto err_out_regions; - probe_ent = vt6420_init_probe_ent(pdev); + if (board_id == vt6420) + probe_ent = vt6420_init_probe_ent(pdev); + else + probe_ent = vt6421_init_probe_ent(pdev); + if (!probe_ent) { printk(KERN_ERR DRV_NAME "(%s): out of memory\n", pci_name(pdev));