hpt366.c

来自「linux 内核源代码」· C语言 代码 · 共 1,677 行 · 第 1/4 页

C
1,677
字号
		printk("%s: using %d MHz DPLL clock\n", name, dpll_clk);	} else {		/* Mark the fact that we're not using the DPLL. */		dpll_clk = 0;		printk("%s: using %d MHz PCI clock\n", name, pci_clk);	}	/*	 * Advance the table pointer to a slot which points to the list	 * of the register values settings matching the clock being used.	 */	info->settings += clock;	/* Store the clock frequencies. */	info->dpll_clk	= dpll_clk;	info->pci_clk	= pci_clk;	/* Point to this chip's own instance of the hpt_info structure. */	pci_set_drvdata(dev, info);	if (chip_type >= HPT370) {		u8  mcr1, mcr4;		/*		 * Reset the state engines.		 * NOTE: Avoid accidentally enabling the disabled channels.		 */		pci_read_config_byte (dev, 0x50, &mcr1);		pci_read_config_byte (dev, 0x54, &mcr4);		pci_write_config_byte(dev, 0x50, (mcr1 | 0x32));		pci_write_config_byte(dev, 0x54, (mcr4 | 0x32));		udelay(100);	}	/*	 * On  HPT371N, if ATA clock is 66 MHz we must set bit 2 in	 * the MISC. register to stretch the UltraDMA Tss timing.	 * NOTE: This register is only writeable via I/O space.	 */	if (chip_type == HPT371N && clock == ATA_CLOCK_66MHZ)		outb(inb(io_base + 0x9c) | 0x04, io_base + 0x9c);	return dev->irq;}static void __devinit init_hwif_hpt366(ide_hwif_t *hwif){	struct pci_dev	*dev	= hwif->pci_dev;	struct hpt_info *info	= pci_get_drvdata(dev);	int serialize		= HPT_SERIALIZE_IO;	u8  scr1 = 0, ata66	= hwif->channel ? 0x01 : 0x02;	u8  chip_type		= info->chip_type;	u8  new_mcr, old_mcr	= 0;	/* Cache the channel's MISC. control registers' offset */	hwif->select_data	= hwif->channel ? 0x54 : 0x50;	hwif->set_pio_mode	= &hpt3xx_set_pio_mode;	hwif->set_dma_mode	= &hpt3xx_set_mode;	hwif->quirkproc		= &hpt3xx_quirkproc;	hwif->intrproc		= &hpt3xx_intrproc;	hwif->maskproc		= &hpt3xx_maskproc;	hwif->busproc		= &hpt3xx_busproc;	hwif->udma_filter	= &hpt3xx_udma_filter;	hwif->mdma_filter	= &hpt3xx_mdma_filter;	/*	 * HPT3xxN chips have some complications:	 *	 * - on 33 MHz PCI we must clock switch	 * - on 66 MHz PCI we must NOT use the PCI clock	 */	if (chip_type >= HPT372N && info->dpll_clk && info->pci_clk < 66) {		/*		 * Clock is shared between the channels,		 * so we'll have to serialize them... :-(		 */		serialize = 1;		hwif->rw_disk = &hpt3xxn_rw_disk;	}	/* Serialize access to this device if needed */	if (serialize && hwif->mate)		hwif->serialized = hwif->mate->serialized = 1;	/*	 * Disable the "fast interrupt" prediction.  Don't hold off	 * on interrupts. (== 0x01 despite what the docs say)	 */	pci_read_config_byte(dev, hwif->select_data + 1, &old_mcr);	if (info->chip_type >= HPT374)		new_mcr = old_mcr & ~0x07;	else if (info->chip_type >= HPT370) {		new_mcr = old_mcr;		new_mcr &= ~0x02;#ifdef HPT_DELAY_INTERRUPT		new_mcr &= ~0x01;#else		new_mcr |=  0x01;#endif	} else					/* HPT366 and HPT368  */		new_mcr = old_mcr & ~0x80;	if (new_mcr != old_mcr)		pci_write_config_byte(dev, hwif->select_data + 1, new_mcr);	if (hwif->dma_base == 0)		return;	/*	 * The HPT37x uses the CBLID pins as outputs for MA15/MA16	 * address lines to access an external EEPROM.  To read valid	 * cable detect state the pins must be enabled as inputs.	 */	if (chip_type == HPT374 && (PCI_FUNC(dev->devfn) & 1)) {		/*		 * HPT374 PCI function 1		 * - set bit 15 of reg 0x52 to enable TCBLID as input		 * - set bit 15 of reg 0x56 to enable FCBLID as input		 */		u8  mcr_addr = hwif->select_data + 2;		u16 mcr;		pci_read_config_word (dev, mcr_addr, &mcr);		pci_write_config_word(dev, mcr_addr, (mcr | 0x8000));		/* now read cable id register */		pci_read_config_byte (dev, 0x5a, &scr1);		pci_write_config_word(dev, mcr_addr, mcr);	} else if (chip_type >= HPT370) {		/*		 * HPT370/372 and 374 pcifn 0		 * - clear bit 0 of reg 0x5b to enable P/SCBLID as inputs		 */		u8 scr2 = 0;		pci_read_config_byte (dev, 0x5b, &scr2);		pci_write_config_byte(dev, 0x5b, (scr2 & ~1));		/* now read cable id register */		pci_read_config_byte (dev, 0x5a, &scr1);		pci_write_config_byte(dev, 0x5b,  scr2);	} else		pci_read_config_byte (dev, 0x5a, &scr1);	if (hwif->cbl != ATA_CBL_PATA40_SHORT)		hwif->cbl = (scr1 & ata66) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;	if (chip_type >= HPT374) {		hwif->ide_dma_test_irq	= &hpt374_ide_dma_test_irq;		hwif->ide_dma_end	= &hpt374_ide_dma_end;	} else if (chip_type >= HPT370) {		hwif->dma_start 	= &hpt370_ide_dma_start;		hwif->ide_dma_end	= &hpt370_ide_dma_end;		hwif->dma_timeout	= &hpt370_dma_timeout;	} else		hwif->dma_lost_irq	= &hpt366_dma_lost_irq;}static void __devinit init_dma_hpt366(ide_hwif_t *hwif, unsigned long dmabase){	struct pci_dev	*dev		= hwif->pci_dev;	u8 masterdma	= 0, slavedma	= 0;	u8 dma_new	= 0, dma_old	= 0;	unsigned long flags;	dma_old = inb(dmabase + 2);	local_irq_save(flags);	dma_new = dma_old;	pci_read_config_byte(dev, hwif->channel ? 0x4b : 0x43, &masterdma);	pci_read_config_byte(dev, hwif->channel ? 0x4f : 0x47,  &slavedma);	if (masterdma & 0x30)	dma_new |= 0x20;	if ( slavedma & 0x30)	dma_new |= 0x40;	if (dma_new != dma_old)		outb(dma_new, dmabase + 2);	local_irq_restore(flags);	ide_setup_dma(hwif, dmabase, 8);}static void __devinit hpt374_init(struct pci_dev *dev, struct pci_dev *dev2){	if (dev2->irq != dev->irq) {		/* FIXME: we need a core pci_set_interrupt() */		dev2->irq = dev->irq;		printk(KERN_INFO "HPT374: PCI config space interrupt fixed\n");	}}static void __devinit hpt371_init(struct pci_dev *dev){	u8 mcr1 = 0;	/*	 * HPT371 chips physically have only one channel, the secondary one,	 * but the primary channel registers do exist!  Go figure...	 * So,  we manually disable the non-existing channel here	 * (if the BIOS hasn't done this already).	 */	pci_read_config_byte(dev, 0x50, &mcr1);	if (mcr1 & 0x04)		pci_write_config_byte(dev, 0x50, mcr1 & ~0x04);}static int __devinit hpt36x_init(struct pci_dev *dev, struct pci_dev *dev2){	u8 mcr1 = 0, pin1 = 0, pin2 = 0;	/*	 * Now we'll have to force both channels enabled if	 * at least one of them has been enabled by BIOS...	 */	pci_read_config_byte(dev, 0x50, &mcr1);	if (mcr1 & 0x30)		pci_write_config_byte(dev, 0x50, mcr1 | 0x30);	pci_read_config_byte(dev,  PCI_INTERRUPT_PIN, &pin1);	pci_read_config_byte(dev2, PCI_INTERRUPT_PIN, &pin2);	if (pin1 != pin2 && dev->irq == dev2->irq) {		printk(KERN_INFO "HPT36x: onboard version of chipset, "				 "pin1=%d pin2=%d\n", pin1, pin2);		return 1;	}	return 0;}static const struct ide_port_info hpt366_chipsets[] __devinitdata = {	{	/* 0 */		.name		= "HPT36x",		.init_chipset	= init_chipset_hpt366,		.init_hwif	= init_hwif_hpt366,		.init_dma	= init_dma_hpt366,		/*		 * HPT36x chips have one channel per function and have		 * both channel enable bits located differently and visible		 * to both functions -- really stupid design decision... :-(		 * Bit 4 is for the primary channel, bit 5 for the secondary.		 */		.enablebits	= {{0x50,0x10,0x10}, {0x54,0x04,0x04}},		.extra		= 240,		.host_flags	= IDE_HFLAG_SINGLE |				  IDE_HFLAG_NO_ATAPI_DMA |				  IDE_HFLAG_OFF_BOARD,		.pio_mask	= ATA_PIO4,		.mwdma_mask	= ATA_MWDMA2,	},{	/* 1 */		.name		= "HPT372A",		.init_chipset	= init_chipset_hpt366,		.init_hwif	= init_hwif_hpt366,		.init_dma	= init_dma_hpt366,		.enablebits	= {{0x50,0x04,0x04}, {0x54,0x04,0x04}},		.extra		= 240,		.host_flags	= IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD,		.pio_mask	= ATA_PIO4,		.mwdma_mask	= ATA_MWDMA2,	},{	/* 2 */		.name		= "HPT302",		.init_chipset	= init_chipset_hpt366,		.init_hwif	= init_hwif_hpt366,		.init_dma	= init_dma_hpt366,		.enablebits	= {{0x50,0x04,0x04}, {0x54,0x04,0x04}},		.extra		= 240,		.host_flags	= IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD,		.pio_mask	= ATA_PIO4,		.mwdma_mask	= ATA_MWDMA2,	},{	/* 3 */		.name		= "HPT371",		.init_chipset	= init_chipset_hpt366,		.init_hwif	= init_hwif_hpt366,		.init_dma	= init_dma_hpt366,		.enablebits	= {{0x50,0x04,0x04}, {0x54,0x04,0x04}},		.extra		= 240,		.host_flags	= IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD,		.pio_mask	= ATA_PIO4,		.mwdma_mask	= ATA_MWDMA2,	},{	/* 4 */		.name		= "HPT374",		.init_chipset	= init_chipset_hpt366,		.init_hwif	= init_hwif_hpt366,		.init_dma	= init_dma_hpt366,		.enablebits	= {{0x50,0x04,0x04}, {0x54,0x04,0x04}},		.udma_mask	= ATA_UDMA5,		.extra		= 240,		.host_flags	= IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD,		.pio_mask	= ATA_PIO4,		.mwdma_mask	= ATA_MWDMA2,	},{	/* 5 */		.name		= "HPT372N",		.init_chipset	= init_chipset_hpt366,		.init_hwif	= init_hwif_hpt366,		.init_dma	= init_dma_hpt366,		.enablebits	= {{0x50,0x04,0x04}, {0x54,0x04,0x04}},		.extra		= 240,		.host_flags	= IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD,		.pio_mask	= ATA_PIO4,		.mwdma_mask	= ATA_MWDMA2,	}};/** *	hpt366_init_one	-	called when an HPT366 is found *	@dev: the hpt366 device *	@id: the matching pci id * *	Called when the PCI registration layer (or the IDE initialization) *	finds a device matching our IDE device tables. */static int __devinit hpt366_init_one(struct pci_dev *dev, const struct pci_device_id *id){	const struct hpt_info *info = NULL;	struct pci_dev *dev2 = NULL;	struct ide_port_info d;	u8 idx = id->driver_data;	u8 rev = dev->revision;	if ((idx == 0 || idx == 4) && (PCI_FUNC(dev->devfn) & 1))		return -ENODEV;	switch (idx) {	case 0:		if (rev < 3)			info = &hpt36x;		else {			static const struct hpt_info *hpt37x_info[] =				{ &hpt370, &hpt370a, &hpt372, &hpt372n };			info = hpt37x_info[min_t(u8, rev, 6) - 3];			idx++;		}		break;	case 1:		info = (rev > 1) ? &hpt372n : &hpt372a;		break;	case 2:		info = (rev > 1) ? &hpt302n : &hpt302;		break;	case 3:		hpt371_init(dev);		info = (rev > 1) ? &hpt371n : &hpt371;		break;	case 4:		info = &hpt374;		break;	case 5:		info = &hpt372n;		break;	}	d = hpt366_chipsets[idx];	d.name = info->chip_name;	d.udma_mask = info->udma_mask;	pci_set_drvdata(dev, (void *)info);	if (info == &hpt36x || info == &hpt374)		dev2 = pci_get_slot(dev->bus, dev->devfn + 1);	if (dev2) {		int ret;		pci_set_drvdata(dev2, (void *)info);		if (info == &hpt374)			hpt374_init(dev, dev2);		else {			if (hpt36x_init(dev, dev2))				d.host_flags |= IDE_HFLAG_BOOTABLE;		}		ret = ide_setup_pci_devices(dev, dev2, &d);		if (ret < 0)			pci_dev_put(dev2);		return ret;	}	return ide_setup_pci_device(dev, &d);}static const struct pci_device_id hpt366_pci_tbl[] = {	{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT366),  0 },	{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372),  1 },	{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT302),  2 },	{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT371),  3 },	{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT374),  4 },	{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372N), 5 },	{ 0, },};MODULE_DEVICE_TABLE(pci, hpt366_pci_tbl);static struct pci_driver driver = {	.name		= "HPT366_IDE",	.id_table	= hpt366_pci_tbl,	.probe		= hpt366_init_one,};static int __init hpt366_ide_init(void){	return ide_pci_register_driver(&driver);}module_init(hpt366_ide_init);MODULE_AUTHOR("Andre Hedrick");MODULE_DESCRIPTION("PCI driver module for Highpoint HPT366 IDE");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?