/dev/io или управление lptом (linux driver example)
Ключевые слова: linux, driver, example, (найти похожие документы)
_ RU.UNIX.BSD (2:5077/15.22) _____________________________________ RU.UNIX.BSD _
From : vadik likholetov 2:5030/266 Wed 30 Dec 98 17:06
Subj : /dev/io или управление lptом
________________________________________________________________________________
кто-то там просил -- возьмите осмысленный драйвер, с которого можно
начать ;-)
/*
* Power controller (c) 1998, vadik likholetov vadik@sensi.org Hardware by
* Alexandr Priomov, alexandr@sensi.org
*/
static int
pwc_open(dev_t dev, int flags, int fmt, struct proc * p)
{
struct pwc_softc *sc;
u_int unit = minor(dev);
sc = pwc_sc + unit;
if ((unit >= NPWC) || (sc->sc_port == 0))
return ENXIO;
if (sc->sc_state != DEFAULT)
return EBUSY;
return 0;
}
static int
pwc_close(dev_t dev, int flags, int fmt, struct proc * p)
{
struct pwc_softc *sc = pwc_sc + minor(dev);
sc->sc_state &= ~OPEN;
while (sc->sc_state & OBUSY)
if (tsleep((caddr_t) sc, PZERO | PCATCH, "pwcclose", hz) != EWOULDBLOCK)
break;
sc->sc_state = DEFAULT;
return 0;
}
static int
pwc_write(dev_t dev, struct uio * uio, int ioflag)
{
struct pwc_softc *sc = pwc_sc + minor(dev);
char buffer[TASK_SIZE];
int port = sc->sc_port;
int s;
int ret;
int i, j, d;
if (uio->uio_resid != TASK_SIZE)
return EOPNOTSUPP;
s = spltty();
if (sc->sc_state & OBUSY)
return EBUSY;
sc->sc_state |= OBUSY;
splx(s);
/* output goes there */
uiomove(buffer, TASK_SIZE, uio);
if (!(inb(port + lpt_status) & ~LPS_NACK)) {
printf("pwc%d: no power on devicen", minor(dev));
ret = EIO;
goto gout;
}
#define NTRIES 10
for (i = 0; i < TASK_SIZE; i++) {
for (j = 0; j < NTRIES; j++)
if ((inb(port + lpt_status) & LPS_NBSY))
break;
else
DELAY(1);
if (j == NTRIES) {
printf("pwc%d: timeout(1) waiting for ~BSY (%x)n",
minor(dev),inb(port+lpt_status));
ret = EIO;
goto gout;
}
d = buffer[i] == '1' ? 1 : 0;