[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>
This commit is contained in:
Родитель
7f299bccb4
Коммит
ff1fa9ef3c
|
@ -160,6 +160,7 @@ struct pcmcia_callback{
|
||||||
struct module *owner;
|
struct module *owner;
|
||||||
int (*event) (struct pcmcia_socket *s, event_t event, int priority);
|
int (*event) (struct pcmcia_socket *s, event_t event, int priority);
|
||||||
int (*resources_done) (struct pcmcia_socket *s);
|
int (*resources_done) (struct pcmcia_socket *s);
|
||||||
|
void (*replace_cis) (void);
|
||||||
};
|
};
|
||||||
|
|
||||||
int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c);
|
int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c);
|
||||||
|
|
|
@ -653,6 +653,11 @@ static inline void pcmcia_add_pseudo_device(struct pcmcia_bus_socket *s)
|
||||||
return;
|
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,
|
static inline int pcmcia_devmatch(struct pcmcia_device *dev,
|
||||||
struct pcmcia_device_id *did)
|
struct pcmcia_device_id *did)
|
||||||
|
@ -1766,6 +1771,7 @@ static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev)
|
||||||
s->callback.owner = THIS_MODULE;
|
s->callback.owner = THIS_MODULE;
|
||||||
s->callback.event = &ds_event;
|
s->callback.event = &ds_event;
|
||||||
s->callback.resources_done = &pcmcia_card_add;
|
s->callback.resources_done = &pcmcia_card_add;
|
||||||
|
s->callback.replace_cis = &pcmcia_bus_rescan;
|
||||||
socket->pcmcia = s;
|
socket->pcmcia = s;
|
||||||
|
|
||||||
ret = pccard_register_pcmcia(socket, &s->callback);
|
ret = pccard_register_pcmcia(socket, &s->callback);
|
||||||
|
|
|
@ -282,6 +282,50 @@ static ssize_t pccard_show_cis(struct kobject *kobj, char *buf, loff_t off, size
|
||||||
return (count);
|
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[] = {
|
static struct class_device_attribute *pccard_socket_attributes[] = {
|
||||||
&class_device_attr_card_type,
|
&class_device_attr_card_type,
|
||||||
|
@ -296,9 +340,10 @@ static struct class_device_attribute *pccard_socket_attributes[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct bin_attribute pccard_cis_attr = {
|
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,
|
.size = 0x200,
|
||||||
.read = pccard_show_cis,
|
.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)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче