From ff1fa9ef3c9fb23a6baa06b63f4bdf3de089b29a Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Mon, 27 Jun 2005 16:28:09 -0700 Subject: [PATCH] pcmcia: CIS overrid via sysfs 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 Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/pcmcia/socket_sysfs.c | 47 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) (limited to 'drivers/pcmcia/socket_sysfs.c') diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c index fd5a3b0557b..8e66eeff672 100644 --- a/drivers/pcmcia/socket_sysfs.c +++ b/drivers/pcmcia/socket_sysfs.c @@ -282,6 +282,50 @@ static ssize_t pccard_show_cis(struct kobject *kobj, char *buf, loff_t off, size 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 class_device_attribute *pccard_socket_attributes[] = { }; 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) -- cgit v1.2.3