alim15x3.c
来自「linux 内核源代码」· C语言 代码 · 共 834 行 · 第 1/2 页
C
834 行
pci_write_config_byte(dev, m5229_udma, tmpbyte); /* * FIXME: Oh, my... DMA timings are never set. */ } else { pci_read_config_byte(dev, m5229_udma, &tmpbyte); tmpbyte &= (0x0f << ((1-unit) << 2)); /* * enable ultra dma and set timing */ tmpbyte |= ((0x08 | ((4-speed1)&0x07)) << (unit << 2)); pci_write_config_byte(dev, m5229_udma, tmpbyte); if (speed >= XFER_UDMA_3) { pci_read_config_byte(dev, 0x4b, &tmpbyte); tmpbyte |= 1; pci_write_config_byte(dev, 0x4b, tmpbyte); } }}/** * ali15x3_dma_setup - begin a DMA phase * @drive: target device * * Returns 1 if the DMA cannot be performed, zero on success. */static int ali15x3_dma_setup(ide_drive_t *drive){ if (m5229_revision < 0xC2 && drive->media != ide_disk) { if (rq_data_dir(drive->hwif->hwgroup->rq)) return 1; /* try PIO instead of DMA */ } return ide_dma_setup(drive);}/** * init_chipset_ali15x3 - Initialise an ALi IDE controller * @dev: PCI device * @name: Name of the controller * * This function initializes the ALI IDE controller and where * appropriate also sets up the 1533 southbridge. */ static unsigned int __devinit init_chipset_ali15x3 (struct pci_dev *dev, const char *name){ unsigned long flags; u8 tmpbyte; struct pci_dev *north = pci_get_slot(dev->bus, PCI_DEVFN(0,0)); m5229_revision = dev->revision; isa_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL);#if defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_IDE_PROC_FS) if (!ali_proc) { ali_proc = 1; bmide_dev = dev; ide_pci_create_host_proc("ali", ali_get_info); }#endif /* defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_IDE_PROC_FS) */ local_irq_save(flags); if (m5229_revision < 0xC2) { /* * revision 0x20 (1543-E, 1543-F) * revision 0xC0, 0xC1 (1543C-C, 1543C-D, 1543C-E) * clear CD-ROM DMA write bit, m5229, 0x4b, bit 7 */ pci_read_config_byte(dev, 0x4b, &tmpbyte); /* * clear bit 7 */ pci_write_config_byte(dev, 0x4b, tmpbyte & 0x7F); /* * check m1533, 0x5e, bit 1~4 == 1001 => & 00011110 = 00010010 */ if (m5229_revision >= 0x20 && isa_dev) { pci_read_config_byte(isa_dev, 0x5e, &tmpbyte); chip_is_1543c_e = ((tmpbyte & 0x1e) == 0x12) ? 1: 0; } goto out; } /* * 1543C-B?, 1535, 1535D, 1553 * Note 1: not all "motherboard" support this detection * Note 2: if no udma 66 device, the detection may "error". * but in this case, we will not set the device to * ultra 66, the detection result is not important */ /* * enable "Cable Detection", m5229, 0x4b, bit3 */ pci_read_config_byte(dev, 0x4b, &tmpbyte); pci_write_config_byte(dev, 0x4b, tmpbyte | 0x08); /* * We should only tune the 1533 enable if we are using an ALi * North bridge. We might have no north found on some zany * box without a device at 0:0.0. The ALi bridge will be at * 0:0.0 so if we didn't find one we know what is cooking. */ if (north && north->vendor != PCI_VENDOR_ID_AL) goto out; if (m5229_revision < 0xC5 && isa_dev) { /* * set south-bridge's enable bit, m1533, 0x79 */ pci_read_config_byte(isa_dev, 0x79, &tmpbyte); if (m5229_revision == 0xC2) { /* * 1543C-B0 (m1533, 0x79, bit 2) */ pci_write_config_byte(isa_dev, 0x79, tmpbyte | 0x04); } else if (m5229_revision >= 0xC3) { /* * 1553/1535 (m1533, 0x79, bit 1) */ pci_write_config_byte(isa_dev, 0x79, tmpbyte | 0x02); } }out: /* * CD_ROM DMA on (m5229, 0x53, bit0) * Enable this bit even if we want to use PIO. * PIO FIFO off (m5229, 0x53, bit1) * The hardware will use 0x54h and 0x55h to control PIO FIFO. * (Not on later devices it seems) * * 0x53 changes meaning on later revs - we must no touch * bit 1 on them. Need to check if 0x20 is the right break. */ if (m5229_revision >= 0x20) { pci_read_config_byte(dev, 0x53, &tmpbyte); if (m5229_revision <= 0x20) tmpbyte = (tmpbyte & (~0x02)) | 0x01; else if (m5229_revision == 0xc7 || m5229_revision == 0xc8) tmpbyte |= 0x03; else tmpbyte |= 0x01; pci_write_config_byte(dev, 0x53, tmpbyte); } pci_dev_put(north); pci_dev_put(isa_dev); local_irq_restore(flags); return 0;}/* * Cable special cases */static const struct dmi_system_id cable_dmi_table[] = { { .ident = "HP Pavilion N5430", .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), DMI_MATCH(DMI_BOARD_VERSION, "OmniBook N32N-736"), }, }, { .ident = "Toshiba Satellite S1800-814", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), DMI_MATCH(DMI_PRODUCT_NAME, "S1800-814"), }, }, { }};static int ali_cable_override(struct pci_dev *pdev){ /* Fujitsu P2000 */ if (pdev->subsystem_vendor == 0x10CF && pdev->subsystem_device == 0x10AF) return 1; /* Mitac 8317 (Winbook-A) and relatives */ if (pdev->subsystem_vendor == 0x1071 && pdev->subsystem_device == 0x8317) return 1; /* Systems by DMI */ if (dmi_check_system(cable_dmi_table)) return 1; return 0;}/** * ata66_ali15x3 - check for UDMA 66 support * @hwif: IDE interface * * This checks if the controller and the cable are capable * of UDMA66 transfers. It doesn't check the drives. * But see note 2 below! * * FIXME: frobs bits that are not defined on newer ALi devicea */static u8 __devinit ata66_ali15x3(ide_hwif_t *hwif){ struct pci_dev *dev = hwif->pci_dev; unsigned long flags; u8 cbl = ATA_CBL_PATA40, tmpbyte; local_irq_save(flags); if (m5229_revision >= 0xC2) { /* * m5229 80-pin cable detection (from Host View) * * 0x4a bit0 is 0 => primary channel has 80-pin * 0x4a bit1 is 0 => secondary channel has 80-pin * * Certain laptops use short but suitable cables * and don't implement the detect logic. */ if (ali_cable_override(dev)) cbl = ATA_CBL_PATA40_SHORT; else { pci_read_config_byte(dev, 0x4a, &tmpbyte); if ((tmpbyte & (1 << hwif->channel)) == 0) cbl = ATA_CBL_PATA80; } } local_irq_restore(flags); return cbl;}/** * init_hwif_common_ali15x3 - Set up ALI IDE hardware * @hwif: IDE interface * * Initialize the IDE structure side of the ALi 15x3 driver. */ static void __devinit init_hwif_common_ali15x3 (ide_hwif_t *hwif){ hwif->set_pio_mode = &ali_set_pio_mode; hwif->set_dma_mode = &ali_set_dma_mode; hwif->udma_filter = &ali_udma_filter; if (hwif->dma_base == 0) return; hwif->dma_setup = &ali15x3_dma_setup; if (hwif->cbl != ATA_CBL_PATA40_SHORT) hwif->cbl = ata66_ali15x3(hwif);}/** * init_hwif_ali15x3 - Initialize the ALI IDE x86 stuff * @hwif: interface to configure * * Obtain the IRQ tables for an ALi based IDE solution on the PC * class platforms. This part of the code isn't applicable to the * Sparc systems */static void __devinit init_hwif_ali15x3 (ide_hwif_t *hwif){ u8 ideic, inmir; s8 irq_routing_table[] = { -1, 9, 3, 10, 4, 5, 7, 6, 1, 11, 0, 12, 0, 14, 0, 15 }; int irq = -1; if (hwif->pci_dev->device == PCI_DEVICE_ID_AL_M5229) hwif->irq = hwif->channel ? 15 : 14; if (isa_dev) { /* * read IDE interface control */ pci_read_config_byte(isa_dev, 0x58, &ideic); /* bit0, bit1 */ ideic = ideic & 0x03; /* get IRQ for IDE Controller */ if ((hwif->channel && ideic == 0x03) || (!hwif->channel && !ideic)) { /* * get SIRQ1 routing table */ pci_read_config_byte(isa_dev, 0x44, &inmir); inmir = inmir & 0x0f; irq = irq_routing_table[inmir]; } else if (hwif->channel && !(ideic & 0x01)) { /* * get SIRQ2 routing table */ pci_read_config_byte(isa_dev, 0x75, &inmir); inmir = inmir & 0x0f; irq = irq_routing_table[inmir]; } if(irq >= 0) hwif->irq = irq; } init_hwif_common_ali15x3(hwif);}/** * init_dma_ali15x3 - set up DMA on ALi15x3 * @hwif: IDE interface * @dmabase: DMA interface base PCI address * * Set up the DMA functionality on the ALi 15x3. For the ALi * controllers this is generic so we can let the generic code do * the actual work. */static void __devinit init_dma_ali15x3 (ide_hwif_t *hwif, unsigned long dmabase){ if (m5229_revision < 0x20) return; if (!hwif->channel) outb(inb(dmabase + 2) & 0x60, dmabase + 2); ide_setup_dma(hwif, dmabase, 8);}static const struct ide_port_info ali15x3_chipset __devinitdata = { .name = "ALI15X3", .init_chipset = init_chipset_ali15x3, .init_hwif = init_hwif_ali15x3, .init_dma = init_dma_ali15x3, .host_flags = IDE_HFLAG_BOOTABLE, .pio_mask = ATA_PIO5, .swdma_mask = ATA_SWDMA2, .mwdma_mask = ATA_MWDMA2,};/** * alim15x3_init_one - set up an ALi15x3 IDE controller * @dev: PCI device to set up * * Perform the actual set up for an ALi15x3 that has been found by the * hot plug layer. */ static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_device_id *id){ static struct pci_device_id ati_rs100[] = { { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS100) }, { }, }; struct ide_port_info d = ali15x3_chipset; u8 rev = dev->revision; if (pci_dev_present(ati_rs100)) printk(KERN_WARNING "alim15x3: ATI Radeon IGP Northbridge is not yet fully tested.\n"); /* don't use LBA48 DMA on ALi devices before rev 0xC5 */ if (rev <= 0xC4) d.host_flags |= IDE_HFLAG_NO_LBA48_DMA; if (rev >= 0x20) { if (rev == 0x20) d.host_flags |= IDE_HFLAG_NO_ATAPI_DMA; if (rev < 0xC2) d.udma_mask = ATA_UDMA2; else if (rev == 0xC2 || rev == 0xC3) d.udma_mask = ATA_UDMA4; else if (rev == 0xC4) d.udma_mask = ATA_UDMA5; else d.udma_mask = ATA_UDMA6; }#if defined(CONFIG_SPARC64) d.init_hwif = init_hwif_common_ali15x3;#endif /* CONFIG_SPARC64 */ return ide_setup_pci_device(dev, &d);}static const struct pci_device_id alim15x3_pci_tbl[] = { { PCI_VDEVICE(AL, PCI_DEVICE_ID_AL_M5229), 0 }, { PCI_VDEVICE(AL, PCI_DEVICE_ID_AL_M5228), 0 }, { 0, },};MODULE_DEVICE_TABLE(pci, alim15x3_pci_tbl);static struct pci_driver driver = { .name = "ALI15x3_IDE", .id_table = alim15x3_pci_tbl, .probe = alim15x3_init_one,};static int __init ali15x3_ide_init(void){ return ide_pci_register_driver(&driver);}module_init(ali15x3_ide_init);MODULE_AUTHOR("Michael Aubry, Andrzej Krzysztofowicz, CJ, Andre Hedrick, Alan Cox");MODULE_DESCRIPTION("PCI driver module for ALi 15x3 IDE");MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?