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 | |
| 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')
| -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 9c25a1e917..c1e32194b0 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); |
