home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.unix.bsd
- Path: sparky!uunet!munnari.oz.au!uniwa!cujo!marsh!cproto
- From: cproto@marsh.cs.curtin.edu.au (Computer Protocol)
- Subject: 386bsd 0.1 printer driver source resubmitted
- Message-ID: <cproto.715011443@marsh>
- Summary: 386bsd printer driver source resubmitted
- Keywords: 386bsd /dev/lp0 lpt printer parallel port
- Sender: news@cujo.curtin.edu.au (News Manager)
- Organization: Curtin University of Technology
- Date: Fri, 28 Aug 1992 14:17:23 GMT
- Lines: 585
-
-
- Hi there,
-
- as a number of people requested it, I resubmit my trivial but working
- printer driver.
-
- Add file lp.c and apply the other changes.
-
- Do the following:
-
- config YOURCONF
- cd ../../compile/YOURCONF
- make depend
- make
- mv /386bsd /386bsd.save
- mv 386bsd /
-
- Create the device entry by doing a
-
- mknod /dev/lp0 c 14 0
-
- Reboot using:
-
- sync;sync;fastboot
-
- Print using something like:
-
- cat printfile > /dev/lp0
-
- Have fun
-
- Regards - Tibor Sashegyi - cproto@abel.cs.curtin.edu.au
-
- ------------- /sys/i386/isa/lp.c --------------
-
- /*
- ** parallel port printer driver
- ** by Tibor Sashegyi 19/04/92
- ** (ideas from everywhere)
- ** stage 2
- */
-
- #include "lp.h"
-
- #if NLP > 0
-
- #include "param.h"
- #include "systm.h"
- #include "proc.h"
- #include "user.h"
- #include "conf.h"
- #include "file.h"
- #include "uio.h"
- #include "kernel.h"
- #include "syslog.h"
- #include "buf.h"
-
- #include "i386/isa/isa_device.h"
-
- /*
- ** printer port base addresses
- */
-
-
- #define LPB_1_BASE 0x378 /* base i/o address printer 1 */
- #define LPB_2_BASE 0x3BC /* base i/o address printer 2 */
- #define LPB_3_BASE 0x278 /* base i/o address printer 3 */
-
- /*
- ** i/o registers
- */
-
- #define LPR_DATA 0x00 /* data register */
- #define LPR_STAT 0x01 /* status register */
- #define LPR_CTRL 0x02 /* control register */
-
- /*
- ** control bits
- */
-
- #define LPC_INIT 0x08 /* select and init printer */
- #define LPC_STROBE 0x1D /* strobe data */
- #define LPC_READY 0x1C /* idle IRQ enabled */
- #define LPC_SELECT 0x0C /* select */
-
- /*
- ** status bits
- */
-
- #define LPS_ERROR 0x08 /* 0 general error */
- #define LPS_SELECT 0x10 /* 1 selected */
- #define LPS_PAPER 0x20 /* 1 out of paper */
- #define LPS_BUSY 0x80 /* 0 busy */
-
- /*
- ** lp control block
- */
-
- #define LPF_ACTIVE 0x01
- #define LPF_OPEN 0x02
- #define LPF_BUSY 0x04
- #define LPF_PAPER 0x08
- #define LPF_ERROR 0x10
-
- #define MAXBUF 0x100
-
- struct lpctrl
- {
- int unit;
- int port;
- char flags;
- int error;
- int count;
- char *cp;
- char buf[MAXBUF];
- } lp_ctrl[NLP];
-
- /*
- ** misc
- */
-
- #define LPWATCH 1
-
- int lpprobe(), lpattach(), lpphysio(), lpstrategy();
- void lpwatchdog(), lpintr(), lpiowait(), lpiodone();
-
- /*
- ** define autoconfig entries
- */
-
- struct isa_driver lpdriver =
- {
- lpprobe, lpattach, "lp"
- };
-
- #define UNIT(x) minor(x)
-
- /*
- ** the following delay value is about right for my machine
- ** fix it for anything else
- */
-
- #define CPUSPEED 7
- #define LPDELAY(n) { register int N = (n) * CPUSPEED; while (--N > 0); }
-
- /*
- ** probe for device
- ** I really should probe for the parallel port
- ** and maybe even the printer, but I trust the
- ** configuration (silly me).
- */
-
- int lpprobe(idev)
- struct isa_device *idev;
- {
- if (idev->id_unit >= NLP)
- return(0);
-
- if ( idev->id_iobase != LPB_1_BASE
- && idev->id_iobase != LPB_2_BASE
- && idev->id_iobase != LPB_3_BASE)
- {
- printf("lp base out of range:%x\n", idev->id_iobase);
- return(0);
- }
-
- return(1);
- }
-
- /*
- ** attach device
- */
-
- int lpattach(idev)
- struct isa_device *idev;
- {
- int unit = idev->id_unit;
- int port = idev->id_iobase;
- struct lpctrl *lpc = &lp_ctrl[unit];
-
-
- lpc->unit = unit;
- lpc->port = port;
- lpc->flags = LPF_ACTIVE;
-
- /*
- ** init printer (pulse width at least 50 us)
- */
-
- outb(port + LPR_CTRL, LPC_INIT);
- LPDELAY(51);
-
- /*
- ** keep selected
- */
-
- outb(port + LPR_CTRL, LPC_SELECT);
-
- return (1);
- }
-
- /*
- ** open device
- */
-
- lpopen(dev, flag, mode, p)
- dev_t dev;
- int flag, mode;
- struct proc *p;
- {
- int unit = UNIT(dev);
- struct lpctrl *lpc = &lp_ctrl[unit];
- char val;
-
- /*
- ** make sure device is configured
- */
-
- if (unit >= NLP || (lpc->flags & LPF_ACTIVE) == 0)
- return(ENXIO);
-
- /*
- ** only one open !
- */
-
- if (lpc->flags & LPF_OPEN)
- return(EBUSY);
-
- /*
- ** check direction
- */
-
- if (flag & FREAD)
- return(ENODEV);
-
- /*
- ** check printer status
- */
-
- val = inb(lpc->port + LPR_STAT);
- if (val & LPS_PAPER)
- {
- uprintf("lp%d: out of paper\n", unit);
- return(EIO);
- }
-
- if ((val & LPS_ERROR) == 0 || (val & LPS_SELECT) == 0)
- {
- uprintf("lp%d: not ready\n", unit);
- return(EIO);
- }
-
- /*
- ** start watchdog timer
- */
-
- timeout(lpwatchdog, lpc, LPWATCH*hz);
-
- /*
- ** enable interrupts and mark as opened
- */
-
- outb(lpc->port + LPR_CTRL, LPC_READY);
- lpc->flags |= LPF_OPEN;
-
- return(0);
- }
-
- /*
- ** close device
- */
-
- int lpclose(dev, flag, mode, p)
- dev_t dev;
- int flag, mode;
- struct proc *p;
- {
- int unit = UNIT(dev);
- struct lpctrl *lpc = &lp_ctrl[unit];
-
- /*
- ** disable interrupts but keep selected, mark as closed
- */
-
- outb(lpc->port + LPR_CTRL, LPC_SELECT);
- lpc->flags &= ~LPF_OPEN;
-
- return(0);
- }
-
- /*
- ** write to device
- */
-
- int lpwrite(dev, uio)
- dev_t dev;
- struct uio *uio;
- {
- return (uioapply(lpphysio, lpstrategy, dev, uio));
- }
-
- /*
- ** check access, lock and call lpstrategy
- ** to output next printer buffer
- */
-
- int lpphysio(strat, dev, off, rw, base, len, p)
- int (*strat)();
- dev_t dev;
- int rw, off;
- caddr_t base;
- int *len;
- struct proc *p;
- {
- int error;
- int rest = *len;
- int cnt;
- caddr_t addr = base;
-
- rw = rw == UIO_READ ? B_READ : 0;
-
- /*
- ** check if accessible
- */
-
- if (rw == B_READ && !useracc(base, *len, B_WRITE))
- return (EFAULT);
-
- if (rw == B_WRITE && !useracc(base, *len, B_READ))
- return (EFAULT);
-
- /*
- ** lock in core
- */
-
- vslock (base, *len);
-
- /*
- ** perform transfer
- */
-
- error = 0;
- while(error == 0 && rest > 0)
- {
- cnt = min(rest, MAXBUF);
- rest -= cnt;
- error = lpstrategy(UNIT(dev), addr, cnt);
- addr += cnt;
- }
-
- /*
- ** unlock
- */
-
- vsunlock (base, *len, 0);
-
- *len = 0;
- return (error);
- }
-
- /*
- ** fetch next buffer and start output
- */
-
- int lpstrategy(unit, addr, len)
- int unit;
- caddr_t addr;
- int len;
- {
- struct lpctrl *lpc = &lp_ctrl[unit];
- int s;
-
- lpc->count = len;
- if (copyin(addr, lpc->buf, len))
- {
- lpiodone(lpc);
- return(EFAULT);
- }
-
- lpc->cp = lpc->buf;
- lpc->flags |= LPF_BUSY;
- lpc->error = 0;
-
- s = splhigh();
- lpintr(unit);
- splx(s);
-
- /*
- ** wait for i/o to complete
- */
-
- lpiowait(lpc);
-
- return(lpc->error);
- }
-
- /*
- ** output next characters until printer becomes busy
- ** interrupt driven except for the first time
- */
-
- void lpintr(unit)
- int unit;
- {
- struct lpctrl *lpc = &lp_ctrl[unit];
- int port = lpc->port;
- char val;
-
- /*
- ** check for spurious interrupt
- */
-
- if (!(lpc->flags & LPF_BUSY))
- return;
-
- /*
- ** any more to print
- */
-
- while (lpc->count)
- {
- val = inb(lpc->port + LPR_STAT);
- if ((val & LPS_BUSY) == 0)
- return;
- /*
- ** output the character
- */
-
- outb(port + LPR_DATA, *lpc->cp++);
- --lpc->count;
-
- /*
- ** valid data must be present for at least 0.5 us
- */
-
- LPDELAY(1);
-
- /*
- ** strobe for 1 us
- */
-
- outb(port + LPR_CTRL, LPC_STROBE);
- LPDELAY(1);
- outb(port + LPR_CTRL, LPC_READY);
-
- /*
- ** valid data must be present for at least 0.5 us
- */
-
- LPDELAY(1);
- }
-
- lpiodone(lpc);
- }
-
- /*
- ** wait for i/o to finish
- */
-
- void lpiowait(lpc)
- struct lpctrl *lpc;
- {
- while (lpc->flags & LPF_BUSY)
- {
- if (lpc->error = tsleep(lpc, PRIBIO|PCATCH, NULL, 0))
- lpc->flags &= ~LPF_BUSY;
- }
- }
-
- /*
- ** wakeup strategy function
- */
-
- void lpiodone(lpc)
- struct lpctrl *lpc;
- {
- lpc->flags &= ~LPF_BUSY;
- wakeup(lpc);
- }
-
- /*
- ** handle watchdog timeout
- */
-
- void lpwatchdog(lpc)
- struct lpctrl *lpc;
- {
- char val;
- int s;
-
- /*
- ** are we still running ?
- */
-
- s = splhigh(); /* bit of an overkill ?!? */
-
- if ((lpc->flags & LPF_OPEN) == 0)
- {
- splx(s);
- return;
- }
-
- /*
- ** check printer status
- */
-
- val = inb(lpc->port + LPR_STAT);
-
- /*
- ** report errors only once
- */
-
- if (val & LPS_PAPER && (lpc->flags & LPF_PAPER) == 0)
- {
- printf("lp%d: out of paper, please fix\n", lpc->unit);
- lpc->flags |= LPF_PAPER;
- }
- if (lpc->flags & LPF_PAPER && (val & LPS_PAPER) == 0)
- lpc->flags &= ~LPF_PAPER;
-
- if ((val & LPS_ERROR) == 0 && (lpc->flags & LPF_ERROR) == 0)
- {
- printf("lp%d: not ready, please fix\n", lpc->unit);
- lpc->flags |= LPF_ERROR;
- }
- if (lpc->flags & LPF_ERROR && (val & LPS_ERROR) == 0)
- lpc->flags &= ~LPF_ERROR;
-
- /*
- ** restart watchdog timer
- */
-
- timeout(lpwatchdog, lpc, LPWATCH*hz);
- splx(s);
- }
-
- #endif
- ----------------- /sys/i386/conf/files.i386 --------------
-
- add this:
-
- i386/isa/lp.c optional lp device-driver
-
- --------------- /sys/i386/conf/YOURCONF -------------------
-
- add this:
-
- device lp0 at isa? port "IO_LPT1" irq 7 vector lpintr
-
- --------------- /sys/i386/i386/conf.c ----------------------
-
- apply the following patch:
-
- *** /sys/i386/i386/conf.c Sat May 30 23:48:08 1992
- --- conf.c Tue Aug 25 22:34:52 1992
- ***************
- *** 165,170 ****
- --- 165,179 ----
- #define com_tty NULL
- #endif
-
- + #include "lp.h"
- + #if NLP > 0
- + int lpopen(),lpclose(),lpwrite();
- + #else
- + #define lpopen enxio
- + #define lpclose enxio
- + #define lpwrite enxio
- + #endif
- +
- int logopen(),logclose(),logread(),logioctl(),logselect();
-
- int ttselect(), seltrue();
- ***************
- *** 214,219 ****
- --- 223,231 ----
- { asopen, asclose, rawread, rawwrite, /*D*/
- asioctl, enodev, nullop, NULL,
- seltrue, enodev, asstrategy },
- + { lpopen, lpclose, enodev, lpwrite, /*E*/
- + enodev, enodev, nullop, NULL,
- + seltrue, enodev, NULL},
- };
- int nchrdev = sizeof (cdevsw) / sizeof (cdevsw[0]);
- -------------------------- end of hack -------------------------
-