From: Adrian M. <ad...@mc...> - 2001-11-21 21:01:20
|
Below is a code fragment from the sound driver i am working on - very basic as you can see. I intend ploughing on - adding to the attach bit to plug into the OSS drivers, but even this simple code misbehaves at the moment. I am sure it is something basic and silly, but I hope you will indulge me by telling me what... What happens now... insmod aica.o generates (correctly) - "Attaching AICA" and then "AICA sound driver has been initialised" lsmod shows it then in situ. But rmmod produces "Device busy" error message. Any ideas? Is it simply because this is not a properly registered driver yet - or is there a coding problem? Any and all help etc.... // Macros to make it easier #define AICA_REG(x) ((int *)(0xa0700000 + (x))) #define SET_AICA_REG(x) (*AICA_REG(x)) static int attach_aica(void) { printk("<1>Attaching AICA\n"); return 0; } static int __init init_aica (void) { MOD_INC_USE_COUNT; //increment count //disable the ARM7 SET_AICA_REG(0x2c00) |= 1; //empty sound memory memset((void*)0xa0800000, 0, 0x200000); /*Simply set low bit of AICA register 0x2c00 to zero this maps to 0xa0702c00 in the SH4 memory map*/ SET_AICA_REG(0x2c00) &= ~1; attach_aica(); printk("<1>AICA sound driver has been initialised\n"); return 0; } static void __exit exit_aica(void) { /*set low bit of register to 1*/ printk("<1>AICA sound driver being unloaded...\n"); SET_AICA_REG(0x2c00) |= 1; MOD_DEC_USE_COUNT; } module_init(init_aica); module_exit(exit_aica); |
From: Paul M. <pm...@mv...> - 2001-11-22 00:19:16
|
On Wed, Nov 21, 2001 at 08:58:06PM +0000, Adrian McMenamin wrote: > But rmmod produces "Device busy" error message. >=20 This is to be expected.. as you're misusing MOD_{INC,DEC}_USE_COUNT. > Any ideas? Is it simply because this is not a properly registered driver = yet=20 > - or is there a coding problem? >=20 > Any and all help etc.... >=20 [snip] > static int __init init_aica (void) > { > MOD_INC_USE_COUNT; //increment count [snip] This is not at all what you want to do. You're forcing its usage count up on an initialization even though nothing is actually using it. The proper way = to do this would be to setup an aica_open() and stick your MOD_INC_USE_COUNT in there, and then decrement it on an aico_close(), then hand that off to a fi= le operations structure when you register. > } >=20 > static void __exit exit_aica(void) > { > /*set low bit of register to 1*/ > printk("<1>AICA sound driver being unloaded...\n"); > SET_AICA_REG(0x2c00) |=3D 1; > MOD_DEC_USE_COUNT; > =20 > } >=20 Same deal here, MOD_DEC_USE_COUNT should only ever be used by a close call. Think of the following scenario .. you bring up the device, and open() /dev/dsp .. this should accordingly increment its usage count, as it's in u= se by the application that open()'ed it. Later on .. when you close() the file descriptor, its usage count is decremented. Checking /proc/modules will always report the current status of a module and its usage count.. a module can't be unloaded if it's in use. Regards, --=20 Paul Mundt <pm...@mv...> MontaVista Software, Inc. |
From: Adrian M. <ad...@mc...> - 2001-11-22 19:05:24
|
On Thursday 22 Nov 2001 12:19 am, Paul Mundt wrote: > On Wed, Nov 21, 2001 at 08:58:06PM +0000, Adrian McMenamin wrote: > > But rmmod produces "Device busy" error message. > > This is to be expected.. as you're misusing MOD_{INC,DEC}_USE_COUNT. > > > Any ideas? Is it simply because this is not a properly registered driver > > yet - or is there a coding problem? > > > > Any and all help etc.... > > [snip] > > > static int __init init_aica (void) > > { > > MOD_INC_USE_COUNT; //increment count > > [snip] > > This is not at all what you want to do. You're forcing its usage count up > on an initialization even though nothing is actually using it. The proper > way to do this would be to setup an aica_open() and stick your > MOD_INC_USE_COUNT in there, and then decrement it on an aico_close(), then > hand that off to a file operations structure when you register. > Errr... yes. I should have paid more attention to the sample code I was looking at. The good news is that I am now pretty confident that this task (writing the driver) is doable... |
From: M. R. B. <mr...@0x...> - 2001-11-23 05:13:27
|
* Adrian McMenamin <ad...@mc...> on Thu, Nov 22, 2001: >=20 > The good news is that I am now pretty confident that this task (writing t= he=20 > driver) is doable... >=20 Two things about directly accessing the AICA hardware: 1) Use io_request_region() to reserve AICA registers and RAM, 2) Use the in{b,w,l}() out{b,w,l}() macros when accessing registers. This lets us do things like wait for the G2 bus FIFO (0xa05f688c) and other cool stuff, without the device driver ever needing to worry about it: void outl(u32 val, void *addr) { while ((u32 *)*(0xa05f688c) & 1) ; *reg =3D val; } You only have to worry about AICA-specific stuff in your driver at this poi= nt, you don't have to get all funky like libdream or KOS. See, even the kernel can do sane abstraction ;). M. R. |
From: Adrian M. <ad...@mc...> - 2001-11-23 08:35:10
|
On Friday 23 Nov 2001 5:13 am, M. R. Brown wrote: > * Adrian McMenamin <ad...@mc...> on Thu, Nov 22, 2001: > > The good news is that I am now pretty confident that this task (writing > > the driver) is doable... > > Two things about directly accessing the AICA hardware: > > 1) Use io_request_region() to reserve AICA registers and RAM, > 2) Use the in{b,w,l}() out{b,w,l}() macros when accessing registers. This > lets us do things like wait for the G2 bus FIFO (0xa05f688c) and other > cool stuff, without the device driver ever needing to worry about it: > > void outl(u32 val, void *addr) > { > while ((u32 *)*(0xa05f688c) & 1) ; > *reg = val; > } > > You only have to worry about AICA-specific stuff in your driver at this > point, you don't have to get all funky like libdream or KOS. > Thanks for the tips. No need to worry about the driver getting "all funky" :-> At the moment the thing I am interested in is getting some noise to come out of the speakers! > See, even the kernel can do sane abstraction ;). > > M. R. |