lkm i/o port allocation problems
infamous41md at hotpop.com
infamous41md at hotpop.com
Sat Jun 19 02:29:07 GMT 2004
/*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
More information about the freebsd-hackers
mailing list