0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/kernel.h>
0012 #include <linux/module.h>
0013 #include <linux/gfp.h>
0014 #include <linux/pci.h>
0015 #include <linux/blkdev.h>
0016 #include <linux/delay.h>
0017 #include <linux/interrupt.h>
0018 #include <linux/device.h>
0019 #include <scsi/scsi_host.h>
0020 #include <linux/libata.h>
0021
0022 #define DRV_NAME "sata_uli"
0023 #define DRV_VERSION "1.3"
0024
0025 enum {
0026 uli_5289 = 0,
0027 uli_5287 = 1,
0028 uli_5281 = 2,
0029
0030 uli_max_ports = 4,
0031
0032
0033 ULI5287_BASE = 0x90,
0034 ULI5287_OFFS = 0x10,
0035 ULI5281_BASE = 0x60,
0036 ULI5281_OFFS = 0x60,
0037 };
0038
0039 struct uli_priv {
0040 unsigned int scr_cfg_addr[uli_max_ports];
0041 };
0042
0043 static int uli_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
0044 static int uli_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val);
0045 static int uli_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val);
0046
0047 static const struct pci_device_id uli_pci_tbl[] = {
0048 { PCI_VDEVICE(AL, 0x5289), uli_5289 },
0049 { PCI_VDEVICE(AL, 0x5287), uli_5287 },
0050 { PCI_VDEVICE(AL, 0x5281), uli_5281 },
0051
0052 { }
0053 };
0054
0055 static struct pci_driver uli_pci_driver = {
0056 .name = DRV_NAME,
0057 .id_table = uli_pci_tbl,
0058 .probe = uli_init_one,
0059 .remove = ata_pci_remove_one,
0060 };
0061
0062 static struct scsi_host_template uli_sht = {
0063 ATA_BMDMA_SHT(DRV_NAME),
0064 };
0065
0066 static struct ata_port_operations uli_ops = {
0067 .inherits = &ata_bmdma_port_ops,
0068 .scr_read = uli_scr_read,
0069 .scr_write = uli_scr_write,
0070 .hardreset = ATA_OP_NULL,
0071 };
0072
0073 static const struct ata_port_info uli_port_info = {
0074 .flags = ATA_FLAG_SATA | ATA_FLAG_IGN_SIMPLEX,
0075 .pio_mask = ATA_PIO4,
0076 .udma_mask = ATA_UDMA6,
0077 .port_ops = &uli_ops,
0078 };
0079
0080
0081 MODULE_AUTHOR("Peer Chen");
0082 MODULE_DESCRIPTION("low-level driver for ULi Electronics SATA controller");
0083 MODULE_LICENSE("GPL");
0084 MODULE_DEVICE_TABLE(pci, uli_pci_tbl);
0085 MODULE_VERSION(DRV_VERSION);
0086
0087 static unsigned int get_scr_cfg_addr(struct ata_port *ap, unsigned int sc_reg)
0088 {
0089 struct uli_priv *hpriv = ap->host->private_data;
0090 return hpriv->scr_cfg_addr[ap->port_no] + (4 * sc_reg);
0091 }
0092
0093 static u32 uli_scr_cfg_read(struct ata_link *link, unsigned int sc_reg)
0094 {
0095 struct pci_dev *pdev = to_pci_dev(link->ap->host->dev);
0096 unsigned int cfg_addr = get_scr_cfg_addr(link->ap, sc_reg);
0097 u32 val;
0098
0099 pci_read_config_dword(pdev, cfg_addr, &val);
0100 return val;
0101 }
0102
0103 static void uli_scr_cfg_write(struct ata_link *link, unsigned int scr, u32 val)
0104 {
0105 struct pci_dev *pdev = to_pci_dev(link->ap->host->dev);
0106 unsigned int cfg_addr = get_scr_cfg_addr(link->ap, scr);
0107
0108 pci_write_config_dword(pdev, cfg_addr, val);
0109 }
0110
0111 static int uli_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val)
0112 {
0113 if (sc_reg > SCR_CONTROL)
0114 return -EINVAL;
0115
0116 *val = uli_scr_cfg_read(link, sc_reg);
0117 return 0;
0118 }
0119
0120 static int uli_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val)
0121 {
0122 if (sc_reg > SCR_CONTROL)
0123 return -EINVAL;
0124
0125 uli_scr_cfg_write(link, sc_reg, val);
0126 return 0;
0127 }
0128
0129 static int uli_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
0130 {
0131 const struct ata_port_info *ppi[] = { &uli_port_info, NULL };
0132 unsigned int board_idx = (unsigned int) ent->driver_data;
0133 struct ata_host *host;
0134 struct uli_priv *hpriv;
0135 void __iomem * const *iomap;
0136 struct ata_ioports *ioaddr;
0137 int n_ports, rc;
0138
0139 ata_print_version_once(&pdev->dev, DRV_VERSION);
0140
0141 rc = pcim_enable_device(pdev);
0142 if (rc)
0143 return rc;
0144
0145 n_ports = 2;
0146 if (board_idx == uli_5287)
0147 n_ports = 4;
0148
0149
0150 host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports);
0151 if (!host)
0152 return -ENOMEM;
0153
0154 hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
0155 if (!hpriv)
0156 return -ENOMEM;
0157 host->private_data = hpriv;
0158
0159
0160 rc = ata_pci_sff_init_host(host);
0161 if (rc)
0162 return rc;
0163
0164 ata_pci_bmdma_init(host);
0165
0166 iomap = host->iomap;
0167
0168 switch (board_idx) {
0169 case uli_5287:
0170
0171
0172
0173 hpriv->scr_cfg_addr[0] = ULI5287_BASE;
0174 hpriv->scr_cfg_addr[1] = ULI5287_BASE + ULI5287_OFFS;
0175
0176 ioaddr = &host->ports[2]->ioaddr;
0177 ioaddr->cmd_addr = iomap[0] + 8;
0178 ioaddr->altstatus_addr =
0179 ioaddr->ctl_addr = (void __iomem *)
0180 ((unsigned long)iomap[1] | ATA_PCI_CTL_OFS) + 4;
0181 ioaddr->bmdma_addr = iomap[4] + 16;
0182 hpriv->scr_cfg_addr[2] = ULI5287_BASE + ULI5287_OFFS*4;
0183 ata_sff_std_ports(ioaddr);
0184
0185 ata_port_desc(host->ports[2],
0186 "cmd 0x%llx ctl 0x%llx bmdma 0x%llx",
0187 (unsigned long long)pci_resource_start(pdev, 0) + 8,
0188 ((unsigned long long)pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS) + 4,
0189 (unsigned long long)pci_resource_start(pdev, 4) + 16);
0190
0191 ioaddr = &host->ports[3]->ioaddr;
0192 ioaddr->cmd_addr = iomap[2] + 8;
0193 ioaddr->altstatus_addr =
0194 ioaddr->ctl_addr = (void __iomem *)
0195 ((unsigned long)iomap[3] | ATA_PCI_CTL_OFS) + 4;
0196 ioaddr->bmdma_addr = iomap[4] + 24;
0197 hpriv->scr_cfg_addr[3] = ULI5287_BASE + ULI5287_OFFS*5;
0198 ata_sff_std_ports(ioaddr);
0199
0200 ata_port_desc(host->ports[2],
0201 "cmd 0x%llx ctl 0x%llx bmdma 0x%llx",
0202 (unsigned long long)pci_resource_start(pdev, 2) + 9,
0203 ((unsigned long long)pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS) + 4,
0204 (unsigned long long)pci_resource_start(pdev, 4) + 24);
0205
0206 break;
0207
0208 case uli_5289:
0209 hpriv->scr_cfg_addr[0] = ULI5287_BASE;
0210 hpriv->scr_cfg_addr[1] = ULI5287_BASE + ULI5287_OFFS;
0211 break;
0212
0213 case uli_5281:
0214 hpriv->scr_cfg_addr[0] = ULI5281_BASE;
0215 hpriv->scr_cfg_addr[1] = ULI5281_BASE + ULI5281_OFFS;
0216 break;
0217
0218 default:
0219 BUG();
0220 break;
0221 }
0222
0223 pci_set_master(pdev);
0224 pci_intx(pdev, 1);
0225 return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt,
0226 IRQF_SHARED, &uli_sht);
0227 }
0228
0229 module_pci_driver(uli_pci_driver);