diff options
author | Tejun Heo <htejun@gmail.com> | 2007-02-26 06:16:13 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-03-01 20:19:45 -0500 |
commit | 5ee2ae7fb2079c5775d8802cd282140d71632a2d (patch) | |
tree | e05aa2cb4197c5b6ffc949f44f99a125a4d3c2ed /drivers | |
parent | 960627b7adf3645e4969b4bfaf03360caabbe76a (diff) |
jmicron ATA: reimplement jmicron ATA quirk
Reimplement jmicron ATA quirk.
* renamed to quirk_jmicron_ata()
* quirk is invoked only for the affected controllers
* programming is stricter. e.g. conf5 bit24 is cleared if
unnecessary.
* code factored for readability
* JMB360 and JMB368 are programmed into proper mode
Verified on JMB360, 363 and 368.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/pci/quirks.c | 80 |
1 files changed, 50 insertions, 30 deletions
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 1e6eda25c0d8..1e6e1e4d3327 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -1218,45 +1218,65 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, asus_hides_a | |||
1218 | * do this early on to make the additional device appear during | 1218 | * do this early on to make the additional device appear during |
1219 | * the PCI scanning. | 1219 | * the PCI scanning. |
1220 | */ | 1220 | */ |
1221 | 1221 | static void quirk_jmicron_ata(struct pci_dev *pdev) | |
1222 | static void quirk_jmicron_dualfn(struct pci_dev *pdev) | ||
1223 | { | 1222 | { |
1224 | u32 conf; | 1223 | u32 conf1, conf5; |
1225 | u8 hdr; | 1224 | u8 hdr; |
1226 | 1225 | ||
1227 | /* Only poke fn 0 */ | 1226 | /* Only poke fn 0 */ |
1228 | if (PCI_FUNC(pdev->devfn)) | 1227 | if (PCI_FUNC(pdev->devfn)) |
1229 | return; | 1228 | return; |
1230 | 1229 | ||
1231 | switch(pdev->device) { | 1230 | pci_read_config_dword(pdev, 0x40, &conf1); |
1232 | case PCI_DEVICE_ID_JMICRON_JMB365: | 1231 | pci_read_config_dword(pdev, 0x80, &conf5); |
1233 | case PCI_DEVICE_ID_JMICRON_JMB366: | ||
1234 | /* Redirect IDE second PATA port to the right spot */ | ||
1235 | pci_read_config_dword(pdev, 0x80, &conf); | ||
1236 | conf |= (1 << 24); | ||
1237 | /* Fall through */ | ||
1238 | pci_write_config_dword(pdev, 0x80, conf); | ||
1239 | case PCI_DEVICE_ID_JMICRON_JMB361: | ||
1240 | case PCI_DEVICE_ID_JMICRON_JMB363: | ||
1241 | pci_read_config_dword(pdev, 0x40, &conf); | ||
1242 | /* Enable dual function mode, AHCI on fn 0, IDE fn1 */ | ||
1243 | /* Set the class codes correctly and then direct IDE 0 */ | ||
1244 | conf &= ~0x000FF200; /* Clear bit 9 and 12-19 */ | ||
1245 | conf |= 0x00C2A102; /* Set 1, 8, 13, 15, 17, 22, 23 */ | ||
1246 | pci_write_config_dword(pdev, 0x40, conf); | ||
1247 | |||
1248 | /* Reconfigure so that the PCI scanner discovers the | ||
1249 | device is now multifunction */ | ||
1250 | |||
1251 | pci_read_config_byte(pdev, PCI_HEADER_TYPE, &hdr); | ||
1252 | pdev->hdr_type = hdr & 0x7f; | ||
1253 | pdev->multifunction = !!(hdr & 0x80); | ||
1254 | 1232 | ||
1255 | break; | 1233 | conf1 &= ~0x00CFF302; /* Clear bit 1, 8, 9, 12-19, 22, 23 */ |
1234 | conf5 &= ~(1 << 24); /* Clear bit 24 */ | ||
1235 | |||
1236 | switch (pdev->device) { | ||
1237 | case PCI_DEVICE_ID_JMICRON_JMB360: | ||
1238 | /* The controller should be in single function ahci mode */ | ||
1239 | conf1 |= 0x0002A100; /* Set 8, 13, 15, 17 */ | ||
1240 | break; | ||
1241 | |||
1242 | case PCI_DEVICE_ID_JMICRON_JMB365: | ||
1243 | case PCI_DEVICE_ID_JMICRON_JMB366: | ||
1244 | /* Redirect IDE second PATA port to the right spot */ | ||
1245 | conf5 |= (1 << 24); | ||
1246 | /* Fall through */ | ||
1247 | case PCI_DEVICE_ID_JMICRON_JMB361: | ||
1248 | case PCI_DEVICE_ID_JMICRON_JMB363: | ||
1249 | /* Enable dual function mode, AHCI on fn 0, IDE fn1 */ | ||
1250 | /* Set the class codes correctly and then direct IDE 0 */ | ||
1251 | conf1 |= 0x00C2A102; /* Set 1, 8, 13, 15, 17, 22, 23 */ | ||
1252 | break; | ||
1253 | |||
1254 | case PCI_DEVICE_ID_JMICRON_JMB368: | ||
1255 | /* The controller should be in single function IDE mode */ | ||
1256 | conf1 |= 0x00C00000; /* Set 22, 23 */ | ||
1257 | break; | ||
1256 | } | 1258 | } |
1257 | } | 1259 | |
1258 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, quirk_jmicron_dualfn); | 1260 | pci_write_config_dword(pdev, 0x40, conf1); |
1259 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, quirk_jmicron_dualfn); | 1261 | pci_write_config_dword(pdev, 0x80, conf5); |
1262 | |||
1263 | /* Update pdev accordingly */ | ||
1264 | pci_read_config_byte(pdev, PCI_HEADER_TYPE, &hdr); | ||
1265 | pdev->hdr_type = hdr & 0x7f; | ||
1266 | pdev->multifunction = !!(hdr & 0x80); | ||
1267 | } | ||
1268 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB360, quirk_jmicron_ata); | ||
1269 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361, quirk_jmicron_ata); | ||
1270 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, quirk_jmicron_ata); | ||
1271 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, quirk_jmicron_ata); | ||
1272 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, quirk_jmicron_ata); | ||
1273 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, quirk_jmicron_ata); | ||
1274 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB360, quirk_jmicron_ata); | ||
1275 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361, quirk_jmicron_ata); | ||
1276 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, quirk_jmicron_ata); | ||
1277 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, quirk_jmicron_ata); | ||
1278 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, quirk_jmicron_ata); | ||
1279 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, quirk_jmicron_ata); | ||
1260 | 1280 | ||
1261 | #endif | 1281 | #endif |
1262 | 1282 | ||