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 + -
显示快捷键?