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

📄 lp.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 2 页
字号:
	lp_table[minor].lp_buffer = (char *) kmalloc(LP_BUFFER_SIZE, GFP_KERNEL);	if (!lp_table[minor].lp_buffer) {		LP_F(minor) &= ~LP_BUSY;		return -ENOMEM;	}	/* Determine if the peripheral supports ECP mode */	lp_claim_parport_or_block (&lp_table[minor]);	if ( (lp_table[minor].dev->port->modes & PARPORT_MODE_ECP) &&             !parport_negotiate (lp_table[minor].dev->port,                                  IEEE1284_MODE_ECP)) {		printk (KERN_INFO "lp%d: ECP mode\n", minor);		lp_table[minor].best_mode = IEEE1284_MODE_ECP;	} else {		printk (KERN_INFO "lp%d: compatibility mode\n", minor);		lp_table[minor].best_mode = IEEE1284_MODE_COMPAT;	}	/* Leave peripheral in compatibility mode */	parport_negotiate (lp_table[minor].dev->port, IEEE1284_MODE_COMPAT);	lp_release_parport (&lp_table[minor]);	lp_table[minor].current_mode = IEEE1284_MODE_COMPAT;	return 0;}static int lp_release(struct inode * inode, struct file * file){	unsigned int minor = MINOR(inode->i_rdev);	lp_claim_parport_or_block (&lp_table[minor]);	parport_negotiate (lp_table[minor].dev->port, IEEE1284_MODE_COMPAT);	lp_table[minor].current_mode = IEEE1284_MODE_COMPAT;	lp_release_parport (&lp_table[minor]);	lock_kernel();	kfree(lp_table[minor].lp_buffer);	lp_table[minor].lp_buffer = NULL;	LP_F(minor) &= ~LP_BUSY;	unlock_kernel();	return 0;}static int lp_ioctl(struct inode *inode, struct file *file,		    unsigned int cmd, unsigned long arg){	unsigned int minor = MINOR(inode->i_rdev);	int status;	int retval = 0;#ifdef LP_DEBUG	printk(KERN_DEBUG "lp%d ioctl, cmd: 0x%x, arg: 0x%lx\n", minor, cmd, arg);#endif	if (minor >= LP_NO)		return -ENODEV;	if ((LP_F(minor) & LP_EXIST) == 0)		return -ENODEV;	switch ( cmd ) {		struct timeval par_timeout;		long to_jiffies;		case LPTIME:			LP_TIME(minor) = arg * HZ/100;			break;		case LPCHAR:			LP_CHAR(minor) = arg;			break;		case LPABORT:			if (arg)				LP_F(minor) |= LP_ABORT;			else				LP_F(minor) &= ~LP_ABORT;			break;		case LPABORTOPEN:			if (arg)				LP_F(minor) |= LP_ABORTOPEN;			else				LP_F(minor) &= ~LP_ABORTOPEN;			break;		case LPCAREFUL:			if (arg)				LP_F(minor) |= LP_CAREFUL;			else				LP_F(minor) &= ~LP_CAREFUL;			break;		case LPWAIT:			LP_WAIT(minor) = arg;			break;		case LPSETIRQ: 			return -EINVAL;			break;		case LPGETIRQ:			if (copy_to_user((int *) arg, &LP_IRQ(minor),					sizeof(int)))				return -EFAULT;			break;		case LPGETSTATUS:			lp_claim_parport_or_block (&lp_table[minor]);			status = r_str(minor);			lp_release_parport (&lp_table[minor]);			if (copy_to_user((int *) arg, &status, sizeof(int)))				return -EFAULT;			break;		case LPRESET:			lp_reset(minor);			break;#ifdef LP_STATS		case LPGETSTATS:			if (copy_to_user((int *) arg, &LP_STAT(minor),					sizeof(struct lp_stats)))				return -EFAULT;			if (capable(CAP_SYS_ADMIN))				memset(&LP_STAT(minor), 0,						sizeof(struct lp_stats));			break;#endif 		case LPGETFLAGS: 			status = LP_F(minor);			if (copy_to_user((int *) arg, &status, sizeof(int)))				return -EFAULT;			break;		case LPSETTIMEOUT:			if (copy_from_user (&par_timeout,					    (struct timeval *) arg,					    sizeof (struct timeval))) {				return -EFAULT;			}			/* Convert to jiffies, place in lp_table */			if ((par_timeout.tv_sec < 0) ||			    (par_timeout.tv_usec < 0)) {				return -EINVAL;			}			to_jiffies = ROUND_UP(par_timeout.tv_usec, 1000000/HZ);			to_jiffies += par_timeout.tv_sec * (long) HZ;			if (to_jiffies <= 0) {				return -EINVAL;			}			lp_table[minor].timeout = to_jiffies;			break;		default:			retval = -EINVAL;	}	return retval;}static struct file_operations lp_fops = {	owner:		THIS_MODULE,	write:		lp_write,	ioctl:		lp_ioctl,	open:		lp_open,	release:	lp_release,#ifdef CONFIG_PARPORT_1284	read:		lp_read,#endif};/* --- support for console on the line printer ----------------- */#ifdef CONFIG_LP_CONSOLE#define CONSOLE_LP 0/* If the printer is out of paper, we can either lose the messages or * stall until the printer is happy again.  Define CONSOLE_LP_STRICT * non-zero to get the latter behaviour. */#define CONSOLE_LP_STRICT 1/* The console must be locked when we get here. */static void lp_console_write (struct console *co, const char *s,			      unsigned count){	struct pardevice *dev = lp_table[CONSOLE_LP].dev;	struct parport *port = dev->port;	ssize_t written;	if (parport_claim (dev))		/* Nothing we can do. */		return;	parport_set_timeout (dev, 0);	/* Go to compatibility mode. */	parport_negotiate (port, IEEE1284_MODE_COMPAT);	do {		/* Write the data, converting LF->CRLF as we go. */		ssize_t canwrite = count;		char *lf = memchr (s, '\n', count);		if (lf)			canwrite = lf - s;		if (canwrite > 0) {			written = parport_write (port, s, canwrite);			if (written <= 0)				continue;			s += written;			count -= written;			canwrite -= written;		}		if (lf && canwrite <= 0) {			const char *crlf = "\r\n";			int i = 2;			/* Dodge the original '\n', and put '\r\n' instead. */			s++;			count--;			do {				written = parport_write (port, crlf, i);				if (written > 0)					i -= written, crlf += written;			} while (i > 0 && (CONSOLE_LP_STRICT || written > 0));		}	} while (count > 0 && (CONSOLE_LP_STRICT || written > 0));	parport_release (dev);}static kdev_t lp_console_device (struct console *c){	return MKDEV(LP_MAJOR, CONSOLE_LP);}static struct console lpcons = {	name:		"lp",	write:		lp_console_write,	device:		lp_console_device,	flags:		CON_PRINTBUFFER,};#endif /* console on line printer *//* --- initialisation code ------------------------------------- */static int parport_nr[LP_NO] = { [0 ... LP_NO-1] = LP_PARPORT_UNSPEC };static char *parport[LP_NO] = { NULL,  };static int reset = 0;MODULE_PARM(parport, "1-" __MODULE_STRING(LP_NO) "s");MODULE_PARM(reset, "i");#ifndef MODULEstatic int __init lp_setup (char *str){	static int parport_ptr; // initially zero	int x;	if (get_option (&str, &x)) {		if (x == 0) {			/* disable driver on "lp=" or "lp=0" */			parport_nr[0] = LP_PARPORT_OFF;		} else {			printk(KERN_WARNING "warning: 'lp=0x%x' is deprecated, ignored\n", x);			return 0;		}	} else if (!strncmp(str, "parport", 7)) {		int n = simple_strtoul(str+7, NULL, 10);		if (parport_ptr < LP_NO)			parport_nr[parport_ptr++] = n;		else			printk(KERN_INFO "lp: too many ports, %s ignored.\n",			       str);	} else if (!strcmp(str, "auto")) {		parport_nr[0] = LP_PARPORT_AUTO;	} else if (!strcmp(str, "none")) {		parport_nr[parport_ptr++] = LP_PARPORT_NONE;	} else if (!strcmp(str, "reset")) {		reset = 1;	}	return 1;}#endifstatic int lp_register(int nr, struct parport *port){	char name[8];	lp_table[nr].dev = parport_register_device(port, "lp", 						   lp_preempt, NULL, NULL, 0,						   (void *) &lp_table[nr]);	if (lp_table[nr].dev == NULL)		return 1;	lp_table[nr].flags |= LP_EXIST;	if (reset)		lp_reset(nr);	sprintf (name, "%d", nr);	devfs_register (devfs_handle, name,			DEVFS_FL_DEFAULT, LP_MAJOR, nr,			S_IFCHR | S_IRUGO | S_IWUGO,			&lp_fops, NULL);	printk(KERN_INFO "lp%d: using %s (%s).\n", nr, port->name, 	       (port->irq == PARPORT_IRQ_NONE)?"polling":"interrupt-driven");#ifdef CONFIG_LP_CONSOLE	if (!nr) {		if (port->modes & PARPORT_MODE_SAFEININT) {			register_console (&lpcons);			console_registered = port;			printk (KERN_INFO "lp%d: console ready\n", CONSOLE_LP);		} else			printk (KERN_ERR "lp%d: cannot run console on %s\n",				CONSOLE_LP, port->name);	}#endif	return 0;}static void lp_attach (struct parport *port){	unsigned int i;	switch (parport_nr[0])	{	case LP_PARPORT_UNSPEC:	case LP_PARPORT_AUTO:		if (parport_nr[0] == LP_PARPORT_AUTO &&		    port->probe_info[0].class != PARPORT_CLASS_PRINTER)			return;		if (lp_count == LP_NO) {			printk("lp: ignoring parallel port (max. %d)\n",LP_NO);			return;		}		if (!lp_register(lp_count, port))			lp_count++;		break;	default:		for (i = 0; i < LP_NO; i++) {			if (port->number == parport_nr[i]) {				if (!lp_register(i, port))					lp_count++;				break;			}		}		break;	}}static void lp_detach (struct parport *port){	/* Write this some day. */#ifdef CONFIG_LP_CONSOLE	if (console_registered == port) {		unregister_console (&lpcons);		console_registered = NULL;	}#endif /* CONFIG_LP_CONSOLE */}static struct parport_driver lp_driver = {	"lp",	lp_attach,	lp_detach,	NULL};int __init lp_init (void){	int i;	if (parport_nr[0] == LP_PARPORT_OFF)		return 0;	for (i = 0; i < LP_NO; i++) {		lp_table[i].dev = NULL;		lp_table[i].flags = 0;		lp_table[i].chars = LP_INIT_CHAR;		lp_table[i].time = LP_INIT_TIME;		lp_table[i].wait = LP_INIT_WAIT;		lp_table[i].lp_buffer = NULL;#ifdef LP_STATS		lp_table[i].lastcall = 0;		lp_table[i].runchars = 0;		memset (&lp_table[i].stats, 0, sizeof (struct lp_stats));#endif		lp_table[i].last_error = 0;		init_waitqueue_head (&lp_table[i].waitq);		init_waitqueue_head (&lp_table[i].dataq);		init_MUTEX (&lp_table[i].port_mutex);		lp_table[i].timeout = 10 * HZ;	}	if (devfs_register_chrdev (LP_MAJOR, "lp", &lp_fops)) {		printk ("lp: unable to get major %d\n", LP_MAJOR);		return -EIO;	}	devfs_handle = devfs_mk_dir (NULL, "printers", NULL);	if (parport_register_driver (&lp_driver)) {		printk ("lp: unable to register with parport\n");		return -EIO;	}	if (!lp_count) {		printk (KERN_INFO "lp: driver loaded but no devices found\n");#ifndef CONFIG_PARPORT_1284		if (parport_nr[0] == LP_PARPORT_AUTO)			printk (KERN_INFO "lp: (is IEEE 1284 support enabled?)\n");#endif	}	return 0;}static int __init lp_init_module (void){	if (parport[0]) {		/* The user gave some parameters.  Let's see what they were.  */		if (!strncmp(parport[0], "auto", 4))			parport_nr[0] = LP_PARPORT_AUTO;		else {			int n;			for (n = 0; n < LP_NO && parport[n]; n++) {				if (!strncmp(parport[n], "none", 4))					parport_nr[n] = LP_PARPORT_NONE;				else {					char *ep;					unsigned long r = simple_strtoul(parport[n], &ep, 0);					if (ep != parport[n]) 						parport_nr[n] = r;					else {						printk(KERN_ERR "lp: bad port specifier `%s'\n", parport[n]);						return -ENODEV;					}				}			}		}	}	return lp_init();}static void lp_cleanup_module (void){	unsigned int offset;	parport_unregister_driver (&lp_driver);#ifdef CONFIG_LP_CONSOLE	unregister_console (&lpcons);#endif	devfs_unregister (devfs_handle);	devfs_unregister_chrdev(LP_MAJOR, "lp");	for (offset = 0; offset < LP_NO; offset++) {		if (lp_table[offset].dev == NULL)			continue;		parport_unregister_device(lp_table[offset].dev);	}}__setup("lp=", lp_setup);module_init(lp_init_module);module_exit(lp_cleanup_module);MODULE_LICENSE("GPL");EXPORT_NO_SYMBOLS;

⌨️ 快捷键说明

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