]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/meta-ti-glsdk.git/blob - recipes-kernel/linux/linux-mainline-3.2/libertas/0014-libertas-USB-convert-to-asynchronous-firmware-loadin.patch
linux-mainline: Add patches to enable libertas firmware loading asynchronously
[glsdk/meta-ti-glsdk.git] / recipes-kernel / linux / linux-mainline-3.2 / libertas / 0014-libertas-USB-convert-to-asynchronous-firmware-loadin.patch
1 From ce84bb69f50e6f6cfeabc9b965365290f4184417 Mon Sep 17 00:00:00 2001
2 From: Daniel Drake <dsd@laptop.org>
3 Date: Mon, 16 Apr 2012 23:53:55 +0100
4 Subject: [PATCH 14/17] libertas USB: convert to asynchronous firmware loading
6 Signed-off-by: Daniel Drake <dsd@laptop.org>
7 Acked-by: Dan Williams <dcbw@redhat.com>
8 Signed-off-by: John W. Linville <linville@tuxdriver.com>
9 ---
10  drivers/net/wireless/libertas/if_usb.c |  102 +++++++++++++------------------
11  1 files changed, 43 insertions(+), 59 deletions(-)
13 diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
14 index f29471b..75403e6 100644
15 --- a/drivers/net/wireless/libertas/if_usb.c
16 +++ b/drivers/net/wireless/libertas/if_usb.c
17 @@ -41,6 +41,16 @@ enum {
18         MODEL_8682 = 0x2
19  };
20  
21 +/* table of firmware file names */
22 +static const struct lbs_fw_table fw_table[] = {
23 +       { MODEL_8388, "libertas/usb8388_olpc.bin", NULL },
24 +       { MODEL_8388, "libertas/usb8388_v9.bin", NULL },
25 +       { MODEL_8388, "libertas/usb8388_v5.bin", NULL },
26 +       { MODEL_8388, "libertas/usb8388.bin", NULL },
27 +       { MODEL_8388, "usb8388.bin", NULL },
28 +       { MODEL_8682, "libertas/usb8682.bin", NULL }
29 +};
30 +
31  static struct usb_device_id if_usb_table[] = {
32         /* Enter the device signature inside */
33         { USB_DEVICE(0x1286, 0x2001), .driver_info = MODEL_8388 },
34 @@ -52,7 +62,9 @@ MODULE_DEVICE_TABLE(usb, if_usb_table);
35  
36  static void if_usb_receive(struct urb *urb);
37  static void if_usb_receive_fwload(struct urb *urb);
38 -static int if_usb_prog_firmware(struct if_usb_card *cardp);
39 +static void if_usb_prog_firmware(struct lbs_private *priv, int ret,
40 +                                const struct firmware *fw,
41 +                                const struct firmware *unused);
42  static int if_usb_host_to_card(struct lbs_private *priv, uint8_t type,
43                                uint8_t *payload, uint16_t nb);
44  static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload,
45 @@ -187,6 +199,7 @@ static int if_usb_probe(struct usb_interface *intf,
46         struct usb_endpoint_descriptor *endpoint;
47         struct lbs_private *priv;
48         struct if_usb_card *cardp;
49 +       int r = -ENOMEM;
50         int i;
51  
52         udev = interface_to_usbdev(intf);
53 @@ -244,17 +257,10 @@ static int if_usb_probe(struct usb_interface *intf,
54                 goto dealloc;
55         }
56  
57 -       /* Upload firmware */
58 -       if (if_usb_prog_firmware(cardp)) {
59 -               lbs_deb_usbd(&udev->dev, "FW upload failed\n");
60 -               goto err_prog_firmware;
61 -       }
62 -
63         if (!(priv = lbs_add_card(cardp, &intf->dev)))
64 -               goto err_prog_firmware;
65 +               goto err_add_card;
66  
67         cardp->priv = priv;
68 -       cardp->priv->fw_ready = 1;
69  
70         priv->hw_host_to_card = if_usb_host_to_card;
71         priv->enter_deep_sleep = NULL;
72 @@ -267,34 +273,25 @@ static int if_usb_probe(struct usb_interface *intf,
73  
74         cardp->boot2_version = udev->descriptor.bcdDevice;
75  
76 -       if_usb_submit_rx_urb(cardp);
77 -
78 -       if (lbs_start_card(priv))
79 -               goto err_start_card;
80 -
81 -       if_usb_setup_firmware(priv);
82 -
83         usb_get_dev(udev);
84         usb_set_intfdata(intf, cardp);
85  
86 -       /*
87 -        * EHS_REMOVE_WAKEUP is not supported on all versions of the firmware.
88 -        */
89 -       priv->wol_criteria = EHS_REMOVE_WAKEUP;
90 -       if (lbs_host_sleep_cfg(priv, priv->wol_criteria, NULL))
91 -               priv->ehs_remove_supported = false;
92 +       r = lbs_get_firmware_async(priv, &udev->dev, cardp->model,
93 +                                  fw_table, if_usb_prog_firmware);
94 +       if (r)
95 +               goto err_get_fw;
96  
97         return 0;
98  
99 -err_start_card:
100 +err_get_fw:
101         lbs_remove_card(priv);
102 -err_prog_firmware:
103 +err_add_card:
104         if_usb_reset_device(cardp);
105  dealloc:
106         if_usb_free(cardp);
107  
108  error:
109 -       return -ENOMEM;
110 +       return r;
111  }
112  
113  /**
114 @@ -829,49 +826,22 @@ static int check_fwfile_format(const uint8_t *data, uint32_t totlen)
115         return ret;
116  }
117  
118 -/* table of firmware file names */
119 -static const struct {
120 -       u32 model;
121 -       const char *fwname;
122 -} fw_table[] = {
123 -       { MODEL_8388, "libertas/usb8388_olpc.bin" },
124 -       { MODEL_8388, "libertas/usb8388_v9.bin" },
125 -       { MODEL_8388, "libertas/usb8388_v5.bin" },
126 -       { MODEL_8388, "libertas/usb8388.bin" },
127 -       { MODEL_8388, "usb8388.bin" },
128 -       { MODEL_8682, "libertas/usb8682.bin" }
129 -};
131 -static int get_fw(struct if_usb_card *cardp)
132 -{
133 -       int i;
135 -       /* Otherwise search for firmware to use */
136 -       for (i = 0; i < ARRAY_SIZE(fw_table); i++) {
137 -               if (fw_table[i].model != cardp->model)
138 -                       continue;
139 -               if (request_firmware(&cardp->fw, fw_table[i].fwname,
140 -                                       &cardp->udev->dev) == 0)
141 -                       return 0;
142 -       }
144 -       return -ENOENT;
145 -}
147 -static int if_usb_prog_firmware(struct if_usb_card *cardp)
148 +static void if_usb_prog_firmware(struct lbs_private *priv, int ret,
149 +                                const struct firmware *fw,
150 +                                const struct firmware *unused)
151  {
152 +       struct if_usb_card *cardp = priv->card;
153         int i = 0;
154         static int reset_count = 10;
155 -       int ret = 0;
156  
157         lbs_deb_enter(LBS_DEB_USB);
158  
159 -       ret = get_fw(cardp);
160         if (ret) {
161                 pr_err("failed to find firmware (%d)\n", ret);
162                 goto done;
163         }
164  
165 +       cardp->fw = fw;
166         if (check_fwfile_format(cardp->fw->data, cardp->fw->size)) {
167                 ret = -EINVAL;
168                 goto release_fw;
169 @@ -954,13 +924,27 @@ restart:
170                 goto release_fw;
171         }
172  
173 +       cardp->priv->fw_ready = 1;
174 +       if_usb_submit_rx_urb(cardp);
176 +       if (lbs_start_card(priv))
177 +               goto release_fw;
179 +       if_usb_setup_firmware(priv);
181 +       /*
182 +        * EHS_REMOVE_WAKEUP is not supported on all versions of the firmware.
183 +        */
184 +       priv->wol_criteria = EHS_REMOVE_WAKEUP;
185 +       if (lbs_host_sleep_cfg(priv, priv->wol_criteria, NULL))
186 +               priv->ehs_remove_supported = false;
188   release_fw:
189         release_firmware(cardp->fw);
190         cardp->fw = NULL;
191  
192   done:
193 -       lbs_deb_leave_args(LBS_DEB_USB, "ret %d", ret);
194 -       return ret;
195 +       lbs_deb_leave(LBS_DEB_USB);
196  }
197  
198  
199 -- 
200 1.7.4.4