bk://bk.arm.linux.org.uk/linux-2.6-pcmcia linux@de.rmk.(none)|ChangeSet|20040706202122|02650 linux # This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2004/07/06 21:21:22+01:00 linux@de.rmk.(none) # [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. # # drivers/pcmcia/socket_sysfs.c # 2004/07/06 21:17:48+01:00 linux@de.rmk.(none) +32 -0 # [PATCH] card insert / eject # # drivers/pcmcia/ds.c # 2004/07/06 21:17:48+01:00 linux@de.rmk.(none) +2 -2 # [PATCH] card insert / eject # # drivers/pcmcia/cs.c # 2004/07/06 21:17:47+01:00 linux@de.rmk.(none) +8 -6 # [PATCH] card insert / eject # # ChangeSet # 2004/07/06 21:12:33+01:00 linux@de.rmk.(none) # [PCMCIA] card vpp / vcc # # Patch from Dominik Brodowski # # Add attributes "card_vpp" and "card_vcc" which return these voltages, # like "3.3V" # # drivers/pcmcia/socket_sysfs.c # 2004/07/06 21:04:53+01:00 linux@de.rmk.(none) +20 -0 # [PATCH] card vpp / vcc # # ChangeSet # 2004/07/06 20:57:25+01:00 linux@de.rmk.(none) # [PCMCIA] card voltage # # Patch from Dominik Brodowski # # Add an attribute "card_voltage" which returns the card's voltage # requirements: # # "5.0V", "3.3V" or "X.XV". # # drivers/pcmcia/socket_sysfs.c # 2004/07/06 20:53:45+01:00 linux@de.rmk.(none) +17 -0 # [PATCH] card voltage # # ChangeSet # 2004/07/06 20:45:17+01:00 linux@de.rmk.(none) # [PCMCIA] core socket sysfs support, export card type # # Patch from Dominik Brodowski # # Add a first socket-related sysfs entry; and to keep things ordered, # do so in a new file drivers/pcmcia/socket_sysfs.c. To keep things # easy, all files will be present all the time, even if no card is in # the socket at a specific moment -- however, accessing the file will # result in -ENODEV then, so that # # # cat /sys/class/pcmcia_socket/pcmcia_socket1/card_type # # will cause an error message like # # "cat: card_type: No such device" # # which is quite self-explanatory. # # # The attribute "card_type" will return either "16-bit" or "32-bit", # depending on whether the PCCard is a 16-bit PCMCIA card or a 32-bit # CardBus card. The result "invalid" should not happen, and if it # happens, something strange is going on. # # drivers/pcmcia/socket_sysfs.c # 2004/07/06 20:41:25+01:00 linux@de.rmk.(none) +76 -0 # # drivers/pcmcia/socket_sysfs.c # 2004/07/06 20:41:25+01:00 linux@de.rmk.(none) +0 -0 # BitKeeper file /usr/src/bk/linux-2.6-pcmcia/drivers/pcmcia/socket_sysfs.c # # drivers/pcmcia/cs_internal.h # 2004/07/06 20:41:25+01:00 linux@de.rmk.(none) +3 -0 # [PATCH] core socket sysfs support, export card type # # drivers/pcmcia/cs.c # 2004/07/06 20:41:25+01:00 linux@de.rmk.(none) +7 -0 # [PATCH] core socket sysfs support, export card type # # drivers/pcmcia/Makefile # 2004/07/06 20:41:24+01:00 linux@de.rmk.(none) +1 -1 # [PATCH] core socket sysfs support, export card type # # ChangeSet # 2004/07/05 21:33:44+01:00 linux@de.rmk.(none) # [PCMCIA] check for proper registration with device core # # Patch from Dominik Brodowski # # Fail if registration of socket with driver core failed. This is # necessary so that socket-related sysfs entries will appear always # if a socket thread is up and running. # # drivers/pcmcia/cs.c # 2004/07/05 21:30:45+01:00 linux@de.rmk.(none) +8 -3 # [PATCH] check for proper registration with device core # # ChangeSet # 2004/06/26 18:49:10-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-pcmcia # # drivers/pcmcia/yenta_socket.c # 2004/06/26 18:49:07-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/pcmcia/i82365.c # 2004/06/26 18:49:07-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/ide/legacy/ide-cs.c # 2004/06/26 18:49:07-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/06/24 12:55:15-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-pcmcia # # drivers/ide/legacy/ide-cs.c # 2004/06/24 12:55:11-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/06/20 23:57:00-07:00 akpm@bix.(none) # Merge bk://bk.arm.linux.org.uk/linux-2.6-pcmcia # into bix.(none):/usr/src/bk-pcmcia # # drivers/pcmcia/yenta_socket.c # 2004/06/20 23:56:57-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/pcmcia/i82365.c # 2004/06/20 23:56:57-07:00 akpm@bix.(none) +0 -0 # Auto merged # diff -Nru a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile --- a/drivers/pcmcia/Makefile 2004-07-08 18:18:20 -07:00 +++ b/drivers/pcmcia/Makefile 2004-07-08 18:18:20 -07:00 @@ -18,7 +18,7 @@ obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_core.o sa1111_cs.o obj-$(CONFIG_PCMCIA_PXA2XX) += pxa2xx_core.o pxa2xx_cs.o -pcmcia_core-y += cistpl.o rsrc_mgr.o bulkmem.o cs.o +pcmcia_core-y += cistpl.o rsrc_mgr.o bulkmem.o cs.o socket_sysfs.o pcmcia_core-$(CONFIG_CARDBUS) += cardbus.o sa11xx_core-y += soc_common.o sa11xx_base.o diff -Nru a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c --- a/drivers/pcmcia/cs.c 2004-07-08 18:18:20 -07:00 +++ b/drivers/pcmcia/cs.c 2004-07-08 18:18:20 -07:00 @@ -264,7 +264,10 @@ goto err; wait_for_completion(&socket->thread_done); - BUG_ON(!socket->thread); + if(!socket->thread) { + printk(KERN_WARNING "PCMCIA: warning: socket thread for socket %p did not start\n", socket); + return -EIO; + } pcmcia_parse_events(socket, SS_DETECT); return 0; @@ -678,9 +681,8 @@ int ret; daemonize("pccardd"); - skt->thread = current; - complete(&skt->thread_done); + skt->thread = current; skt->socket = dead_socket; skt->ops->init(skt); skt->ops->set_socket(skt, &skt->socket); @@ -690,7 +692,17 @@ if (ret) { printk(KERN_WARNING "PCMCIA: unable to register socket 0x%p\n", skt); + skt->thread = NULL; + complete_and_exit(&skt->thread_done, 0); } + if (pccard_sysfs_init(skt)) { + printk(KERN_WARNING "PCMCIA: unable to register sysfs attributes for socket 0x%p\n", + skt); + skt->thread = NULL; + class_device_unregister(&skt->dev); + complete_and_exit(&skt->thread_done, 0); + } + complete(&skt->thread_done); add_wait_queue(&skt->thread_wait, &wait); for (;;) { @@ -2031,16 +2043,18 @@ down(&skt->skt_sem); do { if (!(skt->state & SOCKET_PRESENT)) { - ret = CS_NO_CARD; + ret = -ENODEV; break; } ret = send_event(skt, CS_EVENT_EJECTION_REQUEST, CS_EVENT_PRI_LOW); - if (ret != 0) + if (ret != 0) { + ret = -EINVAL; break; + } socket_remove(skt); - ret = CS_SUCCESS; + ret = 0; } while (0); up(&skt->skt_sem); @@ -2056,14 +2070,14 @@ down(&skt->skt_sem); do { if (skt->state & SOCKET_PRESENT) { - ret = CS_IN_USE; + ret = -EBUSY; break; } if (socket_insert(skt) == CS_NO_CARD) { - ret = CS_NO_CARD; + ret = -ENODEV; break; } - ret = CS_SUCCESS; + ret = 0; } while (0); up(&skt->skt_sem); diff -Nru a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h --- a/drivers/pcmcia/cs_internal.h 2004-07-08 18:18:20 -07:00 +++ b/drivers/pcmcia/cs_internal.h 2004-07-08 18:18:20 -07:00 @@ -192,6 +192,9 @@ int adjust_resource_info(client_handle_t handle, adjust_t *adj); void release_resource_db(void); +/* In socket_sysfs.c */ +int pccard_sysfs_init(struct pcmcia_socket *s); + extern struct rw_semaphore pcmcia_socket_list_rwsem; extern struct list_head pcmcia_socket_list; diff -Nru a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c --- a/drivers/pcmcia/ds.c 2004-07-08 18:18:20 -07:00 +++ b/drivers/pcmcia/ds.c 2004-07-08 18:18:20 -07:00 @@ -973,10 +973,10 @@ ret = pcmcia_resume_card(s->parent); break; case DS_EJECT_CARD: - ret = pcmcia_eject_card(s->parent); + err = pcmcia_eject_card(s->parent); break; case DS_INSERT_CARD: - ret = pcmcia_insert_card(s->parent); + err = pcmcia_insert_card(s->parent); break; case DS_ACCESS_CONFIGURATION_REGISTER: if ((buf.conf_reg.Action == CS_WRITE) && !capable(CAP_SYS_ADMIN)) diff -Nru a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/pcmcia/socket_sysfs.c 2004-07-08 18:18:20 -07:00 @@ -0,0 +1,145 @@ +/* + * socket_sysfs.c -- most of socket-related sysfs output + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * (C) 2003 - 2004 Dominik Brodowski + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define IN_CARD_SERVICES +#include +#include +#include +#include +#include +#include +#include +#include +#include "cs_internal.h" + +#define to_socket(_dev) container_of(_dev, struct pcmcia_socket, dev) + +static ssize_t pccard_show_type(struct class_device *dev, char *buf) +{ + int val; + struct pcmcia_socket *s = to_socket(dev); + + if (!(s->state & SOCKET_PRESENT)) + return -ENODEV; + s->ops->get_status(s, &val); + if (val & SS_CARDBUS) + return sprintf(buf, "32-bit\n"); + if (val & SS_DETECT) + return sprintf(buf, "16-bit\n"); + return sprintf(buf, "invalid\n"); +} +static CLASS_DEVICE_ATTR(card_type, 0400, pccard_show_type, NULL); + +static ssize_t pccard_show_voltage(struct class_device *dev, char *buf) +{ + int val; + struct pcmcia_socket *s = to_socket(dev); + + if (!(s->state & SOCKET_PRESENT)) + return -ENODEV; + s->ops->get_status(s, &val); + if (val & SS_3VCARD) + return sprintf(buf, "3.3V\n"); + if (val & SS_XVCARD) + return sprintf(buf, "X.XV\n"); + return sprintf(buf, "5.0V\n"); +} +static CLASS_DEVICE_ATTR(card_voltage, 0400, pccard_show_voltage, NULL); + +static ssize_t pccard_show_vpp(struct class_device *dev, char *buf) +{ + struct pcmcia_socket *s = to_socket(dev); + if (!(s->state & SOCKET_PRESENT)) + return -ENODEV; + return sprintf(buf, "%d.%dV\n", s->socket.Vpp / 10, s->socket.Vpp % 10); +} +static CLASS_DEVICE_ATTR(card_vpp, 0400, pccard_show_vpp, NULL); + +static ssize_t pccard_show_vcc(struct class_device *dev, char *buf) +{ + struct pcmcia_socket *s = to_socket(dev); + if (!(s->state & SOCKET_PRESENT)) + return -ENODEV; + return sprintf(buf, "%d.%dV\n", s->socket.Vcc / 10, s->socket.Vcc % 10); +} +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[] = { + &class_device_attr_card_type, + &class_device_attr_card_voltage, + &class_device_attr_card_vpp, + &class_device_attr_card_vcc, + &class_device_attr_card_insert, + &class_device_attr_card_eject, + NULL, +}; + +int pccard_sysfs_init(struct pcmcia_socket *s) +{ + struct class_device_attribute *attr; + unsigned int i; + int ret = 0; + for (i = 0; (attr = pccard_socket_attributes[i]); i++) { + if ((ret = class_device_create_file(&s->dev, attr))) + return (ret); + } + return (ret); +}