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

📄 ieee1284_ops.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
						      PARPORT_CONTROL_STROBE,						      0);				break;			}		}		/* Time for Host Transfer Recovery (page 41 of IEEE1284) */		DPRINTK (KERN_DEBUG "%s: ECP transfer stalled!\n", port->name);		parport_frob_control (port, PARPORT_CONTROL_INIT,				      PARPORT_CONTROL_INIT);		udelay (50);		if (parport_read_status (port) & PARPORT_STATUS_PAPEROUT) {			/* It's buggered. */			parport_frob_control (port, PARPORT_CONTROL_INIT, 0);			break;		}		parport_frob_control (port, PARPORT_CONTROL_INIT, 0);		udelay (50);		if (!(parport_read_status (port) & PARPORT_STATUS_PAPEROUT))			break;		DPRINTK (KERN_DEBUG "%s: Host transfer recovered\n",			 port->name);		if (time_after_eq (jiffies, expire)) break;		goto try_again;	success:		parport_frob_control (port, PARPORT_CONTROL_STROBE, 0);		udelay (5);		if (parport_wait_peripheral (port,					     PARPORT_STATUS_BUSY,					     PARPORT_STATUS_BUSY))			/* Peripheral hasn't accepted the data. */			break;	}	port->ieee1284.phase = IEEE1284_PH_FWD_IDLE;	return written;#endif /* IEEE1284 support */}/* ECP mode, reverse channel, data. */size_t parport_ieee1284_ecp_read_data (struct parport *port,				       void *buffer, size_t len, int flags){#ifndef CONFIG_PARPORT_1284	return 0;#else	struct pardevice *dev = port->cad;	unsigned char *buf = buffer;	int rle_count = 0; /* shut gcc up */	int rle = 0;	ssize_t count = 0;	port = port->physport;	if (port->ieee1284.phase != IEEE1284_PH_REV_IDLE)		if (ecp_forward_to_reverse (port))			return 0;	port->ieee1284.phase = IEEE1284_PH_REV_DATA;	/* Set HostAck low to start accepting data. */	parport_frob_control (port,			      PARPORT_CONTROL_AUTOFD			      | PARPORT_CONTROL_STROBE			      | PARPORT_CONTROL_INIT,			      PARPORT_CONTROL_AUTOFD);	while (count < len) {		long expire = jiffies + dev->timeout;		unsigned char byte;		int command;		/* Event 43: Peripheral sets nAck low. It can take as                   long as it wants. */		while (parport_wait_peripheral (port, PARPORT_STATUS_ACK, 0)) {			/* The peripheral hasn't given us data in			   35ms.  If we have data to give back to the			   caller, do it now. */			if (count)				goto out;			/* If we've used up all the time we were allowed,			   give up altogether. */			if (!time_before (jiffies, expire))				goto out;			/* Yield the port for a while. */			if (count && dev->port->irq != PARPORT_IRQ_NONE) {				parport_release (dev);				__set_current_state (TASK_INTERRUPTIBLE);				schedule_timeout ((HZ + 24) / 25);				parport_claim_or_block (dev);			}			else				/* We must have the device claimed here. */				parport_wait_event (port, (HZ + 24) / 25);			/* Is there a signal pending? */			if (signal_pending (current))				goto out;		}		/* Is this a command? */		if (rle)			/* The last byte was a run-length count, so                           this can't be as well. */			command = 0;		else			command = (parport_read_status (port) &				   PARPORT_STATUS_BUSY) ? 1 : 0;		/* Read the data. */		byte = parport_read_data (port);		/* If this is a channel command, rather than an RLE                   command or a normal data byte, don't accept it. */		if (command) {			if (byte & 0x80) {				DPRINTK (KERN_DEBUG "%s: stopping short at "					 "channel command (%02x)\n",					 port->name, byte);				goto out;			}			else if (port->ieee1284.mode != IEEE1284_MODE_ECPRLE)				DPRINTK (KERN_DEBUG "%s: device illegally "					 "using RLE; accepting anyway\n",					 port->name);			rle_count = byte + 1;			/* Are we allowed to read that many bytes? */			if (rle_count > (len - count)) {				DPRINTK (KERN_DEBUG "%s: leaving %d RLE bytes "					 "for next time\n", port->name,					 rle_count);				break;			}			rle = 1;		}		/* Event 44: Set HostAck high, acknowledging handshake. */		parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);		/* Event 45: The peripheral has 35ms to set nAck high. */		if (parport_wait_peripheral (port, PARPORT_STATUS_ACK,					     PARPORT_STATUS_ACK)) {			/* It's gone wrong.  Return what data we have                           to the caller. */			DPRINTK (KERN_DEBUG "ECP read timed out at 45\n");			if (command)				printk (KERN_WARNING					"%s: command ignored (%02x)\n",					port->name, byte);			break;		}		/* Event 46: Set HostAck low and accept the data. */		parport_frob_control (port,				      PARPORT_CONTROL_AUTOFD,				      PARPORT_CONTROL_AUTOFD);		/* If we just read a run-length count, fetch the data. */		if (command)			continue;		/* If this is the byte after a run-length count, decompress. */		if (rle) {			rle = 0;			memset (buf, byte, rle_count);			buf += rle_count;			count += rle_count;			DPRINTK (KERN_DEBUG "%s: decompressed to %d bytes\n",				 port->name, rle_count);		} else {			/* Normal data byte. */			*buf = byte;			buf++, count++;		}	} out:	port->ieee1284.phase = IEEE1284_PH_REV_IDLE;	return count;#endif /* IEEE1284 support */}/* ECP mode, forward channel, commands. */size_t parport_ieee1284_ecp_write_addr (struct parport *port,					const void *buffer, size_t len,					int flags){#ifndef CONFIG_PARPORT_1284	return 0;#else	const unsigned char *buf = buffer;	size_t written;	int retry;	port = port->physport;	if (port->ieee1284.phase != IEEE1284_PH_FWD_IDLE)		if (ecp_reverse_to_forward (port))			return 0;	port->ieee1284.phase = IEEE1284_PH_FWD_DATA;	/* HostAck low (command, not data) */	parport_frob_control (port,			      PARPORT_CONTROL_AUTOFD			      | PARPORT_CONTROL_STROBE			      | PARPORT_CONTROL_INIT,			      PARPORT_CONTROL_AUTOFD			      | PARPORT_CONTROL_INIT);	for (written = 0; written < len; written++, buf++) {		long expire = jiffies + port->cad->timeout;		unsigned char byte;		byte = *buf;	try_again:		parport_write_data (port, byte);		parport_frob_control (port, PARPORT_CONTROL_STROBE,				      PARPORT_CONTROL_STROBE);		udelay (5);		for (retry = 0; retry < 100; retry++) {			if (!parport_wait_peripheral (port,						      PARPORT_STATUS_BUSY, 0))				goto success;			if (signal_pending (current)) {				parport_frob_control (port,						      PARPORT_CONTROL_STROBE,						      0);				break;			}		}		/* Time for Host Transfer Recovery (page 41 of IEEE1284) */		DPRINTK (KERN_DEBUG "%s: ECP transfer stalled!\n", port->name);		parport_frob_control (port, PARPORT_CONTROL_INIT,				      PARPORT_CONTROL_INIT);		udelay (50);		if (parport_read_status (port) & PARPORT_STATUS_PAPEROUT) {			/* It's buggered. */			parport_frob_control (port, PARPORT_CONTROL_INIT, 0);			break;		}		parport_frob_control (port, PARPORT_CONTROL_INIT, 0);		udelay (50);		if (!(parport_read_status (port) & PARPORT_STATUS_PAPEROUT))			break;		DPRINTK (KERN_DEBUG "%s: Host transfer recovered\n",			 port->name);		if (time_after_eq (jiffies, expire)) break;		goto try_again;	success:		parport_frob_control (port, PARPORT_CONTROL_STROBE, 0);		udelay (5);		if (parport_wait_peripheral (port,					     PARPORT_STATUS_BUSY,					     PARPORT_STATUS_BUSY))			/* Peripheral hasn't accepted the data. */			break;	}	port->ieee1284.phase = IEEE1284_PH_FWD_IDLE;	return written;#endif /* IEEE1284 support */}/***              * * EPP functions. * *              ***//* EPP mode, forward channel, data. */size_t parport_ieee1284_epp_write_data (struct parport *port,					const void *buffer, size_t len,					int flags){	/* This is untested */	unsigned char *bp = (unsigned char *) buffer;	size_t ret = 0;	parport_frob_control (port,			      PARPORT_CONTROL_STROBE |			      PARPORT_CONTROL_AUTOFD |			      PARPORT_CONTROL_SELECT,			      PARPORT_CONTROL_STROBE |			      PARPORT_CONTROL_SELECT);	port->ops->data_forward (port);	for (; len > 0; len--, bp++) {		/* Event 62: Write data and strobe data */		parport_write_data (port, *bp);		parport_frob_control (port, PARPORT_CONTROL_AUTOFD,				      PARPORT_CONTROL_AUTOFD);		/* Event 58 */		if (parport_poll_peripheral (port, PARPORT_STATUS_BUSY, 0, 10))			break;		/* Event 63 */		parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);		/* Event 60 */		if (parport_poll_peripheral (port, PARPORT_STATUS_BUSY,					     PARPORT_STATUS_BUSY, 5))			break;		ret++;	}	/* Event 61 */	parport_frob_control (port, PARPORT_CONTROL_STROBE, 0);	return ret;}/* EPP mode, reverse channel, data. */size_t parport_ieee1284_epp_read_data (struct parport *port,				       void *buffer, size_t len,				       int flags){	/* This is untested. */	unsigned char *bp = (unsigned char *) buffer;	unsigned ret = 0;	parport_frob_control (port,			      PARPORT_CONTROL_STROBE |			      PARPORT_CONTROL_SELECT, 0);	port->ops->data_reverse (port);	for (; len > 0; len--, bp++) {		parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);		/* Event 58 */		if (parport_poll_peripheral (port, PARPORT_STATUS_BUSY,					     PARPORT_STATUS_BUSY, 10))			break;		*bp = parport_read_data (port);		parport_frob_control (port, PARPORT_CONTROL_AUTOFD,				      PARPORT_CONTROL_AUTOFD);		if (parport_poll_peripheral (port, PARPORT_STATUS_BUSY, 0, 5))			break;		ret++;	}	port->ops->data_forward (port);	return ret;}/* EPP mode, forward channel, addresses. */size_t parport_ieee1284_epp_write_addr (struct parport *port,					const void *buffer, size_t len,					int flags){	/* This is untested */	unsigned char *bp = (unsigned char *) buffer;	size_t ret = 0;	parport_frob_control (port,			      PARPORT_CONTROL_STROBE |			      PARPORT_CONTROL_SELECT |			      PARPORT_CONTROL_AUTOFD,			      PARPORT_CONTROL_STROBE |			      PARPORT_CONTROL_SELECT);	port->ops->data_forward (port);	for (; len > 0; len--, bp++) {		/* Write data and assert nAStrb. */		parport_write_data (port, *bp);		parport_frob_control (port, PARPORT_CONTROL_SELECT,				      PARPORT_CONTROL_SELECT);		if (parport_poll_peripheral (port, PARPORT_STATUS_BUSY,					     PARPORT_STATUS_BUSY, 10))			break;		parport_frob_control (port, PARPORT_CONTROL_SELECT, 0);		if (parport_poll_peripheral (port, PARPORT_STATUS_BUSY, 0, 5))			break;		ret++;	}	parport_frob_control (port, PARPORT_CONTROL_STROBE, 0);	return ret;}/* EPP mode, reverse channel, addresses. */size_t parport_ieee1284_epp_read_addr (struct parport *port,				       void *buffer, size_t len,				       int flags){	/* This is untested. */	unsigned char *bp = (unsigned char *) buffer;	unsigned ret = 0;	parport_frob_control (port,			      PARPORT_CONTROL_STROBE |			      PARPORT_CONTROL_AUTOFD, 0);	port->ops->data_reverse (port);	for (; len > 0; len--, bp++) {		parport_frob_control (port, PARPORT_CONTROL_SELECT, 0);		/* Event 58 */		if (parport_poll_peripheral (port, PARPORT_STATUS_BUSY,					     PARPORT_STATUS_BUSY, 10))			break;		*bp = parport_read_data (port);		parport_frob_control (port, PARPORT_CONTROL_SELECT,				      PARPORT_CONTROL_SELECT);		if (parport_poll_peripheral (port, PARPORT_STATUS_BUSY, 0, 5))			break;		ret++;	}	port->ops->data_forward (port);	return ret;}

⌨️ 快捷键说明

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