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

📄 cmd64x.c

📁 at91rm9200处理器ide接口驱动程序源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		default:	speedt = 0x328A; break;	}	pci_write_config_word(dev, drive_pci, speedt);}static void config_cmd64x_chipset_for_pio (ide_drive_t *drive, byte set_speed){	byte speed	= 0x00;	byte set_pio	= ide_get_best_pio_mode(drive, 4, 5, NULL);	cmd64x_tuneproc(drive, set_pio);	speed = XFER_PIO_0 + set_pio;	if (set_speed)		(void) ide_config_drive_speed(drive, speed);}static void config_cmd680_chipset_for_pio (ide_drive_t *drive, byte set_speed){	ide_hwif_t *hwif	= HWIF(drive);	struct pci_dev *dev	= hwif->pci_dev;	u8 unit			= (drive->select.b.unit & 0x01);	u8 addr_mask		= (hwif->channel) ? 0x84 : 0x80;	u8 speed		= 0x00;	u8 mode_pci		= 0x00;	u8 channel_timings	= cmd680_taskfile_timing(hwif);	u8 set_pio		= ide_get_best_pio_mode(drive, 4, 5, NULL);	pci_read_config_byte(dev, addr_mask, &mode_pci);	mode_pci &= ~((unit) ? 0x30 : 0x03);	/* WARNING PIO timing mess is going to happen b/w devices, argh */	if ((channel_timings != set_pio) && (set_pio > channel_timings))		set_pio = channel_timings;	cmd680_tuneproc(drive, set_pio);	speed = XFER_PIO_0 + set_pio;	if (set_speed) {		(void) ide_config_drive_speed(drive, speed);		drive->current_speed = speed;	}}static void config_chipset_for_pio (ide_drive_t *drive, byte set_speed){        if (HWIF(drive)->pci_dev->device == PCI_DEVICE_ID_CMD_680) {		config_cmd680_chipset_for_pio(drive, set_speed);	} else {		config_cmd64x_chipset_for_pio(drive, set_speed);	}}static int cmd64x_tune_chipset (ide_drive_t *drive, byte speed){#ifdef CONFIG_BLK_DEV_IDEDMA	ide_hwif_t *hwif	= HWIF(drive);	struct pci_dev *dev	= hwif->pci_dev;	int err			= 0;	u8 unit			= (drive->select.b.unit & 0x01);	u8 pciU			= (hwif->channel) ? UDIDETCR1 : UDIDETCR0;	u8 pciD			= (hwif->channel) ? BMIDESR1 : BMIDESR0;	u8 regU			= 0;	u8 regD			= 0;	if ((drive->media != ide_disk) && (speed < XFER_SW_DMA_0))	return 1;	(void) pci_read_config_byte(dev, pciD, &regD);	(void) pci_read_config_byte(dev, pciU, &regU);	regD &= ~(unit ? 0x40 : 0x20);	regU &= ~(unit ? 0xCA : 0x35);	(void) pci_write_config_byte(dev, pciD, regD);	(void) pci_write_config_byte(dev, pciU, regU);	(void) pci_read_config_byte(dev, pciD, &regD);	(void) pci_read_config_byte(dev, pciU, &regU);	switch(speed) {		case XFER_UDMA_5:	regU |= (unit ? 0x0A : 0x05); break;		case XFER_UDMA_4:	regU |= (unit ? 0x4A : 0x15); break;		case XFER_UDMA_3:	regU |= (unit ? 0x8A : 0x25); break;		case XFER_UDMA_2:	regU |= (unit ? 0x42 : 0x11); break;		case XFER_UDMA_1:	regU |= (unit ? 0x82 : 0x21); break;		case XFER_UDMA_0:	regU |= (unit ? 0xC2 : 0x31); break;		case XFER_MW_DMA_2:	regD |= (unit ? 0x40 : 0x10); break;		case XFER_MW_DMA_1:	regD |= (unit ? 0x80 : 0x20); break;		case XFER_MW_DMA_0:	regD |= (unit ? 0xC0 : 0x30); break;		case XFER_SW_DMA_2:	regD |= (unit ? 0x40 : 0x10); break;		case XFER_SW_DMA_1:	regD |= (unit ? 0x80 : 0x20); break;		case XFER_SW_DMA_0:	regD |= (unit ? 0xC0 : 0x30); break;#else	int err			= 0;		switch(speed) {#endif /* CONFIG_BLK_DEV_IDEDMA */		case XFER_PIO_4:	cmd64x_tuneproc(drive, 4); break;		case XFER_PIO_3:	cmd64x_tuneproc(drive, 3); break;		case XFER_PIO_2:	cmd64x_tuneproc(drive, 2); break;		case XFER_PIO_1:	cmd64x_tuneproc(drive, 1); break;		case XFER_PIO_0:	cmd64x_tuneproc(drive, 0); break;		default:			return 1;	}#ifdef CONFIG_BLK_DEV_IDEDMA	(void) pci_write_config_byte(dev, pciU, regU);#endif /* CONFIG_BLK_DEV_IDEDMA */	err = ide_config_drive_speed(drive, speed);	drive->current_speed = speed;#ifdef CONFIG_BLK_DEV_IDEDMA	regD |= (unit ? 0x40 : 0x20);	(void) pci_write_config_byte(dev, pciD, regD);#endif /* CONFIG_BLK_DEV_IDEDMA */	return err;}static int cmd680_tune_chipset (ide_drive_t *drive, byte speed){	ide_hwif_t *hwif	= HWIF(drive);	struct pci_dev *dev	= hwif->pci_dev;	u8 addr_mask		= (hwif->channel) ? 0x84 : 0x80;	u8 unit			= (drive->select.b.unit & 0x01);	u8 dma_pci		= 0;	u8 udma_pci		= 0;	u8 mode_pci		= 0;	u8 scsc			= 0;	u16 ultra		= 0;	u16 multi		= 0;	int err			= 0;        pci_read_config_byte(dev, addr_mask, &mode_pci);	pci_read_config_byte(dev, 0x8A, &scsc);        switch (drive->dn) {		case 0: dma_pci = 0xA8; udma_pci = 0xAC; break;		case 1: dma_pci = 0xAA; udma_pci = 0xAE; break;		case 2: dma_pci = 0xB8; udma_pci = 0xBC; break;		case 3: dma_pci = 0xBA; udma_pci = 0xBE; break;		default: return 1;	}	pci_read_config_byte(dev, addr_mask, &mode_pci);	mode_pci &= ~((unit) ? 0x30 : 0x03);	pci_read_config_word(dev, dma_pci, &multi);	pci_read_config_word(dev, udma_pci, &ultra);	if ((speed == XFER_UDMA_6) && (scsc & 0x30) == 0x00) {		pci_write_config_byte(dev, 0x8A, scsc|0x01);		pci_read_config_byte(dev, 0x8A, &scsc);	}	switch(speed) {#ifdef CONFIG_BLK_DEV_IDEDMA		case XFER_UDMA_6:			if ((scsc & 0x30) == 0x00)				goto speed_break;			multi = 0x10C1;			ultra &= ~0x3F;			ultra |= 0x01;			break;speed_break :			speed = XFER_UDMA_5;		case XFER_UDMA_5:			multi = 0x10C1;			ultra &= ~0x3F;			ultra |= (((scsc & 0x30) == 0x00) ? 0x01 : 0x02);			break;		case XFER_UDMA_4:			multi = 0x10C1;			ultra &= ~0x3F;			ultra |= (((scsc & 0x30) == 0x00) ? 0x02 : 0x03);			break;		case XFER_UDMA_3:			multi = 0x10C1;			ultra &= ~0x3F;			ultra |= (((scsc & 0x30) == 0x00) ? 0x04 : 0x05);			break;		case XFER_UDMA_2:			multi = 0x10C1;			ultra &= ~0x3F;			ultra |= (((scsc & 0x30) == 0x00) ? 0x05 : 0x07);			break;		case XFER_UDMA_1:			multi = 0x10C1;			ultra &= ~0x3F;			ultra |= (((scsc & 0x30) == 0x00) ? 0x07 : 0x0B);			break;		case XFER_UDMA_0:			multi = 0x10C1;			ultra &= ~0x3F;			ultra |= (((scsc & 0x30) == 0x00) ? 0x0C : 0x0F);			break;		case XFER_MW_DMA_2:			multi = 0x10C1;			break;		case XFER_MW_DMA_1:			multi = 0x10C2;			break;		case XFER_MW_DMA_0:			multi = 0x2208;			break;#endif /* CONFIG_BLK_DEV_IDEDMA */		case XFER_PIO_4:	cmd680_tuneproc(drive, 4); break;		case XFER_PIO_3:	cmd680_tuneproc(drive, 3); break;		case XFER_PIO_2:	cmd680_tuneproc(drive, 2); break;		case XFER_PIO_1:	cmd680_tuneproc(drive, 1); break;		case XFER_PIO_0:	cmd680_tuneproc(drive, 0); break;		default:			return 1;	}		if (speed >= XFER_MW_DMA_0) 		config_cmd680_chipset_for_pio(drive, 0);	if (speed >= XFER_UDMA_0)		mode_pci |= ((unit) ? 0x30 : 0x03);	else if (speed >= XFER_MW_DMA_0)		mode_pci |= ((unit) ? 0x20 : 0x02);	else		mode_pci |= ((unit) ? 0x10 : 0x01);	pci_write_config_byte(dev, addr_mask, mode_pci);	pci_write_config_word(dev, dma_pci, multi);	pci_write_config_word(dev, udma_pci, ultra);	err = ide_config_drive_speed(drive, speed);	drive->current_speed = speed;	return err;}#ifdef CONFIG_BLK_DEV_IDEDMAstatic int config_cmd64x_chipset_for_dma (ide_drive_t *drive, unsigned int rev, byte ultra_66){	struct hd_driveid *id	= drive->id;	ide_hwif_t *hwif	= HWIF(drive);	struct pci_dev *dev	= hwif->pci_dev;	byte speed		= 0x00;	byte set_pio		= 0x00;	byte udma_33		= ((rev >= 0x05) || (ultra_66)) ? 1 : 0;	byte udma_66		= eighty_ninty_three(drive);	byte udma_100		= 0;	int rval;	switch(dev->device) {		case PCI_DEVICE_ID_CMD_649: udma_100 = 1; break;		case PCI_DEVICE_ID_CMD_648:		case PCI_DEVICE_ID_CMD_646:		case PCI_DEVICE_ID_CMD_643:		default:			break;	}	if (drive->media != ide_disk) {		cmdprintk("CMD64X: drive->media != ide_disk at double check, inital check failed!!\n");		return ((int) ide_dma_off);	}	/* 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 ((id->dma_ultra & 0x0020) && (udma_100) && (udma_66) && (udma_33)) {		speed = XFER_UDMA_5;	} else if ((id->dma_ultra & 0x0010) && (udma_66) && (udma_33)) {		speed = XFER_UDMA_4;	} else if ((id->dma_ultra & 0x0008) && (udma_66) && (udma_33)) {		speed = XFER_UDMA_3;	} else if ((id->dma_ultra & 0x0004) && (udma_33)) {		speed = XFER_UDMA_2;	} else if ((id->dma_ultra & 0x0002) && (udma_33)) {		speed = XFER_UDMA_1;	} else if ((id->dma_ultra & 0x0001) && (udma_33)) {		speed = XFER_UDMA_0;	} else if (id->dma_mword & 0x0004) {		speed = XFER_MW_DMA_2;	} else if (id->dma_mword & 0x0002) {		speed = XFER_MW_DMA_1;	} else if (id->dma_mword & 0x0001) {		speed = XFER_MW_DMA_0;	} else if (id->dma_1word & 0x0004) {		speed = XFER_SW_DMA_2;	} else if (id->dma_1word & 0x0002) {		speed = XFER_SW_DMA_1;	} else if (id->dma_1word & 0x0001) {		speed = XFER_SW_DMA_0;	} else {		set_pio = 1;	}	if (!drive->init_speed)		drive->init_speed = speed;	config_chipset_for_pio(drive, set_pio);	if (set_pio)		return ((int) ide_dma_off_quietly);	if (cmd64x_tune_chipset(drive, speed))		return ((int) ide_dma_off);	rval = (int)(	((id->dma_ultra >> 11) & 7) ? ide_dma_on :			((id->dma_ultra >> 8) & 7) ? ide_dma_on :			((id->dma_mword >> 8) & 7) ? ide_dma_on :			((id->dma_1word >> 8) & 7) ? ide_dma_on :						     ide_dma_off_quietly);	return rval;}static int config_cmd680_chipset_for_dma (ide_drive_t *drive){	struct hd_driveid *id	= drive->id;	byte udma_66		= eighty_ninty_three(drive);	byte speed		= 0x00;	byte set_pio		= 0x00;	int rval;	if ((id->dma_ultra & 0x0040) && (udma_66))	speed = XFER_UDMA_6;	else if ((id->dma_ultra & 0x0020) && (udma_66))	speed = XFER_UDMA_5;	else if ((id->dma_ultra & 0x0010) && (udma_66))	speed = XFER_UDMA_4;	else if ((id->dma_ultra & 0x0008) && (udma_66))	speed = XFER_UDMA_3;	else if (id->dma_ultra & 0x0004)		speed = XFER_UDMA_2;	else if (id->dma_ultra & 0x0002)		speed = XFER_UDMA_1;	else if (id->dma_ultra & 0x0001)		speed = XFER_UDMA_0;	else if (id->dma_mword & 0x0004)		speed = XFER_MW_DMA_2;	else if (id->dma_mword & 0x0002)		speed = XFER_MW_DMA_1;	else if (id->dma_mword & 0x0001)		speed = XFER_MW_DMA_0;	else {		set_pio = 1;	}	if (!drive->init_speed)		drive->init_speed = speed;	config_chipset_for_pio(drive, set_pio);	if (set_pio)		return ((int) ide_dma_off_quietly);	if (cmd680_tune_chipset(drive, speed))		return ((int) ide_dma_off);	rval = (int)(	((id->dma_ultra >> 14) & 3) ? ide_dma_on :			((id->dma_ultra >> 11) & 7) ? ide_dma_on :			((id->dma_ultra >> 8) & 7) ? ide_dma_on :			((id->dma_mword >> 8) & 7) ? ide_dma_on :			((id->dma_1word >> 8) & 7) ? ide_dma_on :						     ide_dma_off_quietly);	return rval;}static int config_chipset_for_dma (ide_drive_t *drive, unsigned int rev, byte ultra_66){	if (HWIF(drive)->pci_dev->device == PCI_DEVICE_ID_CMD_680)		return (config_cmd680_chipset_for_dma(drive));	return (config_cmd64x_chipset_for_dma(drive, rev, ultra_66));}static int cmd64x_config_drive_for_dma (ide_drive_t *drive){	struct hd_driveid *id	= drive->id;	ide_hwif_t *hwif	= HWIF(drive);	struct pci_dev *dev	= hwif->pci_dev;	unsigned int class_rev	= 0;	byte can_ultra_33	= 0;	byte can_ultra_66	= 0;	byte can_ultra_100	= 0;	byte can_ultra_133	= 0;	ide_dma_action_t dma_func = ide_dma_on;	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);	class_rev &= 0xff;		switch(dev->device) {		case PCI_DEVICE_ID_CMD_680:			can_ultra_133 = 1;		case PCI_DEVICE_ID_CMD_649:

⌨️ 快捷键说明

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