diff options
Diffstat (limited to 'drivers/net/wireless/wl3501_cs.c')
-rw-r--r-- | drivers/net/wireless/wl3501_cs.c | 178 |
1 files changed, 53 insertions, 125 deletions
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c index 48e10b0c7e74..e52a650f6737 100644 --- a/drivers/net/wireless/wl3501_cs.c +++ b/drivers/net/wireless/wl3501_cs.c | |||
@@ -103,8 +103,8 @@ module_param(pc_debug, int, 0); | |||
103 | * release a socket, in response to card insertion and ejection events. They | 103 | * release a socket, in response to card insertion and ejection events. They |
104 | * are invoked from the wl24 event handler. | 104 | * are invoked from the wl24 event handler. |
105 | */ | 105 | */ |
106 | static void wl3501_config(dev_link_t *link); | 106 | static int wl3501_config(struct pcmcia_device *link); |
107 | static void wl3501_release(dev_link_t *link); | 107 | static void wl3501_release(struct pcmcia_device *link); |
108 | 108 | ||
109 | /* | 109 | /* |
110 | * 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 |
@@ -226,17 +226,6 @@ static void iw_copy_mgmt_info_element(struct iw_mgmt_info_element *to, | |||
226 | iw_set_mgmt_info_element(from->id, to, from->data, from->len); | 226 | iw_set_mgmt_info_element(from->id, to, from->data, from->len); |
227 | } | 227 | } |
228 | 228 | ||
229 | /* | ||
230 | * A linked list of "instances" of the wl24 device. Each actual PCMCIA card | ||
231 | * corresponds to one device instance, and is described by one dev_link_t | ||
232 | * structure (defined in ds.h). | ||
233 | * | ||
234 | * You may not want to use a linked list for this -- for example, the memory | ||
235 | * card driver uses an array of dev_link_t pointers, where minor device numbers | ||
236 | * are used to derive the corresponding array index. | ||
237 | */ | ||
238 | static dev_link_t *wl3501_dev_list; | ||
239 | |||
240 | static inline void wl3501_switch_page(struct wl3501_card *this, u8 page) | 229 | static inline void wl3501_switch_page(struct wl3501_card *this, u8 page) |
241 | { | 230 | { |
242 | wl3501_outb(page, this->base_addr + WL3501_NIC_BSS); | 231 | wl3501_outb(page, this->base_addr + WL3501_NIC_BSS); |
@@ -1281,15 +1270,10 @@ static int wl3501_close(struct net_device *dev) | |||
1281 | struct wl3501_card *this = dev->priv; | 1270 | struct wl3501_card *this = dev->priv; |
1282 | int rc = -ENODEV; | 1271 | int rc = -ENODEV; |
1283 | unsigned long flags; | 1272 | unsigned long flags; |
1284 | dev_link_t *link; | 1273 | struct pcmcia_device *link; |
1274 | link = this->p_dev; | ||
1285 | 1275 | ||
1286 | spin_lock_irqsave(&this->lock, flags); | 1276 | spin_lock_irqsave(&this->lock, flags); |
1287 | /* Check if the device is in wl3501_dev_list */ | ||
1288 | for (link = wl3501_dev_list; link; link = link->next) | ||
1289 | if (link->priv == dev) | ||
1290 | break; | ||
1291 | if (!link) | ||
1292 | goto out; | ||
1293 | link->open--; | 1277 | link->open--; |
1294 | 1278 | ||
1295 | /* Stop wl3501_hard_start_xmit() from now on */ | 1279 | /* Stop wl3501_hard_start_xmit() from now on */ |
@@ -1301,7 +1285,6 @@ static int wl3501_close(struct net_device *dev) | |||
1301 | 1285 | ||
1302 | rc = 0; | 1286 | rc = 0; |
1303 | printk(KERN_INFO "%s: WL3501 closed\n", dev->name); | 1287 | printk(KERN_INFO "%s: WL3501 closed\n", dev->name); |
1304 | out: | ||
1305 | spin_unlock_irqrestore(&this->lock, flags); | 1288 | spin_unlock_irqrestore(&this->lock, flags); |
1306 | return rc; | 1289 | return rc; |
1307 | } | 1290 | } |
@@ -1400,14 +1383,11 @@ static int wl3501_open(struct net_device *dev) | |||
1400 | int rc = -ENODEV; | 1383 | int rc = -ENODEV; |
1401 | struct wl3501_card *this = dev->priv; | 1384 | struct wl3501_card *this = dev->priv; |
1402 | unsigned long flags; | 1385 | unsigned long flags; |
1403 | dev_link_t *link; | 1386 | struct pcmcia_device *link; |
1387 | link = this->p_dev; | ||
1404 | 1388 | ||
1405 | spin_lock_irqsave(&this->lock, flags); | 1389 | spin_lock_irqsave(&this->lock, flags); |
1406 | /* Check if the device is in wl3501_dev_list */ | 1390 | if (!pcmcia_dev_present(link)) |
1407 | for (link = wl3501_dev_list; link; link = link->next) | ||
1408 | if (link->priv == dev) | ||
1409 | break; | ||
1410 | if (!DEV_OK(link)) | ||
1411 | goto out; | 1391 | goto out; |
1412 | netif_device_attach(dev); | 1392 | netif_device_attach(dev); |
1413 | link->open++; | 1393 | link->open++; |
@@ -1497,38 +1477,23 @@ static struct ethtool_ops ops = { | |||
1497 | * Services. If it has been released, all local data structures are freed. | 1477 | * Services. If it has been released, all local data structures are freed. |
1498 | * Otherwise, the structures will be freed when the device is released. | 1478 | * Otherwise, the structures will be freed when the device is released. |
1499 | */ | 1479 | */ |
1500 | static void wl3501_detach(struct pcmcia_device *p_dev) | 1480 | static void wl3501_detach(struct pcmcia_device *link) |
1501 | { | 1481 | { |
1502 | dev_link_t *link = dev_to_instance(p_dev); | ||
1503 | dev_link_t **linkp; | ||
1504 | struct net_device *dev = link->priv; | 1482 | struct net_device *dev = link->priv; |
1505 | 1483 | ||
1506 | /* Locate device structure */ | ||
1507 | for (linkp = &wl3501_dev_list; *linkp; linkp = &(*linkp)->next) | ||
1508 | if (*linkp == link) | ||
1509 | break; | ||
1510 | if (!*linkp) | ||
1511 | goto out; | ||
1512 | |||
1513 | /* If the device is currently configured and active, we won't actually | 1484 | /* If the device is currently configured and active, we won't actually |
1514 | * delete it yet. Instead, it is marked so that when the release() | 1485 | * delete it yet. Instead, it is marked so that when the release() |
1515 | * function is called, that will trigger a proper detach(). */ | 1486 | * function is called, that will trigger a proper detach(). */ |
1516 | 1487 | ||
1517 | if (link->state & DEV_CONFIG) { | 1488 | while (link->open > 0) |
1518 | while (link->open > 0) | 1489 | wl3501_close(dev); |
1519 | wl3501_close(dev); | ||
1520 | |||
1521 | netif_device_detach(dev); | ||
1522 | wl3501_release(link); | ||
1523 | } | ||
1524 | 1490 | ||
1525 | /* Unlink device structure, free pieces */ | 1491 | netif_device_detach(dev); |
1526 | *linkp = link->next; | 1492 | wl3501_release(link); |
1527 | 1493 | ||
1528 | if (link->priv) | 1494 | if (link->priv) |
1529 | free_netdev(link->priv); | 1495 | free_netdev(link->priv); |
1530 | kfree(link); | 1496 | |
1531 | out: | ||
1532 | return; | 1497 | return; |
1533 | } | 1498 | } |
1534 | 1499 | ||
@@ -1953,33 +1918,26 @@ static const struct iw_handler_def wl3501_handler_def = { | |||
1953 | * The dev_link structure is initialized, but we don't actually configure the | 1918 | * The dev_link structure is initialized, but we don't actually configure the |
1954 | * card at this point -- we wait until we receive a card insertion event. | 1919 | * card at this point -- we wait until we receive a card insertion event. |
1955 | */ | 1920 | */ |
1956 | static int wl3501_attach(struct pcmcia_device *p_dev) | 1921 | static int wl3501_probe(struct pcmcia_device *p_dev) |
1957 | { | 1922 | { |
1958 | dev_link_t *link; | ||
1959 | struct net_device *dev; | 1923 | struct net_device *dev; |
1960 | struct wl3501_card *this; | 1924 | struct wl3501_card *this; |
1961 | 1925 | ||
1962 | /* Initialize the dev_link_t structure */ | ||
1963 | link = kzalloc(sizeof(*link), GFP_KERNEL); | ||
1964 | if (!link) | ||
1965 | return -ENOMEM; | ||
1966 | |||
1967 | /* The io structure describes IO port mapping */ | 1926 | /* The io structure describes IO port mapping */ |
1968 | link->io.NumPorts1 = 16; | 1927 | p_dev->io.NumPorts1 = 16; |
1969 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | 1928 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; |
1970 | link->io.IOAddrLines = 5; | 1929 | p_dev->io.IOAddrLines = 5; |
1971 | 1930 | ||
1972 | /* Interrupt setup */ | 1931 | /* Interrupt setup */ |
1973 | link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; | 1932 | p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; |
1974 | link->irq.IRQInfo1 = IRQ_LEVEL_ID; | 1933 | p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID; |
1975 | link->irq.Handler = wl3501_interrupt; | 1934 | p_dev->irq.Handler = wl3501_interrupt; |
1976 | 1935 | ||
1977 | /* General socket configuration */ | 1936 | /* General socket configuration */ |
1978 | link->conf.Attributes = CONF_ENABLE_IRQ; | 1937 | p_dev->conf.Attributes = CONF_ENABLE_IRQ; |
1979 | link->conf.Vcc = 50; | 1938 | p_dev->conf.IntType = INT_MEMORY_AND_IO; |
1980 | link->conf.IntType = INT_MEMORY_AND_IO; | 1939 | p_dev->conf.ConfigIndex = 1; |
1981 | link->conf.ConfigIndex = 1; | 1940 | p_dev->conf.Present = PRESENT_OPTION; |
1982 | link->conf.Present = PRESENT_OPTION; | ||
1983 | 1941 | ||
1984 | dev = alloc_etherdev(sizeof(struct wl3501_card)); | 1942 | dev = alloc_etherdev(sizeof(struct wl3501_card)); |
1985 | if (!dev) | 1943 | if (!dev) |
@@ -1992,22 +1950,15 @@ static int wl3501_attach(struct pcmcia_device *p_dev) | |||
1992 | dev->get_stats = wl3501_get_stats; | 1950 | dev->get_stats = wl3501_get_stats; |
1993 | this = dev->priv; | 1951 | this = dev->priv; |
1994 | this->wireless_data.spy_data = &this->spy_data; | 1952 | this->wireless_data.spy_data = &this->spy_data; |
1953 | this->p_dev = p_dev; | ||
1995 | dev->wireless_data = &this->wireless_data; | 1954 | dev->wireless_data = &this->wireless_data; |
1996 | dev->wireless_handlers = (struct iw_handler_def *)&wl3501_handler_def; | 1955 | dev->wireless_handlers = (struct iw_handler_def *)&wl3501_handler_def; |
1997 | SET_ETHTOOL_OPS(dev, &ops); | 1956 | SET_ETHTOOL_OPS(dev, &ops); |
1998 | netif_stop_queue(dev); | 1957 | netif_stop_queue(dev); |
1999 | link->priv = link->irq.Instance = dev; | 1958 | p_dev->priv = p_dev->irq.Instance = dev; |
2000 | |||
2001 | link->handle = p_dev; | ||
2002 | p_dev->instance = link; | ||
2003 | |||
2004 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | ||
2005 | wl3501_config(link); | ||
2006 | 1959 | ||
2007 | return 0; | 1960 | return wl3501_config(p_dev); |
2008 | out_link: | 1961 | out_link: |
2009 | kfree(link); | ||
2010 | link = NULL; | ||
2011 | return -ENOMEM; | 1962 | return -ENOMEM; |
2012 | } | 1963 | } |
2013 | 1964 | ||
@@ -2022,11 +1973,10 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) | |||
2022 | * received, to configure the PCMCIA socket, and to make the ethernet device | 1973 | * received, to configure the PCMCIA socket, and to make the ethernet device |
2023 | * available to the system. | 1974 | * available to the system. |
2024 | */ | 1975 | */ |
2025 | static void wl3501_config(dev_link_t *link) | 1976 | static int wl3501_config(struct pcmcia_device *link) |
2026 | { | 1977 | { |
2027 | tuple_t tuple; | 1978 | tuple_t tuple; |
2028 | cisparse_t parse; | 1979 | cisparse_t parse; |
2029 | client_handle_t handle = link->handle; | ||
2030 | struct net_device *dev = link->priv; | 1980 | struct net_device *dev = link->priv; |
2031 | int i = 0, j, last_fn, last_ret; | 1981 | int i = 0, j, last_fn, last_ret; |
2032 | unsigned char bf[64]; | 1982 | unsigned char bf[64]; |
@@ -2035,18 +1985,15 @@ static void wl3501_config(dev_link_t *link) | |||
2035 | /* This reads the card's CONFIG tuple to find its config registers. */ | 1985 | /* This reads the card's CONFIG tuple to find its config registers. */ |
2036 | tuple.Attributes = 0; | 1986 | tuple.Attributes = 0; |
2037 | tuple.DesiredTuple = CISTPL_CONFIG; | 1987 | tuple.DesiredTuple = CISTPL_CONFIG; |
2038 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); | 1988 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); |
2039 | tuple.TupleData = bf; | 1989 | tuple.TupleData = bf; |
2040 | tuple.TupleDataMax = sizeof(bf); | 1990 | tuple.TupleDataMax = sizeof(bf); |
2041 | tuple.TupleOffset = 0; | 1991 | tuple.TupleOffset = 0; |
2042 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); | 1992 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); |
2043 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); | 1993 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); |
2044 | link->conf.ConfigBase = parse.config.base; | 1994 | link->conf.ConfigBase = parse.config.base; |
2045 | link->conf.Present = parse.config.rmask[0]; | 1995 | link->conf.Present = parse.config.rmask[0]; |
2046 | 1996 | ||
2047 | /* Configure card */ | ||
2048 | link->state |= DEV_CONFIG; | ||
2049 | |||
2050 | /* Try allocating IO ports. This tries a few fixed addresses. If you | 1997 | /* Try allocating IO ports. This tries a few fixed addresses. If you |
2051 | * want, you can also read the card's config table to pick addresses -- | 1998 | * want, you can also read the card's config table to pick addresses -- |
2052 | * see the serial driver for an example. */ | 1999 | * see the serial driver for an example. */ |
@@ -2056,28 +2003,28 @@ static void wl3501_config(dev_link_t *link) | |||
2056 | * 0x200-0x2ff, and so on, because this seems safer */ | 2003 | * 0x200-0x2ff, and so on, because this seems safer */ |
2057 | link->io.BasePort1 = j; | 2004 | link->io.BasePort1 = j; |
2058 | link->io.BasePort2 = link->io.BasePort1 + 0x10; | 2005 | link->io.BasePort2 = link->io.BasePort1 + 0x10; |
2059 | i = pcmcia_request_io(link->handle, &link->io); | 2006 | i = pcmcia_request_io(link, &link->io); |
2060 | if (i == CS_SUCCESS) | 2007 | if (i == CS_SUCCESS) |
2061 | break; | 2008 | break; |
2062 | } | 2009 | } |
2063 | if (i != CS_SUCCESS) { | 2010 | if (i != CS_SUCCESS) { |
2064 | cs_error(link->handle, RequestIO, i); | 2011 | cs_error(link, RequestIO, i); |
2065 | goto failed; | 2012 | goto failed; |
2066 | } | 2013 | } |
2067 | 2014 | ||
2068 | /* Now allocate an interrupt line. Note that this does not actually | 2015 | /* Now allocate an interrupt line. Note that this does not actually |
2069 | * assign a handler to the interrupt. */ | 2016 | * assign a handler to the interrupt. */ |
2070 | 2017 | ||
2071 | CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); | 2018 | CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); |
2072 | 2019 | ||
2073 | /* This actually configures the PCMCIA socket -- setting up the I/O | 2020 | /* This actually configures the PCMCIA socket -- setting up the I/O |
2074 | * windows and the interrupt mapping. */ | 2021 | * windows and the interrupt mapping. */ |
2075 | 2022 | ||
2076 | CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); | 2023 | CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); |
2077 | 2024 | ||
2078 | dev->irq = link->irq.AssignedIRQ; | 2025 | dev->irq = link->irq.AssignedIRQ; |
2079 | dev->base_addr = link->io.BasePort1; | 2026 | dev->base_addr = link->io.BasePort1; |
2080 | SET_NETDEV_DEV(dev, &handle_to_dev(handle)); | 2027 | SET_NETDEV_DEV(dev, &handle_to_dev(link)); |
2081 | if (register_netdev(dev)) { | 2028 | if (register_netdev(dev)) { |
2082 | printk(KERN_NOTICE "wl3501_cs: register_netdev() failed\n"); | 2029 | printk(KERN_NOTICE "wl3501_cs: register_netdev() failed\n"); |
2083 | goto failed; | 2030 | goto failed; |
@@ -2088,10 +2035,9 @@ static void wl3501_config(dev_link_t *link) | |||
2088 | this = dev->priv; | 2035 | this = dev->priv; |
2089 | /* | 2036 | /* |
2090 | * At this point, the dev_node_t structure(s) should be initialized and | 2037 | * At this point, the dev_node_t structure(s) should be initialized and |
2091 | * arranged in a linked list at link->dev. | 2038 | * arranged in a linked list at link->dev_node. |
2092 | */ | 2039 | */ |
2093 | link->dev = &this->node; | 2040 | link->dev_node = &this->node; |
2094 | link->state &= ~DEV_CONFIG_PENDING; | ||
2095 | 2041 | ||
2096 | this->base_addr = dev->base_addr; | 2042 | this->base_addr = dev->base_addr; |
2097 | 2043 | ||
@@ -2127,13 +2073,13 @@ static void wl3501_config(dev_link_t *link) | |||
2127 | spin_lock_init(&this->lock); | 2073 | spin_lock_init(&this->lock); |
2128 | init_waitqueue_head(&this->wait); | 2074 | init_waitqueue_head(&this->wait); |
2129 | netif_start_queue(dev); | 2075 | netif_start_queue(dev); |
2130 | goto out; | 2076 | return 0; |
2077 | |||
2131 | cs_failed: | 2078 | cs_failed: |
2132 | cs_error(link->handle, last_fn, last_ret); | 2079 | cs_error(link, last_fn, last_ret); |
2133 | failed: | 2080 | failed: |
2134 | wl3501_release(link); | 2081 | wl3501_release(link); |
2135 | out: | 2082 | return -ENODEV; |
2136 | return; | ||
2137 | } | 2083 | } |
2138 | 2084 | ||
2139 | /** | 2085 | /** |
@@ -2144,52 +2090,36 @@ out: | |||
2144 | * and release the PCMCIA configuration. If the device is still open, this | 2090 | * and release the PCMCIA configuration. If the device is still open, this |
2145 | * will be postponed until it is closed. | 2091 | * will be postponed until it is closed. |
2146 | */ | 2092 | */ |
2147 | static void wl3501_release(dev_link_t *link) | 2093 | static void wl3501_release(struct pcmcia_device *link) |
2148 | { | 2094 | { |
2149 | struct net_device *dev = link->priv; | 2095 | struct net_device *dev = link->priv; |
2150 | 2096 | ||
2151 | /* Unlink the device chain */ | 2097 | /* Unlink the device chain */ |
2152 | if (link->dev) { | 2098 | if (link->dev_node) |
2153 | unregister_netdev(dev); | 2099 | unregister_netdev(dev); |
2154 | link->dev = NULL; | ||
2155 | } | ||
2156 | 2100 | ||
2157 | /* Don't bother checking to see if these succeed or not */ | 2101 | pcmcia_disable_device(link); |
2158 | pcmcia_release_configuration(link->handle); | ||
2159 | pcmcia_release_io(link->handle, &link->io); | ||
2160 | pcmcia_release_irq(link->handle, &link->irq); | ||
2161 | link->state &= ~DEV_CONFIG; | ||
2162 | } | 2102 | } |
2163 | 2103 | ||
2164 | static int wl3501_suspend(struct pcmcia_device *p_dev) | 2104 | static int wl3501_suspend(struct pcmcia_device *link) |
2165 | { | 2105 | { |
2166 | dev_link_t *link = dev_to_instance(p_dev); | ||
2167 | struct net_device *dev = link->priv; | 2106 | struct net_device *dev = link->priv; |
2168 | 2107 | ||
2169 | link->state |= DEV_SUSPEND; | ||
2170 | |||
2171 | wl3501_pwr_mgmt(dev->priv, WL3501_SUSPEND); | 2108 | wl3501_pwr_mgmt(dev->priv, WL3501_SUSPEND); |
2172 | if (link->state & DEV_CONFIG) { | 2109 | if (link->open) |
2173 | if (link->open) | 2110 | netif_device_detach(dev); |
2174 | netif_device_detach(dev); | ||
2175 | pcmcia_release_configuration(link->handle); | ||
2176 | } | ||
2177 | 2111 | ||
2178 | return 0; | 2112 | return 0; |
2179 | } | 2113 | } |
2180 | 2114 | ||
2181 | static int wl3501_resume(struct pcmcia_device *p_dev) | 2115 | static int wl3501_resume(struct pcmcia_device *link) |
2182 | { | 2116 | { |
2183 | dev_link_t *link = dev_to_instance(p_dev); | ||
2184 | struct net_device *dev = link->priv; | 2117 | struct net_device *dev = link->priv; |
2185 | 2118 | ||
2186 | wl3501_pwr_mgmt(dev->priv, WL3501_RESUME); | 2119 | wl3501_pwr_mgmt(dev->priv, WL3501_RESUME); |
2187 | if (link->state & DEV_CONFIG) { | 2120 | if (link->open) { |
2188 | pcmcia_request_configuration(link->handle, &link->conf); | 2121 | wl3501_reset(dev); |
2189 | if (link->open) { | 2122 | netif_device_attach(dev); |
2190 | wl3501_reset(dev); | ||
2191 | netif_device_attach(dev); | ||
2192 | } | ||
2193 | } | 2123 | } |
2194 | 2124 | ||
2195 | return 0; | 2125 | return 0; |
@@ -2207,7 +2137,7 @@ static struct pcmcia_driver wl3501_driver = { | |||
2207 | .drv = { | 2137 | .drv = { |
2208 | .name = "wl3501_cs", | 2138 | .name = "wl3501_cs", |
2209 | }, | 2139 | }, |
2210 | .probe = wl3501_attach, | 2140 | .probe = wl3501_probe, |
2211 | .remove = wl3501_detach, | 2141 | .remove = wl3501_detach, |
2212 | .id_table = wl3501_ids, | 2142 | .id_table = wl3501_ids, |
2213 | .suspend = wl3501_suspend, | 2143 | .suspend = wl3501_suspend, |
@@ -2221,9 +2151,7 @@ static int __init wl3501_init_module(void) | |||
2221 | 2151 | ||
2222 | static void __exit wl3501_exit_module(void) | 2152 | static void __exit wl3501_exit_module(void) |
2223 | { | 2153 | { |
2224 | dprintk(0, ": unloading"); | ||
2225 | pcmcia_unregister_driver(&wl3501_driver); | 2154 | pcmcia_unregister_driver(&wl3501_driver); |
2226 | BUG_ON(wl3501_dev_list != NULL); | ||
2227 | } | 2155 | } |
2228 | 2156 | ||
2229 | module_init(wl3501_init_module); | 2157 | module_init(wl3501_init_module); |