📄 alim15x3.c
字号:
/* * clear "ultra enable" bit */ pci_read_config_byte(dev, m5229_udma, &tmpbyte); tmpbyte &= ultra_enable; pci_write_config_byte(dev, m5229_udma, tmpbyte); if (speed < XFER_SW_DMA_0) ali15x3_tune_drive(drive, speed); } 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); } } return (ide_config_drive_speed(drive, speed));}/** * config_chipset_for_dma - set up DMA mode * @drive: drive to configure for * * Place a drive into DMA mode and tune the chipset for * the selected speed. * * Returns true if DMA mode can be used */ static int config_chipset_for_dma (ide_drive_t *drive){ u8 speed = ide_dma_speed(drive, ali15x3_ratemask(drive)); if (!(speed)) return 0; (void) ali15x3_tune_chipset(drive, speed); return ide_dma_enable(drive);}/** * ali15x3_config_drive_for_dma - configure for DMA * @drive: drive to configure * * Configure a drive for DMA operation. If DMA is not possible we * drop the drive into PIO mode instead. * * FIXME: exactly what are we trying to return here */ static int ali15x3_config_drive_for_dma(ide_drive_t *drive){ ide_hwif_t *hwif = HWIF(drive); struct hd_driveid *id = drive->id; if ((m5229_revision<=0x20) && (drive->media!=ide_disk)) return hwif->ide_dma_off_quietly(drive); drive->init_speed = 0; if ((id->capability & 1) != 0 && drive->autodma) { /* Consult the list of known "bad" drives */ if (hwif->ide_dma_bad_drive(drive)) goto ata_pio; if ((id->field_valid & 4) && (m5229_revision >= 0xC2)) { if (id->dma_ultra & hwif->ultra_mask) { /* Force if Capable UltraDMA */ int dma = config_chipset_for_dma(drive); if ((id->field_valid & 2) && !dma) goto try_dma_modes; } } else if (id->field_valid & 2) {try_dma_modes: if ((id->dma_mword & hwif->mwdma_mask) || (id->dma_1word & hwif->swdma_mask)) { /* Force if Capable regular DMA modes */ if (!config_chipset_for_dma(drive)) goto no_dma_set; } } else if (hwif->ide_dma_good_drive(drive) && (id->eide_dma_time < 150)) { /* Consult the list of known "good" drives */ if (!config_chipset_for_dma(drive)) goto no_dma_set; } else { goto ata_pio; } } else {ata_pio: hwif->tuneproc(drive, 255);no_dma_set: return hwif->ide_dma_off_quietly(drive); } return hwif->ide_dma_on(drive);}/** * ali15x3_dma_write - do a DMA IDE write * @drive: drive to issue write for * * Returns 1 if the DMA write cannot be performed, zero on * success. */ static int ali15x3_dma_write (ide_drive_t *drive){ if ((m5229_revision < 0xC2) && (drive->media != ide_disk)) return 1; /* try PIO instead of DMA */ return __ide_dma_write(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 __init init_chipset_ali15x3 (struct pci_dev *dev, const char *name){ unsigned long flags; u8 tmpbyte; struct pci_dev *north = pci_find_slot(0, PCI_DEVFN(0,0)); pci_read_config_byte(dev, PCI_REVISION_ID, &m5229_revision); isa_dev = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL);#if defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS) if (!ali_proc) { ali_proc = 1; bmide_dev = dev; ide_pci_register_host_proc(&ali_procs[0]); }#endif /* defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_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); local_irq_restore(flags); return 0; } /* * 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) { local_irq_restore(flags); return 0; } 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); } } local_irq_restore(flags); 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. */static unsigned int __init ata66_ali15x3 (ide_hwif_t *hwif){ struct pci_dev *dev = hwif->pci_dev; unsigned int ata66 = 0; u8 cable_80_pin[2] = { 0, 0 }; unsigned long flags; u8 tmpbyte; /* Revision C5 and higher we must rely on drive side */ if (m5229_revision >= 0xC5) return 1; local_irq_save(flags); if (m5229_revision >= 0xC2) { /* * Ultra66 cable detection (from Host View) * m5229, 0x4a, bit0: primary, bit1: secondary 80 pin */ pci_read_config_byte(dev, 0x4a, &tmpbyte); /* * 0x4a, bit0 is 0 => primary channel * has 80-pin (from host view) */ if (!(tmpbyte & 0x01)) cable_80_pin[0] = 1; /* * 0x4a, bit1 is 0 => secondary channel * has 80-pin (from host view) */ if (!(tmpbyte & 0x02)) cable_80_pin[1] = 1; /* * Allow ata66 if cable of current channel has 80 pins */ ata66 = (hwif->channel)?cable_80_pin[1]:cable_80_pin[0]; } else { /* * check m1533, 0x5e, bit 1~4 == 1001 => & 00011110 = 00010010 */ pci_read_config_byte(isa_dev, 0x5e, &tmpbyte); chip_is_1543c_e = ((tmpbyte & 0x1e) == 0x12) ? 1: 0; } /* * 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 */ pci_read_config_byte(dev, 0x53, &tmpbyte); if(m5229_revision <= 0x20) tmpbyte = (tmpbyte & (~0x02)) | 0x01; else tmpbyte |= 0x01; pci_write_config_byte(dev, 0x53, tmpbyte); local_irq_restore(flags); return(ata66);}/** * init_hwif_common_ali15x3 - Set up ALI IDE hardware * @hwif: IDE interface * * Initialize the IDE structure side of the ALi 15x3 driver. */ static void __init init_hwif_common_ali15x3 (ide_hwif_t *hwif){ hwif->autodma = 0; hwif->tuneproc = &ali15x3_tune_drive; hwif->speedproc = &ali15x3_tune_chipset; /* Don't use LBA48 on ALi devices before rev 0xC5 */ hwif->addressing = (m5229_revision <= 0xC4) ? 1 : 0; if (!hwif->dma_base) { hwif->drives[0].autotune = 1; hwif->drives[1].autotune = 1; return; } hwif->atapi_dma = 1; if (m5229_revision > 0x20) hwif->ultra_mask = 0x3f; hwif->mwdma_mask = 0x07; hwif->swdma_mask = 0x07; if (m5229_revision >= 0x20) { /* * M1543C or newer for DMAing */ hwif->ide_dma_check = &ali15x3_config_drive_for_dma; hwif->ide_dma_write = &ali15x3_dma_write; if (!noautodma) hwif->autodma = 1; if (!(hwif->udma_four)) hwif->udma_four = ata66_ali15x3(hwif); } hwif->drives[0].autodma = hwif->autodma; hwif->drives[1].autodma = hwif->autodma;}/** * 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 __init 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; 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 __init init_dma_ali15x3 (ide_hwif_t *hwif, unsigned long dmabase){ if (m5229_revision < 0x20) return; if (!(hwif->channel)) hwif->OUTB(hwif->INB(dmabase+2) & 0x60, dmabase+2); ide_setup_dma(hwif, dmabase, 8);}extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *);/** * 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){ ide_pci_device_t *d = &ali15x3_chipsets[id->driver_data]; if(pci_find_device(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_IGP, NULL)) printk(KERN_ERR "Warning: ATI Radeon IGP Northbridge is not yet fully tested.\n");#if defined(CONFIG_SPARC64) d->init_hwif = init_hwif_common_ali15x3;#endif /* CONFIG_SPARC64 */ ide_setup_pci_device(dev, d); MOD_INC_USE_COUNT; return 0;}static struct pci_device_id alim15x3_pci_tbl[] __devinitdata = { { PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5229, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { 0, },};static struct pci_driver driver = { .name = "ALI15x3 IDE", .id_table = alim15x3_pci_tbl, .probe = alim15x3_init_one,};static int ali15x3_ide_init(void){ return ide_pci_register_driver(&driver);}static void ali15x3_ide_exit(void){ ide_pci_unregister_driver(&driver);}module_init(ali15x3_ide_init);module_exit(ali15x3_ide_exit);MODULE_AUTHOR("Michael Aubry, Andrzej Krzysztofowicz, CJ, Andre Hedrick, Alan Cox");MODULE_DESCRIPTION("PCI driver module for ALi 15x3 IDE");MODULE_LICENSE("GPL");EXPORT_NO_SYMBOLS;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -