]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/pcmcia/socket_sysfs.c
Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik...
[linux-2.6-omap-h63xx.git] / drivers / pcmcia / socket_sysfs.c
index fd5a3b0557b33d7ec19ae3020cf09f664f0be692..4a3150a7854cceab92c4cef1c2ac480c29a67e12 100644 (file)
@@ -29,7 +29,6 @@
 #include <asm/irq.h>
 
 #define IN_CARD_SERVICES
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
 #include <pcmcia/cs.h>
@@ -163,24 +162,20 @@ static ssize_t pccard_store_resource(struct class_device *dev, const char *buf,
                return -EINVAL;
 
        spin_lock_irqsave(&s->lock, flags);
-       if (!s->resource_setup_done) {
+       if (!s->resource_setup_done)
                s->resource_setup_done = 1;
-               spin_unlock_irqrestore(&s->lock, flags);
+       spin_unlock_irqrestore(&s->lock, flags);
 
-               down(&s->skt_sem);
-               if ((s->callback) &&
-                   (s->state & SOCKET_PRESENT) &&
-                   !(s->state & SOCKET_CARDBUS)) {
-                       if (try_module_get(s->callback->owner)) {
-                               s->callback->resources_done(s);
-                               module_put(s->callback->owner);
-                       }
+       down(&s->skt_sem);
+       if ((s->callback) &&
+           (s->state & SOCKET_PRESENT) &&
+           !(s->state & SOCKET_CARDBUS)) {
+               if (try_module_get(s->callback->owner)) {
+                       s->callback->requery(s);
+                       module_put(s->callback->owner);
                }
-               up(&s->skt_sem);
-
-               return count;
        }
-       spin_unlock_irqrestore(&s->lock, flags);
+       up(&s->skt_sem);
 
        return count;
 }
@@ -282,6 +277,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->requery(s);
+                               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,12 +335,14 @@ 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)
+static int __devinit pccard_sysfs_add_socket(struct class_device *class_dev,
+                                            struct class_interface *class_intf)
 {
        struct class_device_attribute **attr;
        int ret = 0;
@@ -317,7 +358,8 @@ static int __devinit pccard_sysfs_add_socket(struct class_device *class_dev)
        return ret;
 }
 
-static void __devexit pccard_sysfs_remove_socket(struct class_device *class_dev)
+static void __devexit pccard_sysfs_remove_socket(struct class_device *class_dev,
+                                                struct class_interface *class_intf)
 {
        struct class_device_attribute **attr;