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

📄 parport_pc.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
			clear_epp_timeout (port);			break;		}	}	return got;}static size_t parport_pc_epp_write_addr (struct parport *port,					 const void *buf, size_t length,					 int flags){	size_t written = 0;	if ((flags & PARPORT_EPP_FAST) && (length > 1)) {		outsb (EPPADDR (port), buf, length);		if (inb (STATUS (port)) & 0x01) {			clear_epp_timeout (port);			return -EIO;		}		return length;	}	for (; written < length; written++) {		outb (*((char*)buf)++, EPPADDR (port));		if (inb (STATUS (port)) & 0x01) {			clear_epp_timeout (port);			break;		}	}	return written;}static size_t parport_pc_ecpepp_read_data (struct parport *port, void *buf,					   size_t length, int flags){	size_t got;	frob_set_mode (port, ECR_EPP);	parport_pc_data_reverse (port);	parport_pc_write_control (port, 0x4);	got = parport_pc_epp_read_data (port, buf, length, flags);	frob_set_mode (port, ECR_PS2);	return got;}static size_t parport_pc_ecpepp_write_data (struct parport *port,					    const void *buf, size_t length,					    int flags){	size_t written;	frob_set_mode (port, ECR_EPP);	parport_pc_write_control (port, 0x4);	parport_pc_data_forward (port);	written = parport_pc_epp_write_data (port, buf, length, flags);	frob_set_mode (port, ECR_PS2);	return written;}static size_t parport_pc_ecpepp_read_addr (struct parport *port, void *buf,					   size_t length, int flags){	size_t got;	frob_set_mode (port, ECR_EPP);	parport_pc_data_reverse (port);	parport_pc_write_control (port, 0x4);	got = parport_pc_epp_read_addr (port, buf, length, flags);	frob_set_mode (port, ECR_PS2);	return got;}static size_t parport_pc_ecpepp_write_addr (struct parport *port,					    const void *buf, size_t length,					    int flags){	size_t written;	frob_set_mode (port, ECR_EPP);	parport_pc_write_control (port, 0x4);	parport_pc_data_forward (port);	written = parport_pc_epp_write_addr (port, buf, length, flags);	frob_set_mode (port, ECR_PS2);	return written;}#endif /* IEEE 1284 support */#ifdef CONFIG_PARPORT_PC_FIFOstatic size_t parport_pc_fifo_write_block_pio (struct parport *port,					       const void *buf, size_t length){	int ret = 0;	const unsigned char *bufp = buf;	size_t left = length;	long expire = jiffies + port->physport->cad->timeout;	const int fifo = FIFO (port);	int poll_for = 8; /* 80 usecs */	const struct parport_pc_private *priv = port->physport->private_data;	const int fifo_depth = priv->fifo_depth;	port = port->physport;	/* We don't want to be interrupted every character. */	parport_pc_disable_irq (port);	/* set nErrIntrEn and serviceIntr */	frob_econtrol (port, (1<<4) | (1<<2), (1<<4) | (1<<2));	/* Forward mode. */	parport_pc_data_forward (port); /* Must be in PS2 mode */	while (left) {		unsigned char byte;		unsigned char ecrval = inb (ECONTROL (port));		int i = 0;		if (current->need_resched && time_before (jiffies, expire))			/* Can't yield the port. */			schedule ();		/* Anyone else waiting for the port? */		if (port->waithead) {			printk (KERN_DEBUG "Somebody wants the port\n");			break;		}		if (ecrval & 0x02) {			/* FIFO is full. Wait for interrupt. */			/* Clear serviceIntr */			ECR_WRITE (port, ecrval & ~(1<<2));		false_alarm:			ret = parport_wait_event (port, HZ);			if (ret < 0) break;			ret = 0;			if (!time_before (jiffies, expire)) {				/* Timed out. */				printk (KERN_DEBUG "FIFO write timed out\n");				break;			}			ecrval = inb (ECONTROL (port));			if (!(ecrval & (1<<2))) {				if (current->need_resched &&				    time_before (jiffies, expire))					schedule ();				goto false_alarm;			}			continue;		}		/* Can't fail now. */		expire = jiffies + port->cad->timeout;	poll:		if (signal_pending (current))			break;		if (ecrval & 0x01) {			/* FIFO is empty. Blast it full. */			const int n = left < fifo_depth ? left : fifo_depth;			outsb (fifo, bufp, n);			bufp += n;			left -= n;			/* Adjust the poll time. */			if (i < (poll_for - 2)) poll_for--;			continue;		} else if (i++ < poll_for) {			udelay (10);			ecrval = inb (ECONTROL (port));			goto poll;		}		/* Half-full (call me an optimist) */		byte = *bufp++;		outb (byte, fifo);		left--;        }dump_parport_state ("leave fifo_write_block_pio", port);	return length - left;}static size_t parport_pc_fifo_write_block_dma (struct parport *port,					       const void *buf, size_t length){	int ret = 0;	unsigned long dmaflag;	size_t left = length;	const struct parport_pc_private *priv = port->physport->private_data;	dma_addr_t dma_addr, dma_handle;	size_t maxlen = 0x10000; /* max 64k per DMA transfer */	unsigned long start = (unsigned long) buf;	unsigned long end = (unsigned long) buf + length - 1;dump_parport_state ("enter fifo_write_block_dma", port);	if (end < MAX_DMA_ADDRESS) {		/* If it would cross a 64k boundary, cap it at the end. */		if ((start ^ end) & ~0xffffUL)			maxlen = 0x10000 - (start & 0xffff);		dma_addr = dma_handle = pci_map_single(priv->dev, (void *)buf, length,						       PCI_DMA_TODEVICE);        } else {		/* above 16 MB we use a bounce buffer as ISA-DMA is not possible */		maxlen   = PAGE_SIZE;          /* sizeof(priv->dma_buf) */		dma_addr = priv->dma_handle;		dma_handle = 0;	}	port = port->physport;	/* We don't want to be interrupted every character. */	parport_pc_disable_irq (port);	/* set nErrIntrEn and serviceIntr */	frob_econtrol (port, (1<<4) | (1<<2), (1<<4) | (1<<2));	/* Forward mode. */	parport_pc_data_forward (port); /* Must be in PS2 mode */	while (left) {		long expire = jiffies + port->physport->cad->timeout;		size_t count = left;		if (count > maxlen)			count = maxlen;		if (!dma_handle)   /* bounce buffer ! */			memcpy(priv->dma_buf, buf, count);		dmaflag = claim_dma_lock();		disable_dma(port->dma);		clear_dma_ff(port->dma);		set_dma_mode(port->dma, DMA_MODE_WRITE);		set_dma_addr(port->dma, dma_addr);		set_dma_count(port->dma, count);		/* Set DMA mode */		frob_econtrol (port, 1<<3, 1<<3);		/* Clear serviceIntr */		frob_econtrol (port, 1<<2, 0);		enable_dma(port->dma);		release_dma_lock(dmaflag);		/* assume DMA will be successful */		left -= count;		buf  += count;		if (dma_handle) dma_addr += count;		/* Wait for interrupt. */	false_alarm:		ret = parport_wait_event (port, HZ);		if (ret < 0) break;		ret = 0;		if (!time_before (jiffies, expire)) {			/* Timed out. */			printk (KERN_DEBUG "DMA write timed out\n");			break;		}		/* Is serviceIntr set? */		if (!(inb (ECONTROL (port)) & (1<<2))) {			if (current->need_resched)				schedule ();			goto false_alarm;		}		dmaflag = claim_dma_lock();		disable_dma(port->dma);		clear_dma_ff(port->dma);		count = get_dma_residue(port->dma);		release_dma_lock(dmaflag);		if (current->need_resched)			/* Can't yield the port. */			schedule ();		/* Anyone else waiting for the port? */		if (port->waithead) {			printk (KERN_DEBUG "Somebody wants the port\n");			break;		}		/* update for possible DMA residue ! */		buf  -= count;		left += count;		if (dma_handle) dma_addr -= count;	}	/* Maybe got here through break, so adjust for DMA residue! */	dmaflag = claim_dma_lock();	disable_dma(port->dma);	clear_dma_ff(port->dma);	left += get_dma_residue(port->dma);	release_dma_lock(dmaflag);	/* Turn off DMA mode */	frob_econtrol (port, 1<<3, 0);		if (dma_handle)		pci_unmap_single(priv->dev, dma_handle, length, PCI_DMA_TODEVICE);dump_parport_state ("leave fifo_write_block_dma", port);	return length - left;}/* Parallel Port FIFO mode (ECP chipsets) */size_t parport_pc_compat_write_block_pio (struct parport *port,					  const void *buf, size_t length,					  int flags){	size_t written;	int r;	long int expire;	const struct parport_pc_private *priv = port->physport->private_data;	/* Special case: a timeout of zero means we cannot call schedule(). */	if (!port->physport->cad->timeout)		return parport_ieee1284_write_compat (port, buf,						      length, flags);	/* Set up parallel port FIFO mode.*/	parport_pc_data_forward (port); /* Must be in PS2 mode */	parport_pc_frob_control (port, PARPORT_CONTROL_STROBE, 0);	r = change_mode (port, ECR_PPF); /* Parallel port FIFO */	if (r)  printk (KERN_DEBUG "%s: Warning change_mode ECR_PPF failed\n", port->name);	port->physport->ieee1284.phase = IEEE1284_PH_FWD_DATA;	/* Write the data to the FIFO. */	if (port->dma != PARPORT_DMA_NONE)		written = parport_pc_fifo_write_block_dma (port, buf, length);	else		written = parport_pc_fifo_write_block_pio (port, buf, length);	/* Finish up. */	/* For some hardware we don't want to touch the mode until	 * the FIFO is empty, so allow 4 seconds for each position	 * in the fifo.	 */        expire = jiffies + (priv->fifo_depth * HZ * 4);	do {		/* Wait for the FIFO to empty */		r = change_mode (port, ECR_PS2);		if (r != -EBUSY) {			break;		}	} while (time_before (jiffies, expire));	if (r == -EBUSY) {		printk (KERN_DEBUG "%s: FIFO is stuck\n", port->name);		/* Prevent further data transfer. */		frob_set_mode (port, ECR_TST);		/* Adjust for the contents of the FIFO. */		for (written -= priv->fifo_depth; ; written++) {			if (inb (ECONTROL (port)) & 0x2) {				/* Full up. */				break;			}			outb (0, FIFO (port));		}		/* Reset the FIFO and return to PS2 mode. */		frob_set_mode (port, ECR_PS2);	}	r = parport_wait_peripheral (port,				     PARPORT_STATUS_BUSY,				     PARPORT_STATUS_BUSY);	if (r)		printk (KERN_DEBUG			"%s: BUSY timeout (%d) in compat_write_block_pio\n", 			port->name, r);	port->physport->ieee1284.phase = IEEE1284_PH_FWD_IDLE;	return written;}/* ECP */#ifdef CONFIG_PARPORT_1284size_t parport_pc_ecp_write_block_pio (struct parport *port,				       const void *buf, size_t length,				       int flags){	size_t written;	int r;	long int expire;	const struct parport_pc_private *priv = port->physport->private_data;	/* Special case: a timeout of zero means we cannot call schedule(). */	if (!port->physport->cad->timeout)		return parport_ieee1284_ecp_write_data (port, buf,							length, flags);	/* Switch to forward mode if necessary. */	if (port->physport->ieee1284.phase != IEEE1284_PH_FWD_IDLE) {		/* Event 47: Set nInit high. */		parport_frob_control (port,				      PARPORT_CONTROL_INIT				      | PARPORT_CONTROL_AUTOFD,				      PARPORT_CONTROL_INIT				      | PARPORT_CONTROL_AUTOFD);		/* Event 49: PError goes high. */		r = parport_wait_peripheral (port,					     PARPORT_STATUS_PAPEROUT,					     PARPORT_STATUS_PAPEROUT);		if (r) {			printk (KERN_DEBUG "%s: PError timeout (%d) "				"in ecp_write_block_pio\n", port->name, r);		}	}	/* Set up ECP parallel port mode.*/	parport_pc_data_forward (port); /* Must be in PS2 mode */	parport_pc_frob_control (port,				 PARPORT_CONTROL_STROBE |				 PARPORT_CONTROL_AUTOFD,				 0);	r = change_mode (port, ECR_ECP); /* ECP FIFO */	if (r) printk (KERN_DEBUG "%s: Warning change_mode ECR_ECP failed\n", port->name);	port->physport->ieee1284.phase = IEEE1284_PH_FWD_DATA;	/* Write the data to the FIFO. */	if (port->dma != PARPORT_DMA_NONE)		written = parport_pc_fifo_write_block_dma (port, buf, length);	else		written = parport_pc_fifo_write_block_pio (port, buf, length);	/* Finish up. */	/* For some hardware we don't want to touch the mode until	 * the FIFO is empty, so allow 4 seconds for each position	 * in the fifo.	 */	expire = jiffies + (priv->fifo_depth * (HZ * 4));	do {		/* Wait for the FIFO to empty */		r = change_mode (port, ECR_PS2);		if (r != -EBUSY) {			break;		}	} while (time_before (jiffies, expire));	if (r == -EBUSY) {		printk (KERN_DEBUG "%s: FIFO is stuck\n", port->name);		/* Prevent further data transfer. */		frob_set_mode (port, ECR_TST);		/* Adjust for the contents of the FIFO. */		for (written -= priv->fifo_depth; ; written++) {			if (inb (ECONTROL (port)) & 0x2) {				/* Full up. */				break;			}			outb (0, FIFO (port));		}		/* Reset the FIFO and return to PS2 mode. */		frob_set_mode (port, ECR_PS2);		/* Host transfer recovery. */		parport_pc_data_reverse (port); /* Must be in PS2 mode */		udelay (5);		parport_frob_control (port, PARPORT_CONTROL_INIT, 0);		r = parport_wait_peripheral (port, PARPORT_STATUS_PAPEROUT, 0);		if (r)			printk (KERN_DEBUG "%s: PE,1 timeout (%d) "				"in ecp_write_block_pio\n", port->name, r);		parport_frob_control (port,				      PARPORT_CONTROL_INIT,				      PARPORT_CONTROL_INIT);		r = parport_wait_peripheral (port,					     PARPORT_STATUS_PAPEROUT,					     PARPORT_STATUS_PAPEROUT);                if (r)                        printk (KERN_DEBUG "%s: PE,2 timeout (%d) "				"in ecp_write_block_pio\n", port->name, r);	}	r = parport_wait_peripheral (port,				     PARPORT_STATUS_BUSY, 				     PARPORT_STATUS_BUSY);	if(r)		printk (KERN_DEBUG

⌨️ 快捷键说明

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