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

📄 share.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
 * *	This undoes the effect of parport_register_device(). **/void parport_unregister_device(struct pardevice *dev){	struct parport *port;#ifdef PARPORT_PARANOID	if (dev == NULL) {		printk(KERN_ERR "parport_unregister_device: passed NULL\n");		return;	}#endif	parport_device_proc_unregister(dev);	port = dev->port->physport;	if (port->cad == dev) {		printk(KERN_DEBUG "%s: %s forgot to release port\n",		       port->name, dev->name);		parport_release (dev);	}	spin_lock(&port->pardevice_lock);	if (dev->next)		dev->next->prev = dev->prev;	if (dev->prev)		dev->prev->next = dev->next;	else		port->devices = dev->next;	if (dev->flags & PARPORT_DEV_EXCL)		port->flags &= ~PARPORT_FLAG_EXCL;	spin_unlock(&port->pardevice_lock);	kfree(dev->state);	kfree(dev);	dec_parport_count();	port->ops->dec_use_count();	parport_put_port (port);	/* Yes, that's right, someone _could_ still have a pointer to	 * port, if they used parport_enumerate.  That's why they	 * shouldn't use it (and use parport_register_driver instead)..	 */}/** *	parport_find_number - find a parallel port by number *	@number: parallel port number * *	This returns the parallel port with the specified number, or *	%NULL if there is none. * *	There is an implicit parport_get_port() done already; to throw *	away the reference to the port that parport_find_number() *	gives you, use parport_put_port(). */struct parport *parport_find_number (int number){	struct parport *port, *result = NULL;	spin_lock (&parportlist_lock);	for (port = portlist; port; port = port->next)		if (port->number == number) {			result = parport_get_port (port);			break;		}	spin_unlock (&parportlist_lock);	return result;}/** *	parport_find_base - find a parallel port by base address *	@base: base I/O address * *	This returns the parallel port with the specified base *	address, or %NULL if there is none. * *	There is an implicit parport_get_port() done already; to throw *	away the reference to the port that parport_find_base() *	gives you, use parport_put_port(). */struct parport *parport_find_base (unsigned long base){	struct parport *port, *result = NULL;	spin_lock (&parportlist_lock);	for (port = portlist; port; port = port->next)		if (port->base == base) {			result = parport_get_port (port);			break;		}	spin_unlock (&parportlist_lock);	return result;}/** *	parport_claim - claim access to a parallel port device *	@dev: pointer to structure representing a device on the port * *	This function will not block and so can be used from interrupt *	context.  If parport_claim() succeeds in claiming access to *	the port it returns zero and the port is available to use.  It *	may fail (returning non-zero) if the port is in use by another *	driver and that driver is not willing to relinquish control of *	the port. **/int parport_claim(struct pardevice *dev){	struct pardevice *oldcad;	struct parport *port = dev->port->physport;	unsigned long flags;	if (port->cad == dev) {		printk(KERN_INFO "%s: %s already owner\n",		       dev->port->name,dev->name);		return 0;	}	/* Preempt any current device */	write_lock_irqsave (&port->cad_lock, flags);	if ((oldcad = port->cad) != NULL) {		if (oldcad->preempt) {			if (oldcad->preempt(oldcad->private))				goto blocked;			port->ops->save_state(port, dev->state);		} else			goto blocked;		if (port->cad != oldcad) {			/* I think we'll actually deadlock rather than                           get here, but just in case.. */			printk(KERN_WARNING			       "%s: %s released port when preempted!\n",			       port->name, oldcad->name);			if (port->cad)				goto blocked;		}	}	/* Can't fail from now on, so mark ourselves as no longer waiting.  */	if (dev->waiting & 1) {		dev->waiting = 0;		/* Take ourselves out of the wait list again.  */		spin_lock_irq (&port->waitlist_lock);		if (dev->waitprev)			dev->waitprev->waitnext = dev->waitnext;		else			port->waithead = dev->waitnext;		if (dev->waitnext)			dev->waitnext->waitprev = dev->waitprev;		else			port->waittail = dev->waitprev;		spin_unlock_irq (&port->waitlist_lock);		dev->waitprev = dev->waitnext = NULL;	}	/* Now we do the change of devices */	port->cad = dev;#ifdef CONFIG_PARPORT_1284	/* If it's a mux port, select it. */	if (dev->port->muxport >= 0) {		/* FIXME */		port->muxsel = dev->port->muxport;	}	/* If it's a daisy chain device, select it. */	if (dev->daisy >= 0) {		/* This could be lazier. */		if (!parport_daisy_select (port, dev->daisy,					   IEEE1284_MODE_COMPAT))			port->daisy = dev->daisy;	}#endif /* IEEE1284.3 support */	/* Restore control registers */	port->ops->restore_state(port, dev->state);	write_unlock_irqrestore(&port->cad_lock, flags);	dev->time = jiffies;	return 0;blocked:	/* If this is the first time we tried to claim the port, register an	   interest.  This is only allowed for devices sleeping in	   parport_claim_or_block(), or those with a wakeup function.  */	/* The cad_lock is still held for writing here */	if (dev->waiting & 2 || dev->wakeup) {		spin_lock (&port->waitlist_lock);		if (test_and_set_bit(0, &dev->waiting) == 0) {			/* First add ourselves to the end of the wait list. */			dev->waitnext = NULL;			dev->waitprev = port->waittail;			if (port->waittail) {				port->waittail->waitnext = dev;				port->waittail = dev;			} else				port->waithead = port->waittail = dev;		}		spin_unlock (&port->waitlist_lock);	}	write_unlock_irqrestore (&port->cad_lock, flags);	return -EAGAIN;}/** *	parport_claim_or_block - claim access to a parallel port device *	@dev: pointer to structure representing a device on the port * *	This behaves like parport_claim(), but will block if necessary *	to wait for the port to be free.  A return value of 1 *	indicates that it slept; 0 means that it succeeded without *	needing to sleep.  A negative error code indicates failure. **/int parport_claim_or_block(struct pardevice *dev){	int r;	/* Signal to parport_claim() that we can wait even without a	   wakeup function.  */	dev->waiting = 2;	/* Try to claim the port.  If this fails, we need to sleep.  */	r = parport_claim(dev);	if (r == -EAGAIN) {		unsigned long flags;#ifdef PARPORT_DEBUG_SHARING		printk(KERN_DEBUG "%s: parport_claim() returned -EAGAIN\n", dev->name);#endif		save_flags (flags);		cli();		/* If dev->waiting is clear now, an interrupt		   gave us the port and we would deadlock if we slept.  */		if (dev->waiting) {			sleep_on(&dev->wait_q);			r = 1;		} else {			r = 0;#ifdef PARPORT_DEBUG_SHARING			printk(KERN_DEBUG "%s: didn't sleep in parport_claim_or_block()\n",			       dev->name);#endif		}		restore_flags(flags);#ifdef PARPORT_DEBUG_SHARING		if (dev->port->physport->cad != dev)			printk(KERN_DEBUG "%s: exiting parport_claim_or_block "			       "but %s owns port!\n", dev->name,			       dev->port->physport->cad ?			       dev->port->physport->cad->name:"nobody");#endif	}	dev->waiting = 0;	return r;}/** *	parport_release - give up access to a parallel port device *	@dev: pointer to structure representing parallel port device * *	This function cannot fail, but it should not be called without *	the port claimed.  Similarly, if the port is already claimed *	you should not try claiming it again. **/void parport_release(struct pardevice *dev){	struct parport *port = dev->port->physport;	struct pardevice *pd;	unsigned long flags;	/* Make sure that dev is the current device */	write_lock_irqsave(&port->cad_lock, flags);	if (port->cad != dev) {		write_unlock_irqrestore (&port->cad_lock, flags);		printk(KERN_WARNING "%s: %s tried to release parport "		       "when not owner\n", port->name, dev->name);		return;	}#ifdef CONFIG_PARPORT_1284	/* If this is on a mux port, deselect it. */	if (dev->port->muxport >= 0) {		/* FIXME */		port->muxsel = -1;	}	/* If this is a daisy device, deselect it. */	if (dev->daisy >= 0) {		parport_daisy_deselect_all (port);		port->daisy = -1;	}#endif	port->cad = NULL;	write_unlock_irqrestore(&port->cad_lock, flags);	/* Save control registers */	port->ops->save_state(port, dev->state);	/* If anybody is waiting, find out who's been there longest and	   then wake them up. (Note: no locking required) */	for (pd = port->waithead; pd; pd = pd->waitnext) {		if (pd->waiting & 2) { /* sleeping in claim_or_block */			parport_claim(pd);			if (waitqueue_active(&pd->wait_q))				wake_up(&pd->wait_q);			return;		} else if (pd->wakeup) {			pd->wakeup(pd->private);			if (dev->port->cad) /* racy but no matter */				return;		} else {			printk(KERN_ERR "%s: don't know how to wake %s\n", port->name, pd->name);		}	}	/* Nobody was waiting, so walk the list to see if anyone is	   interested in being woken up. (Note: no locking required) */	for (pd = port->devices; (port->cad == NULL) && pd; pd = pd->next) {		if (pd->wakeup && pd != dev)			pd->wakeup(pd->private);	}}static int parport_parse_params (int nports, const char *str[], int val[],				 int automatic, int none, int nofifo){	unsigned int i;	for (i = 0; i < nports && str[i]; i++) {		if (!strncmp(str[i], "auto", 4))			val[i] = automatic;		else if (!strncmp(str[i], "none", 4))			val[i] = none;		else if (nofifo && !strncmp(str[i], "nofifo", 4))			val[i] = nofifo;		else {			char *ep;			unsigned long r = simple_strtoul(str[i], &ep, 0);			if (ep != str[i])				val[i] = r;			else {				printk("parport: bad specifier `%s'\n", str[i]);				return -1;			}		}	}	return 0;}int parport_parse_irqs(int nports, const char *irqstr[], int irqval[]){	return parport_parse_params (nports, irqstr, irqval, PARPORT_IRQ_AUTO,				     PARPORT_IRQ_NONE, 0);}int parport_parse_dmas(int nports, const char *dmastr[], int dmaval[]){	return parport_parse_params (nports, dmastr, dmaval, PARPORT_DMA_AUTO,				     PARPORT_DMA_NONE, PARPORT_DMA_NOFIFO);}

⌨️ 快捷键说明

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