Re: [PARPORT] parport driver


Riccardo Facchetti (fizban@tin.it)
Thu, 16 Apr 1998 00:29:23 +0200 (MET DST)


On Tue, 14 Apr 1998, Tim Waugh wrote:

> > ParportWrite() - Obvious
> > ParportRead() - Obvious
>
> Er.. excuse me?
>
> Using your interface, please explain to me how one would go about writing
> a printer driver.

May be I am too much simplicistic, but I think an lp driver will be (in
simple pseudo code):

lp_init() {
/*
   parport driver will be alredy init'ed so it know about parport modes
   and it defaults to the best parport default mode (e.g. SPP)
*/
        if (!ParportPresent())
                return NOWAY;
        register_device(lp);
}

lp_open(minor) {
        if (handle = ParportOpen(minor))
                return -ENODEV;
        lp_handles[minor] = handle;
}

lp_ioctl(minor, cmd, arg) {
        switch (cmd) {
                ...
                case LPPARPORTSETUP:
                        ParportSetup(lp_handles[minor], arg);
/* E.g. set up ECP+IRQ+DMA if available */
                        break;
                ...
}

lp_write(minor, buf, len) {
        written = ParportWrite(lp_handles[minor], buf, len);
        return written;
}

lp_close(minor) {
        ParportClose(lp_handles[minor]);
}

Then the parport driver will do the real thing, masquerading all the
hardware stuff. We can write per-arch drivers to speed up the parport
layer.
Parport will look something like

struct parport_operations {
        function write;
        function read;
} EPP_ops, ECP_ops;

struct parport_mode {
        int flags;
        struct parport_operations *ops;
        function initialize;
} EPP_mode, ECP_mode;

struct parport_handle {
        ...
        struct parport_mode *mode;
        ...
} handle;

and e.g.:

ParportInit(minor) {
        EPP_mode->ops = &EPP_ops;
        ECP_mode->ops = &ECP_ops;
        get an handle for parport(minor);
        handle->mode = &EPP_mode;
}

ParportSetup(handle, arg) {
        if (arg & PARPORT_MODE_ECP) {
                handle->mode = &ECP_mode;
                handle->mode.flags = arg;
                /* may be arg contain PARPORT_MODE_INT|PARPORT_MODE_DMA */
        }
        handle->mode->initialize(); /* to spin up the new parport mode */
}

ParportWrite(handle, buf, len) {
        handle->mode->ops->write(buf, len);
}

ParportRead(handle, buf, len) {
        handle->mode->ops->read(buf, len);
}

Note that in the parport_operations functions, you can do whatever you
want. Even bit bang into the port .. of course .. at the cost of some
function calls [ParportWrite() => ops->write()].

Okay. I have ignored all the problems with port status, port sharing et
all. Boh ... we can even write something like ParportSelect() for what it
is worth doing so.

Am I so wrong ?

All of this is came out from a feeling of mine, so please, don't be rude.
I admit I am not a parport guru :)

Ciao,
        Riccardo.

-- To unsubscribe, send mail to: linux-parport-request@torque.net --
-- with the single word "unsubscribe" in the body of the message. --



This archive was generated by hypermail 2.0b3 on Wed 30 Dec 1998 - 10:17:37 EST