Root/
1 | /* |
2 | * WUSB Host Wire Adapter: Radio Control Interface (WUSB[8.6]) |
3 | * Radio Control command/event transport |
4 | * |
5 | * Copyright (C) 2005-2006 Intel Corporation |
6 | * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> |
7 | * |
8 | * This program is free software; you can redistribute it and/or |
9 | * modify it under the terms of the GNU General Public License version |
10 | * 2 as published by the Free Software Foundation. |
11 | * |
12 | * This program is distributed in the hope that it will be useful, |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | * GNU General Public License for more details. |
16 | * |
17 | * You should have received a copy of the GNU General Public License |
18 | * along with this program; if not, write to the Free Software |
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
20 | * 02110-1301, USA. |
21 | * |
22 | * |
23 | * Initialize the Radio Control interface Driver. |
24 | * |
25 | * For each device probed, creates an 'struct hwarc' which contains |
26 | * just the representation of the UWB Radio Controller, and the logic |
27 | * for reading notifications and passing them to the UWB Core. |
28 | * |
29 | * So we initialize all of those, register the UWB Radio Controller |
30 | * and setup the notification/event handle to pipe the notifications |
31 | * to the UWB management Daemon. |
32 | * |
33 | * Command and event filtering. |
34 | * |
35 | * This is the driver for the Radio Control Interface described in WUSB |
36 | * 1.0. The core UWB module assumes that all drivers are compliant to the |
37 | * WHCI 0.95 specification. We thus create a filter that parses all |
38 | * incoming messages from the (WUSB 1.0) device and manipulate them to |
39 | * conform to the WHCI 0.95 specification. Similarly, outgoing messages |
40 | * are parsed and manipulated to conform to the WUSB 1.0 compliant messages |
41 | * that the device expects. Only a few messages are affected: |
42 | * Affected events: |
43 | * UWB_RC_EVT_BEACON |
44 | * UWB_RC_EVT_BP_SLOT_CHANGE |
45 | * UWB_RC_EVT_DRP_AVAIL |
46 | * UWB_RC_EVT_DRP |
47 | * Affected commands: |
48 | * UWB_RC_CMD_SCAN |
49 | * UWB_RC_CMD_SET_DRP_IE |
50 | * |
51 | * |
52 | * |
53 | */ |
54 | #include <linux/init.h> |
55 | #include <linux/module.h> |
56 | #include <linux/slab.h> |
57 | #include <linux/usb.h> |
58 | #include <linux/usb/wusb.h> |
59 | #include <linux/usb/wusb-wa.h> |
60 | #include <linux/uwb.h> |
61 | |
62 | #include "uwb-internal.h" |
63 | |
64 | /* The device uses commands and events from the WHCI specification, although |
65 | * reporting itself as WUSB compliant. */ |
66 | #define WUSB_QUIRK_WHCI_CMD_EVT 0x01 |
67 | |
68 | /** |
69 | * Descriptor for an instance of the UWB Radio Control Driver that |
70 | * attaches to the RCI interface of the Host Wired Adapter. |
71 | * |
72 | * Unless there is a lock specific to the 'data members', all access |
73 | * is protected by uwb_rc->mutex. |
74 | * |
75 | * The NEEP (Notification/Event EndPoint) URB (@neep_urb) writes to |
76 | * @rd_buffer. Note there is no locking because it is perfectly (heh!) |
77 | * serialized--probe() submits an URB, callback is called, processes |
78 | * the data (synchronously), submits another URB, and so on. There is |
79 | * no concurrent access to the buffer. |
80 | */ |
81 | struct hwarc { |
82 | struct usb_device *usb_dev; |
83 | struct usb_interface *usb_iface; |
84 | struct uwb_rc *uwb_rc; /* UWB host controller */ |
85 | struct urb *neep_urb; /* Notification endpoint handling */ |
86 | struct edc neep_edc; |
87 | void *rd_buffer; /* NEEP read buffer */ |
88 | }; |
89 | |
90 | |
91 | /* Beacon received notification (WUSB 1.0 [8.6.3.2]) */ |
92 | struct uwb_rc_evt_beacon_WUSB_0100 { |
93 | struct uwb_rceb rceb; |
94 | u8 bChannelNumber; |
95 | __le16 wBPSTOffset; |
96 | u8 bLQI; |
97 | u8 bRSSI; |
98 | __le16 wBeaconInfoLength; |
99 | u8 BeaconInfo[]; |
100 | } __attribute__((packed)); |
101 | |
102 | /** |
103 | * Filter WUSB 1.0 BEACON RCV notification to be WHCI 0.95 |
104 | * |
105 | * @header: the incoming event |
106 | * @buf_size: size of buffer containing incoming event |
107 | * @new_size: size of event after filtering completed |
108 | * |
109 | * The WHCI 0.95 spec has a "Beacon Type" field. This value is unknown at |
110 | * the time we receive the beacon from WUSB so we just set it to |
111 | * UWB_RC_BEACON_TYPE_NEIGHBOR as a default. |
112 | * The solution below allocates memory upon receipt of every beacon from a |
113 | * WUSB device. This will deteriorate performance. What is the right way to |
114 | * do this? |
115 | */ |
116 | static |
117 | int hwarc_filter_evt_beacon_WUSB_0100(struct uwb_rc *rc, |
118 | struct uwb_rceb **header, |
119 | const size_t buf_size, |
120 | size_t *new_size) |
121 | { |
122 | struct uwb_rc_evt_beacon_WUSB_0100 *be; |
123 | struct uwb_rc_evt_beacon *newbe; |
124 | size_t bytes_left, ielength; |
125 | struct device *dev = &rc->uwb_dev.dev; |
126 | |
127 | be = container_of(*header, struct uwb_rc_evt_beacon_WUSB_0100, rceb); |
128 | bytes_left = buf_size; |
129 | if (bytes_left < sizeof(*be)) { |
130 | dev_err(dev, "Beacon Received Notification: Not enough data " |
131 | "to decode for filtering (%zu vs %zu bytes needed)\n", |
132 | bytes_left, sizeof(*be)); |
133 | return -EINVAL; |
134 | } |
135 | bytes_left -= sizeof(*be); |
136 | ielength = le16_to_cpu(be->wBeaconInfoLength); |
137 | if (bytes_left < ielength) { |
138 | dev_err(dev, "Beacon Received Notification: Not enough data " |
139 | "to decode IEs (%zu vs %zu bytes needed)\n", |
140 | bytes_left, ielength); |
141 | return -EINVAL; |
142 | } |
143 | newbe = kzalloc(sizeof(*newbe) + ielength, GFP_ATOMIC); |
144 | if (newbe == NULL) |
145 | return -ENOMEM; |
146 | newbe->rceb = be->rceb; |
147 | newbe->bChannelNumber = be->bChannelNumber; |
148 | newbe->bBeaconType = UWB_RC_BEACON_TYPE_NEIGHBOR; |
149 | newbe->wBPSTOffset = be->wBPSTOffset; |
150 | newbe->bLQI = be->bLQI; |
151 | newbe->bRSSI = be->bRSSI; |
152 | newbe->wBeaconInfoLength = be->wBeaconInfoLength; |
153 | memcpy(newbe->BeaconInfo, be->BeaconInfo, ielength); |
154 | *header = &newbe->rceb; |
155 | *new_size = sizeof(*newbe) + ielength; |
156 | return 1; /* calling function will free memory */ |
157 | } |
158 | |
159 | |
160 | /* DRP Availability change notification (WUSB 1.0 [8.6.3.8]) */ |
161 | struct uwb_rc_evt_drp_avail_WUSB_0100 { |
162 | struct uwb_rceb rceb; |
163 | __le16 wIELength; |
164 | u8 IEData[]; |
165 | } __attribute__((packed)); |
166 | |
167 | /** |
168 | * Filter WUSB 1.0 DRP AVAILABILITY CHANGE notification to be WHCI 0.95 |
169 | * |
170 | * @header: the incoming event |
171 | * @buf_size: size of buffer containing incoming event |
172 | * @new_size: size of event after filtering completed |
173 | */ |
174 | static |
175 | int hwarc_filter_evt_drp_avail_WUSB_0100(struct uwb_rc *rc, |
176 | struct uwb_rceb **header, |
177 | const size_t buf_size, |
178 | size_t *new_size) |
179 | { |
180 | struct uwb_rc_evt_drp_avail_WUSB_0100 *da; |
181 | struct uwb_rc_evt_drp_avail *newda; |
182 | struct uwb_ie_hdr *ie_hdr; |
183 | size_t bytes_left, ielength; |
184 | struct device *dev = &rc->uwb_dev.dev; |
185 | |
186 | |
187 | da = container_of(*header, struct uwb_rc_evt_drp_avail_WUSB_0100, rceb); |
188 | bytes_left = buf_size; |
189 | if (bytes_left < sizeof(*da)) { |
190 | dev_err(dev, "Not enough data to decode DRP Avail " |
191 | "Notification for filtering. Expected %zu, " |
192 | "received %zu.\n", (size_t)sizeof(*da), bytes_left); |
193 | return -EINVAL; |
194 | } |
195 | bytes_left -= sizeof(*da); |
196 | ielength = le16_to_cpu(da->wIELength); |
197 | if (bytes_left < ielength) { |
198 | dev_err(dev, "DRP Avail Notification filter: IE length " |
199 | "[%zu bytes] does not match actual length " |
200 | "[%zu bytes].\n", ielength, bytes_left); |
201 | return -EINVAL; |
202 | } |
203 | if (ielength < sizeof(*ie_hdr)) { |
204 | dev_err(dev, "DRP Avail Notification filter: Not enough " |
205 | "data to decode IE [%zu bytes, %zu needed]\n", |
206 | ielength, sizeof(*ie_hdr)); |
207 | return -EINVAL; |
208 | } |
209 | ie_hdr = (void *) da->IEData; |
210 | if (ie_hdr->length > 32) { |
211 | dev_err(dev, "DRP Availability Change event has unexpected " |
212 | "length for filtering. Expected < 32 bytes, " |
213 | "got %zu bytes.\n", (size_t)ie_hdr->length); |
214 | return -EINVAL; |
215 | } |
216 | newda = kzalloc(sizeof(*newda), GFP_ATOMIC); |
217 | if (newda == NULL) |
218 | return -ENOMEM; |
219 | newda->rceb = da->rceb; |
220 | memcpy(newda->bmp, (u8 *) ie_hdr + sizeof(*ie_hdr), ie_hdr->length); |
221 | *header = &newda->rceb; |
222 | *new_size = sizeof(*newda); |
223 | return 1; /* calling function will free memory */ |
224 | } |
225 | |
226 | |
227 | /* DRP notification (WUSB 1.0 [8.6.3.9]) */ |
228 | struct uwb_rc_evt_drp_WUSB_0100 { |
229 | struct uwb_rceb rceb; |
230 | struct uwb_dev_addr wSrcAddr; |
231 | u8 bExplicit; |
232 | __le16 wIELength; |
233 | u8 IEData[]; |
234 | } __attribute__((packed)); |
235 | |
236 | /** |
237 | * Filter WUSB 1.0 DRP Notification to be WHCI 0.95 |
238 | * |
239 | * @header: the incoming event |
240 | * @buf_size: size of buffer containing incoming event |
241 | * @new_size: size of event after filtering completed |
242 | * |
243 | * It is hard to manage DRP reservations without having a Reason code. |
244 | * Unfortunately there is none in the WUSB spec. We just set the default to |
245 | * DRP IE RECEIVED. |
246 | * We do not currently use the bBeaconSlotNumber value, so we set this to |
247 | * zero for now. |
248 | */ |
249 | static |
250 | int hwarc_filter_evt_drp_WUSB_0100(struct uwb_rc *rc, |
251 | struct uwb_rceb **header, |
252 | const size_t buf_size, |
253 | size_t *new_size) |
254 | { |
255 | struct uwb_rc_evt_drp_WUSB_0100 *drpev; |
256 | struct uwb_rc_evt_drp *newdrpev; |
257 | size_t bytes_left, ielength; |
258 | struct device *dev = &rc->uwb_dev.dev; |
259 | |
260 | drpev = container_of(*header, struct uwb_rc_evt_drp_WUSB_0100, rceb); |
261 | bytes_left = buf_size; |
262 | if (bytes_left < sizeof(*drpev)) { |
263 | dev_err(dev, "Not enough data to decode DRP Notification " |
264 | "for filtering. Expected %zu, received %zu.\n", |
265 | (size_t)sizeof(*drpev), bytes_left); |
266 | return -EINVAL; |
267 | } |
268 | ielength = le16_to_cpu(drpev->wIELength); |
269 | bytes_left -= sizeof(*drpev); |
270 | if (bytes_left < ielength) { |
271 | dev_err(dev, "DRP Notification filter: header length [%zu " |
272 | "bytes] does not match actual length [%zu " |
273 | "bytes].\n", ielength, bytes_left); |
274 | return -EINVAL; |
275 | } |
276 | newdrpev = kzalloc(sizeof(*newdrpev) + ielength, GFP_ATOMIC); |
277 | if (newdrpev == NULL) |
278 | return -ENOMEM; |
279 | newdrpev->rceb = drpev->rceb; |
280 | newdrpev->src_addr = drpev->wSrcAddr; |
281 | newdrpev->reason = UWB_DRP_NOTIF_DRP_IE_RCVD; |
282 | newdrpev->beacon_slot_number = 0; |
283 | newdrpev->ie_length = drpev->wIELength; |
284 | memcpy(newdrpev->ie_data, drpev->IEData, ielength); |
285 | *header = &newdrpev->rceb; |
286 | *new_size = sizeof(*newdrpev) + ielength; |
287 | return 1; /* calling function will free memory */ |
288 | } |
289 | |
290 | |
291 | /* Scan Command (WUSB 1.0 [8.6.2.5]) */ |
292 | struct uwb_rc_cmd_scan_WUSB_0100 { |
293 | struct uwb_rccb rccb; |
294 | u8 bChannelNumber; |
295 | u8 bScanState; |
296 | } __attribute__((packed)); |
297 | |
298 | /** |
299 | * Filter WHCI 0.95 SCAN command to be WUSB 1.0 SCAN command |
300 | * |
301 | * @header: command sent to device (compliant to WHCI 0.95) |
302 | * @size: size of command sent to device |
303 | * |
304 | * We only reduce the size by two bytes because the WUSB 1.0 scan command |
305 | * does not have the last field (wStarttime). Also, make sure we don't send |
306 | * the device an unexpected scan type. |
307 | */ |
308 | static |
309 | int hwarc_filter_cmd_scan_WUSB_0100(struct uwb_rc *rc, |
310 | struct uwb_rccb **header, |
311 | size_t *size) |
312 | { |
313 | struct uwb_rc_cmd_scan *sc; |
314 | |
315 | sc = container_of(*header, struct uwb_rc_cmd_scan, rccb); |
316 | |
317 | if (sc->bScanState == UWB_SCAN_ONLY_STARTTIME) |
318 | sc->bScanState = UWB_SCAN_ONLY; |
319 | /* Don't send the last two bytes. */ |
320 | *size -= 2; |
321 | return 0; |
322 | } |
323 | |
324 | |
325 | /* SET DRP IE command (WUSB 1.0 [8.6.2.7]) */ |
326 | struct uwb_rc_cmd_set_drp_ie_WUSB_0100 { |
327 | struct uwb_rccb rccb; |
328 | u8 bExplicit; |
329 | __le16 wIELength; |
330 | struct uwb_ie_drp IEData[]; |
331 | } __attribute__((packed)); |
332 | |
333 | /** |
334 | * Filter WHCI 0.95 SET DRP IE command to be WUSB 1.0 SET DRP IE command |
335 | * |
336 | * @header: command sent to device (compliant to WHCI 0.95) |
337 | * @size: size of command sent to device |
338 | * |
339 | * WUSB has an extra bExplicit field - we assume always explicit |
340 | * negotiation so this field is set. The command expected by the device is |
341 | * thus larger than the one prepared by the driver so we need to |
342 | * reallocate memory to accommodate this. |
343 | * We trust the driver to send us the correct data so no checking is done |
344 | * on incoming data - evn though it is variable length. |
345 | */ |
346 | static |
347 | int hwarc_filter_cmd_set_drp_ie_WUSB_0100(struct uwb_rc *rc, |
348 | struct uwb_rccb **header, |
349 | size_t *size) |
350 | { |
351 | struct uwb_rc_cmd_set_drp_ie *orgcmd; |
352 | struct uwb_rc_cmd_set_drp_ie_WUSB_0100 *cmd; |
353 | size_t ielength; |
354 | |
355 | orgcmd = container_of(*header, struct uwb_rc_cmd_set_drp_ie, rccb); |
356 | ielength = le16_to_cpu(orgcmd->wIELength); |
357 | cmd = kzalloc(sizeof(*cmd) + ielength, GFP_KERNEL); |
358 | if (cmd == NULL) |
359 | return -ENOMEM; |
360 | cmd->rccb = orgcmd->rccb; |
361 | cmd->bExplicit = 0; |
362 | cmd->wIELength = orgcmd->wIELength; |
363 | memcpy(cmd->IEData, orgcmd->IEData, ielength); |
364 | *header = &cmd->rccb; |
365 | *size = sizeof(*cmd) + ielength; |
366 | return 1; /* calling function will free memory */ |
367 | } |
368 | |
369 | |
370 | /** |
371 | * Filter data from WHCI driver to WUSB device |
372 | * |
373 | * @header: WHCI 0.95 compliant command from driver |
374 | * @size: length of command |
375 | * |
376 | * The routine managing commands to the device (uwb_rc_cmd()) will call the |
377 | * filtering function pointer (if it exists) before it passes any data to |
378 | * the device. At this time the command has been formatted according to |
379 | * WHCI 0.95 and is ready to be sent to the device. |
380 | * |
381 | * The filter function will be provided with the current command and its |
382 | * length. The function will manipulate the command if necessary and |
383 | * potentially reallocate memory for a command that needed more memory that |
384 | * the given command. If new memory was created the function will return 1 |
385 | * to indicate to the calling function that the memory need to be freed |
386 | * when not needed any more. The size will contain the new length of the |
387 | * command. |
388 | * If memory has not been allocated we rely on the original mechanisms to |
389 | * free the memory of the command - even when we reduce the value of size. |
390 | */ |
391 | static |
392 | int hwarc_filter_cmd_WUSB_0100(struct uwb_rc *rc, struct uwb_rccb **header, |
393 | size_t *size) |
394 | { |
395 | int result; |
396 | struct uwb_rccb *rccb = *header; |
397 | int cmd = le16_to_cpu(rccb->wCommand); |
398 | switch (cmd) { |
399 | case UWB_RC_CMD_SCAN: |
400 | result = hwarc_filter_cmd_scan_WUSB_0100(rc, header, size); |
401 | break; |
402 | case UWB_RC_CMD_SET_DRP_IE: |
403 | result = hwarc_filter_cmd_set_drp_ie_WUSB_0100(rc, header, size); |
404 | break; |
405 | default: |
406 | result = -ENOANO; |
407 | break; |
408 | } |
409 | return result; |
410 | } |
411 | |
412 | |
413 | /** |
414 | * Filter data from WHCI driver to WUSB device |
415 | * |
416 | * @header: WHCI 0.95 compliant command from driver |
417 | * @size: length of command |
418 | * |
419 | * Filter commands based on which protocol the device supports. The WUSB |
420 | * errata should be the same as WHCI 0.95 so we do not filter that here - |
421 | * only WUSB 1.0. |
422 | */ |
423 | static |
424 | int hwarc_filter_cmd(struct uwb_rc *rc, struct uwb_rccb **header, |
425 | size_t *size) |
426 | { |
427 | int result = -ENOANO; |
428 | if (rc->version == 0x0100) |
429 | result = hwarc_filter_cmd_WUSB_0100(rc, header, size); |
430 | return result; |
431 | } |
432 | |
433 | |
434 | /** |
435 | * Compute return value as sum of incoming value and value at given offset |
436 | * |
437 | * @rceb: event for which we compute the size, it contains a variable |
438 | * length field. |
439 | * @core_size: size of the "non variable" part of the event |
440 | * @offset: place in event where the length of the variable part is stored |
441 | * @buf_size: total length of buffer in which event arrived - we need to make |
442 | * sure we read the offset in memory that is still part of the event |
443 | */ |
444 | static |
445 | ssize_t hwarc_get_event_size(struct uwb_rc *rc, const struct uwb_rceb *rceb, |
446 | size_t core_size, size_t offset, |
447 | const size_t buf_size) |
448 | { |
449 | ssize_t size = -ENOSPC; |
450 | const void *ptr = rceb; |
451 | size_t type_size = sizeof(__le16); |
452 | struct device *dev = &rc->uwb_dev.dev; |
453 | |
454 | if (offset + type_size >= buf_size) { |
455 | dev_err(dev, "Not enough data to read extra size of event " |
456 | "0x%02x/%04x/%02x, only got %zu bytes.\n", |
457 | rceb->bEventType, le16_to_cpu(rceb->wEvent), |
458 | rceb->bEventContext, buf_size); |
459 | goto out; |
460 | } |
461 | ptr += offset; |
462 | size = core_size + le16_to_cpu(*(__le16 *)ptr); |
463 | out: |
464 | return size; |
465 | } |
466 | |
467 | |
468 | /* Beacon slot change notification (WUSB 1.0 [8.6.3.5]) */ |
469 | struct uwb_rc_evt_bp_slot_change_WUSB_0100 { |
470 | struct uwb_rceb rceb; |
471 | u8 bSlotNumber; |
472 | } __attribute__((packed)); |
473 | |
474 | |
475 | /** |
476 | * Filter data from WUSB device to WHCI driver |
477 | * |
478 | * @header: incoming event |
479 | * @buf_size: size of buffer in which event arrived |
480 | * @_event_size: actual size of event in the buffer |
481 | * @new_size: size of event after filtered |
482 | * |
483 | * We don't know how the buffer is constructed - there may be more than one |
484 | * event in it so buffer length does not determine event length. We first |
485 | * determine the expected size of the incoming event. This value is passed |
486 | * back only if the actual filtering succeeded (so we know the computed |
487 | * expected size is correct). This value will be zero if |
488 | * the event did not need any filtering. |
489 | * |
490 | * WHCI interprets the BP Slot Change event's data differently than |
491 | * WUSB. The event sizes are exactly the same. The data field |
492 | * indicates the new beacon slot in which a RC is transmitting its |
493 | * beacon. The maximum value of this is 96 (wMacBPLength ECMA-368 |
494 | * 17.16 (Table 117)). We thus know that the WUSB value will not set |
495 | * the bit bNoSlot, so we don't really do anything (placeholder). |
496 | */ |
497 | static |
498 | int hwarc_filter_event_WUSB_0100(struct uwb_rc *rc, struct uwb_rceb **header, |
499 | const size_t buf_size, size_t *_real_size, |
500 | size_t *_new_size) |
501 | { |
502 | int result = -ENOANO; |
503 | struct uwb_rceb *rceb = *header; |
504 | int event = le16_to_cpu(rceb->wEvent); |
505 | ssize_t event_size; |
506 | size_t core_size, offset; |
507 | |
508 | if (rceb->bEventType != UWB_RC_CET_GENERAL) |
509 | goto out; |
510 | switch (event) { |
511 | case UWB_RC_EVT_BEACON: |
512 | core_size = sizeof(struct uwb_rc_evt_beacon_WUSB_0100); |
513 | offset = offsetof(struct uwb_rc_evt_beacon_WUSB_0100, |
514 | wBeaconInfoLength); |
515 | event_size = hwarc_get_event_size(rc, rceb, core_size, |
516 | offset, buf_size); |
517 | if (event_size < 0) |
518 | goto out; |
519 | *_real_size = event_size; |
520 | result = hwarc_filter_evt_beacon_WUSB_0100(rc, header, |
521 | buf_size, _new_size); |
522 | break; |
523 | case UWB_RC_EVT_BP_SLOT_CHANGE: |
524 | *_new_size = *_real_size = |
525 | sizeof(struct uwb_rc_evt_bp_slot_change_WUSB_0100); |
526 | result = 0; |
527 | break; |
528 | |
529 | case UWB_RC_EVT_DRP_AVAIL: |
530 | core_size = sizeof(struct uwb_rc_evt_drp_avail_WUSB_0100); |
531 | offset = offsetof(struct uwb_rc_evt_drp_avail_WUSB_0100, |
532 | wIELength); |
533 | event_size = hwarc_get_event_size(rc, rceb, core_size, |
534 | offset, buf_size); |
535 | if (event_size < 0) |
536 | goto out; |
537 | *_real_size = event_size; |
538 | result = hwarc_filter_evt_drp_avail_WUSB_0100( |
539 | rc, header, buf_size, _new_size); |
540 | break; |
541 | |
542 | case UWB_RC_EVT_DRP: |
543 | core_size = sizeof(struct uwb_rc_evt_drp_WUSB_0100); |
544 | offset = offsetof(struct uwb_rc_evt_drp_WUSB_0100, wIELength); |
545 | event_size = hwarc_get_event_size(rc, rceb, core_size, |
546 | offset, buf_size); |
547 | if (event_size < 0) |
548 | goto out; |
549 | *_real_size = event_size; |
550 | result = hwarc_filter_evt_drp_WUSB_0100(rc, header, |
551 | buf_size, _new_size); |
552 | break; |
553 | |
554 | default: |
555 | break; |
556 | } |
557 | out: |
558 | return result; |
559 | } |
560 | |
561 | /** |
562 | * Filter data from WUSB device to WHCI driver |
563 | * |
564 | * @header: incoming event |
565 | * @buf_size: size of buffer in which event arrived |
566 | * @_event_size: actual size of event in the buffer |
567 | * @_new_size: size of event after filtered |
568 | * |
569 | * Filter events based on which protocol the device supports. The WUSB |
570 | * errata should be the same as WHCI 0.95 so we do not filter that here - |
571 | * only WUSB 1.0. |
572 | * |
573 | * If we don't handle it, we return -ENOANO (why the weird error code? |
574 | * well, so if I get it, I can pinpoint in the code that raised |
575 | * it...after all, not too many places use the higher error codes). |
576 | */ |
577 | static |
578 | int hwarc_filter_event(struct uwb_rc *rc, struct uwb_rceb **header, |
579 | const size_t buf_size, size_t *_real_size, |
580 | size_t *_new_size) |
581 | { |
582 | int result = -ENOANO; |
583 | if (rc->version == 0x0100) |
584 | result = hwarc_filter_event_WUSB_0100( |
585 | rc, header, buf_size, _real_size, _new_size); |
586 | return result; |
587 | } |
588 | |
589 | |
590 | /** |
591 | * Execute an UWB RC command on HWA |
592 | * |
593 | * @rc: Instance of a Radio Controller that is a HWA |
594 | * @cmd: Buffer containing the RCCB and payload to execute |
595 | * @cmd_size: Size of the command buffer. |
596 | * |
597 | * NOTE: rc's mutex has to be locked |
598 | */ |
599 | static |
600 | int hwarc_cmd(struct uwb_rc *uwb_rc, const struct uwb_rccb *cmd, size_t cmd_size) |
601 | { |
602 | struct hwarc *hwarc = uwb_rc->priv; |
603 | return usb_control_msg( |
604 | hwarc->usb_dev, usb_sndctrlpipe(hwarc->usb_dev, 0), |
605 | WA_EXEC_RC_CMD, USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, |
606 | 0, hwarc->usb_iface->cur_altsetting->desc.bInterfaceNumber, |
607 | (void *) cmd, cmd_size, 100 /* FIXME: this is totally arbitrary */); |
608 | } |
609 | |
610 | static |
611 | int hwarc_reset(struct uwb_rc *uwb_rc) |
612 | { |
613 | struct hwarc *hwarc = uwb_rc->priv; |
614 | return usb_reset_device(hwarc->usb_dev); |
615 | } |
616 | |
617 | /** |
618 | * Callback for the notification and event endpoint |
619 | * |
620 | * Check's that everything is fine and then passes the read data to |
621 | * the notification/event handling mechanism (neh). |
622 | */ |
623 | static |
624 | void hwarc_neep_cb(struct urb *urb) |
625 | { |
626 | struct hwarc *hwarc = urb->context; |
627 | struct usb_interface *usb_iface = hwarc->usb_iface; |
628 | struct device *dev = &usb_iface->dev; |
629 | int result; |
630 | |
631 | switch (result = urb->status) { |
632 | case 0: |
633 | uwb_rc_neh_grok(hwarc->uwb_rc, urb->transfer_buffer, |
634 | urb->actual_length); |
635 | break; |
636 | case -ECONNRESET: /* Not an error, but a controlled situation; */ |
637 | case -ENOENT: /* (we killed the URB)...so, no broadcast */ |
638 | goto out; |
639 | case -ESHUTDOWN: /* going away! */ |
640 | goto out; |
641 | default: /* On general errors, retry unless it gets ugly */ |
642 | if (edc_inc(&hwarc->neep_edc, EDC_MAX_ERRORS, |
643 | EDC_ERROR_TIMEFRAME)) |
644 | goto error_exceeded; |
645 | dev_err(dev, "NEEP: URB error %d\n", urb->status); |
646 | } |
647 | result = usb_submit_urb(urb, GFP_ATOMIC); |
648 | if (result < 0 && result != -ENODEV && result != -EPERM) { |
649 | /* ignoring unrecoverable errors */ |
650 | dev_err(dev, "NEEP: Can't resubmit URB (%d) resetting device\n", |
651 | result); |
652 | goto error; |
653 | } |
654 | out: |
655 | return; |
656 | |
657 | error_exceeded: |
658 | dev_err(dev, "NEEP: URB max acceptable errors " |
659 | "exceeded, resetting device\n"); |
660 | error: |
661 | uwb_rc_neh_error(hwarc->uwb_rc, result); |
662 | uwb_rc_reset_all(hwarc->uwb_rc); |
663 | return; |
664 | } |
665 | |
666 | static void hwarc_init(struct hwarc *hwarc) |
667 | { |
668 | edc_init(&hwarc->neep_edc); |
669 | } |
670 | |
671 | /** |
672 | * Initialize the notification/event endpoint stuff |
673 | * |
674 | * Note this is effectively a parallel thread; it knows that |
675 | * hwarc->uwb_rc always exists because the existence of a 'hwarc' |
676 | * means that there is a reverence on the hwarc->uwb_rc (see |
677 | * _probe()), and thus _neep_cb() can execute safely. |
678 | */ |
679 | static int hwarc_neep_init(struct uwb_rc *rc) |
680 | { |
681 | struct hwarc *hwarc = rc->priv; |
682 | struct usb_interface *iface = hwarc->usb_iface; |
683 | struct usb_device *usb_dev = interface_to_usbdev(iface); |
684 | struct device *dev = &iface->dev; |
685 | int result; |
686 | struct usb_endpoint_descriptor *epd; |
687 | |
688 | epd = &iface->cur_altsetting->endpoint[0].desc; |
689 | hwarc->rd_buffer = (void *) __get_free_page(GFP_KERNEL); |
690 | if (hwarc->rd_buffer == NULL) { |
691 | dev_err(dev, "Unable to allocate notification's read buffer\n"); |
692 | goto error_rd_buffer; |
693 | } |
694 | hwarc->neep_urb = usb_alloc_urb(0, GFP_KERNEL); |
695 | if (hwarc->neep_urb == NULL) { |
696 | dev_err(dev, "Unable to allocate notification URB\n"); |
697 | goto error_urb_alloc; |
698 | } |
699 | usb_fill_int_urb(hwarc->neep_urb, usb_dev, |
700 | usb_rcvintpipe(usb_dev, epd->bEndpointAddress), |
701 | hwarc->rd_buffer, PAGE_SIZE, |
702 | hwarc_neep_cb, hwarc, epd->bInterval); |
703 | result = usb_submit_urb(hwarc->neep_urb, GFP_ATOMIC); |
704 | if (result < 0) { |
705 | dev_err(dev, "Cannot submit notification URB: %d\n", result); |
706 | goto error_neep_submit; |
707 | } |
708 | return 0; |
709 | |
710 | error_neep_submit: |
711 | usb_free_urb(hwarc->neep_urb); |
712 | error_urb_alloc: |
713 | free_page((unsigned long)hwarc->rd_buffer); |
714 | error_rd_buffer: |
715 | return -ENOMEM; |
716 | } |
717 | |
718 | |
719 | /** Clean up all the notification endpoint resources */ |
720 | static void hwarc_neep_release(struct uwb_rc *rc) |
721 | { |
722 | struct hwarc *hwarc = rc->priv; |
723 | |
724 | usb_kill_urb(hwarc->neep_urb); |
725 | usb_free_urb(hwarc->neep_urb); |
726 | free_page((unsigned long)hwarc->rd_buffer); |
727 | } |
728 | |
729 | /** |
730 | * Get the version from class-specific descriptor |
731 | * |
732 | * NOTE: this descriptor comes with the big bundled configuration |
733 | * descriptor that includes the interfaces' and endpoints', so |
734 | * we just look for it in the cached copy kept by the USB stack. |
735 | * |
736 | * NOTE2: We convert LE fields to CPU order. |
737 | */ |
738 | static int hwarc_get_version(struct uwb_rc *rc) |
739 | { |
740 | int result; |
741 | |
742 | struct hwarc *hwarc = rc->priv; |
743 | struct uwb_rc_control_intf_class_desc *descr; |
744 | struct device *dev = &rc->uwb_dev.dev; |
745 | struct usb_device *usb_dev = hwarc->usb_dev; |
746 | char *itr; |
747 | struct usb_descriptor_header *hdr; |
748 | size_t itr_size, actconfig_idx; |
749 | u16 version; |
750 | |
751 | actconfig_idx = (usb_dev->actconfig - usb_dev->config) / |
752 | sizeof(usb_dev->config[0]); |
753 | itr = usb_dev->rawdescriptors[actconfig_idx]; |
754 | itr_size = le16_to_cpu(usb_dev->actconfig->desc.wTotalLength); |
755 | while (itr_size >= sizeof(*hdr)) { |
756 | hdr = (struct usb_descriptor_header *) itr; |
757 | dev_dbg(dev, "Extra device descriptor: " |
758 | "type %02x/%u bytes @ %zu (%zu left)\n", |
759 | hdr->bDescriptorType, hdr->bLength, |
760 | (itr - usb_dev->rawdescriptors[actconfig_idx]), |
761 | itr_size); |
762 | if (hdr->bDescriptorType == USB_DT_CS_RADIO_CONTROL) |
763 | goto found; |
764 | itr += hdr->bLength; |
765 | itr_size -= hdr->bLength; |
766 | } |
767 | dev_err(dev, "cannot find Radio Control Interface Class descriptor\n"); |
768 | return -ENODEV; |
769 | |
770 | found: |
771 | result = -EINVAL; |
772 | if (hdr->bLength > itr_size) { /* is it available? */ |
773 | dev_err(dev, "incomplete Radio Control Interface Class " |
774 | "descriptor (%zu bytes left, %u needed)\n", |
775 | itr_size, hdr->bLength); |
776 | goto error; |
777 | } |
778 | if (hdr->bLength < sizeof(*descr)) { |
779 | dev_err(dev, "short Radio Control Interface Class " |
780 | "descriptor\n"); |
781 | goto error; |
782 | } |
783 | descr = (struct uwb_rc_control_intf_class_desc *) hdr; |
784 | /* Make LE fields CPU order */ |
785 | version = __le16_to_cpu(descr->bcdRCIVersion); |
786 | if (version != 0x0100) { |
787 | dev_err(dev, "Device reports protocol version 0x%04x. We " |
788 | "do not support that. \n", version); |
789 | result = -EINVAL; |
790 | goto error; |
791 | } |
792 | rc->version = version; |
793 | dev_dbg(dev, "Device supports WUSB protocol version 0x%04x \n", rc->version); |
794 | result = 0; |
795 | error: |
796 | return result; |
797 | } |
798 | |
799 | /* |
800 | * By creating a 'uwb_rc', we have a reference on it -- that reference |
801 | * is the one we drop when we disconnect. |
802 | * |
803 | * No need to switch altsettings; according to WUSB1.0[8.6.1.1], there |
804 | * is only one altsetting allowed. |
805 | */ |
806 | static int hwarc_probe(struct usb_interface *iface, |
807 | const struct usb_device_id *id) |
808 | { |
809 | int result; |
810 | struct uwb_rc *uwb_rc; |
811 | struct hwarc *hwarc; |
812 | struct device *dev = &iface->dev; |
813 | |
814 | result = -ENOMEM; |
815 | uwb_rc = uwb_rc_alloc(); |
816 | if (uwb_rc == NULL) { |
817 | dev_err(dev, "unable to allocate RC instance\n"); |
818 | goto error_rc_alloc; |
819 | } |
820 | hwarc = kzalloc(sizeof(*hwarc), GFP_KERNEL); |
821 | if (hwarc == NULL) { |
822 | dev_err(dev, "unable to allocate HWA RC instance\n"); |
823 | goto error_alloc; |
824 | } |
825 | hwarc_init(hwarc); |
826 | hwarc->usb_dev = usb_get_dev(interface_to_usbdev(iface)); |
827 | hwarc->usb_iface = usb_get_intf(iface); |
828 | hwarc->uwb_rc = uwb_rc; |
829 | |
830 | uwb_rc->owner = THIS_MODULE; |
831 | uwb_rc->start = hwarc_neep_init; |
832 | uwb_rc->stop = hwarc_neep_release; |
833 | uwb_rc->cmd = hwarc_cmd; |
834 | uwb_rc->reset = hwarc_reset; |
835 | if (id->driver_info & WUSB_QUIRK_WHCI_CMD_EVT) { |
836 | uwb_rc->filter_cmd = NULL; |
837 | uwb_rc->filter_event = NULL; |
838 | } else { |
839 | uwb_rc->filter_cmd = hwarc_filter_cmd; |
840 | uwb_rc->filter_event = hwarc_filter_event; |
841 | } |
842 | |
843 | result = uwb_rc_add(uwb_rc, dev, hwarc); |
844 | if (result < 0) |
845 | goto error_rc_add; |
846 | result = hwarc_get_version(uwb_rc); |
847 | if (result < 0) { |
848 | dev_err(dev, "cannot retrieve version of RC \n"); |
849 | goto error_get_version; |
850 | } |
851 | usb_set_intfdata(iface, hwarc); |
852 | return 0; |
853 | |
854 | error_get_version: |
855 | uwb_rc_rm(uwb_rc); |
856 | error_rc_add: |
857 | usb_put_intf(iface); |
858 | usb_put_dev(hwarc->usb_dev); |
859 | error_alloc: |
860 | uwb_rc_put(uwb_rc); |
861 | error_rc_alloc: |
862 | return result; |
863 | } |
864 | |
865 | static void hwarc_disconnect(struct usb_interface *iface) |
866 | { |
867 | struct hwarc *hwarc = usb_get_intfdata(iface); |
868 | struct uwb_rc *uwb_rc = hwarc->uwb_rc; |
869 | |
870 | usb_set_intfdata(hwarc->usb_iface, NULL); |
871 | uwb_rc_rm(uwb_rc); |
872 | usb_put_intf(hwarc->usb_iface); |
873 | usb_put_dev(hwarc->usb_dev); |
874 | kfree(hwarc); |
875 | uwb_rc_put(uwb_rc); /* when creating the device, refcount = 1 */ |
876 | } |
877 | |
878 | static int hwarc_pre_reset(struct usb_interface *iface) |
879 | { |
880 | struct hwarc *hwarc = usb_get_intfdata(iface); |
881 | struct uwb_rc *uwb_rc = hwarc->uwb_rc; |
882 | |
883 | uwb_rc_pre_reset(uwb_rc); |
884 | return 0; |
885 | } |
886 | |
887 | static int hwarc_post_reset(struct usb_interface *iface) |
888 | { |
889 | struct hwarc *hwarc = usb_get_intfdata(iface); |
890 | struct uwb_rc *uwb_rc = hwarc->uwb_rc; |
891 | |
892 | return uwb_rc_post_reset(uwb_rc); |
893 | } |
894 | |
895 | /** USB device ID's that we handle */ |
896 | static const struct usb_device_id hwarc_id_table[] = { |
897 | /* D-Link DUB-1210 */ |
898 | { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3d02, 0xe0, 0x01, 0x02), |
899 | .driver_info = WUSB_QUIRK_WHCI_CMD_EVT }, |
900 | /* Intel i1480 (using firmware 1.3PA2-20070828) */ |
901 | { USB_DEVICE_AND_INTERFACE_INFO(0x8086, 0x0c3b, 0xe0, 0x01, 0x02), |
902 | .driver_info = WUSB_QUIRK_WHCI_CMD_EVT }, |
903 | /* Generic match for the Radio Control interface */ |
904 | { USB_INTERFACE_INFO(0xe0, 0x01, 0x02), }, |
905 | { }, |
906 | }; |
907 | MODULE_DEVICE_TABLE(usb, hwarc_id_table); |
908 | |
909 | static struct usb_driver hwarc_driver = { |
910 | .name = "hwa-rc", |
911 | .id_table = hwarc_id_table, |
912 | .probe = hwarc_probe, |
913 | .disconnect = hwarc_disconnect, |
914 | .pre_reset = hwarc_pre_reset, |
915 | .post_reset = hwarc_post_reset, |
916 | }; |
917 | |
918 | module_usb_driver(hwarc_driver); |
919 | |
920 | MODULE_AUTHOR("Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>"); |
921 | MODULE_DESCRIPTION("Host Wireless Adapter Radio Control Driver"); |
922 | MODULE_LICENSE("GPL"); |
923 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9