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