[PATCHES] pcmcia: update socket registration

Russell King rmk at arm.linux.org.uk
Mon Jun 9 23:54:01 BST 2003


On Thu, Jun 05, 2003 at 08:22:30PM +0200, Dominik Brodowski wrote:
> If we use try_module_get(driver->owner) at the right place (and
> module_put as well, of course), the check for (driver->use_count > 0)
> can't ever return true. So get rid of it, and add the proper module
> locking calls.
> 
>  ds.c |   22 +++++++---------------
>  1 files changed, 7 insertions(+), 15 deletions(-)
> 
> 
> diff -ruN linux-original/drivers/pcmcia/ds.c linux/drivers/pcmcia/ds.c
> --- linux-original/drivers/pcmcia/ds.c	2003-06-05 18:31:35.000000000 +0200
> +++ linux/drivers/pcmcia/ds.c	2003-06-05 18:30:35.000000000 +0200
> @@ -165,20 +165,6 @@
>   */
>  void pcmcia_unregister_driver(struct pcmcia_driver *driver)
>  {
> -	socket_bind_t *b;
> -	struct pcmcia_bus_socket *bus_sock;
> -
> -	if (driver->use_count > 0) {
> -		/* Blank out any left-over device instances */
> -		driver->attach = NULL; driver->detach = NULL;
> -		down_read(&bus_socket_list_rwsem);
> -		list_for_each_entry(bus_sock, &bus_socket_list, socket_list) {
> -			for (b = bus_sock->bind; b; b = b->next)
> -				if (b->driver == driver) 
> -					b->instance = NULL;
> -		}
> -		up_read(&bus_socket_list_rwsem);
> -	}
>  	driver_unregister(&driver->drv);
>  }
>  EXPORT_SYMBOL(pcmcia_unregister_driver);
> @@ -367,6 +353,9 @@
>  	return -EBUSY;
>      }
>  
> +    if (!try_module_get(driver->owner))
> +	    return -EINVAL;
> +

Something niggles me here - what prevents "driver" becoming an invalid
pointer between the point when we found the driver and the point where
we call try_module_get ?  (eg, I unload the module which contained
"driver" ?)

I suspect we want to call try_module_get() from inside cmp_drv_callback,
eg:

static int cmp_drv_callback(struct device_driver *drv, void *data)
{
        struct cmp_data *cmp = data;
	struct pcmcia_driver *driver = container_of(drv, struct pcmcia_driver, drv);
        if (strncmp((char *)cmp->dev_info, (char *)drv->name,
                    DEV_NAME_LEN) == 0 &&
            try_module_get(driver->owner)) {
                cmp->drv = driver;
                return -EINVAL;
        }
        return 0;
}

and invent put_pcmcia_driver() to do the put_module().

-- 
Russell King (rmk at arm.linux.org.uk)                The developer of ARM Linux
             http://www.arm.linux.org.uk/personal/aboutme.html




More information about the linux-pcmcia mailing list