summaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-08-06 12:25:06 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2010-08-06 12:25:06 -0700
commit1685e633b396b0f3dabbc9fa5d65dfefe6435250 (patch)
treeee83e26e2468ca1518a1b065c690159e12c8def9 /drivers/pcmcia
parent1cfd2bda8c486ae0e7a8005354758ebb68172bca (diff)
parent127c03cdbad9bd5af5d7f33bd31a1015a90cb77f (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')
-rw-r--r--drivers/pcmcia/Makefile1
-rw-r--r--drivers/pcmcia/au1000_generic.h1
-rw-r--r--drivers/pcmcia/au1000_pb1x00.c2
-rw-r--r--drivers/pcmcia/cistpl.c11
-rw-r--r--drivers/pcmcia/cs.c79
-rw-r--r--drivers/pcmcia/cs_internal.h62
-rw-r--r--drivers/pcmcia/db1xxx_ss.c1
-rw-r--r--drivers/pcmcia/ds.c184
-rw-r--r--drivers/pcmcia/i82092.c1
-rw-r--r--drivers/pcmcia/i82365.c1
-rw-r--r--drivers/pcmcia/m32r_cfc.c1
-rw-r--r--drivers/pcmcia/m32r_pcc.c1
-rw-r--r--drivers/pcmcia/m8xx_pcmcia.c1
-rw-r--r--drivers/pcmcia/pcmcia_cis.c1
-rw-r--r--drivers/pcmcia/pcmcia_ioctl.c1077
-rw-r--r--drivers/pcmcia/pcmcia_resource.c331
-rw-r--r--drivers/pcmcia/pd6729.c1
-rw-r--r--drivers/pcmcia/pxa2xx_base.c1
-rw-r--r--drivers/pcmcia/rsrc_iodyn.c8
-rw-r--r--drivers/pcmcia/rsrc_mgr.c6
-rw-r--r--drivers/pcmcia/rsrc_nonstatic.c15
-rw-r--r--drivers/pcmcia/sa1100_generic.c1
-rw-r--r--drivers/pcmcia/soc_common.h1
-rw-r--r--drivers/pcmcia/socket_sysfs.c1
-rw-r--r--drivers/pcmcia/tcic.c1
-rw-r--r--drivers/pcmcia/xxs1500_ss.c1
-rw-r--r--drivers/pcmcia/yenta_socket.c1
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>