diff options
author | Uwe Koziolek <uwe.koziolek@gmx.net> | 2006-12-03 19:34:42 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-02-09 17:39:28 -0500 |
commit | 3f3e7313e4e45f84c4d6e7b3bf91b5c9ad3e05cf (patch) | |
tree | b16aee48b8fdfa023b6a1ae136fad890c785d751 /drivers/ata/sata_sis.c | |
parent | eaefd5fb7d793c9c1bcef1b0c0d5ec3824a85b91 (diff) |
[PATCH] sata_sis: support SiS966/966L
The SiS966/966L has different PCI-IDs for native mode and AHCI mode.
The SiS966 supports four SATA ports only in native mode.
Added additional PCI-ID 0x0183 for SiS965/965L.
this patch is based on the code from David Wang from SiS Corporation published on SiS Website.
Signed-off-by: Uwe Koziolek <uwe.koziolek@gmx.net>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata/sata_sis.c')
-rw-r--r-- | drivers/ata/sata_sis.c | 79 |
1 files changed, 54 insertions, 25 deletions
diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c index 9c25a1e91730..c1e32194b09f 100644 --- a/drivers/ata/sata_sis.c +++ b/drivers/ata/sata_sis.c | |||
@@ -42,7 +42,7 @@ | |||
42 | #include <linux/libata.h> | 42 | #include <linux/libata.h> |
43 | 43 | ||
44 | #define DRV_NAME "sata_sis" | 44 | #define DRV_NAME "sata_sis" |
45 | #define DRV_VERSION "0.6" | 45 | #define DRV_VERSION "0.7" |
46 | 46 | ||
47 | enum { | 47 | enum { |
48 | sis_180 = 0, | 48 | sis_180 = 0, |
@@ -67,9 +67,12 @@ static u32 sis_scr_read (struct ata_port *ap, unsigned int sc_reg); | |||
67 | static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); | 67 | static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); |
68 | 68 | ||
69 | static const struct pci_device_id sis_pci_tbl[] = { | 69 | static const struct pci_device_id sis_pci_tbl[] = { |
70 | { PCI_VDEVICE(SI, 0x180), sis_180 }, | 70 | { PCI_VDEVICE(SI, 0x0180), sis_180 }, /* SiS 964/180 */ |
71 | { PCI_VDEVICE(SI, 0x181), sis_180 }, | 71 | { PCI_VDEVICE(SI, 0x0181), sis_180 }, /* SiS 964/180 */ |
72 | { PCI_VDEVICE(SI, 0x182), sis_180 }, | 72 | { PCI_VDEVICE(SI, 0x0182), sis_180 }, /* SiS 965/965L */ |
73 | { PCI_VDEVICE(SI, 0x0183), sis_180 }, /* SiS 965/965L */ | ||
74 | { PCI_VDEVICE(SI, 0x1182), sis_180 }, /* SiS 966/966L */ | ||
75 | { PCI_VDEVICE(SI, 0x1183), sis_180 }, /* SiS 966/966L */ | ||
73 | 76 | ||
74 | { } /* terminate list */ | 77 | { } /* terminate list */ |
75 | }; | 78 | }; |
@@ -142,24 +145,32 @@ MODULE_LICENSE("GPL"); | |||
142 | MODULE_DEVICE_TABLE(pci, sis_pci_tbl); | 145 | MODULE_DEVICE_TABLE(pci, sis_pci_tbl); |
143 | MODULE_VERSION(DRV_VERSION); | 146 | MODULE_VERSION(DRV_VERSION); |
144 | 147 | ||
145 | static unsigned int get_scr_cfg_addr(unsigned int port_no, unsigned int sc_reg, int device) | 148 | static unsigned int get_scr_cfg_addr(unsigned int port_no, unsigned int sc_reg, struct pci_dev *pdev) |
146 | { | 149 | { |
147 | unsigned int addr = SIS_SCR_BASE + (4 * sc_reg); | 150 | unsigned int addr = SIS_SCR_BASE + (4 * sc_reg); |
148 | 151 | ||
149 | if (port_no) { | 152 | if (port_no) { |
150 | if (device == 0x182) | 153 | switch (pdev->device) { |
151 | addr += SIS182_SATA1_OFS; | 154 | case 0x0180: |
152 | else | 155 | case 0x0181: |
153 | addr += SIS180_SATA1_OFS; | 156 | addr += SIS180_SATA1_OFS; |
157 | break; | ||
158 | |||
159 | case 0x0182: | ||
160 | case 0x0183: | ||
161 | case 0x1182: | ||
162 | case 0x1183: | ||
163 | addr += SIS182_SATA1_OFS; | ||
164 | break; | ||
165 | } | ||
154 | } | 166 | } |
155 | |||
156 | return addr; | 167 | return addr; |
157 | } | 168 | } |
158 | 169 | ||
159 | static u32 sis_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg) | 170 | static u32 sis_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg) |
160 | { | 171 | { |
161 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | 172 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); |
162 | unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, sc_reg, pdev->device); | 173 | unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, sc_reg, pdev); |
163 | u32 val, val2 = 0; | 174 | u32 val, val2 = 0; |
164 | u8 pmr; | 175 | u8 pmr; |
165 | 176 | ||
@@ -170,7 +181,8 @@ static u32 sis_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg) | |||
170 | 181 | ||
171 | pci_read_config_dword(pdev, cfg_addr, &val); | 182 | pci_read_config_dword(pdev, cfg_addr, &val); |
172 | 183 | ||
173 | if ((pdev->device == 0x182) || (pmr & SIS_PMR_COMBINED)) | 184 | if ((pdev->device == 0x0182) || (pdev->device == 0x0183) || (pdev->device == 0x1182) || |
185 | (pdev->device == 0x1183) || (pmr & SIS_PMR_COMBINED)) | ||
174 | pci_read_config_dword(pdev, cfg_addr+0x10, &val2); | 186 | pci_read_config_dword(pdev, cfg_addr+0x10, &val2); |
175 | 187 | ||
176 | return (val|val2) & 0xfffffffb; /* avoid problems with powerdowned ports */ | 188 | return (val|val2) & 0xfffffffb; /* avoid problems with powerdowned ports */ |
@@ -179,7 +191,7 @@ static u32 sis_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg) | |||
179 | static void sis_scr_cfg_write (struct ata_port *ap, unsigned int scr, u32 val) | 191 | static void sis_scr_cfg_write (struct ata_port *ap, unsigned int scr, u32 val) |
180 | { | 192 | { |
181 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | 193 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); |
182 | unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, scr, pdev->device); | 194 | unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, scr, pdev); |
183 | u8 pmr; | 195 | u8 pmr; |
184 | 196 | ||
185 | if (scr == SCR_ERROR) /* doesn't exist in PCI cfg space */ | 197 | if (scr == SCR_ERROR) /* doesn't exist in PCI cfg space */ |
@@ -189,7 +201,8 @@ static void sis_scr_cfg_write (struct ata_port *ap, unsigned int scr, u32 val) | |||
189 | 201 | ||
190 | pci_write_config_dword(pdev, cfg_addr, val); | 202 | pci_write_config_dword(pdev, cfg_addr, val); |
191 | 203 | ||
192 | if ((pdev->device == 0x182) || (pmr & SIS_PMR_COMBINED)) | 204 | if ((pdev->device == 0x0182) || (pdev->device == 0x0183) || (pdev->device == 0x1182) || |
205 | (pdev->device == 0x1183) || (pmr & SIS_PMR_COMBINED)) | ||
193 | pci_write_config_dword(pdev, cfg_addr+0x10, val); | 206 | pci_write_config_dword(pdev, cfg_addr+0x10, val); |
194 | } | 207 | } |
195 | 208 | ||
@@ -209,7 +222,8 @@ static u32 sis_scr_read (struct ata_port *ap, unsigned int sc_reg) | |||
209 | 222 | ||
210 | val = inl(ap->ioaddr.scr_addr + (sc_reg * 4)); | 223 | val = inl(ap->ioaddr.scr_addr + (sc_reg * 4)); |
211 | 224 | ||
212 | if ((pdev->device == 0x182) || (pmr & SIS_PMR_COMBINED)) | 225 | if ((pdev->device == 0x0182) || (pdev->device == 0x0183) || (pdev->device == 0x1182) || |
226 | (pdev->device == 0x1183) || (pmr & SIS_PMR_COMBINED)) | ||
213 | val2 = inl(ap->ioaddr.scr_addr + (sc_reg * 4) + 0x10); | 227 | val2 = inl(ap->ioaddr.scr_addr + (sc_reg * 4) + 0x10); |
214 | 228 | ||
215 | return (val | val2) & 0xfffffffb; | 229 | return (val | val2) & 0xfffffffb; |
@@ -229,7 +243,8 @@ static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) | |||
229 | sis_scr_cfg_write(ap, sc_reg, val); | 243 | sis_scr_cfg_write(ap, sc_reg, val); |
230 | else { | 244 | else { |
231 | outl(val, ap->ioaddr.scr_addr + (sc_reg * 4)); | 245 | outl(val, ap->ioaddr.scr_addr + (sc_reg * 4)); |
232 | if ((pdev->device == 0x182) || (pmr & SIS_PMR_COMBINED)) | 246 | if ((pdev->device == 0x0182) || (pdev->device == 0x0183) || (pdev->device == 0x1182) || |
247 | (pdev->device == 0x1183) || (pmr & SIS_PMR_COMBINED)) | ||
233 | outl(val, ap->ioaddr.scr_addr + (sc_reg * 4)+0x10); | 248 | outl(val, ap->ioaddr.scr_addr + (sc_reg * 4)+0x10); |
234 | } | 249 | } |
235 | } | 250 | } |
@@ -243,7 +258,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
243 | struct ata_port_info pi = sis_port_info, *ppi[2] = { &pi, &pi }; | 258 | struct ata_port_info pi = sis_port_info, *ppi[2] = { &pi, &pi }; |
244 | int pci_dev_busy = 0; | 259 | int pci_dev_busy = 0; |
245 | u8 pmr; | 260 | u8 pmr; |
246 | u8 port2_start; | 261 | u8 port2_start = 0x20; |
247 | 262 | ||
248 | if (!printed_version++) | 263 | if (!printed_version++) |
249 | dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n"); | 264 | dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n"); |
@@ -282,28 +297,42 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
282 | } | 297 | } |
283 | 298 | ||
284 | pci_read_config_byte(pdev, SIS_PMR, &pmr); | 299 | pci_read_config_byte(pdev, SIS_PMR, &pmr); |
285 | if (ent->device != 0x182) { | 300 | switch (ent->device) { |
301 | case 0x0180: | ||
302 | case 0x0181: | ||
286 | if ((pmr & SIS_PMR_COMBINED) == 0) { | 303 | if ((pmr & SIS_PMR_COMBINED) == 0) { |
287 | dev_printk(KERN_INFO, &pdev->dev, | 304 | dev_printk(KERN_INFO, &pdev->dev, |
288 | "Detected SiS 180/181/964 chipset in SATA mode\n"); | 305 | "Detected SiS 180/181/964 chipset in SATA mode\n"); |
289 | port2_start = 64; | 306 | port2_start = 64; |
290 | } | 307 | } else { |
291 | else { | ||
292 | dev_printk(KERN_INFO, &pdev->dev, | 308 | dev_printk(KERN_INFO, &pdev->dev, |
293 | "Detected SiS 180/181 chipset in combined mode\n"); | 309 | "Detected SiS 180/181 chipset in combined mode\n"); |
294 | port2_start=0; | 310 | port2_start=0; |
295 | pi.flags |= ATA_FLAG_SLAVE_POSS; | 311 | pi.flags |= ATA_FLAG_SLAVE_POSS; |
296 | } | 312 | } |
297 | } | 313 | break; |
298 | else { | 314 | |
315 | case 0x0182: | ||
316 | case 0x0183: | ||
299 | pci_read_config_dword ( pdev, 0x6C, &val); | 317 | pci_read_config_dword ( pdev, 0x6C, &val); |
300 | if (val & (1L << 31)) { | 318 | if (val & (1L << 31)) { |
301 | dev_printk(KERN_INFO, &pdev->dev, "Detected SiS 182/965 chipset\n"); | 319 | dev_printk(KERN_INFO, &pdev->dev, "Detected SiS 182/965 chipset\n"); |
302 | pi.flags |= ATA_FLAG_SLAVE_POSS; | 320 | pi.flags |= ATA_FLAG_SLAVE_POSS; |
303 | } | 321 | } else { |
304 | else | ||
305 | dev_printk(KERN_INFO, &pdev->dev, "Detected SiS 182/965L chipset\n"); | 322 | dev_printk(KERN_INFO, &pdev->dev, "Detected SiS 182/965L chipset\n"); |
306 | port2_start = 0x20; | 323 | } |
324 | break; | ||
325 | |||
326 | case 0x1182: | ||
327 | case 0x1183: | ||
328 | pci_read_config_dword(pdev, 0x64, &val); | ||
329 | if (val & 0x10000000) { | ||
330 | dev_printk(KERN_INFO, &pdev->dev, "Detected SiS 1182/1183/966L SATA controller\n"); | ||
331 | } else { | ||
332 | dev_printk(KERN_INFO, &pdev->dev, "Detected SiS 1182/1183/966 SATA controller\n"); | ||
333 | pi.flags |= ATA_FLAG_SLAVE_POSS; | ||
334 | } | ||
335 | break; | ||
307 | } | 336 | } |
308 | 337 | ||
309 | probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY); | 338 | probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY); |