[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 };
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);
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;
52 udev = interface_to_usbdev(intf);
53 @@ -244,17 +257,10 @@ static int if_usb_probe(struct usb_interface *intf,
54 goto dealloc;
55 }
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;
67 cardp->priv = priv;
68 - cardp->priv->fw_ready = 1;
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,
74 cardp->boot2_version = udev->descriptor.bcdDevice;
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);
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;
97 return 0;
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);
108 error:
109 - return -ENOMEM;
110 + return r;
111 }
113 /**
114 @@ -829,49 +826,22 @@ static int check_fwfile_format(const uint8_t *data, uint32_t totlen)
115 return ret;
116 }
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 -};
130 -
131 -static int get_fw(struct if_usb_card *cardp)
132 -{
133 - int i;
134 -
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 - }
143 -
144 - return -ENOENT;
145 -}
146 -
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;
157 lbs_deb_enter(LBS_DEB_USB);
159 - ret = get_fw(cardp);
160 if (ret) {
161 pr_err("failed to find firmware (%d)\n", ret);
162 goto done;
163 }
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 }
173 + cardp->priv->fw_ready = 1;
174 + if_usb_submit_rx_urb(cardp);
175 +
176 + if (lbs_start_card(priv))
177 + goto release_fw;
178 +
179 + if_usb_setup_firmware(priv);
180 +
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;
187 +
188 release_fw:
189 release_firmware(cardp->fw);
190 cardp->fw = NULL;
192 done:
193 - lbs_deb_leave_args(LBS_DEB_USB, "ret %d", ret);
194 - return ret;
195 + lbs_deb_leave(LBS_DEB_USB);
196 }
199 --
200 1.7.4.4