Hi there! I'm trying to access my development board's parallel interface using a device driver. After all I learned so far I developed the following program, which doesn't work.
dmesg says this after calling make load
and about the parallel interface it says this
Calling 'echo "1" > /devmyppi0' doens't make the signals rise. Using outb does work by the way. I guess there's something I didn't understand yet, but what could it be? oh and why is there a "myppi1" on dmesg?
C:
#include <sys/param.h>
#include <sys/module.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/uio.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <machine/bus.h>
#include <sys/rman.h>
#include <machine/resource.h>
#define PPIBASE 0x378
struct myppi_softc
{
int sc_io_rid;
struct resource *sc_io_resource;
struct cdev *sc_cdev0;
struct mtx sc_mutex;
};
static devclass_t myppi_devclass;
static d_open_t myppi_open;
static d_close_t myppi_close;
static d_read_t myppi_read;
static d_write_t myppi_write;
static struct cdevsw myppi_cdevsw = {
.d_version = D_VERSION,
.d_open = myppi_open,
.d_close = myppi_close,
.d_read = myppi_read,
.d_write = myppi_write,
.d_name = "myppi"
};
static int myppi_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
{
uprintf("open\n");
return 0;
}
static int myppi_close(struct cdev *dev, int oflags, int devtype, struct thread *td)
{
uprintf("close\n");
return 0;
}
static int myppi_read(struct cdev *dev, struct uio *uio, int ioflag)
{
uprintf("read\n");
return 0;
}
static int myppi_write(struct cdev *dev, struct uio *uio, int ioflag)
{
struct myppi_softc *sc = dev->si_drv1;
uprintf("write\n");
bus_write_1(sc->sc_io_resource, 0, 0xff);
return 0;
}
static void myppi_identify(driver_t *driver, device_t parent)
{
device_t child;
child = device_find_child(parent, "myppi", -1);
if(!child)
{
child = BUS_ADD_CHILD(parent, 0, "myppi", -1);
bus_set_resource(child, SYS_RES_IOPORT, 0, PPIBASE, 1);
}
}
static int myppi_probe(device_t dev)
{
if(!bus_get_resource_start(dev, SYS_RES_IOPORT, 0))
{
return ENXIO;
}
device_set_desc(dev, "I/O Port Example");
return BUS_PROBE_SPECIFIC;
}
static int myppi_attach(device_t dev)
{
struct myppi_softc *sc = device_get_softc(dev);
sc->sc_io_rid = 0;
sc->sc_io_resource = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &sc->sc_io_rid, RF_ACTIVE);
if(!sc->sc_io_resource)
{
device_printf(dev, "unable to allocate resource\n");
return ENXIO;
}
sc->sc_cdev0 = make_dev(&myppi_cdevsw, 0, UID_ROOT, GID_WHEEL, 0644, "myppi0");
sc->sc_cdev0->si_drv1 = sc;
return 0;
}
static int myppi_detach(device_t dev)
{
struct myppi_softc *sc = device_get_softc(dev);
destroy_dev(sc->sc_cdev0);
bus_release_resource(dev, SYS_RES_IOPORT, sc->sc_io_rid, sc->sc_io_resource);
return 0;
}
static device_method_t myppi_methods[] = {
DEVMETHOD(device_identify, myppi_identify),
DEVMETHOD(device_probe, myppi_probe),
DEVMETHOD(device_attach, myppi_attach),
DEVMETHOD(device_detach, myppi_detach),
{ 0, 0 }
};
static driver_t myppi_driver = {
"myppi",
myppi_methods,
sizeof(struct myppi_softc)
};
DRIVER_MODULE(myppi, acpi, myppi_driver, myppi_devclass, 0, 0);
dmesg says this after calling make load
myppi0: <I/O Port Example> port 0x378 on acpi0
myppi0: unable to allocate resource
device_attach: myppi0 attach returned 6
myppi1: <I/O Port Example> port 0x20-0x21,0x24-0x25,0x28-0x29,0x2c-0x2d,0x30-0x31,0x34-0x35,0x38-0x39,0x3c-0x3d,0xa0-0xa1,0xa4-0xa5,0xa8-0xa9,0xac-0xad,0xb0-0xb1,0xb4-0xb5,0xb8-0xb9,0xbc-0xbd,0x4d0-0x4d1 irq 2 on acpi0
and about the parallel interface it says this
ppc1: <Parallel port> port 0x378-0x37f irq 5 on acpi0
ppc1: Generic chipset (NIBBLE-only) in COMPATIBLE mode
ppbus0: <Parallel port bus> on ppc1
lpt0: <Printer> on ppbus0
lpt0: Interrupt-driven port
ppi0: <Parallel I/O> on ppbus0
Calling 'echo "1" > /devmyppi0' doens't make the signals rise. Using outb does work by the way. I guess there's something I didn't understand yet, but what could it be? oh and why is there a "myppi1" on dmesg?