diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-06 12:25:06 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-06 12:25:06 -0700 |
commit | 1685e633b396b0f3dabbc9fa5d65dfefe6435250 (patch) | |
tree | ee83e26e2468ca1518a1b065c690159e12c8def9 /drivers/pcmcia | |
parent | 1cfd2bda8c486ae0e7a8005354758ebb68172bca (diff) | |
parent | 127c03cdbad9bd5af5d7f33bd31a1015a90cb77f (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6:
pcmcia: avoid buffer overflow in pcmcia_setup_isa_irq
pcmcia: do not request windows if you don't need to
pcmcia: insert PCMCIA device resources into resource tree
pcmcia: export resource information to sysfs
pcmcia: use struct resource for PCMCIA devices, part 2
pcmcia: remove memreq_t
pcmcia: move local definitions out of include/pcmcia/cs.h
pcmcia: do not use io_req_t when calling pcmcia_request_io()
pcmcia: do not use io_req_t after call to pcmcia_request_io()
pcmcia: use struct resource for PCMCIA devices
pcmcia: clean up cs.h
pcmcia: use pcmica_{read,write}_config_byte
pcmcia: remove cs_types.h
pcmcia: remove unused flag, simplify headers
pcmcia: remove obsolete CS_EVENT_ definitions
pcmcia: split up central event handler
pcmcia: simplify event callback
pcmcia: remove obsolete ioctl
Conflicts in:
- drivers/staging/comedi/drivers/*
- drivers/staging/wlags49_h2/wl_cs.c
due to dev_info_t and whitespace changes
Diffstat (limited to 'drivers/pcmcia')
27 files changed, 320 insertions, 1472 deletions
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile index d006e8beab9c..7a2b1604bf1c 100644 --- a/drivers/pcmcia/Makefile +++ b/drivers/pcmcia/Makefile @@ -7,7 +7,6 @@ pcmcia_core-$(CONFIG_CARDBUS) += cardbus.o obj-$(CONFIG_PCCARD) += pcmcia_core.o pcmcia-y += ds.o pcmcia_resource.o cistpl.o pcmcia_cis.o -pcmcia-$(CONFIG_PCMCIA_IOCTL) += pcmcia_ioctl.o obj-$(CONFIG_PCMCIA) += pcmcia.o pcmcia_rsrc-y += rsrc_mgr.o diff --git a/drivers/pcmcia/au1000_generic.h b/drivers/pcmcia/au1000_generic.h index a324d329dea6..67530cefcf3c 100644 --- a/drivers/pcmcia/au1000_generic.h +++ b/drivers/pcmcia/au1000_generic.h @@ -23,7 +23,6 @@ /* include the world */ -#include <pcmcia/cs_types.h> #include <pcmcia/cs.h> #include <pcmcia/ss.h> #include <pcmcia/cistpl.h> diff --git a/drivers/pcmcia/au1000_pb1x00.c b/drivers/pcmcia/au1000_pb1x00.c index 5a979cb8f3e6..807f2d75dad3 100644 --- a/drivers/pcmcia/au1000_pb1x00.c +++ b/drivers/pcmcia/au1000_pb1x00.c @@ -31,11 +31,9 @@ #include <linux/proc_fs.h> #include <linux/types.h> -#include <pcmcia/cs_types.h> #include <pcmcia/cs.h> #include <pcmcia/ss.h> #include <pcmcia/cistpl.h> -#include <pcmcia/bus_ops.h> #include <asm/io.h> #include <asm/irq.h> diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c index 8844bc3e3118..91414a0ddc44 100644 --- a/drivers/pcmcia/cistpl.c +++ b/drivers/pcmcia/cistpl.c @@ -27,7 +27,6 @@ #include <asm/byteorder.h> #include <asm/unaligned.h> -#include <pcmcia/cs_types.h> #include <pcmcia/ss.h> #include <pcmcia/cs.h> #include <pcmcia/cisreg.h> @@ -54,6 +53,9 @@ static const u_int exponent[] = { /* Upper limit on reasonable # of tuples */ #define MAX_TUPLES 200 +/* Bits in IRQInfo1 field */ +#define IRQ_INFO2_VALID 0x10 + /* 16-bit CIS? */ static int cis_width; module_param(cis_width, int, 0444); @@ -210,7 +212,7 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, * Probably only useful for writing one-byte registers. Must be called * with ops_mutex held. */ -void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, +int pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, u_int len, void *ptr) { void __iomem *sys, *end; @@ -232,7 +234,7 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, ((cis_width) ? MAP_16BIT : 0)); if (!sys) { dev_dbg(&s->dev, "could not map memory\n"); - return; /* FIXME: Error */ + return -EINVAL; } writeb(flags, sys+CISREG_ICTRL0); @@ -257,7 +259,7 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, sys = set_cis_map(s, card_offset, flags); if (!sys) { dev_dbg(&s->dev, "could not map memory\n"); - return; /* FIXME: error */ + return -EINVAL; } end = sys + s->map_size; @@ -271,6 +273,7 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, addr = 0; } } + return 0; } diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index 976d80706eae..2ec8ac97445c 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c @@ -32,7 +32,6 @@ #include <asm/system.h> #include <asm/irq.h> -#include <pcmcia/cs_types.h> #include <pcmcia/ss.h> #include <pcmcia/cs.h> #include <pcmcia/cistpl.h> @@ -252,38 +251,6 @@ struct pcmcia_socket *pcmcia_get_socket_by_nr(unsigned int nr) } EXPORT_SYMBOL(pcmcia_get_socket_by_nr); -/* - * The central event handler. Send_event() sends an event to the - * 16-bit subsystem, which then calls the relevant device drivers. - * Parse_events() interprets the event bits from - * a card status change report. Do_shutdown() handles the high - * priority stuff associated with a card removal. - */ - -/* NOTE: send_event needs to be called with skt->sem held. */ - -static int send_event(struct pcmcia_socket *s, event_t event, int priority) -{ - int ret; - - if ((s->state & SOCKET_CARDBUS) && (event != CS_EVENT_CARD_REMOVAL)) - return 0; - - dev_dbg(&s->dev, "send_event(event %d, pri %d, callback 0x%p)\n", - event, priority, s->callback); - - if (!s->callback) - return 0; - if (!try_module_get(s->callback->owner)) - return 0; - - ret = s->callback->event(s, event, priority); - - module_put(s->callback->owner); - - return ret; -} - static int socket_reset(struct pcmcia_socket *skt) { int status, i; @@ -326,7 +293,8 @@ static void socket_shutdown(struct pcmcia_socket *s) dev_dbg(&s->dev, "shutdown\n"); - send_event(s, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH); + if (s->callback) + s->callback->remove(s); mutex_lock(&s->ops_mutex); s->state &= SOCKET_INUSE | SOCKET_PRESENT; @@ -477,7 +445,8 @@ static int socket_insert(struct pcmcia_socket *skt) dev_dbg(&skt->dev, "insert done\n"); mutex_unlock(&skt->ops_mutex); - send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW); + if (!(skt->state & SOCKET_CARDBUS) && (skt->callback)) + skt->callback->add(skt); } else { mutex_unlock(&skt->ops_mutex); socket_shutdown(skt); @@ -494,7 +463,6 @@ static int socket_suspend(struct pcmcia_socket *skt) mutex_lock(&skt->ops_mutex); skt->suspended_state = skt->state; - send_event(skt, CS_EVENT_PM_SUSPEND, CS_EVENT_PRI_LOW); skt->socket = dead_socket; skt->ops->set_socket(skt, &skt->socket); if (skt->ops->suspend) @@ -555,8 +523,8 @@ static int socket_late_resume(struct pcmcia_socket *skt) return 0; } #endif - - send_event(skt, CS_EVENT_PM_RESUME, CS_EVENT_PRI_LOW); + if (!(skt->state & SOCKET_CARDBUS) && (skt->callback)) + skt->callback->early_resume(skt); return 0; } @@ -654,16 +622,8 @@ static int pccardd(void *__skt) spin_unlock_irqrestore(&skt->thread_lock, flags); mutex_lock(&skt->skt_mutex); - if (events) { - if (events & SS_DETECT) - socket_detect_change(skt); - if (events & SS_BATDEAD) - send_event(skt, CS_EVENT_BATTERY_DEAD, CS_EVENT_PRI_LOW); - if (events & SS_BATWARN) - send_event(skt, CS_EVENT_BATTERY_LOW, CS_EVENT_PRI_LOW); - if (events & SS_READY) - send_event(skt, CS_EVENT_READY_CHANGE, CS_EVENT_PRI_LOW); - } + if (events & SS_DETECT) + socket_detect_change(skt); if (sysfs_events) { if (sysfs_events & PCMCIA_UEVENT_EJECT) @@ -783,7 +743,7 @@ int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c) s->callback = c; if ((s->state & (SOCKET_PRESENT|SOCKET_CARDBUS)) == SOCKET_PRESENT) - send_event(s, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW); + s->callback->add(s); } else s->callback = NULL; err: @@ -823,20 +783,13 @@ int pcmcia_reset_card(struct pcmcia_socket *skt) break; } - ret = send_event(skt, CS_EVENT_RESET_REQUEST, CS_EVENT_PRI_LOW); - if (ret == 0) { - send_event(skt, CS_EVENT_RESET_PHYSICAL, CS_EVENT_PRI_LOW); - if (skt->callback) - skt->callback->suspend(skt); - mutex_lock(&skt->ops_mutex); - ret = socket_reset(skt); - mutex_unlock(&skt->ops_mutex); - if (ret == 0) { - send_event(skt, CS_EVENT_CARD_RESET, CS_EVENT_PRI_LOW); - if (skt->callback) - skt->callback->resume(skt); - } - } + if (skt->callback) + skt->callback->suspend(skt); + mutex_lock(&skt->ops_mutex); + ret = socket_reset(skt); + mutex_unlock(&skt->ops_mutex); + if ((ret == 0) && (skt->callback)) + skt->callback->resume(skt); ret = 0; } while (0); diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h index 4126a75445ea..da055dc14d98 100644 --- a/drivers/pcmcia/cs_internal.h +++ b/drivers/pcmcia/cs_internal.h @@ -10,7 +10,7 @@ * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. * * (C) 1999 David A. Hinds - * (C) 2003 - 2008 Dominik Brodowski + * (C) 2003 - 2010 Dominik Brodowski * * * This file contains definitions _only_ needed by the PCMCIA core modules. @@ -26,6 +26,9 @@ /* Flags in client state */ #define CLIENT_WIN_REQ(i) (0x1<<(i)) +/* Flag to access all functions */ +#define BIND_FN_ALL 0xff + /* Each card function gets one of these guys */ typedef struct config_t { struct kref ref; @@ -35,7 +38,10 @@ typedef struct config_t { unsigned int ConfigBase; unsigned char Status, Pin, Copy, Option, ExtStatus; unsigned int CardValues; - io_req_t io; + + struct resource io[MAX_IO_WIN]; /* io ports */ + struct resource mem[MAX_WIN]; /* mem areas */ + struct { u_int Attributes; } irq; @@ -56,18 +62,11 @@ struct pccard_resource_ops { unsigned int attr, unsigned int *base, unsigned int num, - unsigned int align); + unsigned int align, + struct resource **parent); struct resource* (*find_mem) (unsigned long base, unsigned long num, unsigned long align, int low, struct pcmcia_socket *s); - int (*add_io) (struct pcmcia_socket *s, - unsigned int action, - unsigned long r_start, - unsigned long r_end); - int (*add_mem) (struct pcmcia_socket *s, - unsigned int action, - unsigned long r_start, - unsigned long r_end); int (*init) (struct pcmcia_socket *s); void (*exit) (struct pcmcia_socket *s); }; @@ -114,11 +113,12 @@ void cb_free(struct pcmcia_socket *s); struct pcmcia_callback{ struct module *owner; - int (*event) (struct pcmcia_socket *s, - event_t event, int priority); + int (*add) (struct pcmcia_socket *s); + int (*remove) (struct pcmcia_socket *s); void (*requery) (struct pcmcia_socket *s); int (*validate) (struct pcmcia_socket *s, unsigned int *i); int (*suspend) (struct pcmcia_socket *s); + int (*early_resume) (struct pcmcia_socket *s); int (*resume) (struct pcmcia_socket *s); }; @@ -146,6 +146,8 @@ void pcmcia_put_socket(struct pcmcia_socket *skt); /* ds.c */ extern struct bus_type pcmcia_bus_type; +struct pcmcia_device; + /* pcmcia_resource.c */ extern int pcmcia_release_configuration(struct pcmcia_device *p_dev); extern int pcmcia_validate_mem(struct pcmcia_socket *s); @@ -163,8 +165,8 @@ extern struct bin_attribute pccard_cis_attr; int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, u_int len, void *ptr); -void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, - u_int addr, u_int len, void *ptr); +int pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, + u_int addr, u_int len, void *ptr); void release_cis_mem(struct pcmcia_socket *s); void destroy_cis_cache(struct pcmcia_socket *s); int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, @@ -188,34 +190,4 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple); - -#ifdef CONFIG_PCMCIA_IOCTL -/* ds.c */ -extern struct pcmcia_device *pcmcia_get_dev(struct pcmcia_device *p_dev); -extern void pcmcia_put_dev(struct pcmcia_device *p_dev); - -struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, - unsigned int function); - -/* pcmcia_ioctl.c */ -extern void __init pcmcia_setup_ioctl(void); -extern void __exit pcmcia_cleanup_ioctl(void); -extern void handle_event(struct pcmcia_socket *s, event_t event); -extern int handle_request(struct pcmcia_socket *s, event_t event); - -#else /* CONFIG_PCMCIA_IOCTL */ - -static inline void __init pcmcia_setup_ioctl(void) { return; } -static inline void __exit pcmcia_cleanup_ioctl(void) { return; } -static inline void handle_event(struct pcmcia_socket *s, event_t event) -{ - return; -} -static inline int handle_request(struct pcmcia_socket *s, event_t event) -{ - return 0; -} - -#endif /* CONFIG_PCMCIA_IOCTL */ - #endif /* _LINUX_CS_INTERNAL_H */ diff --git a/drivers/pcmcia/db1xxx_ss.c b/drivers/pcmcia/db1xxx_ss.c index 0f4cc3f00028..27575e6378a1 100644 --- a/drivers/pcmcia/db1xxx_ss.c +++ b/drivers/pcmcia/db1xxx_ss.c @@ -29,7 +29,6 @@ #include <linux/slab.h> #include <linux/spinlock.h> -#include <pcmcia/cs_types.h> #include <pcmcia/ss.h> #include <asm/mach-au1x00/au1000.h> diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index eac961463be2..55570d9e1e4c 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -10,7 +10,7 @@ * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. * * (C) 1999 David A. Hinds - * (C) 2003 - 2006 Dominik Brodowski + * (C) 2003 - 2010 Dominik Brodowski */ #include <linux/kernel.h> @@ -26,7 +26,6 @@ #include <linux/dma-mapping.h> #include <linux/slab.h> -#include <pcmcia/cs_types.h> #include <pcmcia/cs.h> #include <pcmcia/cistpl.h> #include <pcmcia/ds.h> @@ -213,7 +212,7 @@ EXPORT_SYMBOL(pcmcia_unregister_driver); /* pcmcia_device handling */ -struct pcmcia_device *pcmcia_get_dev(struct pcmcia_device *p_dev) +static struct pcmcia_device *pcmcia_get_dev(struct pcmcia_device *p_dev) { struct device *tmp_dev; tmp_dev = get_device(&p_dev->dev); @@ -222,7 +221,7 @@ struct pcmcia_device *pcmcia_get_dev(struct pcmcia_device *p_dev) return to_pcmcia_dev(tmp_dev); } -void pcmcia_put_dev(struct pcmcia_device *p_dev) +static void pcmcia_put_dev(struct pcmcia_device *p_dev) { if (p_dev) put_device(&p_dev->dev); @@ -294,7 +293,7 @@ static int pcmcia_device_probe(struct device *dev) } mutex_lock(&s->ops_mutex); - if ((s->pcmcia_state.has_pfc) && + if ((s->pcmcia_pfc) && (p_dev->socket->device_count == 1) && (p_dev->device_no == 0)) pcmcia_parse_uevents(s, PCMCIA_UEVENT_REQUERY); mutex_unlock(&s->ops_mutex); @@ -359,7 +358,7 @@ static int pcmcia_device_remove(struct device *dev) * pseudo multi-function card, we need to unbind * all devices */ - if ((p_dev->socket->pcmcia_state.has_pfc) && + if ((p_dev->socket->pcmcia_pfc) && (p_dev->socket->device_count > 0) && (p_dev->device_no == 0)) pcmcia_card_remove(p_dev->socket, p_dev); @@ -477,7 +476,8 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev) } -struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int function) +static struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, + unsigned int function) { struct pcmcia_device *p_dev, *tmp_dev; int i; @@ -531,7 +531,6 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu list_for_each_entry(tmp_dev, &s->devices_list, socket_device_list) if (p_dev->func == tmp_dev->func) { p_dev->function_config = tmp_dev->function_config; - p_dev->io = tmp_dev->io; p_dev->irq = tmp_dev->irq; kref_get(&p_dev->function_config->ref); } @@ -544,15 +543,29 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu "IRQ setup failed -- device might not work\n"); if (!p_dev->function_config) { + config_t *c; dev_dbg(&p_dev->dev, "creating config_t\n"); - p_dev->function_config = kzalloc(sizeof(struct config_t), - GFP_KERNEL); - if (!p_dev->function_config) { + c = kzalloc(sizeof(struct config_t), GFP_KERNEL); + if (!c) { mutex_unlock(&s->ops_mutex); goto err_unreg; } - kref_init(&p_dev->function_config->ref); + p_dev->function_config = c; + kref_init(&c->ref); + for (i = 0; i < MAX_IO_WIN; i++) { + c->io[i].name = p_dev->devname; + c->io[i].flags = IORESOURCE_IO; + } + for (i = 0; i< MAX_WIN; i++) { + c->mem[i].name = p_dev->devname; + c->mem[i].flags = IORESOURCE_MEM; + } } + for (i = 0; i < MAX_IO_WIN; i++) + p_dev->resource[i] = &p_dev->function_config->io[i]; + for (; i < (MAX_IO_WIN + MAX_WIN); i++) + p_dev->resource[i] = &p_dev->function_config->mem[i-MAX_IO_WIN]; + mutex_unlock(&s->ops_mutex); dev_printk(KERN_NOTICE, &p_dev->dev, @@ -680,7 +693,7 @@ static void pcmcia_requery(struct pcmcia_socket *s) * call pcmcia_device_add() -- which will fail if both * devices are already registered. */ mutex_lock(&s->ops_mutex); - has_pfc = s->pcmcia_state.has_pfc; + has_pfc = s->pcmcia_pfc; mutex_unlock(&s->ops_mutex); if (has_pfc) pcmcia_device_add(s, 0); @@ -812,7 +825,7 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev, if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) { dev_dbg(&dev->dev, "this is a pseudo-multi-function device\n"); mutex_lock(&dev->socket->ops_mutex); - dev->socket->pcmcia_state.has_pfc = 1; + dev->socket->pcmcia_pfc = 1; mutex_unlock(&dev->socket->ops_mutex); if (dev->device_no != did->device_no) return 0; @@ -826,7 +839,7 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev, /* if this is a pseudo-multi-function device, * we need explicit matches */ - if (dev->socket->pcmcia_state.has_pfc) + if (dev->socket->pcmcia_pfc) return 0; if (dev->device_no) return 0; @@ -885,14 +898,6 @@ static int pcmcia_bus_match(struct device *dev, struct device_driver *drv) } mutex_unlock(&p_drv->dynids.lock); -#ifdef CONFIG_PCMCIA_IOCTL - /* matching by cardmgr */ - if (p_dev->cardmgr == p_drv) { - dev_dbg(dev, "cardmgr matched to %s\n", drv->name); - return 1; - } -#endif - while (did && did->match_flags) { dev_dbg(dev, "trying to match to %s\n", drv->name); if (pcmcia_devmatch(p_dev, did)) { @@ -1006,6 +1011,18 @@ pcmcia_device_stringattr(prod_id2, prod_id[1]); pcmcia_device_stringattr(prod_id3, prod_id[2]); pcmcia_device_stringattr(prod_id4, prod_id[3]); +static ssize_t pcmcia_show_resources(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct pcmcia_device *p_dev = to_pcmcia_dev(dev); + char *str = buf; + int i; + + for (i = 0; i < PCMCIA_NUM_RESOURCES; i++) + str += sprintf(str, "%pr\n", p_dev->resource[i]); + + return str - buf; +} static ssize_t pcmcia_show_pm_state(struct device *dev, struct device_attribute *attr, char *buf) { @@ -1076,6 +1093,7 @@ static ssize_t pcmcia_store_allow_func_id_match(struct device *dev, static struct device_attribute pcmcia_dev_attrs[] = { __ATTR(function, 0444, func_show, NULL), __ATTR(pm_state, 0644, pcmcia_show_pm_state, pcmcia_store_pm_state), + __ATTR(resources, 0444, pcmcia_show_resources, NULL), __ATTR_RO(func_id), __ATTR_RO(manf_id), __ATTR_RO(card_id), @@ -1215,86 +1233,57 @@ static int pcmcia_bus_suspend(struct pcmcia_socket *skt) return 0; } +static int pcmcia_bus_remove(struct pcmcia_socket *skt) +{ + atomic_set(&skt->present, 0); + pcmcia_card_remove(skt, NULL); -/*====================================================================== + mutex_lock(&skt->ops_mutex); + destroy_cis_cache(skt); + pcmcia_cleanup_irq(skt); + mutex_unlock(&skt->ops_mutex); - The card status event handler. + return 0; +} -======================================================================*/ +static int pcmcia_bus_add(struct pcmcia_socket *skt) +{ + atomic_set(&skt->present, 1); -/* Normally, the event is passed to individual drivers after - * informing userspace. Only for CS_EVENT_CARD_REMOVAL this - * is inversed to maintain historic compatibility. - */ + mutex_lock(&skt->ops_mutex); + skt->pcmcia_pfc = 0; + destroy_cis_cache(skt); /* to be on the safe side... */ + mutex_unlock(&skt->ops_mutex); -static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) -{ - struct pcmcia_socket *s = pcmcia_get_socket(skt); + pcmcia_card_add(skt); - if (!s) { - dev_printk(KERN_ERR, &skt->dev, - "PCMCIA obtaining reference to socket " \ - "failed, event 0x%x lost!\n", event); - return -ENODEV; - } + return 0; +} - dev_dbg(&skt->dev, "ds_event(0x%06x, %d, 0x%p)\n", - event, priority, skt); +static int pcmcia_bus_early_resume(struct pcmcia_socket *skt) +{ + if (!verify_cis_cache(skt)) { + pcmcia_put_socket(skt); + return 0; + } - switch (event) { - case CS_EVENT_CARD_REMOVAL: - atomic_set(&skt->present, 0); - pcmcia_card_remove(skt, NULL); - handle_event(skt, event); - mutex_lock(&s->ops_mutex); - destroy_cis_cache(s); - pcmcia_cleanup_irq(s); - mutex_unlock(&s->ops_mutex); - break; + dev_dbg(&skt->dev, "cis mismatch - different card\n"); - case CS_EVENT_CARD_INSERTION: - atomic_set(&skt->present, 1); - mutex_lock(&s->ops_mutex); - s->pcmcia_state.has_pfc = 0; - destroy_cis_cache(s); /* to be on the safe side... */ - mutex_unlock(&s->ops_mutex); - pcmcia_card_add(skt); - handle_event(skt, event); - break; - - case CS_EVENT_EJECTION_REQUEST: - break; - - case CS_EVENT_PM_RESUME: - if (verify_cis_cache(skt) != 0) { - dev_dbg(&skt->dev, "cis mismatch - different card\n"); - /* first, remove the card */ - ds_event(skt, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH); - mutex_lock(&s->ops_mutex); - destroy_cis_cache(skt); - kfree(skt->fake_cis); - skt->fake_cis = NULL; - s->functions = 0; - mutex_unlock(&s->ops_mutex); - /* now, add the new card */ - ds_event(skt, CS_EVENT_CARD_INSERTION, - CS_EVENT_PRI_LOW); - } - handle_event(skt, event); - break; + /* first, remove the card */ + pcmcia_bus_remove(skt); - case CS_EVENT_PM_SUSPEND: - case CS_EVENT_RESET_PHYSICAL: - case CS_EVENT_CARD_RESET: - default: - handle_event(skt, event); - break; - } + mutex_lock(&skt->ops_mutex); + destroy_cis_cache(skt); + kfree(skt->fake_cis); + skt->fake_cis = NULL; + skt->functions = 0; + mutex_unlock(&skt->ops_mutex); - pcmcia_put_socket(s); + /* now, add the new card */ + pcmcia_bus_add(skt); + return 0; +} - return 0; -} /* ds_event */ /* * NOTE: This is racy. There's no guarantee the card will still be @@ -1323,10 +1312,12 @@ EXPORT_SYMBOL(pcmcia_dev_present); static struct pcmcia_callback pcmcia_bus_callback = { .owner = THIS_MODULE, - .event = ds_event, + .add = pcmcia_bus_add, + .remove = pcmcia_bus_remove, .requery = pcmcia_requery, .validate = pccard_validate_cis, .suspend = pcmcia_bus_suspend, + .early_resume = pcmcia_bus_early_resume, .resume = pcmcia_bus_resume, }; @@ -1350,11 +1341,8 @@ static int __devinit pcmcia_bus_add_socket(struct device *dev, return ret; } -#ifdef CONFIG_PCMCIA_IOCTL - init_waitqueue_head(&socket->queue); -#endif INIT_LIST_HEAD(&socket->devices_list); - memset(&socket->pcmcia_state, 0, sizeof(u8)); + socket->pcmcia_pfc = 0; socket->device_count = 0; atomic_set(&socket->present, 0); @@ -1429,8 +1417,6 @@ static int __init init_pcmcia_bus(void) return ret; } - pcmcia_setup_ioctl(); - return 0; } fs_initcall(init_pcmcia_bus); /* one level after subsys_initcall so that @@ -1439,8 +1425,6 @@ fs_initcall(init_pcmcia_bus); /* one level after subsys_initcall so that static void __exit exit_pcmcia_bus(void) { - pcmcia_cleanup_ioctl(); - class_interface_unregister(&pcmcia_bus_interface); bus_unregister(&pcmcia_bus_type); diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c index 3003bb3dfcc0..05d0879ce935 100644 --- a/drivers/pcmcia/i82092.c +++ b/drivers/pcmcia/i82092.c @@ -15,7 +15,6 @@ #include <linux/interrupt.h> #include <linux/device.h> -#include <pcmcia/cs_types.h> #include <pcmcia/ss.h> #include <pcmcia/cs.h> diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c index 9e2a15628de5..61746bd598b3 100644 --- a/drivers/pcmcia/i82365.c +++ b/drivers/pcmcia/i82365.c @@ -50,7 +50,6 @@ #include <asm/io.h> #include <asm/system.h> -#include <pcmcia/cs_types.h> #include <pcmcia/ss.h> #include <pcmcia/cs.h> diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c index 7e16ed8eb0a4..24de49925863 100644 --- a/drivers/pcmcia/m32r_cfc.c +++ b/drivers/pcmcia/m32r_cfc.c @@ -26,7 +26,6 @@ #include <asm/io.h> #include <asm/system.h> -#include <pcmcia/cs_types.h> #include <pcmcia/ss.h> #include <pcmcia/cs.h> diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c index 6c5c3f910d71..8e4723844ad3 100644 --- a/drivers/pcmcia/m32r_pcc.c +++ b/drivers/pcmcia/m32r_pcc.c @@ -27,7 +27,6 @@ #include <asm/system.h> #include <asm/addrspace.h> -#include <pcmcia/cs_types.h> #include <pcmcia/ss.h> #include <pcmcia/cs.h> diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c index 25e5e30a18af..f2f90a7d3e12 100644 --- a/drivers/pcmcia/m8xx_pcmcia.c +++ b/drivers/pcmcia/m8xx_pcmcia.c @@ -59,7 +59,6 @@ #include <asm/irq.h> #include <asm/fs_pd.h> -#include <pcmcia/cs_types.h> #include <pcmcia/cs.h> #include <pcmcia/ss.h> diff --git a/drivers/pcmcia/pcmcia_cis.c b/drivers/pcmcia/pcmcia_cis.c index 4a65eaf96b0a..0ac54da15885 100644 --- a/drivers/pcmcia/pcmcia_cis.c +++ b/drivers/pcmcia/pcmcia_cis.c @@ -19,7 +19,6 @@ #include <linux/kernel.h> #include <linux/netdevice.h> -#include <pcmcia/cs_types.h> #include <pcmcia/cisreg.h> #include <pcmcia/cistpl.h> #include <pcmcia/ss.h> diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c deleted file mode 100644 index d007a2a03830..000000000000 --- a/drivers/pcmcia/pcmcia_ioctl.c +++ /dev/null @@ -1,1077 +0,0 @@ -/* - * pcmcia_ioctl.c -- ioctl interface for cardmgr and cardctl - * - * 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. - * - * The initial developer of the original code is David A. Hinds - * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds - * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. - * - * (C) 1999 David A. Hinds - * (C) 2003 - 2004 Dominik Brodowski - */ - -/* - * This file will go away soon. - */ - - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/major.h> -#include <linux/errno.h> -#include <linux/ioctl.h> |