pcmcia: add struct pcmcia_device
PATCH 1/1 pcmcia: add struct pcmcia_device
This patch adds a struct pcmcia_device, and fills it with content for every function of every pcmcia card inserted into the socket.
Unfortunately, information about the card can only be detected when "cardmgr"[*] has told the pcmcia rsrc_mgr on what IO-ports and what IO-mem is available for usage by the pcmcia core or drivers. So the cards need to be re-scanned on completion of the pcmcia initialization.
Re-starting cardmgr will not re-enable the resources.
Dominik
drivers/pcmcia/cistpl.c | 3 drivers/pcmcia/ds.c | 207 ++++++++++++++++++++++++++++++++++++++++++++++-- include/pcmcia/ds.h | 24 +++++ 3 files changed, 227 insertions(+), 7 deletions(-)
drivers/pcmcia/cistpl.c +2 -1
@@ -1392,6 +1392,7 @@ ret =pcmcia_parse_tuple (handle, &tuple, parse);return ret; } +EXPORT_SYMBOL (read_tuple);/*======================================================================
@@ -1451,4 +1452,4 @@return CS_SUCCESS ; } - +EXPORT_SYMBOL (pcmcia_validate_cis);
drivers/pcmcia/ds.c +201 -6
291 lines not on this page · raw message
include/pcmcia/ds.h +24 -0
@@ -165,5 +165,29 @@/* error reporting */ void cs_error (client_handle_t handle,int func,int ret); +struct pcmcia_bus_socket ; + +struct pcmcia_device { +unsigned int socket_no;/* deprecated */ +struct pcmcia_bus_socket *bus_sock; +struct list_head socket_device_list; +unsigned int func; + +/* cis information */ +unsigned int has_cis; +cistpl_vers_1_t vers1; + +unsigned int has_manfid; +cistpl_manfid_t manfid; + +unsigned int has_funcid; +cistpl_funcid_t funcid; + +struct device dev; +}; + +#define to_pcmcia_dev (n) container_of(n, struct pcmcia_device, dev) +#define to_pcmcia_drv (n) container_of(n, struct pcmcia_driver, drv) +#endif /* __KERNEL__ */ #endif /* _LINUX_DS_H */
Ok, some comments on this patch.
Quoted 38 lines · Dominik Brodowski
diff -ruN
linux-original/drivers/pcmcia/cistpl.clinux/drivers/pcmcia/cistpl.cdrivers/pcmcia/cistpl.c +2
-1@@ -1392,6 +1392,7 @@ ret =pcmcia_parse_tuple (handle, &tuple, parse);return ret; } +EXPORT_SYMBOL (read_tuple);/*====================================================================== @@ -1451,4 +1452,4 @@return CS_SUCCESS ; } - +EXPORT_SYMBOL (pcmcia_validate_cis);diff -ruN
linux-original/drivers/pcmcia/ds.clinux/drivers/pcmcia/ds.cdrivers/pcmcia/ds.c +5
-0@@ -108,11 +108,16 @@struct device *socket_dev;struct list_head socket_list;unsigned int socket_no;/* deprecated */ +/* the PCMCIA devices connected to this socket (normally one, more +* for multifunction devices: */ +struct list_head devices_list; +struct semaphore devices_list_sem; };#define SOCKET_PRESENT 0x01#define SOCKET_BUSY 0x02#define SOCKET_REMOVAL_PENDING 0x10 +#define SOCKET_ADDING_PENDING 0x20/*====================================================================*/
drivers/pcmcia/ds.c line 134
Quoted 9 lines
drivers/pcmcia/ds.c +6
-0@@ -121,6 +126,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, +* prodid, etc. of the pcmcia card. +*/ +static int resources_available =0 ; +
This isn't actually such a clear-cut situation. Statically mapped sockets like SA11x0-based stuff are able to access the card with no resources loaded - in fact, there are no resources to be loaded.
One of my patches (which was the troublesome pcmcia-10 patch from akpm's patch set) changes the way we deal with the CIS. For windowed sockets, when a card detected, we immediately try to claim a resource for the CIS window. If this fails, we whinge about "PCMCIA: insert failed" but continue anyway. We could fail at this point.
When resources are changed, I simulate a card removal + insertion request so that the CIS gets re-setup. The longer term solution, imho, is to change the socket setup/reset/unreset code in cs.c to be more of a state machine which could be re-started when resources become available.
Quoted 4 lines
drivers/pcmcia/ds.c +4
-0+/* first case: no resources are available, so we can't decode +* any device information */ +if (!resources_available) { + sprintf (p_dev->dev.bus_id, "pcmcia%d:%d.?",
drivers/pcmcia/ds.c line 304
Quoted 10 lines
drivers/pcmcia/ds.c +10
-0+ s->socket_dev->class_num, s->socket_no); +sprintf (p_dev->dev.name,"unknown" ); + ret =device_register (&p_dev->dev); +if (ret) { +kfree (p_dev); + goto out; + } +list_add (&p_dev->socket_device_list, &s->devices_list); + goto out; + }
I'm not completely sure we want to add a device in this case - if we don't have any resources, there isn't much point in making the device available to drivers.
drivers/pcmcia/ds.c line 312
Quoted 5 lines
drivers/pcmcia/ds.c +5
-0+if (!func) { +cisinfo_t cisinfo; + ret =pcmcia_validate_cis (s->handle, &cisinfo); +if (ret || !cisinfo.Chains) { +printk (KERN_INFO "pcmcia: inserted card has invalid CIS.\n" );
I have a memory-type pcmcia card here, and I believe it doesn't have any CIS what so ever, so this would fail.
Signature · 2 lines
Russell King ([email protected]) The developer of ARM Linux http://www.arm.linux.org.uk/personal/aboutme.html