From d3e03f4ea81456d52810a03a17dd88f78a080818 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Wed, 7 Apr 2010 14:12:56 +0200 Subject: pcmcia: use previously assigned IRQ for all card functions Use a previously assigned IRQ for all card functions, not only if CONFIG_PCMCIA_PROBE is set. Reported-by: Alexander Kurz Signed-off-by: Dominik Brodowski --- drivers/pcmcia/pcmcia_resource.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index caec1dee2a4b..7c3d03bb4f30 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c @@ -755,12 +755,12 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) else printk(KERN_WARNING "pcmcia: Driver needs updating to support IRQ sharing.\n"); -#ifdef CONFIG_PCMCIA_PROBE - - if (s->irq.AssignedIRQ != 0) { - /* If the interrupt is already assigned, it must be the same */ + /* If the interrupt is already assigned, it must be the same */ + if (s->irq.AssignedIRQ != 0) irq = s->irq.AssignedIRQ; - } else { + +#ifdef CONFIG_PCMCIA_PROBE + if (!irq) { int try; u32 mask = s->irq_mask; void *data = p_dev; /* something unique to this device */ -- cgit v1.2.3 From 509b0865fbd8ab6c820397706dde980c1c285538 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Thu, 8 Apr 2010 19:23:07 +0200 Subject: pcmcia: fix io_probe due to parent (PCI) resources Similar to commit 7a96e87d, we need to be aware of any parent PCI device when requesting IO regions, even only for testing ("probing"). Reported-by: Komuro Signed-off-by: Dominik Brodowski --- drivers/pcmcia/rsrc_nonstatic.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index 559069a80a3b..1178a823fbc6 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c @@ -214,7 +214,7 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base, return; } for (i = base, most = 0; i < base+num; i += 8) { - res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA ioprobe"); + res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe"); if (!res) continue; hole = inb(i); @@ -231,9 +231,14 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base, bad = any = 0; for (i = base; i < base+num; i += 8) { - res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA ioprobe"); - if (!res) + res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe"); + if (!res) { + if (!any) + printk(" excluding"); + if (!bad) + bad = any = i; continue; + } for (j = 0; j < 8; j++) if (inb(i+j) != most) break; @@ -253,6 +258,7 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base, } if (bad) { if ((num > 16) && (bad == base) && (i == base+num)) { + sub_interval(&s_data->io_db, bad, i-bad); printk(" nothing: probe failed.\n"); return; } else { -- cgit v1.2.3 From b1095afe6fd6ea4c0d9e75489b955f898d6617d9 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Thu, 8 Apr 2010 20:10:21 +0200 Subject: pcmcia: re-start on MFC override If there are changes to the number of socket devices, we need to start over in all cases: else pcmcia_request_configuration() might get confused. Reported-by: Alexander Kurz Signed-off-by: Dominik Brodowski --- drivers/pcmcia/ds.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index cb6036d89e59..4014cf8e4a26 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -687,12 +687,10 @@ static void pcmcia_requery(struct pcmcia_socket *s) new_funcs = mfc.nfn; else new_funcs = 1; - if (old_funcs > new_funcs) { + if (old_funcs != new_funcs) { + /* we need to re-start */ pcmcia_card_remove(s, NULL); pcmcia_card_add(s); - } else if (new_funcs > old_funcs) { - s->functions = new_funcs; - pcmcia_device_add(s, 1); } } @@ -728,6 +726,8 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename) struct pcmcia_socket *s = dev->socket; const struct firmware *fw; int ret = -ENOMEM; + cistpl_longlink_mfc_t mfc; + int old_funcs, new_funcs = 1; if (!filename) return -EINVAL; @@ -750,6 +750,14 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename) goto release; } + /* we need to re-start if the number of functions changed */ + old_funcs = s->functions; + if (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_LONGLINK_MFC, + &mfc)) + new_funcs = mfc.nfn; + + if (old_funcs != new_funcs) + ret = -EBUSY; /* update information */ pcmcia_device_query(dev); @@ -858,10 +866,8 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev, if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) { dev_dbg(&dev->dev, "device needs a fake CIS\n"); if (!dev->socket->fake_cis) - pcmcia_load_firmware(dev, did->cisfile); - - if (!dev->socket->fake_cis) - return 0; + if (pcmcia_load_firmware(dev, did->cisfile)) + return 0; } if (did->match_flags & PCMCIA_DEV_ID_MATCH_ANONYMOUS) { -- cgit v1.2.3 From 41b97ab5050088cd23692d578e7294c7be26109a Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Thu, 15 Apr 2010 19:01:53 +0200 Subject: pcmcia: fix ioport size calculation in rsrc_nonstatic Size needs to be calculated after manipulating with the start value. Reported-by: Komuro Signed-off-by: Dominik Brodowski --- drivers/pcmcia/rsrc_nonstatic.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index 1178a823fbc6..a6eb7b59ba9f 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c @@ -810,7 +810,7 @@ static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end) { struct socket_data *data = s->resource_data; - unsigned long size = end - start + 1; + unsigned long size; int ret = 0; #if defined(CONFIG_X86) @@ -820,6 +820,8 @@ static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long start = 0x100; #endif + size = end - start + 1; + if (end < start) return -EINVAL; -- cgit v1.2.3 From a8408c17d0038b76a83affb1b56dc18fa1e7ed86 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sat, 17 Apr 2010 17:37:33 +0200 Subject: pcmcia: avoid late calls to pccard_validate_cis pccard_validate_cis() nowadays destroys the CIS cache. Therefore, calling it after card setup should be avoided. We can't control the deprecated PCMCIA ioctl (which is only used on ARM nowadays), but we can avoid -- and report -- any other calls. Signed-off-by: Dominik Brodowski --- drivers/pcmcia/cistpl.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c index f230f6543bff..854959cada3a 100644 --- a/drivers/pcmcia/cistpl.c +++ b/drivers/pcmcia/cistpl.c @@ -1484,6 +1484,11 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *info) if (!s) return -EINVAL; + if (s->functions) { + WARN_ON(1); + return -EINVAL; + } + /* We do not want to validate the CIS cache... */ mutex_lock(&s->ops_mutex); destroy_cis_cache(s); @@ -1639,7 +1644,7 @@ static ssize_t pccard_show_cis(struct kobject *kobj, count = 0; else { struct pcmcia_socket *s; - unsigned int chains; + unsigned int chains = 1; if (off + count > size) count = size - off; @@ -1648,7 +1653,7 @@ static ssize_t pccard_show_cis(struct kobject *kobj, if (!(s->state & SOCKET_PRESENT)) return -ENODEV; - if (pccard_validate_cis(s, &chains)) + if (!s->functions && pccard_validate_cis(s, &chains)) return -EIO; if (!chains) return -ENODATA; -- cgit v1.2.3 From 42d284b986105a6ed5ac386818cae093532b2c55 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Mon, 29 Mar 2010 17:35:24 +0200 Subject: drivers/pcmcia: Add missing local_irq_restore Use local_irq_restore in this error-handling case just like in the one just below. A simplified version of the semantic patch that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r exists@ expression E1; identifier f; @@ f (...) { <+... * local_irq_save (E1,...); ... when != E1 * return ...; ...+> } // Signed-off-by: Julia Lawall Signed-off-by: Dominik Brodowski --- drivers/pcmcia/db1xxx_ss.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/db1xxx_ss.c b/drivers/pcmcia/db1xxx_ss.c index 6206408e196c..2d48196a48cd 100644 --- a/drivers/pcmcia/db1xxx_ss.c +++ b/drivers/pcmcia/db1xxx_ss.c @@ -166,8 +166,10 @@ static int db1x_pcmcia_setup_irqs(struct db1x_pcmcia_sock *sock) ret = request_irq(sock->insert_irq, db1200_pcmcia_cdirq, IRQF_DISABLED, "pcmcia_insert", sock); - if (ret) + if (ret) { + local_irq_restore(flags); goto out1; + } ret = request_irq(sock->eject_irq, db1200_pcmcia_cdirq, IRQF_DISABLED, "pcmcia_eject", sock); -- cgit v1.2.3 From 04de0816173c86948b75da93a6344a0a02bbec4d Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 20 Apr 2010 14:49:01 +0200 Subject: pcmcia: pcmcia_dev_present bugfix pcmcia_dev_present is in and by itself buggy. Add a note specifying why it is broken, and replace the broken locking -- taking a mutex is a bad idea in IRQ context, from which this function is rarely called -- by an atomic_t. Signed-off-by: Dominik Brodowski --- drivers/pcmcia/ds.c | 47 ++++++++++++++--------------------------------- include/pcmcia/ds.h | 7 +++---- include/pcmcia/ss.h | 8 +++----- 3 files changed, 20 insertions(+), 42 deletions(-) (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 4014cf8e4a26..92a5af8aa0b4 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -335,7 +335,6 @@ static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *le mutex_lock(&s->ops_mutex); list_del(&p_dev->socket_device_list); - p_dev->_removed = 1; mutex_unlock(&s->ops_mutex); dev_dbg(&p_dev->dev, "unregistering device\n"); @@ -654,14 +653,7 @@ static int pcmcia_requery_callback(struct device *dev, void * _data) static void pcmcia_requery(struct pcmcia_socket *s) { - int present, has_pfc; - - mutex_lock(&s->ops_mutex); - present = s->pcmcia_state.present; - mutex_unlock(&s->ops_mutex); - - if (!present) - return; + int has_pfc; if (s->functions == 0) { pcmcia_card_add(s); @@ -1260,9 +1252,7 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) switch (event) { case CS_EVENT_CARD_REMOVAL: - mutex_lock(&s->ops_mutex); - s->pcmcia_state.present = 0; - mutex_unlock(&s->ops_mutex); + atomic_set(&skt->present, 0); pcmcia_card_remove(skt, NULL); handle_event(skt, event); mutex_lock(&s->ops_mutex); @@ -1271,9 +1261,9 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) break; case CS_EVENT_CARD_INSERTION: + atomic_set(&skt->present, 1); mutex_lock(&s->ops_mutex); s->pcmcia_state.has_pfc = 0; - s->pcmcia_state.present = 1; destroy_cis_cache(s); /* to be on the safe side... */ mutex_unlock(&s->ops_mutex); pcmcia_card_add(skt); @@ -1313,7 +1303,13 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) return 0; } /* ds_event */ - +/* + * NOTE: This is racy. There's no guarantee the card will still be + * physically present, even if the call to this function returns + * non-NULL. Furthermore, the device driver most likely is unbound + * almost immediately, so the timeframe where pcmcia_dev_present + * returns NULL is probably really really small. + */ struct pcmcia_device *pcmcia_dev_present(struct pcmcia_device *_p_dev) { struct pcmcia_device *p_dev; @@ -1323,22 +1319,9 @@ struct pcmcia_device *pcmcia_dev_present(struct pcmcia_device *_p_dev) if (!p_dev) return NULL; - mutex_lock(&p_dev->socket->ops_mutex); - if (!p_dev->socket->pcmcia_state.present) - goto out; + if (atomic_read(&p_dev->socket->present) != 0) + ret = p_dev; - if (p_dev->socket->pcmcia_state.dead) - goto out; - - if (p_dev->_removed) - goto out; - - if (p_dev->suspended) - goto out; - - ret = p_dev; - out: - mutex_unlock(&p_dev->socket->ops_mutex); pcmcia_put_dev(p_dev); return ret; } @@ -1388,6 +1371,8 @@ static int __devinit pcmcia_bus_add_socket(struct device *dev, return ret; } + atomic_set(&socket->present, 0); + return 0; } @@ -1399,10 +1384,6 @@ static void pcmcia_bus_remove_socket(struct device *dev, if (!socket) return; - mutex_lock(&socket->ops_mutex); - socket->pcmcia_state.dead = 1; - mutex_unlock(&socket->ops_mutex); - pccard_register_pcmcia(socket, NULL); /* unregister any unbound devices */ diff --git a/include/pcmcia/ds.h b/include/pcmcia/ds.h index d57847f2f6c1..aab3c13dc310 100644 --- a/include/pcmcia/ds.h +++ b/include/pcmcia/ds.h @@ -26,6 +26,7 @@ #ifdef __KERNEL__ #include #include +#include /* * PCMCIA device drivers (16-bit cards only; 32-bit cards require CardBus @@ -94,10 +95,8 @@ struct pcmcia_device { config_req_t conf; window_handle_t win; - /* Is the device suspended, or in the process of - * being removed? */ + /* Is the device suspended? */ u16 suspended:1; - u16 _removed:1; /* Flags whether io, irq, win configurations were * requested, and whether the configuration is "locked" */ @@ -115,7 +114,7 @@ struct pcmcia_device { u16 has_card_id:1; u16 has_func_id:1; - u16 reserved:3; + u16 reserved:4; u8 func_id; u16 manf_id; diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h index 2e488b60bc76..344705cb42f4 100644 --- a/include/pcmcia/ss.h +++ b/include/pcmcia/ss.h @@ -224,18 +224,16 @@ struct pcmcia_socket { /* 16-bit state: */ struct { - /* PCMCIA card is present in socket */ - u8 present:1; /* "master" ioctl is used */ u8 busy:1; - /* pcmcia module is being unloaded */ - u8 dead:1; /* the PCMCIA card consists of two pseudo devices */ u8 has_pfc:1; - u8 reserved:4; + u8 reserved:6; } pcmcia_state; + /* non-zero if PCMCIA card is present */ + atomic_t present; #ifdef CONFIG_PCMCIA_IOCTL struct user_info_t *user; -- cgit v1.2.3 From 83bf6f11e82eba8533f8dbd241b2c2825e42ae5d Mon Sep 17 00:00:00 2001 From: Alexander Kurz Date: Sun, 25 Apr 2010 13:44:35 +0400 Subject: pcmcia: fix matching rules for pseudo-multi-function cards Prevent PCMCIA_DEV_ID_MATCH_FUNC_ID from grabbing PFC-cards: I changed the code, so that the first matching struct pcmcia_device_id _PFC_ entry will mark the card has_pfc, preventing PCMCIA_DEV_ID_MATCH_FUNC_ID to match. [linux-pcmcia@lists.infradead.org: re-order commit message] Signed-off-by: Alexander Kurz Signed-off-by: Dominik Brodowski --- drivers/pcmcia/ds.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 92a5af8aa0b4..508f94a2a78d 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -820,11 +820,12 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev, } if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) { - if (dev->device_no != did->device_no) - return 0; + 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; mutex_unlock(&dev->socket->ops_mutex); + if (dev->device_no != did->device_no) + return 0; } if (did->match_flags & PCMCIA_DEV_ID_MATCH_FUNC_ID) { @@ -835,7 +836,7 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev, /* if this is a pseudo-multi-function device, * we need explicit matches */ - if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) + if (dev->socket->pcmcia_state.has_pfc) return 0; if (dev->device_no) return 0; -- cgit v1.2.3 From 0000a5390184af1459e82506fcfa7db96f3e6d33 Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Wed, 21 Apr 2010 17:41:59 +0200 Subject: MIPS: DB1200: PCMCIA card detection must not be auto-enabled. Same issues as SD card detection: One of both is always triggering and the handlers take care to shut it up and enable the other. To avoid messages about "unbalanced interrupt enable/disable" they must not be automatically enabled when initally requested. This was not an issue with the db1200_defconfig due to fortunate timings; on a build without network chip support the warnings appear. Signed-off-by: Manuel Lauss To: Linux-MIPS Patchwork: http://patchwork.linux-mips.org/patch/1133/ Signed-off-by: Ralf Baechle --- arch/mips/alchemy/devboards/db1200/setup.c | 10 +++++++--- drivers/pcmcia/db1xxx_ss.c | 16 ++++------------ 2 files changed, 11 insertions(+), 15 deletions(-) (limited to 'drivers/pcmcia') diff --git a/arch/mips/alchemy/devboards/db1200/setup.c b/arch/mips/alchemy/devboards/db1200/setup.c index be7e92ea01f3..887619547553 100644 --- a/arch/mips/alchemy/devboards/db1200/setup.c +++ b/arch/mips/alchemy/devboards/db1200/setup.c @@ -66,12 +66,16 @@ static int __init db1200_arch_init(void) set_irq_type(AU1200_GPIO7_INT, IRQF_TRIGGER_LOW); bcsr_init_irq(DB1200_INT_BEGIN, DB1200_INT_END, AU1200_GPIO7_INT); - /* do not autoenable these: CPLD has broken edge int handling, - * and the CD handler setup requires manual enabling to work - * around that. + /* insert/eject pairs: one of both is always screaming. To avoid + * issues they must not be automatically enabled when initially + * requested. */ irq_to_desc(DB1200_SD0_INSERT_INT)->status |= IRQ_NOAUTOEN; irq_to_desc(DB1200_SD0_EJECT_INT)->status |= IRQ_NOAUTOEN; + irq_to_desc(DB1200_PC0_INSERT_INT)->status |= IRQ_NOAUTOEN; + irq_to_desc(DB1200_PC0_EJECT_INT)->status |= IRQ_NOAUTOEN; + irq_to_desc(DB1200_PC1_INSERT_INT)->status |= IRQ_NOAUTOEN; + irq_to_desc(DB1200_PC1_EJECT_INT)->status |= IRQ_NOAUTOEN; return 0; } diff --git a/drivers/pcmcia/db1xxx_ss.c b/drivers/pcmcia/db1xxx_ss.c index 2d48196a48cd..0f4cc3f00028 100644 --- a/drivers/pcmcia/db1xxx_ss.c +++ b/drivers/pcmcia/db1xxx_ss.c @@ -146,7 +146,6 @@ static irqreturn_t db1200_pcmcia_cdirq(int irq, void *data) static int db1x_pcmcia_setup_irqs(struct db1x_pcmcia_sock *sock) { int ret; - unsigned long flags; if (sock->stschg_irq != -1) { ret = request_irq(sock->stschg_irq, db1000_pcmcia_stschgirq, @@ -162,30 +161,23 @@ static int db1x_pcmcia_setup_irqs(struct db1x_pcmcia_sock *sock) * active one disabled. */ if (sock->board_type == BOARD_TYPE_DB1200) { - local_irq_save(flags); - ret = request_irq(sock->insert_irq, db1200_pcmcia_cdirq, IRQF_DISABLED, "pcmcia_insert", sock); - if (ret) { - local_irq_restore(flags); + if (ret) goto out1; - } ret = request_irq(sock->eject_irq, db1200_pcmcia_cdirq, IRQF_DISABLED, "pcmcia_eject", sock); if (ret) { free_irq(sock->insert_irq, sock); - local_irq_restore(flags); goto out1; } - /* disable the currently active one */ + /* enable the currently silent one */ if (db1200_card_inserted(sock)) - disable_irq_nosync(sock->insert_irq); + enable_irq(sock->eject_irq); else - disable_irq_nosync(sock->eject_irq); - - local_irq_restore(flags); + enable_irq(sock->insert_irq); } else { /* all other (older) Db1x00 boards use a GPIO to show * card detection status: use both-edge triggers. -- cgit v1.2.3 From cc83b08fc791045ac197e6f4a030599bcd7100c5 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Thu, 29 Apr 2010 15:56:25 +0200 Subject: pcmcia: avoid pccard_validate_cis failure in resume callpath If the PCMCIA CIS changed before a resume event (e.g. due to a card exchange while being suspended, possibly also during a call to "pccardctl reset"), also set the function count to zero so that the subsequent call to pccard_validate_cis() does not fail. Signed-off-by: Dominik Brodowski --- drivers/pcmcia/ds.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 508f94a2a78d..041eee43fd8d 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -1283,6 +1283,7 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) 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, -- cgit v1.2.3 From 43821242078aeced1d576b4b54d7b4a9bd76ec05 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Mon, 3 May 2010 15:10:09 +0200 Subject: pcmcia: order userspace suspend and resume requests Assert that userspace suspend and resume requests appearing (almost) immediately are executed in the following order: suspend, resume. This should result in "pccardctl reset" behaving the same as before. Signed-off-by: Dominik Brodowski --- drivers/pcmcia/cs.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index 75ed866e6953..c3383750e333 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c @@ -671,20 +671,22 @@ static int pccardd(void *__skt) socket_remove(skt); if (sysfs_events & PCMCIA_UEVENT_INSERT) socket_insert(skt); - if ((sysfs_events & PCMCIA_UEVENT_RESUME) && - !(skt->state & SOCKET_CARDBUS)) { - ret = socket_resume(skt); - if (!ret && skt->callback) - skt->callback->resume(skt); - } if ((sysfs_events & PCMCIA_UEVENT_SUSPEND) && !(skt->state & SOCKET_CARDBUS)) { if (skt->callback) ret = skt->callback->suspend(skt); else ret = 0; - if (!ret) + if (!ret) { socket_suspend(skt); + msleep(100); + } + } + if ((sysfs_events & PCMCIA_UEVENT_RESUME) && + !(skt->state & SOCKET_CARDBUS)) { + ret = socket_resume(skt); + if (!ret && skt->callback) + skt->callback->resume(skt); } if ((sysfs_events & PCMCIA_UEVENT_REQUERY) && !(skt->state & SOCKET_CARDBUS)) { -- cgit v1.2.3 From 15d0a873549ef0bdeaa04dacf29a3e15de886d03 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 4 May 2010 13:33:54 +0200 Subject: pcmcia: fix compilation after 16bit state locking changes Commit 04de0816 (pcmcia: pcmcia_dev_present bugfix) broke the deprecated ioctl layer. Fix it by getting rid of references to unexisting fields. Signed-off-by: Marc Zyngier Reported-by: Pavel Machek Signed-off-by: Dominik Brodowski --- drivers/pcmcia/pcmcia_ioctl.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c index 104e73d5d86c..7631faa0cadd 100644 --- a/drivers/pcmcia/pcmcia_ioctl.c +++ b/drivers/pcmcia/pcmcia_ioctl.c @@ -711,7 +711,7 @@ static int ds_open(struct inode *inode, struct file *file) warning_printed = 1; } - if (s->pcmcia_state.present) + if (atomic_read(&s->present)) queue_event(user, CS_EVENT_CARD_INSERTION); out: unlock_kernel(); @@ -770,9 +770,6 @@ static ssize_t ds_read(struct file *file, char __user *buf, return -EIO; s = user->socket; - if (s->pcmcia_state.dead) - return -EIO; - ret = wait_event_interruptible(s->queue, !queue_empty(user)); if (ret == 0) ret = put_user(get_queued_event(user), (int __user *)buf) ? -EFAULT : 4; @@ -838,8 +835,6 @@ static int ds_ioctl(struct inode *inode, struct file *file, return -EIO; s = user->socket; - if (s->pcmcia_state.dead) - return -EIO; size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT; if (size > sizeof(ds_ioctl_arg_t)) -- cgit v1.2.3 From 0cb3c49cdd275aa9ef4b1afd090117b1b86a16d4 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sat, 6 Mar 2010 20:42:35 +0100 Subject: pcmcia: remove unused IRQ modification feature The IRQ modification feature was unused, and I see no reason to keep it. Signed-off-by: Dominik Brodowski --- drivers/pcmcia/pcmcia_resource.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index 7c3d03bb4f30..ba82cb3b1944 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c @@ -275,19 +275,9 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev, goto unlock; } - if (mod->Attributes & CONF_IRQ_CHANGE_VALID) { - if (mod->Attributes & CONF_ENABLE_IRQ) { - c->Attributes |= CONF_ENABLE_IRQ; - s->socket.io_irq = s->irq.AssignedIRQ; - } else { - c->Attributes &= ~CONF_ENABLE_IRQ; - s->socket.io_irq = 0; - } - s->ops->set_socket(s, &s->socket); - } - - if (mod->Attributes & CONF_VCC_CHANGE_VALID) { - dev_dbg(&s->dev, "changing Vcc is not allowed at this time\n"); + if (mod->Attributes & (CONF_IRQ_CHANGE_VALID | CONF_VCC_CHANGE_VALID)) { + dev_dbg(&s->dev, + "changing Vcc or IRQ is not allowed at this time\n"); ret = -EINVAL; goto unlock; } -- cgit v1.2.3 From 6f0f38c45a8f2f511c25893e33011ff32fc811db Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Thu, 8 Apr 2010 20:33:16 +0200 Subject: pcmcia: setup IRQ to be used by PCMCIA drivers at card insert Setup the IRQ to be used by PCMCIA drivers already during the device registration stage, making use of a new function pcmcia_setup_irq(). This will allow us to get rid of quite a lot of indirection in the future. Signed-off-by: Dominik Brodowski --- drivers/pcmcia/cs_internal.h | 2 + drivers/pcmcia/ds.c | 15 ++- drivers/pcmcia/pcmcia_resource.c | 214 +++++++++++++++++++++++---------------- include/pcmcia/ds.h | 3 + 4 files changed, 140 insertions(+), 94 deletions(-) (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h index f95864c2191e..74d91c8849ba 100644 --- a/drivers/pcmcia/cs_internal.h +++ b/drivers/pcmcia/cs_internal.h @@ -149,6 +149,8 @@ extern struct resource *pcmcia_find_mem_region(u_long base, int low, struct pcmcia_socket *s); +void pcmcia_cleanup_irq(struct pcmcia_socket *s); +int pcmcia_setup_irq(struct pcmcia_device *p_dev); /* cistpl.c */ extern struct bin_attribute pccard_cis_attr; diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 041eee43fd8d..5fd2948c7ed9 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -546,26 +546,32 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu p_dev->function_config = tmp_dev->function_config; p_dev->io = tmp_dev->io; p_dev->irq = tmp_dev->irq; + p_dev->irq_v = tmp_dev->irq_v; kref_get(&p_dev->function_config->ref); } /* Add to the list in pcmcia_bus_socket */ list_add(&p_dev->socket_device_list, &s->devices_list); - mutex_unlock(&s->ops_mutex); + if (pcmcia_setup_irq(p_dev)) + dev_warn(&p_dev->dev, + "IRQ setup failed -- device might not work\n"); if (!p_dev->function_config) { 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) + if (!p_dev->function_config) { + mutex_unlock(&s->ops_mutex); goto err_unreg; + } kref_init(&p_dev->function_config->ref); } + mutex_unlock(&s->ops_mutex); dev_printk(KERN_NOTICE, &p_dev->dev, - "pcmcia: registering new device %s\n", - p_dev->devname); + "pcmcia: registering new device %s (IRQ: %d)\n", + p_dev->devname, p_dev->irq_v); pcmcia_device_query(p_dev); @@ -1258,6 +1264,7 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) handle_event(skt, event); mutex_lock(&s->ops_mutex); destroy_cis_cache(s); + pcmcia_cleanup_irq(s); mutex_unlock(&s->ops_mutex); break; diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index ba82cb3b1944..ff9c0bcb7e3a 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c @@ -23,6 +23,8 @@ #include #include +#include + #include #include #include @@ -38,12 +40,6 @@ static int io_speed; module_param(io_speed, int, 0444); -#ifdef CONFIG_PCMCIA_PROBE -#include -/* mask of IRQs already reserved by other cards, we should avoid using them */ -static u8 pcmcia_used_irq[NR_IRQS]; -#endif - static int pcmcia_adjust_io_region(struct resource *res, unsigned long start, unsigned long end, struct pcmcia_socket *s) { @@ -440,15 +436,11 @@ static int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req) } if (--s->irq.Config == 0) { c->state &= ~CONFIG_IRQ_REQ; - s->irq.AssignedIRQ = 0; } if (req->Handler) free_irq(req->AssignedIRQ, p_dev->priv); -#ifdef CONFIG_PCMCIA_PROBE - pcmcia_used_irq[req->AssignedIRQ]--; -#endif ret = 0; out: @@ -699,26 +691,14 @@ EXPORT_SYMBOL(pcmcia_request_io); /** pcmcia_request_irq * * Request_irq() reserves an irq for this client. - * - * Also, since Linux only reserves irq's when they are actually - * hooked, we don't guarantee that an irq will still be available - * when the configuration is locked. Now that I think about it, - * there might be a way to fix this using a dummy handler. */ -#ifdef CONFIG_PCMCIA_PROBE -static irqreturn_t test_action(int cpl, void *dev_id) -{ - return IRQ_NONE; -} -#endif - int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) { struct pcmcia_socket *s = p_dev->socket; config_t *c; - int ret = -EINVAL, irq = 0; - int type; + int ret = -EINVAL, irq = p_dev->irq_v; + int type = IRQF_SHARED; mutex_lock(&s->ops_mutex); @@ -736,63 +716,20 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) goto out; } - /* Decide what type of interrupt we are registering */ - type = 0; - if (s->functions > 1) /* All of this ought to be handled higher up */ - type = IRQF_SHARED; - else if (req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) - type = IRQF_SHARED; - else - printk(KERN_WARNING "pcmcia: Driver needs updating to support IRQ sharing.\n"); - - /* If the interrupt is already assigned, it must be the same */ - if (s->irq.AssignedIRQ != 0) - irq = s->irq.AssignedIRQ; - -#ifdef CONFIG_PCMCIA_PROBE if (!irq) { - int try; - u32 mask = s->irq_mask; - void *data = p_dev; /* something unique to this device */ - - for (try = 0; try < 64; try++) { - irq = try % 32; - - /* marked as available by driver, and not blocked by userspace? */ - if (!((mask >> irq) & 1)) - continue; - - /* avoid an IRQ which is already used by a PCMCIA card */ - if ((try < 32) && pcmcia_used_irq[irq]) - continue; - - /* register the correct driver, if possible, of check whether - * registering a dummy handle works, i.e. if the IRQ isn't - * marked as used by the kernel resource management core */ - ret = request_irq(irq, - (req->Handler) ? req->Handler : test_action, - type, - p_dev->devname, - (req->Handler) ? p_dev->priv : data); - if (!ret) { - if (!req->Handler) - free_irq(irq, data); - break; - } - } + dev_dbg(&s->dev, "no IRQ available\n"); + goto out; } -#endif - /* only assign PCI irq if no IRQ already assigned */ - if (ret && !s->irq.AssignedIRQ) { - if (!s->pci_irq) { - dev_printk(KERN_INFO, &s->dev, "no IRQ found\n"); - goto out; - } - type = IRQF_SHARED; - irq = s->pci_irq; + + if (!(req->Attributes & IRQ_TYPE_DYNAMIC_SHARING)) { + req->Attributes |= IRQ_TYPE_DYNAMIC_SHARING; + dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: " + "request for exclusive IRQ could not be fulfilled.\n"); + dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: the driver " + "needs updating to supported shared IRQ lines.\n"); } - if (ret && req->Handler) { + if (req->Handler) { ret = request_irq(irq, req->Handler, type, p_dev->devname, p_dev->priv); if (ret) { @@ -802,25 +739,13 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) } } - /* Make sure the fact the request type was overridden is passed back */ - if (type == IRQF_SHARED && !(req->Attributes & IRQ_TYPE_DYNAMIC_SHARING)) { - req->Attributes |= IRQ_TYPE_DYNAMIC_SHARING; - dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: " - "request for exclusive IRQ could not be fulfilled.\n"); - dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: the driver " - "needs updating to supported shared IRQ lines.\n"); - } c->irq.Attributes = req->Attributes; - s->irq.AssignedIRQ = req->AssignedIRQ = irq; + req->AssignedIRQ = irq; s->irq.Config++; c->state |= CONFIG_IRQ_REQ; p_dev->_irq = 1; -#ifdef CONFIG_PCMCIA_PROBE - pcmcia_used_irq[irq]++; -#endif - ret = 0; out: mutex_unlock(&s->ops_mutex); @@ -829,6 +754,115 @@ out: EXPORT_SYMBOL(pcmcia_request_irq); +#ifdef CONFIG_PCMCIA_PROBE + +/* mask of IRQs already reserved by other cards, we should avoid using them */ +static u8 pcmcia_used_irq[NR_IRQS]; + +static irqreturn_t test_action(int cpl, void *dev_id) +{ + return IRQ_NONE; +} + +/** + * pcmcia_setup_isa_irq() - determine whether an ISA IRQ can be used + * @p_dev - the associated PCMCIA device + * + * locking note: must be called with ops_mutex locked. + */ +static int pcmcia_setup_isa_irq(struct pcmcia_device *p_dev, int type) +{ + struct pcmcia_socket *s = p_dev->socket; + unsigned int try, irq; + u32 mask = s->irq_mask; + int ret = -ENODEV; + + for (try = 0; try < 64; try++) { + irq = try % 32; + + /* marked as available by driver, not blocked by userspace? */ + if (!((mask >> irq) & 1)) + continue; + + /* avoid an IRQ which is already used by another PCMCIA card */ + if ((try < 32) && pcmcia_used_irq[irq]) + continue; + + /* register the correct driver, if possible, to check whether + * registering a dummy handle works, i.e. if the IRQ isn't + * marked as used by the kernel resource management core */ + ret = request_irq(irq, test_action, type, p_dev->devname, + p_dev); + if (!ret) { + free_irq(irq, p_dev); + p_dev->irq_v = s->irq.AssignedIRQ = irq; + pcmcia_used_irq[irq]++; + break; + } + } + + return ret; +} + +void pcmcia_cleanup_irq(struct pcmcia_socket *s) +{ + pcmcia_used_irq[s->irq.AssignedIRQ]--; + s->irq.AssignedIRQ = 0; +} + +#else /* CONFIG_PCMCIA_PROBE */ + +static int pcmcia_setup_isa_irq(struct pcmcia_device *p_dev, int type) +{ + return -EINVAL; +} + +void pcmcia_cleanup_irq(struct pcmcia_socket *s) +{ + s->irq.AssignedIRQ = 0; + return; +} + +#endif /* CONFIG_PCMCIA_PROBE */ + + +/** + * pcmcia_setup_irq() - determine IRQ to be used for device + * @p_dev - the associated PCMCIA device + * + * locking note: must be called with ops_mutex locked. + */ +int pcmcia_setup_irq(struct pcmcia_device *p_dev) +{ + struct pcmcia_socket *s = p_dev->socket; + + if (p_dev->irq_v) + return 0; + + /* already assigned? */ + if (s->irq.AssignedIRQ) { + p_dev->irq_v = s->irq.AssignedIRQ; + return 0; + } + + /* prefer an exclusive ISA irq */ + if (!pcmcia_setup_isa_irq(p_dev, 0)) + return 0; + + /* but accept a shared ISA irq */ + if (!pcmcia_setup_isa_irq(p_dev, IRQF_SHARED)) + return 0; + + /* but use the PCI irq otherwise */ + if (s->pci_irq) { + p_dev->irq_v = s->irq.AssignedIRQ = s->pci_irq; + return 0; + } + + return -EINVAL; +} + + /** pcmcia_request_window * * Request_window() establishes a mapping between card memory space diff --git a/include/pcmcia/ds.h b/include/pcmcia/ds.h index aab3c13dc310..52ebe75664e8 100644 --- a/include/pcmcia/ds.h +++ b/include/pcmcia/ds.h @@ -95,6 +95,9 @@ struct pcmcia_device { config_req_t conf; window_handle_t win; + /* device setup */ + unsigned int irq_v; /* do not use directly yet */ + /* Is the device suspended? */ u16 suspended:1; -- cgit v1.2.3 From 6f840afb416748c15cf55c19b45c4870554c3af1 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 7 Mar 2010 10:51:23 +0100 Subject: pcmcia: replace struct irq with uint pcmcia_irq in struct pcmcia_socket As we don't need the "Config" counter any more, we can simplify struct pcmcia_socket. Signed-off-by: Dominik Brodowski --- drivers/pcmcia/bfin_cf_pcmcia.c | 2 +- drivers/pcmcia/cardbus.c | 1 - drivers/pcmcia/cs.c | 1 - drivers/pcmcia/omap_cf.c | 2 +- drivers/pcmcia/pcmcia_ioctl.c | 4 ++-- drivers/pcmcia/pcmcia_resource.c | 31 ++++++++++--------------------- include/pcmcia/ss.h | 7 +++---- 7 files changed, 17 insertions(+), 31 deletions(-) (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/bfin_cf_pcmcia.c b/drivers/pcmcia/bfin_cf_pcmcia.c index 9e84d039de41..eae9cbe37a3e 100644 --- a/drivers/pcmcia/bfin_cf_pcmcia.c +++ b/drivers/pcmcia/bfin_cf_pcmcia.c @@ -113,7 +113,7 @@ static int bfin_cf_get_status(struct pcmcia_socket *s, u_int *sp) if (bfin_cf_present(cf->cd_pfx)) { *sp = SS_READY | SS_DETECT | SS_POWERON | SS_3VCARD; - s->irq.AssignedIRQ = 0; + s->pcmcia_irq = 0; s->pci_irq = cf->irq; } else diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c index e6ab2a47d8cb..9a58862f1401 100644 --- a/drivers/pcmcia/cardbus.c +++ b/drivers/pcmcia/cardbus.c @@ -94,7 +94,6 @@ int __ref cb_alloc(struct pcmcia_socket *s) pci_enable_bridges(bus); pci_bus_add_devices(bus); - s->irq.AssignedIRQ = s->pci_irq; return 0; } diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index c3383750e333..976d80706eae 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c @@ -337,7 +337,6 @@ static void socket_shutdown(struct pcmcia_socket *s) s->socket = dead_socket; s->ops->init(s); s->ops->set_socket(s, &s->socket); - s->irq.AssignedIRQ = s->irq.Config = 0; s->lock_count = 0; kfree(s->fake_cis); s->fake_cis = NULL; diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c index a7cfc7964c7c..0ad06a3bd562 100644 --- a/drivers/pcmcia/omap_cf.c +++ b/drivers/pcmcia/omap_cf.c @@ -117,7 +117,7 @@ static int omap_cf_get_status(struct pcmcia_socket *s, u_int *sp) *sp = SS_READY | SS_DETECT | SS_POWERON | SS_3VCARD; cf = container_of(s, struct omap_cf_socket, socket); - s->irq.AssignedIRQ = 0; + s->pcmcia_irq = 0; s->pci_irq = cf->irq; } else *sp = 0; diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c index 7631faa0cadd..fe98aa9b1aef 100644 --- a/drivers/pcmcia/pcmcia_ioctl.c +++ b/drivers/pcmcia/pcmcia_ioctl.c @@ -351,7 +351,7 @@ static int pccard_get_configuration_info(struct pcmcia_socket *s, if (s->state & SOCKET_CARDBUS_CONFIG) { config->Attributes = CONF_VALID_CLIENT; config->IntType = INT_CARDBUS; - config->AssignedIRQ = s->irq.AssignedIRQ; + config->AssignedIRQ = s->pcmcia_irq; if (config->AssignedIRQ) config->Attributes |= CONF_ENABLE_IRQ; if (s->io[0].res) { @@ -391,7 +391,7 @@ static int pccard_get_configuration_info(struct pcmcia_socket *s, config->ExtStatus = c->ExtStatus; config->Present = config->CardValues = c->CardValues; config->IRQAttributes = c->irq.Attributes; - config->AssignedIRQ = s->irq.AssignedIRQ; + config->AssignedIRQ = s->pcmcia_irq; config->BasePort1 = c->io.BasePort1; config->NumPorts1 = c->io.NumPorts1; config->Attributes1 = c->io.Attributes1; diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index ff9c0bcb7e3a..cefc4cda9d3e 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c @@ -430,13 +430,10 @@ static int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req) dev_dbg(&s->dev, "IRQ attributes must match assigned ones\n"); goto out; } - if (s->irq.AssignedIRQ != req->AssignedIRQ) { + if (s->pcmcia_irq != req->AssignedIRQ) { dev_dbg(&s->dev, "IRQ must match assigned one\n"); goto out; } - if (--s->irq.Config == 0) { - c->state &= ~CONFIG_IRQ_REQ; - } if (req->Handler) free_irq(req->AssignedIRQ, p_dev->priv); @@ -533,7 +530,7 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev, if (req->Attributes & CONF_ENABLE_SPKR) s->socket.flags |= SS_SPKR_ENA; if (req->Attributes & CONF_ENABLE_IRQ) - s->socket.io_irq = s->irq.AssignedIRQ; + s->socket.io_irq = s->pcmcia_irq; else s->socket.io_irq = 0; s->ops->set_socket(s, &s->socket); @@ -556,7 +553,7 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev, if (req->Present & PRESENT_IOBASE_0) c->Option |= COR_ADDR_DECODE; } - if (c->state & CONFIG_IRQ_REQ) + if (req->Attributes & CONF_ENABLE_IRQ) if (!(c->irq.Attributes & IRQ_FORCED_PULSE)) c->Option |= COR_LEVEL_REQ; pcmcia_write_cis_mem(s, 1, (base + CISREG_COR)>>1, 1, &c->Option); @@ -711,10 +708,6 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) dev_dbg(&s->dev, "Configuration is locked\n"); goto out; } - if (c->state & CONFIG_IRQ_REQ) { - dev_dbg(&s->dev, "IRQ already configured\n"); - goto out; - } if (!irq) { dev_dbg(&s->dev, "no IRQ available\n"); @@ -723,8 +716,6 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) if (!(req->Attributes & IRQ_TYPE_DYNAMIC_SHARING)) { req->Attributes |= IRQ_TYPE_DYNAMIC_SHARING; - dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: " - "request for exclusive IRQ could not be fulfilled.\n"); dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: the driver " "needs updating to supported shared IRQ lines.\n"); } @@ -741,9 +732,7 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) c->irq.Attributes = req->Attributes; req->AssignedIRQ = irq; - s->irq.Config++; - c->state |= CONFIG_IRQ_REQ; p_dev->_irq = 1; ret = 0; @@ -795,7 +784,7 @@ static int pcmcia_setup_isa_irq(struct pcmcia_device *p_dev, int type) p_dev); if (!ret) { free_irq(irq, p_dev); - p_dev->irq_v = s->irq.AssignedIRQ = irq; + p_dev->irq_v = s->pcmcia_irq = irq; pcmcia_used_irq[irq]++; break; } @@ -806,8 +795,8 @@ static int pcmcia_setup_isa_irq(struct pcmcia_device *p_dev, int type) void pcmcia_cleanup_irq(struct pcmcia_socket *s) { - pcmcia_used_irq[s->irq.AssignedIRQ]--; - s->irq.AssignedIRQ = 0; + pcmcia_used_irq[s->pcmcia_irq]--; + s->pcmcia_irq = 0; } #else /* CONFIG_PCMCIA_PROBE */ @@ -819,7 +808,7 @@ static int pcmcia_setup_isa_irq(struct pcmcia_device *p_dev, int type) void pcmcia_cleanup_irq(struct pcmcia_socket *s) { - s->irq.AssignedIRQ = 0; + s->pcmcia_irq = 0; return; } @@ -840,8 +829,8 @@ int pcmcia_setup_irq(struct pcmcia_device *p_dev) return 0; /* already assigned? */ - if (s->irq.AssignedIRQ) { - p_dev->irq_v = s->irq.AssignedIRQ; + if (s->pcmcia_irq) { + p_dev->irq_v = s->pcmcia_irq; return 0; } @@ -855,7 +844,7 @@ int pcmcia_setup_irq(struct pcmcia_device *p_dev) /* but use the PCI irq otherwise */ if (s->pci_irq) { - p_dev->irq_v = s->irq.AssignedIRQ = s->pci_irq; + p_dev->irq_v = s->pcmcia_irq = s->pci_irq; return 0; } diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h index 344705cb42f4..764281b29218 100644 --- a/include/pcmcia/ss.h +++ b/include/pcmcia/ss.h @@ -141,10 +141,6 @@ struct pcmcia_socket { u_short lock_count; pccard_mem_map cis_mem; void __iomem *cis_virt; - struct { - u_int AssignedIRQ; - u_int Config; - } irq; io_window_t io[MAX_IO_WIN]; pccard_mem_map win[MAX_WIN]; struct list_head cis_cache; @@ -235,6 +231,9 @@ struct pcmcia_socket { /* non-zero if PCMCIA card is present */ atomic_t present; + /* IRQ to be used by PCMCIA devices. May not be IRQ 0. */ + unsigned int pcmcia_irq; + #ifdef CONFIG_PCMCIA_IOCTL struct user_info_t *user; wait_queue_head_t queue; -- cgit v1.2.3 From a7debe789dfcaee9c4d81e5738b0be8c5d93930b Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 7 Mar 2010 10:58:29 +0100 Subject: pcmcia: pass FORCED_PULSE parameter in pcmcia_request_configuration() As it's only used there it makes no sense relying on pcmcia_request_irq(). CC: alsa-devel@alsa-project.org Signed-off-by: Dominik Brodowski --- drivers/pcmcia/pcmcia_resource.c | 11 +++-------- drivers/staging/comedi/drivers/ni_labpc_cs.c | 5 +++-- include/pcmcia/cs.h | 1 + sound/pcmcia/pdaudiocf/pdaudiocf.c | 6 +++--- 4 files changed, 10 insertions(+), 13 deletions(-) (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index cefc4cda9d3e..8dce223f3f44 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c @@ -426,10 +426,6 @@ static int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req) if (c->state & CONFIG_LOCKED) goto out; - if (c->irq.Attributes != req->Attributes) { - dev_dbg(&s->dev, "IRQ attributes must match assigned ones\n"); - goto out; - } if (s->pcmcia_irq != req->AssignedIRQ) { dev_dbg(&s->dev, "IRQ must match assigned one\n"); goto out; @@ -553,9 +549,9 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev, if (req->Present & PRESENT_IOBASE_0) c->Option |= COR_ADDR_DECODE; } - if (req->Attributes & CONF_ENABLE_IRQ) - if (!(c->irq.Attributes & IRQ_FORCED_PULSE)) - c->Option |= COR_LEVEL_REQ; + if ((req->Attributes & CONF_ENABLE_IRQ) && + !(req->Attributes & CONF_ENABLE_PULSE_IRQ)) + c->Option |= COR_LEVEL_REQ; pcmcia_write_cis_mem(s, 1, (base + CISREG_COR)>>1, 1, &c->Option); mdelay(40); } @@ -730,7 +726,6 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) } } - c->irq.Attributes = req->Attributes; req->AssignedIRQ = irq; p_dev->_irq = 1; diff --git a/drivers/staging/comedi/drivers/ni_labpc_cs.c b/drivers/staging/comedi/drivers/ni_labpc_cs.c index 8ad1055a5cc1..6e4ed0d9105a 100644 --- a/drivers/staging/comedi/drivers/ni_labpc_cs.c +++ b/drivers/staging/comedi/drivers/ni_labpc_cs.c @@ -230,7 +230,7 @@ static int labpc_cs_attach(struct pcmcia_device *link) link->priv = local; /* Interrupt setup */ - link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_FORCED_PULSE; + link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; link->irq.Handler = NULL; /* @@ -307,7 +307,8 @@ static int labpc_pcmcia_config_loop(struct pcmcia_device *p_dev, /* Do we need to allocate an interrupt? */ if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) - p_dev->conf.Attributes |= CONF_ENABLE_IRQ; + p_dev->conf.Attributes |= + (CONF_ENABLE_IRQ | CONF_ENABLE_PULSE_IRQ); /* IO window settings */ p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; diff --git a/include/pcmcia/cs.h b/include/pcmcia/cs.h index 75fa3530345b..af615716dc23 100644 --- a/include/pcmcia/cs.h +++ b/include/pcmcia/cs.h @@ -85,6 +85,7 @@ typedef struct config_req_t { #define CONF_ENABLE_IRQ 0x01 #define CONF_ENABLE_DMA 0x02 #define CONF_ENABLE_SPKR 0x04 +#define CONF_ENABLE_PULSE_IRQ 0x08 #define CONF_VALID_CLIENT 0x100 /* IntType field */ diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c index edaa729126bb..dcf85390c5f9 100644 --- a/sound/pcmcia/pdaudiocf/pdaudiocf.c +++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c @@ -142,12 +142,12 @@ static int snd_pdacf_probe(struct pcmcia_device *link) link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.NumPorts1 = 16; - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_FORCED_PULSE; + link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; /* FIXME: This driver should be updated to allow for dynamic IRQ sharing */ - /* link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_FORCED_PULSE; */ + /* link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; */ link->irq.Handler = pdacf_interrupt; - link->conf.Attributes = CONF_ENABLE_IRQ; + link->conf.Attributes = CONF_ENABLE_IRQ | CONF_ENABLE_PULSE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.ConfigIndex = 1; link->conf.Present = PRESENT_OPTION; -- cgit v1.2.3 From eb14120f743d29744d9475bffec56ff4ad43a749 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 7 Mar 2010 12:21:16 +0100 Subject: pcmcia: re-work pcmcia_request_irq() Instead of the old pcmcia_request_irq() interface, drivers may now choose between: - calling request_irq/free_irq directly. Use the IRQ from *p_dev->irq. - use pcmcia_request_irq(p_dev, handler_t); the PCMCIA core will clean up automatically on calls to pcmcia_disable_device() or device ejection. - drivers still not capable of IRQF_SHARED (or not telling us so) may use the deprecated pcmcia_request_exclusive_irq() for the time being; they might receive a shared IRQ nonetheless. CC: linux-bluetooth@vger.kernel.org CC: netdev@vger.kernel.org CC: linux-wireless@vger.kernel.org CC: linux-serial@vger.kernel.org CC: alsa-devel@alsa-project.org CC: linux-usb@vger.kernel.org CC: linux-ide@vger.kernel.org Signed-off-by: Dominik Brodowski --- Documentation/pcmcia/driver-changes.txt | 10 ++ drivers/ata/pata_pcmcia.c | 6 +- drivers/bluetooth/bluecard_cs.c | 7 +- drivers/bluetooth/bt3c_cs.c | 7 +- drivers/bluetooth/btuart_cs.c | 7 +- drivers/bluetooth/dtl1_cs.c | 7 +- drivers/char/pcmcia/ipwireless/main.c | 11 +- drivers/char/pcmcia/synclink_cs.c | 12 +- drivers/ide/ide-cs.c | 8 +- drivers/isdn/hardware/avm/avm_cs.c | 17 +-- drivers/isdn/hisax/avma1_cs.c | 12 +- drivers/isdn/hisax/elsa_cs.c | 13 +-- drivers/isdn/hisax/sedlbauer_cs.c | 23 +--- drivers/isdn/hisax/teles_cs.c | 13 +-- drivers/net/pcmcia/3c574_cs.c | 6 +- drivers/net/pcmcia/3c589_cs.c | 7 +- drivers/net/pcmcia/axnet_cs.c | 13 +-- drivers/net/pcmcia/com20020_cs.c | 8 +- drivers/net/pcmcia/fmvj18x_cs.c | 10 +- drivers/net/pcmcia/ibmtr_cs.c | 8 +- drivers/net/pcmcia/nmclan_cs.c | 6 +- drivers/net/pcmcia/pcnet_cs.c | 8 +- drivers/net/pcmcia/smc91c92_cs.c | 8 +- drivers/net/pcmcia/xirc2ps_cs.c | 7 +- drivers/net/wireless/airo_cs.c | 25 +---- drivers/net/wireless/atmel_cs.c | 28 +---- drivers/net/wireless/b43/pcmcia.c | 5 +- drivers/net/wireless/hostap/hostap_cs.c | 29 +---- drivers/net/wireless/libertas/if_cs.c | 21 +--- drivers/net/wireless/orinoco/orinoco_cs.c | 13 +-- drivers/net/wireless/orinoco/spectrum_cs.c | 13 +-- drivers/net/wireless/ray_cs.c | 8 +- drivers/net/wireless/wl3501_cs.c | 8 +- drivers/parport/parport_cs.c | 8 +- drivers/pcmcia/ds.c | 3 +- drivers/pcmcia/pcmcia_resource.c | 137 +++++++++-------------- drivers/scsi/pcmcia/aha152x_stub.c | 6 +- drivers/scsi/pcmcia/fdomain_stub.c | 6 +- drivers/scsi/pcmcia/nsp_cs.c | 20 +--- drivers/scsi/pcmcia/qlogic_stub.c | 10 +- drivers/scsi/pcmcia/sym53c500_cs.c | 6 +- drivers/serial/serial_cs.c | 27 ++--- drivers/ssb/main.c | 2 +- drivers/staging/comedi/drivers/cb_das16_cs.c | 26 ++--- drivers/staging/comedi/drivers/das08_cs.c | 16 +-- drivers/staging/comedi/drivers/ni_daq_700.c | 23 +--- drivers/staging/comedi/drivers/ni_daq_dio24.c | 23 +--- drivers/staging/comedi/drivers/ni_labpc_cs.c | 24 +--- drivers/staging/comedi/drivers/ni_mio_cs.c | 9 +- drivers/staging/comedi/drivers/quatech_daqp_cs.c | 22 +--- drivers/staging/netwave/netwave_cs.c | 8 +- drivers/staging/wavelan/wavelan_cs.c | 15 +-- drivers/staging/wlags49_h2/wl_cs.c | 9 +- drivers/usb/host/sl811_cs.c | 18 +-- include/pcmcia/cs.h | 7 -- include/pcmcia/ds.h | 11 +- sound/pcmcia/pdaudiocf/pdaudiocf.c | 9 +- sound/pcmcia/vx/vxpocket.c | 8 +- 58 files changed, 244 insertions(+), 593 deletions(-) (limited to 'drivers/pcmcia') diff --git a/Documentation/pcmcia/driver-changes.txt b/Documentation/pcmcia/driver-changes.txt index 446f43b309df..3268a9ae7271 100644 --- a/Documentation/pcmcia/driver-changes.txt +++ b/Documentation/pcmcia/driver-changes.txt @@ -1,4 +1,14 @@ This file details changes in 2.6 which affect PCMCIA card driver authors: +* New IRQ request rules (as of 2.6.35) + Instead of the old pcmcia_request_irq() interface, drivers may now + choose between: + - calling request_irq/free_irq directly. Use the IRQ from *p_dev->irq. + - use pcmcia_request_irq(p_dev, handler_t); the PCMCIA core will + clean up automatically on calls to pcmcia_disable_device() or + device ejection. + - drivers still not capable of IRQF_SHARED (or not telling us so) may + use the deprecated pcmcia_request_exclusive_irq() for the time + being; they might receive a shared IRQ nonetheless. * no cs_error / CS_CHECK / CONFIG_PCMCIA_DEBUG (as of 2.6.33) Instead of the cs_error() callback or the CS_CHECK() macro, please use diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c index d94b8f0bd743..2aab1e0f6633 100644 --- a/drivers/ata/pata_pcmcia.c +++ b/drivers/ata/pata_pcmcia.c @@ -268,7 +268,6 @@ static int pcmcia_init_one(struct pcmcia_device *pdev) pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; pdev->io.Attributes2 = IO_DATA_PATH_WIDTH_8; pdev->io.IOAddrLines = 3; - pdev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; pdev->conf.Attributes = CONF_ENABLE_IRQ; pdev->conf.IntType = INT_MEMORY_AND_IO; @@ -293,8 +292,7 @@ static int pcmcia_init_one(struct pcmcia_device *pdev) } io_base = pdev->io.BasePort1; ctl_base = stk->ctl_base; - ret = pcmcia_request_irq(pdev, &pdev->irq); - if (ret) + if (!pdev->irq) goto failed; ret = pcmcia_request_configuration(pdev, &pdev->conf); @@ -344,7 +342,7 @@ static int pcmcia_init_one(struct pcmcia_device *pdev) } /* activate */ - ret = ata_host_activate(host, pdev->irq.AssignedIRQ, ata_sff_interrupt, + ret = ata_host_activate(host, pdev->irq, ata_sff_interrupt, IRQF_SHARED, &pcmcia_sht); if (ret) goto failed; diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c index d9bf87ca9e83..a34653db07bc 100644 --- a/drivers/bluetooth/bluecard_cs.c +++ b/drivers/bluetooth/bluecard_cs.c @@ -869,9 +869,6 @@ static int bluecard_probe(struct pcmcia_device *link) link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.NumPorts1 = 8; - link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; - - link->irq.Handler = bluecard_interrupt; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -908,9 +905,9 @@ static int bluecard_config(struct pcmcia_device *link) if (i != 0) goto failed; - i = pcmcia_request_irq(link, &link->irq); + i = pcmcia_request_irq(link, bluecard_interrupt); if (i != 0) - link->irq.AssignedIRQ = 0; + goto failed; i = pcmcia_request_configuration(link, &link->conf); if (i != 0) diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c index 027cb8bf650f..1ad9694d4450 100644 --- a/drivers/bluetooth/bt3c_cs.c +++ b/drivers/bluetooth/bt3c_cs.c @@ -661,9 +661,6 @@ static int bt3c_probe(struct pcmcia_device *link) link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.NumPorts1 = 8; - link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; - - link->irq.Handler = bt3c_interrupt; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -743,9 +740,9 @@ static int bt3c_config(struct pcmcia_device *link) goto failed; found_port: - i = pcmcia_request_irq(link, &link->irq); + i = pcmcia_request_irq(link, &bt3c_interrupt); if (i != 0) - link->irq.AssignedIRQ = 0; + goto failed; i = pcmcia_request_configuration(link, &link->conf); if (i != 0) diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c index 60c0953d7d00..1073d660d625 100644 --- a/drivers/bluetooth/btuart_cs.c +++ b/drivers/bluetooth/btuart_cs.c @@ -590,9 +590,6 @@ static int btuart_probe(struct pcmcia_device *link) link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.NumPorts1 = 8; - link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; - - link->irq.Handler = btuart_interrupt; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -672,9 +669,9 @@ static int btuart_config(struct pcmcia_device *link) goto failed; found_port: - i = pcmcia_request_irq(link, &link->irq); + i = pcmcia_request_irq(link, btuart_interrupt); if (i != 0) - link->irq.AssignedIRQ = 0; + goto failed; i = pcmcia_request_configuration(link, &link->conf); if (i != 0) diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c index 17788317c51a..3d72afddabb3 100644 --- a/drivers/bluetooth/dtl1_cs.c +++ b/drivers/bluetooth/dtl1_cs.c @@ -575,9 +575,6 @@ static int dtl1_probe(struct pcmcia_device *link) link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.NumPorts1 = 8; - link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; - - link->irq.Handler = dtl1_interrupt; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -621,9 +618,9 @@ static int dtl1_config(struct pcmcia_device *link) if (pcmcia_loop_config(link, dtl1_confcheck, NULL) < 0) goto failed; - i = pcmcia_request_irq(link, &link->irq); + i = pcmcia_request_irq(link, dtl1_interrupt); if (i != 0) - link->irq.AssignedIRQ = 0; + goto failed; i = pcmcia_request_configuration(link, &link->conf); if (i != 0) diff --git a/drivers/char/pcmcia/ipwireless/main.c b/drivers/char/pcmcia/ipwireless/main.c index dff24dae1485..2237890bc256 100644 --- a/drivers/char/pcmcia/ipwireless/main.c +++ b/drivers/char/pcmcia/ipwireless/main.c @@ -195,9 +195,6 @@ static int config_ipwireless(struct ipw_dev *ipw) link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; - link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; - link->irq.Handler = ipwireless_interrupt; - INIT_WORK(&ipw->work_reboot, signalled_reboot_work); ipwireless_init_hardware_v1(ipw->hardware, link->io.BasePort1, @@ -205,8 +202,7 @@ static int config_ipwireless(struct ipw_dev *ipw) ipw->is_v2_card, signalled_reboot_callback, ipw); - ret = pcmcia_request_irq(link, &link->irq); - + ret = pcmcia_request_irq(link, ipwireless_interrupt); if (ret != 0) goto exit; @@ -217,7 +213,7 @@ static int config_ipwireless(struct ipw_dev *ipw) (unsigned int) link->io.BasePort1, (unsigned int) (link->io.BasePort1 + link->io.NumPorts1 - 1), - (unsigned int) link->irq.AssignedIRQ); + (unsigned int) link->irq); if (ipw->attr_memory && ipw->common_memory) printk(KERN_INFO IPWIRELESS_PCCARD_NAME ": attr memory 0x%08lx-0x%08lx, common memory 0x%08lx-0x%08lx\n", @@ -271,8 +267,6 @@ exit: static void release_ipwireless(struct ipw_dev *ipw) { - pcmcia_disable_device(ipw->link); - if (ipw->common_memory) { release_mem_region(ipw->request_common_memory.Base, ipw->request_common_memory.Size); @@ -288,7 +282,6 @@ static void release_ipwireless(struct ipw_dev *ipw) if (ipw->attr_memory) pcmcia_release_window(ipw->link, ipw->handle_attr_memory); - /* Break the link with Card Services */ pcmcia_disable_device(ipw->link); } diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index c31a0d913d37..027690b70d2c 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c @@ -552,10 +552,6 @@ static int mgslpc_probe(struct pcmcia_device *link) /* Initialize the struct pcmcia_device structure */ - /* Interrupt setup */ - link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; - link->irq.Handler = NULL; - link->conf.Attributes = 0; link->conf.IntType = INT_MEMORY_AND_IO; @@ -608,9 +604,7 @@ static int mgslpc_config(struct pcmcia_device *link) link->conf.ConfigIndex = 8; link->conf.Present = PRESENT_OPTION; - link->irq.Handler = mgslpc_isr; - - ret = pcmcia_request_irq(link, &link->irq); + ret = pcmcia_request_irq(link, mgslpc_isr); if (ret) goto failed; ret = pcmcia_request_configuration(link, &link->conf); @@ -618,7 +612,7 @@ static int mgslpc_config(struct pcmcia_device *link) goto failed; info->io_base = link->io.BasePort1; - info->irq_level = link->irq.AssignedIRQ; + info->irq_level = link->irq; /* add to linked list of devices */ sprintf(info->node.dev_name, "mgslpc0"); @@ -628,7 +622,7 @@ static int mgslpc_config(struct pcmcia_device *link) printk(KERN_INFO "%s: index 0x%02x:", info->node.dev_name, link->conf.ConfigIndex); if (link->conf.Attributes & CONF_ENABLE_IRQ) - printk(", irq %d", link->irq.AssignedIRQ); + printk(", irq %d", link->irq); if (link->io.NumPorts1) printk(", io 0x%04x-0x%04x", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1-1); diff --git a/drivers/ide/ide-cs.c b/drivers/ide/ide-cs.c index b85450865ff0..17ad91e453e4 100644 --- a/drivers/ide/ide-cs.c +++ b/drivers/ide/ide-cs.c @@ -102,7 +102,6 @@ static int ide_probe(struct pcmcia_device *link) link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; link->io.IOAddrLines = 3; - link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -285,8 +284,7 @@ static int ide_config(struct pcmcia_device *link) io_base = link->io.BasePort1; ctl_base = stk->ctl_base; - ret = pcmcia_request_irq(link, &link->irq); - if (ret) + if (!link->irq) goto failed; ret = pcmcia_request_configuration(link, &link->conf); if (ret) @@ -299,11 +297,11 @@ static int ide_config(struct pcmcia_device *link) if (is_kme) outb(0x81, ctl_base+1); - host = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ, link); + host = idecs_register(io_base, ctl_base, link->irq, link); if (host == NULL && link->io.NumPorts1 == 0x20) { outb(0x02, ctl_base + 0x10); host = idecs_register(io_base + 0x10, ctl_base + 0x10, - link->irq.AssignedIRQ, link); + link->irq, link); } if (host == NULL) diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c index 94b796d84053..0d485f6c2194 100644 --- a/drivers/isdn/hardware/avm/avm_cs.c +++ b/drivers/isdn/hardware/avm/avm_cs.c @@ -107,9 +107,6 @@ static int avmcs_probe(struct pcmcia_device *p_dev) p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; p_dev->io.NumPorts2 = 0; - /* Interrupt setup */ - p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; - /* General socket configuration */ p_dev->conf.Attributes = CONF_ENABLE_IRQ; p_dev->conf.IntType = INT_MEMORY_AND_IO; @@ -172,7 +169,7 @@ static int avmcs_configcheck(struct pcmcia_device *p_dev, static int avmcs_config(struct pcmcia_device *link) { local_info_t *dev; - int i; + int i = -1; char devname[128]; int cardtype; int (*addcard)(unsigned int port, unsigned irq); @@ -190,11 +187,7 @@ static int avmcs_config(struct pcmcia_device *link) return -ENODEV; do { - /* - * allocate an interrupt line - */ - i = pcmcia_request_irq(link, &link->irq); - if (i != 0) { + if (!link->irq) { /* undo */ pcmcia_disable_device(link); break; @@ -249,9 +242,9 @@ static int avmcs_config(struct pcmcia_device *link) default: case AVM_CARDTYPE_B1: addcard = b1pcmcia_addcard_b1; break; } - if ((i = (*addcard)(link->io.BasePort1, link->irq.AssignedIRQ)) < 0) { + if ((i = (*addcard)(link->io.BasePort1, link->irq)) < 0) { printk(KERN_ERR "avm_cs: failed to add AVM-%s-Controller at i/o %#x, irq %d\n", - dev->node.dev_name, link->io.BasePort1, link->irq.AssignedIRQ); + dev->node.dev_name, link->io.BasePort1, link->irq); avmcs_release(link); return -ENODEV; } @@ -270,7 +263,7 @@ static int avmcs_config(struct pcmcia_device *link) static void avmcs_release(struct pcmcia_device *link) { - b1pcmcia_delcard(link->io.BasePort1, link->irq.AssignedIRQ); + b1pcmcia_delcard(link->io.BasePort1, link->irq); pcmcia_disable_device(link); } /* avmcs_release */ diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c index 8d1d63a02b34..3ae2176c6f75 100644 --- a/drivers/isdn/hisax/avma1_cs.c +++ b/drivers/isdn/hisax/avma1_cs.c @@ -119,9 +119,6 @@ static int __devinit avma1cs_probe(struct pcmcia_device *p_dev) p_dev->io.Attributes2 = IO_DATA_PATH_WIDTH_16; p_dev->io.IOAddrLines = 5; - /* Interrupt setup */ - p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; - /* General socket configuration */ p_dev->conf.Attributes = CONF_ENABLE_IRQ; p_dev->conf.IntType = INT_MEMORY_AND_IO; @@ -177,7 +174,7 @@ static int avma1cs_configcheck(struct pcmcia_device *p_dev, static int __devinit avma1cs_config(struct pcmcia_device *link) { local_info_t *dev; - int i; + int i = -1; char devname[128]; IsdnCard_t icard; int busy = 0; @@ -197,8 +194,7 @@ static int __devinit avma1cs_config(struct pcmcia_device *link) /* * allocate an interrupt line */ - i = pcmcia_request_irq(link, &link->irq); - if (i != 0) { + if (!link->irq) { /* undo */ pcmcia_disable_device(link); break; @@ -230,9 +226,9 @@ static int __devinit avma1cs_config(struct pcmcia_device *link) } printk(KERN_NOTICE "avma1_cs: checking at i/o %#x, irq %d\n", - link->io.BasePort1, link->irq.AssignedIRQ); + link->io.BasePort1, link->irq); - icard.para[0] = link->irq.AssignedIRQ; + icard.para[0] = link->irq; icard.para[1] = link->io.BasePort1; icard.protocol = isdnprot; icard.typ = ISDN_CTYPE_A1_PCMCIA; diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c index c9f2279e21f5..8e170e4b7cf2 100644 --- a/drivers/isdn/hisax/elsa_cs.c +++ b/drivers/isdn/hisax/elsa_cs.c @@ -136,10 +136,6 @@ static int __devinit elsa_cs_probe(struct pcmcia_device *link) local->cardnr = -1; - /* Interrupt setup */ - link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; - link->irq.Handler = NULL; - /* General socket configuration defaults can go here. In this client, we assume very little, and rely on the CIS for almost @@ -223,11 +219,8 @@ static int __devinit elsa_cs_config(struct pcmcia_device *link) if (i != 0) goto failed; - i = pcmcia_request_irq(link, &link->irq); - if (i != 0) { - link->irq.AssignedIRQ = 0; + if (!link->irq) goto failed; - } i = pcmcia_request_configuration(link, &link->conf); if (i != 0) @@ -244,7 +237,7 @@ static int __devinit elsa_cs_config(struct pcmcia_device *link) printk(KERN_INFO "%s: index 0x%02x: ", dev->node.dev_name, link->conf.ConfigIndex); if (link->conf.Attributes & CONF_ENABLE_IRQ) - printk(", irq %d", link->irq.AssignedIRQ); + printk(", irq %d", link->irq); if (link->io.NumPorts1) printk(", io 0x%04x-0x%04x", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1-1); @@ -253,7 +246,7 @@ static int __devinit elsa_cs_config(struct pcmcia_device *link) link->io.BasePort2+link->io.NumPorts2-1); printk("\n"); - icard.para[0] = link->irq.AssignedIRQ; + icard.para[0] = link->irq; icard.para[1] = link->io.BasePort1; icard.protocol = protocol; icard.typ = ISDN_CTYPE_ELSA_PCMCIA; diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c index 71b3ddef03bb..7778385b05b2 100644 --- a/drivers/isdn/hisax/sedlbauer_cs.c +++ b/drivers/isdn/hisax/sedlbauer_cs.c @@ -143,10 +143,6 @@ static int __devinit sedlbauer_probe(struct pcmcia_device *link) local->p_dev = link; link->priv = local; - /* Interrupt setup */ - link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; - link->irq.Handler = NULL; - /* General socket configuration defaults can go here. In this client, we assume very little, and rely on the CIS for almost @@ -227,9 +223,7 @@ static int sedlbauer_config_check(struct pcmcia_device *p_dev, else if (dflt->vpp1.present & (1<conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000; - /* Do we need to allocate an interrupt? */ - if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) - p_dev->conf.Attributes |= CONF_ENABLE_IRQ; + p_dev->conf.Attributes |= CONF_ENABLE_IRQ; /* IO window settings */ p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; @@ -312,17 +306,6 @@ static int __devinit sedlbauer_config(struct pcmcia_device *link) if (ret) goto failed; - /* - Allocate an interrupt line. Note that this does not assign a - handler to the interrupt, unless the 'Handler' member of the - irq structure is initialized. - */ - if (link->conf.Attributes & CONF_ENABLE_IRQ) { - ret = pcmcia_request_irq(link, &link->irq); - if (ret) - goto failed; - } - /* This actually configures the PCMCIA socket -- setting up the I/O windows and the interrupt mapping, and putting the @@ -346,7 +329,7 @@ static int __devinit sedlbauer_config(struct pcmcia_device *link) if (link->conf.Vpp) printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10); if (link->conf.Attributes & CONF_ENABLE_IRQ) - printk(", irq %d", link->irq.AssignedIRQ); + printk(", irq %d", link->irq); if (link->io.NumPorts1) printk(", io 0x%04x-0x%04x", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1-1); @@ -358,7 +341,7 @@ static int __devinit sedlbauer_config(struct pcmcia_device *link) req->Base+req->Size-1); printk("\n"); - icard.para[0] = link->irq.AssignedIRQ; + icard.para[0] = link->irq; icard.para[1] = link->io.BasePort1; icard.protocol = protocol; icard.typ = ISDN_CTYPE_SEDLBAUER_PCMCIA; diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c index d010a0da8e19..02dec13f25e5 100644 --- a/drivers/isdn/hisax/teles_cs.c +++ b/drivers/isdn/hisax/teles_cs.c @@ -126,10 +126,6 @@ static int __devinit teles_probe(struct pcmcia_device *link) local->p_dev = link; link->priv = local; - /* Interrupt setup */ - link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; - link->irq.Handler = NULL; - /* General socket configuration defaults can go here. In this client, we assume very little, and rely on the CIS for almost @@ -213,11 +209,8 @@ static int __devinit teles_cs_config(struct pcmcia_device *link) if (i != 0) goto cs_failed; - i = pcmcia_request_irq(link, &link->irq); - if (i != 0) { - link->irq.AssignedIRQ = 0; + if (!link->irq) goto cs_failed; - } i = pcmcia_request_configuration(link, &link->conf); if (i != 0) @@ -234,7 +227,7 @@ static int __devinit teles_cs_config(struct pcmcia_device *link) printk(KERN_INFO "%s: index 0x%02x:", dev->node.dev_name, link->conf.ConfigIndex); if (link->conf.Attributes & CONF_ENABLE_IRQ) - printk(", irq %d", link->irq.AssignedIRQ); + printk(", irq %d", link->irq); if (link->io.NumPorts1) printk(", io 0x%04x-0x%04x", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1-1); @@ -243,7 +236,7 @@ static int __devinit teles_cs_config(struct pcmcia_device *link) link->io.BasePort2+link->io.NumPorts2-1); printk("\n"); - icard.para[0] = link->irq.AssignedIRQ; + icard.para[0] = link->irq; icard.para[1] = link->io.BasePort1; icard.protocol = protocol; icard.typ = ISDN_CTYPE_TELESPCMCIA; diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c index 757f87bb1db3..14428317c009 100644 --- a/drivers/net/pcmcia/3c574_cs.c +++ b/drivers/net/pcmcia/3c574_cs.c @@ -283,8 +283,6 @@ static int tc574_probe(struct pcmcia_device *link) spin_lock_init(&lp->window_lock); link->io.NumPorts1 = 32; link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; - link->irq.Handler = &el3_interrupt; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.ConfigIndex = 1; @@ -353,7 +351,7 @@ static int tc574_config(struct pcmcia_device *link) if (i != 0) goto failed; - ret = pcmcia_request_irq(link, &link->irq); + ret = pcmcia_request_irq(link, el3_interrupt); if (ret) goto failed; @@ -361,7 +359,7 @@ static int tc574_config(struct pcmcia_device *link) if (ret) goto failed; - dev->irq = link->irq.AssignedIRQ; + dev->irq = link->irq; dev->base_addr = link->io.BasePort1; ioaddr = dev->base_addr; diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c index 091e0b00043e..405d772bfde7 100644 --- a/drivers/net/pcmcia/3c589_cs.c +++ b/drivers/net/pcmcia/3c589_cs.c @@ -194,8 +194,7 @@ static int tc589_probe(struct pcmcia_device *link) spin_lock_init(&lp->lock); link->io.NumPorts1 = 16; link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; - link->irq.Handler = &el3_interrupt; + link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.ConfigIndex = 1; @@ -271,7 +270,7 @@ static int tc589_config(struct pcmcia_device *link) if (i != 0) goto failed; - ret = pcmcia_request_irq(link, &link->irq); + ret = pcmcia_request_irq(link, el3_interrupt); if (ret) goto failed; @@ -279,7 +278,7 @@ static int tc589_config(struct pcmcia_device *link) if (ret) goto failed; - dev->irq = link->irq.AssignedIRQ; + dev->irq = link->irq; dev->base_addr = link->io.BasePort1; ioaddr = dev->base_addr; EL3WINDOW(0); diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index 9f3d593f14ed..967547a84b4b 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c @@ -168,7 +168,6 @@ static int axnet_probe(struct pcmcia_device *link) info = PRIV(dev); info->p_dev = link; link->priv = dev; - link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -265,12 +264,9 @@ static int try_io_port(struct pcmcia_device *link) int j, ret; if (link->io.NumPorts1 == 32) { link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - if (link->io.NumPorts2 > 0) { - /* for master/slave multifunction cards */ + /* for master/slave multifunction cards */ + if (link->io.NumPorts2 > 0) link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; - link->irq.Attributes = - IRQ_TYPE_DYNAMIC_SHARING; - } } else { /* This should be two 16-port windows */ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; @@ -336,8 +332,7 @@ static int axnet_config(struct pcmcia_device *link) if (ret != 0) goto failed; - ret = pcmcia_request_irq(link, &link->irq); - if (ret) + if (!link->irq) goto failed; if (link->io.NumPorts2 == 8) { @@ -349,7 +344,7 @@ static int axnet_config(struct pcmcia_device *link) if (ret) goto failed; - dev->irq = link->irq.AssignedIRQ; + dev->irq = link->irq; dev->base_addr = link->io.BasePort1; if (!get_prom(link)) { diff --git a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c index 21d9c9d815d1..278438beb915 100644 --- a/drivers/net/pcmcia/com20020_cs.c +++ b/drivers/net/pcmcia/com20020_cs.c @@ -163,7 +163,6 @@ static int com20020_probe(struct pcmcia_device *p_dev) p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; p_dev->io.NumPorts1 = 16; p_dev->io.IOAddrLines = 16; - p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE; p_dev->conf.Attributes = CONF_ENABLE_IRQ; p_dev->conf.IntType = INT_MEMORY_AND_IO; @@ -275,15 +274,14 @@ static int com20020_config(struct pcmcia_device *link) dev_dbg(&link->dev, "got ioaddr %Xh\n", ioaddr); dev_dbg(&link->dev, "request IRQ %d\n", - link->irq.AssignedIRQ); - i = pcmcia_request_irq(link, &link->irq); - if (i != 0) + link->irq); + if (!link->irq) { dev_dbg(&link->dev, "requestIRQ failed totally!\n"); goto failed; } - dev->irq = link->irq.AssignedIRQ; + dev->irq = link->irq; ret = pcmcia_request_configuration(link, &link->conf); if (ret) diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c index b9dc80b9d04a..31f1a037737c 100644 --- a/drivers/net/pcmcia/fmvj18x_cs.c +++ b/drivers/net/pcmcia/fmvj18x_cs.c @@ -254,10 +254,6 @@ static int fmvj18x_probe(struct pcmcia_device *link) link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.IOAddrLines = 5; - /* Interrupt setup */ - link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; - link->irq.Handler = fjn_interrupt; - /* General socket configuration */ link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -425,8 +421,6 @@ static int fmvj18x_config(struct pcmcia_device *link) } if (link->io.NumPorts2 != 0) { - link->irq.Attributes = - IRQ_TYPE_DYNAMIC_SHARING; ret = mfc_try_io_port(link); if (ret != 0) goto failed; } else if (cardtype == UNGERMANN) { @@ -437,14 +431,14 @@ static int fmvj18x_config(struct pcmcia_device *link) if (ret) goto failed; } - ret = pcmcia_request_irq(link, &link->irq); + ret = pcmcia_request_irq(link, fjn_interrupt); if (ret) goto failed; ret = pcmcia_request_configuration(link, &link->conf); if (ret) goto failed; - dev->irq = link->irq.AssignedIRQ; + dev->irq = link->irq; dev->base_addr = link->io.BasePort1; if (link->io.BasePort2 != 0) { diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c index 37f4a6fdc3ef..0225cdffa4b9 100644 --- a/drivers/net/pcmcia/ibmtr_cs.c +++ b/drivers/net/pcmcia/ibmtr_cs.c @@ -156,8 +156,6 @@ static int __devinit ibmtr_attach(struct pcmcia_device *link) link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.NumPorts1 = 4; link->io.IOAddrLines = 16; - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; - link->irq.Handler = ibmtr_interrupt; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.Present = PRESENT_OPTION; @@ -238,11 +236,11 @@ static int __devinit ibmtr_config(struct pcmcia_device *link) } dev->base_addr = link->io.BasePort1; - ret = pcmcia_request_irq(link, &link->irq); + ret = pcmcia_request_exclusive_irq(link, ibmtr_interrupt); if (ret) goto failed; - dev->irq = link->irq.AssignedIRQ; - ti->irq = link->irq.AssignedIRQ; + dev->irq = link->irq; + ti->irq = link->irq; ti->global_int_enable=GLOBAL_INT_ENABLE+((dev->irq==9) ? 2 : dev->irq); /* Allocate the MMIO memory window */ diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c index c717b143f11a..b779e3a0b4dd 100644 --- a/drivers/net/pcmcia/nmclan_cs.c +++ b/drivers/net/pcmcia/nmclan_cs.c @@ -463,8 +463,6 @@ static int nmclan_probe(struct pcmcia_device *link) link->io.NumPorts1 = 32; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.IOAddrLines = 5; - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; - link->irq.Handler = mace_interrupt; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.ConfigIndex = 1; @@ -652,14 +650,14 @@ static int nmclan_config(struct pcmcia_device *link) ret = pcmcia_request_io(link, &link->io); if (ret) goto failed; - ret = pcmcia_request_irq(link, &link->irq); + ret = pcmcia_request_exclusive_irq(link, mace_interrupt); if (ret) goto failed; ret = pcmcia_request_configuration(link, &link->conf); if (ret) goto failed; - dev->irq = link->irq.AssignedIRQ; + dev->irq = link->irq; dev->base_addr = link->io.BasePort1; ioaddr = dev->base_addr; diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index 4c0368de1815..af09be487577 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -264,7 +264,6 @@ static int pcnet_probe(struct pcmcia_device *link) info->p_dev = link; link->priv = dev; - link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -488,8 +487,6 @@ static int try_io_port(struct pcmcia_device *link) if (link->io.NumPorts2 > 0) { /* for master/slave multifunction cards */ link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; - link->irq.Attributes = - IRQ_TYPE_DYNAMIC_SHARING; } } else { /* This should be two 16-port windows */ @@ -559,8 +556,7 @@ static int pcnet_config(struct pcmcia_device *link) if (ret) goto failed; - ret = pcmcia_request_irq(link, &link->irq); - if (ret) + if (!link->irq) goto failed; if (link->io.NumPorts2 == 8) { @@ -574,7 +570,7 @@ static int pcnet_config(struct pcmcia_device *link) ret = pcmcia_request_configuration(link, &link->conf); if (ret) goto failed; - dev->irq = link->irq.AssignedIRQ; + dev->irq = link->irq; dev->base_addr = link->io.BasePort1; if (info->flags & HAS_MISC_REG) { if ((if_port == 1) || (if_port == 2)) diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c index ccc553782a0d..ad061c7106b5 100644 --- a/drivers/net/pcmcia/smc91c92_cs.c +++ b/drivers/net/pcmcia/smc91c92_cs.c @@ -329,8 +329,6 @@ static int smc91c92_probe(struct pcmcia_device *link) link->io.NumPorts1 = 16; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.IOAddrLines = 4; - link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; - link->irq.Handler = &smc_interrupt; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -453,7 +451,6 @@ static int mhz_mfc_config(struct pcmcia_device *link) link->conf.Attributes |= CONF_ENABLE_SPKR; link->conf.Status = CCSR_AUDIO_ENA; - link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; link->io.IOAddrLines = 16; link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; link->io.NumPorts2 = 8; @@ -652,7 +649,6 @@ static int osi_config(struct pcmcia_device *link) link->conf.Attributes |= CONF_ENABLE_SPKR; link->conf.Status = CCSR_AUDIO_ENA; - link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; link->io.NumPorts1 = 64; link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; link->io.NumPorts2 = 8; @@ -877,7 +873,7 @@ static int smc91c92_config(struct pcmcia_device *link) if (i) goto config_failed; - i = pcmcia_request_irq(link, &link->irq); + i = pcmcia_request_irq(link, smc_interrupt); if (i) goto config_failed; i = pcmcia_request_configuration(link, &link->conf); @@ -887,7 +883,7 @@ static int smc91c92_config(struct pcmcia_device *link) if (smc->manfid == MANFID_MOTOROLA) mot_config(link); - dev->irq = link->irq.AssignedIRQ; + dev->irq = link->irq; if ((if_port >= 0) && (if_port <= 2)) dev->if_port = if_port; diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c index 4d1802e457be..c9e7d7d47835 100644 --- a/drivers/net/pcmcia/xirc2ps_cs.c +++ b/drivers/net/pcmcia/xirc2ps_cs.c @@ -555,7 +555,6 @@ xirc2ps_probe(struct pcmcia_device *link) link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.ConfigIndex = 1; - link->irq.Handler = xirc2ps_interrupt; /* Fill in card specific entries */ dev->netdev_ops = &netdev_ops; @@ -841,7 +840,6 @@ xirc2ps_config(struct pcmcia_device * link) link->conf.Attributes |= CONF_ENABLE_SPKR; link->conf.Status |= CCSR_AUDIO_ENA; } - link->irq.Attributes |= IRQ_TYPE_DYNAMIC_SHARING; link->io.NumPorts2 = 8; link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; if (local->dingo) { @@ -866,7 +864,6 @@ xirc2ps_config(struct pcmcia_device * link) } printk(KNOT_XIRC "no ports available\n"); } else { - link->irq.Attributes |= IRQ_TYPE_DYNAMIC_SHARING; link->io.NumPorts1 = 16; for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) { link->io.BasePort1 = ioaddr; @@ -885,7 +882,7 @@ xirc2ps_config(struct pcmcia_device * link) * Now allocate an interrupt line. Note that this does not * actually assign a handler to the interrupt. */ - if ((err=pcmcia_request_irq(link, &link->irq))) + if ((err=pcmcia_request_irq(link, xirc2ps_interrupt))) goto config_error; /**************** @@ -982,7 +979,7 @@ xirc2ps_config(struct pcmcia_device * link) printk(KNOT_XIRC "invalid if_port requested\n"); /* we can now register the device with the net subsystem */ - dev->irq = link->irq.AssignedIRQ; + dev->irq = link->irq; dev->base_addr = link->io.BasePort1; if (local->dingo) diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c index f6036fb42319..7867c51be15f 100644 --- a/drivers/net/wireless/airo_cs.c +++ b/drivers/net/wireless/airo_cs.c @@ -132,10 +132,6 @@ static int airo_probe(struct pcmcia_device *p_dev) dev_dbg(&p_dev->dev, "airo_attach()\n"); - /* Interrupt setup */ - p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; - p_dev->irq.Handler = NULL; - /* General socket configuration defaults can go here. In this client, we assume very little, and rely on the CIS for almost @@ -212,9 +208,7 @@ static int airo_cs_config_check(struct pcmcia_device *p_dev, else if (dflt->vpp1.present & (1<conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000; - /* Do we need to allocate an interrupt? */ - if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) - p_dev->conf.Attributes |= CONF_ENABLE_IRQ; + p_dev->conf.Attributes |= CONF_ENABLE_IRQ; /* IO window settings */ p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; @@ -300,16 +294,8 @@ static int airo_config(struct pcmcia_device *link) if (ret) goto failed; - /* - Allocate an interrupt line. Note that this does not assign a - handler to the interrupt, unless the 'Handler' member of the - irq structure is initialized. - */ - if (link->conf.Attributes & CONF_ENABLE_IRQ) { - ret = pcmcia_request_irq(link, &link->irq); - if (ret) - goto failed; - } + if (!link->irq) + goto failed; /* This actually configures the PCMCIA socket -- setting up @@ -320,7 +306,7 @@ static int airo_config(struct pcmcia_device *link) if (ret) goto failed; ((local_info_t *)link->priv)->eth_dev = - init_airo_card(link->irq.AssignedIRQ, + init_airo_card(link->irq, link->io.BasePort1, 1, &link->dev); if (!((local_info_t *)link->priv)->eth_dev) goto failed; @@ -338,8 +324,7 @@ static int airo_config(struct pcmcia_device *link) dev->node.dev_name, link->conf.ConfigIndex); if (link->conf.Vpp) printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10); - if (link->conf.Attributes & CONF_ENABLE_IRQ) - printk(", irq %d", link->irq.AssignedIRQ); + printk(", irq %d", link->irq); if (link->io.NumPorts1) printk(", io 0x%04x-0x%04x", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1-1); diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c index 32407911842f..759cdc419326 100644 --- a/drivers/net/wireless/atmel_cs.c +++ b/drivers/net/wireless/atmel_cs.c @@ -141,10 +141,6 @@ static int atmel_probe(struct pcmcia_device *p_dev) dev_dbg(&p_dev->dev, "atmel_attach()\n"); - /* Interrupt setup */ - p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; - p_dev->irq.Handler = NULL; - /* General socket configuration defaults can go here. In this client, we assume very little, and rely on the CIS for almost @@ -226,9 +222,7 @@ static int atmel_config_check(struct pcmcia_device *p_dev, else if (dflt->vpp1.present & (1<conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000; - /* Do we need to allocate an interrupt? */ - if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) - p_dev->conf.Attributes |= CONF_ENABLE_IRQ; + p_dev->conf.Attributes |= CONF_ENABLE_IRQ; /* IO window settings */ p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; @@ -278,15 +272,9 @@ static int atmel_config(struct pcmcia_device *link) if (pcmcia_loop_config(link, atmel_config_check, NULL)) goto failed; - /* - Allocate an interrupt line. Note that this does not assign a - handler to the interrupt, unless the 'Handler' member of the - irq structure is initialized. - */ - if (link->conf.Attributes & CONF_ENABLE_IRQ) { - ret = pcmcia_request_irq(link, &link->irq); - if (ret) - goto failed; + if (!link->irq) { + dev_err(&link->dev, "atmel: cannot assign IRQ: check that CONFIG_ISA is set in kernel config."); + goto failed; } /* @@ -298,14 +286,8 @@ static int atmel_config(struct pcmcia_device *link) if (ret) goto failed; - if (link->irq.AssignedIRQ == 0) { - printk(KERN_ALERT - "atmel: cannot assign IRQ: check that CONFIG_ISA is set in kernel config."); - goto failed; - } - ((local_info_t*)link->priv)->eth_dev = - init_atmel_card(link->irq.AssignedIRQ, + init_atmel_card(link->irq, link->io.BasePort1, did ? did->driver_info : ATMEL_FW_TYPE_NONE, &link->dev, diff --git a/drivers/net/wireless/b43/pcmcia.c b/drivers/net/wireless/b43/pcmcia.c index 609e7051e018..0e99b634267c 100644 --- a/drivers/net/wireless/b43/pcmcia.c +++ b/drivers/net/wireless/b43/pcmcia.c @@ -98,10 +98,7 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev) if (res != 0) goto err_disable; - dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; - dev->irq.Handler = NULL; /* The handler is registered later. */ - res = pcmcia_request_irq(dev, &dev->irq); - if (res != 0) + if (!dev->irq) goto err_disable; res = pcmcia_request_configuration(dev, &dev->conf); diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c index a36501dbbe02..5e2efbb03675 100644 --- a/drivers/net/wireless/hostap/hostap_cs.c +++ b/drivers/net/wireless/hostap/hostap_cs.c @@ -556,15 +556,7 @@ static int prism2_config_check(struct pcmcia_device *p_dev, p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000; /* Do we need to allocate an interrupt? */ - if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) - p_dev->conf.Attributes |= CONF_ENABLE_IRQ; - else if (!(p_dev->conf.Attributes & CONF_ENABLE_IRQ)) { - /* At least Compaq WL200 does not have IRQInfo1 set, - * but it does not work without interrupts.. */ - printk(KERN_WARNING "Config has no IRQ info, but trying to " - "enable IRQ anyway..\n"); - p_dev->conf.Attributes |= CONF_ENABLE_IRQ; - } + p_dev->conf.Attributes |= CONF_ENABLE_IRQ; /* IO window settings */ PDEBUG(DEBUG_EXTRA, "IO window settings: cfg->io.nwin=%d " @@ -636,18 +628,9 @@ static int prism2_config(struct pcmcia_device *link) strcpy(hw_priv->node.dev_name, dev->name); link->dev_node = &hw_priv->node; - /* - * Allocate an interrupt line. Note that this does not assign a - * handler to the interrupt, unless the 'Handler' member of the - * irq structure is initialized. - */ - if (link->conf.Attributes & CONF_ENABLE_IRQ) { - link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; - link->irq.Handler = prism2_interrupt; - ret = pcmcia_request_irq(link, &link->irq); - if (ret) - goto failed; - } + ret = pcmcia_request_irq(link, prism2_interrupt); + if (ret) + goto failed; /* * This actually configures the PCMCIA socket -- setting up @@ -658,7 +641,7 @@ static int prism2_config(struct pcmcia_device *link) if (ret) goto failed; - dev->irq = link->irq.AssignedIRQ; + dev->irq = link->irq; dev->base_addr = link->io.BasePort1; /* Finally, report what we've done */ @@ -668,7 +651,7 @@ static int prism2_config(struct pcmcia_device *link) printk(", Vpp %d.%d", link->conf.Vpp / 10, link->conf.Vpp % 10); if (link->conf.Attributes & CONF_ENABLE_IRQ) - printk(", irq %d", link->irq.AssignedIRQ); + printk(", irq %d", link->irq); if (link->io.NumPorts1) printk(", io 0x%04x-0x%04x", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1-1); diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c index 6d55439a7b97..08e4e3908003 100644 --- a/drivers/net/wireless/libertas/if_cs.c +++ b/drivers/net/wireless/libertas/if_cs.c @@ -777,7 +777,7 @@ static void if_cs_release(struct pcmcia_device *p_dev) lbs_deb_enter(LBS_DEB_CS); - free_irq(p_dev->irq.AssignedIRQ, card); + free_irq(p_dev->irq, card); pcmcia_disable_device(p_dev); if (card->iobase) ioport_unmap(card->iobase); @@ -807,8 +807,7 @@ static int if_cs_ioprobe(struct pcmcia_device *p_dev, p_dev->io.NumPorts1 = cfg->io.win[0].len; /* Do we need to allocate an interrupt? */ - if (cfg->irq.IRQInfo1) - p_dev->conf.Attributes |= CONF_ENABLE_IRQ; + p_dev->conf.Attributes |= CONF_ENABLE_IRQ; /* IO window settings */ if (cfg->io.nwin != 1) { @@ -837,9 +836,6 @@ static int if_cs_probe(struct pcmcia_device *p_dev) card->p_dev = p_dev; p_dev->priv = card; - p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; - p_dev->irq.Handler = NULL; - p_dev->conf.Attributes = 0; p_dev->conf.IntType = INT_MEMORY_AND_IO; @@ -854,13 +850,8 @@ static int if_cs_probe(struct pcmcia_device *p_dev) * a handler to the interrupt, unless the 'Handler' member of * the irq structure is initialized. */ - if (p_dev->conf.Attributes & CONF_ENABLE_IRQ) { - ret = pcmcia_request_irq(p_dev, &p_dev->irq); - if (ret) { - lbs_pr_err("error in pcmcia_request_irq\n"); - goto out1; - } - } + if (!p_dev->irq) + goto out1; /* Initialize io access */ card->iobase = ioport_map(p_dev->io.BasePort1, p_dev->io.NumPorts1); @@ -883,7 +874,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev) /* Finally, report what we've done */ lbs_deb_cs("irq %d, io 0x%04x-0x%04x\n", - p_dev->irq.AssignedIRQ, p_dev->io.BasePort1, + p_dev->irq, p_dev->io.BasePort1, p_dev->io.BasePort1 + p_dev->io.NumPorts1 - 1); /* @@ -940,7 +931,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev) priv->fw_ready = 1; /* Now actually get the IRQ */ - ret = request_irq(p_dev->irq.AssignedIRQ, if_cs_interrupt, + ret = request_irq(p_dev->irq, if_cs_interrupt, IRQF_SHARED, DRV_NAME, card); if (ret) { lbs_pr_err("error in request_irq\n"); diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c index 1d4ada188eda..5d29b11fdbc0 100644 --- a/drivers/net/wireless/orinoco/orinoco_cs.c +++ b/drivers/net/wireless/orinoco/orinoco_cs.c @@ -119,10 +119,6 @@ orinoco_cs_probe(struct pcmcia_device *link) card->p_dev = link; link->priv = priv; - /* Interrupt setup */ - link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; - link->irq.Handler = orinoco_interrupt; - /* General socket configuration defaults can go here. In this * client, we assume very little, and rely on the CIS for * almost everything. In most clients, many details (i.e., @@ -258,12 +254,7 @@ orinoco_cs_config(struct pcmcia_device *link) goto failed; } - /* - * Allocate an interrupt line. Note that this does not assign - * a handler to the interrupt, unless the 'Handler' member of - * the irq structure is initialized. - */ - ret = pcmcia_request_irq(link, &link->irq); + ret = pcmcia_request_irq(link, orinoco_interrupt); if (ret) goto failed; @@ -296,7 +287,7 @@ orinoco_cs_config(struct pcmcia_device *link) /* Register an interface with the stack */ if (orinoco_if_add(priv, link->io.BasePort1, - link->irq.AssignedIRQ) != 0) { + link->irq) != 0) { printk(KERN_ERR PFX "orinoco_if_add() failed\n"); goto failed; } diff --git a/drivers/net/wireless/orinoco/spectrum_cs.c b/drivers/net/wireless/orinoco/spectrum_cs.c index 59bda240fdc2..7a8e056cd62d 100644 --- a/drivers/net/wireless/orinoco/spectrum_cs.c +++ b/drivers/net/wireless/orinoco/spectrum_cs.c @@ -193,10 +193,6 @@ spectrum_cs_probe(struct pcmcia_device *link) card->p_dev = link; link->priv = priv; - /* Interrupt setup */ - link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; - link->irq.Handler = orinoco_interrupt; - /* General socket configuration defaults can go here. In this * client, we assume very little, and rely on the CIS for * almost everything. In most clients, many details (i.e., @@ -332,12 +328,7 @@ spectrum_cs_config(struct pcmcia_device *link) goto failed; } - /* - * Allocate an interrupt line. Note that this does not assign - * a handler to the interrupt, unless the 'Handler' member of - * the irq structure is initialized. - */ - ret = pcmcia_request_irq(link, &link->irq); + ret = pcmcia_request_irq(link, orinoco_interrupt); if (ret) goto failed; @@ -374,7 +365,7 @@ spectrum_cs_config(struct pcmcia_device *link) /* Register an interface with the stack */ if (orinoco_if_add(priv, link->io.BasePort1, - link->irq.AssignedIRQ) != 0) { + link->irq) != 0) { printk(KERN_ERR PFX "orinoco_if_add() failed\n"); goto failed; } diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 11865ea21875..fe4642a49bfb 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c @@ -321,10 +321,6 @@ static int ray_probe(struct pcmcia_device *p_dev) p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; p_dev->io.IOAddrLines = 5; - /* Interrupt setup. For PCMCIA, driver takes what's given */ - p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; - p_dev->irq.Handler = &ray_interrupt; - /* General socket configuration */ p_dev->conf.Attributes = CONF_ENABLE_IRQ; p_dev->conf.IntType = INT_MEMORY_AND_IO; @@ -417,10 +413,10 @@ static int ray_config(struct pcmcia_device *link) /* Now allocate an interrupt line. Note that this does not actually assign a handler to the interrupt. */ - ret = pcmcia_request_irq(link, &link->irq); + ret = pcmcia_request_irq(link, ray_interrupt); if (ret) goto failed; - dev->irq = link->irq.AssignedIRQ; + dev->irq = link->irq; /* This actually configures the PCMCIA socket -- setting up the I/O windows and the interrupt mapping. diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c index 7b9621de239f..c43f05b98c4e 100644 --- a/drivers/net/wireless/wl3501_cs.c +++ b/drivers/net/wireless/wl3501_cs.c @@ -1897,10 +1897,6 @@ static int wl3501_probe(struct pcmcia_device *p_dev) p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; p_dev->io.IOAddrLines = 5; - /* Interrupt setup */ - p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; - p_dev->irq.Handler = wl3501_interrupt; - /* General socket configuration */ p_dev->conf.Attributes = CONF_ENABLE_IRQ; p_dev->conf.IntType = INT_MEMORY_AND_IO; @@ -1961,7 +1957,7 @@ static int wl3501_config(struct pcmcia_device *link) /* Now allocate an interrupt line. Note that this does not actually * assign a handler to the interrupt. */ - ret = pcmcia_request_irq(link, &link->irq); + ret = pcmcia_request_irq(link, wl3501_interrupt); if (ret) goto failed; @@ -1972,7 +1968,7 @@ static int wl3501_config(struct pcmcia_device *link) if (ret) goto failed; - dev->irq = link->irq.AssignedIRQ; + dev->irq = link->irq; dev->base_addr = link->io.BasePort1; SET_NETDEV_DEV(dev, &link->dev); if (register_netdev(dev)) { diff --git a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c index 7dd370fa3439..80c9052bf3cd 100644 --- a/drivers/parport/parport_cs.c +++ b/drivers/parport/parport_cs.c @@ -105,7 +105,6 @@ static int parport_probe(struct pcmcia_device *link) link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; - link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -174,20 +173,19 @@ static int parport_config(struct pcmcia_device *link) if (ret) goto failed; - ret = pcmcia_request_irq(link, &link->irq); - if (ret) + if (!link->irq) goto failed; ret = pcmcia_request_configuration(link, &link->conf); if (ret) goto failed; p = parport_pc_probe_port(link->io.BasePort1, link->io.BasePort2, - link->irq.AssignedIRQ, PARPORT_DMA_NONE, + link->irq, PARPORT_DMA_NONE, &link->dev, IRQF_SHARED); if (p == NULL) { printk(KERN_NOTICE "parport_cs: parport_pc_probe_port() at " "0x%3x, irq %u failed\n", link->io.BasePort1, - link->irq.AssignedIRQ); + link->irq); goto failed; } diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 5fd2948c7ed9..a2649c7b05bd 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -546,7 +546,6 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu p_dev->function_config = tmp_dev->function_config; p_dev->io = tmp_dev->io; p_dev->irq = tmp_dev->irq; - p_dev->irq_v = tmp_dev->irq_v; kref_get(&p_dev->function_config->ref); } @@ -571,7 +570,7 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu dev_printk(KERN_NOTICE, &p_dev->dev, "pcmcia: registering new device %s (IRQ: %d)\n", - p_dev->devname, p_dev->irq_v); + p_dev->devname, p_dev->irq); pcmcia_device_query(p_dev); diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index 8dce223f3f44..f355c5ac407b 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c @@ -408,41 +408,6 @@ out: } /* pcmcia_release_io */ -static int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req) -{ - struct pcmcia_socket *s = p_dev->socket; - config_t *c; - int ret = -EINVAL; - - mutex_lock(&s->ops_mutex); - - c = p_dev->function_config; - - if (!p_dev->_irq) - goto out; - - p_dev->_irq = 0; - - if (c->state & CONFIG_LOCKED) - goto out; - - if (s->pcmcia_irq != req->AssignedIRQ) { - dev_dbg(&s->dev, "IRQ must match assigned one\n"); - goto out; - } - - if (req->Handler) - free_irq(req->AssignedIRQ, p_dev->priv); - - ret = 0; - -out: - mutex_unlock(&s->ops_mutex); - - return ret; -} /* pcmcia_release_irq */ - - int pcmcia_release_window(struct pcmcia_device *p_dev, window_handle_t wh) { struct pcmcia_socket *s = p_dev->socket; @@ -681,61 +646,66 @@ out: EXPORT_SYMBOL(pcmcia_request_io); -/** pcmcia_request_irq +/** + * pcmcia_request_irq() - attempt to request a IRQ for a PCMCIA device * - * Request_irq() reserves an irq for this client. + * pcmcia_request_irq() is a wrapper around request_irq which will allow + * the PCMCIA core to clean up the registration in pcmcia_disable_device(). + * Drivers are free to use request_irq() directly, but then they need to + * call free_irq themselfves, too. Also, only IRQF_SHARED capable IRQ + * handlers are allowed. */ - -int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) +int __must_check pcmcia_request_irq(struct pcmcia_device *p_dev, + irq_handler_t handler) { - struct pcmcia_socket *s = p_dev->socket; - config_t *c; - int ret = -EINVAL, irq = p_dev->irq_v; - int type = IRQF_SHARED; + int ret; - mutex_lock(&s->ops_mutex); + if (!p_dev->irq) + return -EINVAL; - if (!(s->state & SOCKET_PRESENT)) { - dev_dbg(&s->dev, "No card present\n"); - goto out; - } - c = p_dev->function_config; - if (c->state & CONFIG_LOCKED) { - dev_dbg(&s->dev, "Configuration is locked\n"); - goto out; - } + ret = request_irq(p_dev->irq, handler, IRQF_SHARED, + p_dev->devname, p_dev->priv); + if (!ret) + p_dev->_irq = 1; - if (!irq) { - dev_dbg(&s->dev, "no IRQ available\n"); - goto out; - } + return ret; +} +EXPORT_SYMBOL(pcmcia_request_irq); - if (!(req->Attributes & IRQ_TYPE_DYNAMIC_SHARING)) { - req->Attributes |= IRQ_TYPE_DYNAMIC_SHARING; - dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: the driver " - "needs updating to supported shared IRQ lines.\n"); - } - if (req->Handler) { - ret = request_irq(irq, req->Handler, type, - p_dev->devname, p_dev->priv); - if (ret) { - dev_printk(KERN_INFO, &s->dev, - "request_irq() failed\n"); - goto out; - } - } +/** + * pcmcia_request_exclusive_irq() - attempt to request an exclusive IRQ first + * + * pcmcia_request_exclusive_irq() is a wrapper around request_irq which + * attempts first to request an exclusive IRQ. If it fails, it also accepts + * a shared IRQ, but prints out a warning. PCMCIA drivers should allow for + * IRQ sharing and either use request_irq directly (then they need to call + * free_irq themselves, too), or the pcmcia_request_irq() function. + */ +int __must_check +pcmcia_request_exclusive_irq(struct pcmcia_device *p_dev, irq_handler_t handler) +{ + int ret; - req->AssignedIRQ = irq; + if (!p_dev->irq) + return -EINVAL; - p_dev->_irq = 1; + ret = request_irq(p_dev->irq, handler, 0, p_dev->devname, p_dev->priv); + if (ret) { + ret = pcmcia_request_irq(p_dev, handler); + dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: " + "request for exclusive IRQ could not be fulfilled.\n"); + dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: the driver " + "needs updating to supported shared IRQ lines.\n"); + } + if (ret) + dev_printk(KERN_INFO, &p_dev->dev, "request_irq() failed\n"); + else + p_dev->_irq = 1; - ret = 0; -out: - mutex_unlock(&s->ops_mutex); return ret; -} /* pcmcia_request_irq */ -EXPORT_SYMBOL(pcmcia_request_irq); +} /* pcmcia_request_exclusive_irq */ +EXPORT_SYMBOL(pcmcia_request_exclusive_irq); #ifdef CONFIG_PCMCIA_PROBE @@ -779,7 +749,7 @@ static int pcmcia_setup_isa_irq(struct pcmcia_device *p_dev, int type) p_dev); if (!ret) { free_irq(irq, p_dev); - p_dev->irq_v = s->pcmcia_irq = irq; + p_dev->irq = s->pcmcia_irq = irq; pcmcia_used_irq[irq]++; break; } @@ -820,12 +790,12 @@ int pcmcia_setup_irq(struct pcmcia_device *p_dev) { struct pcmcia_socket *s = p_dev->socket; - if (p_dev->irq_v) + if (p_dev->irq) return 0; /* already assigned? */ if (s->pcmcia_irq) { - p_dev->irq_v = s->pcmcia_irq; + p_dev->irq = s->pcmcia_irq; return 0; } @@ -839,7 +809,7 @@ int pcmcia_setup_irq(struct pcmcia_device *p_dev) /* but use the PCI irq otherwise */ if (s->pci_irq) { - p_dev->irq_v = s->pcmcia_irq = s->pci_irq; + p_dev->irq = s->pcmcia_irq = s->pci_irq; return 0; } @@ -947,7 +917,8 @@ void pcmcia_disable_device(struct pcmcia_device *p_dev) { pcmcia_release_configuration(p_dev); pcmcia_release_io(p_dev, &p_dev->io); - pcmcia_release_irq(p_dev, &p_dev->irq); + if (p_dev->_irq) + free_irq(p_dev->irq, p_dev->priv); if (p_dev->win) pcmcia_release_window(p_dev, p_dev->win); } diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c index 528733b4a392..c1de4ba1f0a5 100644 --- a/drivers/scsi/pcmcia/aha152x_stub.c +++ b/drivers/scsi/pcmcia/aha152x_stub.c @@ -105,7 +105,6 @@ static int aha152x_probe(struct pcmcia_device *link) link->io.NumPorts1 = 0x20; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.IOAddrLines = 10; - link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.Present = PRESENT_OPTION; @@ -160,8 +159,7 @@ static int aha152x_config_cs(struct pcmcia_device *link) if (ret) goto failed; - ret = pcmcia_request_irq(link, &link->irq); - if (ret) + if (!link->irq) goto failed; ret = pcmcia_request_configuration(link, &link->conf); @@ -172,7 +170,7 @@ static int aha152x_config_cs(struct pcmcia_device *link) memset(&s, 0, sizeof(s)); s.conf = "PCMCIA setup"; s.io_port = link->io.BasePort1; - s.irq = link->irq.AssignedIRQ; + s.irq = link->irq; s.scsiid = host_id; s.reconnect = reconnect; s.parity = parity; diff --git a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c index 914040684079..8cb6d71f0204 100644 --- a/drivers/scsi/pcmcia/fdomain_stub.c +++ b/drivers/scsi/pcmcia/fdomain_stub.c @@ -88,7 +88,6 @@ static int fdomain_probe(struct pcmcia_device *link) link->io.NumPorts1 = 0x10; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.IOAddrLines = 10; - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.Present = PRESENT_OPTION; @@ -133,8 +132,7 @@ static int fdomain_config(struct pcmcia_device *link) if (ret) goto failed; - ret = pcmcia_request_irq(link, &link->irq); - if (ret) + if (!link->irq) goto failed; ret = pcmcia_request_configuration(link, &link->conf); if (ret) @@ -144,7 +142,7 @@ static int fdomain_config(struct pcmcia_device *link) release_region(link->io.BasePort1, link->io.NumPorts1); /* Set configuration options for the fdomain driver */ - sprintf(str, "%d,%d", link->io.BasePort1, link->irq.AssignedIRQ); + sprintf(str, "%d,%d", link->io.BasePort1, link->irq); fdomain_setup(str); host = __fdomain_16x0_detect(&fdomain_driver_template); diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c index 021246454872..24c78ed98f07 100644 --- a/drivers/scsi/pcmcia/nsp_cs.c +++ b/drivers/scsi/pcmcia/nsp_cs.c @@ -1563,13 +1563,6 @@ static int nsp_cs_probe(struct pcmcia_device *link) link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.IOAddrLines = 10; /* not used */ - /* Interrupt setup */ - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; - - /* Interrupt handler */ - link->irq.Handler = &nspintr; - link->irq.Attributes |= IRQF_SHARED; - /* General socket configuration */ link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -1646,8 +1639,7 @@ static int nsp_cs_config_check(struct pcmcia_device *p_dev, } /* Do we need to allocate an interrupt? */ - if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) - p_dev->conf.Attributes |= CONF_ENABLE_IRQ; + p_dev->conf.Attributes |= CONF_ENABLE_IRQ; /* IO window settings */ p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; @@ -1720,10 +1712,8 @@ static int nsp_cs_config(struct pcmcia_device *link) if (ret) goto cs_failed; - if (link->conf.Attributes & CONF_ENABLE_IRQ) { - if (pcmcia_request_irq(link, &link->irq)) - goto cs_failed; - } + if (pcmcia_request_irq(link, nspintr)) + goto cs_failed; ret = pcmcia_request_configuration(link, &link->conf); if (ret) @@ -1741,7 +1731,7 @@ static int nsp_cs_config(struct pcmcia_device *link) /* Set port and IRQ */ data->BaseAddress = link->io.BasePort1; data->NumAddress = link->io.NumPorts1; - data->IrqNumber = link->irq.AssignedIRQ; + data->IrqNumber = link->irq; nsp_dbg(NSP_DEBUG_INIT, "I/O[0x%x+0x%x] IRQ %d", data->BaseAddress, data->NumAddress, data->IrqNumber); @@ -1775,7 +1765,7 @@ static int nsp_cs_config(struct pcmcia_device *link) printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10); } if (link->conf.Attributes & CONF_ENABLE_IRQ) { - printk(", irq %d", link->irq.AssignedIRQ); + printk(", irq %d", link->irq); } if (link->io.NumPorts1) { printk(", io 0x%04x-0x%04x", link->io.BasePort1, diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c index f85f094870b4..c3a4428dbcff 100644 --- a/drivers/scsi/pcmcia/qlogic_stub.c +++ b/drivers/scsi/pcmcia/qlogic_stub.c @@ -161,7 +161,6 @@ static int qlogic_probe(struct pcmcia_device *link) link->io.NumPorts1 = 16; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.IOAddrLines = 10; - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.Present = PRESENT_OPTION; @@ -209,8 +208,7 @@ static int qlogic_config(struct pcmcia_device * link) if (ret) goto failed; - ret = pcmcia_request_irq(link, &link->irq); - if (ret) + if (!link->irq) goto failed; ret = pcmcia_request_configuration(link, &link->conf); @@ -227,10 +225,10 @@ static int qlogic_config(struct pcmcia_device * link) /* The KXL-810AN has a bigger IO port window */ if (link->io.NumPorts1 == 32) host = qlogic_detect(&qlogicfas_driver_template, link, - link->io.BasePort1 + 16, link->irq.AssignedIRQ); + link->io.BasePort1 + 16, link->irq); else host = qlogic_detect(&qlogicfas_driver_template, link, - link->io.BasePort1, link->irq.AssignedIRQ); + link->io.BasePort1, link->irq); if (!host) { printk(KERN_INFO "%s: no SCSI devices found\n", qlogic_name); @@ -258,7 +256,7 @@ static void qlogic_release(struct pcmcia_device *link) scsi_remove_host(info->host); - free_irq(link->irq.AssignedIRQ, info->host); + free_irq(link->irq, info->host); pcmcia_disable_device(link); scsi_host_put(info->host); diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c index e7564d8f0cbf..6eacf4ca200f 100644 --- a/drivers/scsi/pcmcia/sym53c500_cs.c +++ b/drivers/scsi/pcmcia/sym53c500_cs.c @@ -719,8 +719,7 @@ SYM53C500_config(struct pcmcia_device *link) if (ret) goto failed; - ret = pcmcia_request_irq(link, &link->irq); - if (ret) + if (!link->irq) goto failed; ret = pcmcia_request_configuration(link, &link->conf); @@ -752,7 +751,7 @@ SYM53C500_config(struct pcmcia_device *link) * 0x320, 0x330, 0x340, 0x350 */ port_base = link->io.BasePort1; - irq_level = link->irq.AssignedIRQ; + irq_level = link->irq; DEB(printk("SYM53C500: port_base=0x%x, irq=%d, fast_pio=%d\n", port_base, irq_level, USE_FAST_PIO);) @@ -866,7 +865,6 @@ SYM53C500_probe(struct pcmcia_device *link) link->io.NumPorts1 = 16; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.IOAddrLines = 10; - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index 8cfa5b12ea7a..6459252ed371 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c @@ -343,7 +343,6 @@ static int serial_probe(struct pcmcia_device *link) link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.NumPorts1 = 8; - link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; link->conf.Attributes = CONF_ENABLE_IRQ; if (do_sound) { link->conf.Attributes |= CONF_ENABLE_SPKR; @@ -486,7 +485,7 @@ static int simple_config(struct pcmcia_device *link) } if (info->slave) { return setup_serial(link, info, port, - link->irq.AssignedIRQ); + link->irq); } } @@ -507,10 +506,6 @@ static int simple_config(struct pcmcia_device *link) return -1; found_port: - i = pcmcia_request_irq(link, &link->irq); - if (i != 0) - link->irq.AssignedIRQ = 0; - if (info->multi && (info->manfid == MANFID_3COM)) link->conf.ConfigIndex &= ~(0x08); @@ -523,7 +518,7 @@ found_port: i = pcmcia_request_configuration(link, &link->conf); if (i != 0) return -1; - return setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ); + return setup_serial(link, info, link->io.BasePort1, link->irq); } static int multi_config_check(struct pcmcia_device *p_dev, @@ -586,13 +581,9 @@ static int multi_config(struct pcmcia_device *link) } } - i = pcmcia_request_irq(link, &link->irq); - if (i != 0) { - /* FIXME: comment does not fit, error handling does not fit */ - printk(KERN_NOTICE - "serial_cs: no usable port range found, giving up\n"); - link->irq.AssignedIRQ = 0; - } + if (!link->irq) + dev_warn(&link->dev, + "serial_cs: no usable IRQ found, continuing...\n"); /* * Apply any configuration quirks. @@ -615,11 +606,11 @@ static int multi_config(struct pcmcia_device *link) if (link->conf.ConfigIndex == 1 || link->conf.ConfigIndex == 3) { err = setup_serial(link, info, base2, - link->irq.AssignedIRQ); + link->irq); base2 = link->io.BasePort1; } else { err = setup_serial(link, info, link->io.BasePort1, - link->irq.AssignedIRQ); + link->irq); } info->c950ctrl = base2; @@ -633,10 +624,10 @@ static int multi_config(struct pcmcia_device *link) return 0; } - setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ); + setup_serial(link, info, link->io.BasePort1, link->irq); for (i = 0; i < info->multi - 1; i++) setup_serial(link, info, base2 + (8 * i), - link->irq.AssignedIRQ); + link->irq); return 0; } diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index 80ff7d9e60de..bc9bdb277bec 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c @@ -490,7 +490,7 @@ static int ssb_devices_register(struct ssb_bus *bus) break; case SSB_BUSTYPE_PCMCIA: #ifdef CONFIG_SSB_PCMCIAHOST - sdev->irq = bus->host_pcmcia->irq.AssignedIRQ; + sdev->irq = bus->host_pcmcia->irq; dev->parent = &bus->host_pcmcia->dev; #endif break; diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 5632991760af..e0352c6cf82d 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -180,12 +180,12 @@ static int das16cs_attach(struct comedi_device *dev, } printk("\n"); - ret = request_irq(link->irq.AssignedIRQ, das16cs_interrupt, + ret = request_irq(link->irq, das16cs_interrupt, IRQF_SHARED, "cb_das16_cs", dev); if (ret < 0) { return ret; } - dev->irq = link->irq.AssignedIRQ; + dev->irq = link->irq; printk("irq=%u ", dev->irq); dev->board_ptr = das16cs_probe(dev, link); @@ -702,10 +702,6 @@ static int das16cs_pcmcia_attach(struct pcmcia_device *link) link->priv = local; /* Initialize the pcmcia_device structure */ - /* Interrupt setup */ - link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; - link->irq.Handler = NULL; - link->conf.Attributes = 0; link->conf.IntType = INT_MEMORY_AND_IO; @@ -740,8 +736,7 @@ static int das16cs_pcmcia_config_loop(struct pcmcia_device *p_dev, return -EINVAL; /* Do we need to allocate an interrupt? */ - if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) - p_dev->conf.Attributes |= CONF_ENABLE_IRQ; + p_dev->conf.Attributes |= CONF_ENABLE_IRQ; /* IO window settings */ p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; @@ -780,16 +775,9 @@ static void das16cs_pcmcia_config(struct pcmcia_device *link) goto failed; } - /* - Allocate an interrupt line. Note that this does not assign a - handler to the interrupt, unless the 'Handler' member of the - irq structure is initialized. - */ - if (link->conf.Attributes & CONF_ENABLE_IRQ) { - ret = pcmcia_request_irq(link, &link->irq); - if (ret) - goto failed; - } + if (!link->irq) + goto failed; + /* This actually configures the PCMCIA socket -- setting up the I/O windows and the interrupt mapping, and putting the @@ -811,7 +799,7 @@ static void das16cs_pcmcia_config(struct pcmcia_device *link) printk(KERN_INFO "%s: index 0x%02x", dev->node.dev_name, link->conf.ConfigIndex); if (link->conf.Attributes & CONF_ENABLE_IRQ) - printk(", irq %u", link->irq.AssignedIRQ); + printk(", irq %u", link->irq); if (link->io.NumPorts1) printk(", io 0x%04x-0x%04x", link->io.BasePort1, link->io.BasePort1 + link->io.NumPorts1 - 1); diff --git a/drivers/staging/comedi/drivers/das08_cs.c b/drivers/staging/comedi/drivers/das08_cs.c index 9164ce158dcd..bd69c4fdcbf5 100644 --- a/drivers/staging/comedi/drivers/das08_cs.c +++ b/drivers/staging/comedi/drivers/das08_cs.c @@ -172,10 +172,6 @@ static int das08_pcmcia_attach(struct pcmcia_device *link) local->link = link; link->priv = local; - /* Interrupt setup */ - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; - link->irq.Handler = NULL; - /* General socket configuration defaults can go here. In this client, we assume very little, and rely on the CIS for almost @@ -229,8 +225,7 @@ static int das08_pcmcia_config_loop(struct pcmcia_device *p_dev, return -ENODEV; /* Do we need to allocate an interrupt? */ - if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) - p_dev->conf.Attributes |= CONF_ENABLE_IRQ; + p_dev->conf.Attributes |= CONF_ENABLE_IRQ; /* IO window settings */ p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; @@ -277,11 +272,8 @@ static void das08_pcmcia_config(struct pcmcia_device *link) goto failed; } - if (link->conf.Attributes & CONF_ENABLE_IRQ) { - ret = pcmcia_request_irq(link, &link->irq); - if (ret) - goto failed; - } + if (!link->irq) + goto failed; /* This actually configures the PCMCIA socket -- setting up @@ -304,7 +296,7 @@ static void das08_pcmcia_config(struct pcmcia_device *link) printk(KERN_INFO "%s: index 0x%02x", dev->node.dev_name, link->conf.ConfigIndex); if (link->conf.Attributes & CONF_ENABLE_IRQ) - printk(", irq %u", link->irq.AssignedIRQ); + printk(", irq %u", link->irq); if (link->io.NumPorts1) printk(", io 0x%04x-0x%04x", link->io.BasePort1, link->io.BasePort1 + link->io.NumPorts1 - 1); diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 7ea64538e055..072bc4b62011 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -380,7 +380,7 @@ static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it) return -EIO; iobase = link->io.BasePort1; #ifdef incomplete - irq = link->irq.AssignedIRQ; + irq = link->irq; #endif break; default: @@ -502,10 +502,6 @@ static int dio700_cs_attach(struct pcmcia_device *link) local->link = link; link->priv = local; - /* Interrupt setup */ - link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; - link->irq.Handler = NULL; - /* General socket configuration defaults can go here. In this client, we assume very little, and rely on the CIS for almost @@ -577,8 +573,7 @@ static int dio700_pcmcia_config_loop(struct pcmcia_device *p_dev, } /* Do we need to allocate an interrupt? */ - if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) - p_dev->conf.Attributes |= CONF_ENABLE_IRQ; + p_dev->conf.Attributes |= CONF_ENABLE_IRQ; /* IO window settings */ p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; @@ -639,16 +634,8 @@ static void dio700_config(struct pcmcia_device *link) goto failed; } - /* - Allocate an interrupt line. Note that this does not assign a - handler to the interrupt, unless the 'Handler' member of the - irq structure is initialized. - */ - if (link->conf.Attributes & CONF_ENABLE_IRQ) { - ret = pcmcia_request_irq(link, &link->irq); - if (ret) - goto failed; - } + if (!link->irq) + goto failed; /* This actually configures the PCMCIA socket -- setting up @@ -671,7 +658,7 @@ static void dio700_config(struct pcmcia_device *link) printk(KERN_INFO "%s: index 0x%02x", dev->node.dev_name, link->conf.ConfigIndex); if (link->conf.Attributes & CONF_ENABLE_IRQ) - printk(", irq %d", link->irq.AssignedIRQ); + printk(", irq %d", link->irq); if (link->io.NumPorts1) printk(", io 0x%04x-0x%04x", link->io.BasePort1, link->io.BasePort1 + link->io.NumPorts1 - 1); diff --git a/drivers/staging/comedi/drivers/ni_daq_dio24.c b/drivers/staging/comedi/drivers/ni_daq_dio24.c index ddc312b5d20d..2259fb40608b 100644 --- a/drivers/staging/comedi/drivers/ni_daq_dio24.c +++ b/drivers/staging/comedi/drivers/ni_daq_dio24.c @@ -131,7 +131,7 @@ static int dio24_attach(struct comedi_device *dev, struct comedi_devconfig *it) return -EIO; iobase = link->io.BasePort1; #ifdef incomplete - irq = link->irq.AssignedIRQ; + irq = link->irq; #endif break; default: @@ -253,10 +253,6 @@ static int dio24_cs_attach(struct pcmcia_device *link) local->link = link; link->priv = local; - /* Interrupt setup */ - link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; - link->irq.Handler = NULL; - /* General socket configuration defaults can go here. In this client, we assume very little, and rely on the CIS for almost @@ -328,8 +324,7 @@ static int dio24_pcmcia_config_loop(struct pcmcia_device *p_dev, } /* Do we need to allocate an interrupt? */ - if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) - p_dev->conf.Attributes |= CONF_ENABLE_IRQ; + p_dev->conf.Attributes |= CONF_ENABLE_IRQ; /* IO window settings */ p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; @@ -390,16 +385,8 @@ static void dio24_config(struct pcmcia_device *link) goto failed; } - /* - Allocate an interrupt line. Note that this does not assign a - handler to the interrupt, unless the 'Handler' member of the - irq structure is initialized. - */ - if (link->conf.Attributes & CONF_ENABLE_IRQ) { - ret = pcmcia_request_irq(link, &link->irq); - if (ret) - goto failed; - } + if (!link->irq) + goto failed; /* This actually configures the PCMCIA socket -- setting up @@ -422,7 +409,7 @@ static void dio24_config(struct pcmcia_device *link) printk(KERN_INFO "%s: index 0x%02x", dev->node.dev_name, link->conf.ConfigIndex); if (link->conf.Attributes & CONF_ENABLE_IRQ) - printk(", irq %d", link->irq.AssignedIRQ); + printk(", irq %d", link->irq); if (link->io.NumPorts1) printk(", io 0x%04x-0x%04x", link->io.BasePort1, link->io.BasePort1 + link->io.NumPorts1 - 1); diff --git a/drivers/staging/comedi/drivers/ni_labpc_cs.c b/drivers/staging/comedi/drivers/ni_labpc_cs.c index 6e4ed0d9105a..907b2ae467b2 100644 --- a/drivers/staging/comedi/drivers/ni_labpc_cs.c +++ b/drivers/staging/comedi/drivers/ni_labpc_cs.c @@ -144,7 +144,7 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (!link) return -EIO; iobase = link->io.BasePort1; - irq = link->irq.AssignedIRQ; + irq = link->irq; break; default: printk("bug! couldn't determine board type\n"); @@ -229,10 +229,6 @@ static int labpc_cs_attach(struct pcmcia_device *link) local->link = link; link->priv = local; - /* Interrupt setup */ - link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; - link->irq.Handler = NULL; - /* General socket configuration defaults can go here. In this client, we assume very little, and rely on the CIS for almost @@ -306,9 +302,7 @@ static int labpc_pcmcia_config_loop(struct pcmcia_device *p_dev, } /* Do we need to allocate an interrupt? */ - if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) - p_dev->conf.Attributes |= - (CONF_ENABLE_IRQ | CONF_ENABLE_PULSE_IRQ); + p_dev->conf.Attributes |= CONF_ENABLE_IRQ | CONF_ENABLE_PULSE_IRQ; /* IO window settings */ p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; @@ -368,16 +362,8 @@ static void labpc_config(struct pcmcia_device *link) goto failed; } - /* - Allocate an interrupt line. Note that this does not assign a - handler to the interrupt, unless the 'Handler' member of the - irq structure is initialized. - */ - if (link->conf.Attributes & CONF_ENABLE_IRQ) { - ret = pcmcia_request_irq(link, &link->irq); - if (ret) - goto failed; - } + if (!link->irq) + goto failed; /* This actually configures the PCMCIA socket -- setting up @@ -400,7 +386,7 @@ static void labpc_config(struct pcmcia_device *link) printk(KERN_INFO "%s: index 0x%02x", dev->node.dev_name, link->conf.ConfigIndex); if (link->conf.Attributes & CONF_ENABLE_IRQ) - printk(", irq %d", link->irq.AssignedIRQ); + printk(", irq %d", link->irq); if (link->io.NumPorts1) printk(", io 0x%04x-0x%04x", link->io.BasePort1, link->io.BasePort1 + link->io.NumPorts1 - 1); diff --git a/drivers/staging/comedi/drivers/ni_mio_cs.c b/drivers/staging/comedi/drivers/ni_mio_cs.c index dc4849a40c97..a6007abce34a 100644 --- a/drivers/staging/comedi/drivers/ni_mio_cs.c +++ b/drivers/staging/comedi/drivers/ni_mio_cs.c @@ -272,7 +272,6 @@ static int cs_attach(struct pcmcia_device *link) { link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; link->io.NumPorts1 = 16; - link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -344,10 +343,8 @@ static void mio_cs_config(struct pcmcia_device *link) return; } - ret = pcmcia_request_irq(link, &link->irq); - if (ret) { - printk("pcmcia_request_irq() returned error: %i\n", ret); - } + if (!link->irq) + dev_info(&link->dev, "no IRQ available\n"); ret = pcmcia_request_configuration(link, &link->conf); @@ -369,7 +366,7 @@ static int mio_cs_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->driver = &driver_ni_mio_cs; dev->iobase = link->io.BasePort1; - irq = link->irq.AssignedIRQ; + irq = link->irq; printk("comedi%d: %s: DAQCard: io 0x%04lx, irq %u, ", dev->minor, dev->driver->driver_name, dev->iobase, irq); diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c index 3325f24448b5..7aa17f92968c 100644 --- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c +++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c @@ -1040,10 +1040,6 @@ static int daqp_cs_attach(struct pcmcia_device *link) local->link = link; link->priv = local; - /* Interrupt setup */ - link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; - link->irq.Handler = daqp_interrupt; - /* General socket configuration defaults can go here. In this client, we assume very little, and rely on the CIS for almost @@ -1105,8 +1101,7 @@ static int daqp_pcmcia_config_loop(struct pcmcia_device *p_dev, return -ENODEV; /* Do we need to allocate an interrupt? */ - if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) - p_dev->conf.Attributes |= CONF_ENABLE_IRQ; + p_dev->conf.Attributes |= CONF_ENABLE_IRQ; /* IO window settings */ p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; @@ -1144,16 +1139,9 @@ static void daqp_cs_config(struct pcmcia_device *link) goto failed; } - /* - Allocate an interrupt line. Note that this does not assign a - handler to the interrupt, unless the 'Handler' member of the - irq structure is initialized. - */ - if (link->conf.Attributes & CONF_ENABLE_IRQ) { - ret = pcmcia_request_irq(link, &link->irq); - if (ret) - goto failed; - } + ret = pcmcia_request_irq(link, daqp_interrupt); + if (ret) + goto failed; /* This actually configures the PCMCIA socket -- setting up @@ -1180,7 +1168,7 @@ static void daqp_cs_config(struct pcmcia_device *link) printk(KERN_INFO "%s: index 0x%02x", dev->node.dev_name, link->conf.ConfigIndex); if (link->conf.Attributes & CONF_ENABLE_IRQ) - printk(", irq %u", link->irq.AssignedIRQ); + printk(", irq %u", link->irq); if (link->io.NumPorts1) printk(", io 0x%04x-0x%04x", link->io.BasePort1, link->io.BasePort1 + link->io.NumPorts1 - 1); diff --git a/drivers/staging/netwave/netwave_cs.c b/drivers/staging/netwave/netwave_cs.c index 3875a722d12b..449e6a5c19e1 100644 --- a/drivers/staging/netwave/netwave_cs.c +++ b/drivers/staging/netwave/netwave_cs.c @@ -382,10 +382,6 @@ static int netwave_probe(struct pcmcia_device *link) link->io.Attributes2 = IO_DATA_PATH_WIDTH_16; */ link->io.IOAddrLines = 5; - /* Interrupt setup */ - link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; - link->irq.Handler = &netwave_interrupt; - /* General socket configuration */ link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -732,7 +728,7 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) { * Now allocate an interrupt line. Note that this does not * actually assign a handler to the interrupt. */ - ret = pcmcia_request_irq(link, &link->irq); + ret = pcmcia_request_irq(link, netwave_interrupt); if (ret) goto failed; @@ -767,7 +763,7 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) { ramBase = ioremap(req.Base, 0x8000); priv->ramBase = ramBase; - dev->irq = link->irq.AssignedIRQ; + dev->irq = link->irq; dev->base_addr = link->io.BasePort1; SET_NETDEV_DEV(dev, &link->dev); diff --git a/drivers/staging/wavelan/wavelan_cs.c b/drivers/staging/wavelan/wavelan_cs.c index 04f691d127b4..37fa85517a58 100644 --- a/drivers/staging/wavelan/wavelan_cs.c +++ b/drivers/staging/wavelan/wavelan_cs.c @@ -3850,12 +3850,8 @@ wv_pcmcia_config(struct pcmcia_device * link) if (i != 0) break; - /* - * Now allocate an interrupt line. Note that this does not - * actually assign a handler to the interrupt. - */ - i = pcmcia_request_irq(link, &link->irq); - if (i != 0) + i = pcmcia_request_interrupt(link, wavelan_interrupt); + if (!i) break; /* @@ -3890,7 +3886,7 @@ wv_pcmcia_config(struct pcmcia_device * link) break; /* Feed device with this info... */ - dev->irq = link->irq.AssignedIRQ; + dev->irq = link->irq; dev->base_addr = link->io.BasePort1; netif_start_queue(dev); @@ -4437,10 +4433,6 @@ wavelan_probe(struct pcmcia_device *p_dev) p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; p_dev->io.IOAddrLines = 3; - /* Interrupt setup */ - p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; - p_dev->irq.Handler = wavelan_interrupt; - /* General socket configuration */ p_dev->conf.Attributes = CONF_ENABLE_IRQ; p_dev->conf.IntType = INT_MEMORY_AND_IO; @@ -4487,7 +4479,6 @@ wavelan_probe(struct pcmcia_device *p_dev) ret = wv_hw_config(dev); if (ret) { - dev->irq = 0; pcmcia_disable_device(p_dev); return ret; } diff --git a/drivers/staging/wlags49_h2/wl_cs.c b/drivers/staging/wlags49_h2/wl_cs.c index 9da42e66085e..c9d99d88b786 100644 --- a/drivers/staging/wlags49_h2/wl_cs.c +++ b/drivers/staging/wlags49_h2/wl_cs.c @@ -156,15 +156,12 @@ static int wl_adapter_attach(struct pcmcia_device *link) link->io.NumPorts1 = HCF_NUM_IO_PORTS; link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; link->io.IOAddrLines = 6; - link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT; - link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID; - link->irq.Handler = &wl_isr; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.ConfigIndex = 5; link->conf.Present = PRESENT_OPTION; - link->priv = link->irq.Instance = dev; + link->priv = dev; lp = wl_priv(dev); lp->link = link; @@ -318,11 +315,11 @@ void wl_adapter_insert( struct pcmcia_device *link ) link->conf.Attributes |= CONF_ENABLE_IRQ; CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io)); - CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, wl_isr)); CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); - dev->irq = link->irq.AssignedIRQ; + dev->irq = link->irq; dev->base_addr = link->io.BasePort1; SET_NETDEV_DEV(dev, &handle_to_dev(link)); diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c index 39d253e841f6..a712788f9b10 100644 --- a/drivers/usb/host/sl811_cs.c +++ b/drivers/usb/host/sl811_cs.c @@ -163,8 +163,7 @@ static int sl811_cs_config_check(struct pcmcia_device *p_dev, dflt->vpp1.param[CISTPL_POWER_VNOM]/10000; /* we need an interrupt */ - if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) - p_dev->conf.Attributes |= CONF_ENABLE_IRQ; + p_dev->conf.Attributes |= CONF_ENABLE_IRQ; /* IO window settings */ p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; @@ -197,11 +196,8 @@ static int sl811_cs_config(struct pcmcia_device *link) /* require an IRQ and two registers */ if (!link->io.NumPorts1 || link->io.NumPorts1 < 2) goto failed; - if (link->conf.Attributes & CONF_ENABLE_IRQ) { - ret = pcmcia_request_irq(link, &link->irq); - if (ret) - goto failed; - } else + + if (!link->irq) goto failed; ret = pcmcia_request_configuration(link, &link->conf); @@ -216,12 +212,12 @@ static int sl811_cs_config(struct pcmcia_device *link) dev->node.dev_name, link->conf.ConfigIndex); if (link->conf.Vpp) printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10); - printk(", irq %d", link->irq.AssignedIRQ); + printk(", irq %d", link->irq); printk(", io 0x%04x-0x%04x", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1-1); printk("\n"); - if (sl811_hc_init(parent, link->io.BasePort1, link->irq.AssignedIRQ) + if (sl811_hc_init(parent, link->io.BasePort1, link->irq) < 0) { failed: printk(KERN_WARNING "sl811_cs_config failed\n"); @@ -241,10 +237,6 @@ static int sl811_cs_probe(struct pcmcia_device *link) local->p_dev = link; link->priv = local; - /* Initialize */ - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; - link->irq.Handler = NULL; - link->conf.Attributes = 0; link->conf.IntType = INT_MEMORY_AND_IO; diff --git a/include/pcmcia/cs.h b/include/pcmcia/cs.h index af615716dc23..a04e6caa585a 100644 --- a/include/pcmcia/cs.h +++ b/include/pcmcia/cs.h @@ -114,13 +114,6 @@ typedef struct io_req_t { #define IO_DATA_PATH_WIDTH_16 0x08 #define IO_DATA_PATH_WIDTH_AUTO 0x10 -/* For RequestIRQ and ReleaseIRQ */ -typedef struct irq_req_t { - u_int Attributes; - u_int AssignedIRQ; - irq_handler_t Handler; -} irq_req_t; - /* Attributes for RequestIRQ and ReleaseIRQ */ #define IRQ_TYPE 0x03 #define IRQ_TYPE_EXCLUSIVE 0x00 diff --git a/include/pcmcia/ds.h b/include/pcmcia/ds.h index 52ebe75664e8..d18330b401b1 100644 --- a/include/pcmcia/ds.h +++ b/include/pcmcia/ds.h @@ -91,12 +91,11 @@ struct pcmcia_device { dev_node_t *dev_node; u_int open; io_req_t io; - irq_req_t irq; config_req_t conf; window_handle_t win; /* device setup */ - unsigned int irq_v; /* do not use directly yet */ + unsigned int irq; /* Is the device suspended? */ u16 suspended:1; @@ -194,7 +193,13 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, /* device configuration */ int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req); -int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req); + +int __must_check __deprecated +pcmcia_request_exclusive_irq(struct pcmcia_device *p_dev, + irq_handler_t handler); +int __must_check pcmcia_request_irq(struct pcmcia_device *p_dev, + irq_handler_t handler); + int pcmcia_request_configuration(struct pcmcia_device *p_dev, config_req_t *req); diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c index dcf85390c5f9..60fddf363d54 100644 --- a/sound/pcmcia/pdaudiocf/pdaudiocf.c +++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c @@ -142,11 +142,6 @@ static int snd_pdacf_probe(struct pcmcia_device *link) link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.NumPorts1 = 16; - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; - /* FIXME: This driver should be updated to allow for dynamic IRQ sharing */ - /* link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; */ - - link->irq.Handler = pdacf_interrupt; link->conf.Attributes = CONF_ENABLE_IRQ | CONF_ENABLE_PULSE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.ConfigIndex = 1; @@ -228,7 +223,7 @@ static int pdacf_config(struct pcmcia_device *link) if (ret) goto failed; - ret = pcmcia_request_irq(link, &link->irq); + ret = pcmcia_request_exclusive_irq(link, pdacf_interrupt); if (ret) goto failed; @@ -236,7 +231,7 @@ static int pdacf_config(struct pcmcia_device *link) if (ret) goto failed; - if (snd_pdacf_assign_resources(pdacf, link->io.BasePort1, link->irq.AssignedIRQ) < 0) + if (snd_pdacf_assign_resources(pdacf, link->io.BasePort1, link->irq) < 0) goto failed; link->dev_node = &pdacf->node; diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c index cfd1438bcc64..5eced7a7c987 100644 --- a/sound/pcmcia/vx/vxpocket.c +++ b/sound/pcmcia/vx/vxpocket.c @@ -162,10 +162,6 @@ static int snd_vxpocket_new(struct snd_card *card, int ibl, link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.NumPorts1 = 16; - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; - - link->irq.Handler = &snd_vx_irq_handler; - link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.ConfigIndex = 1; @@ -235,7 +231,7 @@ static int vxpocket_config(struct pcmcia_device *link) if (ret) goto failed; - ret = pcmcia_request_irq(link, &link->irq); + ret = pcmcia_request_exclusive_irq(link, snd_vx_irq_handler); if (ret) goto failed; @@ -246,7 +242,7 @@ static int vxpocket_config(struct pcmcia_device *link) chip->dev = &link->dev; snd_card_set_dev(chip->card, chip->dev); - if (snd_vxpocket_assign_resources(chip, link->io.BasePort1, link->irq.AssignedIRQ) < 0) + if (snd_vxpocket_assign_resources(chip, link->io.BasePort1, link->irq) < 0) goto failed; link->dev_node = &vxp->node; -- cgit v1.2.3 From b9300aa7449f6636b188743d09199dcf27b1a4b4 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sat, 20 Mar 2010 19:43:40 +0100 Subject: pcmcia: dev_node removal (core) Remove the dev_node declaration. We now only pass the device name to the deprecated userspace tools. Signed-off-by: Dominik Brodowski --- Documentation/pcmcia/driver-changes.txt | 3 +++ drivers/pcmcia/ds.c | 2 -- drivers/pcmcia/pcmcia_ioctl.c | 15 +++------------ include/pcmcia/ds.h | 10 ---------- 4 files changed, 6 insertions(+), 24 deletions(-) (limited to 'drivers/pcmcia') diff --git a/Documentation/pcmcia/driver-changes.txt b/Documentation/pcmcia/driver-changes.txt index 3268a9ae7271..61bc4e943116 100644 --- a/Documentation/pcmcia/driver-changes.txt +++ b/Documentation/pcmcia/driver-changes.txt @@ -1,4 +1,7 @@ This file details changes in 2.6 which affect PCMCIA card driver authors: +* No dev_node_t (as of 2.6.35) + There is no more need to fill out a "dev_node_t" structure. + * New IRQ request rules (as of 2.6.35) Instead of the old pcmcia_request_irq() interface, drivers may now choose between: diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index a2649c7b05bd..0e12d85dd723 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -371,8 +371,6 @@ static int pcmcia_device_remove(struct device *dev) if (p_drv->remove) p_drv->remove(p_dev); - p_dev->dev_node = NULL; - /* check for proper unloading */ if (p_dev->_irq || p_dev->_io || p_dev->_locked) dev_printk(KERN_INFO, dev, diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c index fe98aa9b1aef..a42a6c7be10a 100644 --- a/drivers/pcmcia/pcmcia_ioctl.c +++ b/drivers/pcmcia/pcmcia_ioctl.c @@ -571,7 +571,6 @@ static struct pci_bus *pcmcia_lookup_bus(struct pcmcia_socket *s) static int get_device_info(struct pcmcia_socket *s, bind_info_t *bind_info, int first) { - dev_node_t *node; struct pcmcia_device *p_dev; struct pcmcia_driver *p_drv; int ret = 0; @@ -633,21 +632,13 @@ static int get_device_info(struct pcmcia_socket *s, bind_info_t *bind_info, int goto err_put; } - if (first) - node = p_dev->dev_node; - else - for (node = p_dev->dev_node; node; node = node->next) - if (node == bind_info->next) - break; - if (!node) { + if (!first) { ret = -ENODEV; goto err_put; } - strlcpy(bind_info->name, node->dev_name, DEV_NAME_LEN); - bind_info->major = node->major; - bind_info->minor = node->minor; - bind_info->next = node->next; + strlcpy(bind_info->name, dev_name(&p_dev->dev), DEV_NAME_LEN); + bind_info->next = NULL; err_put: pcmcia_put_dev(p_dev); diff --git a/include/pcmcia/ds.h b/include/pcmcia/ds.h index d18330b401b1..b4429f78b9c3 100644 --- a/include/pcmcia/ds.h +++ b/include/pcmcia/ds.h @@ -62,15 +62,6 @@ struct pcmcia_driver { int pcmcia_register_driver(struct pcmcia_driver *driver); void pcmcia_unregister_driver(struct pcmcia_driver *driver); -/* Some drivers use dev_node_t to store char or block device information. - * Don't use this in new drivers, though. - */ -typedef struct dev_node_t { - char dev_name[DEV_NAME_LEN]; - u_short major, minor; - struct dev_node_t *next; -} dev_node_t; - struct pcmcia_device { /* the socket and the device_no [for multifunction devices] uniquely define a pcmcia_device */ @@ -88,7 +79,6 @@ struct pcmcia_device { struct list_head socket_device_list; /* deprecated, will be cleaned up soon */ - dev_node_t *dev_node; u_int open; io_req_t io; config_req_t conf; -- cgit v1.2.3 From 5c128e84324ca9389bc5f7d39f6b18f6de4a58ec Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sat, 20 Mar 2010 20:03:57 +0100 Subject: pcmcia: move high level CIS access code to separate file No code changes. Signed-off-by: Dominik Brodowski --- drivers/pcmcia/Makefile | 2 +- drivers/pcmcia/cistpl.c | 100 ----------- drivers/pcmcia/pcmcia_cis.c | 355 +++++++++++++++++++++++++++++++++++++++ drivers/pcmcia/pcmcia_resource.c | 229 ------------------------- 4 files changed, 356 insertions(+), 330 deletions(-) create mode 100644 drivers/pcmcia/pcmcia_cis.c (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile index 381b031d9d75..8122b03e2ae5 100644 --- a/drivers/pcmcia/Makefile +++ b/drivers/pcmcia/Makefile @@ -6,7 +6,7 @@ pcmcia_core-y += cs.o rsrc_mgr.o socket_sysfs.o pcmcia_core-$(CONFIG_CARDBUS) += cardbus.o obj-$(CONFIG_PCCARD) += pcmcia_core.o -pcmcia-y += ds.o pcmcia_resource.o cistpl.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 diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c index 854959cada3a..e0b09e71d5c0 100644 --- a/drivers/pcmcia/cistpl.c +++ b/drivers/pcmcia/cistpl.c @@ -1361,106 +1361,6 @@ int pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse) EXPORT_SYMBOL(pcmcia_parse_tuple); -/** - * pccard_read_tuple() - internal CIS tuple access - * @s: the struct pcmcia_socket where the card is inserted - * @function: the device function we loop for - * @code: which CIS code shall we look for? - * @parse: buffer where the tuple shall be parsed (or NULL, if no parse) - * - * pccard_read_tuple() reads out one tuple and attempts to parse it - */ -int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, - cisdata_t code, void *parse) -{ - tuple_t tuple; - cisdata_t *buf; - int ret; - - buf = kmalloc(256, GFP_KERNEL); - if (buf == NULL) { - dev_printk(KERN_WARNING, &s->dev, "no memory to read tuple\n"); - return -ENOMEM; - } - tuple.DesiredTuple = code; - tuple.Attributes = 0; - if (function == BIND_FN_ALL) - tuple.Attributes = TUPLE_RETURN_COMMON; - ret = pccard_get_first_tuple(s, function, &tuple); - if (ret != 0) - goto done; - tuple.TupleData = buf; - tuple.TupleOffset = 0; - tuple.TupleDataMax = 255; - ret = pccard_get_tuple_data(s, &tuple); - if (ret != 0) - goto done; - ret = pcmcia_parse_tuple(&tuple, parse); -done: - kfree(buf); - return ret; -} - - -/** - * pccard_loop_tuple() - loop over tuples in the CIS - * @s: the struct pcmcia_socket where the card is inserted - * @function: the device function we loop for - * @code: which CIS code shall we look for? - * @parse: buffer where the tuple shall be parsed (or NULL, if no parse) - * @priv_data: private data to be passed to the loop_tuple function. - * @loop_tuple: function to call for each CIS entry of type @function. IT - * gets passed the raw tuple, the paresed tuple (if @parse is - * set) and @priv_data. - * - * pccard_loop_tuple() loops over all CIS entries of type @function, and - * calls the @loop_tuple function for each entry. If the call to @loop_tuple - * returns 0, the loop exits. Returns 0 on success or errorcode otherwise. - */ -int pccard_loop_tuple(struct pcmcia_socket *s, unsigned int function, - cisdata_t code, cisparse_t *parse, void *priv_data, - int (*loop_tuple) (tuple_t *tuple, - cisparse_t *parse, - void *priv_data)) -{ - tuple_t tuple; - cisdata_t *buf; - int ret; - - buf = kzalloc(256, GFP_KERNEL); - if (buf == NULL) { - dev_printk(KERN_WARNING, &s->dev, "no memory to read tuple\n"); - return -ENOMEM; - } - - tuple.TupleData = buf; - tuple.TupleDataMax = 255; - tuple.TupleOffset = 0; - tuple.DesiredTuple = code; - tuple.Attributes = 0; - - ret = pccard_get_first_tuple(s, function, &tuple); - while (!ret) { - if (pccard_get_tuple_data(s, &tuple)) - goto next_entry; - - if (parse) - if (pcmcia_parse_tuple(&tuple, parse)) - goto next_entry; - - ret = loop_tuple(&tuple, parse, priv_data); - if (!ret) - break; - -next_entry: - ret = pccard_get_next_tuple(s, function, &tuple); - } - - kfree(buf); - return ret; -} - - /** * pccard_validate_cis() - check whether card has a sensible CIS * @s: the struct pcmcia_socket we are to check diff --git a/drivers/pcmcia/pcmcia_cis.c b/drivers/pcmcia/pcmcia_cis.c new file mode 100644 index 000000000000..7406387f1f5e --- /dev/null +++ b/drivers/pcmcia/pcmcia_cis.c @@ -0,0 +1,355 @@ +/* + * PCMCIA high-level CIS access functions + * + * The initial developer of the original code is David A. Hinds + * . Portions created by David A. Hinds + * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. + * + * Copyright (C) 1999 David A. Hinds + * Copyright (C) 2004-2009 Dominik Brodowski + * + * 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. + * + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include "cs_internal.h" + + +/** + * pccard_read_tuple() - internal CIS tuple access + * @s: the struct pcmcia_socket where the card is inserted + * @function: the device function we loop for + * @code: which CIS code shall we look for? + * @parse: buffer where the tuple shall be parsed (or NULL, if no parse) + * + * pccard_read_tuple() reads out one tuple and attempts to parse it + */ +int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, + cisdata_t code, void *parse) +{ + tuple_t tuple; + cisdata_t *buf; + int ret; + + buf = kmalloc(256, GFP_KERNEL); + if (buf == NULL) { + dev_printk(KERN_WARNING, &s->dev, "no memory to read tuple\n"); + return -ENOMEM; + } + tuple.DesiredTuple = code; + tuple.Attributes = 0; + if (function == BIND_FN_ALL) + tuple.Attributes = TUPLE_RETURN_COMMON; + ret = pccard_get_first_tuple(s, function, &tuple); + if (ret != 0) + goto done; + tuple.TupleData = buf; + tuple.TupleOffset = 0; + tuple.TupleDataMax = 255; + ret = pccard_get_tuple_data(s, &tuple); + if (ret != 0) + goto done; + ret = pcmcia_parse_tuple(&tuple, parse); +done: + kfree(buf); + return ret; +} + + +/** + * pccard_loop_tuple() - loop over tuples in the CIS + * @s: the struct pcmcia_socket where the card is inserted + * @function: the device function we loop for + * @code: which CIS code shall we look for? + * @parse: buffer where the tuple shall be parsed (or NULL, if no parse) + * @priv_data: private data to be passed to the loop_tuple function. + * @loop_tuple: function to call for each CIS entry of type @function. IT + * gets passed the raw tuple, the paresed tuple (if @parse is + * set) and @priv_data. + * + * pccard_loop_tuple() loops over all CIS entries of type @function, and + * calls the @loop_tuple function for each entry. If the call to @loop_tuple + * returns 0, the loop exits. Returns 0 on success or errorcode otherwise. + */ +int pccard_loop_tuple(struct pcmcia_socket *s, unsigned int function, + cisdata_t code, cisparse_t *parse, void *priv_data, + int (*loop_tuple) (tuple_t *tuple, + cisparse_t *parse, + void *priv_data)) +{ + tuple_t tuple; + cisdata_t *buf; + int ret; + + buf = kzalloc(256, GFP_KERNEL); + if (buf == NULL) { + dev_printk(KERN_WARNING, &s->dev, "no memory to read tuple\n"); + return -ENOMEM; + } + + tuple.TupleData = buf; + tuple.TupleDataMax = 255; + tuple.TupleOffset = 0; + tuple.DesiredTuple = code; + tuple.Attributes = 0; + + ret = pccard_get_first_tuple(s, function, &tuple); + while (!ret) { + if (pccard_get_tuple_data(s, &tuple)) + goto next_entry; + + if (parse) + if (pcmcia_parse_tuple(&tuple, parse)) + goto next_entry; + + ret = loop_tuple(&tuple, parse, priv_data); + if (!ret) + break; + +next_entry: + ret = pccard_get_next_tuple(s, function, &tuple); + } + + kfree(buf); + return ret; +} + +struct pcmcia_cfg_mem { + struct pcmcia_device *p_dev; + void *priv_data; + int (*conf_check) (struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cfg, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data); + cisparse_t parse; + cistpl_cftable_entry_t dflt; +}; + +/** + * pcmcia_do_loop_config() - internal helper for pcmcia_loop_config() + * + * pcmcia_do_loop_config() is the internal callback for the call from + * pcmcia_loop_config() to pccard_loop_tuple(). Data is transferred + * by a struct pcmcia_cfg_mem. + */ +static int pcmcia_do_loop_config(tuple_t *tuple, cisparse_t *parse, void *priv) +{ + cistpl_cftable_entry_t *cfg = &parse->cftable_entry; + struct pcmcia_cfg_mem *cfg_mem = priv; + + /* default values */ + cfg_mem->p_dev->conf.ConfigIndex = cfg->index; + if (cfg->flags & CISTPL_CFTABLE_DEFAULT) + cfg_mem->dflt = *cfg; + + return cfg_mem->conf_check(cfg_mem->p_dev, cfg, &cfg_mem->dflt, + cfg_mem->p_dev->socket->socket.Vcc, + cfg_mem->priv_data); +} + +/** + * pcmcia_loop_config() - loop over configuration options + * @p_dev: the struct pcmcia_device which we need to loop for. + * @conf_check: function to call for each configuration option. + * It gets passed the struct pcmcia_device, the CIS data + * describing the configuration option, and private data + * being passed to pcmcia_loop_config() + * @priv_data: private data to be passed to the conf_check function. + * + * pcmcia_loop_config() loops over all configuration options, and calls + * the driver-specific conf_check() for each one, checking whether + * it is a valid one. Returns 0 on success or errorcode otherwise. + */ +int pcmcia_loop_config(struct pcmcia_device *p_dev, + int (*conf_check) (struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cfg, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data), + void *priv_data) +{ + struct pcmcia_cfg_mem *cfg_mem; + int ret; + + cfg_mem = kzalloc(sizeof(struct pcmcia_cfg_mem), GFP_KERNEL); + if (cfg_mem == NULL) + return -ENOMEM; + + cfg_mem->p_dev = p_dev; + cfg_mem->conf_check = conf_check; + cfg_mem->priv_data = priv_data; + + ret = pccard_loop_tuple(p_dev->socket, p_dev->func, + CISTPL_CFTABLE_ENTRY, &cfg_mem->parse, + cfg_mem, pcmcia_do_loop_config); + + kfree(cfg_mem); + return ret; +} +EXPORT_SYMBOL(pcmcia_loop_config); + + +struct pcmcia_loop_mem { + struct pcmcia_device *p_dev; + void *priv_data; + int (*loop_tuple) (struct pcmcia_device *p_dev, + tuple_t *tuple, + void *priv_data); +}; + +/** + * pcmcia_do_loop_tuple() - internal helper for pcmcia_loop_config() + * + * pcmcia_do_loop_tuple() is the internal callback for the call from + * pcmcia_loop_tuple() to pccard_loop_tuple(). Data is transferred + * by a struct pcmcia_cfg_mem. + */ +static int pcmcia_do_loop_tuple(tuple_t *tuple, cisparse_t *parse, void *priv) +{ + struct pcmcia_loop_mem *loop = priv; + + return loop->loop_tuple(loop->p_dev, tuple, loop->priv_data); +}; + +/** + * pcmcia_loop_tuple() - loop over tuples in the CIS + * @p_dev: the struct pcmcia_device which we need to loop for. + * @code: which CIS code shall we look for? + * @priv_data: private data to be passed to the loop_tuple function. + * @loop_tuple: function to call for each CIS entry of type @function. IT + * gets passed the raw tuple and @priv_data. + * + * pcmcia_loop_tuple() loops over all CIS entries of type @function, and + * calls the @loop_tuple function for each entry. If the call to @loop_tuple + * returns 0, the loop exits. Returns 0 on success or errorcode otherwise. + */ +int pcmcia_loop_tuple(struct pcmcia_device *p_dev, cisdata_t code, + int (*loop_tuple) (struct pcmcia_device *p_dev, + tuple_t *tuple, + void *priv_data), + void *priv_data) +{ + struct pcmcia_loop_mem loop = { + .p_dev = p_dev, + .loop_tuple = loop_tuple, + .priv_data = priv_data}; + + return pccard_loop_tuple(p_dev->socket, p_dev->func, code, NULL, + &loop, pcmcia_do_loop_tuple); +} +EXPORT_SYMBOL(pcmcia_loop_tuple); + + +struct pcmcia_loop_get { + size_t len; + cisdata_t **buf; +}; + +/** + * pcmcia_do_get_tuple() - internal helper for pcmcia_get_tuple() + * + * pcmcia_do_get_tuple() is the internal callback for the call from + * pcmcia_get_tuple() to pcmcia_loop_tuple(). As we're only interested in + * the first tuple, return 0 unconditionally. Create a memory buffer large + * enough to hold the content of the tuple, and fill it with the tuple data. + * The caller is responsible to free the buffer. + */ +static int pcmcia_do_get_tuple(struct pcmcia_device *p_dev, tuple_t *tuple, + void *priv) +{ + struct pcmcia_loop_get *get = priv; + + *get->buf = kzalloc(tuple->TupleDataLen, GFP_KERNEL); + if (*get->buf) { + get->len = tuple->TupleDataLen; + memcpy(*get->buf, tuple->TupleData, tuple->TupleDataLen); + } else + dev_dbg(&p_dev->dev, "do_get_tuple: out of memory\n"); + return 0; +} + +/** + * pcmcia_get_tuple() - get first tuple from CIS + * @p_dev: the struct pcmcia_device which we need to loop for. + * @code: which CIS code shall we look for? + * @buf: pointer to store the buffer to. + * + * pcmcia_get_tuple() gets the content of the first CIS entry of type @code. + * It returns the buffer length (or zero). The caller is responsible to free + * the buffer passed in @buf. + */ +size_t pcmcia_get_tuple(struct pcmcia_device *p_dev, cisdata_t code, + unsigned char **buf) +{ + struct pcmcia_loop_get get = { + .len = 0, + .buf = buf, + }; + + *get.buf = NULL; + pcmcia_loop_tuple(p_dev, code, pcmcia_do_get_tuple, &get); + + return get.len; +} +EXPORT_SYMBOL(pcmcia_get_tuple); + + +/** + * pcmcia_do_get_mac() - internal helper for pcmcia_get_mac_from_cis() + * + * pcmcia_do_get_mac() is the internal callback for the call from + * pcmcia_get_mac_from_cis() to pcmcia_loop_tuple(). We check whether the + * tuple contains a proper LAN_NODE_ID of length 6, and copy the data + * to struct net_device->dev_addr[i]. + */ +static int pcmcia_do_get_mac(struct pcmcia_device *p_dev, tuple_t *tuple, + void *priv) +{ + struct net_device *dev = priv; + int i; + + if (tuple->TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID) + return -EINVAL; + if (tuple->TupleDataLen < ETH_ALEN + 2) { + dev_warn(&p_dev->dev, "Invalid CIS tuple length for " + "LAN_NODE_ID\n"); + return -EINVAL; + } + + if (tuple->TupleData[1] != ETH_ALEN) { + dev_warn(&p_dev->dev, "Invalid header for LAN_NODE_ID\n"); + return -EINVAL; + } + for (i = 0; i < 6; i++) + dev->dev_addr[i] = tuple->TupleData[i+2]; + return 0; +} + +/** + * pcmcia_get_mac_from_cis() - read out MAC address from CISTPL_FUNCE + * @p_dev: the struct pcmcia_device for which we want the address. + * @dev: a properly prepared struct net_device to store the info to. + * + * pcmcia_get_mac_from_cis() reads out the hardware MAC address from + * CISTPL_FUNCE and stores it into struct net_device *dev->dev_addr which + * must be set up properly by the driver (see examples!). + */ +int pcmcia_get_mac_from_cis(struct pcmcia_device *p_dev, struct net_device *dev) +{ + return pcmcia_loop_tuple(p_dev, CISTPL_FUNCE, pcmcia_do_get_mac, dev); +} +EXPORT_SYMBOL(pcmcia_get_mac_from_cis); + diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index f355c5ac407b..9c5f9cd5e03d 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c @@ -923,232 +923,3 @@ void pcmcia_disable_device(struct pcmcia_device *p_dev) pcmcia_release_window(p_dev, p_dev->win); } EXPORT_SYMBOL(pcmcia_disable_device); - - -struct pcmcia_cfg_mem { - struct pcmcia_device *p_dev; - void *priv_data; - int (*conf_check) (struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cfg, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data); - cisparse_t parse; - cistpl_cftable_entry_t dflt; -}; - -/** - * pcmcia_do_loop_config() - internal helper for pcmcia_loop_config() - * - * pcmcia_do_loop_config() is the internal callback for the call from - * pcmcia_loop_config() to pccard_loop_tuple(). Data is transferred - * by a struct pcmcia_cfg_mem. - */ -static int pcmcia_do_loop_config(tuple_t *tuple, cisparse_t *parse, void *priv) -{ - cistpl_cftable_entry_t *cfg = &parse->cftable_entry; - struct pcmcia_cfg_mem *cfg_mem = priv; - - /* default values */ - cfg_mem->p_dev->conf.ConfigIndex = cfg->index; - if (cfg->flags & CISTPL_CFTABLE_DEFAULT) - cfg_mem->dflt = *cfg; - - return cfg_mem->conf_check(cfg_mem->p_dev, cfg, &cfg_mem->dflt, - cfg_mem->p_dev->socket->socket.Vcc, - cfg_mem->priv_data); -} - -/** - * pcmcia_loop_config() - loop over configuration options - * @p_dev: the struct pcmcia_device which we need to loop for. - * @conf_check: function to call for each configuration option. - * It gets passed the struct pcmcia_device, the CIS data - * describing the configuration option, and private data - * being passed to pcmcia_loop_config() - * @priv_data: private data to be passed to the conf_check function. - * - * pcmcia_loop_config() loops over all configuration options, and calls - * the driver-specific conf_check() for each one, checking whether - * it is a valid one. Returns 0 on success or errorcode otherwise. - */ -int pcmcia_loop_config(struct pcmcia_device *p_dev, - int (*conf_check) (struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cfg, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data), - void *priv_data) -{ - struct pcmcia_cfg_mem *cfg_mem; - int ret; - - cfg_mem = kzalloc(sizeof(struct pcmcia_cfg_mem), GFP_KERNEL); - if (cfg_mem == NULL) - return -ENOMEM; - - cfg_mem->p_dev = p_dev; - cfg_mem->conf_check = conf_check; - cfg_mem->priv_data = priv_data; - - ret = pccard_loop_tuple(p_dev->socket, p_dev->func, - CISTPL_CFTABLE_ENTRY, &cfg_mem->parse, - cfg_mem, pcmcia_do_loop_config); - - kfree(cfg_mem); - return ret; -} -EXPORT_SYMBOL(pcmcia_loop_config); - - -struct pcmcia_loop_mem { - struct pcmcia_device *p_dev; - void *priv_data; - int (*loop_tuple) (struct pcmcia_device *p_dev, - tuple_t *tuple, - void *priv_data); -}; - -/** - * pcmcia_do_loop_tuple() - internal helper for pcmcia_loop_config() - * - * pcmcia_do_loop_tuple() is the internal callback for the call from - * pcmcia_loop_tuple() to pccard_loop_tuple(). Data is transferred - * by a struct pcmcia_cfg_mem. - */ -static int pcmcia_do_loop_tuple(tuple_t *tuple, cisparse_t *parse, void *priv) -{ - struct pcmcia_loop_mem *loop = priv; - - return loop->loop_tuple(loop->p_dev, tuple, loop->priv_data); -}; - -/** - * pcmcia_loop_tuple() - loop over tuples in the CIS - * @p_dev: the struct pcmcia_device which we need to loop for. - * @code: which CIS code shall we look for? - * @priv_data: private data to be passed to the loop_tuple function. - * @loop_tuple: function to call for each CIS entry of type @function. IT - * gets passed the raw tuple and @priv_data. - * - * pcmcia_loop_tuple() loops over all CIS entries of type @function, and - * calls the @loop_tuple function for each entry. If the call to @loop_tuple - * returns 0, the loop exits. Returns 0 on success or errorcode otherwise. - */ -int pcmcia_loop_tuple(struct pcmcia_device *p_dev, cisdata_t code, - int (*loop_tuple) (struct pcmcia_device *p_dev, - tuple_t *tuple, - void *priv_data), - void *priv_data) -{ - struct pcmcia_loop_mem loop = { - .p_dev = p_dev, - .loop_tuple = loop_tuple, - .priv_data = priv_data}; - - return pccard_loop_tuple(p_dev->socket, p_dev->func, code, NULL, - &loop, pcmcia_do_loop_tuple); -} -EXPORT_SYMBOL(pcmcia_loop_tuple); - - -struct pcmcia_loop_get { - size_t len; - cisdata_t **buf; -}; - -/** - * pcmcia_do_get_tuple() - internal helper for pcmcia_get_tuple() - * - * pcmcia_do_get_tuple() is the internal callback for the call from - * pcmcia_get_tuple() to pcmcia_loop_tuple(). As we're only interested in - * the first tuple, return 0 unconditionally. Create a memory buffer large - * enough to hold the content of the tuple, and fill it with the tuple data. - * The caller is responsible to free the buffer. - */ -static int pcmcia_do_get_tuple(struct pcmcia_device *p_dev, tuple_t *tuple, - void *priv) -{ - struct pcmcia_loop_get *get = priv; - - *get->buf = kzalloc(tuple->TupleDataLen, GFP_KERNEL); - if (*get->buf) { - get->len = tuple->TupleDataLen; - memcpy(*get->buf, tuple->TupleData, tuple->TupleDataLen); - } else - dev_dbg(&p_dev->dev, "do_get_tuple: out of memory\n"); - return 0; -} - -/** - * pcmcia_get_tuple() - get first tuple from CIS - * @p_dev: the struct pcmcia_device which we need to loop for. - * @code: which CIS code shall we look for? - * @buf: pointer to store the buffer to. - * - * pcmcia_get_tuple() gets the content of the first CIS entry of type @code. - * It returns the buffer length (or zero). The caller is responsible to free - * the buffer passed in @buf. - */ -size_t pcmcia_get_tuple(struct pcmcia_device *p_dev, cisdata_t code, - unsigned char **buf) -{ - struct pcmcia_loop_get get = { - .len = 0, - .buf = buf, - }; - - *get.buf = NULL; - pcmcia_loop_tuple(p_dev, code, pcmcia_do_get_tuple, &get); - - return get.len; -} -EXPORT_SYMBOL(pcmcia_get_tuple); - - -/** - * pcmcia_do_get_mac() - internal helper for pcmcia_get_mac_from_cis() - * - * pcmcia_do_get_mac() is the internal callback for the call from - * pcmcia_get_mac_from_cis() to pcmcia_loop_tuple(). We check whether the - * tuple contains a proper LAN_NODE_ID of length 6, and copy the data - * to struct net_device->dev_addr[i]. - */ -static int pcmcia_do_get_mac(struct pcmcia_device *p_dev, tuple_t *tuple, - void *priv) -{ - struct net_device *dev = priv; - int i; - - if (tuple->TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID) - return -EINVAL; - if (tuple->TupleDataLen < ETH_ALEN + 2) { - dev_warn(&p_dev->dev, "Invalid CIS tuple length for " - "LAN_NODE_ID\n"); - return -EINVAL; - } - - if (tuple->TupleData[1] != ETH_ALEN) { - dev_warn(&p_dev->dev, "Invalid header for LAN_NODE_ID\n"); - return -EINVAL; - } - for (i = 0; i < 6; i++) - dev->dev_addr[i] = tuple->TupleData[i+2]; - return 0; -} - -/** - * pcmcia_get_mac_from_cis() - read out MAC address from CISTPL_FUNCE - * @p_dev: the struct pcmcia_device for which we want the address. - * @dev: a properly prepared struct net_device to store the info to. - * - * pcmcia_get_mac_from_cis() reads out the hardware MAC address from - * CISTPL_FUNCE and stores it into struct net_device *dev->dev_addr which - * must be set up properly by the driver (see examples!). - */ -int pcmcia_get_mac_from_cis(struct pcmcia_device *p_dev, struct net_device *dev) -{ - return pcmcia_loop_tuple(p_dev, CISTPL_FUNCE, pcmcia_do_get_mac, dev); -} -EXPORT_SYMBOL(pcmcia_get_mac_from_cis); - -- cgit v1.2.3 From 49b1153adfe18a3cce7e70aa26c690f275917cd0 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 7 Mar 2010 16:41:57 +0100 Subject: pcmcia: move all pcmcia_resource_ops providers into one module Signed-off-by: Dominik Brodowski --- drivers/pcmcia/Kconfig | 2 +- drivers/pcmcia/Makefile | 7 ++- drivers/pcmcia/cs_internal.h | 8 +++ drivers/pcmcia/rsrc_iodyn.c | 107 ++++++++++++++++++++++++++++++++++++++ drivers/pcmcia/rsrc_mgr.c | 110 +++++----------------------------------- drivers/pcmcia/rsrc_nonstatic.c | 24 +++------ 6 files changed, 141 insertions(+), 117 deletions(-) create mode 100644 drivers/pcmcia/rsrc_iodyn.c (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig index d189e4743e69..4c5b53f62079 100644 --- a/drivers/pcmcia/Kconfig +++ b/drivers/pcmcia/Kconfig @@ -317,7 +317,7 @@ config ELECTRA_CF PA Semi Electra eval board. config PCCARD_NONSTATIC - tristate + bool config PCCARD_IODYN bool diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile index 8122b03e2ae5..7031d0a4f4b0 100644 --- a/drivers/pcmcia/Makefile +++ b/drivers/pcmcia/Makefile @@ -2,7 +2,7 @@ # Makefile for the kernel pcmcia subsystem (c/o David Hinds) # -pcmcia_core-y += cs.o rsrc_mgr.o socket_sysfs.o +pcmcia_core-y += cs.o socket_sysfs.o pcmcia_core-$(CONFIG_CARDBUS) += cardbus.o obj-$(CONFIG_PCCARD) += pcmcia_core.o @@ -10,7 +10,10 @@ pcmcia-y += ds.o pcmcia_resource.o cistpl.o pcmcia_cis.o pcmcia-$(CONFIG_PCMCIA_IOCTL) += pcmcia_ioctl.o obj-$(CONFIG_PCMCIA) += pcmcia.o -obj-$(CONFIG_PCCARD_NONSTATIC) += rsrc_nonstatic.o +pcmcia_rsrc-y += rsrc_mgr.o +pcmcia_rsrc-$(CONFIG_PCCARD_NONSTATIC) += rsrc_nonstatic.o +pcmcia_rsrc-$(CONFIG_PCCARD_IODYN) += rsrc_iodyn.o +obj-$(CONFIG_PCCARD) += pcmcia_rsrc.o # socket drivers diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h index 74d91c8849ba..ab000ea67296 100644 --- a/drivers/pcmcia/cs_internal.h +++ b/drivers/pcmcia/cs_internal.h @@ -88,6 +88,14 @@ struct pccard_resource_ops { #define SOCKET_CARDBUS_CONFIG 0x10000 +/* + * Stuff internal to module "pcmcia_rsrc": + */ +extern int static_init(struct pcmcia_socket *s); +extern struct resource *pcmcia_make_resource(unsigned long start, + unsigned long end, + int flags, const char *name); + /* * Stuff internal to module "pcmcia_core": */ diff --git a/drivers/pcmcia/rsrc_iodyn.c b/drivers/pcmcia/rsrc_iodyn.c new file mode 100644 index 000000000000..3fa808b582f6 --- /dev/null +++ b/drivers/pcmcia/rsrc_iodyn.c @@ -0,0 +1,107 @@ +/* + * rsrc_iodyn.c -- Resource management routines for MEM-static sockets. + * + * 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 + * . Portions created by David A. Hinds + * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. + * + * (C) 1999 David A. Hinds + */ + +#include +#include + +#include +#include +#include +#include +#include "cs_internal.h" + + +struct pcmcia_align_data { + unsigned long mask; + unsigned long offset; +}; + +static resource_size_t pcmcia_align(void *align_data, + const struct resource *res, + resource_size_t size, resource_size_t align) +{ + struct pcmcia_align_data *data = align_data; + resource_size_t start; + + start = (res->start & ~data->mask) + data->offset; + if (start < res->start) + start += data->mask + 1; + +#ifdef CONFIG_X86 + if (res->flags & IORESOURCE_IO) { + if (start & 0x300) + start = (start + 0x3ff) & ~0x3ff; + } +#endif + +#ifdef CONFIG_M68K + if (res->flags & IORESOURCE_IO) { + if ((res->start + size - 1) >= 1024) + start = res->end; + } +#endif + + return start; +} + + +static int iodyn_adjust_io_region(struct resource *res, unsigned long r_start, + unsigned long r_end, struct pcmcia_socket *s) +{ + return adjust_resource(res, r_start, r_end - r_start + 1); +} + + +static struct resource *iodyn_find_io_region(unsigned long base, int num, + unsigned long align, struct pcmcia_socket *s) +{ + struct resource *res = pcmcia_make_resource(0, num, IORESOURCE_IO, + dev_name(&s->dev)); + struct pcmcia_align_data data; + unsigned long min = base; + int ret; + + if (align == 0) + align = 0x10000; + + data.mask = align - 1; + data.offset = base & data.mask; + +#ifdef CONFIG_PCI + if (s->cb_dev) { + ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1, + min, 0, pcmcia_align, &data); + } else +#endif + ret = allocate_resource(&ioport_resource, res, num, min, ~0UL, + 1, pcmcia_align, &data); + + if (ret != 0) { + kfree(res); + res = NULL; + } + return res; +} + +struct pccard_resource_ops pccard_iodyn_ops = { + .validate_mem = NULL, + .adjust_io_region = iodyn_adjust_io_region, + .find_io = iodyn_find_io_region, + .find_mem = NULL, + .add_io = NULL, + .add_mem = NULL, + .init = static_init, + .exit = NULL, +}; +EXPORT_SYMBOL(pccard_iodyn_ops); diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c index ffa5f3cae57b..71838cae890c 100644 --- a/drivers/pcmcia/rsrc_mgr.c +++ b/drivers/pcmcia/rsrc_mgr.c @@ -22,7 +22,7 @@ #include #include "cs_internal.h" -static int static_init(struct pcmcia_socket *s) +int static_init(struct pcmcia_socket *s) { /* the good thing about SS_CAP_STATIC_MAP sockets is * that they don't need a resource database */ @@ -32,118 +32,34 @@ static int static_init(struct pcmcia_socket *s) return 0; } - -struct pccard_resource_ops pccard_static_ops = { - .validate_mem = NULL, - .adjust_io_region = NULL, - .find_io = NULL, - .find_mem = NULL, - .add_io = NULL, - .add_mem = NULL, - .init = static_init, - .exit = NULL, -}; -EXPORT_SYMBOL(pccard_static_ops); - - -#ifdef CONFIG_PCCARD_IODYN - -static struct resource * -make_resource(unsigned long b, unsigned long n, int flags, char *name) +struct resource *pcmcia_make_resource(unsigned long start, unsigned long end, + int flags, const char *name) { struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL); if (res) { res->name = name; - res->start = b; - res->end = b + n - 1; + res->start = start; + res->end = start + end - 1; res->flags = flags; } return res; } -struct pcmcia_align_data { - unsigned long mask; - unsigned long offset; -}; - -static resource_size_t pcmcia_align(void *align_data, - const struct resource *res, - resource_size_t size, resource_size_t align) -{ - struct pcmcia_align_data *data = align_data; - resource_size_t start; - - start = (res->start & ~data->mask) + data->offset; - if (start < res->start) - start += data->mask + 1; - -#ifdef CONFIG_X86 - if (res->flags & IORESOURCE_IO) { - if (start & 0x300) - start = (start + 0x3ff) & ~0x3ff; - } -#endif - -#ifdef CONFIG_M68K - if (res->flags & IORESOURCE_IO) { - if ((res->start + size - 1) >= 1024) - start = res->end; - } -#endif - - return start; -} - - -static int iodyn_adjust_io_region(struct resource *res, unsigned long r_start, - unsigned long r_end, struct pcmcia_socket *s) -{ - return adjust_resource(res, r_start, r_end - r_start + 1); -} - - -static struct resource *iodyn_find_io_region(unsigned long base, int num, - unsigned long align, struct pcmcia_socket *s) -{ - struct resource *res = make_resource(0, num, IORESOURCE_IO, - dev_name(&s->dev)); - struct pcmcia_align_data data; - unsigned long min = base; - int ret; - - if (align == 0) - align = 0x10000; - data.mask = align - 1; - data.offset = base & data.mask; - -#ifdef CONFIG_PCI - if (s->cb_dev) { - ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1, - min, 0, pcmcia_align, &data); - } else -#endif - ret = allocate_resource(&ioport_resource, res, num, min, ~0UL, - 1, pcmcia_align, &data); - - if (ret != 0) { - kfree(res); - res = NULL; - } - return res; -} - -struct pccard_resource_ops pccard_iodyn_ops = { +struct pccard_resource_ops pccard_static_ops = { .validate_mem = NULL, - .adjust_io_region = iodyn_adjust_io_region, - .find_io = iodyn_find_io_region, + .adjust_io_region = NULL, + .find_io = NULL, .find_mem = NULL, .add_io = NULL, .add_mem = NULL, .init = static_init, .exit = NULL, }; -EXPORT_SYMBOL(pccard_iodyn_ops); +EXPORT_SYMBOL(pccard_static_ops); + -#endif /* CONFIG_PCCARD_IODYN */ +MODULE_AUTHOR("David A. Hinds, Dominik Brodowski"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("rsrc_nonstatic"); diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index a6eb7b59ba9f..c5ebc603b058 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c @@ -34,8 +34,10 @@ #include #include "cs_internal.h" +/* moved to rsrc_mgr.c MODULE_AUTHOR("David A. Hinds, Dominik Brodowski"); MODULE_LICENSE("GPL"); +*/ /* Parameters that can be set with 'insmod' */ @@ -69,20 +71,6 @@ struct socket_data { ======================================================================*/ -static struct resource * -make_resource(resource_size_t b, resource_size_t n, int flags, const char *name) -{ - struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL); - - if (res) { - res->name = name; - res->start = b; - res->end = b + n - 1; - res->flags = flags; - } - return res; -} - static struct resource * claim_region(struct pcmcia_socket *s, resource_size_t base, resource_size_t size, int type, char *name) @@ -90,7 +78,7 @@ claim_region(struct pcmcia_socket *s, resource_size_t base, struct resource *res, *parent; parent = type & IORESOURCE_MEM ? &iomem_resource : &ioport_resource; - res = make_resource(base, size, type | IORESOURCE_BUSY, name); + res = pcmcia_make_resource(base, size, type | IORESOURCE_BUSY, name); if (res) { #ifdef CONFIG_PCI @@ -698,7 +686,8 @@ static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_star static struct resource *nonstatic_find_io_region(unsigned long base, int num, unsigned long align, struct pcmcia_socket *s) { - struct resource *res = make_resource(0, num, IORESOURCE_IO, dev_name(&s->dev)); + struct resource *res = pcmcia_make_resource(0, num, IORESOURCE_IO, + dev_name(&s->dev)); struct socket_data *s_data = s->resource_data; struct pcmcia_align_data data; unsigned long min = base; @@ -730,7 +719,8 @@ static struct resource *nonstatic_find_io_region(unsigned long base, int num, static struct resource *nonstatic_find_mem_region(u_long base, u_long num, u_long align, int low, struct pcmcia_socket *s) { - struct resource *res = make_resource(0, num, IORESOURCE_MEM, dev_name(&s->dev)); + struct resource *res = pcmcia_make_resource(0, num, IORESOURCE_MEM, + dev_name(&s->dev)); struct socket_data *s_data = s->resource_data; struct pcmcia_align_data data; unsigned long min, max; -- cgit v1.2.3 From b19a7275dec4b470ea9abaae6129d21a0d75ab2f Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sat, 20 Mar 2010 13:10:47 +0100 Subject: pcmcia: clarify alloc_io_space, move it to resource handlers Clean up the alloc_io_space() function by moving most of it to the actual resource_ops. This allows for a bit less re-directions. Future cleanups will follow, and will make up for the code duplication currently present between rsrc_iodyn and rsrc_nonstatic (which are hardly ever built at the same time anyway, therefore no increase in built size). Signed-off-by: Dominik Brodowski --- drivers/pcmcia/cs_internal.h | 12 ++--- drivers/pcmcia/pcmcia_resource.c | 71 +++----------------------- drivers/pcmcia/rsrc_iodyn.c | 92 ++++++++++++++++++++++++++++------ drivers/pcmcia/rsrc_mgr.c | 14 +++++- drivers/pcmcia/rsrc_nonstatic.c | 105 +++++++++++++++++++++++++++++++++++---- include/pcmcia/ds.h | 11 +++- 6 files changed, 204 insertions(+), 101 deletions(-) (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h index ab000ea67296..4126a75445ea 100644 --- a/drivers/pcmcia/cs_internal.h +++ b/drivers/pcmcia/cs_internal.h @@ -52,13 +52,11 @@ struct cis_cache_entry { struct pccard_resource_ops { int (*validate_mem) (struct pcmcia_socket *s); - int (*adjust_io_region) (struct resource *res, - unsigned long r_start, - unsigned long r_end, - struct pcmcia_socket *s); - struct resource* (*find_io) (unsigned long base, int num, - unsigned long align, - struct pcmcia_socket *s); + int (*find_io) (struct pcmcia_socket *s, + unsigned int attr, + unsigned int *base, + unsigned int num, + unsigned int align); struct resource* (*find_mem) (unsigned long base, unsigned long num, unsigned long align, int low, struct pcmcia_socket *s); diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index 9c5f9cd5e03d..c6419c18a6c8 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c @@ -40,23 +40,6 @@ static int io_speed; module_param(io_speed, int, 0444); -static int pcmcia_adjust_io_region(struct resource *res, unsigned long start, - unsigned long end, struct pcmcia_socket *s) -{ - if (s->resource_ops->adjust_io_region) - return s->resource_ops->adjust_io_region(res, start, end, s); - return -ENOMEM; -} - -static struct resource *pcmcia_find_io_region(unsigned long base, int num, - unsigned long align, - struct pcmcia_socket *s) -{ - if (s->resource_ops->find_io) - return s->resource_ops->find_io(base, num, align, s); - return NULL; -} - int pcmcia_validate_mem(struct pcmcia_socket *s) { if (s->resource_ops->validate_mem) @@ -82,8 +65,7 @@ struct resource *pcmcia_find_mem_region(u_long base, u_long num, u_long align, static int alloc_io_space(struct pcmcia_socket *s, u_int attr, unsigned int *base, unsigned int num, u_int lines) { - int i; - unsigned int try, align; + unsigned int align; align = (*base) ? (lines ? 1<features & SS_CAP_STATIC_MAP) && s->io_offset) { - *base = s->io_offset | (*base & 0x0fff); - return 0; - } - /* Check for an already-allocated window that must conflict with - * what was asked for. It is a hack because it does not catch all - * potential conflicts, just the most obvious ones. - */ - for (i = 0; i < MAX_IO_WIN; i++) - if ((s->io[i].res) && *base && - ((s->io[i].res->start & (align-1)) == *base)) - return 1; - for (i = 0; i < MAX_IO_WIN; i++) { - if (!s->io[i].res) { - s->io[i].res = pcmcia_find_io_region(*base, num, align, s); - if (s->io[i].res) { - *base = s->io[i].res->start; - s->io[i].res->flags = (s->io[i].res->flags & ~IORESOURCE_BITS) | (attr & IORESOURCE_BITS); - s->io[i].InUse = num; - break; - } else - return 1; - } else if ((s->io[i].res->flags & IORESOURCE_BITS) != (attr & IORESOURCE_BITS)) - continue; - /* Try to extend top of window */ - try = s->io[i].res->end + 1; - if ((*base == 0) || (*base == try)) - if (pcmcia_adjust_io_region(s->io[i].res, s->io[i].res->start, - s->io[i].res->end + num, s) == 0) { - *base = try; - s->io[i].InUse += num; - break; - } - /* Try to extend bottom of window */ - try = s->io[i].res->start - num; - if ((*base == 0) || (*base == try)) - if (pcmcia_adjust_io_region(s->io[i].res, s->io[i].res->start - num, - s->io[i].res->end, s) == 0) { - *base = try; - s->io[i].InUse += num; - break; - } - } - return (i == MAX_IO_WIN); + + return s->resource_ops->find_io(s, attr, base, num, align); } /* alloc_io_space */ @@ -683,7 +623,8 @@ EXPORT_SYMBOL(pcmcia_request_irq); * free_irq themselves, too), or the pcmcia_request_irq() function. */ int __must_check -pcmcia_request_exclusive_irq(struct pcmcia_device *p_dev, irq_handler_t handler) +__pcmcia_request_exclusive_irq(struct pcmcia_device *p_dev, + irq_handler_t handler) { int ret; @@ -705,7 +646,7 @@ pcmcia_request_exclusive_irq(struct pcmcia_device *p_dev, irq_handler_t handler) return ret; } /* pcmcia_request_exclusive_irq */ -EXPORT_SYMBOL(pcmcia_request_exclusive_irq); +EXPORT_SYMBOL(__pcmcia_request_exclusive_irq); #ifdef CONFIG_PCMCIA_PROBE diff --git a/drivers/pcmcia/rsrc_iodyn.c b/drivers/pcmcia/rsrc_iodyn.c index 3fa808b582f6..779137561580 100644 --- a/drivers/pcmcia/rsrc_iodyn.c +++ b/drivers/pcmcia/rsrc_iodyn.c @@ -56,15 +56,9 @@ static resource_size_t pcmcia_align(void *align_data, } -static int iodyn_adjust_io_region(struct resource *res, unsigned long r_start, - unsigned long r_end, struct pcmcia_socket *s) -{ - return adjust_resource(res, r_start, r_end - r_start + 1); -} - - -static struct resource *iodyn_find_io_region(unsigned long base, int num, - unsigned long align, struct pcmcia_socket *s) +static struct resource *__iodyn_find_io_region(struct pcmcia_socket *s, + unsigned long base, int num, + unsigned long align) { struct resource *res = pcmcia_make_resource(0, num, IORESOURCE_IO, dev_name(&s->dev)); @@ -72,9 +66,6 @@ static struct resource *iodyn_find_io_region(unsigned long base, int num, unsigned long min = base; int ret; - if (align == 0) - align = 0x10000; - data.mask = align - 1; data.offset = base & data.mask; @@ -94,10 +85,83 @@ static struct resource *iodyn_find_io_region(unsigned long base, int num, return res; } +static int iodyn_find_io(struct pcmcia_socket *s, unsigned int attr, + unsigned int *base, unsigned int num, + unsigned int align) +{ + int i, ret = 0; + + /* Check for an already-allocated window that must conflict with + * what was asked for. It is a hack because it does not catch all + * potential conflicts, just the most obvious ones. + */ + for (i = 0; i < MAX_IO_WIN; i++) { + if (!s->io[i].res) + continue; + + if (!*base) + continue; + + if ((s->io[i].res->start & (align-1)) == *base) + return -EBUSY; + } + + for (i = 0; i < MAX_IO_WIN; i++) { + struct resource *res = s->io[i].res; + unsigned int try; + + if (res && (res->flags & IORESOURCE_BITS) != + (attr & IORESOURCE_BITS)) + continue; + + if (!res) { + if (align == 0) + align = 0x10000; + + res = s->io[i].res = __iodyn_find_io_region(s, *base, + num, align); + if (!res) + return -EINVAL; + + *base = res->start; + s->io[i].res->flags = + ((res->flags & ~IORESOURCE_BITS) | + (attr & IORESOURCE_BITS)); + s->io[i].InUse = num; + return 0; + } + + /* Try to extend top of window */ + try = res->end + 1; + if ((*base == 0) || (*base == try)) { + if (adjust_resource(s->io[i].res, res->start, + res->end - res->start + num + 1)) + continue; + *base = try; + s->io[i].InUse += num; + return 0; + } + + /* Try to extend bottom of window */ + try = res->start - num; + if ((*base == 0) || (*base == try)) { + if (adjust_resource(s->io[i].res, + res->start - num, + res->end - res->start + num + 1)) + continue; + *base = try; + s->io[i].InUse += num; + return 0; + } + } + + return -EINVAL; +} + + struct pccard_resource_ops pccard_iodyn_ops = { .validate_mem = NULL, - .adjust_io_region = iodyn_adjust_io_region, - .find_io = iodyn_find_io_region, + .find_io = iodyn_find_io, .find_mem = NULL, .add_io = NULL, .add_mem = NULL, diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c index 71838cae890c..142efac3c387 100644 --- a/drivers/pcmcia/rsrc_mgr.c +++ b/drivers/pcmcia/rsrc_mgr.c @@ -46,11 +46,21 @@ struct resource *pcmcia_make_resource(unsigned long start, unsigned long end, return res; } +static int static_find_io(struct pcmcia_socket *s, unsigned int attr, + unsigned int *base, unsigned int num, + unsigned int align) +{ + if (!s->io_offset) + return -EINVAL; + *base = s->io_offset | (*base & 0x0fff); + + return 0; +} + struct pccard_resource_ops pccard_static_ops = { .validate_mem = NULL, - .adjust_io_region = NULL, - .find_io = NULL, + .find_io = static_find_io, .find_mem = NULL, .add_io = NULL, .add_mem = NULL, diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index c5ebc603b058..ba5256debde2 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c @@ -649,8 +649,9 @@ pcmcia_align(void *align_data, const struct resource *res, * Adjust an existing IO region allocation, but making sure that we don't * encroach outside the resources which the user supplied. */ -static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_start, - unsigned long r_end, struct pcmcia_socket *s) +static int __nonstatic_adjust_io_region(struct pcmcia_socket *s, + unsigned long r_start, + unsigned long r_end) { struct resource_map *m; struct socket_data *s_data = s->resource_data; @@ -663,8 +664,7 @@ static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_star if (start > r_start || r_end > end) continue; - ret = adjust_resource(res, r_start, r_end - r_start + 1); - break; + ret = 0; } return ret; @@ -683,8 +683,9 @@ static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_star ======================================================================*/ -static struct resource *nonstatic_find_io_region(unsigned long base, int num, - unsigned long align, struct pcmcia_socket *s) +static struct resource *__nonstatic_find_io_region(struct pcmcia_socket *s, + unsigned long base, int num, + unsigned long align) { struct resource *res = pcmcia_make_resource(0, num, IORESOURCE_IO, dev_name(&s->dev)); @@ -693,9 +694,6 @@ static struct resource *nonstatic_find_io_region(unsigned long base, int num, unsigned long min = base; int ret; - if (align == 0) - align = 0x10000; - data.mask = align - 1; data.offset = base & data.mask; data.map = &s_data->io_db; @@ -716,6 +714,92 @@ static struct resource *nonstatic_find_io_region(unsigned long base, int num, return res; } +static int nonstatic_find_io(struct pcmcia_socket *s, unsigned int attr, + unsigned int *base, unsigned int num, + unsigned int align) +{ + int i, ret = 0; + + /* Check for an already-allocated window that must conflict with + * what was asked for. It is a hack because it does not catch all + * potential conflicts, just the most obvious ones. + */ + for (i = 0; i < MAX_IO_WIN; i++) { + if (!s->io[i].res) + continue; + + if (!*base) + continue; + + if ((s->io[i].res->start & (align-1)) == *base) + return -EBUSY; + } + + for (i = 0; i < MAX_IO_WIN; i++) { + struct resource *res = s->io[i].res; + unsigned int try; + + if (res && (res->flags & IORESOURCE_BITS) != + (attr & IORESOURCE_BITS)) + continue; + + if (!res) { + if (align == 0) + align = 0x10000; + + res = s->io[i].res = __nonstatic_find_io_region(s, + *base, num, + align); + if (!res) + return -EINVAL; + + *base = res->start; + s->io[i].res->flags = + ((res->flags & ~IORESOURCE_BITS) | + (attr & IORESOURCE_BITS)); + s->io[i].InUse = num; + return 0; + } + + /* Try to extend top of window */ + try = res->end + 1; + if ((*base == 0) || (*base == try)) { + ret = __nonstatic_adjust_io_region(s, res->start, + res->end + num); + if (!ret) { + ret = adjust_resource(s->io[i].res, res->start, + res->end - res->start + num + 1); + if (ret) + continue; + *base = try; + s->io[i].InUse += num; + return 0; + } + } + + /* Try to extend bottom of window */ + try = res->start - num; + if ((*base == 0) || (*base == try)) { + ret = __nonstatic_adjust_io_region(s, + res->start - num, + res->end); + if (!ret) { + ret = adjust_resource(s->io[i].res, + res->start - num, + res->end - res->start + num + 1); + if (ret) + continue; + *base = try; + s->io[i].InUse += num; + return 0; + } + } + } + + return -EINVAL; +} + + static struct resource *nonstatic_find_mem_region(u_long base, u_long num, u_long align, int low, struct pcmcia_socket *s) { @@ -946,8 +1030,7 @@ static void nonstatic_release_resource_db(struct pcmcia_socket *s) struct pccard_resource_ops pccard_nonstatic_ops = { .validate_mem = pcmcia_nonstatic_validate_mem, - .adjust_io_region = nonstatic_adjust_io_region, - .find_io = nonstatic_find_io_region, + .find_io = nonstatic_find_io, .find_mem = nonstatic_find_mem_region, .add_io = adjust_io, .add_mem = adjust_memory, diff --git a/include/pcmcia/ds.h b/include/pcmcia/ds.h index b4429f78b9c3..c180165fbd3e 100644 --- a/include/pcmcia/ds.h +++ b/include/pcmcia/ds.h @@ -184,9 +184,16 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, /* device configuration */ int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req); -int __must_check __deprecated -pcmcia_request_exclusive_irq(struct pcmcia_device *p_dev, +int __must_check +__pcmcia_request_exclusive_irq(struct pcmcia_device *p_dev, irq_handler_t handler); +static inline __must_check __deprecated int +pcmcia_request_exclusive_irq(struct pcmcia_device *p_dev, + irq_handler_t handler) +{ + return __pcmcia_request_exclusive_irq(p_dev, handler); +} + int __must_check pcmcia_request_irq(struct pcmcia_device *p_dev, irq_handler_t handler); -- cgit v1.2.3 From cf26e8dc419424786575990aa133e76f5fb38657 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Mon, 29 Mar 2010 21:40:35 +0200 Subject: pcmcia: do not autoadd root PCI bus resources On the PCI root bus on the x86 architecture, the risk of hitting some strange system devices is too high: If a driver isn't loaded, the resources are not claimed; even if a driver is loaded, it may not request all resources or even the wrong one. We can neither trust the rest of the kernel nor ACPI/PNP and CRS parsing to get it right. Therefore, explicitly spell out what safeguards we provide, and add a safeguard to only use resources which are set up exclusively for the secondary PCI bus (non-subtractive mode): the risk of hitting system devices is quite low, as they usually aren't connected to the secondary PCI bus. CC: Jesse Barnes CC: Bjorn Helgaas Signed-off-by: Dominik Brodowski --- drivers/pcmcia/rsrc_nonstatic.c | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index ba5256debde2..dcd1a4ad3d63 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c @@ -935,23 +935,42 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s) return -ENODEV; #if defined(CONFIG_X86) - /* If this is the root bus, the risk of hitting - * some strange system devices which aren't protected - * by either ACPI resource tables or properly requested - * resources is too big. Therefore, don't do auto-adding - * of resources at the moment. + /* If this is the root bus, the risk of hitting some strange + * system devices is too high: If a driver isn't loaded, the + * resources are not claimed; even if a driver is loaded, it + * may not request all resources or even the wrong one. We + * can neither trust the rest of the kernel nor ACPI/PNP and + * CRS parsing to get it right. Therefore, use several + * safeguards: + * + * - Do not auto-add resources if the CardBus bridge is on + * the PCI root bus + * + * - Avoid any I/O ports < 0x100. + * + * - On PCI-PCI bridges, only use resources which are set up + * exclusively for the secondary PCI bus: the risk of hitting + * system devices is quite low, as they usually aren't + * connected to the secondary PCI bus. */ if (s->cb_dev->bus->number == 0) return -EINVAL; -#endif + for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++) { + res = s->cb_dev->bus->resource[i]; +#else pci_bus_for_each_resource(s->cb_dev->bus, res, i) { +#endif if (!res) continue; if (res->flags & IORESOURCE_IO) { + /* safeguard against the root resource, where the + * risk of hitting any other device would be too + * high */ if (res == &ioport_resource) continue; + dev_printk(KERN_INFO, &s->cb_dev->dev, "pcmcia: parent PCI bridge window: %pR\n", res); @@ -961,8 +980,12 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s) } if (res->flags & IORESOURCE_MEM) { + /* safeguard against the root resource, where the + * risk of hitting any other device would be too + * high */ if (res == &iomem_resource) continue; + dev_printk(KERN_INFO, &s->cb_dev->dev, "pcmcia: parent PCI bridge window: %pR\n", res); -- cgit v1.2.3 From 6d59622e52c296cad8702c483a0092f428b794ef Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 30 Mar 2010 02:52:37 +0900 Subject: pcmcia: update gfp/slab.h includes Implicit slab.h inclusion via percpu.h is about to go away. Make sure gfp.h or slab.h is included as necessary. Signed-off-by: Tejun Heo Cc: Stephen Rothwell Signed-off-by: Dominik Brodowski --- drivers/isdn/hardware/avm/avm_cs.c | 1 - drivers/pcmcia/pcmcia_cis.c | 1 + drivers/pcmcia/rsrc_iodyn.c | 1 + 3 files changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/pcmcia') diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c index 8bbc452ff598..f410d0eb2fef 100644 --- a/drivers/isdn/hardware/avm/avm_cs.c +++ b/drivers/isdn/hardware/avm/avm_cs.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/pcmcia/pcmcia_cis.c b/drivers/pcmcia/pcmcia_cis.c index 7406387f1f5e..4a65eaf96b0a 100644 --- a/drivers/pcmcia/pcmcia_cis.c +++ b/drivers/pcmcia/pcmcia_cis.c @@ -14,6 +14,7 @@ * */ +#include #include #include #include diff --git a/drivers/pcmcia/rsrc_iodyn.c b/drivers/pcmcia/rsrc_iodyn.c index 779137561580..d0bf35021065 100644 --- a/drivers/pcmcia/rsrc_iodyn.c +++ b/drivers/pcmcia/rsrc_iodyn.c @@ -12,6 +12,7 @@ * (C) 1999 David A. Hinds */ +#include #include #include -- cgit v1.2.3 From a60f22c4af3382b86301d64d6a9d68f30191d4c9 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 7 Mar 2010 09:22:51 +0100 Subject: pcmcia: remove pcmcia_add_device_lock As all cards to pcmcia_device_add() are already locked by skt_mutex, and the critical sections inside this function are further protected by ops_mutex, there's no need to keep a third lock around. Therfore, remove pcmcia_add_device_lock. Signed-off-by: Dominik Brodowski --- drivers/pcmcia/ds.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 0e12d85dd723..7ef7adee5e4f 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -477,15 +477,6 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev) } -/* device_add_lock is needed to avoid double registration by cardmgr and kernel. - * Serializes pcmcia_device_add; will most likely be removed in future. - * - * While it has the caveat that adding new PCMCIA devices inside(!) device_register() - * won't work, this doesn't matter much at the moment: the driver core doesn't - * support it either. - */ -static DEFINE_MUTEX(device_add_lock); - struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int function) { struct pcmcia_device *p_dev, *tmp_dev; @@ -495,8 +486,6 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu if (!s) return NULL; - mutex_lock(&device_add_lock); - pr_debug("adding device to %d, function %d\n", s->sock, function); p_dev = kzalloc(sizeof(struct pcmcia_device), GFP_KERNEL); @@ -536,8 +525,8 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu /* * p_dev->function_config must be the same for all card functions. - * Note that this is serialized by the device_add_lock, so that - * only one such struct will be created. + * Note that this is serialized by ops_mutex, so that only one + * such struct will be created. */ list_for_each_entry(tmp_dev, &s->devices_list, socket_device_list) if (p_dev->func == tmp_dev->func) { @@ -575,8 +564,6 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu if (device_register(&p_dev->dev)) goto err_unreg; - mutex_unlock(&device_add_lock); - return p_dev; err_unreg: @@ -594,7 +581,6 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu kfree(p_dev->devname); kfree(p_dev); err_put: - mutex_unlock(&device_add_lock); pcmcia_put_socket(s); return NULL; -- cgit v1.2.3 From 059f667d9f81082e94dead14ff3fa7b3b42c98a0 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 30 Mar 2010 18:07:50 +0200 Subject: pcmcia: call pcmcia_{read,write}_cis_mem with ops_mutex held This avoids multiple lock takings in several codepaths. Signed-off-by: Dominik Brodowski --- drivers/pcmcia/cistpl.c | 21 +++++++++------------ drivers/pcmcia/pcmcia_ioctl.c | 4 ++++ drivers/pcmcia/pcmcia_resource.c | 13 ++++++------- 3 files changed, 19 insertions(+), 19 deletions(-) (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c index e0b09e71d5c0..60d428be0b07 100644 --- a/drivers/pcmcia/cistpl.c +++ b/drivers/pcmcia/cistpl.c @@ -129,6 +129,8 @@ static void __iomem *set_cis_map(struct pcmcia_socket *s, /** * pcmcia_read_cis_mem() - low-level function to read CIS memory + * + * must be called with ops_mutex held */ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, u_int len, void *ptr) @@ -138,7 +140,6 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, dev_dbg(&s->dev, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len); - mutex_lock(&s->ops_mutex); if (attr & IS_INDIRECT) { /* Indirect accesses use a bunch of special registers at fixed locations in common memory */ @@ -153,7 +154,6 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, if (!sys) { dev_dbg(&s->dev, "could not map memory\n"); memset(ptr, 0xff, len); - mutex_unlock(&s->ops_mutex); return -1; } @@ -184,7 +184,6 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, if (!sys) { dev_dbg(&s->dev, "could not map memory\n"); memset(ptr, 0xff, len); - mutex_unlock(&s->ops_mutex); return -1; } end = sys + s->map_size; @@ -198,7 +197,6 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, addr = 0; } } - mutex_unlock(&s->ops_mutex); dev_dbg(&s->dev, " %#2.2x %#2.2x %#2.2x %#2.2x ...\n", *(u_char *)(ptr+0), *(u_char *)(ptr+1), *(u_char *)(ptr+2), *(u_char *)(ptr+3)); @@ -209,7 +207,8 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, /** * pcmcia_write_cis_mem() - low-level function to write CIS memory * - * Probably only useful for writing one-byte registers. + * 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, u_int len, void *ptr) @@ -220,7 +219,6 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, dev_dbg(&s->dev, "pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len); - mutex_lock(&s->ops_mutex); if (attr & IS_INDIRECT) { /* Indirect accesses use a bunch of special registers at fixed locations in common memory */ @@ -234,7 +232,6 @@ 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"); - mutex_unlock(&s->ops_mutex); return; /* FIXME: Error */ } @@ -260,7 +257,6 @@ 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"); - mutex_unlock(&s->ops_mutex); return; /* FIXME: error */ } @@ -275,7 +271,6 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, addr = 0; } } - mutex_unlock(&s->ops_mutex); } @@ -314,7 +309,6 @@ static int read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr, return 0; } } - mutex_unlock(&s->ops_mutex); ret = pcmcia_read_cis_mem(s, attr, addr, len, ptr); @@ -326,11 +320,11 @@ static int read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr, cis->len = len; cis->attr = attr; memcpy(cis->cache, ptr, len); - mutex_lock(&s->ops_mutex); list_add(&cis->node, &s->cis_cache); - mutex_unlock(&s->ops_mutex); } } + mutex_unlock(&s->ops_mutex); + return ret; } @@ -386,6 +380,7 @@ int verify_cis_cache(struct pcmcia_socket *s) "no memory for verifying CIS\n"); return -ENOMEM; } + mutex_lock(&s->ops_mutex); list_for_each_entry(cis, &s->cis_cache, node) { int len = cis->len; @@ -395,10 +390,12 @@ int verify_cis_cache(struct pcmcia_socket *s) ret = pcmcia_read_cis_mem(s, cis->attr, cis->addr, len, buf); if (ret || memcmp(buf, cis->cache, len) != 0) { kfree(buf); + mutex_unlock(&s->ops_mutex); return -1; } } kfree(buf); + mutex_unlock(&s->ops_mutex); return 0; } diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c index a42a6c7be10a..ef0c5f133691 100644 --- a/drivers/pcmcia/pcmcia_ioctl.c +++ b/drivers/pcmcia/pcmcia_ioctl.c @@ -301,7 +301,9 @@ static int pccard_get_status(struct pcmcia_socket *s, (c->IntType & (INT_MEMORY_AND_IO | INT_ZOOMED_VIDEO))) { u_char reg; if (c->CardValues & PRESENT_PIN_REPLACE) { + mutex_lock(&s->ops_mutex); pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_PRR)>>1, 1, ®); + mutex_unlock(&s->ops_mutex); status->CardState |= (reg & PRR_WP_STATUS) ? CS_EVENT_WRITE_PROTECT : 0; status->CardState |= @@ -315,7 +317,9 @@ static int pccard_get_status(struct pcmcia_socket *s, status->CardState |= CS_EVENT_READY_CHANGE; } if (c->CardValues & PRESENT_EXT_STATUS) { + mutex_lock(&s->ops_mutex); pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_ESR)>>1, 1, ®); + mutex_unlock(&s->ops_mutex); status->CardState |= (reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0; } diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index c6419c18a6c8..29f91fac1dff 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c @@ -123,6 +123,7 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, config_t *c; int addr; u_char val; + int ret = 0; if (!p_dev || !p_dev->function_config) return -EINVAL; @@ -139,11 +140,10 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, } addr = (c->ConfigBase + reg->Offset) >> 1; - mutex_unlock(&s->ops_mutex); switch (reg->Action) { case CS_READ: - pcmcia_read_cis_mem(s, 1, addr, 1, &val); + ret = pcmcia_read_cis_mem(s, 1, addr, 1, &val); reg->Value = val; break; case CS_WRITE: @@ -152,10 +152,11 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, break; default: dev_dbg(&s->dev, "Invalid conf register request\n"); - return -EINVAL; + ret = -EINVAL; break; } - return 0; + mutex_unlock(&s->ops_mutex); + return ret; } /* pcmcia_access_configuration_register */ EXPORT_SYMBOL(pcmcia_access_configuration_register); @@ -436,7 +437,6 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev, s->socket.io_irq = 0; s->ops->set_socket(s, &s->socket); s->lock_count++; - mutex_unlock(&s->ops_mutex); /* Set up CIS configuration registers */ base = c->ConfigBase = req->ConfigBase; @@ -485,7 +485,6 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev, /* Configure I/O windows */ if (c->state & CONFIG_IO_REQ) { - mutex_lock(&s->ops_mutex); iomap.speed = io_speed; for (i = 0; i < MAX_IO_WIN; i++) if (s->io[i].res) { @@ -504,11 +503,11 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev, s->ops->set_io_map(s, &iomap); s->io[i].Config++; } - mutex_unlock(&s->ops_mutex); } c->state |= CONFIG_LOCKED; p_dev->_locked = 1; + mutex_unlock(&s->ops_mutex); return 0; } /* pcmcia_request_configuration */ EXPORT_SYMBOL(pcmcia_request_configuration); -- cgit v1.2.3 From 378b451ede192163780bb15b1ad0a913aa8ee4ae Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 30 Mar 2010 18:23:24 +0200 Subject: pcmcia: remove suspend-related comment from yenta_socket.c While pci_set_power_state() is called by the PCI core unconditionally on all PCI devices, it is not called on _any_ PCI bridge device. Therefore, it is not surprising calling pci_set_power_state() on CardBus devices causes trouble. CC: dbrownell@users.sourceforge.net CC: gregkh@suse.de Signed-off-by: Dominik Brodowski --- drivers/pcmcia/yenta_socket.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index 83ace277426c..424e576f3acb 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c @@ -1303,13 +1303,6 @@ static int yenta_dev_suspend_noirq(struct device *dev) pci_read_config_dword(pdev, 17*4, &socket->saved_state[1]); pci_disable_device(pdev); - /* - * Some laptops (IBM T22) do not like us putting the Cardbus - * bridge into D3. At a guess, some other laptop will - * probably require this, so leave it commented out for now. - */ - /* pci_set_power_state(dev, 3); */ - return 0; } -- cgit v1.2.3 From addff0faecfc5e73e8a742687255cef847e260db Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 10 Mar 2010 04:16:28 +0100 Subject: [ARM] pxa: add support for Voipac PXA270 PCMCIA PCMCIA support for Voipac PXA270 Signed-off-by: Marek Vasut Signed-off-by: Eric Miao --- arch/arm/mach-pxa/include/mach/vpac270.h | 8 ++ arch/arm/mach-pxa/vpac270.c | 20 +++ drivers/pcmcia/Kconfig | 3 +- drivers/pcmcia/Makefile | 1 + drivers/pcmcia/pxa2xx_vpac270.c | 229 +++++++++++++++++++++++++++++++ 5 files changed, 260 insertions(+), 1 deletion(-) create mode 100644 drivers/pcmcia/pxa2xx_vpac270.c (limited to 'drivers/pcmcia') diff --git a/arch/arm/mach-pxa/include/mach/vpac270.h b/arch/arm/mach-pxa/include/mach/vpac270.h index 8f8eaed101dc..a77e310bcca8 100644 --- a/arch/arm/mach-pxa/include/mach/vpac270.h +++ b/arch/arm/mach-pxa/include/mach/vpac270.h @@ -23,4 +23,12 @@ #define GPIO52_VPAC270_SD_READONLY 52 #define GPIO53_VPAC270_SD_DETECT_N 53 +#define GPIO84_VPAC270_PCMCIA_CD 84 +#define GPIO35_VPAC270_PCMCIA_RDY 35 +#define GPIO107_VPAC270_PCMCIA_PPEN 107 +#define GPIO11_VPAC270_PCMCIA_RESET 11 +#define GPIO17_VPAC270_CF_CD 17 +#define GPIO12_VPAC270_CF_RDY 12 +#define GPIO16_VPAC270_CF_RESET 16 + #endif diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c index 710a17c80a14..f1b073707f03 100644 --- a/arch/arm/mach-pxa/vpac270.c +++ b/arch/arm/mach-pxa/vpac270.c @@ -85,6 +85,26 @@ static unsigned long vpac270_pin_config[] __initdata = { GPIO75_LCD_LCLK, GPIO76_LCD_PCLK, GPIO77_LCD_BIAS, + + /* PCMCIA */ + GPIO48_nPOE, + GPIO49_nPWE, + GPIO50_nPIOR, + GPIO51_nPIOW, + GPIO85_nPCE_1, + GPIO54_nPCE_2, + GPIO55_nPREG, + GPIO57_nIOIS16, + GPIO56_nPWAIT, + GPIO104_PSKTSEL, + GPIO84_GPIO, /* PCMCIA CD */ + GPIO35_GPIO, /* PCMCIA RDY */ + GPIO107_GPIO, /* PCMCIA PPEN */ + GPIO11_GPIO, /* PCMCIA RESET */ + GPIO17_GPIO, /* CF CD */ + GPIO12_GPIO, /* CF RDY */ + GPIO16_GPIO, /* CF RESET */ + }; /****************************************************************************** diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig index d189e4743e69..a44733d44ca1 100644 --- a/drivers/pcmcia/Kconfig +++ b/drivers/pcmcia/Kconfig @@ -234,7 +234,8 @@ config PCMCIA_PXA2XX depends on ARM && ARCH_PXA && PCMCIA depends on (ARCH_LUBBOCK || MACH_MAINSTONE || PXA_SHARPSL \ || MACH_ARMCORE || ARCH_PXA_PALM || TRIZEPS_PCMCIA \ - || ARCOM_PCMCIA || ARCH_PXA_ESERIES || MACH_STARGATE2) + || ARCOM_PCMCIA || ARCH_PXA_ESERIES || MACH_STARGATE2 \ + || MACH_VPAC270) select PCMCIA_SOC_COMMON help Say Y here to include support for the PXA2xx PCMCIA controller diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile index 381b031d9d75..4dae3613c458 100644 --- a/drivers/pcmcia/Makefile +++ b/drivers/pcmcia/Makefile @@ -66,6 +66,7 @@ pxa2xx-obj-$(CONFIG_MACH_PALMTC) += pxa2xx_palmtc.o pxa2xx-obj-$(CONFIG_MACH_PALMLD) += pxa2xx_palmld.o pxa2xx-obj-$(CONFIG_MACH_E740) += pxa2xx_e740.o pxa2xx-obj-$(CONFIG_MACH_STARGATE2) += pxa2xx_stargate2.o +pxa2xx-obj-$(CONFIG_MACH_VPAC270) += pxa2xx_vpac270.o obj-$(CONFIG_PCMCIA_PXA2XX) += pxa2xx_base.o $(pxa2xx-obj-y) diff --git a/drivers/pcmcia/pxa2xx_vpac270.c b/drivers/pcmcia/pxa2xx_vpac270.c new file mode 100644 index 000000000000..55627eccee8e --- /dev/null +++ b/drivers/pcmcia/pxa2xx_vpac270.c @@ -0,0 +1,229 @@ +/* + * linux/drivers/pcmcia/pxa2xx_vpac270.c + * + * Driver for Voipac PXA270 PCMCIA and CF sockets + * + * Copyright (C) 2010 + * Marek Vasut + * + * 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. + * + */ + +#include +#include + +#include + +#include +#include + +#include "soc_common.h" + +static struct pcmcia_irqs cd_irqs[] = { + { + .sock = 0, + .irq = IRQ_GPIO(GPIO84_VPAC270_PCMCIA_CD), + .str = "PCMCIA CD" + }, + { + .sock = 1, + .irq = IRQ_GPIO(GPIO17_VPAC270_CF_CD), + .str = "CF CD" + }, +}; + +static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt) +{ + int ret; + + if (skt->nr == 0) { + ret = gpio_request(GPIO84_VPAC270_PCMCIA_CD, "PCMCIA CD"); + if (ret) + goto err1; + ret = gpio_direction_input(GPIO84_VPAC270_PCMCIA_CD); + if (ret) + goto err2; + + ret = gpio_request(GPIO35_VPAC270_PCMCIA_RDY, "PCMCIA RDY"); + if (ret) + goto err2; + ret = gpio_direction_input(GPIO35_VPAC270_PCMCIA_RDY); + if (ret) + goto err3; + + ret = gpio_request(GPIO107_VPAC270_PCMCIA_PPEN, "PCMCIA PPEN"); + if (ret) + goto err3; + ret = gpio_direction_output(GPIO107_VPAC270_PCMCIA_PPEN, 0); + if (ret) + goto err4; + + ret = gpio_request(GPIO11_VPAC270_PCMCIA_RESET, "PCMCIA RESET"); + if (ret) + goto err4; + ret = gpio_direction_output(GPIO11_VPAC270_PCMCIA_RESET, 0); + if (ret) + goto err5; + + skt->socket.pci_irq = gpio_to_irq(GPIO35_VPAC270_PCMCIA_RDY); + + return soc_pcmcia_request_irqs(skt, &cd_irqs[0], 1); + +err5: + gpio_free(GPIO11_VPAC270_PCMCIA_RESET); +err4: + gpio_free(GPIO107_VPAC270_PCMCIA_PPEN); +err3: + gpio_free(GPIO35_VPAC270_PCMCIA_RDY); +err2: + gpio_free(GPIO84_VPAC270_PCMCIA_CD); +err1: + return ret; + + } else { + ret = gpio_request(GPIO17_VPAC270_CF_CD, "CF CD"); + if (ret) + goto err6; + ret = gpio_direction_input(GPIO17_VPAC270_CF_CD); + if (ret) + goto err7; + + ret = gpio_request(GPIO12_VPAC270_CF_RDY, "CF RDY"); + if (ret) + goto err7; + ret = gpio_direction_input(GPIO12_VPAC270_CF_RDY); + if (ret) + goto err8; + + ret = gpio_request(GPIO16_VPAC270_CF_RESET, "CF RESET"); + if (ret) + goto err8; + ret = gpio_direction_output(GPIO16_VPAC270_CF_RESET, 0); + if (ret) + goto err9; + + skt->socket.pci_irq = gpio_to_irq(GPIO12_VPAC270_CF_RDY); + + return soc_pcmcia_request_irqs(skt, &cd_irqs[1], 1); + +err9: + gpio_free(GPIO16_VPAC270_CF_RESET); +err8: + gpio_free(GPIO12_VPAC270_CF_RDY); +err7: + gpio_free(GPIO17_VPAC270_CF_CD); +err6: + return ret; + + } +} + +static void vpac270_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) +{ + gpio_free(GPIO11_VPAC270_PCMCIA_RESET); + gpio_free(GPIO107_VPAC270_PCMCIA_PPEN); + gpio_free(GPIO35_VPAC270_PCMCIA_RDY); + gpio_free(GPIO84_VPAC270_PCMCIA_CD); + gpio_free(GPIO16_VPAC270_CF_RESET); + gpio_free(GPIO12_VPAC270_CF_RDY); + gpio_free(GPIO17_VPAC270_CF_CD); +} + +static void vpac270_pcmcia_socket_state(struct soc_pcmcia_socket *skt, + struct pcmcia_state *state) +{ + if (skt->nr == 0) { + state->detect = !gpio_get_value(GPIO84_VPAC270_PCMCIA_CD); + state->ready = !!gpio_get_value(GPIO35_VPAC270_PCMCIA_RDY); + } else { + state->detect = !gpio_get_value(GPIO17_VPAC270_CF_CD); + state->ready = !!gpio_get_value(GPIO12_VPAC270_CF_RDY); + } + state->bvd1 = 1; + state->bvd2 = 1; + state->wrprot = 0; + state->vs_3v = 1; + state->vs_Xv = 0; +} + +static int +vpac270_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, + const socket_state_t *state) +{ + if (skt->nr == 0) { + gpio_set_value(GPIO11_VPAC270_PCMCIA_RESET, + (state->flags & SS_RESET)); + gpio_set_value(GPIO107_VPAC270_PCMCIA_PPEN, + !(state->Vcc == 33 || state->Vcc == 50)); + } else { + gpio_set_value(GPIO16_VPAC270_CF_RESET, + (state->flags & SS_RESET)); + } + + return 0; +} + +static void vpac270_pcmcia_socket_init(struct soc_pcmcia_socket *skt) +{ +} + +static void vpac270_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) +{ +} + +static struct pcmcia_low_level vpac270_pcmcia_ops = { + .owner = THIS_MODULE, + + .first = 0, + .nr = 2, + + .hw_init = vpac270_pcmcia_hw_init, + .hw_shutdown = vpac270_pcmcia_hw_shutdown, + + .socket_state = vpac270_pcmcia_socket_state, + .configure_socket = vpac270_pcmcia_configure_socket, + + .socket_init = vpac270_pcmcia_socket_init, + .socket_suspend = vpac270_pcmcia_socket_suspend, +}; + +static struct platform_device *vpac270_pcmcia_device; + +static int __init vpac270_pcmcia_init(void) +{ + int ret; + + if (!machine_is_vpac270()) + return -ENODEV; + + vpac270_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1); + if (!vpac270_pcmcia_device) + return -ENOMEM; + + ret = platform_device_add_data(vpac270_pcmcia_device, + &vpac270_pcmcia_ops, sizeof(vpac270_pcmcia_ops)); + + if (!ret) + ret = platform_device_add(vpac270_pcmcia_device); + + if (ret) + platform_device_put(vpac270_pcmcia_device); + + return ret; +} + +static void __exit vpac270_pcmcia_exit(void) +{ + platform_device_unregister(vpac270_pcmcia_device); +} + +module_init(vpac270_pcmcia_init); +module_exit(vpac270_pcmcia_exit); + +MODULE_AUTHOR("Marek Vasut "); +MODULE_DESCRIPTION("PCMCIA support for Voipac PXA270"); +MODULE_ALIAS("platform:pxa2xx-pcmcia"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From acd200bf45487271d54f05938ad9e30f32a530ee Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sat, 6 Mar 2010 13:31:17 +0100 Subject: pcmcia: disable PCMCIA ioctl also for ARM As per a3f916f2c84f2b9e1d32cc0dbfe326a9e380dbfb, disable the long obsolete PCMCIA ioctl also for ARM. Signed-off-by: Dominik Brodowski --- drivers/pcmcia/Kconfig | 20 -------------------- 1 file changed, 20 deletions(-) (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig index 4c5b53f62079..caca50eaa0e7 100644 --- a/drivers/pcmcia/Kconfig +++ b/drivers/pcmcia/Kconfig @@ -49,26 +49,6 @@ config PCMCIA_LOAD_CIS If unsure, say Y. -config PCMCIA_IOCTL - bool "PCMCIA control ioctl (obsolete)" - depends on PCMCIA && ARM && !SMP && !PREEMPT - default y - help - If you say Y here, the deprecated ioctl interface to the PCMCIA - subsystem will be built. It is needed by the deprecated pcmcia-cs - tools (cardmgr, cardctl) to function properly. - - You should use the new pcmciautils package instead (see - for location and details). - - This config option will most likely be removed from kernel 2.6.35, - the associated code from kernel 2.6.36. - - As the PCMCIA ioctl is not locking safe, it depends on !SMP and - !PREEMPT. - - If unsure, say N. - config CARDBUS bool "32-bit CardBus support" depends on PCI -- cgit v1.2.3 From 2c3c8bea608866d8bd9dcf92657d57fdcac011c5 Mon Sep 17 00:00:00 2001 From: Chris Wright Date: Wed, 12 May 2010 18:28:57 -0700 Subject: sysfs: add struct file* to bin_attr callbacks This allows bin_attr->read,write,mmap callbacks to check file specific data (such as inode owner) as part of any privilege validation. Signed-off-by: Chris Wright Signed-off-by: Greg Kroah-Hartman --- arch/alpha/kernel/pci-sysfs.c | 8 ++++--- arch/mips/txx9/generic/setup.c | 4 ++-- arch/powerpc/sysdev/mv64x60_pci.c | 4 ++-- arch/s390/kernel/ipl.c | 14 ++++++------ drivers/acpi/system.c | 2 +- drivers/base/firmware_class.c | 11 ++++++---- drivers/firmware/dcdbas.c | 4 ++-- drivers/firmware/dell_rbu.c | 10 ++++----- drivers/firmware/efivars.c | 4 ++-- drivers/gpu/drm/drm_sysfs.c | 5 +++-- drivers/misc/c2port/core.c | 4 ++-- drivers/misc/ds1682.c | 6 ++++-- drivers/misc/eeprom/at24.c | 6 ++++-- drivers/misc/eeprom/at25.c | 6 ++++-- drivers/misc/eeprom/eeprom.c | 3 ++- drivers/misc/eeprom/max6875.c | 2 +- drivers/net/netxen/netxen_nic_main.c | 11 ++++++---- drivers/net/qlcnic/qlcnic_main.c | 12 +++++++---- drivers/pci/hotplug/acpiphp_ibm.c | 5 +++-- drivers/pci/pci-sysfs.c | 42 +++++++++++++++++++++++++----------- drivers/pcmcia/cistpl.c | 4 ++-- drivers/power/olpc_battery.c | 2 +- drivers/rapidio/rio-sysfs.c | 6 ++++-- drivers/rtc/rtc-cmos.c | 6 ++++-- drivers/rtc/rtc-ds1305.c | 6 ++++-- drivers/rtc/rtc-ds1307.c | 6 ++++-- drivers/rtc/rtc-ds1511.c | 10 +++++---- drivers/rtc/rtc-ds1553.c | 4 ++-- drivers/rtc/rtc-ds1742.c | 4 ++-- drivers/rtc/rtc-m48t59.c | 4 ++-- drivers/rtc/rtc-stk17ta8.c | 4 ++-- drivers/rtc/rtc-tx4939.c | 4 ++-- drivers/s390/cio/chp.c | 5 +++-- drivers/scsi/3w-sas.c | 4 ++-- drivers/scsi/arcmsr/arcmsr_attr.c | 9 +++++--- drivers/scsi/ibmvscsi/ibmvfc.c | 3 ++- drivers/scsi/ipr.c | 9 +++++--- drivers/scsi/lpfc/lpfc_attr.c | 20 ++++++++++++----- drivers/scsi/qla2xxx/qla_attr.c | 32 +++++++++++++-------------- drivers/staging/udlfb/udlfb.c | 3 ++- drivers/usb/core/sysfs.c | 3 ++- drivers/video/aty/radeon_base.c | 4 ++-- drivers/w1/slaves/w1_ds2431.c | 4 ++-- drivers/w1/slaves/w1_ds2433.c | 4 ++-- drivers/w1/slaves/w1_ds2760.c | 2 +- drivers/w1/w1.c | 4 ++-- drivers/zorro/zorro-sysfs.c | 2 +- fs/sysfs/bin.c | 24 ++++++++++----------- include/linux/sysfs.h | 7 +++--- kernel/ksysfs.c | 3 ++- kernel/module.c | 2 +- net/bridge/br_sysfs_br.c | 2 +- 52 files changed, 220 insertions(+), 149 deletions(-) (limited to 'drivers/pcmcia') diff --git a/arch/alpha/kernel/pci-sysfs.c b/arch/alpha/kernel/pci-sysfs.c index d979e7c7bc4b..a5fffc882c72 100644 --- a/arch/alpha/kernel/pci-sysfs.c +++ b/arch/alpha/kernel/pci-sysfs.c @@ -53,6 +53,7 @@ static int __pci_mmap_fits(struct pci_dev *pdev, int num, /** * pci_mmap_resource - map a PCI resource into user memory space + * @filp: open sysfs file * @kobj: kobject for mapping * @attr: struct bin_attribute for the file being mapped * @vma: struct vm_area_struct passed into the mmap @@ -60,7 +61,8 @@ static int __pci_mmap_fits(struct pci_dev *pdev, int num, * * Use the bus mapping routines to map a PCI resource into userspace. */ -static int pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, +static int pci_mmap_resource(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, struct vm_area_struct *vma, int sparse) { struct pci_dev *pdev = to_pci_dev(container_of(kobj, @@ -89,14 +91,14 @@ static int pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, return hose_mmap_page_range(pdev->sysdata, vma, mmap_type, sparse); } -static int pci_mmap_resource_sparse(struct kobject *kobj, +static int pci_mmap_resource_sparse(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, struct vm_area_struct *vma) { return pci_mmap_resource(kobj, attr, vma, 1); } -static int pci_mmap_resource_dense(struct kobject *kobj, +static int pci_mmap_resource_dense(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, struct vm_area_struct *vma) { diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index adc69291f9e2..575d219b8001 100644 --- a/arch/mips/txx9/generic/setup.c +++ b/arch/mips/txx9/generic/setup.c @@ -905,7 +905,7 @@ struct txx9_sramc_sysdev { void __iomem *base; }; -static ssize_t txx9_sram_read(struct kobject *kobj, +static ssize_t txx9_sram_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t size) { @@ -920,7 +920,7 @@ static ssize_t txx9_sram_read(struct kobject *kobj, return size; } -static ssize_t txx9_sram_write(struct kobject *kobj, +static ssize_t txx9_sram_write(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t size) { diff --git a/arch/powerpc/sysdev/mv64x60_pci.c b/arch/powerpc/sysdev/mv64x60_pci.c index 1456015a22d8..198f288570cc 100644 --- a/arch/powerpc/sysdev/mv64x60_pci.c +++ b/arch/powerpc/sysdev/mv64x60_pci.c @@ -24,7 +24,7 @@ #define MV64X60_VAL_LEN_MAX 11 #define MV64X60_PCICFG_CPCI_HOTSWAP 0x68 -static ssize_t mv64x60_hs_reg_read(struct kobject *kobj, +static ssize_t mv64x60_hs_reg_read(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { @@ -45,7 +45,7 @@ static ssize_t mv64x60_hs_reg_read(struct kobject *kobj, return sprintf(buf, "0x%08x\n", v); } -static ssize_t mv64x60_hs_reg_write(struct kobject *kobj, +static ssize_t mv64x60_hs_reg_write(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 72c8b0d070c8..a689070be287 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -403,8 +403,9 @@ static ssize_t sys_ipl_device_show(struct kobject *kobj, static struct kobj_attribute sys_ipl_device_attr = __ATTR(device, S_IRUGO, sys_ipl_device_show, NULL); -static ssize_t ipl_parameter_read(struct kobject *kobj, struct bin_attribute *attr, - char *buf, loff_t off, size_t count) +static ssize_t ipl_parameter_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, + loff_t off, size_t count) { return memory_read_from_buffer(buf, count, &off, IPL_PARMBLOCK_START, IPL_PARMBLOCK_SIZE); @@ -419,8 +420,9 @@ static struct bin_attribute ipl_parameter_attr = { .read = &ipl_parameter_read, }; -static ssize_t ipl_scp_data_read(struct kobject *kobj, struct bin_attribute *attr, - char *buf, loff_t off, size_t count) +static ssize_t ipl_scp_data_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, + loff_t off, size_t count) { unsigned int size = IPL_PARMBLOCK_START->ipl_info.fcp.scp_data_len; void *scp_data = &IPL_PARMBLOCK_START->ipl_info.fcp.scp_data; @@ -694,7 +696,7 @@ static struct kobj_attribute sys_reipl_ccw_vmparm_attr = /* FCP reipl device attributes */ -static ssize_t reipl_fcp_scpdata_read(struct kobject *kobj, +static ssize_t reipl_fcp_scpdata_read(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { @@ -704,7 +706,7 @@ static ssize_t reipl_fcp_scpdata_read(struct kobject *kobj, return memory_read_from_buffer(buf, count, &off, scp_data, size); } -static ssize_t reipl_fcp_scpdata_write(struct kobject *kobj, +static ssize_t reipl_fcp_scpdata_write(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c index e35525b39f6b..c79e789ed03a 100644 --- a/drivers/acpi/system.c +++ b/drivers/acpi/system.c @@ -71,7 +71,7 @@ struct acpi_table_attr { struct list_head node; }; -static ssize_t acpi_table_show(struct kobject *kobj, +static ssize_t acpi_table_show(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t offset, size_t count) { diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index d98e424675cf..3f093b0dd217 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -278,8 +278,9 @@ static ssize_t firmware_loading_store(struct device *dev, static DEVICE_ATTR(loading, 0644, firmware_loading_show, firmware_loading_store); static ssize_t -firmware_data_read(struct kobject *kobj, struct bin_attribute *bin_attr, - char *buffer, loff_t offset, size_t count) +firmware_data_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buffer, loff_t offset, + size_t count) { struct device *dev = to_dev(kobj); struct firmware_priv *fw_priv = dev_get_drvdata(dev); @@ -362,6 +363,7 @@ fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size) /** * firmware_data_write - write method for firmware + * @filp: open sysfs file * @kobj: kobject for the device * @bin_attr: bin_attr structure * @buffer: buffer being written @@ -372,8 +374,9 @@ fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size) * the driver as a firmware image. **/ static ssize_t -firmware_data_write(struct kobject *kobj, struct bin_attribute *bin_attr, - char *buffer, loff_t offset, size_t count) +firmware_data_write(struct file* filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buffer, + loff_t offset, size_t count) { struct device *dev = to_dev(kobj); struct firmware_priv *fw_priv = dev_get_drvdata(dev); diff --git a/drivers/firmware/dcdbas.c b/drivers/firmware/dcdbas.c index fb09bb3c0ad6..aa9bc9e980e1 100644 --- a/drivers/firmware/dcdbas.c +++ b/drivers/firmware/dcdbas.c @@ -149,7 +149,7 @@ static ssize_t smi_data_buf_size_store(struct device *dev, return count; } -static ssize_t smi_data_read(struct kobject *kobj, +static ssize_t smi_data_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t count) { @@ -162,7 +162,7 @@ static ssize_t smi_data_read(struct kobject *kobj, return ret; } -static ssize_t smi_data_write(struct kobject *kobj, +static ssize_t smi_data_write(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t count) { diff --git a/drivers/firmware/dell_rbu.c b/drivers/firmware/dell_rbu.c index 3a4460265b10..2f452f1f7c8a 100644 --- a/drivers/firmware/dell_rbu.c +++ b/drivers/firmware/dell_rbu.c @@ -522,7 +522,7 @@ static ssize_t read_rbu_mono_data(char *buffer, loff_t pos, size_t count) rbu_data.image_update_buffer, rbu_data.bios_image_size); } -static ssize_t read_rbu_data(struct kobject *kobj, +static ssize_t read_rbu_data(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buffer, loff_t pos, size_t count) { @@ -576,7 +576,7 @@ static void callbackfn_rbu(const struct firmware *fw, void *context) release_firmware(fw); } -static ssize_t read_rbu_image_type(struct kobject *kobj, +static ssize_t read_rbu_image_type(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buffer, loff_t pos, size_t count) { @@ -586,7 +586,7 @@ static ssize_t read_rbu_image_type(struct kobject *kobj, return size; } -static ssize_t write_rbu_image_type(struct kobject *kobj, +static ssize_t write_rbu_image_type(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buffer, loff_t pos, size_t count) { @@ -647,7 +647,7 @@ static ssize_t write_rbu_image_type(struct kobject *kobj, return rc; } -static ssize_t read_rbu_packet_size(struct kobject *kobj, +static ssize_t read_rbu_packet_size(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buffer, loff_t pos, size_t count) { @@ -660,7 +660,7 @@ static ssize_t read_rbu_packet_size(struct kobject *kobj, return size; } -static ssize_t write_rbu_packet_size(struct kobject *kobj, +static ssize_t write_rbu_packet_size(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buffer, loff_t pos, size_t count) { diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index 81b70bd07586..2a62ec6390e0 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c @@ -402,7 +402,7 @@ efivar_unregister(struct efivar_entry *var) } -static ssize_t efivar_create(struct kobject *kobj, +static ssize_t efivar_create(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t count) { @@ -461,7 +461,7 @@ static ssize_t efivar_create(struct kobject *kobj, return count; } -static ssize_t efivar_delete(struct kobject *kobj, +static ssize_t efivar_delete(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t count) { diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 25bbd30ed7af..387166d5a109 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c @@ -193,8 +193,9 @@ static ssize_t enabled_show(struct device *device, "disabled"); } -static ssize_t edid_show(struct kobject *kobj, struct bin_attribute *attr, - char *buf, loff_t off, size_t count) +static ssize_t edid_show(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t off, + size_t count) { struct device *connector_dev = container_of(kobj, struct device, kobj); struct drm_connector *connector = to_drm_connector(connector_dev); diff --git a/drivers/misc/c2port/core.c b/drivers/misc/c2port/core.c index ed090e77c9cd..19fc7c1cb428 100644 --- a/drivers/misc/c2port/core.c +++ b/drivers/misc/c2port/core.c @@ -707,7 +707,7 @@ static ssize_t __c2port_read_flash_data(struct c2port_device *dev, return nread; } -static ssize_t c2port_read_flash_data(struct kobject *kobj, +static ssize_t c2port_read_flash_data(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buffer, loff_t offset, size_t count) { @@ -824,7 +824,7 @@ static ssize_t __c2port_write_flash_data(struct c2port_device *dev, return nwrite; } -static ssize_t c2port_write_flash_data(struct kobject *kobj, +static ssize_t c2port_write_flash_data(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buffer, loff_t offset, size_t count) { diff --git a/drivers/misc/ds1682.c b/drivers/misc/ds1682.c index 9197cfc55015..a513f0aa6432 100644 --- a/drivers/misc/ds1682.c +++ b/drivers/misc/ds1682.c @@ -140,7 +140,8 @@ static const struct attribute_group ds1682_group = { /* * User data attribute */ -static ssize_t ds1682_eeprom_read(struct kobject *kobj, struct bin_attribute *attr, +static ssize_t ds1682_eeprom_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t off, size_t count) { struct i2c_client *client = kobj_to_i2c_client(kobj); @@ -163,7 +164,8 @@ static ssize_t ds1682_eeprom_read(struct kobject *kobj, struct bin_attribute *at return count; } -static ssize_t ds1682_eeprom_write(struct kobject *kobj, struct bin_attribute *attr, +static ssize_t ds1682_eeprom_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t off, size_t count) { struct i2c_client *client = kobj_to_i2c_client(kobj); diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c index db7d0f21b65d..a79a62f75481 100644 --- a/drivers/misc/eeprom/at24.c +++ b/drivers/misc/eeprom/at24.c @@ -274,7 +274,8 @@ static ssize_t at24_read(struct at24_data *at24, return retval; } -static ssize_t at24_bin_read(struct kobject *kobj, struct bin_attribute *attr, +static ssize_t at24_bin_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t off, size_t count) { struct at24_data *at24; @@ -395,7 +396,8 @@ static ssize_t at24_write(struct at24_data *at24, const char *buf, loff_t off, return retval; } -static ssize_t at24_bin_write(struct kobject *kobj, struct bin_attribute *attr, +static ssize_t at24_bin_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t off, size_t count) { struct at24_data *at24; diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c index d194212a41f6..c627e4174ccd 100644 --- a/drivers/misc/eeprom/at25.c +++ b/drivers/misc/eeprom/at25.c @@ -126,7 +126,8 @@ at25_ee_read( } static ssize_t -at25_bin_read(struct kobject *kobj, struct bin_attribute *bin_attr, +at25_bin_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct device *dev; @@ -253,7 +254,8 @@ at25_ee_write(struct at25_data *at25, const char *buf, loff_t off, } static ssize_t -at25_bin_write(struct kobject *kobj, struct bin_attribute *bin_attr, +at25_bin_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct device *dev; diff --git a/drivers/misc/eeprom/eeprom.c b/drivers/misc/eeprom/eeprom.c index e306a8cd2f96..45060ddc4e59 100644 --- a/drivers/misc/eeprom/eeprom.c +++ b/drivers/misc/eeprom/eeprom.c @@ -81,7 +81,8 @@ exit: mutex_unlock(&data->update_lock); } -static ssize_t eeprom_read(struct kobject *kobj, struct bin_attribute *bin_attr, +static ssize_t eeprom_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj)); diff --git a/drivers/misc/eeprom/max6875.c b/drivers/misc/eeprom/max6875.c index fe2909278507..5653a3ce0517 100644 --- a/drivers/misc/eeprom/max6875.c +++ b/drivers/misc/eeprom/max6875.c @@ -107,7 +107,7 @@ exit_up: mutex_unlock(&data->update_lock); } -static ssize_t max6875_read(struct kobject *kobj, +static ssize_t max6875_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index c61a61f177b7..6ce6ce1df6d2 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -2560,7 +2560,8 @@ netxen_sysfs_validate_crb(struct netxen_adapter *adapter, } static ssize_t -netxen_sysfs_read_crb(struct kobject *kobj, struct bin_attribute *attr, +netxen_sysfs_read_crb(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t offset, size_t size) { struct device *dev = container_of(kobj, struct device, kobj); @@ -2587,7 +2588,8 @@ netxen_sysfs_read_crb(struct kobject *kobj, struct bin_attribute *attr, } static ssize_t -netxen_sysfs_write_crb(struct kobject *kobj, struct bin_attribute *attr, +netxen_sysfs_write_crb(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t offset, size_t size) { struct device *dev = container_of(kobj, struct device, kobj); @@ -2627,7 +2629,8 @@ netxen_sysfs_validate_mem(struct netxen_adapter *adapter, } static ssize_t -netxen_sysfs_read_mem(struct kobject *kobj, struct bin_attribute *attr, +netxen_sysfs_read_mem(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t offset, size_t size) { struct device *dev = container_of(kobj, struct device, kobj); @@ -2647,7 +2650,7 @@ netxen_sysfs_read_mem(struct kobject *kobj, struct bin_attribute *attr, return size; } -static ssize_t netxen_sysfs_write_mem(struct kobject *kobj, +static ssize_t netxen_sysfs_write_mem(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t offset, size_t size) { diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 1003eb76fda3..23ea9caa5261 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -2464,7 +2464,8 @@ qlcnic_sysfs_validate_crb(struct qlcnic_adapter *adapter, } static ssize_t -qlcnic_sysfs_read_crb(struct kobject *kobj, struct bin_attribute *attr, +qlcnic_sysfs_read_crb(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t offset, size_t size) { struct device *dev = container_of(kobj, struct device, kobj); @@ -2488,7 +2489,8 @@ qlcnic_sysfs_read_crb(struct kobject *kobj, struct bin_attribute *attr, } static ssize_t -qlcnic_sysfs_write_crb(struct kobject *kobj, struct bin_attribute *attr, +qlcnic_sysfs_write_crb(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t offset, size_t size) { struct device *dev = container_of(kobj, struct device, kobj); @@ -2525,7 +2527,8 @@ qlcnic_sysfs_validate_mem(struct qlcnic_adapter *adapter, } static ssize_t -qlcnic_sysfs_read_mem(struct kobject *kobj, struct bin_attribute *attr, +qlcnic_sysfs_read_mem(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t offset, size_t size) { struct device *dev = container_of(kobj, struct device, kobj); @@ -2546,7 +2549,8 @@ qlcnic_sysfs_read_mem(struct kobject *kobj, struct bin_attribute *attr, } static ssize_t -qlcnic_sysfs_write_mem(struct kobject *kobj, struct bin_attribute *attr, +qlcnic_sysfs_write_mem(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t offset, size_t size) { struct device *dev = container_of(kobj, struct device, kobj); diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c index 6ecbfb27db9d..e525263210ee 100644 --- a/drivers/pci/hotplug/acpiphp_ibm.c +++ b/drivers/pci/hotplug/acpiphp_ibm.c @@ -108,7 +108,7 @@ static int ibm_set_attention_status(struct hotplug_slot *slot, u8 status); static int ibm_get_attention_status(struct hotplug_slot *slot, u8 *status); static void ibm_handle_events(acpi_handle handle, u32 event, void *context); static int ibm_get_table_from_acpi(char **bufp); -static ssize_t ibm_read_apci_table(struct kobject *kobj, +static ssize_t ibm_read_apci_table(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buffer, loff_t pos, size_t size); static acpi_status __init ibm_find_acpi_device(acpi_handle handle, @@ -351,6 +351,7 @@ read_table_done: /** * ibm_read_apci_table - callback for the sysfs apci_table file + * @filp: the open sysfs file * @kobj: the kobject this binary attribute is a part of * @bin_attr: struct bin_attribute for this file * @buffer: the kernel space buffer to fill @@ -364,7 +365,7 @@ read_table_done: * things get really tricky here... * our solution is to only allow reading the table in all at once. */ -static ssize_t ibm_read_apci_table(struct kobject *kobj, +static ssize_t ibm_read_apci_table(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buffer, loff_t pos, size_t size) { diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index fad93983bfed..ad44557e65c4 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -357,7 +357,8 @@ boot_vga_show(struct device *dev, struct device_attribute *attr, char *buf) struct device_attribute vga_attr = __ATTR_RO(boot_vga); static ssize_t -pci_read_config(struct kobject *kobj, struct bin_attribute *bin_attr, +pci_read_config(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct pci_dev *dev = to_pci_dev(container_of(kobj,struct device,kobj)); @@ -430,7 +431,8 @@ pci_read_config(struct kobject *kobj, struct bin_attribute *bin_attr, } static ssize_t -pci_write_config(struct kobject *kobj, struct bin_attribute *bin_attr, +pci_write_config(struct file* filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct pci_dev *dev = to_pci_dev(container_of(kobj,struct device,kobj)); @@ -487,7 +489,8 @@ pci_write_config(struct kobject *kobj, struct bin_attribute *bin_attr, } static ssize_t -read_vpd_attr(struct kobject *kobj, struct bin_attribute *bin_attr, +read_vpd_attr(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct pci_dev *dev = @@ -502,7 +505,8 @@ read_vpd_attr(struct kobject *kobj, struct bin_attribute *bin_attr, } static ssize_t -write_vpd_attr(struct kobject *kobj, struct bin_attribute *bin_attr, +write_vpd_attr(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct pci_dev *dev = @@ -519,6 +523,7 @@ write_vpd_attr(struct kobject *kobj, struct bin_attribute *bin_attr, #ifdef HAVE_PCI_LEGACY /** * pci_read_legacy_io - read byte(s) from legacy I/O port space + * @filp: open sysfs file * @kobj: kobject corresponding to file to read from * @bin_attr: struct bin_attribute for this file * @buf: buffer to store results @@ -529,7 +534,8 @@ write_vpd_attr(struct kobject *kobj, struct bin_attribute *bin_attr, * callback routine (pci_legacy_read). */ static ssize_t -pci_read_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr, +pci_read_legacy_io(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct pci_bus *bus = to_pci_bus(container_of(kobj, @@ -545,6 +551,7 @@ pci_read_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr, /** * pci_write_legacy_io - write byte(s) to legacy I/O port space + * @filp: open sysfs file * @kobj: kobject corresponding to file to read from * @bin_attr: struct bin_attribute for this file * @buf: buffer containing value to be written @@ -555,7 +562,8 @@ pci_read_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr, * callback routine (pci_legacy_write). */ static ssize_t -pci_write_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr, +pci_write_legacy_io(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct pci_bus *bus = to_pci_bus(container_of(kobj, @@ -570,6 +578,7 @@ pci_write_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr, /** * pci_mmap_legacy_mem - map legacy PCI memory into user memory space + * @filp: open sysfs file * @kobj: kobject corresponding to device to be mapped * @attr: struct bin_attribute for this file * @vma: struct vm_area_struct passed to mmap @@ -579,7 +588,8 @@ pci_write_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr, * memory space. */ static int -pci_mmap_legacy_mem(struct kobject *kobj, struct bin_attribute *attr, +pci_mmap_legacy_mem(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, struct vm_area_struct *vma) { struct pci_bus *bus = to_pci_bus(container_of(kobj, @@ -591,6 +601,7 @@ pci_mmap_legacy_mem(struct kobject *kobj, struct bin_attribute *attr, /** * pci_mmap_legacy_io - map legacy PCI IO into user memory space + * @filp: open sysfs file * @kobj: kobject corresponding to device to be mapped * @attr: struct bin_attribute for this file * @vma: struct vm_area_struct passed to mmap @@ -600,7 +611,8 @@ pci_mmap_legacy_mem(struct kobject *kobj, struct bin_attribute *attr, * memory space. Returns -ENOSYS if the operation isn't supported */ static int -pci_mmap_legacy_io(struct kobject *kobj, struct bin_attribute *attr, +pci_mmap_legacy_io(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, struct vm_area_struct *vma) { struct pci_bus *bus = to_pci_bus(container_of(kobj, @@ -750,14 +762,16 @@ pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, } static int -pci_mmap_resource_uc(struct kobject *kobj, struct bin_attribute *attr, +pci_mmap_resource_uc(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, struct vm_area_struct *vma) { return pci_mmap_resource(kobj, attr, vma, 0); } static int -pci_mmap_resource_wc(struct kobject *kobj, struct bin_attribute *attr, +pci_mmap_resource_wc(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, struct vm_area_struct *vma) { return pci_mmap_resource(kobj, attr, vma, 1); @@ -861,6 +875,7 @@ void __weak pci_remove_resource_files(struct pci_dev *dev) { return; } /** * pci_write_rom - used to enable access to the PCI ROM display + * @filp: sysfs file * @kobj: kernel object handle * @bin_attr: struct bin_attribute for this file * @buf: user input @@ -870,7 +885,8 @@ void __weak pci_remove_resource_files(struct pci_dev *dev) { return; } * writing anything except 0 enables it */ static ssize_t -pci_write_rom(struct kobject *kobj, struct bin_attribute *bin_attr, +pci_write_rom(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct pci_dev *pdev = to_pci_dev(container_of(kobj, struct device, kobj)); @@ -885,6 +901,7 @@ pci_write_rom(struct kobject *kobj, struct bin_attribute *bin_attr, /** * pci_read_rom - read a PCI ROM + * @filp: sysfs file * @kobj: kernel object handle * @bin_attr: struct bin_attribute for this file * @buf: where to put the data we read from the ROM @@ -895,7 +912,8 @@ pci_write_rom(struct kobject *kobj, struct bin_attribute *bin_attr, * device corresponding to @kobj. */ static ssize_t -pci_read_rom(struct kobject *kobj, struct bin_attribute *bin_attr, +pci_read_rom(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct pci_dev *pdev = to_pci_dev(container_of(kobj, struct device, kobj)); diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c index 60d428be0b07..8844bc3e3118 100644 --- a/drivers/pcmcia/cistpl.c +++ b/drivers/pcmcia/cistpl.c @@ -1531,7 +1531,7 @@ static ssize_t pccard_extract_cis(struct pcmcia_socket *s, char *buf, } -static ssize_t pccard_show_cis(struct kobject *kobj, +static ssize_t pccard_show_cis(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -1562,7 +1562,7 @@ static ssize_t pccard_show_cis(struct kobject *kobj, } -static ssize_t pccard_store_cis(struct kobject *kobj, +static ssize_t pccard_store_cis(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { diff --git a/drivers/power/olpc_battery.c b/drivers/power/olpc_battery.c index 8fefe5a73558..baefcf1cffc9 100644 --- a/drivers/power/olpc_battery.c +++ b/drivers/power/olpc_battery.c @@ -354,7 +354,7 @@ static enum power_supply_property olpc_bat_props[] = { #define EEPROM_END 0x80 #define EEPROM_SIZE (EEPROM_END - EEPROM_START) -static ssize_t olpc_bat_eeprom_read(struct kobject *kobj, +static ssize_t olpc_bat_eeprom_read(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { uint8_t ec_byte; diff --git a/drivers/rapidio/rio-sysfs.c b/drivers/rapidio/rio-sysfs.c index ba742e82c57d..00b475658356 100644 --- a/drivers/rapidio/rio-sysfs.c +++ b/drivers/rapidio/rio-sysfs.c @@ -68,7 +68,8 @@ struct device_attribute rio_dev_attrs[] = { }; static ssize_t -rio_read_config(struct kobject *kobj, struct bin_attribute *bin_attr, +rio_read_config(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct rio_dev *dev = @@ -139,7 +140,8 @@ rio_read_config(struct kobject *kobj, struct bin_attribute *bin_attr, } static ssize_t -rio_write_config(struct kobject *kobj, struct bin_attribute *bin_attr, +rio_write_config(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct rio_dev *dev = diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index e9aa814ddd23..ece4dbddc0ea 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -519,7 +519,8 @@ static const struct rtc_class_ops cmos_rtc_ops = { #define NVRAM_OFFSET (RTC_REG_D + 1) static ssize_t -cmos_nvram_read(struct kobject *kobj, struct bin_attribute *attr, +cmos_nvram_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t off, size_t count) { int retval; @@ -547,7 +548,8 @@ cmos_nvram_read(struct kobject *kobj, struct bin_attribute *attr, } static ssize_t -cmos_nvram_write(struct kobject *kobj, struct bin_attribute *attr, +cmos_nvram_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t off, size_t count) { struct cmos_rtc *cmos; diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c index 7836c9cec557..48da85e97ca4 100644 --- a/drivers/rtc/rtc-ds1305.c +++ b/drivers/rtc/rtc-ds1305.c @@ -542,7 +542,8 @@ static void msg_init(struct spi_message *m, struct spi_transfer *x, } static ssize_t -ds1305_nvram_read(struct kobject *kobj, struct bin_attribute *attr, +ds1305_nvram_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t off, size_t count) { struct spi_device *spi; @@ -572,7 +573,8 @@ ds1305_nvram_read(struct kobject *kobj, struct bin_attribute *attr, } static ssize_t -ds1305_nvram_write(struct kobject *kobj, struct bin_attribute *attr, +ds1305_nvram_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t off, size_t count) { struct spi_device *spi; diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index c4ec5c158aa1..de033b7ac21f 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -556,7 +556,8 @@ static const struct rtc_class_ops ds13xx_rtc_ops = { #define NVRAM_SIZE 56 static ssize_t -ds1307_nvram_read(struct kobject *kobj, struct bin_attribute *attr, +ds1307_nvram_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t off, size_t count) { struct i2c_client *client; @@ -580,7 +581,8 @@ ds1307_nvram_read(struct kobject *kobj, struct bin_attribute *attr, } static ssize_t -ds1307_nvram_write(struct kobject *kobj, struct bin_attribute *attr, +ds1307_nvram_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t off, size_t count) { struct i2c_client *client; diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c index 06b8566c4532..37268e97de49 100644 --- a/drivers/rtc/rtc-ds1511.c +++ b/drivers/rtc/rtc-ds1511.c @@ -423,8 +423,9 @@ static const struct rtc_class_ops ds1511_rtc_ops = { }; static ssize_t -ds1511_nvram_read(struct kobject *kobj, struct bin_attribute *ba, - char *buf, loff_t pos, size_t size) +ds1511_nvram_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *ba, + char *buf, loff_t pos, size_t size) { ssize_t count; @@ -452,8 +453,9 @@ ds1511_nvram_read(struct kobject *kobj, struct bin_attribute *ba, } static ssize_t -ds1511_nvram_write(struct kobject *kobj, struct bin_attribute *bin_attr, - char *buf, loff_t pos, size_t size) +ds1511_nvram_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t pos, size_t size) { ssize_t count; diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c index 244f9994bcbb..ff432e2ca275 100644 --- a/drivers/rtc/rtc-ds1553.c +++ b/drivers/rtc/rtc-ds1553.c @@ -252,7 +252,7 @@ static const struct rtc_class_ops ds1553_rtc_ops = { .update_irq_enable = ds1553_rtc_update_irq_enable, }; -static ssize_t ds1553_nvram_read(struct kobject *kobj, +static ssize_t ds1553_nvram_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t size) { @@ -267,7 +267,7 @@ static ssize_t ds1553_nvram_read(struct kobject *kobj, return count; } -static ssize_t ds1553_nvram_write(struct kobject *kobj, +static ssize_t ds1553_nvram_write(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t size) { diff --git a/drivers/rtc/rtc-ds1742.c b/drivers/rtc/rtc-ds1742.c index 2b4b0bc42d6f..042630c90dd3 100644 --- a/drivers/rtc/rtc-ds1742.c +++ b/drivers/rtc/rtc-ds1742.c @@ -128,7 +128,7 @@ static const struct rtc_class_ops ds1742_rtc_ops = { .set_time = ds1742_rtc_set_time, }; -static ssize_t ds1742_nvram_read(struct kobject *kobj, +static ssize_t ds1742_nvram_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t size) { @@ -143,7 +143,7 @@ static ssize_t ds1742_nvram_read(struct kobject *kobj, return count; } -static ssize_t ds1742_nvram_write(struct kobject *kobj, +static ssize_t ds1742_nvram_write(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t size) { diff --git a/drivers/rtc/rtc-m48t59.c b/drivers/rtc/rtc-m48t59.c index 365ff3ac2348..be8359fdb65a 100644 --- a/drivers/rtc/rtc-m48t59.c +++ b/drivers/rtc/rtc-m48t59.c @@ -343,7 +343,7 @@ static const struct rtc_class_ops m48t02_rtc_ops = { .set_time = m48t59_rtc_set_time, }; -static ssize_t m48t59_nvram_read(struct kobject *kobj, +static ssize_t m48t59_nvram_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t size) { @@ -363,7 +363,7 @@ static ssize_t m48t59_nvram_read(struct kobject *kobj, return cnt; } -static ssize_t m48t59_nvram_write(struct kobject *kobj, +static ssize_t m48t59_nvram_write(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t size) { diff --git a/drivers/rtc/rtc-stk17ta8.c b/drivers/rtc/rtc-stk17ta8.c index b53a00198dbe..3b943673cd3e 100644 --- a/drivers/rtc/rtc-stk17ta8.c +++ b/drivers/rtc/rtc-stk17ta8.c @@ -244,7 +244,7 @@ static const struct rtc_class_ops stk17ta8_rtc_ops = { .alarm_irq_enable = stk17ta8_rtc_alarm_irq_enable, }; -static ssize_t stk17ta8_nvram_read(struct kobject *kobj, +static ssize_t stk17ta8_nvram_read(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t pos, size_t size) { @@ -259,7 +259,7 @@ static ssize_t stk17ta8_nvram_read(struct kobject *kobj, return count; } -static ssize_t stk17ta8_nvram_write(struct kobject *kobj, +static ssize_t stk17ta8_nvram_write(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t pos, size_t size) { diff --git a/drivers/rtc/rtc-tx4939.c b/drivers/rtc/rtc-tx4939.c index 20bfc64a15c8..ec6313d15359 100644 --- a/drivers/rtc/rtc-tx4939.c +++ b/drivers/rtc/rtc-tx4939.c @@ -188,7 +188,7 @@ static const struct rtc_class_ops tx4939_rtc_ops = { .alarm_irq_enable = tx4939_rtc_alarm_irq_enable, }; -static ssize_t tx4939_rtc_nvram_read(struct kobject *kobj, +static ssize_t tx4939_rtc_nvram_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t size) { @@ -207,7 +207,7 @@ static ssize_t tx4939_rtc_nvram_read(struct kobject *kobj, return count; } -static ssize_t tx4939_rtc_nvram_write(struct kobject *kobj, +static ssize_t tx4939_rtc_nvram_write(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t size) { diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c index 1d16189f2f2d..6c9fa15aac7b 100644 --- a/drivers/s390/cio/chp.c +++ b/drivers/s390/cio/chp.c @@ -135,7 +135,8 @@ static int s390_vary_chpid(struct chp_id chpid, int on) /* * Channel measurement related functions */ -static ssize_t chp_measurement_chars_read(struct kobject *kobj, +static ssize_t chp_measurement_chars_read(struct file *filp, + struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -182,7 +183,7 @@ static void chp_measurement_copy_block(struct cmg_entry *buf, } while (reference_buf.values[0] != buf->values[0]); } -static ssize_t chp_measurement_read(struct kobject *kobj, +static ssize_t chp_measurement_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { diff --git a/drivers/scsi/3w-sas.c b/drivers/scsi/3w-sas.c index 54c5ffb1eaa1..d38000db9237 100644 --- a/drivers/scsi/3w-sas.c +++ b/drivers/scsi/3w-sas.c @@ -98,7 +98,7 @@ static int twl_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_res /* Functions */ /* This function returns AENs through sysfs */ -static ssize_t twl_sysfs_aen_read(struct kobject *kobj, +static ssize_t twl_sysfs_aen_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *outbuf, loff_t offset, size_t count) { @@ -129,7 +129,7 @@ static struct bin_attribute twl_sysfs_aen_read_attr = { }; /* This function returns driver compatibility info through sysfs */ -static ssize_t twl_sysfs_compat_info(struct kobject *kobj, +static ssize_t twl_sysfs_compat_info(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *outbuf, loff_t offset, size_t count) { diff --git a/drivers/scsi/arcmsr/arcmsr_attr.c b/drivers/scsi/arcmsr/arcmsr_attr.c index 5877f29a6005..a4e04c50c436 100644 --- a/drivers/scsi/arcmsr/arcmsr_attr.c +++ b/drivers/scsi/arcmsr/arcmsr_attr.c @@ -59,7 +59,8 @@ struct device_attribute *arcmsr_host_attrs[]; -static ssize_t arcmsr_sysfs_iop_message_read(struct kobject *kobj, +static ssize_t arcmsr_sysfs_iop_message_read(struct file *filp, + struct kobject *kobj, struct bin_attribute *bin, char *buf, loff_t off, size_t count) @@ -105,7 +106,8 @@ static ssize_t arcmsr_sysfs_iop_message_read(struct kobject *kobj, return (allxfer_len); } -static ssize_t arcmsr_sysfs_iop_message_write(struct kobject *kobj, +static ssize_t arcmsr_sysfs_iop_message_write(struct file *filp, + struct kobject *kobj, struct bin_attribute *bin, char *buf, loff_t off, size_t count) @@ -153,7 +155,8 @@ static ssize_t arcmsr_sysfs_iop_message_write(struct kobject *kobj, } } -static ssize_t arcmsr_sysfs_iop_message_clear(struct kobject *kobj, +static ssize_t arcmsr_sysfs_iop_message_clear(struct file *filp, + struct kobject *kobj, struct bin_attribute *bin, char *buf, loff_t off, size_t count) diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index d18f45c95639..3eb2b7b3d8b0 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c @@ -2919,6 +2919,7 @@ static DEVICE_ATTR(log_level, S_IRUGO | S_IWUSR, #ifdef CONFIG_SCSI_IBMVFC_TRACE /** * ibmvfc_read_trace - Dump the adapter trace + * @filp: open sysfs file * @kobj: kobject struct * @bin_attr: bin_attribute struct * @buf: buffer @@ -2928,7 +2929,7 @@ static DEVICE_ATTR(log_level, S_IRUGO | S_IWUSR, * Return value: * number of bytes printed to buffer **/ -static ssize_t ibmvfc_read_trace(struct kobject *kobj, +static ssize_t ibmvfc_read_trace(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index b90c118119d7..6a6661c35b2f 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -3120,6 +3120,7 @@ restart: #ifdef CONFIG_SCSI_IPR_TRACE /** * ipr_read_trace - Dump the adapter trace + * @filp: open sysfs file * @kobj: kobject struct * @bin_attr: bin_attribute struct * @buf: buffer @@ -3129,7 +3130,7 @@ restart: * Return value: * number of bytes printed to buffer **/ -static ssize_t ipr_read_trace(struct kobject *kobj, +static ssize_t ipr_read_trace(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -3764,6 +3765,7 @@ static struct device_attribute *ipr_ioa_attrs[] = { #ifdef CONFIG_SCSI_IPR_DUMP /** * ipr_read_dump - Dump the adapter + * @filp: open sysfs file * @kobj: kobject struct * @bin_attr: bin_attribute struct * @buf: buffer @@ -3773,7 +3775,7 @@ static struct device_attribute *ipr_ioa_attrs[] = { * Return value: * number of bytes printed to buffer **/ -static ssize_t ipr_read_dump(struct kobject *kobj, +static ssize_t ipr_read_dump(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -3927,6 +3929,7 @@ static int ipr_free_dump(struct ipr_ioa_cfg *ioa_cfg) /** * ipr_write_dump - Setup dump state of adapter + * @filp: open sysfs file * @kobj: kobject struct * @bin_attr: bin_attribute struct * @buf: buffer @@ -3936,7 +3939,7 @@ static int ipr_free_dump(struct ipr_ioa_cfg *ioa_cfg) * Return value: * number of bytes printed to buffer **/ -static ssize_t ipr_write_dump(struct kobject *kobj, +static ssize_t ipr_write_dump(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 2e5f376d9ccc..bf33b315f93e 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -2643,6 +2643,7 @@ static DEVICE_ATTR(lpfc_stat_data_ctrl, S_IRUGO | S_IWUSR, /** * sysfs_drvr_stat_data_read - Read function for lpfc_drvr_stat_data attribute + * @filp: sysfs file * @kobj: Pointer to the kernel object * @bin_attr: Attribute object * @buff: Buffer pointer @@ -2654,7 +2655,8 @@ static DEVICE_ATTR(lpfc_stat_data_ctrl, S_IRUGO | S_IWUSR, * applications. **/ static ssize_t -sysfs_drvr_stat_data_read(struct kobject *kobj, struct bin_attribute *bin_attr, +sysfs_drvr_stat_data_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct device *dev = container_of(kobj, struct device, @@ -3362,6 +3364,7 @@ struct device_attribute *lpfc_vport_attrs[] = { /** * sysfs_ctlreg_write - Write method for writing to ctlreg + * @filp: open sysfs file * @kobj: kernel kobject that contains the kernel class device. * @bin_attr: kernel attributes passed to us. * @buf: contains the data to be written to the adapter IOREG space. @@ -3379,7 +3382,8 @@ struct device_attribute *lpfc_vport_attrs[] = { * value of count, buf contents written **/ static ssize_t -sysfs_ctlreg_write(struct kobject *kobj, struct bin_attribute *bin_attr, +sysfs_ctlreg_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { size_t buf_off; @@ -3415,6 +3419,7 @@ sysfs_ctlreg_write(struct kobject *kobj, struct bin_attribute *bin_attr, /** * sysfs_ctlreg_read - Read method for reading from ctlreg + * @filp: open sysfs file * @kobj: kernel kobject that contains the kernel class device. * @bin_attr: kernel attributes passed to us. * @buf: if successful contains the data from the adapter IOREG space. @@ -3431,7 +3436,8 @@ sysfs_ctlreg_write(struct kobject *kobj, struct bin_attribute *bin_attr, * value of count, buf contents read **/ static ssize_t -sysfs_ctlreg_read(struct kobject *kobj, struct bin_attribute *bin_attr, +sysfs_ctlreg_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { size_t buf_off; @@ -3496,6 +3502,7 @@ sysfs_mbox_idle(struct lpfc_hba *phba) /** * sysfs_mbox_write - Write method for writing information via mbox + * @filp: open sysfs file * @kobj: kernel kobject that contains the kernel class device. * @bin_attr: kernel attributes passed to us. * @buf: contains the data to be written to sysfs mbox. @@ -3516,7 +3523,8 @@ sysfs_mbox_idle(struct lpfc_hba *phba) * count number of bytes transferred **/ static ssize_t -sysfs_mbox_write(struct kobject *kobj, struct bin_attribute *bin_attr, +sysfs_mbox_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct device *dev = container_of(kobj, struct device, kobj); @@ -3571,6 +3579,7 @@ sysfs_mbox_write(struct kobject *kobj, struct bin_attribute *bin_attr, /** * sysfs_mbox_read - Read method for reading information via mbox + * @filp: open sysfs file * @kobj: kernel kobject that contains the kernel class device. * @bin_attr: kernel attributes passed to us. * @buf: contains the data to be read from sysfs mbox. @@ -3593,7 +3602,8 @@ sysfs_mbox_write(struct kobject *kobj, struct bin_attribute *bin_attr, * count number of bytes transferred **/ static ssize_t -sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr, +sysfs_mbox_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct device *dev = container_of(kobj, struct device, kobj); diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 3b708606b932..1e4cafabba15 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -16,7 +16,7 @@ static int qla24xx_vport_disable(struct fc_vport *, bool); /* SYSFS attributes --------------------------------------------------------- */ static ssize_t -qla2x00_sysfs_read_fw_dump(struct kobject *kobj, +qla2x00_sysfs_read_fw_dump(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -32,7 +32,7 @@ qla2x00_sysfs_read_fw_dump(struct kobject *kobj, } static ssize_t -qla2x00_sysfs_write_fw_dump(struct kobject *kobj, +qla2x00_sysfs_write_fw_dump(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -92,7 +92,7 @@ static struct bin_attribute sysfs_fw_dump_attr = { }; static ssize_t -qla2x00_sysfs_read_nvram(struct kobject *kobj, +qla2x00_sysfs_read_nvram(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -111,7 +111,7 @@ qla2x00_sysfs_read_nvram(struct kobject *kobj, } static ssize_t -qla2x00_sysfs_write_nvram(struct kobject *kobj, +qla2x00_sysfs_write_nvram(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -177,7 +177,7 @@ static struct bin_attribute sysfs_nvram_attr = { }; static ssize_t -qla2x00_sysfs_read_optrom(struct kobject *kobj, +qla2x00_sysfs_read_optrom(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -193,7 +193,7 @@ qla2x00_sysfs_read_optrom(struct kobject *kobj, } static ssize_t -qla2x00_sysfs_write_optrom(struct kobject *kobj, +qla2x00_sysfs_write_optrom(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -224,7 +224,7 @@ static struct bin_attribute sysfs_optrom_attr = { }; static ssize_t -qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj, +qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -387,7 +387,7 @@ static struct bin_attribute sysfs_optrom_ctl_attr = { }; static ssize_t -qla2x00_sysfs_read_vpd(struct kobject *kobj, +qla2x00_sysfs_read_vpd(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -408,7 +408,7 @@ qla2x00_sysfs_read_vpd(struct kobject *kobj, } static ssize_t -qla2x00_sysfs_write_vpd(struct kobject *kobj, +qla2x00_sysfs_write_vpd(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -461,7 +461,7 @@ static struct bin_attribute sysfs_vpd_attr = { }; static ssize_t -qla2x00_sysfs_read_sfp(struct kobject *kobj, +qla2x00_sysfs_read_sfp(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -522,7 +522,7 @@ static struct bin_attribute sysfs_sfp_attr = { }; static ssize_t -qla2x00_sysfs_write_reset(struct kobject *kobj, +qla2x00_sysfs_write_reset(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -592,7 +592,7 @@ static struct bin_attribute sysfs_reset_attr = { }; static ssize_t -qla2x00_sysfs_write_edc(struct kobject *kobj, +qla2x00_sysfs_write_edc(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -650,7 +650,7 @@ static struct bin_attribute sysfs_edc_attr = { }; static ssize_t -qla2x00_sysfs_write_edc_status(struct kobject *kobj, +qla2x00_sysfs_write_edc_status(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -700,7 +700,7 @@ qla2x00_sysfs_write_edc_status(struct kobject *kobj, } static ssize_t -qla2x00_sysfs_read_edc_status(struct kobject *kobj, +qla2x00_sysfs_read_edc_status(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -730,7 +730,7 @@ static struct bin_attribute sysfs_edc_status_attr = { }; static ssize_t -qla2x00_sysfs_read_xgmac_stats(struct kobject *kobj, +qla2x00_sysfs_read_xgmac_stats(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -782,7 +782,7 @@ static struct bin_attribute sysfs_xgmac_stats_attr = { }; static ssize_t -qla2x00_sysfs_read_dcbx_tlv(struct kobject *kobj, +qla2x00_sysfs_read_dcbx_tlv(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { diff --git a/drivers/staging/udlfb/udlfb.c b/drivers/staging/udlfb/udlfb.c index aa8195199a2c..577f2bf6eb23 100644 --- a/drivers/staging/udlfb/udlfb.c +++ b/drivers/staging/udlfb/udlfb.c @@ -1063,7 +1063,8 @@ static ssize_t metrics_misc_show(struct device *fbdev, atomic_read(&dev->lost_pixels) ? "yes" : "no"); } -static ssize_t edid_show(struct kobject *kobj, struct bin_attribute *a, +static ssize_t edid_show(struct file *filp, struct kobject *kobj, + struct bin_attribute *a, char *buf, loff_t off, size_t count) { struct device *fbdev = container_of(kobj, struct device, kobj); struct fb_info *fb_info = dev_get_drvdata(fbdev); diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 06863befaf3a..448f5b47fc48 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -658,7 +658,8 @@ const struct attribute_group *usb_device_groups[] = { /* Binary descriptors */ static ssize_t -read_descriptors(struct kobject *kobj, struct bin_attribute *attr, +read_descriptors(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t off, size_t count) { struct device *dev = container_of(kobj, struct device, kobj); diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c index 6c37e8ee5efe..3c1e13ed1cba 100644 --- a/drivers/video/aty/radeon_base.c +++ b/drivers/video/aty/radeon_base.c @@ -2099,7 +2099,7 @@ static ssize_t radeon_show_one_edid(char *buf, loff_t off, size_t count, const u } -static ssize_t radeon_show_edid1(struct kobject *kobj, +static ssize_t radeon_show_edid1(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -2112,7 +2112,7 @@ static ssize_t radeon_show_edid1(struct kobject *kobj, } -static ssize_t radeon_show_edid2(struct kobject *kobj, +static ssize_t radeon_show_edid2(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { diff --git a/drivers/w1/slaves/w1_ds2431.c b/drivers/w1/slaves/w1_ds2431.c index 2c6c0cf6a20f..84e2410aec1d 100644 --- a/drivers/w1/slaves/w1_ds2431.c +++ b/drivers/w1/slaves/w1_ds2431.c @@ -96,7 +96,7 @@ static int w1_f2d_readblock(struct w1_slave *sl, int off, int count, char *buf) return -1; } -static ssize_t w1_f2d_read_bin(struct kobject *kobj, +static ssize_t w1_f2d_read_bin(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -202,7 +202,7 @@ retry: return 0; } -static ssize_t w1_f2d_write_bin(struct kobject *kobj, +static ssize_t w1_f2d_write_bin(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { diff --git a/drivers/w1/slaves/w1_ds2433.c b/drivers/w1/slaves/w1_ds2433.c index d2bf32118a98..0f7b8f9c509a 100644 --- a/drivers/w1/slaves/w1_ds2433.c +++ b/drivers/w1/slaves/w1_ds2433.c @@ -92,7 +92,7 @@ static int w1_f23_refresh_block(struct w1_slave *sl, struct w1_f23_data *data, } #endif /* CONFIG_W1_SLAVE_DS2433_CRC */ -static ssize_t w1_f23_read_bin(struct kobject *kobj, +static ssize_t w1_f23_read_bin(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -206,7 +206,7 @@ static int w1_f23_write(struct w1_slave *sl, int addr, int len, const u8 *data) return 0; } -static ssize_t w1_f23_write_bin(struct kobject *kobj, +static ssize_t w1_f23_write_bin(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { diff --git a/drivers/w1/slaves/w1_ds2760.c b/drivers/w1/slaves/w1_ds2760.c index 6e153343e117..483d45180911 100644 --- a/drivers/w1/slaves/w1_ds2760.c +++ b/drivers/w1/slaves/w1_ds2760.c @@ -97,7 +97,7 @@ int w1_ds2760_recall_eeprom(struct device *dev, int addr) return w1_ds2760_eeprom_cmd(dev, addr, W1_DS2760_RECALL_DATA); } -static ssize_t w1_ds2760_read_bin(struct kobject *kobj, +static ssize_t w1_ds2760_read_bin(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c index ad5897dc4495..2839e281cd65 100644 --- a/drivers/w1/w1.c +++ b/drivers/w1/w1.c @@ -120,7 +120,7 @@ static struct device_attribute w1_slave_attr_id = /* Default family */ -static ssize_t w1_default_write(struct kobject *kobj, +static ssize_t w1_default_write(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -139,7 +139,7 @@ out_up: return count; } -static ssize_t w1_default_read(struct kobject *kobj, +static ssize_t w1_default_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { diff --git a/drivers/zorro/zorro-sysfs.c b/drivers/zorro/zorro-sysfs.c index eb924e0a64ce..26f7184ef9e1 100644 --- a/drivers/zorro/zorro-sysfs.c +++ b/drivers/zorro/zorro-sysfs.c @@ -49,7 +49,7 @@ static ssize_t zorro_show_resource(struct device *dev, struct device_attribute * static DEVICE_ATTR(resource, S_IRUGO, zorro_show_resource, NULL); -static ssize_t zorro_read_config(struct kobject *kobj, +static ssize_t zorro_read_config(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c index 806b277453f9..4e321f7353fa 100644 --- a/fs/sysfs/bin.c +++ b/fs/sysfs/bin.c @@ -46,9 +46,9 @@ struct bin_buffer { }; static int -fill_read(struct dentry *dentry, char *buffer, loff_t off, size_t count) +fill_read(struct file *file, char *buffer, loff_t off, size_t count) { - struct sysfs_dirent *attr_sd = dentry->d_fsdata; + struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; struct bin_attribute *attr = attr_sd->s_bin_attr.bin_attr; struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; int rc; @@ -59,7 +59,7 @@ fill_read(struct dentry *dentry, char *buffer, loff_t off, size_t count) rc = -EIO; if (attr->read) - rc = attr->read(kobj, attr, buffer, off, count); + rc = attr->read(file, kobj, attr, buffer, off, count); sysfs_put_active(attr_sd); @@ -70,8 +70,7 @@ static ssize_t read(struct file *file, char __user *userbuf, size_t bytes, loff_t *off) { struct bin_buffer *bb = file->private_data; - struct dentry *dentry = file->f_path.dentry; - int size = dentry->d_inode->i_size; + int size = file->f_path.dentry->d_inode->i_size; loff_t offs = *off; int count = min_t(size_t, bytes, PAGE_SIZE); char *temp; @@ -92,7 +91,7 @@ read(struct file *file, char __user *userbuf, size_t bytes, loff_t *off) mutex_lock(&bb->mutex); - count = fill_read(dentry, bb->buffer, offs, count); + count = fill_read(file, bb->buffer, offs, count); if (count < 0) { mutex_unlock(&bb->mutex); goto out_free; @@ -117,9 +116,9 @@ read(struct file *file, char __user *userbuf, size_t bytes, loff_t *off) } static int -flush_write(struct dentry *dentry, char *buffer, loff_t offset, size_t count) +flush_write(struct file *file, char *buffer, loff_t offset, size_t count) { - struct sysfs_dirent *attr_sd = dentry->d_fsdata; + struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; struct bin_attribute *attr = attr_sd->s_bin_attr.bin_attr; struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; int rc; @@ -130,7 +129,7 @@ flush_write(struct dentry *dentry, char *buffer, loff_t offset, size_t count) rc = -EIO; if (attr->write) - rc = attr->write(kobj, attr, buffer, offset, count); + rc = attr->write(file, kobj, attr, buffer, offset, count); sysfs_put_active(attr_sd); @@ -141,8 +140,7 @@ static ssize_t write(struct file *file, const char __user *userbuf, size_t bytes, loff_t *off) { struct bin_buffer *bb = file->private_data; - struct dentry *dentry = file->f_path.dentry; - int size = dentry->d_inode->i_size; + int size = file->f_path.dentry->d_inode->i_size; loff_t offs = *off; int count = min_t(size_t, bytes, PAGE_SIZE); char *temp; @@ -165,7 +163,7 @@ static ssize_t write(struct file *file, const char __user *userbuf, memcpy(bb->buffer, temp, count); - count = flush_write(dentry, bb->buffer, offs, count); + count = flush_write(file, bb->buffer, offs, count); mutex_unlock(&bb->mutex); if (count > 0) @@ -363,7 +361,7 @@ static int mmap(struct file *file, struct vm_area_struct *vma) if (!attr->mmap) goto out_put; - rc = attr->mmap(kobj, attr, vma); + rc = attr->mmap(file, kobj, attr, vma); if (rc) goto out_put; diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index 6903e9204032..f2694eb4dd3d 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -87,17 +87,18 @@ struct attribute_group { #define attr_name(_attr) (_attr).attr.name +struct file; struct vm_area_struct; struct bin_attribute { struct attribute attr; size_t size; void *private; - ssize_t (*read)(struct kobject *, struct bin_attribute *, + ssize_t (*read)(struct file *, struct kobject *, struct bin_attribute *, char *, loff_t, size_t); - ssize_t (*write)(struct kobject *, struct bin_attribute *, + ssize_t (*write)(struct file *,struct kobject *, struct bin_attribute *, char *, loff_t, size_t); - int (*mmap)(struct kobject *, struct bin_attribute *attr, + int (*mmap)(struct file *, struct kobject *, struct bin_attribute *attr, struct vm_area_struct *vma); }; diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c index 21fe3c426948..0b624e791805 100644 --- a/kernel/ksysfs.c +++ b/kernel/ksysfs.c @@ -138,7 +138,8 @@ extern const void __start_notes __attribute__((weak)); extern const void __stop_notes __attribute__((weak)); #define notes_size (&__stop_notes - &__start_notes) -static ssize_t notes_read(struct kobject *kobj, struct bin_attribute *bin_attr, +static ssize_t notes_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { memcpy(buf, &__start_notes + off, count); diff --git a/kernel/module.c b/kernel/module.c index e2564580f3f1..5e14483768bb 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -1182,7 +1182,7 @@ struct module_notes_attrs { struct bin_attribute attrs[0]; }; -static ssize_t module_notes_read(struct kobject *kobj, +static ssize_t module_notes_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t count) { diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c index dd321e39e621..486b8f3861d2 100644 --- a/net/bridge/br_sysfs_br.c +++ b/net/bridge/br_sysfs_br.c @@ -659,7 +659,7 @@ static struct attribute_group bridge_group = { * * Returns the number of bytes read. */ -static ssize_t brforward_read(struct kobject *kobj, +static ssize_t brforward_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { -- cgit v1.2.3