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