Re: [OOPS/HACK] atmel_cs and the latest changes in sysfs/symlink.c

Dmitry Torokhov
2004-04-25T21:54:05Z

On Friday 23 April 2004 03:39 pm, Russell King wrote:
> On Fri, Apr 23, 2004 at 10:14:24PM +0200, Marcel Holtmann wrote:
> > should we apply the pcmcia_get_sys_device() patch from Dmitry for now to
> > fix the current drivers that need a device for loading the firmware?
>
> I don't think so - it obtains the struct device for the bridge itself
> which has nothing to do with the card inserted in the slot.
>

Yes, my bad... I wonder if something like the patch below could be useful
for now (although it created only one device entry even if card has multiple
functions so we really need another device for every function):

===== ss.h 1.27 vs edited =====
--- 1.27/include/pcmcia/ss.h Sat Sep 6 16:32:55 2003
+++ edited/ss.h Sun Apr 25 15:10:40 2004
@@ -196,7 +196,6 @@
/* deprecated */
unsigned int sock; /* socket number */

-
/* socket capabilities */
u_int features;
u_int irq_mask;
@@ -232,6 +231,7 @@

/* socket device */
struct class_device dev;
+ struct device *card_dev;
void *driver_data; /* data internal to the socket driver */

};
===== cs.c 1.78 vs edited =====
--- 1.78/drivers/pcmcia/cs.c Mon Apr 19 03:12:13 2004
+++ edited/cs.c Sun Apr 25 15:14:36 2004
@@ -60,6 +60,7 @@
#include <pcmcia/bulkmem.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h>
+#include <pcmcia/ds.h>
#include "cs_internal.h"

#ifdef CONFIG_PCI
@@ -324,6 +325,40 @@
}
EXPORT_SYMBOL(pcmcia_get_socket_by_nr);

+static void release_card_device(struct device *dev)
+{
+ kfree(dev);
+}
+
+static void register_card_device(struct pcmcia_socket *skt)
+{
+ struct device *dev;
+
+ WARN_ON(skt->card_dev);
+
+ skt->card_dev = dev = kmalloc(sizeof(struct device), GFP_KERNEL);
+ if (dev) {
+
+ memset(dev, 0, sizeof(struct device));
+
+ dev->parent = skt->dev.dev;
+ dev->driver = NULL;
+ dev->bus = &pcmcia_bus_type;
+ dev->release = &release_card_device;
+
+ snprintf(dev->bus_id, sizeof(dev->bus_id), "pccard%d", skt->sock);
+
+ device_register(dev);
+ }
+}
+
+static void unregister_card_device(struct pcmcia_socket *skt)
+{
+ if (skt->card_dev) {
+ device_unregister(skt->card_dev);
+ skt->card_dev = NULL;
+ }
+}

/*======================================================================

@@ -574,8 +609,11 @@
#endif
cs_dbg(skt, 4, "insert done\n");

+ register_card_device(skt);
+
send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
} else {
+ unregister_card_device(skt);
socket_shutdown(skt);
cs_socket_put(skt);
}
@@ -596,6 +634,7 @@
return CS_SUCCESS;
}

+
/*
* Resume a socket. If a card is present, verify its CIS against
* our cached copy. If they are different, the card has been
@@ -620,11 +659,14 @@
if (verify_cis_cache(skt) != 0) {
socket_remove_drivers(skt);
destroy_cis_cache(skt);
+ unregister_card_device(skt);
+ register_card_device(skt);
send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
} else {
send_event(skt, CS_EVENT_PM_RESUME, CS_EVENT_PRI_LOW);
}
} else {
+ unregister_card_device(skt);
socket_shutdown(skt);
cs_socket_put(skt);
}
@@ -636,6 +678,7 @@

static void socket_remove(struct pcmcia_socket *skt)
{
+ unregister_card_device(skt);
socket_shutdown(skt);
cs_socket_put(skt);
}