diff options
author | Holger Schurig <hs4233@mail.mn-solutions.de> | 2007-05-25 12:41:52 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2007-06-11 14:28:39 -0400 |
commit | 435a1acba23437a6c8462dd8437e48cdf09a2f71 (patch) | |
tree | 69b7f6c02f92d0148d8e470137446b0125e14681 /drivers/net | |
parent | 084708b61014776198c56d1606343d4f504c691e (diff) |
[PATCH] libertas: fix RESET logic at unload time
Previously, we had a fixed array of 5 elements where we remembered all
initialized devices. This has been changed to use a "struct list_head"
organization, which is IMHO cleaner.
Also renamed usb_cardp to cardp, as in the reset of the code.
Renamed reset_device() to if_usb_reset_device() like many other functions.
Signed-off-by: Holger Schurig <hs4233@mail.mn-solutions.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/libertas/if_usb.c | 84 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/if_usb.h | 7 |
2 files changed, 44 insertions, 47 deletions
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c index ca5d01296a08..97469fe106fb 100644 --- a/drivers/net/wireless/libertas/if_usb.c +++ b/drivers/net/wireless/libertas/if_usb.c | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <linux/moduleparam.h> | 5 | #include <linux/moduleparam.h> |
6 | #include <linux/firmware.h> | 6 | #include <linux/firmware.h> |
7 | #include <linux/netdevice.h> | 7 | #include <linux/netdevice.h> |
8 | #include <linux/list.h> | ||
8 | #include <linux/usb.h> | 9 | #include <linux/usb.h> |
9 | 10 | ||
10 | #include "host.h" | 11 | #include "host.h" |
@@ -21,10 +22,14 @@ static u8 *default_fw_name = "usb8388.bin"; | |||
21 | char *libertas_fw_name = NULL; | 22 | char *libertas_fw_name = NULL; |
22 | module_param_named(fw_name, libertas_fw_name, charp, 0644); | 23 | module_param_named(fw_name, libertas_fw_name, charp, 0644); |
23 | 24 | ||
24 | 25 | /* | |
25 | #define MAX_DEVS 5 | 26 | * We need to send a RESET command to all USB devices before |
26 | static struct net_device *libertas_devs[MAX_DEVS]; | 27 | * we tear down the USB connection. Otherwise we would not |
27 | static int libertas_found = 0; | 28 | * be able to re-init device the device if the module gets |
29 | * loaded again. This is a list of all initialized USB devices, | ||
30 | * for the reset code see if_usb_reset_device() | ||
31 | */ | ||
32 | static LIST_HEAD(usb_devices); | ||
28 | 33 | ||
29 | static struct usb_device_id if_usb_table[] = { | 34 | static struct usb_device_id if_usb_table[] = { |
30 | /* Enter the device signature inside */ | 35 | /* Enter the device signature inside */ |
@@ -37,7 +42,7 @@ MODULE_DEVICE_TABLE(usb, if_usb_table); | |||
37 | 42 | ||
38 | static void if_usb_receive(struct urb *urb); | 43 | static void if_usb_receive(struct urb *urb); |
39 | static void if_usb_receive_fwload(struct urb *urb); | 44 | static void if_usb_receive_fwload(struct urb *urb); |
40 | static int reset_device(wlan_private *priv); | 45 | static int if_usb_reset_device(wlan_private *priv); |
41 | static int if_usb_register_dev(wlan_private * priv); | 46 | static int if_usb_register_dev(wlan_private * priv); |
42 | static int if_usb_unregister_dev(wlan_private *); | 47 | static int if_usb_unregister_dev(wlan_private *); |
43 | static int if_usb_prog_firmware(wlan_private *); | 48 | static int if_usb_prog_firmware(wlan_private *); |
@@ -118,18 +123,18 @@ static int if_usb_probe(struct usb_interface *intf, | |||
118 | struct usb_host_interface *iface_desc; | 123 | struct usb_host_interface *iface_desc; |
119 | struct usb_endpoint_descriptor *endpoint; | 124 | struct usb_endpoint_descriptor *endpoint; |
120 | wlan_private *priv; | 125 | wlan_private *priv; |
121 | struct usb_card_rec *usb_cardp; | 126 | struct usb_card_rec *cardp; |
122 | int i; | 127 | int i; |
123 | 128 | ||
124 | udev = interface_to_usbdev(intf); | 129 | udev = interface_to_usbdev(intf); |
125 | 130 | ||
126 | usb_cardp = kzalloc(sizeof(struct usb_card_rec), GFP_KERNEL); | 131 | cardp = kzalloc(sizeof(struct usb_card_rec), GFP_KERNEL); |
127 | if (!usb_cardp) { | 132 | if (!cardp) { |
128 | lbs_pr_err("Out of memory allocating private data.\n"); | 133 | lbs_pr_err("Out of memory allocating private data.\n"); |
129 | goto error; | 134 | goto error; |
130 | } | 135 | } |
131 | 136 | ||
132 | usb_cardp->udev = udev; | 137 | cardp->udev = udev; |
133 | iface_desc = intf->cur_altsetting; | 138 | iface_desc = intf->cur_altsetting; |
134 | 139 | ||
135 | lbs_deb_usbd(&udev->dev, "bcdUSB = 0x%X bDeviceClass = 0x%X" | 140 | lbs_deb_usbd(&udev->dev, "bcdUSB = 0x%X bDeviceClass = 0x%X" |
@@ -148,17 +153,17 @@ static int if_usb_probe(struct usb_interface *intf, | |||
148 | lbs_deb_usbd(&udev->dev, "Bulk in size is %d\n", | 153 | lbs_deb_usbd(&udev->dev, "Bulk in size is %d\n", |
149 | endpoint->wMaxPacketSize); | 154 | endpoint->wMaxPacketSize); |
150 | if (! | 155 | if (! |
151 | (usb_cardp->rx_urb = | 156 | (cardp->rx_urb = |
152 | usb_alloc_urb(0, GFP_KERNEL))) { | 157 | usb_alloc_urb(0, GFP_KERNEL))) { |
153 | lbs_deb_usbd(&udev->dev, | 158 | lbs_deb_usbd(&udev->dev, |
154 | "Rx URB allocation failed\n"); | 159 | "Rx URB allocation failed\n"); |
155 | goto dealloc; | 160 | goto dealloc; |
156 | } | 161 | } |
157 | usb_cardp->rx_urb_recall = 0; | 162 | cardp->rx_urb_recall = 0; |
158 | 163 | ||
159 | usb_cardp->bulk_in_size = | 164 | cardp->bulk_in_size = |
160 | endpoint->wMaxPacketSize; | 165 | endpoint->wMaxPacketSize; |
161 | usb_cardp->bulk_in_endpointAddr = | 166 | cardp->bulk_in_endpointAddr = |
162 | (endpoint-> | 167 | (endpoint-> |
163 | bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); | 168 | bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); |
164 | lbs_deb_usbd(&udev->dev, "in_endpoint = %d\n", | 169 | lbs_deb_usbd(&udev->dev, "in_endpoint = %d\n", |
@@ -172,27 +177,27 @@ static int if_usb_probe(struct usb_interface *intf, | |||
172 | USB_ENDPOINT_XFER_BULK)) { | 177 | USB_ENDPOINT_XFER_BULK)) { |
173 | /* We found bulk out endpoint */ | 178 | /* We found bulk out endpoint */ |
174 | if (! | 179 | if (! |
175 | (usb_cardp->tx_urb = | 180 | (cardp->tx_urb = |
176 | usb_alloc_urb(0, GFP_KERNEL))) { | 181 | usb_alloc_urb(0, GFP_KERNEL))) { |
177 | lbs_deb_usbd(&udev->dev, | 182 | lbs_deb_usbd(&udev->dev, |
178 | "Tx URB allocation failed\n"); | 183 | "Tx URB allocation failed\n"); |
179 | goto dealloc; | 184 | goto dealloc; |
180 | } | 185 | } |
181 | 186 | ||
182 | usb_cardp->bulk_out_size = | 187 | cardp->bulk_out_size = |
183 | endpoint->wMaxPacketSize; | 188 | endpoint->wMaxPacketSize; |
184 | lbs_deb_usbd(&udev->dev, | 189 | lbs_deb_usbd(&udev->dev, |
185 | "Bulk out size is %d\n", | 190 | "Bulk out size is %d\n", |
186 | endpoint->wMaxPacketSize); | 191 | endpoint->wMaxPacketSize); |
187 | usb_cardp->bulk_out_endpointAddr = | 192 | cardp->bulk_out_endpointAddr = |
188 | endpoint->bEndpointAddress; | 193 | endpoint->bEndpointAddress; |
189 | lbs_deb_usbd(&udev->dev, "out_endpoint = %d\n", | 194 | lbs_deb_usbd(&udev->dev, "out_endpoint = %d\n", |
190 | endpoint->bEndpointAddress); | 195 | endpoint->bEndpointAddress); |
191 | usb_cardp->bulk_out_buffer = | 196 | cardp->bulk_out_buffer = |
192 | kmalloc(MRVDRV_ETH_TX_PACKET_BUFFER_SIZE, | 197 | kmalloc(MRVDRV_ETH_TX_PACKET_BUFFER_SIZE, |
193 | GFP_KERNEL); | 198 | GFP_KERNEL); |
194 | 199 | ||
195 | if (!usb_cardp->bulk_out_buffer) { | 200 | if (!cardp->bulk_out_buffer) { |
196 | lbs_deb_usbd(&udev->dev, | 201 | lbs_deb_usbd(&udev->dev, |
197 | "Could not allocate buffer\n"); | 202 | "Could not allocate buffer\n"); |
198 | goto dealloc; | 203 | goto dealloc; |
@@ -205,7 +210,7 @@ static int if_usb_probe(struct usb_interface *intf, | |||
205 | * about keeping pwlanpriv around since it will be set on our | 210 | * about keeping pwlanpriv around since it will be set on our |
206 | * usb device data in -> add() -> hw_register_dev() -> if_usb_register_dev. | 211 | * usb device data in -> add() -> hw_register_dev() -> if_usb_register_dev. |
207 | */ | 212 | */ |
208 | if (!(priv = libertas_add_card(usb_cardp))) | 213 | if (!(priv = libertas_add_card(cardp))) |
209 | goto dealloc; | 214 | goto dealloc; |
210 | 215 | ||
211 | if (libertas_add_mesh(priv)) | 216 | if (libertas_add_mesh(priv)) |
@@ -221,19 +226,11 @@ static int if_usb_probe(struct usb_interface *intf, | |||
221 | if (libertas_activate_card(priv, libertas_fw_name)) | 226 | if (libertas_activate_card(priv, libertas_fw_name)) |
222 | goto err_activate_card; | 227 | goto err_activate_card; |
223 | 228 | ||
224 | if (libertas_found < MAX_DEVS) { | 229 | list_add_tail(&cardp->list, &usb_devices); |
225 | libertas_devs[libertas_found] = priv->wlan_dev.netdev; | ||
226 | libertas_found++; | ||
227 | } | ||
228 | 230 | ||
229 | usb_get_dev(udev); | 231 | usb_get_dev(udev); |
230 | usb_set_intfdata(intf, usb_cardp); | 232 | usb_set_intfdata(intf, cardp); |
231 | 233 | ||
232 | /* | ||
233 | * return card structure, which can be got back in the | ||
234 | * diconnect function as the ptr | ||
235 | * argument. | ||
236 | */ | ||
237 | return 0; | 234 | return 0; |
238 | 235 | ||
239 | err_activate_card: | 236 | err_activate_card: |
@@ -243,7 +240,7 @@ err_add_mesh: | |||
243 | free_netdev(priv->wlan_dev.netdev); | 240 | free_netdev(priv->wlan_dev.netdev); |
244 | kfree(priv->adapter); | 241 | kfree(priv->adapter); |
245 | dealloc: | 242 | dealloc: |
246 | if_usb_free(usb_cardp); | 243 | if_usb_free(cardp); |
247 | 244 | ||
248 | error: | 245 | error: |
249 | return -ENOMEM; | 246 | return -ENOMEM; |
@@ -251,8 +248,7 @@ error: | |||
251 | 248 | ||
252 | /** | 249 | /** |
253 | * @brief free resource and cleanup | 250 | * @brief free resource and cleanup |
254 | * @param udev pointer to usb_device | 251 | * @param intf USB interface structure |
255 | * @param ptr pointer to usb_cardp | ||
256 | * @return N/A | 252 | * @return N/A |
257 | */ | 253 | */ |
258 | static void if_usb_disconnect(struct usb_interface *intf) | 254 | static void if_usb_disconnect(struct usb_interface *intf) |
@@ -260,7 +256,6 @@ static void if_usb_disconnect(struct usb_interface *intf) | |||
260 | struct usb_card_rec *cardp = usb_get_intfdata(intf); | 256 | struct usb_card_rec *cardp = usb_get_intfdata(intf); |
261 | wlan_private *priv = (wlan_private *) cardp->priv; | 257 | wlan_private *priv = (wlan_private *) cardp->priv; |
262 | wlan_adapter *adapter = NULL; | 258 | wlan_adapter *adapter = NULL; |
263 | int i; | ||
264 | 259 | ||
265 | adapter = priv->adapter; | 260 | adapter = priv->adapter; |
266 | 261 | ||
@@ -269,13 +264,7 @@ static void if_usb_disconnect(struct usb_interface *intf) | |||
269 | */ | 264 | */ |
270 | adapter->surpriseremoved = 1; | 265 | adapter->surpriseremoved = 1; |
271 | 266 | ||
272 | for (i = 0; i<libertas_found; i++) { | 267 | list_del(&cardp->list); |
273 | if (libertas_devs[i]==priv->wlan_dev.netdev) { | ||
274 | libertas_devs[i] = libertas_devs[--libertas_found]; | ||
275 | libertas_devs[libertas_found] = NULL ; | ||
276 | break; | ||
277 | } | ||
278 | } | ||
279 | 268 | ||
280 | /* card is removed and we can call wlan_remove_card */ | 269 | /* card is removed and we can call wlan_remove_card */ |
281 | lbs_deb_usbd(&cardp->udev->dev, "call remove card\n"); | 270 | lbs_deb_usbd(&cardp->udev->dev, "call remove card\n"); |
@@ -384,7 +373,7 @@ static int libertas_do_reset(wlan_private *priv) | |||
384 | ret = usb_reset_device(cardp->udev); | 373 | ret = usb_reset_device(cardp->udev); |
385 | if (!ret) { | 374 | if (!ret) { |
386 | msleep(10); | 375 | msleep(10); |
387 | reset_device(priv); | 376 | if_usb_reset_device(priv); |
388 | msleep(10); | 377 | msleep(10); |
389 | } | 378 | } |
390 | 379 | ||
@@ -772,7 +761,7 @@ static int if_usb_read_event_cause(wlan_private * priv) | |||
772 | return 0; | 761 | return 0; |
773 | } | 762 | } |
774 | 763 | ||
775 | static int reset_device(wlan_private *priv) | 764 | static int if_usb_reset_device(wlan_private *priv) |
776 | { | 765 | { |
777 | int ret; | 766 | int ret; |
778 | 767 | ||
@@ -794,7 +783,7 @@ static int if_usb_unregister_dev(wlan_private * priv) | |||
794 | * again. | 783 | * again. |
795 | */ | 784 | */ |
796 | if (priv) | 785 | if (priv) |
797 | reset_device(priv); | 786 | if_usb_reset_device(priv); |
798 | 787 | ||
799 | return ret; | 788 | return ret; |
800 | } | 789 | } |
@@ -988,13 +977,14 @@ static int if_usb_init_module(void) | |||
988 | 977 | ||
989 | static void if_usb_exit_module(void) | 978 | static void if_usb_exit_module(void) |
990 | { | 979 | { |
991 | int i; | 980 | struct list_head *ptr; |
981 | struct usb_card_rec *cardp; | ||
992 | 982 | ||
993 | lbs_deb_enter(LBS_DEB_MAIN); | 983 | lbs_deb_enter(LBS_DEB_MAIN); |
994 | 984 | ||
995 | for (i = 0; i<libertas_found; i++) { | 985 | list_for_each(ptr, &usb_devices) { |
996 | wlan_private *priv = libertas_devs[i]->priv; | 986 | cardp = list_entry(ptr, struct usb_card_rec, list); |
997 | reset_device(priv); | 987 | if_usb_reset_device((wlan_private *) cardp->priv); |
998 | } | 988 | } |
999 | 989 | ||
1000 | /* API unregisters the driver from USB subsystem */ | 990 | /* API unregisters the driver from USB subsystem */ |
diff --git a/drivers/net/wireless/libertas/if_usb.h b/drivers/net/wireless/libertas/if_usb.h index e994d75c5250..bfad79eb43cf 100644 --- a/drivers/net/wireless/libertas/if_usb.h +++ b/drivers/net/wireless/libertas/if_usb.h | |||
@@ -1,3 +1,8 @@ | |||
1 | #ifndef _LIBERTAS_IF_USB_H | ||
2 | #define _LIBERTAS_IF_USB_H | ||
3 | |||
4 | #include <linux/list.h> | ||
5 | |||
1 | /** | 6 | /** |
2 | * This file contains definition for USB interface. | 7 | * This file contains definition for USB interface. |
3 | */ | 8 | */ |
@@ -39,6 +44,7 @@ struct read_cb_info { | |||
39 | 44 | ||
40 | /** USB card description structure*/ | 45 | /** USB card description structure*/ |
41 | struct usb_card_rec { | 46 | struct usb_card_rec { |
47 | struct list_head list; | ||
42 | struct net_device *eth_dev; | 48 | struct net_device *eth_dev; |
43 | struct usb_device *udev; | 49 | struct usb_device *udev; |
44 | struct urb *rx_urb, *tx_urb; | 50 | struct urb *rx_urb, *tx_urb; |
@@ -100,3 +106,4 @@ int usb_tx_block(wlan_private *priv, u8 *payload, u16 nb); | |||
100 | void if_usb_free(struct usb_card_rec *cardp); | 106 | void if_usb_free(struct usb_card_rec *cardp); |
101 | int if_usb_issue_boot_command(wlan_private *priv, int ivalue); | 107 | int if_usb_issue_boot_command(wlan_private *priv, int ivalue); |
102 | 108 | ||
109 | #endif | ||