X-Git-Url: http://git.onelab.eu/?p=linux-2.6.git;a=blobdiff_plain;f=drivers%2Fnet%2Fwireless%2Fwl3501_cs.c;fp=drivers%2Fnet%2Fwireless%2Fwl3501_cs.c;h=c250f08c8dd51dd99206123d1bf3025985dae567;hp=48e10b0c7e747ede33fe13c5dbd6582511aee870;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hpb=76828883507a47dae78837ab5dec5a5b4513c667 diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c index 48e10b0c7..c250f08c8 100644 --- a/drivers/net/wireless/wl3501_cs.c +++ b/drivers/net/wireless/wl3501_cs.c @@ -28,7 +28,6 @@ */ #undef REALLY_SLOW_IO /* most systems can safely undef this */ -#include #include #include #include @@ -103,8 +102,8 @@ module_param(pc_debug, int, 0); * release a socket, in response to card insertion and ejection events. They * are invoked from the wl24 event handler. */ -static void wl3501_config(dev_link_t *link); -static void wl3501_release(dev_link_t *link); +static int wl3501_config(struct pcmcia_device *link); +static void wl3501_release(struct pcmcia_device *link); /* * The dev_info variable is the "key" that is used to match up this @@ -226,17 +225,6 @@ static void iw_copy_mgmt_info_element(struct iw_mgmt_info_element *to, iw_set_mgmt_info_element(from->id, to, from->data, from->len); } -/* - * A linked list of "instances" of the wl24 device. Each actual PCMCIA card - * corresponds to one device instance, and is described by one dev_link_t - * structure (defined in ds.h). - * - * You may not want to use a linked list for this -- for example, the memory - * card driver uses an array of dev_link_t pointers, where minor device numbers - * are used to derive the corresponding array index. - */ -static dev_link_t *wl3501_dev_list; - static inline void wl3501_switch_page(struct wl3501_card *this, u8 page) { wl3501_outb(page, this->base_addr + WL3501_NIC_BSS); @@ -1157,7 +1145,6 @@ static inline void wl3501_ack_interrupt(struct wl3501_card *this) * wl3501_interrupt - Hardware interrupt from card. * @irq - Interrupt number * @dev_id - net_device - * @regs - registers * * We must acknowledge the interrupt as soon as possible, and block the * interrupt from the same card immediately to prevent re-entry. @@ -1166,27 +1153,20 @@ static inline void wl3501_ack_interrupt(struct wl3501_card *this) * On the other hand, to prevent SUTRO from malfunctioning, we must * unlock the SUTRO as soon as possible. */ -static irqreturn_t wl3501_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t wl3501_interrupt(int irq, void *dev_id) { - struct net_device *dev = (struct net_device *)dev_id; + struct net_device *dev = dev_id; struct wl3501_card *this; - int handled = 1; - if (!dev) - goto unknown; - this = dev->priv; + this = netdev_priv(dev); spin_lock(&this->lock); wl3501_ack_interrupt(this); wl3501_block_interrupt(this); wl3501_rx_interrupt(dev); wl3501_unblock_interrupt(this); spin_unlock(&this->lock); -out: - return IRQ_RETVAL(handled); -unknown: - handled = 0; - printk(KERN_ERR "%s: irq %d for unknown device.\n", __FUNCTION__, irq); - goto out; + + return IRQ_HANDLED; } static int wl3501_reset_board(struct wl3501_card *this) @@ -1281,15 +1261,10 @@ static int wl3501_close(struct net_device *dev) struct wl3501_card *this = dev->priv; int rc = -ENODEV; unsigned long flags; - dev_link_t *link; + struct pcmcia_device *link; + link = this->p_dev; spin_lock_irqsave(&this->lock, flags); - /* Check if the device is in wl3501_dev_list */ - for (link = wl3501_dev_list; link; link = link->next) - if (link->priv == dev) - break; - if (!link) - goto out; link->open--; /* Stop wl3501_hard_start_xmit() from now on */ @@ -1301,7 +1276,6 @@ static int wl3501_close(struct net_device *dev) rc = 0; printk(KERN_INFO "%s: WL3501 closed\n", dev->name); -out: spin_unlock_irqrestore(&this->lock, flags); return rc; } @@ -1400,14 +1374,11 @@ static int wl3501_open(struct net_device *dev) int rc = -ENODEV; struct wl3501_card *this = dev->priv; unsigned long flags; - dev_link_t *link; + struct pcmcia_device *link; + link = this->p_dev; spin_lock_irqsave(&this->lock, flags); - /* Check if the device is in wl3501_dev_list */ - for (link = wl3501_dev_list; link; link = link->next) - if (link->priv == dev) - break; - if (!DEV_OK(link)) + if (!pcmcia_dev_present(link)) goto out; netif_device_attach(dev); link->open++; @@ -1485,7 +1456,7 @@ static void wl3501_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *i strlcpy(info->driver, wl3501_dev_info, sizeof(info->driver)); } -static struct ethtool_ops ops = { +static const struct ethtool_ops ops = { .get_drvinfo = wl3501_get_drvinfo }; @@ -1497,38 +1468,23 @@ static struct ethtool_ops ops = { * Services. If it has been released, all local data structures are freed. * Otherwise, the structures will be freed when the device is released. */ -static void wl3501_detach(struct pcmcia_device *p_dev) +static void wl3501_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); - dev_link_t **linkp; struct net_device *dev = link->priv; - /* Locate device structure */ - for (linkp = &wl3501_dev_list; *linkp; linkp = &(*linkp)->next) - if (*linkp == link) - break; - if (!*linkp) - goto out; - /* If the device is currently configured and active, we won't actually * delete it yet. Instead, it is marked so that when the release() * function is called, that will trigger a proper detach(). */ - if (link->state & DEV_CONFIG) { - while (link->open > 0) - wl3501_close(dev); - - netif_device_detach(dev); - wl3501_release(link); - } + while (link->open > 0) + wl3501_close(dev); - /* Unlink device structure, free pieces */ - *linkp = link->next; + netif_device_detach(dev); + wl3501_release(link); if (link->priv) free_netdev(link->priv); - kfree(link); -out: + return; } @@ -1838,15 +1794,15 @@ static int wl3501_get_retry(struct net_device *dev, &retry, sizeof(retry)); if (rc) goto out; - if (wrqu->retry.flags & IW_RETRY_MAX) { - wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX; + if (wrqu->retry.flags & IW_RETRY_LONG) { + wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_LONG; goto set_value; } rc = wl3501_get_mib_value(this, WL3501_MIB_ATTR_SHORT_RETRY_LIMIT, &retry, sizeof(retry)); if (rc) goto out; - wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN; + wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_SHORT; set_value: wrqu->retry.value = retry; wrqu->retry.disabled = 0; @@ -1953,33 +1909,25 @@ static const struct iw_handler_def wl3501_handler_def = { * The dev_link structure is initialized, but we don't actually configure the * card at this point -- we wait until we receive a card insertion event. */ -static int wl3501_attach(struct pcmcia_device *p_dev) +static int wl3501_probe(struct pcmcia_device *p_dev) { - dev_link_t *link; struct net_device *dev; struct wl3501_card *this; - /* Initialize the dev_link_t structure */ - link = kzalloc(sizeof(*link), GFP_KERNEL); - if (!link) - return -ENOMEM; - /* The io structure describes IO port mapping */ - link->io.NumPorts1 = 16; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - link->io.IOAddrLines = 5; + p_dev->io.NumPorts1 = 16; + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + p_dev->io.IOAddrLines = 5; /* Interrupt setup */ - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; - link->irq.IRQInfo1 = IRQ_LEVEL_ID; - link->irq.Handler = wl3501_interrupt; + p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; + p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID; + p_dev->irq.Handler = wl3501_interrupt; /* General socket configuration */ - link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.Vcc = 50; - link->conf.IntType = INT_MEMORY_AND_IO; - link->conf.ConfigIndex = 1; - link->conf.Present = PRESENT_OPTION; + p_dev->conf.Attributes = CONF_ENABLE_IRQ; + p_dev->conf.IntType = INT_MEMORY_AND_IO; + p_dev->conf.ConfigIndex = 1; dev = alloc_etherdev(sizeof(struct wl3501_card)); if (!dev) @@ -1992,22 +1940,15 @@ static int wl3501_attach(struct pcmcia_device *p_dev) dev->get_stats = wl3501_get_stats; this = dev->priv; this->wireless_data.spy_data = &this->spy_data; + this->p_dev = p_dev; dev->wireless_data = &this->wireless_data; dev->wireless_handlers = (struct iw_handler_def *)&wl3501_handler_def; SET_ETHTOOL_OPS(dev, &ops); netif_stop_queue(dev); - link->priv = link->irq.Instance = dev; - - link->handle = p_dev; - p_dev->instance = link; + p_dev->priv = p_dev->irq.Instance = dev; - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - wl3501_config(link); - - return 0; + return wl3501_config(p_dev); out_link: - kfree(link); - link = NULL; return -ENOMEM; } @@ -2022,31 +1963,12 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) * received, to configure the PCMCIA socket, and to make the ethernet device * available to the system. */ -static void wl3501_config(dev_link_t *link) +static int wl3501_config(struct pcmcia_device *link) { - tuple_t tuple; - cisparse_t parse; - client_handle_t handle = link->handle; struct net_device *dev = link->priv; int i = 0, j, last_fn, last_ret; - unsigned char bf[64]; struct wl3501_card *this; - /* This reads the card's CONFIG tuple to find its config registers. */ - tuple.Attributes = 0; - tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); - tuple.TupleData = bf; - tuple.TupleDataMax = sizeof(bf); - tuple.TupleOffset = 0; - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); - link->conf.ConfigBase = parse.config.base; - link->conf.Present = parse.config.rmask[0]; - - /* Configure card */ - link->state |= DEV_CONFIG; - /* Try allocating IO ports. This tries a few fixed addresses. If you * want, you can also read the card's config table to pick addresses -- * see the serial driver for an example. */ @@ -2056,28 +1978,28 @@ static void wl3501_config(dev_link_t *link) * 0x200-0x2ff, and so on, because this seems safer */ link->io.BasePort1 = j; link->io.BasePort2 = link->io.BasePort1 + 0x10; - i = pcmcia_request_io(link->handle, &link->io); + i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) break; } if (i != CS_SUCCESS) { - cs_error(link->handle, RequestIO, i); + cs_error(link, RequestIO, i); goto failed; } /* Now allocate an interrupt line. Note that this does not actually * assign a handler to the interrupt. */ - CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); /* This actually configures the PCMCIA socket -- setting up the I/O * windows and the interrupt mapping. */ - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); dev->irq = link->irq.AssignedIRQ; dev->base_addr = link->io.BasePort1; - SET_NETDEV_DEV(dev, &handle_to_dev(handle)); + SET_NETDEV_DEV(dev, &handle_to_dev(link)); if (register_netdev(dev)) { printk(KERN_NOTICE "wl3501_cs: register_netdev() failed\n"); goto failed; @@ -2088,10 +2010,9 @@ static void wl3501_config(dev_link_t *link) this = dev->priv; /* * At this point, the dev_node_t structure(s) should be initialized and - * arranged in a linked list at link->dev. + * arranged in a linked list at link->dev_node. */ - link->dev = &this->node; - link->state &= ~DEV_CONFIG_PENDING; + link->dev_node = &this->node; this->base_addr = dev->base_addr; @@ -2127,13 +2048,13 @@ static void wl3501_config(dev_link_t *link) spin_lock_init(&this->lock); init_waitqueue_head(&this->wait); netif_start_queue(dev); - goto out; + return 0; + cs_failed: - cs_error(link->handle, last_fn, last_ret); + cs_error(link, last_fn, last_ret); failed: wl3501_release(link); -out: - return; + return -ENODEV; } /** @@ -2144,52 +2065,36 @@ out: * and release the PCMCIA configuration. If the device is still open, this * will be postponed until it is closed. */ -static void wl3501_release(dev_link_t *link) +static void wl3501_release(struct pcmcia_device *link) { struct net_device *dev = link->priv; /* Unlink the device chain */ - if (link->dev) { + if (link->dev_node) unregister_netdev(dev); - link->dev = NULL; - } - /* Don't bother checking to see if these succeed or not */ - pcmcia_release_configuration(link->handle); - pcmcia_release_io(link->handle, &link->io); - pcmcia_release_irq(link->handle, &link->irq); - link->state &= ~DEV_CONFIG; + pcmcia_disable_device(link); } -static int wl3501_suspend(struct pcmcia_device *p_dev) +static int wl3501_suspend(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - link->state |= DEV_SUSPEND; - wl3501_pwr_mgmt(dev->priv, WL3501_SUSPEND); - if (link->state & DEV_CONFIG) { - if (link->open) - netif_device_detach(dev); - pcmcia_release_configuration(link->handle); - } + if (link->open) + netif_device_detach(dev); return 0; } -static int wl3501_resume(struct pcmcia_device *p_dev) +static int wl3501_resume(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; wl3501_pwr_mgmt(dev->priv, WL3501_RESUME); - if (link->state & DEV_CONFIG) { - pcmcia_request_configuration(link->handle, &link->conf); - if (link->open) { - wl3501_reset(dev); - netif_device_attach(dev); - } + if (link->open) { + wl3501_reset(dev); + netif_device_attach(dev); } return 0; @@ -2207,7 +2112,7 @@ static struct pcmcia_driver wl3501_driver = { .drv = { .name = "wl3501_cs", }, - .probe = wl3501_attach, + .probe = wl3501_probe, .remove = wl3501_detach, .id_table = wl3501_ids, .suspend = wl3501_suspend, @@ -2221,9 +2126,7 @@ static int __init wl3501_init_module(void) static void __exit wl3501_exit_module(void) { - dprintk(0, ": unloading"); pcmcia_unregister_driver(&wl3501_driver); - BUG_ON(wl3501_dev_list != NULL); } module_init(wl3501_init_module);