summaryrefslogtreecommitdiff
path: root/drivers/pcmcia/socket_sysfs.c
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.net>2005-06-27 16:28:09 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-27 18:03:07 -0700
commitff1fa9ef3c9fb23a6baa06b63f4bdf3de089b29a (patch)
tree05cd82cc6bbb4c9881de5d9c5584cc64f15262d1 /drivers/pcmcia/socket_sysfs.c
parent7f299bccb422d707be3b074f9a669b34cb207a14 (diff)
downloadlwn-ff1fa9ef3c9fb23a6baa06b63f4bdf3de089b29a.tar.gz
lwn-ff1fa9ef3c9fb23a6baa06b63f4bdf3de089b29a.zip
[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 <linux@dominikbrodowski.net> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/pcmcia/socket_sysfs.c')
-rw-r--r--drivers/pcmcia/socket_sysfs.c47
1 files changed, 46 insertions, 1 deletions
diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c
index fd5a3b0557b3..8e66eeff672e 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)