Date: Fri, 18 Jun 2004 22:29:56 -0400 From: infamous41md@hotpop.com To: freebsd hackers <freebsd-hackers@freebsd.org> Subject: lkm i/o port allocation problems Message-ID: <20040618222956.72ccfbf2.infamous41md@hotpop.com>
next in thread | raw e-mail | index | archive | help
/*I am trying to figure out how to port over an infrared reciever driver from linux to freebsd. i have been reading the developers book, as well as the source for sio/ep and several other char drivers that use i/o ports. i can't seem to get my i/o port allocation to work. whenever i request the region w/ bus_alloc_resource() it returns NULL to me the first time i load my module. however, once i try again, i get the message: ser0 at port 0x2f8-0x2ff on isa0 ser is the name of my module. so it seems that even tho the alloc call is failing, somehow i still have the region to myself??? and now, even after i reboot my computer, whenever i try to load my module i immediately get the above error message. so it seems that somehow, even tho it is restarted, it never lets go of the i/o region?? this module is not called at start time, it is only loaded when i give kldload command my other problem is that in order to get the probe/attach functions to be called, i used the identify function in which i call the BUS_ADD_CHILD() function as i saw ep driver do. is this correct? b/c after i load my module once, the next time i try to load it this call always fails. is this correct way to do this? if not, how do i get the probe function to be called, b/c it wasn't being called when i loaded my module. here is the code, it is very short as i chopped out the extra stuff. if someone could please take a quick look im sure it would be obvious what i've done wrong, but i can't see what the problem is. i've been digging thru the resource allocation functions and they're just to complex for me to understand atm. thanks very much for any help. */ #include <sys/types.h> #include <sys/errno.h> #include <sys/param.h> /* defines used in kernel.h */ #include <sys/kernel.h> /* types used in module initialization */ #include <sys/module.h> #include <machine/bus.h> #include <machine/resource.h> #include <sys/bus.h> #include <sys/conf.h> /* cdevsw struct */ #include <sys/malloc.h> #include <sys/rman.h> #include <sys/systm.h> /* uprintf */ #include <sys/uio.h> /* uio struct */ #include <isa/isavar.h> #include <isa/pnpvar.h> /* device structure */ static struct resource *rp; char ser_driver_name[] = "ser"; devclass_t ser_devclass; /* isa stuff */ static int ser_isa_attach(device_t); static int ser_isa_detach(device_t); static int ser_isa_probe(device_t); static void ser_isa_ident(driver_t *, device_t); static device_method_t ser_isa_methods[] = { /* Device interface */ DEVMETHOD(device_probe, ser_isa_probe), DEVMETHOD(device_attach, ser_isa_attach), DEVMETHOD(device_detach, ser_isa_detach), DEVMETHOD(device_identify, ser_isa_ident), { 0, 0 } }; static driver_t ser_isa_driver = { ser_driver_name, ser_isa_methods, 0, }; static struct isa_pnp_id ser_ids[] = { { 0, NULL} }; static int ser_isa_probe(device_t dev) { uprintf("probing\n"); return 0; } static void ser_isa_ident(driver_t *driv, device_t dev) { int ret = 0; device_t child; uprintf("identing\n"); child = BUS_ADD_CHILD(dev, 0, "ser", 0); if(child == NULL){ uprintf("bus add child == NULL\n"); return; } device_set_driver(child, driv); /* allocate i/o ports */ if( (ret = bus_set_resource(child, SYS_RES_IOPORT, 0, 0x2f8, 8)) ) uprintf("bus set bad, ret = %d\n", ret); } static int ser_isa_attach(device_t dev) { int rid; uprintf("attaching\n"); rid = 0; rp = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 8, RF_ACTIVE); if(rp == NULL){ uprintf("bus alloc bad\n"); }else{ uprintf("allocated bus resources\n"); } return 0; } static int ser_isa_detach(device_t dev) { /* give back i/o region */ if(rp){ if(bus_release_resource(dev, SYS_RES_IOPORT, 0, rp) == 0) uprintf("releasd resources\n"); else uprintf("error releasein\n"); } uprintf("detached\n"); return 0; } /* * Load handler that deals with the loading and unloading of a KLD. */ static int mdev_loader(struct module * m, int what, void *arg) { int err = 0; switch (what) { case MOD_LOAD: /* kldload */ break; case MOD_UNLOAD: break; default: err = EINVAL; break; } return (err); } DRIVER_MODULE(ser, isa, ser_isa_driver, ser_devclass, mdev_loader, 0); -- -sean -- -sean
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20040618222956.72ccfbf2.infamous41md>