patch-2.1.47 linux/drivers/pnp/parport_share.c

Next file: linux/fs/dcache.c
Previous file: linux/drivers/pnp/parport_procfs.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.46/linux/drivers/pnp/parport_share.c linux/drivers/pnp/parport_share.c
@@ -1,470 +0,0 @@
-/* $Id: parport_share.c,v 1.3.2.5 1997/04/16 21:20:44 phil Exp $
- * Parallel-port resource manager code.
- * 
- * Authors: David Campbell <campbell@tirian.che.curtin.edu.au>
- *          Tim Waugh <tmw20@cam.ac.uk>
- *	    Jose Renau <renau@acm.org>
- *
- * based on work by Grant Guenther <grant@torque.net>
- *              and Philip Blundell <Philip.Blundell@pobox.com>
- */
-
-#include <linux/tasks.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-
-#include <linux/parport.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/kernel.h>
-#include <linux/malloc.h>
-
-#undef PARPORT_PARANOID
-
-#include "parport_ll_io.h"
-
-static struct parport *portlist = NULL, *portlist_tail = NULL;
-static int portcount = 0;
-
-/* from parport_init.c */
-extern int initialize_parport(struct parport *, unsigned long base, 
-			      int irq, int dma, int count);
-
-/* Return a list of all the ports we know about. */
-struct parport *parport_enumerate(void)
-{
-	return portlist;
-}
-
-void parport_null_intr_func(int irq, void *dev_id, struct pt_regs *regs)
-{
-	/* NULL function - Does nothing */
-	return;
-}
-
-struct parport *parport_register_port(unsigned long base, int irq, int dma)
-{
-	struct parport new, *tmp;
-
-	/* Check for a previously registered port.
-	 * NOTE: we will ignore irq and dma if we find a previously
-	 * registered device.
-	 */
-	for (tmp = portlist; tmp; tmp = tmp->next) {
-		if (tmp->base == base)
-			return tmp;
-	}
-
-	/* Has someone grabbed the address yet? */
-	if (check_region(base, 3))
-		return NULL;
-
-	if (!initialize_parport(&new,base,irq,dma,portcount))
-		return NULL;
-					   
-	if (new.dma >= 0) {
-		if (request_dma(new.dma, new.name)) {
-			printk(KERN_INFO "%s: unable to claim DMA %d\n", 
-			       new.name, new.dma);
-			release_region(new.base, new.size);
-			if( new.modes & PARPORT_MODE_ECR )
-				release_region(new.base+0x400, 3);
-			kfree(new.name);
-			return NULL;
-		}
-	}
-
-	tmp = kmalloc(sizeof(struct parport), GFP_KERNEL);
-	if (!tmp) {
-		printk(KERN_WARNING "parport: memory squeeze\n");
-		release_region(new.base, new.size);
-		if( new.modes & PARPORT_MODE_ECR )
-			release_region(new.base+0x400, 3);
-		kfree(new.name);
-		return NULL;
-	}
-	memcpy(tmp, &new, sizeof(struct parport));
-
-	if (new.irq != PARPORT_IRQ_NONE) {
-		if (request_irq(new.irq, parport_null_intr_func,
-			  SA_INTERRUPT, new.name, tmp) != 0) {
-			printk(KERN_INFO "%s: unable to claim IRQ %d\n", 
-			       new.name, new.irq);
-			kfree(tmp);
-			release_region(new.base, new.size);
-			if( new.modes & PARPORT_MODE_ECR )
-				release_region(new.base+0x400, 3);
-			kfree(new.name);
-			return NULL;
-		}
-	}
-
-	/* Here we chain the entry to our list. */
-	if (portlist_tail)
-		portlist_tail->next = tmp;
-	portlist_tail = tmp;
-	if (!portlist)
-		portlist = tmp;
-
-	printk(KERN_INFO "%s at 0x%x", tmp->name, tmp->base);
-	if (tmp->irq >= 0)
-		printk(", irq %d", tmp->irq);
-	if (tmp->dma >= 0)
-		printk(", dma %d", tmp->dma);
-	printk(" [");
-	{
-		/* Ugh! */
-#define printmode(x) {if(tmp->modes&PARPORT_MODE_##x){printk("%s%s",f?",":"",#x);f++;}}
-		int f = 0;
-		printmode(SPP);
-		printmode(PS2);
-		printmode(EPP);
-		printmode(ECP);
-		printmode(ECPEPP);
-		printmode(ECPPS2);
-#undef printmode
-	}
-	printk("]\n");
-	portcount++;
-
-	/* Restore device back to default conditions */
-	if (tmp->modes & PARPORT_MODE_ECR)
-		w_ecr(tmp, tmp->ecr);
-	w_ctr(tmp, tmp->ctr);
-
-	tmp->probe_info.class = PARPORT_CLASS_LEGACY;  /* assume the worst */
-	return tmp;
-}
-
-void parport_destroy(struct parport *port)
-{
-	/* Dangerous to try destroying a port if its friends are nearby. */
-	if (port->devices) {
-		printk("%s: attempt to release active port\n", port->name);
-		return;		/* Devices still present */
-	}
-
-	/* No point in further destroying a port that already lies in ruins. */
-	if (port->flags & PARPORT_FLAG_COMA) 
-		return;
-
-	/* Now clean out the port entry */
-	if (port->irq >= 0)
-		free_irq(port->irq, port);
-	if (port->dma >= 0)
-		free_dma(port->dma);
-	release_region(port->base, port->size);
-	if( port->modes & PARPORT_MODE_ECR )
-		release_region(port->base+0x400, 3);
-	port->flags |= PARPORT_FLAG_COMA; 
-}
-
-struct ppd *parport_register_device(struct parport *port, const char *name,
-				   callback_func pf, callback_func kf,
-				   irq_handler_func irq_func, int flags,
-				   void *handle)
-{
-	struct ppd *tmp;
-
-	/* We only allow one lurker device (eg PLIP) */
-	if (flags & PARPORT_DEV_LURK) {
-		if (port->lurker) {
-			printk(KERN_INFO "%s: refused to register second lurker (%s)\n",
-				   port->name, name);
-			return NULL;
-		}
-		if (!pf || !kf) {
-			printk(KERN_INFO "%s: refused to register lurking device (%s) without callbacks\n"
-				   ,port->name, name);
-			return NULL;
-		}
-	}
-
-	/* We may need to claw back the port hardware. */
-	if (port->flags & PARPORT_FLAG_COMA) {
-		if (check_region(port->base, 3)) {
-			return NULL;
-		}
-		request_region(port->base, port->size, port->name);
-		if( port->modes & PARPORT_MODE_ECR )
-			request_region(port->base+0x400, 3,port->name);
-			
-		if (port->dma >= 0) {
-			if (request_dma(port->dma, port->name)) {
-				release_region(port->base, port->size);
-				if( port->modes & PARPORT_MODE_ECR )
-					release_region(port->base+0x400, 3);
-				return NULL;
-			}
-		}
-		if (port->irq != PARPORT_IRQ_NONE) {
-			if (request_irq(port->irq, parport_null_intr_func,
-					SA_INTERRUPT, port->name,
-					port) != 0) {
-				release_region(port->base, port->size);
-				if( port->modes & PARPORT_MODE_ECR )
-					release_region(port->base+0x400, 3);
-				if (port->dma >= 0)
-					free_dma(port->dma);
-				return NULL;
-			}
-		}
-		port->flags &= ~PARPORT_FLAG_COMA;
-	}
-
-	tmp = kmalloc(sizeof(struct ppd), GFP_KERNEL);
-	tmp->name = (char *) name;
-	tmp->port = port;
-	tmp->preempt = pf;
-	tmp->wakeup = kf;
-	tmp->private = handle;
-	tmp->flags = flags;
-	tmp->irq_func = irq_func;
-	tmp->ctr = port->ctr;
-	tmp->ecr = port->ecr;
-
-	/* Chain this onto the list */
-	tmp->prev = NULL;
-	tmp->next = port->devices;
-	if (port->devices)
-		port->devices->prev = tmp;
-	port->devices = tmp;
-
-	if (flags & PARPORT_DEV_LURK)
-		port->lurker = tmp;
-
-	inc_parport_count();
-
-	return tmp;
-}
-
-void parport_unregister_device(struct ppd *dev)
-{
-	struct parport *port;
-
-	if (!dev) {
-		printk(KERN_ERR "parport_unregister_device: passed NULL\n");
-		return;
-	}
-
-	port = dev->port;
-
-	if (port->cad == dev) {
-		printk(KERN_INFO "%s: refused to unregister currently active device %s\n", port->name, dev->name);
-		return;
-	}
-
-	if (port->lurker == dev)
-		port->lurker = NULL;
-
-	if (dev->next)
-		dev->next->prev = dev->prev;
-	if (dev->prev)
-		dev->prev->next = dev->next;
-	else
-		port->devices = dev->next;
-
-	kfree(dev);
-
-	dec_parport_count();
-
-	/* If there are no more devices, put the port to sleep. */
-	if (!port->devices)
-		parport_destroy(port);
-
-	return;
-}
-
-int parport_claim(struct ppd *dev)
-{
-	struct ppd *pd1;
-
-	if (dev->port->cad == dev) {
-		printk(KERN_INFO "%s: %s already owner\n",
-			   dev->port->name,dev->name);
-		return 0;
-	}
-
-	/* Preempt any current device */
-	pd1 = dev->port->cad;
-	if (dev->port->cad) {
-		if (dev->port->cad->preempt) {
-			/* Now try to preempt */
-			if (dev->port->cad->preempt(dev->port->cad->private))
-				return -EAGAIN;
-
-			/* Save control registers */
-			if (dev->port->modes & PARPORT_MODE_ECR)
-				dev->port->cad->ecr = dev->port->ecr = 
-					r_ecr(dev->port);
-			if (dev->port->modes & PARPORT_MODE_SPP)
-				dev->port->cad->ctr = dev->port->ctr =
-					r_ctr(dev->port);
-		} else
-			return -EAGAIN;
-	}
-
-	/* Watch out for bad things */
-	if (dev->port->cad != pd1) {
-		printk(KERN_WARNING "%s: death while preempting %s\n",
-		       dev->port->name, dev->name);
-		if (dev->port->cad)
-			return -EAGAIN;
-	}
-
-	/* Now we do the change of devices */
-	dev->port->cad = dev;
-
-	if (dev->port->irq >= 0) {
-		free_irq(dev->port->irq, dev->port);
-		request_irq(dev->port->irq, dev->irq_func ? dev->irq_func :
-			    parport_null_intr_func, SA_INTERRUPT, dev->name,
-			    dev->port);
-	}
-
-	/* Restore control registers */
-	if (dev->port->modes & PARPORT_MODE_ECR)
-		if (dev->ecr != dev->port->ecr) w_ecr(dev->port, dev->ecr);
-	if (dev->port->modes & PARPORT_MODE_SPP)
-		if (dev->ctr != dev->port->ctr) w_ctr(dev->port, dev->ctr);
-
-	return 0;
-}
-
-void parport_release(struct ppd *dev)
-{
-	struct ppd *pd1;
-
-	/* Make sure that dev is the current device */
-	if (dev->port->cad != dev) {
-		printk(KERN_WARNING "%s: %s tried to release parport when not owner\n", dev->port->name, dev->name);
-		return;
-	}
-	dev->port->cad = NULL;
-
-	/* Save control registers */
-	if (dev->port->modes & PARPORT_MODE_ECR)
-		dev->ecr = dev->port->ecr = r_ecr(dev->port);
-	if (dev->port->modes & PARPORT_MODE_SPP)
-		dev->ctr = dev->port->ctr = r_ctr(dev->port);
-	
-	if (dev->port->irq >= 0) {
-		free_irq(dev->port->irq, dev->port);
-		request_irq(dev->port->irq, parport_null_intr_func,
-			    SA_INTERRUPT, dev->port->name, dev->port);
- 	}
-
-	/* Walk the list, offering a wakeup callback to everybody other
-	 * than the lurker and the device that called us.
-	 */
-	for (pd1 = dev->next; pd1; pd1 = pd1->next) {
-		if (!(pd1->flags & PARPORT_DEV_LURK)) {
-			if (pd1->wakeup) {
-				pd1->wakeup(pd1->private);
-				if (dev->port->cad)
-					return;
-			}
-		}
-	}
-
-	for (pd1 = dev->port->devices; pd1 && pd1 != dev; pd1 = pd1->next) {
-		if (!(pd1->flags & PARPORT_DEV_LURK)) {
-			if (pd1->wakeup) {
-				pd1->wakeup(pd1->private);
-				if (dev->port->cad)
-					return;
-			}
-		}
-	}
-
-	/* Now give the lurker a chance.
-	 * There should be a wakeup callback because we checked for it
-	 * at registration.
-	 */
-	if (dev->port->lurker && (dev->port->lurker != dev)) {
-		if (dev->port->lurker->wakeup) {
-			dev->port->lurker->wakeup(dev->port->lurker->private);
-		} 
-#ifdef PARPORT_PARANOID
-		else {  /* can't happen */
-			printk(KERN_DEBUG
-			  "%s (%s): lurker's wakeup callback went away!\n",
-			       dev->port->name, dev->name);
-		}
-#endif
-	}
-}
-
-/* The following read funktions are an implementation of a status readback
- * and device id request confirming to IEEE1284-1994.
- *
- * These probably ought to go in some seperate file, so people like the SPARC
- * don't have to pull them in.
- */
-
-/* Wait for Status line(s) to change in 35 ms - see IEEE1284-1994 page 24 to
- * 25 for this. After this time we can create a timeout because the
- * peripheral doesn't conform to IEEE1284. We want to save CPU time: we are
- * waiting a maximum time of 500 us busy (this is for speed). If there is
- * not the right answer in this time, we call schedule and other processes
- * are able "to eat" the time up to 30ms.  So the maximum load avarage can't
- * get above 5% for a read even if the peripheral is really slow. (but your
- * read gets very slow then - only about 10 characters per second. This
- * should be tuneable). Thanks to Andreas who pointed me to this and ordered
- * the documentation.
- */ 
-
-int parport_wait_peripheral(struct parport *port, unsigned char mask, 
-	unsigned char result)
-{
-	int counter=0;
-	unsigned char status; 
-	
-	do {
-		status = parport_r_status(port);
-		udelay(25);
-		counter++;
-		if (need_resched)
-			schedule();
-	} while ( ((status & mask) != result) && (counter < 20) );
-	if ( (counter == 20) && ((status & mask) != result) ) { 
-		current->state=TASK_INTERRUPTIBLE;
-		current->timeout=jiffies+4;
-		schedule(); /* wait for 4 scheduler runs (40ms) */
-		status = parport_r_status(port);
-		if ((status & mask) != result) return 1; /* timeout */
-	}
-	return 0; /* okay right response from device */
-}		
-
-/* Test if nibble mode for status readback is okay. Returns the value false
- * if the printer doesn't support readback at all. If it supports readbacks
- * and printer data is available the function returns 1, otherwise 2. The
- * only valid values for "mode" are 0 and 4. 0 requests normal nibble mode,
- * 4 is for "request device id using nibble mode". The request for the
- * device id is best done in an ioctl (or at bootup time).  There is no
- * check for an invalid value, the only function using this call at the
- * moment is lp_read and the ioctl LPGETDEVICEID both fixed calls from
- * trusted kernel.
- */
-int parport_ieee1284_nibble_mode_ok(struct parport *port, unsigned char mode) 
-{
-	parport_w_data(port, mode);
-	udelay(5);		
-	parport_w_ctrl(port, parport_r_ctrl(port) & ~8);  /* SelectIN low */
-	parport_w_ctrl(port, parport_r_ctrl(port) | 2); /* AutoFeed high */
-	if (parport_wait_peripheral(port, 0x78, 0x38)) { /* timeout? */
-		parport_w_ctrl(port, (parport_r_ctrl(port) & ~2) | 8);
-		return 0; /* first stage of negotiation failed, 
-                           * no IEEE1284 compliant device on this port 
-                           */ 
-	}
-	parport_w_ctrl(port, parport_r_ctrl(port) | 1);      /* Strobe high */
-	udelay(5);				     /* Strobe wait */
-	parport_w_ctrl(port, parport_r_ctrl(port) & ~1);     /* Strobe low */
-	udelay(5);
-	parport_w_ctrl(port, parport_r_ctrl(port) & ~2);     /* AutoFeed low */
-	return (parport_wait_peripheral(port, 0x20, 0))?2:1;
-}

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov