The one thing which surprises me in this patch that cis->Length needs to be set to count+1. Without it, it doesn't work, but with it, it doesn't make sense to me. Signed-off-by: Dominik Brodowski Index: 2.6.11-rc5/drivers/pcmcia/cs_internal.h =================================================================== --- 2.6.11-rc5.orig/drivers/pcmcia/cs_internal.h 2005-02-26 19:29:58.000000000 +0100 +++ 2.6.11-rc5/drivers/pcmcia/cs_internal.h 2005-02-26 23:01:05.000000000 +0100 @@ -160,6 +160,7 @@ struct module *owner; int (*event) (struct pcmcia_socket *s, event_t event, int priority); int (*resources_done) (struct pcmcia_socket *s); + void (*replace_cis) (void); }; int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c); Index: 2.6.11-rc5/drivers/pcmcia/ds.c =================================================================== --- 2.6.11-rc5.orig/drivers/pcmcia/ds.c 2005-02-26 22:55:07.000000000 +0100 +++ 2.6.11-rc5/drivers/pcmcia/ds.c 2005-02-26 23:01:05.000000000 +0100 @@ -653,6 +653,11 @@ return; } +static void pcmcia_bus_rescan(void) +{ + /* must be called with skt_sem held */ + bus_rescan_devices(&pcmcia_bus_type); +} static inline int pcmcia_devmatch(struct pcmcia_device *dev, struct pcmcia_device_id *did) @@ -1764,6 +1769,7 @@ s->callback.owner = THIS_MODULE; s->callback.event = &ds_event; s->callback.resources_done = &pcmcia_card_add; + s->callback.replace_cis = &pcmcia_bus_rescan; socket->pcmcia = s; ret = pccard_register_pcmcia(socket, &s->callback); Index: 2.6.11-rc5/drivers/pcmcia/socket_sysfs.c =================================================================== --- 2.6.11-rc5.orig/drivers/pcmcia/socket_sysfs.c 2005-02-26 23:01:02.000000000 +0100 +++ 2.6.11-rc5/drivers/pcmcia/socket_sysfs.c 2005-02-26 23:01:05.000000000 +0100 @@ -282,6 +282,50 @@ return (count); } +static ssize_t pccard_store_cis(struct kobject *kobj, char *buf, loff_t off, size_t count) +{ + struct pcmcia_socket *s = to_socket(container_of(kobj, struct class_device, kobj)); + cisdump_t *cis; + ssize_t ret = count; + + if (off) + return -EINVAL; + + if (count >= 0x200) + return -EINVAL; + + if (!(s->state & SOCKET_PRESENT)) + return -ENODEV; + + cis = kmalloc(sizeof(cisdump_t), GFP_KERNEL); + if (!cis) + return -ENOMEM; + memset(cis, 0, sizeof(cisdump_t)); + + cis->Length = count + 1; + memcpy(cis->Data, buf, count); + + if (pcmcia_replace_cis(s, cis)) + ret = -EIO; + + kfree(cis); + + if (!ret) { + down(&s->skt_sem); + if ((s->callback) && (s->state & SOCKET_PRESENT) && + !(s->state & SOCKET_CARDBUS)) { + if (try_module_get(s->callback->owner)) { + s->callback->replace_cis(); + module_put(s->callback->owner); + } + } + up(&s->skt_sem); + } + + + return (ret); +} + static struct class_device_attribute *pccard_socket_attributes[] = { &class_device_attr_card_type, @@ -296,9 +340,10 @@ }; static struct bin_attribute pccard_cis_attr = { - .attr = { .name = "cis", .mode = S_IRUGO, .owner = THIS_MODULE}, + .attr = { .name = "cis", .mode = S_IRUGO | S_IWUSR, .owner = THIS_MODULE}, .size = 0x200, .read = pccard_show_cis, + .write = pccard_store_cis, }; static int __devinit pccard_sysfs_add_socket(struct class_device *class_dev)