diff options
| author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-03-01 22:48:21 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-03-01 22:48:21 -0500 |
| commit | 562aa1d4c6a874373f9a48ac184f662fbbb06a04 (patch) | |
| tree | ad4d9c19f7a98bb4f35b35104ffecb5723f686c8 | |
| parent | b4350861dd6d5668bb9fe18eec4227d30e9131b0 (diff) | |
| parent | afb2d552bc4c241c009f5947311a95de426a75d9 (diff) | |
Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev
* 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev:
ahci: improve spurious SDB FIS handling
ahci/pata_jmicron: match class not function number
jmicron ATA: reimplement jmicron ATA quirk
pata_jmicron: drop unnecessary device programming in [re]init
libata: blacklist FUJITSU MHT2060BH for NCQ
sata_sil24: kill unused local variable idx in sil24_fill_sg()
libata: clear drvdata in ata_host_release(), take#2
| -rw-r--r-- | drivers/ata/ahci.c | 55 | ||||
| -rw-r--r-- | drivers/ata/libata-core.c | 5 | ||||
| -rw-r--r-- | drivers/ata/pata_cs5520.c | 1 | ||||
| -rw-r--r-- | drivers/ata/pata_isapnp.c | 1 | ||||
| -rw-r--r-- | drivers/ata/pata_jmicron.c | 51 | ||||
| -rw-r--r-- | drivers/ata/pata_platform.c | 1 | ||||
| -rw-r--r-- | drivers/ata/sata_sil24.c | 3 | ||||
| -rw-r--r-- | drivers/pci/quirks.c | 83 |
8 files changed, 95 insertions, 105 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 6d932409aadd..1539734bbbad 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
| @@ -200,6 +200,7 @@ struct ahci_port_priv { | |||
| 200 | /* for NCQ spurious interrupt analysis */ | 200 | /* for NCQ spurious interrupt analysis */ |
| 201 | unsigned int ncq_saw_d2h:1; | 201 | unsigned int ncq_saw_d2h:1; |
| 202 | unsigned int ncq_saw_dmas:1; | 202 | unsigned int ncq_saw_dmas:1; |
| 203 | unsigned int ncq_saw_sdb:1; | ||
| 203 | }; | 204 | }; |
| 204 | 205 | ||
| 205 | static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg); | 206 | static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg); |
| @@ -384,12 +385,9 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
| 384 | { PCI_VDEVICE(INTEL, 0x294d), board_ahci_pi }, /* ICH9 */ | 385 | { PCI_VDEVICE(INTEL, 0x294d), board_ahci_pi }, /* ICH9 */ |
| 385 | { PCI_VDEVICE(INTEL, 0x294e), board_ahci_pi }, /* ICH9M */ | 386 | { PCI_VDEVICE(INTEL, 0x294e), board_ahci_pi }, /* ICH9M */ |
| 386 | 387 | ||
| 387 | /* JMicron */ | 388 | /* JMicron 360/1/3/5/6, match class to avoid IDE function */ |
| 388 | { PCI_VDEVICE(JMICRON, 0x2360), board_ahci_ign_iferr }, /* JMB360 */ | 389 | { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, |
| 389 | { PCI_VDEVICE(JMICRON, 0x2361), board_ahci_ign_iferr }, /* JMB361 */ | 390 | PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci_ign_iferr }, |
| 390 | { PCI_VDEVICE(JMICRON, 0x2363), board_ahci_ign_iferr }, /* JMB363 */ | ||
| 391 | { PCI_VDEVICE(JMICRON, 0x2365), board_ahci_ign_iferr }, /* JMB365 */ | ||
| 392 | { PCI_VDEVICE(JMICRON, 0x2366), board_ahci_ign_iferr }, /* JMB366 */ | ||
| 393 | 391 | ||
| 394 | /* ATI */ | 392 | /* ATI */ |
| 395 | { PCI_VDEVICE(ATI, 0x4380), board_ahci }, /* ATI SB600 non-raid */ | 393 | { PCI_VDEVICE(ATI, 0x4380), board_ahci }, /* ATI SB600 non-raid */ |
| @@ -1160,23 +1158,31 @@ static void ahci_host_intr(struct ata_port *ap) | |||
| 1160 | } | 1158 | } |
| 1161 | 1159 | ||
| 1162 | if (status & PORT_IRQ_SDB_FIS) { | 1160 | if (status & PORT_IRQ_SDB_FIS) { |
| 1163 | /* SDB FIS containing spurious completions might be | ||
| 1164 | * dangerous, whine and fail commands with HSM | ||
| 1165 | * violation. EH will turn off NCQ after several such | ||
| 1166 | * failures. | ||
| 1167 | */ | ||
| 1168 | const __le32 *f = pp->rx_fis + RX_FIS_SDB; | 1161 | const __le32 *f = pp->rx_fis + RX_FIS_SDB; |
| 1169 | 1162 | ||
| 1170 | ata_ehi_push_desc(ehi, "spurious completion during NCQ " | 1163 | if (le32_to_cpu(f[1])) { |
| 1171 | "issue=0x%x SAct=0x%x FIS=%08x:%08x", | 1164 | /* SDB FIS containing spurious completions |
| 1172 | readl(port_mmio + PORT_CMD_ISSUE), | 1165 | * might be dangerous, whine and fail commands |
| 1173 | readl(port_mmio + PORT_SCR_ACT), | 1166 | * with HSM violation. EH will turn off NCQ |
| 1174 | le32_to_cpu(f[0]), le32_to_cpu(f[1])); | 1167 | * after several such failures. |
| 1175 | 1168 | */ | |
| 1176 | ehi->err_mask |= AC_ERR_HSM; | 1169 | ata_ehi_push_desc(ehi, |
| 1177 | ehi->action |= ATA_EH_SOFTRESET; | 1170 | "spurious completions during NCQ " |
| 1178 | ata_port_freeze(ap); | 1171 | "issue=0x%x SAct=0x%x FIS=%08x:%08x", |
| 1179 | 1172 | readl(port_mmio + PORT_CMD_ISSUE), | |
| 1173 | readl(port_mmio + PORT_SCR_ACT), | ||
| 1174 | le32_to_cpu(f[0]), le32_to_cpu(f[1])); | ||
| 1175 | ehi->err_mask |= AC_ERR_HSM; | ||
| 1176 | ehi->action |= ATA_EH_SOFTRESET; | ||
| 1177 | ata_port_freeze(ap); | ||
| 1178 | } else { | ||
| 1179 | if (!pp->ncq_saw_sdb) | ||
| 1180 | ata_port_printk(ap, KERN_INFO, | ||
| 1181 | "spurious SDB FIS %08x:%08x during NCQ, " | ||
| 1182 | "this message won't be printed again\n", | ||
| 1183 | le32_to_cpu(f[0]), le32_to_cpu(f[1])); | ||
| 1184 | pp->ncq_saw_sdb = 1; | ||
| 1185 | } | ||
| 1180 | known_irq = 1; | 1186 | known_irq = 1; |
| 1181 | } | 1187 | } |
| 1182 | 1188 | ||
| @@ -1665,13 +1671,6 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 1665 | if (!printed_version++) | 1671 | if (!printed_version++) |
| 1666 | dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); | 1672 | dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); |
| 1667 | 1673 | ||
| 1668 | if (pdev->vendor == PCI_VENDOR_ID_JMICRON) { | ||
| 1669 | /* Function 1 is the PATA controller except on the 368, where | ||
| 1670 | we are not AHCI anyway */ | ||
| 1671 | if (PCI_FUNC(pdev->devfn)) | ||
| 1672 | return -ENODEV; | ||
| 1673 | } | ||
| 1674 | |||
| 1675 | rc = pcim_enable_device(pdev); | 1674 | rc = pcim_enable_device(pdev); |
| 1676 | if (rc) | 1675 | if (rc) |
| 1677 | return rc; | 1676 | return rc; |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index c8d44a7c403f..ac3d1204ea35 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
| @@ -3346,6 +3346,8 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { | |||
| 3346 | /* Devices where NCQ should be avoided */ | 3346 | /* Devices where NCQ should be avoided */ |
| 3347 | /* NCQ is slow */ | 3347 | /* NCQ is slow */ |
| 3348 | { "WDC WD740ADFD-00", NULL, ATA_HORKAGE_NONCQ }, | 3348 | { "WDC WD740ADFD-00", NULL, ATA_HORKAGE_NONCQ }, |
| 3349 | /* http://thread.gmane.org/gmane.linux.ide/14907 */ | ||
| 3350 | { "FUJITSU MHT2060BH", NULL, ATA_HORKAGE_NONCQ }, | ||
| 3349 | 3351 | ||
| 3350 | /* Devices with NCQ limits */ | 3352 | /* Devices with NCQ limits */ |
| 3351 | 3353 | ||
| @@ -5680,6 +5682,8 @@ static void ata_host_release(struct device *gendev, void *res) | |||
| 5680 | 5682 | ||
| 5681 | if (host->ops->host_stop) | 5683 | if (host->ops->host_stop) |
| 5682 | host->ops->host_stop(host); | 5684 | host->ops->host_stop(host); |
| 5685 | |||
| 5686 | dev_set_drvdata(gendev, NULL); | ||
| 5683 | } | 5687 | } |
| 5684 | 5688 | ||
| 5685 | /** | 5689 | /** |
| @@ -5902,7 +5906,6 @@ int ata_device_add(const struct ata_probe_ent *ent) | |||
| 5902 | 5906 | ||
| 5903 | err_out: | 5907 | err_out: |
| 5904 | devres_release_group(dev, ata_device_add); | 5908 | devres_release_group(dev, ata_device_add); |
| 5905 | dev_set_drvdata(dev, NULL); | ||
| 5906 | VPRINTK("EXIT, returning %d\n", rc); | 5909 | VPRINTK("EXIT, returning %d\n", rc); |
| 5907 | return 0; | 5910 | return 0; |
| 5908 | } | 5911 | } |
diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c index c1334c6c4156..8ff2d58c599e 100644 --- a/drivers/ata/pata_cs5520.c +++ b/drivers/ata/pata_cs5520.c | |||
| @@ -306,7 +306,6 @@ static void __devexit cs5520_remove_one(struct pci_dev *pdev) | |||
| 306 | struct ata_host *host = dev_get_drvdata(dev); | 306 | struct ata_host *host = dev_get_drvdata(dev); |
| 307 | 307 | ||
| 308 | ata_host_detach(host); | 308 | ata_host_detach(host); |
| 309 | dev_set_drvdata(dev, NULL); | ||
| 310 | } | 309 | } |
| 311 | 310 | ||
| 312 | /** | 311 | /** |
diff --git a/drivers/ata/pata_isapnp.c b/drivers/ata/pata_isapnp.c index d5f2e85e28f3..1a61cc891741 100644 --- a/drivers/ata/pata_isapnp.c +++ b/drivers/ata/pata_isapnp.c | |||
| @@ -128,7 +128,6 @@ static void isapnp_remove_one(struct pnp_dev *idev) | |||
| 128 | struct ata_host *host = dev_get_drvdata(dev); | 128 | struct ata_host *host = dev_get_drvdata(dev); |
| 129 | 129 | ||
| 130 | ata_host_detach(host); | 130 | ata_host_detach(host); |
| 131 | dev_set_drvdata(dev, NULL); | ||
| 132 | } | 131 | } |
| 133 | 132 | ||
| 134 | static struct pnp_device_id isapnp_devices[] = { | 133 | static struct pnp_device_id isapnp_devices[] = { |
diff --git a/drivers/ata/pata_jmicron.c b/drivers/ata/pata_jmicron.c index 7a635dd326f8..47d0f94fd792 100644 --- a/drivers/ata/pata_jmicron.c +++ b/drivers/ata/pata_jmicron.c | |||
| @@ -202,49 +202,20 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i | |||
| 202 | }; | 202 | }; |
| 203 | struct ata_port_info *port_info[2] = { &info, &info }; | 203 | struct ata_port_info *port_info[2] = { &info, &info }; |
| 204 | 204 | ||
| 205 | u32 reg; | ||
| 206 | |||
| 207 | /* PATA controller is fn 1, AHCI is fn 0 */ | ||
| 208 | if (id->driver_data != 368 && PCI_FUNC(pdev->devfn) != 1) | ||
| 209 | return -ENODEV; | ||
| 210 | |||
| 211 | /* The 365/66 have two PATA channels, redirect the second */ | ||
| 212 | if (id->driver_data == 365 || id->driver_data == 366) { | ||
| 213 | pci_read_config_dword(pdev, 0x80, ®); | ||
| 214 | reg |= (1 << 24); /* IDE1 to PATA IDE secondary */ | ||
| 215 | pci_write_config_dword(pdev, 0x80, reg); | ||
| 216 | } | ||
| 217 | |||
| 218 | return ata_pci_init_one(pdev, port_info, 2); | 205 | return ata_pci_init_one(pdev, port_info, 2); |
| 219 | } | 206 | } |
| 220 | 207 | ||
| 221 | static int jmicron_reinit_one(struct pci_dev *pdev) | ||
| 222 | { | ||
| 223 | u32 reg; | ||
| 224 | |||
| 225 | switch(pdev->device) { | ||
| 226 | case PCI_DEVICE_ID_JMICRON_JMB368: | ||
| 227 | break; | ||
| 228 | case PCI_DEVICE_ID_JMICRON_JMB365: | ||
| 229 | case PCI_DEVICE_ID_JMICRON_JMB366: | ||
| 230 | /* Restore mapping or disks swap and boy does it get ugly */ | ||
| 231 | pci_read_config_dword(pdev, 0x80, ®); | ||
| 232 | reg |= (1 << 24); /* IDE1 to PATA IDE secondary */ | ||
| 233 | pci_write_config_dword(pdev, 0x80, reg); | ||
| 234 | /* Fall through */ | ||
| 235 | default: | ||
| 236 | /* Make sure AHCI is turned back on */ | ||
| 237 | pci_write_config_byte(pdev, 0x41, 0xa1); | ||
| 238 | } | ||
| 239 | return ata_pci_device_resume(pdev); | ||
| 240 | } | ||
| 241 | |||
| 242 | static const struct pci_device_id jmicron_pci_tbl[] = { | 208 | static const struct pci_device_id jmicron_pci_tbl[] = { |
| 243 | { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB361), 361}, | 209 | { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361, |
| 244 | { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB363), 363}, | 210 | PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xffff00, 361 }, |
| 245 | { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB365), 365}, | 211 | { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, |
| 246 | { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB366), 366}, | 212 | PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xffff00, 363 }, |
| 247 | { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB368), 368}, | 213 | { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, |
| 214 | PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xffff00, 365 }, | ||
| 215 | { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, | ||
| 216 | PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xffff00, 366 }, | ||
| 217 | { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, | ||
| 218 | PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xffff00, 368 }, | ||
| 248 | 219 | ||
| 249 | { } /* terminate list */ | 220 | { } /* terminate list */ |
| 250 | }; | 221 | }; |
| @@ -255,7 +226,7 @@ static struct pci_driver jmicron_pci_driver = { | |||
| 255 | .probe = jmicron_init_one, | 226 | .probe = jmicron_init_one, |
| 256 | .remove = ata_pci_remove_one, | 227 | .remove = ata_pci_remove_one, |
| 257 | .suspend = ata_pci_device_suspend, | 228 | .suspend = ata_pci_device_suspend, |
| 258 | .resume = jmicron_reinit_one, | 229 | .resume = ata_pci_device_resume, |
| 259 | }; | 230 | }; |
| 260 | 231 | ||
| 261 | static int __init jmicron_init(void) | 232 | static int __init jmicron_init(void) |
diff --git a/drivers/ata/pata_platform.c b/drivers/ata/pata_platform.c index 02ea95fcba69..4b82a5435a4e 100644 --- a/drivers/ata/pata_platform.c +++ b/drivers/ata/pata_platform.c | |||
| @@ -228,7 +228,6 @@ static int __devexit pata_platform_remove(struct platform_device *pdev) | |||
| 228 | struct ata_host *host = dev_get_drvdata(dev); | 228 | struct ata_host *host = dev_get_drvdata(dev); |
| 229 | 229 | ||
| 230 | ata_host_detach(host); | 230 | ata_host_detach(host); |
| 231 | dev_set_drvdata(dev, NULL); | ||
| 232 | 231 | ||
| 233 | return 0; | 232 | return 0; |
| 234 | } | 233 | } |
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c index 5d083f43f90d..b1bab82b16de 100644 --- a/drivers/ata/sata_sil24.c +++ b/drivers/ata/sata_sil24.c | |||
| @@ -647,7 +647,6 @@ static inline void sil24_fill_sg(struct ata_queued_cmd *qc, | |||
| 647 | struct sil24_sge *sge) | 647 | struct sil24_sge *sge) |
| 648 | { | 648 | { |
| 649 | struct scatterlist *sg; | 649 | struct scatterlist *sg; |
| 650 | unsigned int idx = 0; | ||
| 651 | 650 | ||
| 652 | ata_for_each_sg(sg, qc) { | 651 | ata_for_each_sg(sg, qc) { |
| 653 | sge->addr = cpu_to_le64(sg_dma_address(sg)); | 652 | sge->addr = cpu_to_le64(sg_dma_address(sg)); |
| @@ -656,9 +655,7 @@ static inline void sil24_fill_sg(struct ata_queued_cmd *qc, | |||
| 656 | sge->flags = cpu_to_le32(SGE_TRM); | 655 | sge->flags = cpu_to_le32(SGE_TRM); |
| 657 | else | 656 | else |
| 658 | sge->flags = 0; | 657 | sge->flags = 0; |
| 659 | |||
| 660 | sge++; | 658 | sge++; |
| 661 | idx++; | ||
| 662 | } | 659 | } |
| 663 | } | 660 | } |
| 664 | 661 | ||
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 1e6eda25c0d8..1bf548287564 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
| @@ -1218,45 +1218,68 @@ 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, class; |
| 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 | pci_read_config_dword(pdev, PCI_CLASS_REVISION, &class); | ||
| 1269 | pdev->class = class >> 8; | ||
| 1270 | } | ||
| 1271 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB360, quirk_jmicron_ata); | ||
| 1272 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361, quirk_jmicron_ata); | ||
| 1273 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, quirk_jmicron_ata); | ||
| 1274 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, quirk_jmicron_ata); | ||
| 1275 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, quirk_jmicron_ata); | ||
| 1276 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, quirk_jmicron_ata); | ||
| 1277 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB360, quirk_jmicron_ata); | ||
| 1278 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361, quirk_jmicron_ata); | ||
| 1279 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, quirk_jmicron_ata); | ||
| 1280 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, quirk_jmicron_ata); | ||
| 1281 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, quirk_jmicron_ata); | ||
| 1282 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, quirk_jmicron_ata); | ||
| 1260 | 1283 | ||
| 1261 | #endif | 1284 | #endif |
| 1262 | 1285 | ||
