[PATCHES 2.5] pcmcia: add struct pcmcia_device

Russell King rmk at arm.linux.org.uk
Sat Apr 19 15:46:35 BST 2003


I still have problems with pcmcia-2.5.67-2-resources_available-1 - in fact
I have more problems with it than I did before.

> diff -ruN linux-original/drivers/pcmcia/ds.c linux/drivers/pcmcia/ds.c
> --- linux-original/drivers/pcmcia/ds.c	2003-04-15 23:57:35.000000000 +0200
> +++ linux/drivers/pcmcia/ds.c	2003-04-19 10:08:57.000000000 +0200
> @@ -122,6 +122,12 @@
>  
>  static int major_dev = -1;
>  
> +/* this is set to 1 when the iomem/ioport configuration of rsrc_mgr.c
> + * is completed -- only then it is possible to decode the name, manfid,
> + * cardid, etc. of the pcmcia card.
> + */
> +static int resources_available = 0;
> +
>  /* list of all sockets registered with the pcmcia bus driver */
>  static DECLARE_RWSEM(bus_socket_list_rwsem);
>  static LIST_HEAD(bus_socket_list);
> @@ -714,6 +720,7 @@
>      u_int size;
>      int ret, err;
>      ds_ioctl_arg_t buf;
> +    static int ioctl_resources_count = 0;
>  
>      DEBUG(2, "ds_ioctl(socket %d, %#x, %#lx)\n", i, cmd, arg);
>      
> @@ -743,14 +750,30 @@
>  	}
>      }
>      
> +    if  ((!resources_available) && 
> +	((cmd != DS_ADJUST_RESOURCE_INFO) && 
> +	(ioctl_resources_count > 0))) {
> +	    resources_available = 1;
> +//	    pcmcia_rescan_cards();
> +    }
> +
>      err = ret = 0;
>      
>      if (cmd & IOC_IN) copy_from_user((char *)&buf, (char *)arg, size);
>      
>      switch (cmd) {
>      case DS_ADJUST_RESOURCE_INFO:
> -	ret = pcmcia_adjust_resource_info(s->handle, &buf.adjust);
> -	break;
> +	    if (resources_available) {
> +		    /* gotta go */
> +		    ioctl_resources_count = -ioctl_resources_count;

I can see this going horribly wrong.  I'd much prefer that we didn't
guess what's going on, but used something which told us positively
what the status is.  If that means we need to add extra functions to
rsrc_mgr.c, then that's the right answer.

I've just merged my state machine patch into bk for Linus, so you can
assume that code's in (unless Linus whinges about it) which means you
can suspend the insert processing if resources aren't available (via
your favourite method) and then call pcmcia_resources_available() to
cause the state machine to re-test the resource state.  (see my
socket map-type patch for an example of this.)

Also, for the sysfs_output patch:

> @@ -377,6 +414,15 @@
>  	}
>  	list_add(&p_dev->socket_device_list, &s->devices_list);
>  
> +	/* add sysfs files */
> +	device_create_file(&p_dev->dev, &dev_attr_func_id);
> +	device_create_file(&p_dev->dev, &dev_attr_manf_id);
> +	device_create_file(&p_dev->dev, &dev_attr_card_id);
> +	device_create_file(&p_dev->dev, &dev_attr_vers1);
> +	device_create_file(&p_dev->dev, &dev_attr_vers2);
> +	device_create_file(&p_dev->dev, &dev_attr_vers3);
> +	device_create_file(&p_dev->dev, &dev_attr_vers4);
> +

The overall size may be smaller if you do:

static struct device_attribute *pcmcia_dev_attrs[] = {
	&dev_attr_func_id,
	&dev_attr_manf_id,
	&dev_attr_card_id,
	&dev_attr_vers1,
	&dev_attr_vers2,
	&dev_attr_vers3,
	&dev_attr_vers4,
};

...
	for (i = 0; i < ARRAY_SIZE(pcmcia_dev_attrs); i++)
		device_create_file(&p_dev->dev, pcmcia_dev_attrs[i]);

> @@ -398,6 +444,15 @@
>  	down(&s->devices_list_sem);
>  	list_for_each_safe(p1, p2, &s->devices_list) {
>  		struct pcmcia_device *p_dev = container_of(p1, struct pcmcia_device, socket_device_list);

		for (i = 0; i < ARRAY_SIZE(pcmcia_dev_attrs); i++)
			device_remove_file(&p_dev->dev, pcmcia_dev_attrs[i]);

>  		device_unregister(&p_dev->dev);
>  		list_del(&p_dev->socket_device_list);
>  		kfree(p_dev);

It also has the advantage that you only have one place to add new
device attributes, and therefore you won't forget to remove them
before unregistering the device.

-- 
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