⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmd64x.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	case XFER_MW_DMA_1:		program_cycle_times(drive, 150, 80);		break;	case XFER_MW_DMA_0:		program_cycle_times(drive, 480, 215);		break;	default:		return;	}	if (speed >= XFER_SW_DMA_0)		(void) pci_write_config_byte(dev, pciU, regU);}static int cmd648_ide_dma_end (ide_drive_t *drive){	ide_hwif_t *hwif	= HWIF(drive);	int err			= __ide_dma_end(drive);	u8  irq_mask		= hwif->channel ? MRDMODE_INTR_CH1 :						  MRDMODE_INTR_CH0;	u8  mrdmode		= inb(hwif->dma_master + 0x01);	/* clear the interrupt bit */	outb((mrdmode & ~(MRDMODE_INTR_CH0 | MRDMODE_INTR_CH1)) | irq_mask,	     hwif->dma_master + 0x01);	return err;}static int cmd64x_ide_dma_end (ide_drive_t *drive){	ide_hwif_t *hwif	= HWIF(drive);	struct pci_dev *dev	= hwif->pci_dev;	int irq_reg		= hwif->channel ? ARTTIM23 : CFR;	u8  irq_mask		= hwif->channel ? ARTTIM23_INTR_CH1 :						  CFR_INTR_CH0;	u8  irq_stat		= 0;	int err			= __ide_dma_end(drive);	(void) pci_read_config_byte(dev, irq_reg, &irq_stat);	/* clear the interrupt bit */	(void) pci_write_config_byte(dev, irq_reg, irq_stat | irq_mask);	return err;}static int cmd648_ide_dma_test_irq (ide_drive_t *drive){	ide_hwif_t *hwif	= HWIF(drive);	u8 irq_mask		= hwif->channel ? MRDMODE_INTR_CH1 :						  MRDMODE_INTR_CH0;	u8 dma_stat		= inb(hwif->dma_status);	u8 mrdmode		= inb(hwif->dma_master + 0x01);#ifdef DEBUG	printk("%s: dma_stat: 0x%02x mrdmode: 0x%02x irq_mask: 0x%02x\n",	       drive->name, dma_stat, mrdmode, irq_mask);#endif	if (!(mrdmode & irq_mask))		return 0;	/* return 1 if INTR asserted */	if (dma_stat & 4)		return 1;	return 0;}static int cmd64x_ide_dma_test_irq (ide_drive_t *drive){	ide_hwif_t *hwif	= HWIF(drive);	struct pci_dev *dev	= hwif->pci_dev;	int irq_reg		= hwif->channel ? ARTTIM23 : CFR;	u8  irq_mask		= hwif->channel ? ARTTIM23_INTR_CH1 :						  CFR_INTR_CH0;	u8  dma_stat		= inb(hwif->dma_status);	u8  irq_stat		= 0;	(void) pci_read_config_byte(dev, irq_reg, &irq_stat);#ifdef DEBUG	printk("%s: dma_stat: 0x%02x irq_stat: 0x%02x irq_mask: 0x%02x\n",	       drive->name, dma_stat, irq_stat, irq_mask);#endif	if (!(irq_stat & irq_mask))		return 0;	/* return 1 if INTR asserted */	if (dma_stat & 4)		return 1;	return 0;}/* * ASUS P55T2P4D with CMD646 chipset revision 0x01 requires the old * event order for DMA transfers. */static int cmd646_1_ide_dma_end (ide_drive_t *drive){	ide_hwif_t *hwif = HWIF(drive);	u8 dma_stat = 0, dma_cmd = 0;	drive->waiting_for_dma = 0;	/* get DMA status */	dma_stat = inb(hwif->dma_status);	/* read DMA command state */	dma_cmd = inb(hwif->dma_command);	/* stop DMA */	outb(dma_cmd & ~1, hwif->dma_command);	/* clear the INTR & ERROR bits */	outb(dma_stat | 6, hwif->dma_status);	/* and free any DMA resources */	ide_destroy_dmatable(drive);	/* verify good DMA status */	return (dma_stat & 7) != 4;}static unsigned int __devinit init_chipset_cmd64x(struct pci_dev *dev, const char *name){	u8 mrdmode = 0;	if (dev->device == PCI_DEVICE_ID_CMD_646) {		switch (dev->revision) {		case 0x07:		case 0x05:			printk("%s: UltraDMA capable\n", name);			break;		case 0x03:		default:			printk("%s: MultiWord DMA force limited\n", name);			break;		case 0x01:			printk("%s: MultiWord DMA limited, "			       "IRQ workaround enabled\n", name);			break;		}	}	/* Set a good latency timer and cache line size value. */	(void) pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);	/* FIXME: pci_set_master() to ensure a good latency timer value */	/*	 * Enable interrupts, select MEMORY READ LINE for reads.	 *	 * NOTE: although not mentioned in the PCI0646U specs,	 * bits 0-1 are write only and won't be read back as	 * set or not -- PCI0646U2 specs clarify this point.	 */	(void) pci_read_config_byte (dev, MRDMODE, &mrdmode);	mrdmode &= ~0x30;	(void) pci_write_config_byte(dev, MRDMODE, (mrdmode | 0x02));#if defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_IDE_PROC_FS)	cmd_devs[n_cmd_devs++] = dev;	if (!cmd64x_proc) {		cmd64x_proc = 1;		ide_pci_create_host_proc("cmd64x", cmd64x_get_info);	}#endif /* DISPLAY_CMD64X_TIMINGS && CONFIG_IDE_PROC_FS */	return 0;}static u8 __devinit ata66_cmd64x(ide_hwif_t *hwif){	struct pci_dev  *dev	= hwif->pci_dev;	u8 bmidecsr = 0, mask	= hwif->channel ? 0x02 : 0x01;	switch (dev->device) {	case PCI_DEVICE_ID_CMD_648:	case PCI_DEVICE_ID_CMD_649: 		pci_read_config_byte(dev, BMIDECSR, &bmidecsr);		return (bmidecsr & mask) ? ATA_CBL_PATA80 : ATA_CBL_PATA40;	default:		return ATA_CBL_PATA40;	}}static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif){	struct pci_dev *dev	= hwif->pci_dev;	hwif->set_pio_mode = &cmd64x_set_pio_mode;	hwif->set_dma_mode = &cmd64x_set_dma_mode;	if (!hwif->dma_base)		return;	/*	 * UltraDMA only supported on PCI646U and PCI646U2, which	 * correspond to revisions 0x03, 0x05 and 0x07 respectively.	 * Actually, although the CMD tech support people won't	 * tell me the details, the 0x03 revision cannot support	 * UDMA correctly without hardware modifications, and even	 * then it only works with Quantum disks due to some	 * hold time assumptions in the 646U part which are fixed	 * in the 646U2.	 *	 * So we only do UltraDMA on revision 0x05 and 0x07 chipsets.	 */	if (dev->device == PCI_DEVICE_ID_CMD_646 && dev->revision < 5)		hwif->ultra_mask = 0x00;	if (hwif->cbl != ATA_CBL_PATA40_SHORT)		hwif->cbl = ata66_cmd64x(hwif);	switch (dev->device) {	case PCI_DEVICE_ID_CMD_648:	case PCI_DEVICE_ID_CMD_649:	alt_irq_bits:		hwif->ide_dma_end	= &cmd648_ide_dma_end;		hwif->ide_dma_test_irq	= &cmd648_ide_dma_test_irq;		break;	case PCI_DEVICE_ID_CMD_646:		if (dev->revision == 0x01) {			hwif->ide_dma_end = &cmd646_1_ide_dma_end;			break;		} else if (dev->revision >= 0x03)			goto alt_irq_bits;		/* fall thru */	default:		hwif->ide_dma_end	= &cmd64x_ide_dma_end;		hwif->ide_dma_test_irq	= &cmd64x_ide_dma_test_irq;		break;	}}static const struct ide_port_info cmd64x_chipsets[] __devinitdata = {	{	/* 0 */		.name		= "CMD643",		.init_chipset	= init_chipset_cmd64x,		.init_hwif	= init_hwif_cmd64x,		.enablebits	= {{0x00,0x00,0x00}, {0x51,0x08,0x08}},		.host_flags	= IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_BOOTABLE,		.pio_mask	= ATA_PIO5,		.mwdma_mask	= ATA_MWDMA2,		.udma_mask	= 0x00, /* no udma */	},{	/* 1 */		.name		= "CMD646",		.init_chipset	= init_chipset_cmd64x,		.init_hwif	= init_hwif_cmd64x,		.enablebits	= {{0x51,0x04,0x04}, {0x51,0x08,0x08}},		.chipset	= ide_cmd646,		.host_flags	= IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_BOOTABLE,		.pio_mask	= ATA_PIO5,		.mwdma_mask	= ATA_MWDMA2,		.udma_mask	= ATA_UDMA2,	},{	/* 2 */		.name		= "CMD648",		.init_chipset	= init_chipset_cmd64x,		.init_hwif	= init_hwif_cmd64x,		.enablebits	= {{0x51,0x04,0x04}, {0x51,0x08,0x08}},		.host_flags	= IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_BOOTABLE,		.pio_mask	= ATA_PIO5,		.mwdma_mask	= ATA_MWDMA2,		.udma_mask	= ATA_UDMA4,	},{	/* 3 */		.name		= "CMD649",		.init_chipset	= init_chipset_cmd64x,		.init_hwif	= init_hwif_cmd64x,		.enablebits	= {{0x51,0x04,0x04}, {0x51,0x08,0x08}},		.host_flags	= IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_BOOTABLE,		.pio_mask	= ATA_PIO5,		.mwdma_mask	= ATA_MWDMA2,		.udma_mask	= ATA_UDMA5,	}};static int __devinit cmd64x_init_one(struct pci_dev *dev, const struct pci_device_id *id){	struct ide_port_info d;	u8 idx = id->driver_data;	d = cmd64x_chipsets[idx];	/*	 * The original PCI0646 didn't have the primary channel enable bit,	 * it appeared starting with PCI0646U (i.e. revision ID 3).	 */	if (idx == 1 && dev->revision < 3)		d.enablebits[0].reg = 0;	return ide_setup_pci_device(dev, &d);}static const struct pci_device_id cmd64x_pci_tbl[] = {	{ PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_643), 0 },	{ PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_646), 1 },	{ PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_648), 2 },	{ PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_649), 3 },	{ 0, },};MODULE_DEVICE_TABLE(pci, cmd64x_pci_tbl);static struct pci_driver driver = {	.name		= "CMD64x_IDE",	.id_table	= cmd64x_pci_tbl,	.probe		= cmd64x_init_one,};static int __init cmd64x_ide_init(void){	return ide_pci_register_driver(&driver);}module_init(cmd64x_ide_init);MODULE_AUTHOR("Eddie Dost, David Miller, Andre Hedrick");MODULE_DESCRIPTION("PCI driver module for CMD64x IDE");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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