Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 21 Jun 2004 23:38:04 -0400
From:      infamous41md@hotpop.com
To:        freebsd-hackers@freebsd.org
Subject:   Re: lkm i/o port allocation problems
Message-ID:  <20040621233804.194deae4.infamous41md@hotpop.com>
In-Reply-To: <20040619.170012.20320023.imp@bsdimp.com>
References:  <20040618221344.1848e9db.infamous42md@hotpop.com> <20040619.170012.20320023.imp@bsdimp.com>

next in thread | previous in thread | raw e-mail | index | archive | help
thanks much for the reply, im going to bring print this and bring it inside to my bsd box and see what happens. i'll let you know how it works out.

On Sat, 19 Jun 2004 17:00:12 -0600 (MDT)
"M. Warner Losh" <imp@bsdimp.com> wrote:

> : /*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
> 
> Do you have another driver at this range of ports?  It is on my
> machine:
> 
> 	sio1 at port 0x2f8-0x2ff irq 3 on isa0
> 
> so you have to ensure that you don't have sio binding to this device.
> You'll get bus_alloc_resource returning NULL in this case.
> 
> : 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???
> 
> I don't understand this statement at all.  Just because the ISA bus
> thinks your driver might have the resources, doesn't mean that your
> driver actually has them.  The information is there because many
> devices might be at the same location (think aha and bt).
> 
> : and now, even after i
> : reboot my computer, whenever i try to load my module i immediately get the above
> : error message.
> 
> What error message.  You included none in your comments.
> 
> : 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
> 
> Maybe sio1 has claimed this device already.  Maybe your system has
> pnpbios/acpi listing the device?  That's the usual reason...
> 
> : 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?
> 
> No.  You don't have to do this.  In fact, you shouldn't generally do
> this in your driver.  You should either bind to the PNP ID (which gets
> reprobed on every driver add), or you should add hints to the boot
> loader.
> 
> : b/c after i load my module
> : once, the next time i try to load it this call always fails. 
> 
> That's because one usually doesn't need to do this :-).
> 
> : 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),
> 
> You rarely need identify.  In this case it is contraindicated.
> 
> : static int ser_isa_probe(device_t dev)
> : {
> :     uprintf("probing\n");
> :         
> :     return 0;
> : }
> 
> Don't use uprintf.  You will find that when you add the driver to the
> boot process, you'll get a panic here because there's no controlling
> terminal...
> 
> : 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);
> :         
> : }
> 
> This isn't necessary.  I'd not use it at all.
> 
> : 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;
> : }
> 
> Chances are good this is failing because there's another device
> already servicing the device that has this range.  This may mean that
> you will have to have your driver loaded at boot time so it doesn't do
> that and you may also have to hack sio to return an indefinite probe
> (some non-0 negative number).
> 
> There's something called the softc.  You should store store the
> resource in the softc for the driver, not in a global.
> 
> : 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;
> : }
> 
> 
> Apart from the uprintf and sotfc comments above, there's nothign
> really wrong here.
> 
> : /*
> :  * 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);
> : }
> 
> You don't need this at all.  In fact, it may be causing you problems.
> Delete it.
> 
> : DRIVER_MODULE(ser, isa, ser_isa_driver, ser_devclass, mdev_loader, 0);
> _______________________________________________
> freebsd-hackers@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
> To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@freebsd.org"


-- 
-sean



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20040621233804.194deae4.infamous41md>