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

📄 floppy.h

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 H
📖 第 1 页 / 共 2 页
字号:
	}	dcsr |= EBUS_DCSR_EN_CNT | EBUS_DCSR_TC;	/*	 * For EBus WRITE means to system memory, which is	 * READ for us.	 */	if (mode == DMA_MODE_WRITE) {		dcsr &= ~(EBUS_DCSR_WRITE);		sun_pci_dma_direction = PCI_DMA_TODEVICE;	} else {		dcsr |= EBUS_DCSR_WRITE;		sun_pci_dma_direction = PCI_DMA_FROMDEVICE;	}	writel(dcsr, &sun_pci_fd_ebus_dma->dcsr);}static void sun_pci_fd_set_dma_count(int length){	sun_pci_dma_len = length;	writel(length, &sun_pci_fd_ebus_dma->dbcr);}static void sun_pci_fd_set_dma_addr(char *buffer){	unsigned int addr;	addr = sun_pci_dma_addr = pci_map_single(sun_pci_ebus_dev,						 buffer,						 sun_pci_dma_len,						 sun_pci_dma_direction);	writel(addr, &sun_pci_fd_ebus_dma->dacr);}static unsigned int sun_pci_get_dma_residue(void){	unsigned int dcsr, res;	res = readl(&sun_pci_fd_ebus_dma->dbcr);	if (res != 0) {		dcsr = readl(&sun_pci_fd_ebus_dma->dcsr);		sun_pci_fd_reset_dma();		writel(dcsr, &sun_pci_fd_ebus_dma->dcsr);	}	return res;}static void sun_pci_fd_enable_irq(void){	unsigned int dcsr;	dcsr = readl(&sun_pci_fd_ebus_dma->dcsr);	dcsr |= EBUS_DCSR_INT_EN;	writel(dcsr, &sun_pci_fd_ebus_dma->dcsr);}static void sun_pci_fd_disable_irq(void){	unsigned int dcsr;	dcsr = readl(&sun_pci_fd_ebus_dma->dcsr);	dcsr &= ~(EBUS_DCSR_INT_EN);	writel(dcsr, &sun_pci_fd_ebus_dma->dcsr);}static int sun_pci_fd_request_irq(void){	int err;	err = request_irq(FLOPPY_IRQ, floppy_interrupt, SA_SHIRQ,			  "floppy", sun_fdc);	if (err)		return -1;	sun_pci_fd_enable_irq();	return 0;}static void sun_pci_fd_free_irq(void){	sun_pci_fd_disable_irq();	free_irq(FLOPPY_IRQ, sun_fdc);}static int sun_pci_fd_eject(int drive){	return -EINVAL;}/* * Floppy probing, we'd like to use /dev/fd0 for a single Floppy on PCI, * even if this is configured using DS1, thus looks like /dev/fd1 with * the cabling used in Ultras. */#define DOR	(port + 2)#define MSR	(port + 4)#define FIFO	(port + 5)static void sun_pci_fd_out_byte(unsigned long port, unsigned char val,			        unsigned long reg){	unsigned char status;	int timeout = 1000;	while (!((status = inb(MSR)) & 0x80) && --timeout)		udelay(100);	outb(val, reg);}static unsigned char sun_pci_fd_sensei(unsigned long port){	unsigned char result[2] = { 0x70, 0x00 };	unsigned char status;	int i = 0;	sun_pci_fd_out_byte(port, 0x08, FIFO);	do {		int timeout = 1000;		while (!((status = inb(MSR)) & 0x80) && --timeout)			udelay(100);		if (!timeout)			break;		if ((status & 0xf0) == 0xd0)			result[i++] = inb(FIFO);		else			break;	} while (i < 2);	return result[0];}static void sun_pci_fd_reset(unsigned long port){	unsigned char mask = 0x00;	unsigned char status;	int timeout = 10000;	outb(0x80, MSR);	do {		status = sun_pci_fd_sensei(port);		if ((status & 0xc0) == 0xc0)			mask |= 1 << (status & 0x03);		else			udelay(100);	} while ((mask != 0x0f) && --timeout);}static int sun_pci_fd_test_drive(unsigned long port, int drive){	unsigned char status, data;	int timeout = 1000;	int ready;	sun_pci_fd_reset(port);	data = (0x10 << drive) | 0x0c | drive;	sun_pci_fd_out_byte(port, data, DOR);	sun_pci_fd_out_byte(port, 0x07, FIFO);	sun_pci_fd_out_byte(port, drive & 0x03, FIFO);	do {		udelay(100);		status = sun_pci_fd_sensei(port);	} while (((status & 0xc0) == 0x80) && --timeout);	if (!timeout)		ready = 0;	else		ready = (status & 0x10) ? 0 : 1;	sun_pci_fd_reset(port);	return ready;}#undef FIFO#undef MSR#undef DOR#endif /* CONFIG_PCI */static unsigned long __init sun_floppy_init(void){	char state[128];	struct sbus_bus *bus;	struct sbus_dev *sdev = NULL;	static int initialized = 0;	if (initialized)		return sun_floppy_types[0];	initialized = 1;	for_all_sbusdev (sdev, bus) {		if (!strcmp(sdev->prom_name, "SUNW,fdtwo")) 			break;	}	if(sdev) {		floppy_sdev = sdev;		FLOPPY_IRQ = sdev->irqs[0];	} else {#ifdef CONFIG_PCI		struct linux_ebus *ebus;		struct linux_ebus_device *edev = 0;		unsigned long config = 0;		unsigned long auxio_reg;		for_each_ebus(ebus) {			for_each_ebusdev(edev, ebus) {				if (!strcmp(edev->prom_name, "fdthree"))					goto ebus_done;			}		}	ebus_done:		if (!edev)			return 0;		prom_getproperty(edev->prom_node, "status",				 state, sizeof(state));		if(!strncmp(state, "disabled", 8))			return 0;					sun_fdc = (struct sun_flpy_controller *)edev->resource[0].start;		FLOPPY_IRQ = edev->irqs[0];		/* Make sure the high density bit is set, some systems		 * (most notably Ultra5/Ultra10) come up with it clear.		 */		auxio_reg = edev->resource[2].start;		writel(readl(auxio_reg)|0x2, auxio_reg);		sun_pci_ebus_dev = ebus->self;		sun_pci_fd_ebus_dma = (struct linux_ebus_dma *)			edev->resource[1].start;		sun_pci_fd_reset_dma();		sun_fdops.fd_inb = sun_pci_fd_inb;		sun_fdops.fd_outb = sun_pci_fd_outb;		use_virtual_dma = 0;		sun_fdops.fd_enable_dma = sun_pci_fd_enable_dma;		sun_fdops.fd_disable_dma = sun_pci_fd_disable_dma;		sun_fdops.fd_set_dma_mode = sun_pci_fd_set_dma_mode;		sun_fdops.fd_set_dma_addr = sun_pci_fd_set_dma_addr;		sun_fdops.fd_set_dma_count = sun_pci_fd_set_dma_count;		sun_fdops.get_dma_residue = sun_pci_get_dma_residue;		sun_fdops.fd_enable_irq = sun_pci_fd_enable_irq;		sun_fdops.fd_disable_irq = sun_pci_fd_disable_irq;		sun_fdops.fd_request_irq = sun_pci_fd_request_irq;		sun_fdops.fd_free_irq = sun_pci_fd_free_irq;		sun_fdops.fd_eject = sun_pci_fd_eject;        	fdc_status = (unsigned long) &sun_fdc->status_82077;		FLOPPY_MOTOR_MASK = 0xf0;		/*		 * XXX: Find out on which machines this is really needed.		 */		if (1) {			sun_pci_broken_drive = 1;			sun_fdops.fd_outb = sun_pci_fd_broken_outb;		}		allowed_drive_mask = 0;		if (sun_pci_fd_test_drive((unsigned long)sun_fdc, 0))			sun_floppy_types[0] = 4;		if (sun_pci_fd_test_drive((unsigned long)sun_fdc, 1))			sun_floppy_types[1] = 4;		/*		 * Find NS87303 SuperIO config registers (through ecpp).		 */		for_each_ebus(ebus) {			for_each_ebusdev(edev, ebus) {				if (!strcmp(edev->prom_name, "ecpp")) {					config = edev->resource[1].start;					goto config_done;				}			}		}	config_done:		/*		 * Sanity check, is this really the NS87303?		 */		switch (config & 0x3ff) {		case 0x02e:		case 0x15c:		case 0x26e:		case 0x398:			break;		default:			config = 0;		}		if (!config)			return sun_floppy_types[0];		/* Enable PC-AT mode. */		ns87303_modify(config, ASC, 0, 0xc0);#ifdef PCI_FDC_SWAP_DRIVES		/*		 * If only Floppy 1 is present, swap drives.		 */		if (!sun_floppy_types[0] && sun_floppy_types[1]) {			/*			 * Set the drive exchange bit in FCR on NS87303,			 * make shure other bits are sane before doing so.			 */			ns87303_modify(config, FER, FER_EDM, 0);			ns87303_modify(config, ASC, ASC_DRV2_SEL, 0);			ns87303_modify(config, FCR, 0, FCR_LDE);			cfg = sun_floppy_types[0];			sun_floppy_types[0] = sun_floppy_types[1];			sun_floppy_types[1] = cfg;			if (sun_pci_broken_drive != -1) {				sun_pci_broken_drive = 1 - sun_pci_broken_drive;				sun_fdops.fd_outb = sun_pci_fd_lde_broken_outb;			}		}#endif /* PCI_FDC_SWAP_DRIVES */		return sun_floppy_types[0];#else		return 0;#endif	}	prom_getproperty(sdev->prom_node, "status", state, sizeof(state));	if(!strncmp(state, "disabled", 8))		return 0;	/*	 * We cannot do sbus_ioremap here: it does request_region,	 * which the generic floppy driver tries to do once again.	 * But we must use the sdev resource values as they have	 * had parent ranges applied.	 */	sun_fdc = (struct sun_flpy_controller *)		(sdev->resource[0].start +		 ((sdev->resource[0].flags & 0x1ffUL) << 32UL));	/* Last minute sanity check... */	if(sbus_readb(&sun_fdc->status1_82077) == 0xff) {		sun_fdc = (struct sun_flpy_controller *)-1;		return 0;	}        sun_fdops.fd_inb = sun_82077_fd_inb;        sun_fdops.fd_outb = sun_82077_fd_outb;	can_use_virtual_dma = use_virtual_dma = 1;	sun_fdops.fd_enable_dma = sun_fd_enable_dma;	sun_fdops.fd_disable_dma = sun_fd_disable_dma;	sun_fdops.fd_set_dma_mode = sun_fd_set_dma_mode;	sun_fdops.fd_set_dma_addr = sun_fd_set_dma_addr;	sun_fdops.fd_set_dma_count = sun_fd_set_dma_count;	sun_fdops.get_dma_residue = sun_get_dma_residue;	sun_fdops.fd_enable_irq = sun_fd_enable_irq;	sun_fdops.fd_disable_irq = sun_fd_disable_irq;	sun_fdops.fd_request_irq = sun_fd_request_irq;	sun_fdops.fd_free_irq = sun_fd_free_irq;	sun_fdops.fd_eject = sun_fd_eject;        fdc_status = (unsigned long) &sun_fdc->status_82077;	/* Success... */	allowed_drive_mask = 0x01;	sun_floppy_types[0] = 4;	sun_floppy_types[1] = 0;	return sun_floppy_types[0];}#endif /* !(__ASM_SPARC64_FLOPPY_H) */

⌨️ 快捷键说明

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