^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2006 Red Hat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * May be copied or modified under the terms of the GNU General Public License
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/ide.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #define DRV_NAME "jmicron"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) typedef enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) PORT_PATA0 = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) PORT_PATA1 = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) PORT_SATA = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) } port_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * jmicron_cable_detect - cable detection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * @hwif: IDE port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * Returns the cable type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) static u8 jmicron_cable_detect(ide_hwif_t *hwif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct pci_dev *pdev = to_pci_dev(hwif->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) u32 control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) u32 control5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) int port = hwif->channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) port_type port_map[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) pci_read_config_dword(pdev, 0x40, &control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /* There are two basic mappings. One has the two SATA ports merged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) as master/slave and the secondary as PATA, the other has only the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) SATA port mapped */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) if (control & (1 << 23)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) port_map[0] = PORT_SATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) port_map[1] = PORT_PATA0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) port_map[0] = PORT_SATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) port_map[1] = PORT_SATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) /* The 365/366 may have this bit set to map the second PATA port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) as the internal primary channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) pci_read_config_dword(pdev, 0x80, &control5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (control5 & (1<<24))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) port_map[0] = PORT_PATA1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) /* The two ports may then be logically swapped by the firmware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) if (control & (1 << 22))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) port = port ^ 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * Now we know which physical port we are talking about we can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * actually do our cable checking etc. Thankfully we don't need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * to do the plumbing for other cases.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) switch (port_map[port]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) case PORT_PATA0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) if (control & (1 << 3)) /* 40/80 pin primary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) return ATA_CBL_PATA40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) return ATA_CBL_PATA80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) case PORT_PATA1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) if (control5 & (1 << 19)) /* 40/80 pin secondary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return ATA_CBL_PATA40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) return ATA_CBL_PATA80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) case PORT_SATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /* Avoid bogus "control reaches end of non-void function" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) return ATA_CBL_PATA80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static void jmicron_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * jmicron_set_dma_mode - set host controller for DMA mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * @hwif: port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * @drive: drive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * As the JMicron snoops for timings we don't need to do anything here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static void jmicron_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) static const struct ide_port_ops jmicron_port_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) .set_pio_mode = jmicron_set_pio_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) .set_dma_mode = jmicron_set_dma_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) .cable_detect = jmicron_cable_detect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static const struct ide_port_info jmicron_chipset = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) .name = DRV_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) .enablebits = { { 0x40, 0x01, 0x01 }, { 0x40, 0x10, 0x10 } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) .port_ops = &jmicron_port_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) .pio_mask = ATA_PIO5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) .mwdma_mask = ATA_MWDMA2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) .udma_mask = ATA_UDMA6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * jmicron_init_one - pci layer discovery entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * @dev: PCI device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * @id: ident table entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * Called by the PCI code when it finds a Jmicron controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * We then use the IDE PCI generic helper to do most of the work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static int jmicron_init_one(struct pci_dev *dev, const struct pci_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) return ide_pci_init_one(dev, &jmicron_chipset, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /* All JMB PATA controllers have and will continue to have the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * interface. Matching vendor and device class is enough for all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * current and future controllers if the controller is programmed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * properly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * If libata is configured, jmicron PCI quirk programs the controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * into the correct mode. If libata isn't configured, match known
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * device IDs too to maintain backward compatibility.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static struct pci_device_id jmicron_pci_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #if !defined(CONFIG_ATA) && !defined(CONFIG_ATA_MODULE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB361) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB363) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB365) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB366) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB368) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) PCI_CLASS_STORAGE_IDE << 8, 0xffff00, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) { 0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) MODULE_DEVICE_TABLE(pci, jmicron_pci_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) static struct pci_driver jmicron_pci_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) .name = "JMicron IDE",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) .id_table = jmicron_pci_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) .probe = jmicron_init_one,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) .remove = ide_pci_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) .suspend = ide_pci_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) .resume = ide_pci_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) static int __init jmicron_ide_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return ide_pci_register_driver(&jmicron_pci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) static void __exit jmicron_ide_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) pci_unregister_driver(&jmicron_pci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) module_init(jmicron_ide_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) module_exit(jmicron_ide_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) MODULE_AUTHOR("Alan Cox");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) MODULE_DESCRIPTION("PCI driver module for the JMicron in legacy modes");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) MODULE_LICENSE("GPL");