|
|
1.1 ! root 1: /* ! 2: * Mach Operating System ! 3: * Copyright (c) 1993-1990 Carnegie Mellon University ! 4: * All Rights Reserved. ! 5: * ! 6: * Permission to use, copy, modify and distribute this software and its ! 7: * documentation is hereby granted, provided that both the copyright ! 8: * notice and this permission notice appear in all copies of the ! 9: * software, derivative works or modified versions, and any portions ! 10: * thereof, and that both notices appear in supporting documentation. ! 11: * ! 12: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" ! 13: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR ! 14: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ! 15: * ! 16: * Carnegie Mellon requests users of this software to return to ! 17: * ! 18: * Software Distribution Coordinator or [email protected] ! 19: * School of Computer Science ! 20: * Carnegie Mellon University ! 21: * Pittsburgh PA 15213-3890 ! 22: * ! 23: * any improvements or extensions that they make and grant Carnegie Mellon ! 24: * the rights to redistribute these changes. ! 25: */ ! 26: /* ! 27: * Parallel port printer driver v1.0 ! 28: * All rights reserved. ! 29: */ ! 30: ! 31: #include <lpr.h> ! 32: #if NLPR > 0 ! 33: #include <par.h> ! 34: #include <de6c.h> ! 35: ! 36: #ifdef MACH_KERNEL ! 37: #include <mach/std_types.h> ! 38: #include <sys/types.h> ! 39: #include <sys/time.h> ! 40: #include <device/conf.h> ! 41: #include <device/errno.h> ! 42: #include <device/tty.h> ! 43: #include <device/io_req.h> ! 44: #else MACH_KERNEL ! 45: #include <sys/param.h> ! 46: #include <sys/conf.h> ! 47: #include <sys/dir.h> ! 48: #include <sys/user.h> ! 49: #include <sys/proc.h> ! 50: #include <sys/ioctl.h> ! 51: #include <sys/tty.h> ! 52: #include <sys/systm.h> ! 53: #include <sys/uio.h> ! 54: #include <sys/file.h> ! 55: #endif MACH_KERNEL ! 56: ! 57: #include <i386/ipl.h> ! 58: #include <i386/pio.h> ! 59: #include <chips/busses.h> ! 60: #include <i386at/lprreg.h> ! 61: ! 62: #if NPAR > 0 ! 63: extern int parattach(); ! 64: #endif ! 65: ! 66: #if NDE6C > 0 ! 67: extern int de6cattach(); ! 68: #endif ! 69: ! 70: extern void splx(); ! 71: extern spl_t spltty(); ! 72: extern void timeout(); ! 73: extern void ttrstrt(); ! 74: ! 75: /* ! 76: * Driver information for auto-configuration stuff. ! 77: */ ! 78: ! 79: int lprprobe(), lprintr(), lprstart(), lprstop(); ! 80: void lprattach(struct bus_device *); ! 81: #ifdef MACH_KERNEL ! 82: int lprstop(), lprgetstat(), lprsetstat(); ! 83: #endif MACH_KERNEL ! 84: ! 85: struct bus_device *lprinfo[NLPR]; /* ??? */ ! 86: ! 87: static vm_offset_t lpr_std[NLPR] = { 0 }; ! 88: static struct bus_device *lpr_info[NLPR]; ! 89: struct bus_driver lprdriver = { ! 90: lprprobe, 0, lprattach, 0, lpr_std, "lpr", lpr_info, 0, 0, 0}; ! 91: ! 92: struct tty lpr_tty[NLPR]; ! 93: ! 94: int lpr_alive[NLPR]; ! 95: ! 96: lprprobe(port, dev) ! 97: struct bus_device *dev; ! 98: { ! 99: u_short addr = (u_short) dev->address; ! 100: int unit = dev->unit; ! 101: int ret; ! 102: ! 103: if ((unit < 0) || (unit > NLPR)) { ! 104: printf("com %d out of range\n", unit); ! 105: return(0); ! 106: } ! 107: ! 108: outb(INTR_ENAB(addr),0x07); ! 109: outb(DATA(addr),0xaa); ! 110: ret = inb(DATA(addr)) == 0xaa; ! 111: if (ret) { ! 112: if (lpr_alive[unit]) { ! 113: printf("lpr: Multiple alive entries for unit %d.\n", unit); ! 114: printf("lpr: Ignoring entry with address = %x .\n", addr); ! 115: ret = 0; ! 116: } else ! 117: lpr_alive[unit]++; ! 118: } ! 119: return(ret); ! 120: } ! 121: ! 122: void lprattach(struct bus_device *dev) ! 123: { ! 124: u_char unit = dev->unit; ! 125: u_short addr = (u_short) dev->address; ! 126: struct tty *tp = &lpr_tty[unit]; ! 127: ! 128: take_dev_irq(dev); ! 129: printf(", port = %x, spl = %d, pic = %d.", ! 130: dev->address, dev->sysdep, dev->sysdep1); ! 131: lprinfo[unit] = dev; ! 132: ! 133: outb(INTR_ENAB(addr), inb(INTR_ENAB(addr)) & 0x0f); ! 134: ! 135: #if NPAR > 0 ! 136: parattach(dev); ! 137: #endif ! 138: ! 139: #if NDE6C > 0 && !defined(LINUX_DEV) ! 140: de6cattach(dev); ! 141: #endif ! 142: return; ! 143: } ! 144: ! 145: lpropen(dev, flag, ior) ! 146: int dev; ! 147: int flag; ! 148: #ifdef MACH_KERNEL ! 149: io_req_t ior; ! 150: #endif MACH_KERNEL ! 151: { ! 152: int unit = minor(dev); ! 153: struct bus_device *isai; ! 154: struct tty *tp; ! 155: u_short addr; ! 156: ! 157: if (unit >= NLPR || (isai = lprinfo[unit]) == 0 || isai->alive == 0) ! 158: return(ENXIO); ! 159: tp = &lpr_tty[unit]; ! 160: #ifndef MACH_KERNEL ! 161: if (tp->t_state & TS_XCLUDE && u.u_uid != 0) ! 162: return(EBUSY); ! 163: #endif MACH_KERNEL ! 164: addr = (u_short) isai->address; ! 165: tp->t_dev = dev; ! 166: tp->t_addr = *(caddr_t *)&addr; ! 167: tp->t_oproc = lprstart; ! 168: tp->t_state |= TS_WOPEN; ! 169: #ifdef MACH_KERNEL ! 170: tp->t_stop = lprstop; ! 171: tp->t_getstat = lprgetstat; ! 172: tp->t_setstat = lprsetstat; ! 173: #endif MACH_KERNEL ! 174: if ((tp->t_state & TS_ISOPEN) == 0) ! 175: ttychars(tp); ! 176: outb(INTR_ENAB(addr), inb(INTR_ENAB(addr)) | 0x10); ! 177: tp->t_state |= TS_CARR_ON; ! 178: return (char_open(dev, tp, flag, ior)); ! 179: } ! 180: ! 181: lprclose(dev, flag) ! 182: int dev; ! 183: int flag; ! 184: { ! 185: int unit = minor(dev); ! 186: struct tty *tp = &lpr_tty[unit]; ! 187: u_short addr = (u_short) lprinfo[unit]->address; ! 188: ! 189: #ifndef MACH_KERNEL ! 190: (*linesw[tp->t_line].l_close)(tp); ! 191: #endif MACH_KERNEL ! 192: ttyclose(tp); ! 193: if (tp->t_state&TS_HUPCLS || (tp->t_state&TS_ISOPEN)==0) { ! 194: outb(INTR_ENAB(addr), inb(INTR_ENAB(addr)) & 0x0f); ! 195: tp->t_state &= ~TS_BUSY; ! 196: } ! 197: } ! 198: ! 199: #ifdef MACH_KERNEL ! 200: lprread(dev, ior) ! 201: int dev; ! 202: io_req_t ior; ! 203: { ! 204: return char_read(&lpr_tty[minor(dev)], ior); ! 205: } ! 206: ! 207: lprwrite(dev, ior) ! 208: int dev; ! 209: io_req_t ior; ! 210: { ! 211: return char_write(&lpr_tty[minor(dev)], ior); ! 212: } ! 213: ! 214: lprportdeath(dev, port) ! 215: dev_t dev; ! 216: mach_port_t port; ! 217: { ! 218: return (tty_portdeath(&lpr_tty[minor(dev)], port)); ! 219: } ! 220: ! 221: io_return_t ! 222: lprgetstat(dev, flavor, data, count) ! 223: dev_t dev; ! 224: int flavor; ! 225: int *data; /* pointer to OUT array */ ! 226: unsigned int *count; /* out */ ! 227: { ! 228: io_return_t result = D_SUCCESS; ! 229: int unit = minor(dev); ! 230: ! 231: switch (flavor) { ! 232: default: ! 233: result = tty_get_status(&lpr_tty[unit], flavor, data, count); ! 234: break; ! 235: } ! 236: return (result); ! 237: } ! 238: ! 239: io_return_t ! 240: lprsetstat(dev, flavor, data, count) ! 241: dev_t dev; ! 242: int flavor; ! 243: int * data; ! 244: unsigned int count; ! 245: { ! 246: io_return_t result = D_SUCCESS; ! 247: int unit = minor(dev); ! 248: u_short dev_addr = (u_short) lprinfo[unit]->address; ! 249: int s; ! 250: ! 251: switch (flavor) { ! 252: default: ! 253: result = tty_set_status(&lpr_tty[unit], flavor, data, count); ! 254: /* if (result == D_SUCCESS && flavor == TTY_STATUS) ! 255: lprparam(unit); ! 256: */ return (result); ! 257: } ! 258: return (D_SUCCESS); ! 259: } ! 260: #else MACH_KERNEL ! 261: int lprwrite(dev, uio) ! 262: int dev; ! 263: struct uio *uio; ! 264: { ! 265: struct tty *tp= &lpr_tty[minor(dev)]; ! 266: ! 267: return ((*linesw[tp->t_line].l_write)(tp, uio)); ! 268: } ! 269: ! 270: int lprioctl(dev, cmd, addr, mode) ! 271: int dev; ! 272: int cmd; ! 273: caddr_t addr; ! 274: int mode; ! 275: { ! 276: int error; ! 277: spl_t s; ! 278: int unit = minor(dev); ! 279: struct tty *tp = &lpr_tty[unit]; ! 280: ! 281: error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr,mode); ! 282: if (error >= 0) ! 283: return(error); ! 284: error = ttioctl(tp, cmd, addr,mode); ! 285: if (error >= 0) ! 286: return (error); ! 287: s = spltty(); ! 288: switch (cmd) { ! 289: default: ! 290: splx(s); ! 291: return(ENOTTY); ! 292: } ! 293: splx(s); ! 294: return(0); ! 295: } ! 296: #endif MACH_KERNEL ! 297: ! 298: int lprintr(unit) ! 299: int unit; ! 300: { ! 301: register struct tty *tp = &lpr_tty[unit]; ! 302: ! 303: if ((tp->t_state & TS_ISOPEN) == 0) ! 304: return; ! 305: ! 306: tp->t_state &= ~TS_BUSY; ! 307: if (tp->t_state&TS_FLUSH) ! 308: tp->t_state &=~TS_FLUSH; ! 309: tt_write_wakeup(tp); ! 310: lprstart(tp); ! 311: } ! 312: ! 313: int lprstart(tp) ! 314: struct tty *tp; ! 315: { ! 316: spl_t s = spltty(); ! 317: u_short addr = (natural_t) tp->t_addr; ! 318: int status = inb(STATUS(addr)); ! 319: char nch; ! 320: ! 321: if (tp->t_state & (TS_TIMEOUT|TS_TTSTOP|TS_BUSY)) { ! 322: splx(s); ! 323: return(0); ! 324: } ! 325: ! 326: if (status & 0x20) { ! 327: printf("Printer out of paper!\n"); ! 328: splx(s); ! 329: return(0); ! 330: } ! 331: ! 332: if (tp->t_outq.c_cc <= TTLOWAT(tp)) { ! 333: #ifdef MACH_KERNEL ! 334: tt_write_wakeup(tp); ! 335: #else MACH_KERNEL ! 336: if (tp->t_state & TS_ASLEEP) { ! 337: tp->t_state &= ~TS_ASLEEP; ! 338: wakeup ((caddr_t)&tp->t_outq); ! 339: } ! 340: if (tp->t_wsel) { ! 341: selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); ! 342: tp->t_wsel = 0; ! 343: tp->t_state &= ~TS_WCOLL; ! 344: } ! 345: #endif MACH_KERNEL ! 346: } ! 347: if (tp->t_outq.c_cc == 0) { ! 348: splx(s); ! 349: return(0); ! 350: } ! 351: #ifdef MACH_KERNEL ! 352: nch = getc(&tp->t_outq); ! 353: if ((tp->t_flags & LITOUT) == 0 && (nch & 0200)) { ! 354: timeout(ttrstrt, (char *)tp, (nch & 0x7f) + 6); ! 355: tp->t_state |= TS_TIMEOUT; ! 356: return; ! 357: } ! 358: outb(DATA(addr), nch); ! 359: outb(INTR_ENAB(addr),inb(INTR_ENAB(addr)) | 0x01); ! 360: outb(INTR_ENAB(addr),inb(INTR_ENAB(addr)) & 0x1e); ! 361: tp->t_state |= TS_BUSY; ! 362: #else MACH_KERNEL ! 363: if (tp->t_flags & (RAW|LITOUT)) ! 364: nch = ndqb(&tp->t_outq,0); ! 365: else { ! 366: nch = ndqb(&tp->t_outq, 0200); ! 367: if (nch == 0) { ! 368: nch = getc(&tp->t_outq); ! 369: timeout(ttrstrt,(caddr_t)tp,(nch&0x7f)+6); ! 370: tp->t_state |= TS_TIMEOUT; ! 371: splx(s); ! 372: return(0); ! 373: } ! 374: } ! 375: if (nch) { ! 376: nch=getc(&tp->t_outq); ! 377: outb(DATA(addr), nch); ! 378: outb(INTR_ENAB(addr),inb(INTR_ENAB(addr)) | 0x01); ! 379: outb(INTR_ENAB(addr),inb(INTR_ENAB(addr)) & 0x1e); ! 380: tp->t_state |= TS_BUSY; ! 381: } ! 382: #endif MACH_KERNEL ! 383: splx(s); ! 384: return(0); ! 385: } ! 386: ! 387: #ifdef MACH_KERNEL ! 388: lprstop(tp, flags) ! 389: register struct tty *tp; ! 390: int flags; ! 391: { ! 392: if ((tp->t_state & TS_BUSY) && (tp->t_state & TS_TTSTOP) == 0) ! 393: tp->t_state |= TS_FLUSH; ! 394: } ! 395: #else MACH_KERNEL ! 396: int lprstop(tp, flag) ! 397: struct tty *tp; ! 398: { ! 399: int s = spltty(); ! 400: ! 401: if ((tp->t_state&TS_BUSY) && (!(tp->t_state&TS_TTSTOP))) ! 402: tp->t_state |= TS_FLUSH; ! 403: splx(s); ! 404: } ! 405: #endif MACH_KERNEL ! 406: lprpr(unit) ! 407: { ! 408: lprpr_addr(lprinfo[unit]->address); ! 409: return 0; ! 410: } ! 411: ! 412: lprpr_addr(addr) ! 413: { ! 414: printf("DATA(%x) %x, STATUS(%x) %x, INTR_ENAB(%x) %x\n", ! 415: DATA(addr), inb(DATA(addr)), ! 416: STATUS(addr), inb(STATUS(addr)), ! 417: INTR_ENAB(addr), inb(INTR_ENAB(addr))); ! 418: } ! 419: #endif NLPR
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.