Date: Fri, 24 Jul 2009 18:17:42 +0200 From: Andre Albsmeier <Andre.Albsmeier@siemens.com> To: John Baldwin <jhb@freebsd.org> Cc: freebsd-hackers@freebsd.org, Andre Albsmeier <Andre.Albsmeier@siemens.com> Subject: Re: Reading acpi memory from a driver attached to hostb Message-ID: <20090724161742.GA73257@curry.mchp.siemens.de> In-Reply-To: <200907231606.11904.jhb@freebsd.org> References: <200907230835.50814.jhb@freebsd.org> <200907231425.n6NEPeRH026492@ambrisko.com> <20090723175351.GA70584@curry.mchp.siemens.de> <200907231606.11904.jhb@freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, 23-Jul-2009 at 16:06:11 -0400, John Baldwin wrote: > On Thursday 23 July 2009 1:53:51 pm Andre Albsmeier wrote: > > John, apparently you sent me an email (thanks a lot) which I never > > received (we have to blame our company's spam filters which I do > > not control). I'll comment on it here in my reply to Doug... > > Yes, I saw the bounces. Hopefully you see the list version of this. Yes, I've been lucky this time. > > > > | Did you try > > > | doing 'bus_alloc_resource(device_get_parent(device_get_parent(dev))' in > your > > > | driver that is a child of hostb0? > > > > I tried this, well, something similar: I had to do 4 times > > device_get_parent() to end up at acpi0: > > > > mydriver -> hostb0 -> pci0 -> pcib0 -> acpi0 > > You don't actually need to do that. pci0 will pass the request up to acpi0 That's what I hoped as well. > eventually. You just need to ask pci0 to allocate it for you and it will see > you are not a direct child and take the 'passthrough' case here: > > struct resource * > pci_alloc_resource(device_t dev, device_t child, int type, int *rid, > u_long start, u_long end, u_long count, u_int flags) > { > ... > > if (device_get_parent(child) != dev) > return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child, > type, rid, start, end, count, flags)); > ... > } > > Rather than trying to allocate the whole chunk of the ACPI resource, I would > just do a specific allocation like so: > > rid = 0; > res = BUS_ALLOC_RESOURCE(device_get_parent(device_get_parent(dev)), > dev, SYS_RES_MEMORY, &rid, <the real start address>, <the real > end address>, <the length>, RF_ACTIVE); OK, I have modified my driver exactly this way, but still no success. It seems my code didn't make it to the list (the attachment was stripped) so I include it inline now. Testing is quite simple, every feedback is welcome: 1. check if "devinfo -r" spits out some free "I/O memory addresses" ranges under acpi0 with at minimum 4 bytes length. 2. select one of them and assign its start address to rstart in eccmon_probe() at the line which reads now u_long rstart = 0xfed14000; (this is the address I use for testing) 3. compile, kldload and dmesg. I always get the message "bus_alloc_resource() returned NULL". Thanks, -Andre -------------------- eccmon.c start ------------------------------------- #include <sys/param.h> #include <sys/systm.h> #include <sys/module.h> #include <sys/kernel.h> #include <machine/bus.h> #include <sys/bus.h> #include <sys/rman.h> #include <machine/pci_cfgreg.h> #include <dev/pci/pcivar.h> #include <dev/pci/pcireg.h> struct eccmon_softc { device_t dev; int res_set; /* flag if bus_set_resource() was used successfully */ struct resource* res; int rid; }; /**********************/ /* eccmon_probe() */ /**********************/ static int eccmon_probe( const device_t const dev ) { u_long rstart = 0xfed14000; int ret; struct resource* res; int rid = 0; device_printf( dev, "probe: started for %x:%x\n", pci_get_vendor( dev ) , pci_get_device( dev ) ); /* * try to bus_alloc_resource the resource and give it back */ if( (res = BUS_ALLOC_RESOURCE( device_get_parent(device_get_parent(dev)), dev, SYS_RES_MEMORY, &rid, rstart, rstart+4, 4, RF_ACTIVE )) == NULL ) { device_printf( dev, "bus_alloc_resource() returned NULL\n" ); return ENXIO; } if( (ret = BUS_RELEASE_RESOURCE( device_get_parent(device_get_parent(dev)), dev, SYS_RES_MEMORY, rid, res )) != 0 ) device_printf( dev, "bus_release_resource() returned %d\n", ret ); return ENXIO; } /***********************/ /* eccmon_attach() */ /***********************/ static int eccmon_attach( const device_t const dev ) { device_printf( dev, "attach: started for %x:%x\n", pci_get_vendor( dev ) , pci_get_device( dev ) ); return ENXIO; } /***********************/ /* eccmon_detach() */ /***********************/ static int eccmon_detach( const device_t const dev ) { device_printf( dev, "detach: started for %x:%x\n", pci_get_vendor( dev ) , pci_get_device( dev ) ); return 0; } /*************************/ /* eccmon_identify() */ /*************************/ static void eccmon_identify( driver_t *driver, device_t p ) { device_printf( p, "identify: start: %x %x\n", pci_get_vendor( p ), pci_get_device( p ) ); device_printf( p, "identify on: %s %d\n", device_get_name( p ), device_get_unit(p) ); if( device_find_child( p, "eccmon", -1 ) == NULL && strcmp( device_get_name( p ), "hostb" ) == 0 && device_get_unit( p ) == 0 ) { device_t child = device_add_child( p, "eccmon", -1 ); device_printf( p, "identify added child: %p\n", child ); } } /***********************/ /* driver(9) stuff */ /***********************/ static device_method_t eccmon_methods[] = { DEVMETHOD( device_identify, eccmon_identify ), DEVMETHOD( device_probe, eccmon_probe ), DEVMETHOD( device_attach, eccmon_attach ), DEVMETHOD( device_detach, eccmon_detach ), { 0, 0 } }; static driver_t eccmon_driver = { "eccmon", eccmon_methods, sizeof( struct eccmon_softc ) }; static devclass_t eccmon_devclass; DRIVER_MODULE( eccmon, hostb, eccmon_driver, eccmon_devclass, NULL, NULL ); -------------------- eccmon.c end ------------------------------------- -------------------- Makefile start ------------------------------------- KMOD = eccmon SRCS = eccmon.c device_if.h bus_if.h pci_if.h NO_MAN = 1 CFLAGS+=-DDEVEL .include <bsd.kmod.mk> -------------------- Makefile end -------------------------------------
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20090724161742.GA73257>