From: Dominik Brodowski 01-move-and-remove-stuff Move pcmcia_{de,}register_client() from cs.c to ds.c, and remove the unused pcmcia_get_{first,next}_client() calls -- they would be an unnecessary hassle to deal with in the next patches. 02-license As discussed previously, my integration of ds.c and cs.c with the driver model can and will only be available under the GPL, as it's too much derived of other buses' implementation of integration with the driver model. cs_internal.h did only contain the MPL header before - I contacted Dave Hinds because of this, and as far as he can tell, it was just an oversight that this was not marked as dual-licensed as the other files are. 03-ds-kref Switch pcmcia_bus_socket's reference counting to struct kref. Also, split the access by number into two calls, so that get_bus_socket can be used in a more generic way. 04-cs-class_dev Add pcmcia_{put,get}_socket 05-ds-grab-cs-ref Grab a reference of struct pcmcia_socket for every struct pcmcia_bus_socket. 06-ds-get-ref-for-p_dev Obtain a reference to struct pcmcia_bus_socket for each pcmcia_device. This means that pcmcia_device always holds an indirect reference to struct pcmcia_socket as well. 07-p_dev-client-pointer Add a pointer to the "client" structure to struct pcmcia_device. 08-send_event-p_dev Use a struct pcmcia_device-based approach to inform "clients" of events. It needs to be done using bus_for_each_device() so that we don't need to take the device_list spinlock. 09-removal-p_dev Use pcmcia_dev instead of the "client" single-linked list to mark clients as stale. 10-move-inside-ds Move some code around in ds.c. Avoids forward-declarations, and keeps related code close to each other. 11-register_client-p_dev Search the devices_list for an UNBOUND client in register_client, instead of the single linked list clients. 12-direct_ordered_unbind Restructure unbind_request(): Before, unbind_request was called by cardmgr on the following occasions: a) if the CS_EVENT_CARD_INSERTION event failed b) during do_remove(), which is called on 1) when cardmgr is informed of a CS_EVENT_CARD_REMOVAL event 2) when cardmgr is informed of a CS_EVENT_EJECTION_REQUEST event, if do_check() succeeds 3) cardmgr exit (SIGINT/SIGTERM), if do_check() succeeds We can ignore a), as the user is informed of the problem anyway, and can take appropriate action then (eject the card, update config, write new driver, insert card...). b1) can be done directly, even before the userspace cardmgr is informed. This speeds up the call to ->detach(). b2) All drivers I checked were based on the assumption that a CS_EVENT_CARD_REMOVAL event is received _first_, before a call to ->detach(). Most notably, some drivers issue first a call to their release() function [which else is called during EVENT_CARD_REMOVAL] during ->detach() if it hasn't been issued before. So, it doesn't hurt if unbind is only called during the EVENT_CARD_REMOVAL step, and not during EJECTION_REQUEST. The REMOVAL step is only called anyway if EJECTION_REQUEST succeeds, and the latter can only succeed if do_check() succeeds. b3) If cardmgr exits, ds_release() is called. We can check for any 16-bit devices there, and call a CARD_REMOVAL event there. Only difference is that a failure of do_check() does not block CARD_REMOVAL. IMHO this is accepatble. Consequences: - call unbind_request during CARD_REMOVAL handling, even before userspace is informed. - return "0" if UNBIND_REQUEST is called from userspace. - clean up 16-bit pcmcia devices existing during cardmgr exit - the driver's event handler is called with CARD_REMOVAL _always_ before ->detach() is called. Signed-off-by: Dominik Brodowski Signed-off-by: Andrew Morton --- 25-akpm/drivers/pcmcia/bulkmem.c | 45 +--- 25-akpm/drivers/pcmcia/cardbus.c | 45 +--- 25-akpm/drivers/pcmcia/cistpl.c | 45 +--- 25-akpm/drivers/pcmcia/cs.c | 256 ++++----------------------- 25-akpm/drivers/pcmcia/cs_internal.h | 18 - 25-akpm/drivers/pcmcia/ds.c | 329 +++++++++++++++++++++++++++++------ 25-akpm/drivers/pcmcia/rsrc_mgr.c | 45 +--- 25-akpm/include/pcmcia/bulkmem.h | 28 -- 25-akpm/include/pcmcia/ciscode.h | 25 -- 25-akpm/include/pcmcia/cisreg.h | 25 -- 25-akpm/include/pcmcia/cistpl.h | 25 -- 25-akpm/include/pcmcia/cs.h | 28 -- 25-akpm/include/pcmcia/cs_types.h | 25 -- 25-akpm/include/pcmcia/ds.h | 2 25-akpm/include/pcmcia/mem_op.h | 25 -- 25-akpm/include/pcmcia/ss.h | 25 -- 16 files changed, 419 insertions(+), 572 deletions(-) diff -puN drivers/pcmcia/bulkmem.c~pcmcia-18a-client_t-and-pcmcia_device-integration drivers/pcmcia/bulkmem.c --- 25/drivers/pcmcia/bulkmem.c~pcmcia-18a-client_t-and-pcmcia_device-integration Wed Nov 3 16:11:54 2004 +++ 25-akpm/drivers/pcmcia/bulkmem.c Wed Nov 3 16:11:54 2004 @@ -1,35 +1,16 @@ -/*====================================================================== - - PCMCIA Bulk Memory Services - - bulkmem.c 1.38 2000/09/25 19:29:51 - - The contents of this file are subject to the Mozilla Public - License Version 1.1 (the "License"); you may not use this file - except in compliance with the License. You may obtain a copy of - the License at http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS - IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - implied. See the License for the specific language governing - rights and limitations under the License. - - 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. - - Alternatively, the contents of this file may be used under the - terms of the GNU General Public License version 2 (the "GPL"), in which - case the provisions of the GPL are applicable instead of the - above. If you wish to allow the use of your version of this file - only under the terms of the GPL and not to allow others to use - your version of this file under the MPL, indicate your decision - by deleting the provisions above and replace them with the notice - and other provisions required by the GPL. If you do not delete - the provisions above, a recipient may use your version of this - file under either the MPL or the GPL. - -======================================================================*/ +/* + * bulkmem.c -- 16-bit PCMCIA Bulk Memory Services + * + * 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 diff -puN drivers/pcmcia/cardbus.c~pcmcia-18a-client_t-and-pcmcia_device-integration drivers/pcmcia/cardbus.c --- 25/drivers/pcmcia/cardbus.c~pcmcia-18a-client_t-and-pcmcia_device-integration Wed Nov 3 16:11:54 2004 +++ 25-akpm/drivers/pcmcia/cardbus.c Wed Nov 3 16:11:54 2004 @@ -1,35 +1,16 @@ -/*====================================================================== - - Cardbus device configuration - - cardbus.c 1.87 2002/10/24 06:11:41 - - The contents of this file are subject to the Mozilla Public - License Version 1.1 (the "License"); you may not use this file - except in compliance with the License. You may obtain a copy of - the License at http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS - IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - implied. See the License for the specific language governing - rights and limitations under the License. - - 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. - - Alternatively, the contents of this file may be used under the - terms of the GNU General Public License version 2 (the "GPL"), in which - case the provisions of the GPL are applicable instead of the - above. If you wish to allow the use of your version of this file - only under the terms of the GPL and not to allow others to use - your version of this file under the MPL, indicate your decision - by deleting the provisions above and replace them with the notice - and other provisions required by the GPL. If you do not delete - the provisions above, a recipient may use your version of this - file under either the MPL or the GPL. - -======================================================================*/ +/* + * cardbus.c -- 16-bit PCMCIA core support + * + * 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 + */ /* * Cardbus handling has been re-written to be more of a PCI bridge thing, diff -puN drivers/pcmcia/cistpl.c~pcmcia-18a-client_t-and-pcmcia_device-integration drivers/pcmcia/cistpl.c --- 25/drivers/pcmcia/cistpl.c~pcmcia-18a-client_t-and-pcmcia_device-integration Wed Nov 3 16:11:54 2004 +++ 25-akpm/drivers/pcmcia/cistpl.c Wed Nov 3 16:11:54 2004 @@ -1,35 +1,16 @@ -/*====================================================================== - - PCMCIA Card Information Structure parser - - cistpl.c 1.99 2002/10/24 06:11:48 - - The contents of this file are subject to the Mozilla Public - License Version 1.1 (the "License"); you may not use this file - except in compliance with the License. You may obtain a copy of - the License at http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS - IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - implied. See the License for the specific language governing - rights and limitations under the License. - - 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. - - Alternatively, the contents of this file may be used under the - terms of the GNU General Public License version 2 (the "GPL"), in - which case the provisions of the GPL are applicable instead of the - above. If you wish to allow the use of your version of this file - only under the terms of the GPL and not to allow others to use - your version of this file under the MPL, indicate your decision - by deleting the provisions above and replace them with the notice - and other provisions required by the GPL. If you do not delete - the provisions above, a recipient may use your version of this - file under either the MPL or the GPL. - -======================================================================*/ +/* + * cistpl.c -- 16-bit PCMCIA Card Information Structure parser + * + * 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 diff -puN drivers/pcmcia/cs.c~pcmcia-18a-client_t-and-pcmcia_device-integration drivers/pcmcia/cs.c --- 25/drivers/pcmcia/cs.c~pcmcia-18a-client_t-and-pcmcia_device-integration Wed Nov 3 16:11:54 2004 +++ 25-akpm/drivers/pcmcia/cs.c Wed Nov 3 16:11:54 2004 @@ -1,35 +1,16 @@ -/*====================================================================== - - Kernel Card Services -- core services - - cs.c 1.271 2000/10/02 20:27:49 - - The contents of this file are subject to the Mozilla Public - License Version 1.1 (the "License"); you may not use this file - except in compliance with the License. You may obtain a copy of - the License at http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS - IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - implied. See the License for the specific language governing - rights and limitations under the License. - - 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. - - Alternatively, the contents of this file may be used under the - terms of the GNU General Public License version 2 (the "GPL"), in which - case the provisions of the GPL are applicable instead of the - above. If you wish to allow the use of your version of this file - only under the terms of the GPL and not to allow others to use - your version of this file under the MPL, indicate your decision - by deleting the provisions above and replace them with the notice - and other provisions required by the GPL. If you do not delete - the provisions above, a recipient may use your version of this - file under either the MPL or the GPL. - -======================================================================*/ +/* + * cs.c -- Kernel Card Services - core services + * + * 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 @@ -92,7 +73,7 @@ static const char *options = "options: " MODULE_AUTHOR("David Hinds "); MODULE_DESCRIPTION("Linux Kernel Card Services\noptions:" OPTIONS); -MODULE_LICENSE("Dual MPL/GPL"); +MODULE_LICENSE("GPL"); #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444) @@ -132,6 +113,8 @@ socket_state_t dead_socket = { /* List of all sockets, protected by a rwsem */ LIST_HEAD(pcmcia_socket_list); DECLARE_RWSEM(pcmcia_socket_list_rwsem); +EXPORT_SYMBOL(pcmcia_socket_list); +EXPORT_SYMBOL(pcmcia_socket_list_rwsem); /*==================================================================== @@ -189,6 +172,29 @@ int pcmcia_socket_dev_resume(struct devi EXPORT_SYMBOL(pcmcia_socket_dev_resume); +struct pcmcia_socket * pcmcia_get_socket(struct pcmcia_socket *skt) +{ + struct class_device *cl_dev = class_device_get(&skt->dev); + if (!cl_dev) + return NULL; + skt = class_get_devdata(cl_dev); + if (!try_module_get(skt->owner)) { + class_device_put(&skt->dev); + return NULL; + } + return (skt); +} +EXPORT_SYMBOL(pcmcia_get_socket); + + +void pcmcia_put_socket(struct pcmcia_socket *skt) +{ + module_put(skt->owner); + class_device_put(&skt->dev); +} +EXPORT_SYMBOL(pcmcia_put_socket); + + static void pcmcia_release_socket(struct class_device *class_dev) { struct pcmcia_socket *socket = class_get_devdata(class_dev); @@ -393,8 +399,9 @@ static void shutdown_socket(struct pcmci /*====================================================================== - The central event handler. Send_event() sends an event to all - valid clients. Parse_events() interprets the event bits from + The central event handler. Send_event() sends an event to the + 16-bit subsystem, which then calls the relevant device drivers. + Parse_events() interprets the event bits from a card status change report. Do_shutdown() handles the high priority stuff associated with a card removal. @@ -427,15 +434,9 @@ static int send_event(struct pcmcia_sock static void socket_remove_drivers(struct pcmcia_socket *skt) { - client_t *client; - cs_dbg(skt, 4, "remove_drivers\n"); send_event(skt, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH); - - for (client = skt->clients; client; client = client->next) - if (!(client->Attributes & INFO_MASTER_CLIENT)) - client->state |= CLIENT_STALE; } static void socket_shutdown(struct pcmcia_socket *skt) @@ -890,49 +891,6 @@ int pccard_access_configuration_register } /* access_configuration_register */ EXPORT_SYMBOL(pccard_access_configuration_register); -/*====================================================================*/ - -int pcmcia_deregister_client(client_handle_t handle) -{ - client_t **client; - struct pcmcia_socket *s; - u_long flags; - int i; - - if (CHECK_HANDLE(handle)) - return CS_BAD_HANDLE; - - s = SOCKET(handle); - cs_dbg(s, 1, "deregister_client(%p)\n", handle); - - if (handle->state & - (CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED)) - return CS_IN_USE; - for (i = 0; i < MAX_WIN; i++) - if (handle->state & CLIENT_WIN_REQ(i)) - return CS_IN_USE; - - if ((handle->state & CLIENT_STALE) || - (handle->Attributes & INFO_MASTER_CLIENT)) { - spin_lock_irqsave(&s->lock, flags); - client = &s->clients; - while ((*client) && ((*client) != handle)) - client = &(*client)->next; - if (*client == NULL) { - spin_unlock_irqrestore(&s->lock, flags); - return CS_BAD_HANDLE; - } - *client = handle->next; - handle->client_magic = 0; - kfree(handle); - spin_unlock_irqrestore(&s->lock, flags); - } else { - handle->state = CLIENT_UNBOUND; - handle->event_handler = NULL; - } - - return CS_SUCCESS; -} /* deregister_client */ /*====================================================================*/ @@ -1016,53 +974,6 @@ int pcmcia_get_card_services_info(servin return CS_SUCCESS; } /* get_card_services_info */ -#ifdef CONFIG_PCMCIA_OBSOLETE - -/*====================================================================== - - Note that get_first_client() *does* recognize the Socket field - in the request structure. - -======================================================================*/ - -int pcmcia_get_first_client(client_handle_t *handle, client_req_t *req) -{ - socket_t s; - struct pcmcia_socket *socket; - if (req->Attributes & CLIENT_THIS_SOCKET) - s = req->Socket; - else - s = 0; - socket = pcmcia_get_socket_by_nr(s); - if (!socket) - return CS_BAD_SOCKET; - if (socket->clients == NULL) - return CS_NO_MORE_ITEMS; - *handle = socket->clients; - return CS_SUCCESS; -} /* get_first_client */ -EXPORT_SYMBOL(pcmcia_get_first_client); - -/*====================================================================*/ - -int pcmcia_get_next_client(client_handle_t *handle, client_req_t *req) -{ - struct pcmcia_socket *s; - if ((handle == NULL) || CHECK_HANDLE(*handle)) - return CS_BAD_HANDLE; - if ((*handle)->next == NULL) { - if (req->Attributes & CLIENT_THIS_SOCKET) - return CS_NO_MORE_ITEMS; - s = (*handle)->Socket; - if (s->clients == NULL) - return CS_NO_MORE_ITEMS; - *handle = s->clients; - } else - *handle = (*handle)->next; - return CS_SUCCESS; -} /* get_next_client */ -EXPORT_SYMBOL(pcmcia_get_next_client); -#endif /* CONFIG_PCMCIA_OBSOLETE */ /*====================================================================*/ @@ -1284,87 +1195,6 @@ EXPORT_SYMBOL(pcmcia_modify_window); #endif /* CONFIG_PCMCIA_OBSOLETE */ - -/*====================================================================== - - Register_client() uses the dev_info_t handle to match the - caller with a socket. The driver must have already been bound - to a socket with bind_device() -- in fact, bind_device() - allocates the client structure that will be used. - -======================================================================*/ - -int pcmcia_register_client(client_handle_t *handle, client_reg_t *req) -{ - client_t *client = NULL; - struct pcmcia_socket *s; - - /* Look for unbound client with matching dev_info */ - down_read(&pcmcia_socket_list_rwsem); - list_for_each_entry(s, &pcmcia_socket_list, socket_list) { - client = s->clients; - while (client != NULL) { - if ((strcmp(client->dev_info, (char *)req->dev_info) == 0) - && (client->state & CLIENT_UNBOUND)) break; - client = client->next; - } - if (client != NULL) break; - } - up_read(&pcmcia_socket_list_rwsem); - if (client == NULL) - return CS_OUT_OF_RESOURCE; - - /* - * Prevent this racing with a card insertion. - */ - down(&s->skt_sem); - *handle = client; - client->state &= ~CLIENT_UNBOUND; - client->Socket = s; - client->Attributes = req->Attributes; - client->EventMask = req->EventMask; - client->event_handler = req->event_handler; - client->event_callback_args = req->event_callback_args; - client->event_callback_args.client_handle = client; - - if (s->state & SOCKET_CARDBUS) - client->state |= CLIENT_CARDBUS; - - if ((!(s->state & SOCKET_CARDBUS)) && (s->functions == 0) && - (client->Function != BIND_FN_ALL)) { - cistpl_longlink_mfc_t mfc; - if (pccard_read_tuple(s, client->Function, CISTPL_LONGLINK_MFC, &mfc) - == CS_SUCCESS) - s->functions = mfc.nfn; - else - s->functions = 1; - s->config = kmalloc(sizeof(config_t) * s->functions, - GFP_KERNEL); - if (!s->config) - goto out_no_resource; - memset(s->config, 0, sizeof(config_t) * s->functions); - } - - cs_dbg(s, 1, "register_client(): client 0x%p, dev %s\n", - client, client->dev_info); - if (client->EventMask & CS_EVENT_REGISTRATION_COMPLETE) - EVENT(client, CS_EVENT_REGISTRATION_COMPLETE, CS_EVENT_PRI_LOW); - - if ((s->state & (SOCKET_PRESENT|SOCKET_CARDBUS)) == SOCKET_PRESENT) { - if (client->EventMask & CS_EVENT_CARD_INSERTION) - EVENT(client, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW); - else - client->PendingEvents |= CS_EVENT_CARD_INSERTION; - } - - up(&s->skt_sem); - return CS_SUCCESS; - - out_no_resource: - up(&s->skt_sem); - return CS_OUT_OF_RESOURCE; -} /* register_client */ - /* register pcmcia_callback */ int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c) { @@ -2085,14 +1915,12 @@ EXPORT_SYMBOL(pcmcia_set_event_mask); ======================================================================*/ /* in alpha order */ -EXPORT_SYMBOL(pcmcia_deregister_client); EXPORT_SYMBOL(pcmcia_eject_card); EXPORT_SYMBOL(pcmcia_get_card_services_info); EXPORT_SYMBOL(pcmcia_get_mem_page); EXPORT_SYMBOL(pcmcia_insert_card); EXPORT_SYMBOL(pcmcia_map_mem_page); EXPORT_SYMBOL(pcmcia_modify_configuration); -EXPORT_SYMBOL(pcmcia_register_client); EXPORT_SYMBOL(pcmcia_release_configuration); EXPORT_SYMBOL(pcmcia_release_io); EXPORT_SYMBOL(pcmcia_release_irq); diff -puN drivers/pcmcia/cs_internal.h~pcmcia-18a-client_t-and-pcmcia_device-integration drivers/pcmcia/cs_internal.h --- 25/drivers/pcmcia/cs_internal.h~pcmcia-18a-client_t-and-pcmcia_device-integration Wed Nov 3 16:11:54 2004 +++ 25-akpm/drivers/pcmcia/cs_internal.h Wed Nov 3 16:11:54 2004 @@ -1,19 +1,15 @@ /* - * cs_internal.h 1.57 2002/10/24 06:11:43 + * cs_internal.h * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License - * at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - * the License for the specific language governing rights and - * limitations under the License. + * 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. + * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. + * + * (C) 1999 David A. Hinds */ #ifndef _LINUX_CS_INTERNAL_H diff -puN drivers/pcmcia/ds.c~pcmcia-18a-client_t-and-pcmcia_device-integration drivers/pcmcia/ds.c --- 25/drivers/pcmcia/ds.c~pcmcia-18a-client_t-and-pcmcia_device-integration Wed Nov 3 16:11:54 2004 +++ 25-akpm/drivers/pcmcia/ds.c Wed Nov 3 16:11:54 2004 @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -86,7 +87,7 @@ typedef struct user_info_t { /* Socket state information */ struct pcmcia_bus_socket { - atomic_t refcount; + struct kref refcount; struct pcmcia_callback callback; int state; user_info_t *user; @@ -111,6 +112,8 @@ static int major_dev = -1; static struct proc_dir_entry *proc_pccard; +static int unbind_request(struct pcmcia_bus_socket *s); + /*====================================================================*/ /* code which was in cs.c before */ @@ -256,22 +259,22 @@ EXPORT_SYMBOL(cs_error); static struct pcmcia_driver * get_pcmcia_driver (dev_info_t *dev_info); static struct pcmcia_bus_socket * get_socket_info_by_nr(unsigned int nr); -static void pcmcia_put_bus_socket(struct pcmcia_bus_socket *s) +static void pcmcia_release_bus_socket(struct kref *refcount) { - if (atomic_dec_and_test(&s->refcount)) - kfree(s); + struct pcmcia_bus_socket *s = container_of(refcount, struct pcmcia_bus_socket, refcount); + pcmcia_put_socket(s->parent); + kfree(s); } -static struct pcmcia_bus_socket *pcmcia_get_bus_socket(int nr) +static void pcmcia_put_bus_socket(struct pcmcia_bus_socket *s) { - struct pcmcia_bus_socket *s; + kref_put(&s->refcount, pcmcia_release_bus_socket); +} - s = get_socket_info_by_nr(nr); - if (s) { - WARN_ON(atomic_read(&s->refcount) == 0); - atomic_inc(&s->refcount); - } - return s; +static struct pcmcia_bus_socket *pcmcia_get_bus_socket(struct pcmcia_bus_socket *s) +{ + kref_get(&s->refcount); + return (s); } /** @@ -347,6 +350,7 @@ static inline void put_p_dev(struct pcmc static void pcmcia_release_dev(struct device *dev) { struct pcmcia_device *p_dev = to_pcmcia_dev(dev); + pcmcia_put_bus_socket(p_dev->socket->pcmcia); kfree(p_dev); } @@ -403,21 +407,48 @@ static int handle_request(struct pcmcia_ The card status event handler. ======================================================================*/ +struct send_event_data { + struct pcmcia_socket *skt; + event_t event; + int priority; +}; + +static int send_event_callback(struct device *dev, void * _data) +{ + struct pcmcia_device *p_dev = to_pcmcia_dev(dev); + struct send_event_data *data = _data; + + /* we get called for all sockets, but may only pass the event + * for drivers _on the affected socket_ */ + if (p_dev->socket != data->skt) + return 0; + + if (p_dev->client->state & (CLIENT_UNBOUND|CLIENT_STALE)) + return 0; + + if (p_dev->client->EventMask & data->event) + return EVENT(p_dev->client, data->event, data->priority); + + return 0; +} static int send_event(struct pcmcia_socket *s, event_t event, int priority) { int ret = 0; - client_t *client; + struct send_event_data private; + struct pcmcia_bus_socket *skt = pcmcia_get_bus_socket(s->pcmcia); + + if (!skt) + return 0; + + private.skt = s; + private.event = event; + private.priority = priority; + + ret = bus_for_each_dev(&pcmcia_bus_type, NULL, &private, send_event_callback); + + pcmcia_put_bus_socket(skt); - for (client = s->clients; client; client = client->next) { - if (client->state & (CLIENT_UNBOUND|CLIENT_STALE)) - continue; - if (client->EventMask & event) { - ret = EVENT(client, event, priority); - if (ret != 0) - return ret; - } - } return ret; } /* send_event */ @@ -440,6 +471,7 @@ static int ds_event(struct pcmcia_socket case CS_EVENT_CARD_REMOVAL: s->state &= ~DS_SOCKET_PRESENT; send_event(skt, event, priority); + unbind_request(s); handle_event(s, event); break; @@ -496,8 +528,9 @@ static int bind_mtd(struct pcmcia_bus_so /*====================================================================== - bind_request() and bind_device() are merged by now. Individual - descriptions: + bind_request() and bind_device() are merged by now. Register_client() + is called right at the end of bind_request(), during the driver's + ->attach() call. Individual descriptions: bind_request() connects a socket to a particular client driver. It looks up the specified device ID in the list of registered @@ -509,6 +542,11 @@ static int bind_mtd(struct pcmcia_bus_so a newly inserted card. An instance of that driver will then be eligible to register as a client of this socket. + Register_client() uses the dev_info_t handle to match the + caller with a socket. The driver must have already been bound + to a socket with bind_device() -- in fact, bind_device() + allocates the client structure that will be used. + ======================================================================*/ static int bind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info) @@ -554,12 +592,21 @@ static int bind_request(struct pcmcia_bu p_dev = kmalloc(sizeof(struct pcmcia_device), GFP_KERNEL); if (!p_dev) { ret = -ENOMEM; + pcmcia_put_bus_socket(s); goto err_free_client; } memset(p_dev, 0, sizeof(struct pcmcia_device)); + s = pcmcia_get_bus_socket(s); + if (!s) { + ret = -ENODEV; + kfree(p_dev); + goto err_free_client; + } + p_dev->socket = s->parent; p_dev->func = bind_info->function; + p_dev->client = client; p_dev->dev.bus = &pcmcia_bus_type; p_dev->dev.parent = s->parent->dev.dev; @@ -570,6 +617,7 @@ static int bind_request(struct pcmcia_bu ret = device_register(&p_dev->dev); if (ret) { kfree(p_dev); + pcmcia_put_bus_socket(s); goto err_free_client; } @@ -615,6 +663,103 @@ static int bind_request(struct pcmcia_bu return (ret); } /* bind_request */ +int pcmcia_register_client(client_handle_t *handle, client_reg_t *req) +{ + client_t *client = NULL; + struct pcmcia_socket *s; + struct pcmcia_bus_socket *skt = NULL; + struct pcmcia_device *p_dev = NULL; + + /* Look for unbound client with matching dev_info */ + down_read(&pcmcia_socket_list_rwsem); + list_for_each_entry(s, &pcmcia_socket_list, socket_list) { + unsigned long flags; + + if (s->state & SOCKET_CARDBUS) + continue; + + skt = s->pcmcia; + if (!skt) + continue; + skt = pcmcia_get_bus_socket(skt); + if (!skt) + continue; + spin_lock_irqsave(&pcmcia_dev_list_lock, flags); + list_for_each_entry(p_dev, &skt->devices_list, socket_device_list) { + if ((p_dev->client->state & CLIENT_UNBOUND) && + (!strcmp(p_dev->client->dev_info, (char *)req->dev_info))) { + p_dev = get_p_dev(p_dev); + if (p_dev) + client = p_dev->client; + spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); + goto found; + } + } + spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); + pcmcia_put_bus_socket(skt); + } + found: + up_read(&pcmcia_socket_list_rwsem); + if (!p_dev || !client) + return -ENODEV; + + pcmcia_put_bus_socket(skt); /* safe, as we already hold a reference from bind_device */ + + /* + * Prevent this racing with a card insertion. + */ + down(&s->skt_sem); + *handle = client; + client->state &= ~CLIENT_UNBOUND; + client->Socket = s; + client->Attributes = req->Attributes; + client->EventMask = req->EventMask; + client->event_handler = req->event_handler; + client->event_callback_args = req->event_callback_args; + client->event_callback_args.client_handle = client; + + if (s->state & SOCKET_CARDBUS) + client->state |= CLIENT_CARDBUS; + + if ((!(s->state & SOCKET_CARDBUS)) && (s->functions == 0) && + (client->Function != BIND_FN_ALL)) { + cistpl_longlink_mfc_t mfc; + if (pccard_read_tuple(s, client->Function, CISTPL_LONGLINK_MFC, &mfc) + == CS_SUCCESS) + s->functions = mfc.nfn; + else + s->functions = 1; + s->config = kmalloc(sizeof(config_t) * s->functions, + GFP_KERNEL); + if (!s->config) + goto out_no_resource; + memset(s->config, 0, sizeof(config_t) * s->functions); + } + + ds_dbg(1, "register_client(): client 0x%p, dev %s\n", + client, client->dev_info); + if (client->EventMask & CS_EVENT_REGISTRATION_COMPLETE) + EVENT(client, CS_EVENT_REGISTRATION_COMPLETE, CS_EVENT_PRI_LOW); + + if ((s->state & (SOCKET_PRESENT|SOCKET_CARDBUS)) == SOCKET_PRESENT) { + if (client->EventMask & CS_EVENT_CARD_INSERTION) + EVENT(client, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW); + else + client->PendingEvents |= CS_EVENT_CARD_INSERTION; + } + + up(&s->skt_sem); + put_p_dev(p_dev); /* FIXME: put in deregister_client. */ + return CS_SUCCESS; + + out_no_resource: + up(&s->skt_sem); + put_p_dev(p_dev); + return CS_OUT_OF_RESOURCE; +} /* register_client */ +EXPORT_SYMBOL(pcmcia_register_client); + + /*====================================================================*/ extern struct pci_bus *pcmcia_lookup_bus(struct pcmcia_socket *s); @@ -706,40 +851,86 @@ static int get_device_info(struct pcmcia /*====================================================================*/ -static int unbind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info) +/* unbind _all_ devices attached to a given pcmcia_bus_socket. The + * drivers have been called with EVENT_CARD_REMOVAL before. + */ +static int unbind_request(struct pcmcia_bus_socket *s) { struct pcmcia_device *p_dev; struct pcmcia_driver *p_drv; unsigned long flags; - ds_dbg(2, "unbind_request(%d, '%s')\n", s->parent->sock, - (char *)bind_info->dev_info); + ds_dbg(2, "unbind_request(%d)\n", s->parent->sock); - /* unregister the pcmcia_device */ - spin_lock_irqsave(&pcmcia_dev_list_lock, flags); - list_for_each_entry(p_dev, &s->devices_list, socket_device_list) { - if (p_dev->func == bind_info->function) - goto found; + for (;;) { + /* unregister all pcmcia_devices registered with this socket*/ + spin_lock_irqsave(&pcmcia_dev_list_lock, flags); + if (list_empty(&s->devices_list)) { + spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); + return 0; + } + p_dev = list_entry((&s->devices_list)->next, struct pcmcia_device, socket_device_list); + list_del(&p_dev->socket_device_list); + p_dev->client->state |= CLIENT_STALE; + spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); + + /* detach the "instance" */ + p_drv = to_pcmcia_drv(p_dev->dev.driver); + if (p_drv) { + module_put(p_drv->owner); + if ((p_drv->detach) && (p_dev->instance)) + p_drv->detach(p_dev->instance); + } + + device_unregister(&p_dev->dev); } - spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); + return 0; +} /* unbind_request */ - found: - list_del(&p_dev->socket_device_list); - spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); +int pcmcia_deregister_client(client_handle_t handle) +{ + client_t **client; + struct pcmcia_socket *s; + u_long flags; + int i; - /* detach the "instance" */ - p_drv = to_pcmcia_drv(p_dev->dev.driver); - if (p_drv) { - module_put(p_drv->owner); - if ((p_drv->detach) && (p_dev->instance)) - p_drv->detach(p_dev->instance); + if (CHECK_HANDLE(handle)) + return CS_BAD_HANDLE; + + s = SOCKET(handle); + ds_dbg(1, "deregister_client(%p)\n", handle); + + if (handle->state & + (CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED)) + return CS_IN_USE; + for (i = 0; i < MAX_WIN; i++) + if (handle->state & CLIENT_WIN_REQ(i)) + return CS_IN_USE; + + if ((handle->state & CLIENT_STALE) || + (handle->Attributes & INFO_MASTER_CLIENT)) { + spin_lock_irqsave(&s->lock, flags); + client = &s->clients; + while ((*client) && ((*client) != handle)) + client = &(*client)->next; + if (*client == NULL) { + spin_unlock_irqrestore(&s->lock, flags); + return CS_BAD_HANDLE; + } + *client = handle->next; + handle->client_magic = 0; + kfree(handle); + spin_unlock_irqrestore(&s->lock, flags); + } else { + handle->state = CLIENT_UNBOUND; + handle->event_handler = NULL; } - device_unregister(&p_dev->dev); + return CS_SUCCESS; +} /* deregister_client */ +EXPORT_SYMBOL(pcmcia_deregister_client); - return 0; -} /* unbind_request */ /*====================================================================== @@ -755,19 +946,27 @@ static int ds_open(struct inode *inode, ds_dbg(0, "ds_open(socket %d)\n", i); - s = pcmcia_get_bus_socket(i); + s = get_socket_info_by_nr(i); + if (!s) + return -ENODEV; + s = pcmcia_get_bus_socket(s); if (!s) return -ENODEV; if ((file->f_flags & O_ACCMODE) != O_RDONLY) { - if (s->state & DS_SOCKET_BUSY) - return -EBUSY; + if (s->state & DS_SOCKET_BUSY) { + pcmcia_put_bus_socket(s); + return -EBUSY; + } else s->state |= DS_SOCKET_BUSY; } user = kmalloc(sizeof(user_info_t), GFP_KERNEL); - if (!user) return -ENOMEM; + if (!user) { + pcmcia_put_bus_socket(s); + return -ENOMEM; + } user->event_tail = user->event_head = 0; user->next = s->user; user->user_magic = USER_MAGIC; @@ -786,6 +985,8 @@ static int ds_release(struct inode *inod { struct pcmcia_bus_socket *s; user_info_t *user, **link; + unsigned long flags; + unsigned int has_p_devs = 0; ds_dbg(0, "ds_release(socket %d)\n", iminor(inode)); @@ -795,6 +996,16 @@ static int ds_release(struct inode *inod s = user->socket; + /* if 16-bit devices are associated with this device, remove them */ + down(&s->parent->skt_sem); + spin_lock_irqsave(&pcmcia_dev_list_lock, flags); + if (!list_empty(&s->devices_list)) + has_p_devs = 1; + spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); + if (has_p_devs) + ds_event(s->parent, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH); + up(&s->parent->skt_sem); + /* Unlink user data structure */ if ((file->f_flags & O_ACCMODE) != O_RDONLY) { s->state &= ~DS_SOCKET_BUSY; @@ -1048,7 +1259,7 @@ static int ds_ioctl(struct inode * inode err = get_device_info(s, &buf.bind_info, 0); break; case DS_UNBIND_REQUEST: - err = unbind_request(s, &buf.bind_info); + err = 0; break; case DS_BIND_MTD: if (!capable(CAP_SYS_ADMIN)) return -EPERM; @@ -1102,7 +1313,7 @@ static struct file_operations ds_fops = static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev) { - struct pcmcia_socket *socket = class_dev->class_data; + struct pcmcia_socket *socket = class_get_devdata(class_dev); struct pcmcia_bus_socket *s; int ret; @@ -1110,7 +1321,16 @@ static int __devinit pcmcia_bus_add_sock if(!s) return -ENOMEM; memset(s, 0, sizeof(struct pcmcia_bus_socket)); - atomic_set(&s->refcount, 1); + + /* get reference to parent socket */ + s->parent = pcmcia_get_socket(socket); + if (!s->parent) { + printk(KERN_ERR "PCMCIA obtaining reference to socket %p failed\n", socket); + kfree (s); + return -ENODEV; + } + + kref_init(&s->refcount); /* * Ugly. But we want to wait for the socket threads to have started up. @@ -1122,9 +1342,6 @@ static int __devinit pcmcia_bus_add_sock init_waitqueue_head(&s->request); INIT_LIST_HEAD(&s->devices_list); - /* initialize data */ - s->parent = socket; - /* Set up hotline to Card Services */ s->callback.owner = THIS_MODULE; s->callback.event = &ds_event; @@ -1144,7 +1361,7 @@ static int __devinit pcmcia_bus_add_sock static void pcmcia_bus_remove_socket(struct class_device *class_dev) { - struct pcmcia_socket *socket = class_dev->class_data; + struct pcmcia_socket *socket = class_get_devdata(class_dev); if (!socket || !socket->pcmcia) return; diff -puN drivers/pcmcia/rsrc_mgr.c~pcmcia-18a-client_t-and-pcmcia_device-integration drivers/pcmcia/rsrc_mgr.c --- 25/drivers/pcmcia/rsrc_mgr.c~pcmcia-18a-client_t-and-pcmcia_device-integration Wed Nov 3 16:11:54 2004 +++ 25-akpm/drivers/pcmcia/rsrc_mgr.c Wed Nov 3 16:11:54 2004 @@ -1,35 +1,16 @@ -/*====================================================================== - - Resource management routines - - rsrc_mgr.c 1.79 2000/08/30 20:23:58 - - The contents of this file are subject to the Mozilla Public - License Version 1.1 (the "License"); you may not use this file - except in compliance with the License. You may obtain a copy of - the License at http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS - IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - implied. See the License for the specific language governing - rights and limitations under the License. - - 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. - - Alternatively, the contents of this file may be used under the - terms of the GNU General Public License version 2 (the "GPL"), in which - case the provisions of the GPL are applicable instead of the - above. If you wish to allow the use of your version of this file - only under the terms of the GPL and not to allow others to use - your version of this file under the MPL, indicate your decision - by deleting the provisions above and replace them with the notice - and other provisions required by the GPL. If you do not delete - the provisions above, a recipient may use your version of this - file under either the MPL or the GPL. - -======================================================================*/ +/* + * rsrc_mgr.c -- Resource management routines + * + * 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 diff -puN include/pcmcia/bulkmem.h~pcmcia-18a-client_t-and-pcmcia_device-integration include/pcmcia/bulkmem.h --- 25/include/pcmcia/bulkmem.h~pcmcia-18a-client_t-and-pcmcia_device-integration Wed Nov 3 16:11:54 2004 +++ 25-akpm/include/pcmcia/bulkmem.h Wed Nov 3 16:11:54 2004 @@ -1,33 +1,15 @@ /* - * Definitions for bulk memory services + * bulkmem.h -- Definitions for bulk memory services * - * bulkmem.h 1.12 2000/06/12 21:55:41 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License - * at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - * the License for the specific language governing rights and - * limitations under the License. + * 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. * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License version 2 (the "GPL"), in which - * case the provisions of the GPL are applicable instead of the - * above. If you wish to allow the use of your version of this file - * only under the terms of the GPL and not to allow others to use - * your version of this file under the MPL, indicate your decision by - * deleting the provisions above and replace them with the notice and - * other provisions required by the GPL. If you do not delete the - * provisions above, a recipient may use your version of this file - * under either the MPL or the GPL. - * bulkmem.h 1.3 1995/05/27 04:49:49 + * (C) 1999 David A. Hinds */ #ifndef _LINUX_BULKMEM_H diff -puN include/pcmcia/ciscode.h~pcmcia-18a-client_t-and-pcmcia_device-integration include/pcmcia/ciscode.h --- 25/include/pcmcia/ciscode.h~pcmcia-18a-client_t-and-pcmcia_device-integration Wed Nov 3 16:11:54 2004 +++ 25-akpm/include/pcmcia/ciscode.h Wed Nov 3 16:11:54 2004 @@ -1,30 +1,15 @@ /* - * ciscode.h 1.56 2002/10/25 06:37:30 + * ciscode.h -- Definitions for bulk memory services * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License - * at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - * the License for the specific language governing rights and - * limitations under the License. + * 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. * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License version 2 (the "GPL"), in - * which case the provisions of the GPL are applicable instead of the - * above. If you wish to allow the use of your version of this file - * only under the terms of the GPL and not to allow others to use - * your version of this file under the MPL, indicate your decision by - * deleting the provisions above and replace them with the notice and - * other provisions required by the GPL. If you do not delete the - * provisions above, a recipient may use your version of this file - * under either the MPL or the GPL. + * (C) 1999 David A. Hinds */ #ifndef _LINUX_CISCODE_H diff -puN include/pcmcia/cisreg.h~pcmcia-18a-client_t-and-pcmcia_device-integration include/pcmcia/cisreg.h --- 25/include/pcmcia/cisreg.h~pcmcia-18a-client_t-and-pcmcia_device-integration Wed Nov 3 16:11:54 2004 +++ 25-akpm/include/pcmcia/cisreg.h Wed Nov 3 16:11:54 2004 @@ -1,30 +1,15 @@ /* - * cisreg.h 1.17 2000/06/12 21:55:41 + * cisreg.h * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License - * at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - * the License for the specific language governing rights and - * limitations under the License. + * 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. * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License version 2 (the "GPL"), in which - * case the provisions of the GPL are applicable instead of the - * above. If you wish to allow the use of your version of this file - * only under the terms of the GPL and not to allow others to use - * your version of this file under the MPL, indicate your decision by - * deleting the provisions above and replace them with the notice and - * other provisions required by the GPL. If you do not delete the - * provisions above, a recipient may use your version of this file - * under either the MPL or the GPL. + * (C) 1999 David A. Hinds */ #ifndef _LINUX_CISREG_H diff -puN include/pcmcia/cistpl.h~pcmcia-18a-client_t-and-pcmcia_device-integration include/pcmcia/cistpl.h --- 25/include/pcmcia/cistpl.h~pcmcia-18a-client_t-and-pcmcia_device-integration Wed Nov 3 16:11:54 2004 +++ 25-akpm/include/pcmcia/cistpl.h Wed Nov 3 16:11:54 2004 @@ -1,30 +1,15 @@ /* - * cistpl.h 1.34 2000/06/19 23:18:12 + * cistpl.h * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License - * at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - * the License for the specific language governing rights and - * limitations under the License. + * 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. * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License version 2 (the "GPL"), in which - * case the provisions of the GPL are applicable instead of the - * above. If you wish to allow the use of your version of this file - * only under the terms of the GPL and not to allow others to use - * your version of this file under the MPL, indicate your decision by - * deleting the provisions above and replace them with the notice and - * other provisions required by the GPL. If you do not delete the - * provisions above, a recipient may use your version of this file - * under either the MPL or the GPL. + * (C) 1999 David A. Hinds */ #ifndef _LINUX_CISTPL_H diff -puN include/pcmcia/cs.h~pcmcia-18a-client_t-and-pcmcia_device-integration include/pcmcia/cs.h --- 25/include/pcmcia/cs.h~pcmcia-18a-client_t-and-pcmcia_device-integration Wed Nov 3 16:11:54 2004 +++ 25-akpm/include/pcmcia/cs.h Wed Nov 3 16:11:54 2004 @@ -1,30 +1,15 @@ /* - * cs.h 1.71 2000/08/29 00:54:20 + * cs.h * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License - * at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - * the License for the specific language governing rights and - * limitations under the License. + * 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. * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License version 2 (the "GPL"), in which - * case the provisions of the GPL are applicable instead of the - * above. If you wish to allow the use of your version of this file - * only under the terms of the GPL and not to allow others to use - * your version of this file under the MPL, indicate your decision by - * deleting the provisions above and replace them with the notice and - * other provisions required by the GPL. If you do not delete the - * provisions above, a recipient may use your version of this file - * under either the MPL or the GPL. + * (C) 1999 David A. Hinds */ #ifndef _LINUX_CS_H @@ -441,6 +426,9 @@ int pcmcia_modify_window(window_handle_t int pcmcia_set_event_mask(client_handle_t handle, eventmask_t *mask); #endif +struct pcmcia_socket * pcmcia_get_socket(struct pcmcia_socket *skt); +void pcmcia_put_socket(struct pcmcia_socket *skt); + #endif /* __KERNEL__ */ #endif /* _LINUX_CS_H */ diff -puN include/pcmcia/cs_types.h~pcmcia-18a-client_t-and-pcmcia_device-integration include/pcmcia/cs_types.h --- 25/include/pcmcia/cs_types.h~pcmcia-18a-client_t-and-pcmcia_device-integration Wed Nov 3 16:11:54 2004 +++ 25-akpm/include/pcmcia/cs_types.h Wed Nov 3 16:11:54 2004 @@ -1,30 +1,15 @@ /* - * cs_types.h 1.18 2000/06/12 21:55:40 + * cs_types.h * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License - * at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - * the License for the specific language governing rights and - * limitations under the License. + * 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. * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License version 2 (the "GPL"), in which - * case the provisions of the GPL are applicable instead of the - * above. If you wish to allow the use of your version of this file - * only under the terms of the GPL and not to allow others to use - * your version of this file under the MPL, indicate your decision by - * deleting the provisions above and replace them with the notice and - * other provisions required by the GPL. If you do not delete the - * provisions above, a recipient may use your version of this file - * under either the MPL or the GPL. + * (C) 1999 David A. Hinds */ #ifndef _LINUX_CS_TYPES_H diff -puN include/pcmcia/ds.h~pcmcia-18a-client_t-and-pcmcia_device-integration include/pcmcia/ds.h --- 25/include/pcmcia/ds.h~pcmcia-18a-client_t-and-pcmcia_device-integration Wed Nov 3 16:11:54 2004 +++ 25-akpm/include/pcmcia/ds.h Wed Nov 3 16:11:54 2004 @@ -128,6 +128,7 @@ typedef struct dev_link_t { struct pcmcia_socket; +struct client_t; extern struct bus_type pcmcia_bus_type; @@ -153,6 +154,7 @@ struct pcmcia_device { /* deprecated, a cleaned up version will be moved into this struct soon */ dev_link_t *instance; + struct client_t *client; struct device dev; }; diff -puN include/pcmcia/mem_op.h~pcmcia-18a-client_t-and-pcmcia_device-integration include/pcmcia/mem_op.h --- 25/include/pcmcia/mem_op.h~pcmcia-18a-client_t-and-pcmcia_device-integration Wed Nov 3 16:11:54 2004 +++ 25-akpm/include/pcmcia/mem_op.h Wed Nov 3 16:11:54 2004 @@ -1,30 +1,15 @@ /* - * mem_op.h 1.13 2000/06/12 21:55:40 + * mem_op.h * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License - * at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - * the License for the specific language governing rights and - * limitations under the License. + * 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. * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License version 2 (the "GPL"), in which - * case the provisions of the GPL are applicable instead of the - * above. If you wish to allow the use of your version of this file - * only under the terms of the GPL and not to allow others to use - * your version of this file under the MPL, indicate your decision by - * deleting the provisions above and replace them with the notice and - * other provisions required by the GPL. If you do not delete the - * provisions above, a recipient may use your version of this file - * under either the MPL or the GPL. + * (C) 1999 David A. Hinds */ #ifndef _LINUX_MEM_OP_H diff -puN include/pcmcia/ss.h~pcmcia-18a-client_t-and-pcmcia_device-integration include/pcmcia/ss.h --- 25/include/pcmcia/ss.h~pcmcia-18a-client_t-and-pcmcia_device-integration Wed Nov 3 16:11:54 2004 +++ 25-akpm/include/pcmcia/ss.h Wed Nov 3 16:11:54 2004 @@ -1,30 +1,15 @@ /* - * ss.h 1.28 2000/06/12 21:55:40 + * ss.h * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License - * at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - * the License for the specific language governing rights and - * limitations under the License. + * 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. * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License version 2 (the "GPL"), in which - * case the provisions of the GPL are applicable instead of the - * above. If you wish to allow the use of your version of this file - * only under the terms of the GPL and not to allow others to use - * your version of this file under the MPL, indicate your decision by - * deleting the provisions above and replace them with the notice and - * other provisions required by the GPL. If you do not delete the - * provisions above, a recipient may use your version of this file - * under either the MPL or the GPL. + * (C) 1999 David A. Hinds */ #ifndef _LINUX_SS_H _