File:  [DragonFly] / src / sys / dev / misc / lpt / lpt.c
Revision 1.9: download - view: text, annotated - select for diffs
Wed May 19 22:52:43 2004 UTC (10 years, 7 months ago) by dillon
Branches: MAIN
CVS tags: HEAD, DragonFly_Snap13Sep2004, DragonFly_1_0_REL, DragonFly_1_0_RC1, DragonFly_1_0A_REL
Device layer rollup commit.

* cdevsw_add() is now required.  cdevsw_add() and cdevsw_remove() may specify
  a mask/match indicating the range of supported minor numbers.  Multiple
  cdevsw_add()'s using the same major number, but distinctly different
  ranges, may be issued.  All devices that failed to call cdevsw_add() before
  now do.

* cdevsw_remove() now automatically marks all devices within its supported
  range as being destroyed.

* vnode->v_rdev is no longer resolved when the vnode is created.  Instead,
  only v_udev (a newly added field) is resolved.  v_rdev is resolved when
  the vnode is opened and cleared on the last close.

* A great deal of code was making rather dubious assumptions with regards
  to the validity of devices associated with vnodes, primarily due to
  the persistence of a device structure due to being indexed by (major, minor)
  instead of by (cdevsw, major, minor).  In particular, if you run a program
  which connects to a USB device and then you pull the USB device and plug
  it back in, the vnode subsystem will continue to believe that the device
  is open when, in fact, it isn't (because it was destroyed and recreated).

  In particular, note that all the VFS mount procedures now check devices
  via v_udev instead of v_rdev prior to calling VOP_OPEN(), since v_rdev
  is NULL prior to the first open.

* The disk layer's device interaction has been rewritten.  The disk layer
  (i.e. the slice and disklabel management layer) no longer overloads
  its data onto the device structure representing the underlying physical
  disk.  Instead, the disk layer uses the new cdevsw_add() functionality
  to register its own cdevsw using the underlying device's major number,
  and simply does NOT register the underlying device's cdevsw.  No
  confusion is created because the device hash is now based on
  (cdevsw,major,minor) rather then (major,minor).

  NOTE: This also means that underlying raw disk devices may use the entire
  device minor number instead of having to reserve the bits used by the disk
  layer, and also means that can we (theoretically) stack a fully
  disklabel-supported 'disk' on top of any block device.

* The new reference counting scheme prevents this by associating a device
  with a cdevsw and disconnecting the device from its cdevsw when the cdevsw
  is removed.  Additionally, all udev2dev() lookups run through the cdevsw
  mask/match and only successfully find devices still associated with an
  active cdevsw.

* Major work on MFS:  MFS no longer shortcuts vnode and device creation.  It
  now creates a real vnode and a real device and implements real open and
  close VOPs.  Additionally, due to the disk layer changes, MFS is no longer
  limited to 255 mounts.  The new limit is 16 million.  Since MFS creates a
  real device node, mount_mfs will now create a real /dev/mfs<PID> device
  that can be read from userland (e.g. so you can dump an MFS filesystem).

* BUF AND DEVICE STRATEGY changes.  The struct buf contains a b_dev field.
  In order to properly handle stacked devices we now require that the b_dev
  field be initialized before the device strategy routine is called.  This
  required some additional work in various VFS implementations.  To enforce
  this requirement, biodone() now sets b_dev to NODEV.  The new disk layer
  will adjust b_dev before forwarding a request to the actual physical
  device.

* A bug in the ISO CD boot sequence which resulted in a panic has been fixed.

Testing by: lots of people, but David Rhodus found the most aggregious bugs.

    1: /*
    2:  * Copyright (c) 1990 William F. Jolitz, TeleMuse
    3:  * All rights reserved.
    4:  *
    5:  * Redistribution and use in source and binary forms, with or without
    6:  * modification, are permitted provided that the following conditions
    7:  * are met:
    8:  * 1. Redistributions of source code must retain the above copyright
    9:  *    notice, this list of conditions and the following disclaimer.
   10:  * 2. Redistributions in binary form must reproduce the above copyright
   11:  *    notice, this list of conditions and the following disclaimer in the
   12:  *    documentation and/or other materials provided with the distribution.
   13:  * 3. All advertising materials mentioning features or use of this software
   14:  *    must display the following acknowledgement:
   15:  *	This software is a component of "386BSD" developed by
   16:  *	William F. Jolitz, TeleMuse.
   17:  * 4. Neither the name of the developer nor the name "386BSD"
   18:  *    may be used to endorse or promote products derived from this software
   19:  *    without specific prior written permission.
   20:  *
   21:  * THIS SOFTWARE IS A COMPONENT OF 386BSD DEVELOPED BY WILLIAM F. JOLITZ
   22:  * AND IS INTENDED FOR RESEARCH AND EDUCATIONAL PURPOSES ONLY. THIS
   23:  * SOFTWARE SHOULD NOT BE CONSIDERED TO BE A COMMERCIAL PRODUCT.
   24:  * THE DEVELOPER URGES THAT USERS WHO REQUIRE A COMMERCIAL PRODUCT
   25:  * NOT MAKE USE OF THIS WORK.
   26:  *
   27:  * FOR USERS WHO WISH TO UNDERSTAND THE 386BSD SYSTEM DEVELOPED
   28:  * BY WILLIAM F. JOLITZ, WE RECOMMEND THE USER STUDY WRITTEN
   29:  * REFERENCES SUCH AS THE  "PORTING UNIX TO THE 386" SERIES
   30:  * (BEGINNING JANUARY 1991 "DR. DOBBS JOURNAL", USA AND BEGINNING
   31:  * JUNE 1991 "UNIX MAGAZIN", GERMANY) BY WILLIAM F. JOLITZ AND
   32:  * LYNNE GREER JOLITZ, AS WELL AS OTHER BOOKS ON UNIX AND THE
   33:  * ON-LINE 386BSD USER MANUAL BEFORE USE. A BOOK DISCUSSING THE INTERNALS
   34:  * OF 386BSD ENTITLED "386BSD FROM THE INSIDE OUT" WILL BE AVAILABLE LATE 1992.
   35:  *
   36:  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``AS IS'' AND
   37:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   38:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   39:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE DEVELOPER BE LIABLE
   40:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   41:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   42:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   43:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   44:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   45:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   46:  * SUCH DAMAGE.
   47:  *
   48:  *	from: unknown origin, 386BSD 0.1
   49:  *	From Id: lpt.c,v 1.55.2.1 1996/11/12 09:08:38 phk Exp
   50:  *	From Id: nlpt.c,v 1.14 1999/02/08 13:55:43 des Exp
   51:  * $FreeBSD: src/sys/dev/ppbus/lpt.c,v 1.15.2.3 2000/07/07 00:30:40 obrien Exp $
   52:  * $DragonFly: src/sys/dev/misc/lpt/lpt.c,v 1.9 2004/05/19 22:52:43 dillon Exp $
   53:  */
   54: 
   55: /*
   56:  * Device Driver for AT parallel printer port
   57:  * Written by William Jolitz 12/18/90
   58:  */
   59: 
   60: /*
   61:  * Updated for ppbus by Nicolas Souchu
   62:  * [Mon Jul 28 1997]
   63:  */
   64: 
   65: #include "opt_lpt.h"
   66: 
   67: #include <sys/param.h>
   68: #include <sys/systm.h>
   69: #include <sys/module.h>
   70: #include <sys/bus.h>
   71: #include <sys/conf.h>
   72: #include <sys/kernel.h>
   73: #include <sys/uio.h>
   74: #include <sys/syslog.h>
   75: #include <sys/malloc.h>
   76: 
   77: #include <machine/clock.h>
   78: #include <machine/bus.h>
   79: #include <machine/resource.h>
   80: #include <sys/rman.h>
   81: 
   82: #include "lptio.h"
   83: #include <bus/ppbus/ppbconf.h>
   84: #include <bus/ppbus/ppb_1284.h>
   85: #include "lpt.h"
   86: #include "ppbus_if.h"
   87: #include <bus/ppbus/ppbio.h>
   88: 
   89: MALLOC_DEFINE(M_LPT, "lpt", "LPT buffers");
   90: 
   91: #ifndef LPT_DEBUG
   92: #define lprintf(args)
   93: #else
   94: #define lprintf(args)						\
   95: 		do {						\
   96: 			if (lptflag)				\
   97: 				printf args;			\
   98: 		} while (0)
   99: static int volatile lptflag = 1;
  100: #endif
  101: 
  102: #define	LPINITRDY	4	/* wait up to 4 seconds for a ready */
  103: #define	LPTOUTINITIAL	10	/* initial timeout to wait for ready 1/10 s */
  104: #define	LPTOUTMAX	1	/* maximal timeout 1 s */
  105: #define	BUFSIZE		1024
  106: #define	BUFSTATSIZE	32
  107: 
  108: #define	LPTUNIT(s)	((s)&0x03)
  109: #define	LPTFLAGS(s)	((s)&0xfc)
  110: 
  111: struct lpt_data {
  112: 
  113: 	short	sc_state;
  114: 	/* default case: negative prime, negative ack, handshake strobe,
  115: 	   prime once */
  116: 	u_char	sc_control;
  117: 	char	sc_flags;
  118: #define LP_UNITMASK	0x03	/* up to 4 units */
  119: #define LP_POS_INIT	0x04	/* if we are a postive init signal */
  120: #define LP_POS_ACK	0x08	/* if we are a positive going ack */
  121: #define LP_NO_PRIME	0x10	/* don't prime the printer at all */
  122: #define LP_PRIMEOPEN	0x20	/* prime on every open */
  123: #define LP_AUTOLF	0x40	/* tell printer to do an automatic lf */
  124: #define LP_BYPASS	0x80	/* bypass  printer ready checks */
  125: 	void	*sc_inbuf;
  126: 	void	*sc_statbuf;
  127: 	short	sc_xfercnt ;
  128: 	char	sc_primed;
  129: 	char	*sc_cp ;
  130: 	u_short	sc_irq ;	/* IRQ status of port */
  131: #define LP_HAS_IRQ	0x01	/* we have an irq available */
  132: #define LP_USE_IRQ	0x02	/* we are using our irq */
  133: #define LP_ENABLE_IRQ	0x04	/* enable IRQ on open */
  134: #define LP_ENABLE_EXT	0x10	/* we shall use advanced mode when possible */
  135: 	u_char	sc_backoff ;	/* time to call lptout() again */
  136: 
  137: 	struct resource *intr_resource;	/* interrupt resource */
  138: 	void *intr_cookie;		/* interrupt registration cookie */
  139: 
  140: };
  141: 
  142: #define LPT_NAME	"lpt"		/* our official name */
  143: 
  144: static timeout_t lptout;
  145: static int	lpt_port_test(device_t dev, u_char data, u_char mask);
  146: static int	lpt_detect(device_t dev);
  147: 
  148: #define DEVTOSOFTC(dev) \
  149: 	((struct lpt_data *)device_get_softc(dev))
  150: #define UNITOSOFTC(unit) \
  151: 	((struct lpt_data *)devclass_get_softc(lpt_devclass, (unit)))
  152: #define UNITODEVICE(unit) \
  153: 	(devclass_get_device(lpt_devclass, (unit)))
  154: 
  155: static void lptintr(device_t dev);
  156: static void lpt_intr(void *arg);	/* without spls */
  157: 
  158: static devclass_t lpt_devclass;
  159: 
  160: 
  161: /* bits for state */
  162: #define	OPEN		(1<<0)	/* device is open */
  163: #define	ASLP		(1<<1)	/* awaiting draining of printer */
  164: #define	EERROR		(1<<2)	/* error was received from printer */
  165: #define	OBUSY		(1<<3)	/* printer is busy doing output */
  166: #define LPTOUT		(1<<4)	/* timeout while not selected */
  167: #define TOUT		(1<<5)	/* timeout while not selected */
  168: #define LPTINIT		(1<<6)	/* waiting to initialize for open */
  169: #define INTERRUPTED	(1<<7)	/* write call was interrupted */
  170: 
  171: #define HAVEBUS		(1<<8)	/* the driver owns the bus */
  172: 
  173: 
  174: /* status masks to interrogate printer status */
  175: #define RDY_MASK	(LPS_SEL|LPS_OUT|LPS_NBSY|LPS_NERR)	/* ready ? */
  176: #define LP_READY	(LPS_SEL|LPS_NBSY|LPS_NERR)
  177: 
  178: /* Printer Ready condition  - from lpa.c */
  179: /* Only used in polling code */
  180: #define	LPS_INVERT	(LPS_NBSY | LPS_NACK |           LPS_SEL | LPS_NERR)
  181: #define	LPS_MASK	(LPS_NBSY | LPS_NACK | LPS_OUT | LPS_SEL | LPS_NERR)
  182: #define	NOT_READY(ppbus) ((ppb_rstr(ppbus)^LPS_INVERT)&LPS_MASK)
  183: 
  184: #define	MAX_SLEEP	(hz*5)	/* Timeout while waiting for device ready */
  185: #define	MAX_SPIN	20	/* Max delay for device ready in usecs */
  186: 
  187: 
  188: static	d_open_t	lptopen;
  189: static	d_close_t	lptclose;
  190: static	d_write_t	lptwrite;
  191: static	d_read_t	lptread;
  192: static	d_ioctl_t	lptioctl;
  193: 
  194: #define CDEV_MAJOR 16
  195: static struct cdevsw lpt_cdevsw = {
  196: 	/* name */	LPT_NAME,
  197: 	/* maj */	CDEV_MAJOR,
  198: 	/* flags */	0,
  199: 	/* port */	NULL,
  200: 	/* clone */	NULL,
  201: 
  202: 	/* open */	lptopen,
  203: 	/* close */	lptclose,
  204: 	/* read */	lptread,
  205: 	/* write */	lptwrite,
  206: 	/* ioctl */	lptioctl,
  207: 	/* poll */	nopoll,
  208: 	/* mmap */	nommap,
  209: 	/* strategy */	nostrategy,
  210: 	/* dump */	nodump,
  211: 	/* psize */	nopsize
  212: };
  213: 
  214: static int
  215: lpt_request_ppbus(device_t dev, int how)
  216: {
  217: 	device_t ppbus = device_get_parent(dev);
  218: 	struct lpt_data *sc = DEVTOSOFTC(dev);
  219: 	int error;
  220: 
  221: 	if (sc->sc_state & HAVEBUS)
  222: 		return (0);
  223: 
  224: 	/* we have the bus only if the request succeded */
  225: 	if ((error = ppb_request_bus(ppbus, dev, how)) == 0)
  226: 		sc->sc_state |= HAVEBUS;
  227: 
  228: 	return (error);
  229: }
  230: 
  231: static int
  232: lpt_release_ppbus(device_t dev)
  233: {
  234: 	device_t ppbus = device_get_parent(dev);
  235: 	struct lpt_data *sc = DEVTOSOFTC(dev);
  236: 	int error = 0;
  237: 
  238: 	if ((error = ppb_release_bus(ppbus, dev)) == 0)
  239: 		sc->sc_state &= ~HAVEBUS;
  240: 
  241: 	return (error);
  242: }
  243: 
  244: /*
  245:  * Internal routine to lptprobe to do port tests of one byte value
  246:  */
  247: static int
  248: lpt_port_test(device_t ppbus, u_char data, u_char mask)
  249: {
  250: 	int	temp, timeout;
  251: 
  252: 	data = data & mask;
  253: 	ppb_wdtr(ppbus, data);
  254: 	timeout = 10000;
  255: 	do {
  256: 		DELAY(10);
  257: 		temp = ppb_rdtr(ppbus) & mask;
  258: 	}
  259: 	while (temp != data && --timeout);
  260: 	lprintf(("out=%x\tin=%x\ttout=%d\n", data, temp, timeout));
  261: 	return (temp == data);
  262: }
  263: 
  264: /*
  265:  * Probe simplified by replacing multiple loops with a hardcoded
  266:  * test pattern - 1999/02/08 des@freebsd.org
  267:  *
  268:  * New lpt port probe Geoff Rehmet - Rhodes University - 14/2/94
  269:  * Based partially on Rod Grimes' printer probe
  270:  *
  271:  * Logic:
  272:  *	1) If no port address was given, use the bios detected ports
  273:  *	   and autodetect what ports the printers are on.
  274:  *	2) Otherwise, probe the data port at the address given,
  275:  *	   using the method in Rod Grimes' port probe.
  276:  *	   (Much code ripped off directly from Rod's probe.)
  277:  *
  278:  * Comments from Rod's probe:
  279:  * Logic:
  280:  *	1) You should be able to write to and read back the same value
  281:  *	   to the data port.  Do an alternating zeros, alternating ones,
  282:  *	   walking zero, and walking one test to check for stuck bits.
  283:  *
  284:  *	2) You should be able to write to and read back the same value
  285:  *	   to the control port lower 5 bits, the upper 3 bits are reserved
  286:  *	   per the IBM PC technical reference manauls and different boards
  287:  *	   do different things with them.  Do an alternating zeros, alternating
  288:  *	   ones, walking zero, and walking one test to check for stuck bits.
  289:  *
  290:  *	   Some printers drag the strobe line down when the are powered off
  291:  * 	   so this bit has been masked out of the control port test.
  292:  *
  293:  *	   XXX Some printers may not like a fast pulse on init or strobe, I
  294:  *	   don't know at this point, if that becomes a problem these bits
  295:  *	   should be turned off in the mask byte for the control port test.
  296:  *
  297:  *	   We are finally left with a mask of 0x14, due to some printers
  298:  *	   being adamant about holding other bits high ........
  299:  *
  300:  *	   Before probing the control port, we write a 0 to the data port -
  301:  *	   If not, some printers chuck out garbage when the strobe line
  302:  *	   gets toggled.
  303:  *
  304:  *	3) Set the data and control ports to a value of 0
  305:  *
  306:  *	This probe routine has been tested on Epson Lx-800, HP LJ3P,
  307:  *	Epson FX-1170 and C.Itoh 8510RM
  308:  *	printers.
  309:  *	Quick exit on fail added.
  310:  */
  311: static int
  312: lpt_detect(device_t dev)
  313: {
  314: 	device_t ppbus = device_get_parent(dev);
  315: 
  316: 	static u_char	testbyte[18] = {
  317: 		0x55,			/* alternating zeros */
  318: 		0xaa,			/* alternating ones */
  319: 		0xfe, 0xfd, 0xfb, 0xf7,
  320: 		0xef, 0xdf, 0xbf, 0x7f,	/* walking zero */
  321: 		0x01, 0x02, 0x04, 0x08,
  322: 		0x10, 0x20, 0x40, 0x80	/* walking one */
  323: 	};
  324: 	int		i, error, status;
  325: 
  326: 	status = 1;				/* assume success */
  327: 
  328: 	if ((error = lpt_request_ppbus(dev, PPB_DONTWAIT))) {
  329: 		printf(LPT_NAME ": cannot alloc ppbus (%d)!\n", error);
  330: 		status = 0;
  331: 		goto end_probe;
  332: 	}
  333: 
  334: 	for (i = 0; i < 18 && status; i++)
  335: 		if (!lpt_port_test(ppbus, testbyte[i], 0xff)) {
  336: 			status = 0;
  337: 			goto end_probe;
  338: 		}
  339: 
  340: end_probe:
  341: 	/* write 0's to control and data ports */
  342: 	ppb_wdtr(ppbus, 0);
  343: 	ppb_wctr(ppbus, 0);
  344: 
  345: 	lpt_release_ppbus(dev);
  346: 
  347: 	return (status);
  348: }
  349: 
  350: static void
  351: lpt_identify(driver_t *driver, device_t parent)
  352: {
  353: 
  354: 	BUS_ADD_CHILD(parent, 0, LPT_NAME, 0);
  355: }
  356: 
  357: /*
  358:  * lpt_probe()
  359:  */
  360: static int
  361: lpt_probe(device_t dev)
  362: {
  363: 	struct lpt_data *sc;
  364: 	
  365: 	sc = DEVTOSOFTC(dev);
  366: 	bzero(sc, sizeof(struct lpt_data));
  367: 
  368: 	/*
  369: 	 * Now, try to detect the printer.
  370: 	 */
  371: 	if (!lpt_detect(dev))
  372: 		return (ENXIO);
  373: 
  374: 	device_set_desc(dev, "Printer");
  375: 
  376: 	return (0);
  377: }
  378: 
  379: static int
  380: lpt_attach(device_t dev)
  381: {
  382: 	device_t ppbus = device_get_parent(dev);
  383: 	struct lpt_data *sc = DEVTOSOFTC(dev);
  384: 	int zero = 0, unit = device_get_unit(dev);
  385: 	int error;
  386: 	uintptr_t irq;
  387: 
  388: 	sc->sc_primed = 0;	/* not primed yet */
  389: 
  390: 	if ((error = lpt_request_ppbus(dev, PPB_DONTWAIT))) {
  391: 		printf(LPT_NAME ": cannot alloc ppbus (%d)!\n", error);
  392: 		return (0);
  393: 	}
  394: 
  395: 	ppb_wctr(ppbus, LPC_NINIT);
  396: 
  397: 	/* check if we can use interrupt, should be done by ppc stuff */
  398: 	lprintf(("oldirq %x\n", sc->sc_irq));
  399: 
  400: 	/* retrieve the ppbus irq */
  401: 	BUS_READ_IVAR(ppbus, dev, PPBUS_IVAR_IRQ, &irq);
  402: 
  403: 	if (irq > 0) {
  404: 		/* declare our interrupt handler */
  405: 		sc->intr_resource = bus_alloc_resource(dev, SYS_RES_IRQ,
  406: 						       &zero, irq, irq, 1, RF_SHAREABLE);
  407: 	}
  408: 	if (sc->intr_resource) {
  409: 		sc->sc_irq = LP_HAS_IRQ | LP_USE_IRQ | LP_ENABLE_IRQ;
  410: 		device_printf(dev, "Interrupt-driven port\n");
  411: 	} else {
  412: 		sc->sc_irq = 0;
  413: 		device_printf(dev, "Polled port\n");
  414: 	}
  415: 	lprintf(("irq %x %x\n", irq, sc->sc_irq));
  416: 
  417: 	lpt_release_ppbus(dev);
  418: 
  419: 	cdevsw_add(&lpt_cdevsw, LP_UNITMASK, unit);
  420: 	make_dev(&lpt_cdevsw, unit,
  421: 	    UID_ROOT, GID_WHEEL, 0600, LPT_NAME "%d", unit);
  422: 	make_dev(&lpt_cdevsw, unit | LP_BYPASS,
  423: 	    UID_ROOT, GID_WHEEL, 0600, LPT_NAME "%d.ctl", unit);
  424: 	return (0);
  425: }
  426: 
  427: static void
  428: lptout(void *arg)
  429: {
  430: 	device_t dev = (device_t)arg;
  431: 	struct lpt_data *sc = DEVTOSOFTC(dev);
  432: #ifdef LPT_DEBUG
  433: 	device_t ppbus = device_get_parent(dev);
  434: #endif
  435: 
  436: 	lprintf(("T %x ", ppb_rstr(ppbus)));
  437: 	if (sc->sc_state & OPEN) {
  438: 		sc->sc_backoff++;
  439: 		if (sc->sc_backoff > hz/LPTOUTMAX)
  440: 			sc->sc_backoff = sc->sc_backoff > hz/LPTOUTMAX;
  441: 		timeout(lptout, (caddr_t)dev, sc->sc_backoff);
  442: 	} else
  443: 		sc->sc_state &= ~TOUT;
  444: 
  445: 	if (sc->sc_state & EERROR)
  446: 		sc->sc_state &= ~EERROR;
  447: 
  448: 	/*
  449: 	 * Avoid possible hangs due to missed interrupts
  450: 	 */
  451: 	if (sc->sc_xfercnt) {
  452: 		lptintr(dev);
  453: 	} else {
  454: 		sc->sc_state &= ~OBUSY;
  455: 		wakeup((caddr_t)dev);
  456: 	}
  457: }
  458: 
  459: /*
  460:  * lptopen -- reset the printer, then wait until it's selected and not busy.
  461:  *	If LP_BYPASS flag is selected, then we do not try to select the
  462:  *	printer -- this is just used for passing ioctls.
  463:  */
  464: 
  465: static	int
  466: lptopen(dev_t dev, int flags, int fmt, struct thread *p)
  467: {
  468: 	int s;
  469: 	int trys, err;
  470: 	u_int unit = LPTUNIT(minor(dev));
  471: 	struct lpt_data *sc = UNITOSOFTC(unit);
  472: 	device_t lptdev = UNITODEVICE(unit);
  473: 	device_t ppbus = device_get_parent(lptdev);
  474: 
  475: 	if (!sc)
  476: 		return (ENXIO);
  477: 
  478: 	if (sc->sc_state) {
  479: 		lprintf((LPT_NAME ": still open %x\n", sc->sc_state));
  480: 		return(EBUSY);
  481: 	} else
  482: 		sc->sc_state |= LPTINIT;
  483: 
  484: 	sc->sc_flags = LPTFLAGS(minor(dev));
  485: 
  486: 	/* Check for open with BYPASS flag set. */
  487: 	if (sc->sc_flags & LP_BYPASS) {
  488: 		sc->sc_state = OPEN;
  489: 		return(0);
  490: 	}
  491: 
  492: 	/* request the ppbus only if we don't have it already */
  493: 	if ((err = lpt_request_ppbus(lptdev, PPB_WAIT|PPB_INTR)) != 0) {
  494: 		/* give it a chance to try later */
  495: 		sc->sc_state = 0;
  496: 		return (err);
  497: 	}
  498: 
  499: 	s = spltty();
  500: 	lprintf((LPT_NAME " flags 0x%x\n", sc->sc_flags));
  501: 
  502: 	/* set IRQ status according to ENABLE_IRQ flag
  503: 	 */
  504: 	if (sc->sc_irq & LP_ENABLE_IRQ)
  505: 		sc->sc_irq |= LP_USE_IRQ;
  506: 	else
  507: 		sc->sc_irq &= ~LP_USE_IRQ;
  508: 
  509: 	/* init printer */
  510: 	if ((sc->sc_flags & LP_NO_PRIME) == 0) {
  511: 		if((sc->sc_flags & LP_PRIMEOPEN) || sc->sc_primed == 0) {
  512: 			ppb_wctr(ppbus, 0);
  513: 			sc->sc_primed++;
  514: 			DELAY(500);
  515: 		}
  516: 	}
  517: 
  518: 	ppb_wctr(ppbus, LPC_SEL|LPC_NINIT);
  519: 
  520: 	/* wait till ready (printer running diagnostics) */
  521: 	trys = 0;
  522: 	do {
  523: 		/* ran out of waiting for the printer */
  524: 		if (trys++ >= LPINITRDY*4) {
  525: 			splx(s);
  526: 			sc->sc_state = 0;
  527: 			lprintf(("status %x\n", ppb_rstr(ppbus)));
  528: 
  529: 			lpt_release_ppbus(lptdev);
  530: 			return (EBUSY);
  531: 		}
  532: 
  533: 		/* wait 1/4 second, give up if we get a signal */
  534: 		if (tsleep((caddr_t)lptdev, PCATCH, "lptinit", hz/4) !=
  535: 		    EWOULDBLOCK) {
  536: 			sc->sc_state = 0;
  537: 			splx(s);
  538: 
  539: 			lpt_release_ppbus(lptdev);
  540: 			return (EBUSY);
  541: 		}
  542: 
  543: 		/* is printer online and ready for output */
  544: 	} while ((ppb_rstr(ppbus) &
  545: 			(LPS_SEL|LPS_OUT|LPS_NBSY|LPS_NERR)) !=
  546: 					(LPS_SEL|LPS_NBSY|LPS_NERR));
  547: 
  548: 	sc->sc_control = LPC_SEL|LPC_NINIT;
  549: 	if (sc->sc_flags & LP_AUTOLF)
  550: 		sc->sc_control |= LPC_AUTOL;
  551: 
  552: 	/* enable interrupt if interrupt-driven */
  553: 	if (sc->sc_irq & LP_USE_IRQ)
  554: 		sc->sc_control |= LPC_ENA;
  555: 
  556: 	ppb_wctr(ppbus, sc->sc_control);
  557: 
  558: 	sc->sc_state = OPEN;
  559: 	sc->sc_inbuf = malloc(BUFSIZE, M_LPT, M_WAITOK);
  560: 	sc->sc_statbuf = malloc(BUFSTATSIZE, M_LPT, M_WAITOK);
  561: 	sc->sc_xfercnt = 0;
  562: 	splx(s);
  563: 
  564: 	/* release the ppbus */
  565: 	lpt_release_ppbus(lptdev);
  566: 
  567: 	/* only use timeout if using interrupt */
  568: 	lprintf(("irq %x\n", sc->sc_irq));
  569: 	if (sc->sc_irq & LP_USE_IRQ) {
  570: 		sc->sc_state |= TOUT;
  571: 		timeout(lptout, (caddr_t)lptdev,
  572: 			 (sc->sc_backoff = hz/LPTOUTINITIAL));
  573: 	}
  574: 
  575: 	lprintf(("opened.\n"));
  576: 	return(0);
  577: }
  578: 
  579: /*
  580:  * lptclose -- close the device, free the local line buffer.
  581:  *
  582:  * Check for interrupted write call added.
  583:  */
  584: 
  585: static	int
  586: lptclose(dev_t dev, int flags, int fmt, struct thread *p)
  587: {
  588: 	u_int unit = LPTUNIT(minor(dev));
  589: 	struct lpt_data *sc = UNITOSOFTC(unit);
  590: 	device_t lptdev = UNITODEVICE(unit);
  591:         device_t ppbus = device_get_parent(lptdev);
  592: 	int err;
  593: 
  594: 	if(sc->sc_flags & LP_BYPASS)
  595: 		goto end_close;
  596: 
  597: 	if ((err = lpt_request_ppbus(lptdev, PPB_WAIT|PPB_INTR)) != 0)
  598: 		return (err);
  599: 
  600: 	sc->sc_state &= ~OPEN;
  601: 
  602: 	/* if the last write was interrupted, don't complete it */
  603: 	if((!(sc->sc_state  & INTERRUPTED)) && (sc->sc_irq & LP_USE_IRQ))
  604: 		while ((ppb_rstr(ppbus) &
  605: 			(LPS_SEL|LPS_OUT|LPS_NBSY|LPS_NERR)) !=
  606: 			(LPS_SEL|LPS_NBSY|LPS_NERR) || sc->sc_xfercnt)
  607: 			/* wait 1/4 second, give up if we get a signal */
  608: 			if (tsleep((caddr_t)lptdev, PCATCH,
  609: 				"lpclose", hz) != EWOULDBLOCK)
  610: 				break;
  611: 
  612: 	ppb_wctr(ppbus, LPC_NINIT);
  613: 	free(sc->sc_inbuf, M_LPT);
  614: 	free(sc->sc_statbuf, M_LPT);
  615: 
  616: end_close:
  617: 	/* release the bus anyway
  618: 	 * unregistration of interrupt forced by release
  619: 	 */
  620: 	lpt_release_ppbus(lptdev);
  621: 
  622: 	sc->sc_state = 0;
  623: 	sc->sc_xfercnt = 0;
  624: 	lprintf(("closed.\n"));
  625: 	return(0);
  626: }
  627: 
  628: /*
  629:  * lpt_pushbytes()
  630:  *	Workhorse for actually spinning and writing bytes to printer
  631:  *	Derived from lpa.c
  632:  *	Originally by ?
  633:  *
  634:  *	This code is only used when we are polling the port
  635:  */
  636: static int
  637: lpt_pushbytes(device_t dev)
  638: {
  639: 	struct lpt_data *sc = DEVTOSOFTC(dev);
  640: 	device_t ppbus = device_get_parent(dev);
  641: 	int spin, err, tic;
  642: 	char ch;
  643: 
  644: 	lprintf(("p"));
  645: 	/* loop for every character .. */
  646: 	while (sc->sc_xfercnt > 0) {
  647: 		/* printer data */
  648: 		ch = *(sc->sc_cp);
  649: 		sc->sc_cp++;
  650: 		sc->sc_xfercnt--;
  651: 
  652: 		/*
  653: 		 * Wait for printer ready.
  654: 		 * Loop 20 usecs testing BUSY bit, then sleep
  655: 		 * for exponentially increasing timeout. (vak)
  656: 		 */
  657: 		for (spin = 0; NOT_READY(ppbus) && spin < MAX_SPIN; ++spin)
  658: 			DELAY(1);	/* XXX delay is NOT this accurate! */
  659: 		if (spin >= MAX_SPIN) {
  660: 			tic = 0;
  661: 			while (NOT_READY(ppbus)) {
  662: 				/*
  663: 				 * Now sleep, every cycle a
  664: 				 * little longer ..
  665: 				 */
  666: 				tic = tic + tic + 1;
  667: 				/*
  668: 				 * But no more than 10 seconds. (vak)
  669: 				 */
  670: 				if (tic > MAX_SLEEP)
  671: 					tic = MAX_SLEEP;
  672: 				err = tsleep((caddr_t)dev, 0,
  673: 					LPT_NAME "poll", tic);
  674: 				if (err != EWOULDBLOCK) {
  675: 					return (err);
  676: 				}
  677: 			}
  678: 		}
  679: 
  680: 		/* output data */
  681: 		ppb_wdtr(ppbus, ch);
  682: 		/* strobe */
  683: 		ppb_wctr(ppbus, sc->sc_control|LPC_STB);
  684: 		ppb_wctr(ppbus, sc->sc_control);
  685: 
  686: 	}
  687: 	return(0);
  688: }
  689: 
  690: /*
  691:  * lptread --retrieve printer status in IEEE1284 NIBBLE mode
  692:  */
  693: 
  694: static int
  695: lptread(dev_t dev, struct uio *uio, int ioflag)
  696: {
  697:         u_int	unit = LPTUNIT(minor(dev));
  698: 	struct lpt_data *sc = UNITOSOFTC(unit);
  699: 	device_t lptdev = UNITODEVICE(unit);
  700:         device_t ppbus = device_get_parent(lptdev);
  701: 	int error = 0, len;
  702: 
  703: 	if (sc->sc_flags & LP_BYPASS) {
  704: 		/* we can't do reads in bypass mode */
  705: 		return (EPERM);
  706: 	}
  707: 
  708: 	if ((error = ppb_1284_negociate(ppbus, PPB_NIBBLE, 0)))
  709: 		return (error);
  710: 
  711: 	/* read data in an other buffer, read/write may be simultaneous */
  712: 	len = 0;
  713: 	while (uio->uio_resid) {
  714: 		if ((error = ppb_1284_read(ppbus, PPB_NIBBLE,
  715: 				sc->sc_statbuf, min(BUFSTATSIZE,
  716: 				uio->uio_resid), &len))) {
  717: 			goto error;
  718: 		}
  719: 
  720: 		if (!len)
  721: 			goto error;		/* no more data */
  722: 
  723: 		if ((error = uiomove(sc->sc_statbuf, len, uio)))
  724: 			goto error;
  725: 	}
  726: 
  727: error:
  728: 	ppb_1284_terminate(ppbus);
  729: 	return (error);
  730: }
  731: 
  732: /*
  733:  * lptwrite --copy a line from user space to a local buffer, then call
  734:  * putc to get the chars moved to the output queue.
  735:  *
  736:  * Flagging of interrupted write added.
  737:  */
  738: 
  739: static	int
  740: lptwrite(dev_t dev, struct uio *uio, int ioflag)
  741: {
  742: 	unsigned n;
  743: 	int err;
  744:         u_int	unit = LPTUNIT(minor(dev));
  745: 	struct lpt_data *sc = UNITOSOFTC(unit);
  746: 	device_t lptdev = UNITODEVICE(unit);
  747:         device_t ppbus = device_get_parent(lptdev);
  748: 
  749: 	if(sc->sc_flags & LP_BYPASS) {
  750: 		/* we can't do writes in bypass mode */
  751: 		return(EPERM);
  752: 	}
  753: 
  754: 	/* request the ppbus only if we don't have it already */
  755: 	/* XXX interrupt registration?! */
  756: 	if ((err = lpt_request_ppbus(lptdev, PPB_WAIT|PPB_INTR)) != 0)
  757: 		return (err);
  758: 
  759: 	/* if interrupts are working, register the handler */
  760: 	if (sc->sc_irq & LP_USE_IRQ) {
  761: 		/* register our interrupt handler */
  762: 		err = BUS_SETUP_INTR(ppbus, lptdev, sc->intr_resource,
  763: 			       INTR_TYPE_TTY, lpt_intr, lptdev,
  764: 			       &sc->intr_cookie);
  765: 		if (err) {
  766: 			device_printf(lptdev, "handler registration failed, polled mode.\n");
  767: 			sc->sc_irq &= ~LP_USE_IRQ;
  768: 		}
  769: 	}
  770: 
  771: 	sc->sc_state &= ~INTERRUPTED;
  772: 	while ((n = min(BUFSIZE, uio->uio_resid)) != 0) {
  773: 		sc->sc_cp = sc->sc_inbuf;
  774: 		uiomove(sc->sc_cp, n, uio);
  775: 		sc->sc_xfercnt = n ;
  776: 
  777: 		if (sc->sc_irq & LP_ENABLE_EXT) {
  778: 			/* try any extended mode */
  779: 			err = ppb_write(ppbus, sc->sc_cp,
  780: 					sc->sc_xfercnt, 0);
  781: 			switch (err) {
  782: 			case 0:
  783: 				/* if not all data was sent, we could rely
  784: 				 * on polling for the last bytes */
  785: 				sc->sc_xfercnt = 0;
  786: 				break;
  787: 			case EINTR:
  788: 				sc->sc_state |= INTERRUPTED;	
  789: 				return(err);
  790: 			case EINVAL:
  791: 				/* advanced mode not avail */
  792: 				log(LOG_NOTICE, LPT_NAME "%d: advanced mode not avail, polling\n", unit);
  793: 				break;
  794: 			default:
  795: 				return(err);
  796: 			}
  797: 		} else while ((sc->sc_xfercnt > 0)&&(sc->sc_irq & LP_USE_IRQ)) {
  798: 			lprintf(("i"));
  799: 			/* if the printer is ready for a char, */
  800: 			/* give it one */
  801: 			if ((sc->sc_state & OBUSY) == 0){
  802: 				lprintf(("\nC %d. ", sc->sc_xfercnt));
  803: 				lptintr(lptdev);
  804: 			}
  805: 			lprintf(("W "));
  806: 			if (sc->sc_state & OBUSY)
  807: 				if ((err = tsleep((caddr_t)lptdev,
  808: 					 PCATCH, LPT_NAME "write", 0))) {
  809: 					sc->sc_state |= INTERRUPTED;
  810: 					return(err);
  811: 				}
  812: 		}
  813: 
  814: 		/* check to see if we must do a polled write */
  815: 		if(!(sc->sc_irq & LP_USE_IRQ) && (sc->sc_xfercnt)) {
  816: 			lprintf(("p"));
  817: 
  818: 			err = lpt_pushbytes(lptdev);
  819: 
  820: 			if (err)
  821: 				return(err);
  822: 		}
  823: 	}
  824: 
  825: 	/* we have not been interrupted, release the ppbus */
  826: 	lpt_release_ppbus(lptdev);
  827: 
  828: 	return(0);
  829: }
  830: 
  831: /*
  832:  * lpt_intr -- handle printer interrupts which occur when the printer is
  833:  * ready to accept another char.
  834:  *
  835:  * do checking for interrupted write call.
  836:  */
  837: 
  838: static void
  839: lpt_intr(void *arg)
  840: {
  841: 	device_t lptdev = (device_t)arg;
  842:         device_t ppbus = device_get_parent(lptdev);
  843: 	struct lpt_data *sc = DEVTOSOFTC(lptdev);
  844: 	int sts = 0;
  845: 	int i;
  846: 	
  847: 	/* we must own the bus to use it */
  848: 	if ((sc->sc_state & HAVEBUS) == 0)
  849: 		return;
  850: 
  851: 	/*
  852: 	 * Is printer online and ready for output?
  853: 	 *
  854: 	 * Avoid falling back to lptout() too quickly.  First spin-loop
  855: 	 * to see if the printer will become ready ``really soon now''.
  856: 	 */
  857: 	for (i = 0; i < 100 &&
  858: 	     ((sts=ppb_rstr(ppbus)) & RDY_MASK) != LP_READY; i++) ;
  859: 
  860: 	if ((sts & RDY_MASK) == LP_READY) {
  861: 		sc->sc_state = (sc->sc_state | OBUSY) & ~EERROR;
  862: 		sc->sc_backoff = hz/LPTOUTINITIAL;
  863: 
  864: 		if (sc->sc_xfercnt) {
  865: 			/* send char */
  866: 			/*lprintf(("%x ", *sc->sc_cp)); */
  867: 			ppb_wdtr(ppbus, *sc->sc_cp++) ;
  868: 			ppb_wctr(ppbus, sc->sc_control|LPC_STB);
  869: 			/* DELAY(X) */
  870: 			ppb_wctr(ppbus, sc->sc_control);
  871: 
  872: 			/* any more data for printer */
  873: 			if(--(sc->sc_xfercnt) > 0) return;
  874: 		}
  875: 
  876: 		/*
  877: 		 * No more data waiting for printer.
  878: 		 * Wakeup is not done if write call was not interrupted.
  879: 		 */
  880: 		sc->sc_state &= ~OBUSY;
  881: 
  882: 		if(!(sc->sc_state & INTERRUPTED))
  883: 			wakeup((caddr_t)lptdev);
  884: 		lprintf(("w "));
  885: 		return;
  886: 	} else	{	/* check for error */
  887: 		if(((sts & (LPS_NERR | LPS_OUT) ) != LPS_NERR) &&
  888: 				(sc->sc_state & OPEN))
  889: 			sc->sc_state |= EERROR;
  890: 		/* lptout() will jump in and try to restart. */
  891: 	}
  892: 	lprintf(("sts %x ", sts));
  893: }
  894: 
  895: static void
  896: lptintr(device_t dev)
  897: {
  898: 	/* call the interrupt at required spl level */
  899: 	int s = spltty();
  900: 
  901: 	lpt_intr(dev);
  902: 
  903: 	splx(s);
  904: 	return;
  905: }
  906: 
  907: static	int
  908: lptioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct thread *p)
  909: {
  910: 	int	error = 0;
  911:         u_int	unit = LPTUNIT(minor(dev));
  912:         struct	lpt_data *sc = UNITOSOFTC(unit);
  913: 	u_char	old_sc_irq;	/* old printer IRQ status */
  914: 
  915: 	switch (cmd) {
  916: 	case LPT_IRQ :
  917: 		if(sc->sc_irq & LP_HAS_IRQ) {
  918: 			/*
  919: 			 * NOTE:
  920: 			 * If the IRQ status is changed,
  921: 			 * this will only be visible on the
  922: 			 * next open.
  923: 			 *
  924: 			 * If interrupt status changes,
  925: 			 * this gets syslog'd.
  926: 			 */
  927: 			old_sc_irq = sc->sc_irq;
  928: 			switch(*(int*)data) {
  929: 			case 0:
  930: 				sc->sc_irq &= (~LP_ENABLE_IRQ);
  931: 				break;
  932: 			case 1:
  933: 				sc->sc_irq &= (~LP_ENABLE_EXT);
  934: 				sc->sc_irq |= LP_ENABLE_IRQ;
  935: 				break;
  936: 			case 2:
  937: 				/* classic irq based transfer and advanced
  938: 				 * modes are in conflict
  939: 				 */
  940: 				sc->sc_irq &= (~LP_ENABLE_IRQ);
  941: 				sc->sc_irq |= LP_ENABLE_EXT;
  942: 				break;
  943: 			case 3:
  944: 				sc->sc_irq &= (~LP_ENABLE_EXT);
  945: 				break;
  946: 			default:
  947: 				break;
  948: 			}
  949: 				
  950: 			if (old_sc_irq != sc->sc_irq )
  951: 				log(LOG_NOTICE, LPT_NAME "%d: switched to %s %s mode\n",
  952: 					unit,
  953: 					(sc->sc_irq & LP_ENABLE_IRQ)?
  954: 					"interrupt-driven":"polled",
  955: 					(sc->sc_irq & LP_ENABLE_EXT)?
  956: 					"extended":"standard");
  957: 		} else /* polled port */
  958: 			error = EOPNOTSUPP;
  959: 		break;
  960: 	default:
  961: 		error = ENODEV;
  962: 	}
  963: 
  964: 	return(error);
  965: }
  966: 
  967: static device_method_t lpt_methods[] = {
  968: 	/* device interface */
  969: 	DEVMETHOD(device_identify,	lpt_identify),
  970: 	DEVMETHOD(device_probe,		lpt_probe),
  971: 	DEVMETHOD(device_attach,	lpt_attach),
  972: 
  973: 	{ 0, 0 }
  974: };
  975: 
  976: static driver_t lpt_driver = {
  977: 	LPT_NAME,
  978: 	lpt_methods,
  979: 	sizeof(struct lpt_data),
  980: };
  981: 
  982: DRIVER_MODULE(lpt, ppbus, lpt_driver, lpt_devclass, 0, 0);