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