📄 alim15x3.c
字号:
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 != NULL) && ((id->capability & 1) != 0) && drive->autodma) { /* Consult the list of known "bad" drives */ if (__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 (__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_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_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_create_host_proc("ali", ali_get_info); }#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. * But see note 2 below! * * FIXME: frobs bits that are not defined on newer ALi devicea */static unsigned int __devinit 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; 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 __devinit 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 DMA on ALi devices before rev 0xC5 */ hwif->no_lba48_dma = (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 = 0x7f; 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->dma_setup = &ali15x3_dma_setup; 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 __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)) hwif->OUTB(hwif->INB(dmabase+2) & 0x60, dmabase+2); ide_setup_dma(hwif, dmabase, 8);}static ide_pci_device_t ali15x3_chipset __devinitdata = { .name = "ALI15X3", .init_chipset = init_chipset_ali15x3, .init_hwif = init_hwif_ali15x3, .init_dma = init_dma_ali15x3, .channels = 2, .autodma = AUTODMA, .bootable = ON_BOARD,};/** * 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) }, { }, }; ide_pci_device_t *d = &ali15x3_chipset; if (pci_dev_present(ati_rs100)) printk(KERN_WARNING "alim15x3: ATI Radeon IGP Northbridge is not yet fully tested.\n");#if defined(CONFIG_SPARC64) d->init_hwif = init_hwif_common_ali15x3;#endif /* CONFIG_SPARC64 */ return ide_setup_pci_device(dev, d);}static struct pci_device_id alim15x3_pci_tbl[] = { { PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5229, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5228, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 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 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 + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -