aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl3501_cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/wl3501_cs.c')
-rw-r--r--drivers/net/wireless/wl3501_cs.c133
1 files changed, 48 insertions, 85 deletions
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index 978fdc606781..48e10b0c7e74 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -105,7 +105,6 @@ module_param(pc_debug, int, 0);
105 */ 105 */
106static void wl3501_config(dev_link_t *link); 106static void wl3501_config(dev_link_t *link);
107static void wl3501_release(dev_link_t *link); 107static void wl3501_release(dev_link_t *link);
108static int wl3501_event(event_t event, int pri, event_callback_args_t *args);
109 108
110/* 109/*
111 * The dev_info variable is the "key" that is used to match up this 110 * The dev_info variable is the "key" that is used to match up this
@@ -1498,9 +1497,11 @@ static struct ethtool_ops ops = {
1498 * Services. If it has been released, all local data structures are freed. 1497 * Services. If it has been released, all local data structures are freed.
1499 * Otherwise, the structures will be freed when the device is released. 1498 * Otherwise, the structures will be freed when the device is released.
1500 */ 1499 */
1501static void wl3501_detach(dev_link_t *link) 1500static void wl3501_detach(struct pcmcia_device *p_dev)
1502{ 1501{
1502 dev_link_t *link = dev_to_instance(p_dev);
1503 dev_link_t **linkp; 1503 dev_link_t **linkp;
1504 struct net_device *dev = link->priv;
1504 1505
1505 /* Locate device structure */ 1506 /* Locate device structure */
1506 for (linkp = &wl3501_dev_list; *linkp; linkp = &(*linkp)->next) 1507 for (linkp = &wl3501_dev_list; *linkp; linkp = &(*linkp)->next)
@@ -1514,16 +1515,12 @@ static void wl3501_detach(dev_link_t *link)
1514 * function is called, that will trigger a proper detach(). */ 1515 * function is called, that will trigger a proper detach(). */
1515 1516
1516 if (link->state & DEV_CONFIG) { 1517 if (link->state & DEV_CONFIG) {
1517#ifdef PCMCIA_DEBUG 1518 while (link->open > 0)
1518 printk(KERN_DEBUG "wl3501_cs: detach postponed, '%s' " 1519 wl3501_close(dev);
1519 "still locked\n", link->dev->dev_name);
1520#endif
1521 goto out;
1522 }
1523 1520
1524 /* Break the link with Card Services */ 1521 netif_device_detach(dev);
1525 if (link->handle) 1522 wl3501_release(link);
1526 pcmcia_deregister_client(link->handle); 1523 }
1527 1524
1528 /* Unlink device structure, free pieces */ 1525 /* Unlink device structure, free pieces */
1529 *linkp = link->next; 1526 *linkp = link->next;
@@ -1956,18 +1953,16 @@ static const struct iw_handler_def wl3501_handler_def = {
1956 * The dev_link structure is initialized, but we don't actually configure the 1953 * The dev_link structure is initialized, but we don't actually configure the
1957 * card at this point -- we wait until we receive a card insertion event. 1954 * card at this point -- we wait until we receive a card insertion event.
1958 */ 1955 */
1959static dev_link_t *wl3501_attach(void) 1956static int wl3501_attach(struct pcmcia_device *p_dev)
1960{ 1957{
1961 client_reg_t client_reg;
1962 dev_link_t *link; 1958 dev_link_t *link;
1963 struct net_device *dev; 1959 struct net_device *dev;
1964 struct wl3501_card *this; 1960 struct wl3501_card *this;
1965 int ret;
1966 1961
1967 /* Initialize the dev_link_t structure */ 1962 /* Initialize the dev_link_t structure */
1968 link = kzalloc(sizeof(*link), GFP_KERNEL); 1963 link = kzalloc(sizeof(*link), GFP_KERNEL);
1969 if (!link) 1964 if (!link)
1970 goto out; 1965 return -ENOMEM;
1971 1966
1972 /* The io structure describes IO port mapping */ 1967 /* The io structure describes IO port mapping */
1973 link->io.NumPorts1 = 16; 1968 link->io.NumPorts1 = 16;
@@ -2003,24 +1998,17 @@ static dev_link_t *wl3501_attach(void)
2003 netif_stop_queue(dev); 1998 netif_stop_queue(dev);
2004 link->priv = link->irq.Instance = dev; 1999 link->priv = link->irq.Instance = dev;
2005 2000
2006 /* Register with Card Services */ 2001 link->handle = p_dev;
2007 link->next = wl3501_dev_list; 2002 p_dev->instance = link;
2008 wl3501_dev_list = link; 2003
2009 client_reg.dev_info = &wl3501_dev_info; 2004 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
2010 client_reg.Version = 0x0210; 2005 wl3501_config(link);
2011 client_reg.event_callback_args.client_data = link; 2006
2012 ret = pcmcia_register_client(&link->handle, &client_reg); 2007 return 0;
2013 if (ret) {
2014 cs_error(link->handle, RegisterClient, ret);
2015 wl3501_detach(link);
2016 link = NULL;
2017 }
2018out:
2019 return link;
2020out_link: 2008out_link:
2021 kfree(link); 2009 kfree(link);
2022 link = NULL; 2010 link = NULL;
2023 goto out; 2011 return -ENOMEM;
2024} 2012}
2025 2013
2026#define CS_CHECK(fn, ret) \ 2014#define CS_CHECK(fn, ret) \
@@ -2173,67 +2161,41 @@ static void wl3501_release(dev_link_t *link)
2173 link->state &= ~DEV_CONFIG; 2161 link->state &= ~DEV_CONFIG;
2174} 2162}
2175 2163
2176/** 2164static int wl3501_suspend(struct pcmcia_device *p_dev)
2177 * wl3501_event - The card status event handler
2178 * @event - event
2179 * @pri - priority
2180 * @args - arguments for this event
2181 *
2182 * The card status event handler. Mostly, this schedules other stuff to run
2183 * after an event is received. A CARD_REMOVAL event also sets some flags to
2184 * discourage the net drivers from trying to talk to the card any more.
2185 *
2186 * When a CARD_REMOVAL event is received, we immediately set a flag to block
2187 * future accesses to this device. All the functions that actually access the
2188 * device should check this flag to make sure the card is still present.
2189 */
2190static int wl3501_event(event_t event, int pri, event_callback_args_t *args)
2191{ 2165{
2192 dev_link_t *link = args->client_data; 2166 dev_link_t *link = dev_to_instance(p_dev);
2193 struct net_device *dev = link->priv; 2167 struct net_device *dev = link->priv;
2194 2168
2195 switch (event) { 2169 link->state |= DEV_SUSPEND;
2196 case CS_EVENT_CARD_REMOVAL: 2170
2197 link->state &= ~DEV_PRESENT; 2171 wl3501_pwr_mgmt(dev->priv, WL3501_SUSPEND);
2198 if (link->state & DEV_CONFIG) { 2172 if (link->state & DEV_CONFIG) {
2199 while (link->open > 0) 2173 if (link->open)
2200 wl3501_close(dev);
2201 netif_device_detach(dev); 2174 netif_device_detach(dev);
2202 wl3501_release(link); 2175 pcmcia_release_configuration(link->handle);
2203 } 2176 }
2204 break; 2177
2205 case CS_EVENT_CARD_INSERTION: 2178 return 0;
2206 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 2179}
2207 wl3501_config(link); 2180
2208 break; 2181static int wl3501_resume(struct pcmcia_device *p_dev)
2209 case CS_EVENT_PM_SUSPEND: 2182{
2210 link->state |= DEV_SUSPEND; 2183 dev_link_t *link = dev_to_instance(p_dev);
2211 wl3501_pwr_mgmt(dev->priv, WL3501_SUSPEND); 2184 struct net_device *dev = link->priv;
2212 /* Fall through... */ 2185
2213 case CS_EVENT_RESET_PHYSICAL: 2186 wl3501_pwr_mgmt(dev->priv, WL3501_RESUME);
2214 if (link->state & DEV_CONFIG) { 2187 if (link->state & DEV_CONFIG) {
2215 if (link->open) 2188 pcmcia_request_configuration(link->handle, &link->conf);
2216 netif_device_detach(dev); 2189 if (link->open) {
2217 pcmcia_release_configuration(link->handle); 2190 wl3501_reset(dev);
2218 } 2191 netif_device_attach(dev);
2219 break;
2220 case CS_EVENT_PM_RESUME:
2221 link->state &= ~DEV_SUSPEND;
2222 wl3501_pwr_mgmt(dev->priv, WL3501_RESUME);
2223 /* Fall through... */
2224 case CS_EVENT_CARD_RESET:
2225 if (link->state & DEV_CONFIG) {
2226 pcmcia_request_configuration(link->handle, &link->conf);
2227 if (link->open) {
2228 wl3501_reset(dev);
2229 netif_device_attach(dev);
2230 }
2231 } 2192 }
2232 break;
2233 } 2193 }
2194
2234 return 0; 2195 return 0;
2235} 2196}
2236 2197
2198
2237static struct pcmcia_device_id wl3501_ids[] = { 2199static struct pcmcia_device_id wl3501_ids[] = {
2238 PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0001), 2200 PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0001),
2239 PCMCIA_DEVICE_NULL 2201 PCMCIA_DEVICE_NULL
@@ -2245,10 +2207,11 @@ static struct pcmcia_driver wl3501_driver = {
2245 .drv = { 2207 .drv = {
2246 .name = "wl3501_cs", 2208 .name = "wl3501_cs",
2247 }, 2209 },
2248 .attach = wl3501_attach, 2210 .probe = wl3501_attach,
2249 .event = wl3501_event, 2211 .remove = wl3501_detach,
2250 .detach = wl3501_detach,
2251 .id_table = wl3501_ids, 2212 .id_table = wl3501_ids,
2213 .suspend = wl3501_suspend,
2214 .resume = wl3501_resume,
2252}; 2215};
2253 2216
2254static int __init wl3501_init_module(void) 2217static int __init wl3501_init_module(void)