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

📄 au1xxx-ide.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
	/* Is the drive in our DMA black list? */	if ( auide_hwif.black_list ) {		drive->using_dma = 0;		/* Borrowed the warning message from ide-dma.c */		printk(KERN_WARNING "%s: Disabling DMA for %s (blacklisted)\n",		       drive->name, drive->id->model);	       	}	else		drive->using_dma = 1;	speed = ide_find_best_mode(drive, XFER_PIO | XFER_MWDMA);		if (drive->autodma && (speed & XFER_MODE) != XFER_PIO)		return HWIF(drive)->ide_dma_on(drive);	return HWIF(drive)->ide_dma_off_quietly(drive);}static int auide_dma_test_irq(ide_drive_t *drive){		if (drive->waiting_for_dma == 0)		printk(KERN_WARNING "%s: ide_dma_test_irq \                                     called while not waiting\n", drive->name);	/* If dbdma didn't execute the STOP command yet, the	 * active bit is still set	 */	drive->waiting_for_dma++;	if (drive->waiting_for_dma >= DMA_WAIT_TIMEOUT) {		printk(KERN_WARNING "%s: timeout waiting for ddma to \                                     complete\n", drive->name);		return 1;	}	udelay(10);	return 0;}static int auide_dma_host_on(ide_drive_t *drive){	return 0;}static int auide_dma_on(ide_drive_t *drive){	drive->using_dma = 1;	return auide_dma_host_on(drive);}static int auide_dma_host_off(ide_drive_t *drive){	return 0;}static int auide_dma_off_quietly(ide_drive_t *drive){	drive->using_dma = 0;	return auide_dma_host_off(drive);}static int auide_dma_lostirq(ide_drive_t *drive){	printk(KERN_ERR "%s: IRQ lost\n", drive->name);	return 0;}static void auide_ddma_tx_callback(int irq, void *param, struct pt_regs *regs){	_auide_hwif *ahwif = (_auide_hwif*)param;	ahwif->drive->waiting_for_dma = 0;}static void auide_ddma_rx_callback(int irq, void *param, struct pt_regs *regs){	_auide_hwif *ahwif = (_auide_hwif*)param;	ahwif->drive->waiting_for_dma = 0;}#endif /* end CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */static void auide_init_dbdma_dev(dbdev_tab_t *dev, u32 dev_id, u32 tsize, u32 devwidth, u32 flags){	dev->dev_id          = dev_id;	dev->dev_physaddr    = (u32)AU1XXX_ATA_PHYS_ADDR;	dev->dev_intlevel    = 0;	dev->dev_intpolarity = 0;	dev->dev_tsize       = tsize;	dev->dev_devwidth    = devwidth;	dev->dev_flags       = flags;}  #if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)static int auide_dma_timeout(ide_drive_t *drive){//      printk("%s\n", __FUNCTION__);	printk(KERN_ERR "%s: DMA timeout occurred: ", drive->name);	if (HWIF(drive)->ide_dma_test_irq(drive))		return 0;	return HWIF(drive)->ide_dma_end(drive);}					static int auide_ddma_init(_auide_hwif *auide) {		dbdev_tab_t source_dev_tab, target_dev_tab;	u32 dev_id, tsize, devwidth, flags;	ide_hwif_t *hwif = auide->hwif;	dev_id   = AU1XXX_ATA_DDMA_REQ;	if (auide->white_list || auide->black_list) {		tsize    = 8;		devwidth = 32;	}	else { 		tsize    = 1;		devwidth = 16;				printk(KERN_ERR "au1xxx-ide: %s is not on ide driver whitelist.\n",auide_hwif.drive->id->model);		printk(KERN_ERR "            please read 'Documentation/mips/AU1xxx_IDE.README'");	}#ifdef IDE_AU1XXX_BURSTMODE 	flags = DEV_FLAGS_SYNC | DEV_FLAGS_BURSTABLE;#else	flags = DEV_FLAGS_SYNC;#endif	/* setup dev_tab for tx channel */	auide_init_dbdma_dev( &source_dev_tab,			      dev_id,			      tsize, devwidth, DEV_FLAGS_OUT | flags); 	auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );	auide_init_dbdma_dev( &source_dev_tab,			      dev_id,			      tsize, devwidth, DEV_FLAGS_IN | flags); 	auide->rx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );		/* We also need to add a target device for the DMA */	auide_init_dbdma_dev( &target_dev_tab,			      (u32)DSCR_CMD0_ALWAYS,			      tsize, devwidth, DEV_FLAGS_ANYUSE);	auide->target_dev_id = au1xxx_ddma_add_device(&target_dev_tab);	 	/* Get a channel for TX */	auide->tx_chan = au1xxx_dbdma_chan_alloc(auide->target_dev_id,						 auide->tx_dev_id,						 auide_ddma_tx_callback,						 (void*)auide); 	/* Get a channel for RX */	auide->rx_chan = au1xxx_dbdma_chan_alloc(auide->rx_dev_id,						 auide->target_dev_id,						 auide_ddma_rx_callback,						 (void*)auide);	auide->tx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->tx_chan,							     NUM_DESCRIPTORS);	auide->rx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->rx_chan,							     NUM_DESCRIPTORS); 	hwif->dmatable_cpu = dma_alloc_coherent(auide->dev,						PRD_ENTRIES * PRD_BYTES,        /* 1 Page */						&hwif->dmatable_dma, GFP_KERNEL);		au1xxx_dbdma_start( auide->tx_chan );	au1xxx_dbdma_start( auide->rx_chan ); 	return 0;} #else static int auide_ddma_init( _auide_hwif *auide ){	dbdev_tab_t source_dev_tab;	int flags;#ifdef IDE_AU1XXX_BURSTMODE 	flags = DEV_FLAGS_SYNC | DEV_FLAGS_BURSTABLE;#else	flags = DEV_FLAGS_SYNC;#endif	/* setup dev_tab for tx channel */	auide_init_dbdma_dev( &source_dev_tab,			      (u32)DSCR_CMD0_ALWAYS,			      8, 32, DEV_FLAGS_OUT | flags); 	auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );	auide_init_dbdma_dev( &source_dev_tab,			      (u32)DSCR_CMD0_ALWAYS,			      8, 32, DEV_FLAGS_IN | flags); 	auide->rx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );		/* Get a channel for TX */	auide->tx_chan = au1xxx_dbdma_chan_alloc(DSCR_CMD0_ALWAYS,						 auide->tx_dev_id,						 NULL,						 (void*)auide); 	/* Get a channel for RX */	auide->rx_chan = au1xxx_dbdma_chan_alloc(auide->rx_dev_id,						 DSCR_CMD0_ALWAYS,						 NULL,						 (void*)auide); 	auide->tx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->tx_chan,							     NUM_DESCRIPTORS);	auide->rx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->rx_chan,							     NUM_DESCRIPTORS); 	au1xxx_dbdma_start( auide->tx_chan );	au1xxx_dbdma_start( auide->rx_chan ); 		return 0;}#endifstatic void auide_setup_ports(hw_regs_t *hw, _auide_hwif *ahwif){	int i;	unsigned long *ata_regs = hw->io_ports;	/* FIXME? */	for (i = 0; i < IDE_CONTROL_OFFSET; i++) {		*ata_regs++ = ahwif->regbase + (i << AU1XXX_ATA_REG_OFFSET);	}	/* set the Alternative Status register */	*ata_regs = ahwif->regbase + (14 << AU1XXX_ATA_REG_OFFSET);}static int au_ide_probe(struct device *dev){	struct platform_device *pdev = to_platform_device(dev);	_auide_hwif *ahwif = &auide_hwif;	ide_hwif_t *hwif;	struct resource *res;	int ret = 0;#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)	char *mode = "MWDMA2";#elif defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA)	char *mode = "PIO+DDMA(offload)";#endif	memset(&auide_hwif, 0, sizeof(_auide_hwif));	auide_hwif.dev                  = 0;	ahwif->dev = dev;	ahwif->irq = platform_get_irq(pdev, 0);	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);	if (res == NULL) {		pr_debug("%s %d: no base address\n", DRV_NAME, pdev->id);		ret = -ENODEV;		goto out;	}	if (!request_mem_region (res->start, res->end-res->start, pdev->name)) {		pr_debug("%s: request_mem_region failed\n", DRV_NAME);		ret =  -EBUSY;		goto out;	}	ahwif->regbase = (u32)ioremap(res->start, res->end-res->start);	if (ahwif->regbase == 0) {		ret = -ENOMEM;		goto out;	}	/* FIXME:  This might possibly break PCMCIA IDE devices */	hwif                            = &ide_hwifs[pdev->id];	hw_regs_t *hw 			= &hwif->hw;	hwif->irq = hw->irq             = ahwif->irq;	hwif->chipset                   = ide_au1xxx;	auide_setup_ports(hw, ahwif);	memcpy(hwif->io_ports, hw->io_ports, sizeof(hwif->io_ports));	hwif->ultra_mask                = 0x0;  /* Disable Ultra DMA */#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA	hwif->mwdma_mask                = 0x07; /* Multimode-2 DMA  */	hwif->swdma_mask                = 0x00;#else	hwif->mwdma_mask                = 0x0;	hwif->swdma_mask                = 0x0;#endif	hwif->noprobe = 0;	hwif->drives[0].unmask          = 1;	hwif->drives[1].unmask          = 1;	/* hold should be on in all cases */	hwif->hold                      = 1;	hwif->mmio                      = 2;	/* If the user has selected DDMA assisted copies,	   then set up a few local I/O function entry points 	*/#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA		hwif->INSW                      = auide_insw;	hwif->OUTSW                     = auide_outsw;#endif	hwif->tuneproc                  = &auide_tune_drive;	hwif->speedproc                 = &auide_tune_chipset;#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA	hwif->ide_dma_off_quietly       = &auide_dma_off_quietly;	hwif->ide_dma_timeout           = &auide_dma_timeout;	hwif->ide_dma_check             = &auide_dma_check;	hwif->dma_exec_cmd              = &auide_dma_exec_cmd;	hwif->dma_start                 = &auide_dma_start;	hwif->ide_dma_end               = &auide_dma_end;	hwif->dma_setup                 = &auide_dma_setup;	hwif->ide_dma_test_irq          = &auide_dma_test_irq;	hwif->ide_dma_host_off          = &auide_dma_host_off;	hwif->ide_dma_host_on           = &auide_dma_host_on;	hwif->ide_dma_lostirq           = &auide_dma_lostirq;	hwif->ide_dma_on                = &auide_dma_on;	hwif->autodma                   = 1;	hwif->drives[0].autodma         = hwif->autodma;	hwif->drives[1].autodma         = hwif->autodma;	hwif->atapi_dma                 = 1;#else /* !CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */	hwif->autodma                   = 0;	hwif->channel                   = 0;	hwif->hold                      = 1;	hwif->select_data               = 0;    /* no chipset-specific code */	hwif->config_data               = 0;    /* no chipset-specific code */	hwif->drives[0].autodma         = 0;	hwif->drives[0].autotune        = 1;    /* 1=autotune, 2=noautotune, 0=default */#endif	hwif->drives[0].no_io_32bit     = 1;   	auide_hwif.hwif                 = hwif;	hwif->hwif_data                 = &auide_hwif;#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA           	auide_ddma_init(&auide_hwif);	dbdma_init_done = 1;#endif	probe_hwif_init(hwif);	dev_set_drvdata(dev, hwif);	printk(KERN_INFO "Au1xxx IDE(builtin) configured for %s\n", mode ); out:	return ret;}static int au_ide_remove(struct device *dev){	struct platform_device *pdev = to_platform_device(dev);	struct resource *res;	ide_hwif_t *hwif = dev_get_drvdata(dev);	_auide_hwif *ahwif = &auide_hwif;	ide_unregister(hwif - ide_hwifs);	iounmap((void *)ahwif->regbase);	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);	release_mem_region(res->start, res->end - res->start);	return 0;}static struct device_driver au1200_ide_driver = {	.name		= "au1200-ide",	.bus		= &platform_bus_type,	.probe 		= au_ide_probe,	.remove		= au_ide_remove,};static int __init au_ide_init(void){	return driver_register(&au1200_ide_driver);}static void __exit au_ide_exit(void){	driver_unregister(&au1200_ide_driver);}MODULE_LICENSE("GPL");MODULE_DESCRIPTION("AU1200 IDE driver");module_init(au_ide_init);module_exit(au_ide_exit);

⌨️ 快捷键说明

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