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

📄 pata_via.c

📁 their RouterBoard 1xx and 5xx series devices. The original Mikrotik code
💻 C
📖 第 1 页 / 共 2 页
字号:
}static void via_set_piomode(struct ata_port *ap, struct ata_device *adev){	const struct via_isa_bridge *config = ap->host->private_data;	int set_ast = (config->flags & VIA_BAD_AST) ? 0 : 1;	int mode = config->flags & VIA_UDMA;	static u8 tclock[5] = { 1, 1, 2, 3, 4 };	static u8 udma[5] = { 0, 33, 66, 100, 133 };	via_do_set_mode(ap, adev, adev->pio_mode, tclock[mode], set_ast, udma[mode]);}static void via_set_dmamode(struct ata_port *ap, struct ata_device *adev){	const struct via_isa_bridge *config = ap->host->private_data;	int set_ast = (config->flags & VIA_BAD_AST) ? 0 : 1;	int mode = config->flags & VIA_UDMA;	static u8 tclock[5] = { 1, 1, 2, 3, 4 };	static u8 udma[5] = { 0, 33, 66, 100, 133 };	via_do_set_mode(ap, adev, adev->dma_mode, tclock[mode], set_ast, udma[mode]);}static struct scsi_host_template via_sht = {	ATA_BMDMA_SHT(DRV_NAME),};static struct ata_port_operations via_port_ops = {	.inherits	= &ata_bmdma_port_ops,	.cable_detect	= via_cable_detect,	.set_piomode	= via_set_piomode,	.set_dmamode	= via_set_dmamode,	.prereset	= via_pre_reset,};static struct ata_port_operations via_port_ops_noirq = {	.inherits	= &via_port_ops,	.sff_data_xfer	= ata_sff_data_xfer_noirq,};/** *	via_config_fifo		-	set up the FIFO *	@pdev: PCI device *	@flags: configuration flags * *	Set the FIFO properties for this device if necessary. Used both on *	set up and on and the resume path */static void via_config_fifo(struct pci_dev *pdev, unsigned int flags){	u8 enable;	/* 0x40 low bits indicate enabled channels */	pci_read_config_byte(pdev, 0x40 , &enable);	enable &= 3;	if (flags & VIA_SET_FIFO) {		static const u8 fifo_setting[4] = {0x00, 0x60, 0x00, 0x20};		u8 fifo;		pci_read_config_byte(pdev, 0x43, &fifo);		/* Clear PREQ# until DDACK# for errata */		if (flags & VIA_BAD_PREQ)			fifo &= 0x7F;		else			fifo &= 0x9f;		/* Turn on FIFO for enabled channels */		fifo |= fifo_setting[enable];		pci_write_config_byte(pdev, 0x43, fifo);	}}/** *	via_init_one		-	discovery callback *	@pdev: PCI device *	@id: PCI table info * *	A VIA IDE interface has been discovered. Figure out what revision *	and perform configuration work before handing it to the ATA layer */static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id){	/* Early VIA without UDMA support */	static const struct ata_port_info via_mwdma_info = {		.flags = ATA_FLAG_SLAVE_POSS,		.pio_mask = 0x1f,		.mwdma_mask = 0x07,		.port_ops = &via_port_ops	};	/* Ditto with IRQ masking required */	static const struct ata_port_info via_mwdma_info_borked = {		.flags = ATA_FLAG_SLAVE_POSS,		.pio_mask = 0x1f,		.mwdma_mask = 0x07,		.port_ops = &via_port_ops_noirq,	};	/* VIA UDMA 33 devices (and borked 66) */	static const struct ata_port_info via_udma33_info = {		.flags = ATA_FLAG_SLAVE_POSS,		.pio_mask = 0x1f,		.mwdma_mask = 0x07,		.udma_mask = ATA_UDMA2,		.port_ops = &via_port_ops	};	/* VIA UDMA 66 devices */	static const struct ata_port_info via_udma66_info = {		.flags = ATA_FLAG_SLAVE_POSS,		.pio_mask = 0x1f,		.mwdma_mask = 0x07,		.udma_mask = ATA_UDMA4,		.port_ops = &via_port_ops	};	/* VIA UDMA 100 devices */	static const struct ata_port_info via_udma100_info = {		.flags = ATA_FLAG_SLAVE_POSS,		.pio_mask = 0x1f,		.mwdma_mask = 0x07,		.udma_mask = ATA_UDMA5,		.port_ops = &via_port_ops	};	/* UDMA133 with bad AST (All current 133) */	static const struct ata_port_info via_udma133_info = {		.flags = ATA_FLAG_SLAVE_POSS,		.pio_mask = 0x1f,		.mwdma_mask = 0x07,		.udma_mask = ATA_UDMA6,	/* FIXME: should check north bridge */		.port_ops = &via_port_ops	};	const struct ata_port_info *ppi[] = { NULL, NULL };	struct pci_dev *isa = NULL;	const struct via_isa_bridge *config;	static int printed_version;	u8 enable;	u32 timing;	int rc;	if (!printed_version++)		dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");	rc = pcim_enable_device(pdev);	if (rc)		return rc;	/* To find out how the IDE will behave and what features we	   actually have to look at the bridge not the IDE controller */	for (config = via_isa_bridges; config->id; config++)		if ((isa = pci_get_device(PCI_VENDOR_ID_VIA +			!!(config->flags & VIA_BAD_ID),			config->id, NULL))) {			if (isa->revision >= config->rev_min &&			    isa->revision <= config->rev_max)				break;			pci_dev_put(isa);		}	if (!config->id) {		printk(KERN_WARNING "via: Unknown VIA SouthBridge, disabling.\n");		return -ENODEV;	}	pci_dev_put(isa);	if (!(config->flags & VIA_NO_ENABLES)) {		/* 0x40 low bits indicate enabled channels */		pci_read_config_byte(pdev, 0x40 , &enable);		enable &= 3;		if (enable == 0)			return -ENODEV;	}	/* Initialise the FIFO for the enabled channels. */	via_config_fifo(pdev, config->flags);	/* Clock set up */	switch(config->flags & VIA_UDMA) {		case VIA_UDMA_NONE:			if (config->flags & VIA_NO_UNMASK)				ppi[0] = &via_mwdma_info_borked;			else				ppi[0] = &via_mwdma_info;			break;		case VIA_UDMA_33:			ppi[0] = &via_udma33_info;			break;		case VIA_UDMA_66:			ppi[0] = &via_udma66_info;			/* The 66 MHz devices require we enable the clock */			pci_read_config_dword(pdev, 0x50, &timing);			timing |= 0x80008;			pci_write_config_dword(pdev, 0x50, timing);			break;		case VIA_UDMA_100:			ppi[0] = &via_udma100_info;			break;		case VIA_UDMA_133:			ppi[0] = &via_udma133_info;			break;		default:			WARN_ON(1);			return -ENODEV;	}	if (config->flags & VIA_BAD_CLK66) {		/* Disable the 66MHz clock on problem devices */		pci_read_config_dword(pdev, 0x50, &timing);		timing &= ~0x80008;		pci_write_config_dword(pdev, 0x50, timing);	}	/* We have established the device type, now fire it up */	return ata_pci_sff_init_one(pdev, ppi, &via_sht, (void *)config);}#ifdef CONFIG_PM/** *	via_reinit_one		-	reinit after resume *	@pdev; PCI device * *	Called when the VIA PATA device is resumed. We must then *	reconfigure the fifo and other setup we may have altered. In *	addition the kernel needs to have the resume methods on PCI *	quirk supported. */static int via_reinit_one(struct pci_dev *pdev){	u32 timing;	struct ata_host *host = dev_get_drvdata(&pdev->dev);	const struct via_isa_bridge *config = host->private_data;	int rc;	rc = ata_pci_device_do_resume(pdev);	if (rc)		return rc;	via_config_fifo(pdev, config->flags);	if ((config->flags & VIA_UDMA) == VIA_UDMA_66) {		/* The 66 MHz devices require we enable the clock */		pci_read_config_dword(pdev, 0x50, &timing);		timing |= 0x80008;		pci_write_config_dword(pdev, 0x50, timing);	}	if (config->flags & VIA_BAD_CLK66) {		/* Disable the 66MHz clock on problem devices */		pci_read_config_dword(pdev, 0x50, &timing);		timing &= ~0x80008;		pci_write_config_dword(pdev, 0x50, timing);	}	ata_host_resume(host);	return 0;}#endifstatic const struct pci_device_id via[] = {	{ PCI_VDEVICE(VIA, 0x0571), },	{ PCI_VDEVICE(VIA, 0x0581), },	{ PCI_VDEVICE(VIA, 0x1571), },	{ PCI_VDEVICE(VIA, 0x3164), },	{ PCI_VDEVICE(VIA, 0x5324), },	{ },};static struct pci_driver via_pci_driver = {	.name 		= DRV_NAME,	.id_table	= via,	.probe 		= via_init_one,	.remove		= ata_pci_remove_one,#ifdef CONFIG_PM	.suspend	= ata_pci_device_suspend,	.resume		= via_reinit_one,#endif};static int __init via_init(void){	return pci_register_driver(&via_pci_driver);}static void __exit via_exit(void){	pci_unregister_driver(&via_pci_driver);}MODULE_AUTHOR("Alan Cox");MODULE_DESCRIPTION("low-level driver for VIA PATA");MODULE_LICENSE("GPL");MODULE_DEVICE_TABLE(pci, via);MODULE_VERSION(DRV_VERSION);module_init(via_init);module_exit(via_exit);

⌨️ 快捷键说明

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