diff options
author | Hante Meuleman <meuleman@broadcom.com> | 2014-06-21 06:11:15 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-06-25 15:32:48 -0400 |
commit | 51c7f5eddd0f2e8eb6b49a3025b04148cf3b3912 (patch) | |
tree | 6d568d5faf19a6d8b1ead06815e60cc04d4457eb /drivers/net/wireless/brcm80211/brcmfmac/usb.c | |
parent | d83f8face594340551b2c57ae95acfe70ae444f8 (diff) |
brcmfmac: Change USB probe routine to support Composite USB
Some of the USB devices also have Bluetooth inside. These devices
can with specific firmware result in a composite USB device. This
change will update the driver such that it will also accept the
correct interface of composite devices. It is backward compatible
with old non-composite USB fw.
Reviewed-by: Arend Van Spriel <arend@broadcom.com>
Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com>
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/brcm80211/brcmfmac/usb.c')
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/usb.c | 204 |
1 files changed, 87 insertions, 117 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index d2927acfbd79..839bcda9465a 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c | |||
@@ -29,33 +29,24 @@ | |||
29 | #include "usb_rdl.h" | 29 | #include "usb_rdl.h" |
30 | #include "usb.h" | 30 | #include "usb.h" |
31 | 31 | ||
32 | #define IOCTL_RESP_TIMEOUT 2000 | 32 | #define IOCTL_RESP_TIMEOUT 2000 |
33 | 33 | ||
34 | #define BRCMF_USB_RESET_GETVER_SPINWAIT 100 /* in unit of ms */ | 34 | #define BRCMF_USB_RESET_GETVER_SPINWAIT 100 /* in unit of ms */ |
35 | #define BRCMF_USB_RESET_GETVER_LOOP_CNT 10 | 35 | #define BRCMF_USB_RESET_GETVER_LOOP_CNT 10 |
36 | 36 | ||
37 | #define BRCMF_POSTBOOT_ID 0xA123 /* ID to detect if dongle | 37 | #define BRCMF_POSTBOOT_ID 0xA123 /* ID to detect if dongle |
38 | has boot up */ | 38 | has boot up */ |
39 | #define BRCMF_USB_NRXQ 50 | 39 | #define BRCMF_USB_NRXQ 50 |
40 | #define BRCMF_USB_NTXQ 50 | 40 | #define BRCMF_USB_NTXQ 50 |
41 | 41 | ||
42 | #define CONFIGDESC(usb) (&((usb)->actconfig)->desc) | 42 | #define BRCMF_USB_CBCTL_WRITE 0 |
43 | #define IFPTR(usb, idx) ((usb)->actconfig->interface[(idx)]) | 43 | #define BRCMF_USB_CBCTL_READ 1 |
44 | #define IFALTS(usb, idx) (IFPTR((usb), (idx))->altsetting[0]) | 44 | #define BRCMF_USB_MAX_PKT_SIZE 1600 |
45 | #define IFDESC(usb, idx) IFALTS((usb), (idx)).desc | ||
46 | #define IFEPDESC(usb, idx, ep) (IFALTS((usb), (idx)).endpoint[(ep)]).desc | ||
47 | 45 | ||
48 | #define CONTROL_IF 0 | 46 | #define BRCMF_USB_43143_FW_NAME "brcm/brcmfmac43143.bin" |
49 | #define BULK_IF 0 | 47 | #define BRCMF_USB_43236_FW_NAME "brcm/brcmfmac43236b.bin" |
50 | 48 | #define BRCMF_USB_43242_FW_NAME "brcm/brcmfmac43242a.bin" | |
51 | #define BRCMF_USB_CBCTL_WRITE 0 | 49 | #define BRCMF_USB_43569_FW_NAME "brcm/brcmfmac43569.bin" |
52 | #define BRCMF_USB_CBCTL_READ 1 | ||
53 | #define BRCMF_USB_MAX_PKT_SIZE 1600 | ||
54 | |||
55 | #define BRCMF_USB_43143_FW_NAME "brcm/brcmfmac43143.bin" | ||
56 | #define BRCMF_USB_43236_FW_NAME "brcm/brcmfmac43236b.bin" | ||
57 | #define BRCMF_USB_43242_FW_NAME "brcm/brcmfmac43242a.bin" | ||
58 | #define BRCMF_USB_43569_FW_NAME "brcm/brcmfmac43569.bin" | ||
59 | 50 | ||
60 | struct brcmf_usb_image { | 51 | struct brcmf_usb_image { |
61 | struct list_head list; | 52 | struct list_head list; |
@@ -71,7 +62,7 @@ struct brcmf_usbdev_info { | |||
71 | struct list_head rx_postq; | 62 | struct list_head rx_postq; |
72 | struct list_head tx_freeq; | 63 | struct list_head tx_freeq; |
73 | struct list_head tx_postq; | 64 | struct list_head tx_postq; |
74 | uint rx_pipe, tx_pipe, rx_pipe2; | 65 | uint rx_pipe, tx_pipe; |
75 | 66 | ||
76 | int rx_low_watermark; | 67 | int rx_low_watermark; |
77 | int tx_low_watermark; | 68 | int tx_low_watermark; |
@@ -98,6 +89,7 @@ struct brcmf_usbdev_info { | |||
98 | int ctl_completed; | 89 | int ctl_completed; |
99 | wait_queue_head_t ioctl_resp_wait; | 90 | wait_queue_head_t ioctl_resp_wait; |
100 | ulong ctl_op; | 91 | ulong ctl_op; |
92 | u8 ifnum; | ||
101 | 93 | ||
102 | struct urb *bulk_urb; /* used for FW download */ | 94 | struct urb *bulk_urb; /* used for FW download */ |
103 | }; | 95 | }; |
@@ -577,7 +569,6 @@ fail: | |||
577 | static int brcmf_usb_up(struct device *dev) | 569 | static int brcmf_usb_up(struct device *dev) |
578 | { | 570 | { |
579 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); | 571 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); |
580 | u16 ifnum; | ||
581 | 572 | ||
582 | brcmf_dbg(USB, "Enter\n"); | 573 | brcmf_dbg(USB, "Enter\n"); |
583 | if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP) | 574 | if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP) |
@@ -590,21 +581,19 @@ static int brcmf_usb_up(struct device *dev) | |||
590 | devinfo->ctl_in_pipe = usb_rcvctrlpipe(devinfo->usbdev, 0); | 581 | devinfo->ctl_in_pipe = usb_rcvctrlpipe(devinfo->usbdev, 0); |
591 | devinfo->ctl_out_pipe = usb_sndctrlpipe(devinfo->usbdev, 0); | 582 | devinfo->ctl_out_pipe = usb_sndctrlpipe(devinfo->usbdev, 0); |
592 | 583 | ||
593 | ifnum = IFDESC(devinfo->usbdev, CONTROL_IF).bInterfaceNumber; | ||
594 | |||
595 | /* CTL Write */ | 584 | /* CTL Write */ |
596 | devinfo->ctl_write.bRequestType = | 585 | devinfo->ctl_write.bRequestType = |
597 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE; | 586 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE; |
598 | devinfo->ctl_write.bRequest = 0; | 587 | devinfo->ctl_write.bRequest = 0; |
599 | devinfo->ctl_write.wValue = cpu_to_le16(0); | 588 | devinfo->ctl_write.wValue = cpu_to_le16(0); |
600 | devinfo->ctl_write.wIndex = cpu_to_le16p(&ifnum); | 589 | devinfo->ctl_write.wIndex = cpu_to_le16(devinfo->ifnum); |
601 | 590 | ||
602 | /* CTL Read */ | 591 | /* CTL Read */ |
603 | devinfo->ctl_read.bRequestType = | 592 | devinfo->ctl_read.bRequestType = |
604 | USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE; | 593 | USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE; |
605 | devinfo->ctl_read.bRequest = 1; | 594 | devinfo->ctl_read.bRequest = 1; |
606 | devinfo->ctl_read.wValue = cpu_to_le16(0); | 595 | devinfo->ctl_read.wValue = cpu_to_le16(0); |
607 | devinfo->ctl_read.wIndex = cpu_to_le16p(&ifnum); | 596 | devinfo->ctl_read.wIndex = cpu_to_le16(devinfo->ifnum); |
608 | } | 597 | } |
609 | brcmf_usb_rx_fill_all(devinfo); | 598 | brcmf_usb_rx_fill_all(devinfo); |
610 | return 0; | 599 | return 0; |
@@ -643,19 +632,19 @@ brcmf_usb_sync_complete(struct urb *urb) | |||
643 | brcmf_usb_ioctl_resp_wake(devinfo); | 632 | brcmf_usb_ioctl_resp_wake(devinfo); |
644 | } | 633 | } |
645 | 634 | ||
646 | static bool brcmf_usb_dl_cmd(struct brcmf_usbdev_info *devinfo, u8 cmd, | 635 | static int brcmf_usb_dl_cmd(struct brcmf_usbdev_info *devinfo, u8 cmd, |
647 | void *buffer, int buflen) | 636 | void *buffer, int buflen) |
648 | { | 637 | { |
649 | int ret = 0; | 638 | int ret; |
650 | char *tmpbuf; | 639 | char *tmpbuf; |
651 | u16 size; | 640 | u16 size; |
652 | 641 | ||
653 | if ((!devinfo) || (devinfo->ctl_urb == NULL)) | 642 | if ((!devinfo) || (devinfo->ctl_urb == NULL)) |
654 | return false; | 643 | return -EINVAL; |
655 | 644 | ||
656 | tmpbuf = kmalloc(buflen, GFP_ATOMIC); | 645 | tmpbuf = kmalloc(buflen, GFP_ATOMIC); |
657 | if (!tmpbuf) | 646 | if (!tmpbuf) |
658 | return false; | 647 | return -ENOMEM; |
659 | 648 | ||
660 | size = buflen; | 649 | size = buflen; |
661 | devinfo->ctl_urb->transfer_buffer_length = size; | 650 | devinfo->ctl_urb->transfer_buffer_length = size; |
@@ -676,14 +665,16 @@ static bool brcmf_usb_dl_cmd(struct brcmf_usbdev_info *devinfo, u8 cmd, | |||
676 | ret = usb_submit_urb(devinfo->ctl_urb, GFP_ATOMIC); | 665 | ret = usb_submit_urb(devinfo->ctl_urb, GFP_ATOMIC); |
677 | if (ret < 0) { | 666 | if (ret < 0) { |
678 | brcmf_err("usb_submit_urb failed %d\n", ret); | 667 | brcmf_err("usb_submit_urb failed %d\n", ret); |
679 | kfree(tmpbuf); | 668 | goto finalize; |
680 | return false; | ||
681 | } | 669 | } |
682 | 670 | ||
683 | ret = brcmf_usb_ioctl_resp_wait(devinfo); | 671 | if (!brcmf_usb_ioctl_resp_wait(devinfo)) |
684 | memcpy(buffer, tmpbuf, buflen); | 672 | ret = -ETIMEDOUT; |
685 | kfree(tmpbuf); | 673 | else |
674 | memcpy(buffer, tmpbuf, buflen); | ||
686 | 675 | ||
676 | finalize: | ||
677 | kfree(tmpbuf); | ||
687 | return ret; | 678 | return ret; |
688 | } | 679 | } |
689 | 680 | ||
@@ -725,6 +716,7 @@ brcmf_usb_resetcfg(struct brcmf_usbdev_info *devinfo) | |||
725 | { | 716 | { |
726 | struct bootrom_id_le id; | 717 | struct bootrom_id_le id; |
727 | u32 loop_cnt; | 718 | u32 loop_cnt; |
719 | int err; | ||
728 | 720 | ||
729 | brcmf_dbg(USB, "Enter\n"); | 721 | brcmf_dbg(USB, "Enter\n"); |
730 | 722 | ||
@@ -733,7 +725,9 @@ brcmf_usb_resetcfg(struct brcmf_usbdev_info *devinfo) | |||
733 | mdelay(BRCMF_USB_RESET_GETVER_SPINWAIT); | 725 | mdelay(BRCMF_USB_RESET_GETVER_SPINWAIT); |
734 | loop_cnt++; | 726 | loop_cnt++; |
735 | id.chip = cpu_to_le32(0xDEAD); /* Get the ID */ | 727 | id.chip = cpu_to_le32(0xDEAD); /* Get the ID */ |
736 | brcmf_usb_dl_cmd(devinfo, DL_GETVER, &id, sizeof(id)); | 728 | err = brcmf_usb_dl_cmd(devinfo, DL_GETVER, &id, sizeof(id)); |
729 | if ((err) && (err != -ETIMEDOUT)) | ||
730 | return err; | ||
737 | if (id.chip == cpu_to_le32(BRCMF_POSTBOOT_ID)) | 731 | if (id.chip == cpu_to_le32(BRCMF_POSTBOOT_ID)) |
738 | break; | 732 | break; |
739 | } while (loop_cnt < BRCMF_USB_RESET_GETVER_LOOP_CNT); | 733 | } while (loop_cnt < BRCMF_USB_RESET_GETVER_LOOP_CNT); |
@@ -795,8 +789,7 @@ brcmf_usb_dl_writeimage(struct brcmf_usbdev_info *devinfo, u8 *fw, int fwlen) | |||
795 | } | 789 | } |
796 | 790 | ||
797 | /* 1) Prepare USB boot loader for runtime image */ | 791 | /* 1) Prepare USB boot loader for runtime image */ |
798 | brcmf_usb_dl_cmd(devinfo, DL_START, &state, | 792 | brcmf_usb_dl_cmd(devinfo, DL_START, &state, sizeof(state)); |
799 | sizeof(struct rdl_state_le)); | ||
800 | 793 | ||
801 | rdlstate = le32_to_cpu(state.state); | 794 | rdlstate = le32_to_cpu(state.state); |
802 | rdlbytes = le32_to_cpu(state.bytes); | 795 | rdlbytes = le32_to_cpu(state.bytes); |
@@ -840,10 +833,10 @@ brcmf_usb_dl_writeimage(struct brcmf_usbdev_info *devinfo, u8 *fw, int fwlen) | |||
840 | dlpos += sendlen; | 833 | dlpos += sendlen; |
841 | sent += sendlen; | 834 | sent += sendlen; |
842 | } | 835 | } |
843 | if (!brcmf_usb_dl_cmd(devinfo, DL_GETSTATE, &state, | 836 | err = brcmf_usb_dl_cmd(devinfo, DL_GETSTATE, &state, |
844 | sizeof(struct rdl_state_le))) { | 837 | sizeof(state)); |
845 | brcmf_err("DL_GETSTATE Failed xxxx\n"); | 838 | if (err) { |
846 | err = -EINVAL; | 839 | brcmf_err("DL_GETSTATE Failed\n"); |
847 | goto fail; | 840 | goto fail; |
848 | } | 841 | } |
849 | 842 | ||
@@ -899,13 +892,12 @@ static int brcmf_usb_dlrun(struct brcmf_usbdev_info *devinfo) | |||
899 | return -EINVAL; | 892 | return -EINVAL; |
900 | 893 | ||
901 | /* Check we are runnable */ | 894 | /* Check we are runnable */ |
902 | brcmf_usb_dl_cmd(devinfo, DL_GETSTATE, &state, | 895 | state.state = 0; |
903 | sizeof(struct rdl_state_le)); | 896 | brcmf_usb_dl_cmd(devinfo, DL_GETSTATE, &state, sizeof(state)); |
904 | 897 | ||
905 | /* Start the image */ | 898 | /* Start the image */ |
906 | if (state.state == cpu_to_le32(DL_RUNNABLE)) { | 899 | if (state.state == cpu_to_le32(DL_RUNNABLE)) { |
907 | if (!brcmf_usb_dl_cmd(devinfo, DL_GO, &state, | 900 | if (brcmf_usb_dl_cmd(devinfo, DL_GO, &state, sizeof(state))) |
908 | sizeof(struct rdl_state_le))) | ||
909 | return -ENODEV; | 901 | return -ENODEV; |
910 | if (brcmf_usb_resetcfg(devinfo)) | 902 | if (brcmf_usb_resetcfg(devinfo)) |
911 | return -ENODEV; | 903 | return -ENODEV; |
@@ -1228,13 +1220,13 @@ brcmf_usb_disconnect_cb(struct brcmf_usbdev_info *devinfo) | |||
1228 | static int | 1220 | static int |
1229 | brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) | 1221 | brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) |
1230 | { | 1222 | { |
1231 | int ep; | ||
1232 | struct usb_endpoint_descriptor *endpoint; | ||
1233 | int ret = 0; | ||
1234 | struct usb_device *usb = interface_to_usbdev(intf); | 1223 | struct usb_device *usb = interface_to_usbdev(intf); |
1235 | int num_of_eps; | ||
1236 | u8 endpoint_num; | ||
1237 | struct brcmf_usbdev_info *devinfo; | 1224 | struct brcmf_usbdev_info *devinfo; |
1225 | struct usb_interface_descriptor *desc; | ||
1226 | struct usb_endpoint_descriptor *endpoint; | ||
1227 | int ret = 0; | ||
1228 | u32 num_of_eps; | ||
1229 | u8 endpoint_num, ep; | ||
1238 | 1230 | ||
1239 | brcmf_dbg(USB, "Enter 0x%04x:0x%04x\n", id->idVendor, id->idProduct); | 1231 | brcmf_dbg(USB, "Enter 0x%04x:0x%04x\n", id->idVendor, id->idProduct); |
1240 | 1232 | ||
@@ -1244,92 +1236,71 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
1244 | 1236 | ||
1245 | devinfo->usbdev = usb; | 1237 | devinfo->usbdev = usb; |
1246 | devinfo->dev = &usb->dev; | 1238 | devinfo->dev = &usb->dev; |
1247 | |||
1248 | usb_set_intfdata(intf, devinfo); | 1239 | usb_set_intfdata(intf, devinfo); |
1249 | 1240 | ||
1250 | /* Check that the device supports only one configuration */ | 1241 | /* Check that the device supports only one configuration */ |
1251 | if (usb->descriptor.bNumConfigurations != 1) { | 1242 | if (usb->descriptor.bNumConfigurations != 1) { |
1252 | ret = -1; | 1243 | brcmf_err("Number of configurations: %d not supported\n", |
1253 | goto fail; | 1244 | usb->descriptor.bNumConfigurations); |
1254 | } | 1245 | ret = -ENODEV; |
1255 | |||
1256 | if (usb->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) { | ||
1257 | ret = -1; | ||
1258 | goto fail; | ||
1259 | } | ||
1260 | |||
1261 | /* | ||
1262 | * Only the BDC interface configuration is supported: | ||
1263 | * Device class: USB_CLASS_VENDOR_SPEC | ||
1264 | * if0 class: USB_CLASS_VENDOR_SPEC | ||
1265 | * if0/ep0: control | ||
1266 | * if0/ep1: bulk in | ||
1267 | * if0/ep2: bulk out (ok if swapped with bulk in) | ||
1268 | */ | ||
1269 | if (CONFIGDESC(usb)->bNumInterfaces != 1) { | ||
1270 | ret = -1; | ||
1271 | goto fail; | 1246 | goto fail; |
1272 | } | 1247 | } |
1273 | 1248 | ||
1274 | /* Check interface */ | 1249 | if ((usb->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) && |
1275 | if (IFDESC(usb, CONTROL_IF).bInterfaceClass != USB_CLASS_VENDOR_SPEC || | 1250 | (usb->descriptor.bDeviceClass != USB_CLASS_MISC) && |
1276 | IFDESC(usb, CONTROL_IF).bInterfaceSubClass != 2 || | 1251 | (usb->descriptor.bDeviceClass != USB_CLASS_WIRELESS_CONTROLLER)) { |
1277 | IFDESC(usb, CONTROL_IF).bInterfaceProtocol != 0xff) { | 1252 | brcmf_err("Device class: 0x%x not supported\n", |
1278 | brcmf_err("invalid control interface: class %d, subclass %d, proto %d\n", | 1253 | usb->descriptor.bDeviceClass); |
1279 | IFDESC(usb, CONTROL_IF).bInterfaceClass, | 1254 | ret = -ENODEV; |
1280 | IFDESC(usb, CONTROL_IF).bInterfaceSubClass, | ||
1281 | IFDESC(usb, CONTROL_IF).bInterfaceProtocol); | ||
1282 | ret = -1; | ||
1283 | goto fail; | 1255 | goto fail; |
1284 | } | 1256 | } |
1285 | 1257 | ||
1286 | /* Check control endpoint */ | 1258 | desc = &intf->altsetting[0].desc; |
1287 | endpoint = &IFEPDESC(usb, CONTROL_IF, 0); | 1259 | if ((desc->bInterfaceClass != USB_CLASS_VENDOR_SPEC) || |
1288 | if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | 1260 | (desc->bInterfaceSubClass != 2) || |
1289 | != USB_ENDPOINT_XFER_INT) { | 1261 | (desc->bInterfaceProtocol != 0xff)) { |
1290 | brcmf_err("invalid control endpoint %d\n", | 1262 | brcmf_err("non WLAN interface %d: 0x%x:0x%x:0x%x\n", |
1291 | endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK); | 1263 | desc->bInterfaceNumber, desc->bInterfaceClass, |
1292 | ret = -1; | 1264 | desc->bInterfaceSubClass, desc->bInterfaceProtocol); |
1265 | ret = -ENODEV; | ||
1293 | goto fail; | 1266 | goto fail; |
1294 | } | 1267 | } |
1295 | 1268 | ||
1296 | devinfo->rx_pipe = 0; | 1269 | num_of_eps = desc->bNumEndpoints; |
1297 | devinfo->rx_pipe2 = 0; | 1270 | for (ep = 0; ep < num_of_eps; ep++) { |
1298 | devinfo->tx_pipe = 0; | 1271 | endpoint = &intf->altsetting[0].endpoint[ep].desc; |
1299 | num_of_eps = IFDESC(usb, BULK_IF).bNumEndpoints - 1; | 1272 | endpoint_num = usb_endpoint_num(endpoint); |
1300 | 1273 | if (!usb_endpoint_xfer_bulk(endpoint)) | |
1301 | /* Check data endpoints and get pipes */ | 1274 | continue; |
1302 | for (ep = 1; ep <= num_of_eps; ep++) { | 1275 | if (usb_endpoint_dir_in(endpoint)) { |
1303 | endpoint = &IFEPDESC(usb, BULK_IF, ep); | 1276 | if (!devinfo->rx_pipe) |
1304 | if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != | ||
1305 | USB_ENDPOINT_XFER_BULK) { | ||
1306 | brcmf_err("invalid data endpoint %d\n", ep); | ||
1307 | ret = -1; | ||
1308 | goto fail; | ||
1309 | } | ||
1310 | |||
1311 | endpoint_num = endpoint->bEndpointAddress & | ||
1312 | USB_ENDPOINT_NUMBER_MASK; | ||
1313 | if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) | ||
1314 | == USB_DIR_IN) { | ||
1315 | if (!devinfo->rx_pipe) { | ||
1316 | devinfo->rx_pipe = | 1277 | devinfo->rx_pipe = |
1317 | usb_rcvbulkpipe(usb, endpoint_num); | 1278 | usb_rcvbulkpipe(usb, endpoint_num); |
1318 | } else { | ||
1319 | devinfo->rx_pipe2 = | ||
1320 | usb_rcvbulkpipe(usb, endpoint_num); | ||
1321 | } | ||
1322 | } else { | 1279 | } else { |
1323 | devinfo->tx_pipe = usb_sndbulkpipe(usb, endpoint_num); | 1280 | if (!devinfo->tx_pipe) |
1281 | devinfo->tx_pipe = | ||
1282 | usb_sndbulkpipe(usb, endpoint_num); | ||
1324 | } | 1283 | } |
1325 | } | 1284 | } |
1285 | if (devinfo->rx_pipe == 0) { | ||
1286 | brcmf_err("No RX (in) Bulk EP found\n"); | ||
1287 | ret = -ENODEV; | ||
1288 | goto fail; | ||
1289 | } | ||
1290 | if (devinfo->tx_pipe == 0) { | ||
1291 | brcmf_err("No TX (out) Bulk EP found\n"); | ||
1292 | ret = -ENODEV; | ||
1293 | goto fail; | ||
1294 | } | ||
1295 | |||
1296 | devinfo->ifnum = desc->bInterfaceNumber; | ||
1326 | 1297 | ||
1327 | if (usb->speed == USB_SPEED_SUPER) | 1298 | if (usb->speed == USB_SPEED_SUPER) |
1328 | brcmf_dbg(USB, "Broadcom super speed USB wireless device detected\n"); | 1299 | brcmf_dbg(USB, "Broadcom super speed USB WLAN interface detected\n"); |
1329 | else if (usb->speed == USB_SPEED_HIGH) | 1300 | else if (usb->speed == USB_SPEED_HIGH) |
1330 | brcmf_dbg(USB, "Broadcom high speed USB wireless device detected\n"); | 1301 | brcmf_dbg(USB, "Broadcom high speed USB WLAN interface detected\n"); |
1331 | else | 1302 | else |
1332 | brcmf_dbg(USB, "Broadcom full speed USB wireless device detected\n"); | 1303 | brcmf_dbg(USB, "Broadcom full speed USB WLAN interface detected\n"); |
1333 | 1304 | ||
1334 | ret = brcmf_usb_probe_cb(devinfo); | 1305 | ret = brcmf_usb_probe_cb(devinfo); |
1335 | if (ret) | 1306 | if (ret) |
@@ -1339,11 +1310,9 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
1339 | return 0; | 1310 | return 0; |
1340 | 1311 | ||
1341 | fail: | 1312 | fail: |
1342 | brcmf_err("failed with errno %d\n", ret); | ||
1343 | kfree(devinfo); | 1313 | kfree(devinfo); |
1344 | usb_set_intfdata(intf, NULL); | 1314 | usb_set_intfdata(intf, NULL); |
1345 | return ret; | 1315 | return ret; |
1346 | |||
1347 | } | 1316 | } |
1348 | 1317 | ||
1349 | static void | 1318 | static void |
@@ -1388,6 +1357,7 @@ static int brcmf_usb_reset_resume(struct usb_interface *intf) | |||
1388 | { | 1357 | { |
1389 | struct usb_device *usb = interface_to_usbdev(intf); | 1358 | struct usb_device *usb = interface_to_usbdev(intf); |
1390 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); | 1359 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); |
1360 | |||
1391 | brcmf_dbg(USB, "Enter\n"); | 1361 | brcmf_dbg(USB, "Enter\n"); |
1392 | 1362 | ||
1393 | return brcmf_fw_get_firmwares(&usb->dev, 0, | 1363 | return brcmf_fw_get_firmwares(&usb->dev, 0, |