aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/zd1211rw/zd_usb.c
diff options
context:
space:
mode:
authorDaniel Drake <dsd@gentoo.org>2007-07-01 13:22:32 -0400
committerJohn W. Linville <linville@tuxdriver.com>2007-07-10 14:14:56 -0400
commit74553aedd46b3a2cae986f909cf2a3f99369decc (patch)
tree6904945b36c017c58249b1900fbbd531f3286e49 /drivers/net/wireless/zd1211rw/zd_usb.c
parent93f510bbac64f552ef6872a39ae12afa06c4e999 (diff)
[PATCH] zd1211rw: Defer firmware load until first ifup
While playing with the firmware a while back, I discovered a way to access the device's entire address space before the firmware has been loaded. Previously we were loading the firmware early on (during probe) so that we could read the MAC address from the EEPROM and register a netdevice. Now that we can read the EEPROM without having firmware, we can defer firmware loading until later while still reading the MAC address early on. This has the advantage that zd1211rw can now be built into the kernel -- previously if this was the case, zd1211rw would be loaded before the filesystem is available and firmware loading would fail. Firmware load and other device initialization operations now happen the first time the interface is brought up. Some architectural changes were needed: handling of the is_zd1211b flag was moved into the zd_usb structure, MAC address handling was obviously changed, and a preinit_hw stage was added (the order is now: init, preinit_hw, init_hw). Signed-off-by: Daniel Drake <dsd@gentoo.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/zd1211rw/zd_usb.c')
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c97
1 files changed, 70 insertions, 27 deletions
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index 180dbcb55f6..a1a54748ccb 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -196,26 +196,27 @@ static u16 get_word(const void *data, u16 offset)
196 return le16_to_cpu(p[offset]); 196 return le16_to_cpu(p[offset]);
197} 197}
198 198
199static char *get_fw_name(char *buffer, size_t size, u8 device_type, 199static char *get_fw_name(struct zd_usb *usb, char *buffer, size_t size,
200 const char* postfix) 200 const char* postfix)
201{ 201{
202 scnprintf(buffer, size, "%s%s", 202 scnprintf(buffer, size, "%s%s",
203 device_type == DEVICE_ZD1211B ? 203 usb->is_zd1211b ?
204 FW_ZD1211B_PREFIX : FW_ZD1211_PREFIX, 204 FW_ZD1211B_PREFIX : FW_ZD1211_PREFIX,
205 postfix); 205 postfix);
206 return buffer; 206 return buffer;
207} 207}
208 208
209static int handle_version_mismatch(struct usb_device *udev, u8 device_type, 209static int handle_version_mismatch(struct zd_usb *usb,
210 const struct firmware *ub_fw) 210 const struct firmware *ub_fw)
211{ 211{
212 struct usb_device *udev = zd_usb_to_usbdev(usb);
212 const struct firmware *ur_fw = NULL; 213 const struct firmware *ur_fw = NULL;
213 int offset; 214 int offset;
214 int r = 0; 215 int r = 0;
215 char fw_name[128]; 216 char fw_name[128];
216 217
217 r = request_fw_file(&ur_fw, 218 r = request_fw_file(&ur_fw,
218 get_fw_name(fw_name, sizeof(fw_name), device_type, "ur"), 219 get_fw_name(usb, fw_name, sizeof(fw_name), "ur"),
219 &udev->dev); 220 &udev->dev);
220 if (r) 221 if (r)
221 goto error; 222 goto error;
@@ -238,11 +239,12 @@ error:
238 return r; 239 return r;
239} 240}
240 241
241static int upload_firmware(struct usb_device *udev, u8 device_type) 242static int upload_firmware(struct zd_usb *usb)
242{ 243{
243 int r; 244 int r;
244 u16 fw_bcdDevice; 245 u16 fw_bcdDevice;
245 u16 bcdDevice; 246 u16 bcdDevice;
247 struct usb_device *udev = zd_usb_to_usbdev(usb);
246 const struct firmware *ub_fw = NULL; 248 const struct firmware *ub_fw = NULL;
247 const struct firmware *uph_fw = NULL; 249 const struct firmware *uph_fw = NULL;
248 char fw_name[128]; 250 char fw_name[128];
@@ -250,7 +252,7 @@ static int upload_firmware(struct usb_device *udev, u8 device_type)
250 bcdDevice = get_bcdDevice(udev); 252 bcdDevice = get_bcdDevice(udev);
251 253
252 r = request_fw_file(&ub_fw, 254 r = request_fw_file(&ub_fw,
253 get_fw_name(fw_name, sizeof(fw_name), device_type, "ub"), 255 get_fw_name(usb, fw_name, sizeof(fw_name), "ub"),
254 &udev->dev); 256 &udev->dev);
255 if (r) 257 if (r)
256 goto error; 258 goto error;
@@ -265,7 +267,7 @@ static int upload_firmware(struct usb_device *udev, u8 device_type)
265 dev_warn(&udev->dev, "device has old bootcode, please " 267 dev_warn(&udev->dev, "device has old bootcode, please "
266 "report success or failure\n"); 268 "report success or failure\n");
267 269
268 r = handle_version_mismatch(udev, device_type, ub_fw); 270 r = handle_version_mismatch(usb, ub_fw);
269 if (r) 271 if (r)
270 goto error; 272 goto error;
271 } else { 273 } else {
@@ -276,7 +278,7 @@ static int upload_firmware(struct usb_device *udev, u8 device_type)
276 278
277 279
278 r = request_fw_file(&uph_fw, 280 r = request_fw_file(&uph_fw,
279 get_fw_name(fw_name, sizeof(fw_name), device_type, "uphr"), 281 get_fw_name(usb, fw_name, sizeof(fw_name), "uphr"),
280 &udev->dev); 282 &udev->dev);
281 if (r) 283 if (r)
282 goto error; 284 goto error;
@@ -295,6 +297,30 @@ error:
295 return r; 297 return r;
296} 298}
297 299
300/* Read data from device address space using "firmware interface" which does
301 * not require firmware to be loaded. */
302int zd_usb_read_fw(struct zd_usb *usb, zd_addr_t addr, u8 *data, u16 len)
303{
304 int r;
305 struct usb_device *udev = zd_usb_to_usbdev(usb);
306
307 r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
308 USB_REQ_FIRMWARE_READ_DATA, USB_DIR_IN | 0x40, addr, 0,
309 data, len, 5000);
310 if (r < 0) {
311 dev_err(&udev->dev,
312 "read over firmware interface failed: %d\n", r);
313 return r;
314 } else if (r != len) {
315 dev_err(&udev->dev,
316 "incomplete read over firmware interface: %d/%d\n",
317 r, len);
318 return -EIO;
319 }
320
321 return 0;
322}
323
298#define urb_dev(urb) (&(urb)->dev->dev) 324#define urb_dev(urb) (&(urb)->dev->dev)
299 325
300static inline void handle_regs_int(struct urb *urb) 326static inline void handle_regs_int(struct urb *urb)
@@ -921,9 +947,42 @@ static int eject_installer(struct usb_interface *intf)
921 return 0; 947 return 0;
922} 948}
923 949
950int zd_usb_init_hw(struct zd_usb *usb)
951{
952 int r;
953 struct zd_mac *mac = zd_usb_to_mac(usb);
954
955 dev_dbg_f(zd_usb_dev(usb), "\n");
956
957 r = upload_firmware(usb);
958 if (r) {
959 dev_err(zd_usb_dev(usb),
960 "couldn't load firmware. Error number %d\n", r);
961 return r;
962 }
963
964 r = usb_reset_configuration(zd_usb_to_usbdev(usb));
965 if (r) {
966 dev_dbg_f(zd_usb_dev(usb),
967 "couldn't reset configuration. Error number %d\n", r);
968 return r;
969 }
970
971 r = zd_mac_init_hw(mac);
972 if (r) {
973 dev_dbg_f(zd_usb_dev(usb),
974 "couldn't initialize mac. Error number %d\n", r);
975 return r;
976 }
977
978 usb->initialized = 1;
979 return 0;
980}
981
924static int probe(struct usb_interface *intf, const struct usb_device_id *id) 982static int probe(struct usb_interface *intf, const struct usb_device_id *id)
925{ 983{
926 int r; 984 int r;
985 struct zd_usb *usb;
927 struct usb_device *udev = interface_to_usbdev(intf); 986 struct usb_device *udev = interface_to_usbdev(intf);
928 struct net_device *netdev = NULL; 987 struct net_device *netdev = NULL;
929 988
@@ -951,26 +1010,10 @@ static int probe(struct usb_interface *intf, const struct usb_device_id *id)
951 goto error; 1010 goto error;
952 } 1011 }
953 1012
954 r = upload_firmware(udev, id->driver_info); 1013 usb = &zd_netdev_mac(netdev)->chip.usb;
955 if (r) { 1014 usb->is_zd1211b = (id->driver_info == DEVICE_ZD1211B) != 0;
956 dev_err(&intf->dev,
957 "couldn't load firmware. Error number %d\n", r);
958 goto error;
959 }
960 1015
961 r = usb_reset_configuration(udev); 1016 r = zd_mac_preinit_hw(zd_netdev_mac(netdev));
962 if (r) {
963 dev_dbg_f(&intf->dev,
964 "couldn't reset configuration. Error number %d\n", r);
965 goto error;
966 }
967
968 /* At this point the interrupt endpoint is not generally enabled. We
969 * save the USB bandwidth until the network device is opened. But
970 * notify that the initialization of the MAC will require the
971 * interrupts to be temporary enabled.
972 */
973 r = zd_mac_init_hw(zd_netdev_mac(netdev), id->driver_info);
974 if (r) { 1017 if (r) {
975 dev_dbg_f(&intf->dev, 1018 dev_dbg_f(&intf->dev,
976 "couldn't initialize mac. Error number %d\n", r); 1019 "couldn't initialize mac. Error number %d\n", r);