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>

authored by Tejun Heo and committed by Jeff Garzik 5ee2ae7f 960627b7

+47 -27
+47 -27
drivers/pci/quirks.c
··· 1218 1218 * do this early on to make the additional device appear during 1219 1219 * the PCI scanning. 1220 1220 */ 1221 - 1222 - static void quirk_jmicron_dualfn(struct pci_dev *pdev) 1221 + static void quirk_jmicron_ata(struct pci_dev *pdev) 1223 1222 { 1224 - u32 conf; 1223 + u32 conf1, conf5; 1225 1224 u8 hdr; 1226 1225 1227 1226 /* Only poke fn 0 */ 1228 1227 if (PCI_FUNC(pdev->devfn)) 1229 1228 return; 1230 1229 1231 - switch(pdev->device) { 1232 - case PCI_DEVICE_ID_JMICRON_JMB365: 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); 1230 + pci_read_config_dword(pdev, 0x40, &conf1); 1231 + pci_read_config_dword(pdev, 0x80, &conf5); 1247 1232 1248 - /* Reconfigure so that the PCI scanner discovers the 1249 - device is now multifunction */ 1233 + conf1 &= ~0x00CFF302; /* Clear bit 1, 8, 9, 12-19, 22, 23 */ 1234 + conf5 &= ~(1 << 24); /* Clear bit 24 */ 1250 1235 1251 - pci_read_config_byte(pdev, PCI_HEADER_TYPE, &hdr); 1252 - pdev->hdr_type = hdr & 0x7f; 1253 - pdev->multifunction = !!(hdr & 0x80); 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; 1254 1241 1255 - break; 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 } 1259 + 1260 + pci_write_config_dword(pdev, 0x40, conf1); 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); 1257 1267 } 1258 - DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, quirk_jmicron_dualfn); 1259 - DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, quirk_jmicron_dualfn); 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 1281 #endif 1262 1282