Commit 61e4f592 authored by Dominik Brodowski's avatar Dominik Brodowski Committed by Russell King

[PCMCIA] card insert / eject

Patch from Dominik Brodowski

Add two further attributes, "card_insert" and "card_eject". Reading
these files will fail; but writing _anything_ non-empty to these
files will execute an user insert/ejection request -- equivalent
to "cardctl insert", "cardctl eject".

To ensure proper error values to userspace, transform the return
values from CS_ error codes to -E error codes.
parent 4249c814
...@@ -2043,16 +2043,18 @@ int pcmcia_eject_card(struct pcmcia_socket *skt) ...@@ -2043,16 +2043,18 @@ int pcmcia_eject_card(struct pcmcia_socket *skt)
down(&skt->skt_sem); down(&skt->skt_sem);
do { do {
if (!(skt->state & SOCKET_PRESENT)) { if (!(skt->state & SOCKET_PRESENT)) {
ret = CS_NO_CARD; ret = -ENODEV;
break; break;
} }
ret = send_event(skt, CS_EVENT_EJECTION_REQUEST, CS_EVENT_PRI_LOW); ret = send_event(skt, CS_EVENT_EJECTION_REQUEST, CS_EVENT_PRI_LOW);
if (ret != 0) if (ret != 0) {
ret = -EINVAL;
break; break;
}
socket_remove(skt); socket_remove(skt);
ret = CS_SUCCESS; ret = 0;
} while (0); } while (0);
up(&skt->skt_sem); up(&skt->skt_sem);
...@@ -2068,14 +2070,14 @@ int pcmcia_insert_card(struct pcmcia_socket *skt) ...@@ -2068,14 +2070,14 @@ int pcmcia_insert_card(struct pcmcia_socket *skt)
down(&skt->skt_sem); down(&skt->skt_sem);
do { do {
if (skt->state & SOCKET_PRESENT) { if (skt->state & SOCKET_PRESENT) {
ret = CS_IN_USE; ret = -EBUSY;
break; break;
} }
if (socket_insert(skt) == CS_NO_CARD) { if (socket_insert(skt) == CS_NO_CARD) {
ret = CS_NO_CARD; ret = -ENODEV;
break; break;
} }
ret = CS_SUCCESS; ret = 0;
} while (0); } while (0);
up(&skt->skt_sem); up(&skt->skt_sem);
......
...@@ -973,10 +973,10 @@ static int ds_ioctl(struct inode * inode, struct file * file, ...@@ -973,10 +973,10 @@ static int ds_ioctl(struct inode * inode, struct file * file,
ret = pcmcia_resume_card(s->parent); ret = pcmcia_resume_card(s->parent);
break; break;
case DS_EJECT_CARD: case DS_EJECT_CARD:
ret = pcmcia_eject_card(s->parent); err = pcmcia_eject_card(s->parent);
break; break;
case DS_INSERT_CARD: case DS_INSERT_CARD:
ret = pcmcia_insert_card(s->parent); err = pcmcia_insert_card(s->parent);
break; break;
case DS_ACCESS_CONFIGURATION_REGISTER: case DS_ACCESS_CONFIGURATION_REGISTER:
if ((buf.conf_reg.Action == CS_WRITE) && !capable(CAP_SYS_ADMIN)) if ((buf.conf_reg.Action == CS_WRITE) && !capable(CAP_SYS_ADMIN))
......
...@@ -92,11 +92,43 @@ static ssize_t pccard_show_vcc(struct class_device *dev, char *buf) ...@@ -92,11 +92,43 @@ static ssize_t pccard_show_vcc(struct class_device *dev, char *buf)
} }
static CLASS_DEVICE_ATTR(card_vcc, 0400, pccard_show_vcc, NULL); static CLASS_DEVICE_ATTR(card_vcc, 0400, pccard_show_vcc, NULL);
static ssize_t pccard_store_insert(struct class_device *dev, const char *buf, size_t count)
{
ssize_t ret;
struct pcmcia_socket *s = to_socket(dev);
if (!count)
return -EINVAL;
ret = pcmcia_insert_card(s);
return ret ? ret : count;
}
static CLASS_DEVICE_ATTR(card_insert, 0200, NULL, pccard_store_insert);
static ssize_t pccard_store_eject(struct class_device *dev, const char *buf, size_t count)
{
ssize_t ret;
struct pcmcia_socket *s = to_socket(dev);
if (!count)
return -EINVAL;
ret = pcmcia_eject_card(s);
return ret ? ret : count;
}
static CLASS_DEVICE_ATTR(card_eject, 0200, NULL, pccard_store_eject);
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,
&class_device_attr_card_voltage, &class_device_attr_card_voltage,
&class_device_attr_card_vpp, &class_device_attr_card_vpp,
&class_device_attr_card_vcc, &class_device_attr_card_vcc,
&class_device_attr_card_insert,
&class_device_attr_card_eject,
NULL, NULL,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment