aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorDavid Vrabel <dv02@dv02pc01.europe.root.pri>2008-10-10 06:47:31 -0400
committerDavid Vrabel <dv02@dv02pc01.europe.root.pri>2008-10-10 06:47:31 -0400
commit99ee3a6d4577e7633c66304e4aefeca5489c8d5c (patch)
tree94dbf1db8b2efb6b4fdaf6fdaa86de655c64ff1c /drivers/usb
parent3fa8749e584b55f1180411ab1b51117190bac1e5 (diff)
parentedfa042c880f62848aa55b3e71e538fe383929da (diff)
Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/dvrabel/uwb into for-upstream
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/Kconfig2
-rw-r--r--drivers/usb/Makefile3
-rw-r--r--drivers/usb/host/Kconfig28
-rw-r--r--drivers/usb/host/Makefile3
-rw-r--r--drivers/usb/host/hwa-hc.c925
-rw-r--r--drivers/usb/host/whci/Kbuild11
-rw-r--r--drivers/usb/host/whci/asl.c367
-rw-r--r--drivers/usb/host/whci/hcd.c339
-rw-r--r--drivers/usb/host/whci/hw.c87
-rw-r--r--drivers/usb/host/whci/init.c188
-rw-r--r--drivers/usb/host/whci/int.c95
-rw-r--r--drivers/usb/host/whci/pzl.c398
-rw-r--r--drivers/usb/host/whci/qset.c567
-rw-r--r--drivers/usb/host/whci/whcd.h197
-rw-r--r--drivers/usb/host/whci/whci-hc.h416
-rw-r--r--drivers/usb/host/whci/wusb.c241
-rw-r--r--drivers/usb/wusbcore/Kconfig41
-rw-r--r--drivers/usb/wusbcore/Makefile26
-rw-r--r--drivers/usb/wusbcore/cbaf.c673
-rw-r--r--drivers/usb/wusbcore/crypto.c538
-rw-r--r--drivers/usb/wusbcore/dev-sysfs.c143
-rw-r--r--drivers/usb/wusbcore/devconnect.c1314
-rw-r--r--drivers/usb/wusbcore/mmc.c329
-rw-r--r--drivers/usb/wusbcore/pal.c42
-rw-r--r--drivers/usb/wusbcore/reservation.c115
-rw-r--r--drivers/usb/wusbcore/rh.c477
-rw-r--r--drivers/usb/wusbcore/security.c642
-rw-r--r--drivers/usb/wusbcore/wa-hc.c95
-rw-r--r--drivers/usb/wusbcore/wa-hc.h417
-rw-r--r--drivers/usb/wusbcore/wa-nep.c310
-rw-r--r--drivers/usb/wusbcore/wa-rpipe.c562
-rw-r--r--drivers/usb/wusbcore/wa-xfer.c1709
-rw-r--r--drivers/usb/wusbcore/wusbhc.c418
-rw-r--r--drivers/usb/wusbcore/wusbhc.h495
34 files changed, 12213 insertions, 0 deletions
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index bcefbddeba50..c23a9857ee67 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -97,6 +97,8 @@ source "drivers/usb/core/Kconfig"
97 97
98source "drivers/usb/mon/Kconfig" 98source "drivers/usb/mon/Kconfig"
99 99
100source "drivers/usb/wusbcore/Kconfig"
101
100source "drivers/usb/host/Kconfig" 102source "drivers/usb/host/Kconfig"
101 103
102source "drivers/usb/musb/Kconfig" 104source "drivers/usb/musb/Kconfig"
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
index a419c42e880e..8b7c419b876e 100644
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
@@ -16,9 +16,12 @@ obj-$(CONFIG_USB_UHCI_HCD) += host/
16obj-$(CONFIG_USB_SL811_HCD) += host/ 16obj-$(CONFIG_USB_SL811_HCD) += host/
17obj-$(CONFIG_USB_U132_HCD) += host/ 17obj-$(CONFIG_USB_U132_HCD) += host/
18obj-$(CONFIG_USB_R8A66597_HCD) += host/ 18obj-$(CONFIG_USB_R8A66597_HCD) += host/
19obj-$(CONFIG_USB_HWA_HCD) += host/
19 20
20obj-$(CONFIG_USB_C67X00_HCD) += c67x00/ 21obj-$(CONFIG_USB_C67X00_HCD) += c67x00/
21 22
23obj-$(CONFIG_USB_WUSB) += wusbcore/
24
22obj-$(CONFIG_USB_ACM) += class/ 25obj-$(CONFIG_USB_ACM) += class/
23obj-$(CONFIG_USB_PRINTER) += class/ 26obj-$(CONFIG_USB_PRINTER) += class/
24 27
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 228797e54f9c..72fb655e6033 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -305,3 +305,31 @@ config SUPERH_ON_CHIP_R8A66597
305 help 305 help
306 This driver enables support for the on-chip R8A66597 in the 306 This driver enables support for the on-chip R8A66597 in the
307 SH7366 and SH7723 processors. 307 SH7366 and SH7723 processors.
308
309config USB_WHCI_HCD
310 tristate "Wireless USB Host Controller Interface (WHCI) driver (EXPERIMENTAL)"
311 depends on EXPERIMENTAL
312 depends on PCI && USB
313 select USB_WUSB
314 select UWB_WHCI
315 help
316 A driver for PCI-based Wireless USB Host Controllers that are
317 compliant with the WHCI specification.
318
319 To compile this driver a module, choose M here: the module
320 will be called "whci-hcd".
321
322config USB_HWA_HCD
323 tristate "Host Wire Adapter (HWA) driver (EXPERIMENTAL)"
324 depends on EXPERIMENTAL
325 depends on USB
326 select USB_WUSB
327 select UWB_HWA
328 help
329 This driver enables you to connect Wireless USB devices to
330 your system using a Host Wire Adaptor USB dongle. This is an
331 UWB Radio Controller and WUSB Host Controller connected to
332 your machine via USB (specified in WUSB1.0).
333
334 To compile this driver a module, choose M here: the module
335 will be called "hwa-hc".
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index f1edda2dcfde..23be22224044 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -8,6 +8,8 @@ endif
8 8
9isp1760-objs := isp1760-hcd.o isp1760-if.o 9isp1760-objs := isp1760-hcd.o isp1760-if.o
10 10
11obj-$(CONFIG_USB_WHCI_HCD) += whci/
12
11obj-$(CONFIG_PCI) += pci-quirks.o 13obj-$(CONFIG_PCI) += pci-quirks.o
12 14
13obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o 15obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o
@@ -19,3 +21,4 @@ obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o
19obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o 21obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o
20obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o 22obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o
21obj-$(CONFIG_USB_ISP1760_HCD) += isp1760.o 23obj-$(CONFIG_USB_ISP1760_HCD) += isp1760.o
24obj-$(CONFIG_USB_HWA_HCD) += hwa-hc.o
diff --git a/drivers/usb/host/hwa-hc.c b/drivers/usb/host/hwa-hc.c
new file mode 100644
index 000000000000..64be4d88df11
--- /dev/null
+++ b/drivers/usb/host/hwa-hc.c
@@ -0,0 +1,925 @@
1/*
2 * Host Wire Adapter:
3 * Driver glue, HWA-specific functions, bridges to WAHC and WUSBHC
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 * The HWA driver is a simple layer that forwards requests to the WAHC
24 * (Wire Adater Host Controller) or WUSBHC (Wireless USB Host
25 * Controller) layers.
26 *
27 * Host Wire Adapter is the 'WUSB 1.0 standard' name for Wireless-USB
28 * Host Controller that is connected to your system via USB (a USB
29 * dongle that implements a USB host...). There is also a Device Wired
30 * Adaptor, DWA (Wireless USB hub) that uses the same mechanism for
31 * transferring data (it is after all a USB host connected via
32 * Wireless USB), we have a common layer called Wire Adapter Host
33 * Controller that does all the hard work. The WUSBHC (Wireless USB
34 * Host Controller) is the part common to WUSB Host Controllers, the
35 * HWA and the PCI-based one, that is implemented following the WHCI
36 * spec. All these layers are implemented in ../wusbcore.
37 *
38 * The main functions are hwahc_op_urb_{en,de}queue(), that pass the
39 * job of converting a URB to a Wire Adapter
40 *
41 * Entry points:
42 *
43 * hwahc_driver_*() Driver initialization, registration and
44 * teardown.
45 *
46 * hwahc_probe() New device came up, create an instance for
47 * it [from device enumeration].
48 *
49 * hwahc_disconnect() Remove device instance [from device
50 * enumeration].
51 *
52 * [__]hwahc_op_*() Host-Wire-Adaptor specific functions for
53 * starting/stopping/etc (some might be made also
54 * DWA).
55 */
56#include <linux/kernel.h>
57#include <linux/version.h>
58#include <linux/init.h>
59#include <linux/module.h>
60#include <linux/workqueue.h>
61#include <linux/wait.h>
62#include <linux/completion.h>
63#include "../wusbcore/wa-hc.h"
64#include "../wusbcore/wusbhc.h"
65
66#define D_LOCAL 0
67#include <linux/uwb/debug.h>
68
69struct hwahc {
70 struct wusbhc wusbhc; /* has to be 1st */
71 struct wahc wa;
72 u8 buffer[16]; /* for misc usb transactions */
73};
74
75/**
76 * FIXME should be wusbhc
77 *
78 * NOTE: we need to cache the Cluster ID because later...there is no
79 * way to get it :)
80 */
81static int __hwahc_set_cluster_id(struct hwahc *hwahc, u8 cluster_id)
82{
83 int result;
84 struct wusbhc *wusbhc = &hwahc->wusbhc;
85 struct wahc *wa = &hwahc->wa;
86 struct device *dev = &wa->usb_iface->dev;
87
88 result = usb_control_msg(wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
89 WUSB_REQ_SET_CLUSTER_ID,
90 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
91 cluster_id,
92 wa->usb_iface->cur_altsetting->desc.bInterfaceNumber,
93 NULL, 0, 1000 /* FIXME: arbitrary */);
94 if (result < 0)
95 dev_err(dev, "Cannot set WUSB Cluster ID to 0x%02x: %d\n",
96 cluster_id, result);
97 else
98 wusbhc->cluster_id = cluster_id;
99 dev_info(dev, "Wireless USB Cluster ID set to 0x%02x\n", cluster_id);
100 return result;
101}
102
103static int __hwahc_op_set_num_dnts(struct wusbhc *wusbhc, u8 interval, u8 slots)
104{
105 struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
106 struct wahc *wa = &hwahc->wa;
107
108 return usb_control_msg(wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
109 WUSB_REQ_SET_NUM_DNTS,
110 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
111 interval << 8 | slots,
112 wa->usb_iface->cur_altsetting->desc.bInterfaceNumber,
113 NULL, 0, 1000 /* FIXME: arbitrary */);
114}
115
116/*
117 * Reset a WUSB host controller and wait for it to complete doing it.
118 *
119 * @usb_hcd: Pointer to WUSB Host Controller instance.
120 *
121 */
122static int hwahc_op_reset(struct usb_hcd *usb_hcd)
123{
124 int result;
125 struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
126 struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
127 struct device *dev = &hwahc->wa.usb_iface->dev;
128
129 d_fnstart(4, dev, "(hwahc %p)\n", hwahc);
130 mutex_lock(&wusbhc->mutex);
131 wa_nep_disarm(&hwahc->wa);
132 result = __wa_set_feature(&hwahc->wa, WA_RESET);
133 if (result < 0) {
134 dev_err(dev, "error commanding HC to reset: %d\n", result);
135 goto error_unlock;
136 }
137 d_printf(3, dev, "reset: waiting for device to change state\n");
138 result = __wa_wait_status(&hwahc->wa, WA_STATUS_RESETTING, 0);
139 if (result < 0) {
140 dev_err(dev, "error waiting for HC to reset: %d\n", result);
141 goto error_unlock;
142 }
143error_unlock:
144 mutex_unlock(&wusbhc->mutex);
145 d_fnend(4, dev, "(hwahc %p) = %d\n", hwahc, result);
146 return result;
147}
148
149/*
150 * FIXME: break this function up
151 */
152static int hwahc_op_start(struct usb_hcd *usb_hcd)
153{
154 u8 addr;
155 int result;
156 struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
157 struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
158 struct device *dev = &hwahc->wa.usb_iface->dev;
159
160 /* Set up a Host Info WUSB Information Element */
161 d_fnstart(4, dev, "(hwahc %p)\n", hwahc);
162 result = -ENOSPC;
163 mutex_lock(&wusbhc->mutex);
164 /* Start the numbering from the top so that the bottom
165 * range of the unauth addr space is used for devices,
166 * the top for HCs; use 0xfe - RC# */
167 addr = wusb_cluster_id_get();
168 if (addr == 0)
169 goto error_cluster_id_get;
170 result = __hwahc_set_cluster_id(hwahc, addr);
171 if (result < 0)
172 goto error_set_cluster_id;
173
174 result = wa_nep_arm(&hwahc->wa, GFP_KERNEL);
175 if (result < 0) {
176 dev_err(dev, "cannot listen to notifications: %d\n", result);
177 goto error_stop;
178 }
179 usb_hcd->uses_new_polling = 1;
180 usb_hcd->poll_rh = 1;
181 usb_hcd->state = HC_STATE_RUNNING;
182 result = 0;
183out:
184 mutex_unlock(&wusbhc->mutex);
185 d_fnend(4, dev, "(hwahc %p) = %d\n", hwahc, result);
186 return result;
187
188error_stop:
189 __wa_stop(&hwahc->wa);
190error_set_cluster_id:
191 wusb_cluster_id_put(wusbhc->cluster_id);
192error_cluster_id_get:
193 goto out;
194
195}
196
197/*
198 * FIXME: break this function up
199 */
200static int __hwahc_op_wusbhc_start(struct wusbhc *wusbhc)
201{
202 int result;
203 struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
204 struct device *dev = &hwahc->wa.usb_iface->dev;
205
206 /* Set up a Host Info WUSB Information Element */
207 d_fnstart(4, dev, "(hwahc %p)\n", hwahc);
208 result = -ENOSPC;
209
210 result = __wa_set_feature(&hwahc->wa, WA_ENABLE);
211 if (result < 0) {
212 dev_err(dev, "error commanding HC to start: %d\n", result);
213 goto error_stop;
214 }
215 result = __wa_wait_status(&hwahc->wa, WA_ENABLE, WA_ENABLE);
216 if (result < 0) {
217 dev_err(dev, "error waiting for HC to start: %d\n", result);
218 goto error_stop;
219 }
220 result = 0;
221out:
222 d_fnend(4, dev, "(hwahc %p) = %d\n", hwahc, result);
223 return result;
224
225error_stop:
226 result = __wa_clear_feature(&hwahc->wa, WA_ENABLE);
227 goto out;
228}
229
230static int hwahc_op_suspend(struct usb_hcd *usb_hcd, pm_message_t msg)
231{
232 struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
233 struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
234 dev_err(wusbhc->dev, "%s (%p [%p], 0x%lx) UNIMPLEMENTED\n", __func__,
235 usb_hcd, hwahc, *(unsigned long *) &msg);
236 return -ENOSYS;
237}
238
239static int hwahc_op_resume(struct usb_hcd *usb_hcd)
240{
241 struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
242 struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
243
244 dev_err(wusbhc->dev, "%s (%p [%p]) UNIMPLEMENTED\n", __func__,
245 usb_hcd, hwahc);
246 return -ENOSYS;
247}
248
249static void __hwahc_op_wusbhc_stop(struct wusbhc *wusbhc)
250{
251 int result;
252 struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
253 struct device *dev = &hwahc->wa.usb_iface->dev;
254
255 d_fnstart(4, dev, "(hwahc %p)\n", hwahc);
256 /* Nothing for now */
257 d_fnend(4, dev, "(hwahc %p) = %d\n", hwahc, result);
258 return;
259}
260
261/*
262 * No need to abort pipes, as when this is called, all the children
263 * has been disconnected and that has done it [through
264 * usb_disable_interface() -> usb_disable_endpoint() ->
265 * hwahc_op_ep_disable() - >rpipe_ep_disable()].
266 */
267static void hwahc_op_stop(struct usb_hcd *usb_hcd)
268{
269 int result;
270 struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
271 struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
272 struct wahc *wa = &hwahc->wa;
273 struct device *dev = &wa->usb_iface->dev;
274
275 d_fnstart(4, dev, "(hwahc %p)\n", hwahc);
276 mutex_lock(&wusbhc->mutex);
277 wusbhc_stop(wusbhc);
278 wa_nep_disarm(&hwahc->wa);
279 result = __wa_stop(&hwahc->wa);
280 wusb_cluster_id_put(wusbhc->cluster_id);
281 mutex_unlock(&wusbhc->mutex);
282 d_fnend(4, dev, "(hwahc %p) = %d\n", hwahc, result);
283 return;
284}
285
286static int hwahc_op_get_frame_number(struct usb_hcd *usb_hcd)
287{
288 struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
289 struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
290
291 dev_err(wusbhc->dev, "%s (%p [%p]) UNIMPLEMENTED\n", __func__,
292 usb_hcd, hwahc);
293 return -ENOSYS;
294}
295
296static int hwahc_op_urb_enqueue(struct usb_hcd *usb_hcd, struct urb *urb,
297 gfp_t gfp)
298{
299 struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
300 struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
301
302 return wa_urb_enqueue(&hwahc->wa, urb->ep, urb, gfp);
303}
304
305static int hwahc_op_urb_dequeue(struct usb_hcd *usb_hcd, struct urb *urb,
306 int status)
307{
308 struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
309 struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
310
311 return wa_urb_dequeue(&hwahc->wa, urb);
312}
313
314/*
315 * Release resources allocated for an endpoint
316 *
317 * If there is an associated rpipe to this endpoint, go ahead and put it.
318 */
319static void hwahc_op_endpoint_disable(struct usb_hcd *usb_hcd,
320 struct usb_host_endpoint *ep)
321{
322 struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
323 struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
324
325 rpipe_ep_disable(&hwahc->wa, ep);
326}
327
328/*
329 * Set the UWB MAS allocation for the WUSB cluster
330 *
331 * @stream_index: stream to use (-1 for cancelling the allocation)
332 * @mas: mas bitmap to use
333 */
334static int __hwahc_op_bwa_set(struct wusbhc *wusbhc, s8 stream_index,
335 const struct uwb_mas_bm *mas)
336{
337 int result;
338 struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
339 struct wahc *wa = &hwahc->wa;
340 struct device *dev = &wa->usb_iface->dev;
341 u8 mas_le[UWB_NUM_MAS/8];
342
343 /* Set the stream index */
344 result = usb_control_msg(wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
345 WUSB_REQ_SET_STREAM_IDX,
346 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
347 stream_index,
348 wa->usb_iface->cur_altsetting->desc.bInterfaceNumber,
349 NULL, 0, 1000 /* FIXME: arbitrary */);
350 if (result < 0) {
351 dev_err(dev, "Cannot set WUSB stream index: %d\n", result);
352 goto out;
353 }
354 uwb_mas_bm_copy_le(mas_le, mas);
355 /* Set the MAS allocation */
356 result = usb_control_msg(wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
357 WUSB_REQ_SET_WUSB_MAS,
358 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
359 0, wa->usb_iface->cur_altsetting->desc.bInterfaceNumber,
360 mas_le, 32, 1000 /* FIXME: arbitrary */);
361 if (result < 0)
362 dev_err(dev, "Cannot set WUSB MAS allocation: %d\n", result);
363out:
364 return result;
365}
366
367/*
368 * Add an IE to the host's MMC
369 *
370 * @interval: See WUSB1.0[8.5.3.1]
371 * @repeat_cnt: See WUSB1.0[8.5.3.1]
372 * @handle: See WUSB1.0[8.5.3.1]
373 * @wuie: Pointer to the header of the WUSB IE data to add.
374 * MUST BE allocated in a kmalloc buffer (no stack or
375 * vmalloc).
376 *
377 * NOTE: the format of the WUSB IEs for MMCs are different to the
378 * normal MBOA MAC IEs (IE Id + Length in MBOA MAC vs. Length +
379 * Id in WUSB IEs). Standards...you gotta love'em.
380 */
381static int __hwahc_op_mmcie_add(struct wusbhc *wusbhc, u8 interval,
382 u8 repeat_cnt, u8 handle,
383 struct wuie_hdr *wuie)
384{
385 struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
386 struct wahc *wa = &hwahc->wa;
387 u8 iface_no = wa->usb_iface->cur_altsetting->desc.bInterfaceNumber;
388
389 return usb_control_msg(wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
390 WUSB_REQ_ADD_MMC_IE,
391 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
392 interval << 8 | repeat_cnt,
393 handle << 8 | iface_no,
394 wuie, wuie->bLength, 1000 /* FIXME: arbitrary */);
395}
396
397/*
398 * Remove an IE to the host's MMC
399 *
400 * @handle: See WUSB1.0[8.5.3.1]
401 */
402static int __hwahc_op_mmcie_rm(struct wusbhc *wusbhc, u8 handle)
403{
404 struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
405 struct wahc *wa = &hwahc->wa;
406 u8 iface_no = wa->usb_iface->cur_altsetting->desc.bInterfaceNumber;
407 return usb_control_msg(wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
408 WUSB_REQ_REMOVE_MMC_IE,
409 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
410 0, handle << 8 | iface_no,
411 NULL, 0, 1000 /* FIXME: arbitrary */);
412}
413
414/*
415 * Update device information for a given fake port
416 *
417 * @port_idx: Fake port to which device is connected (wusbhc index, not
418 * USB port number).
419 */
420static int __hwahc_op_dev_info_set(struct wusbhc *wusbhc,
421 struct wusb_dev *wusb_dev)
422{
423 struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
424 struct wahc *wa = &hwahc->wa;
425 u8 iface_no = wa->usb_iface->cur_altsetting->desc.bInterfaceNumber;
426 struct hwa_dev_info *dev_info;
427 int ret;
428
429 /* fill out the Device Info buffer and send it */
430 dev_info = kzalloc(sizeof(struct hwa_dev_info), GFP_KERNEL);
431 if (!dev_info)
432 return -ENOMEM;
433 uwb_mas_bm_copy_le(dev_info->bmDeviceAvailability,
434 &wusb_dev->availability);
435 dev_info->bDeviceAddress = wusb_dev->addr;
436
437 /*
438 * If the descriptors haven't been read yet, use a default PHY
439 * rate of 53.3 Mbit/s only. The correct value will be used
440 * when this will be called again as part of the
441 * authentication process (which occurs after the descriptors
442 * have been read).
443 */
444 if (wusb_dev->wusb_cap_descr)
445 dev_info->wPHYRates = wusb_dev->wusb_cap_descr->wPHYRates;
446 else
447 dev_info->wPHYRates = cpu_to_le16(USB_WIRELESS_PHY_53);
448
449 ret = usb_control_msg(wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
450 WUSB_REQ_SET_DEV_INFO,
451 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
452 0, wusb_dev->port_idx << 8 | iface_no,
453 dev_info, sizeof(struct hwa_dev_info),
454 1000 /* FIXME: arbitrary */);
455 kfree(dev_info);
456 return ret;
457}
458
459/*
460 * Set host's idea of which encryption (and key) method to use when
461 * talking to ad evice on a given port.
462 *
463 * If key is NULL, it means disable encryption for that "virtual port"
464 * (used when we disconnect).
465 */
466static int __hwahc_dev_set_key(struct wusbhc *wusbhc, u8 port_idx, u32 tkid,
467 const void *key, size_t key_size,
468 u8 key_idx)
469{
470 int result = -ENOMEM;
471 struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
472 struct wahc *wa = &hwahc->wa;
473 u8 iface_no = wa->usb_iface->cur_altsetting->desc.bInterfaceNumber;
474 struct usb_key_descriptor *keyd;
475 size_t keyd_len;
476
477 keyd_len = sizeof(*keyd) + key_size;
478 keyd = kzalloc(keyd_len, GFP_KERNEL);
479 if (keyd == NULL)
480 return -ENOMEM;
481
482 keyd->bLength = keyd_len;
483 keyd->bDescriptorType = USB_DT_KEY;
484 keyd->tTKID[0] = (tkid >> 0) & 0xff;
485 keyd->tTKID[1] = (tkid >> 8) & 0xff;
486 keyd->tTKID[2] = (tkid >> 16) & 0xff;
487 memcpy(keyd->bKeyData, key, key_size);
488
489 result = usb_control_msg(wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
490 USB_REQ_SET_DESCRIPTOR,
491 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
492 USB_DT_KEY << 8 | key_idx,
493 port_idx << 8 | iface_no,
494 keyd, keyd_len, 1000 /* FIXME: arbitrary */);
495
496 memset(keyd, 0, sizeof(*keyd)); /* clear keys etc. */
497 kfree(keyd);
498 return result;
499}
500
501/*
502 * Set host's idea of which encryption (and key) method to use when
503 * talking to ad evice on a given port.
504 *
505 * If key is NULL, it means disable encryption for that "virtual port"
506 * (used when we disconnect).
507 */
508static int __hwahc_op_set_ptk(struct wusbhc *wusbhc, u8 port_idx, u32 tkid,
509 const void *key, size_t key_size)
510{
511 int result = -ENOMEM;
512 struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
513 struct wahc *wa = &hwahc->wa;
514 u8 iface_no = wa->usb_iface->cur_altsetting->desc.bInterfaceNumber;
515 u8 encryption_value;
516
517 /* Tell the host which key to use to talk to the device */
518 if (key) {
519 u8 key_idx = wusb_key_index(0, WUSB_KEY_INDEX_TYPE_PTK,
520 WUSB_KEY_INDEX_ORIGINATOR_HOST);
521
522 result = __hwahc_dev_set_key(wusbhc, port_idx, tkid,
523 key, key_size, key_idx);
524 if (result < 0)
525 goto error_set_key;
526 encryption_value = wusbhc->ccm1_etd->bEncryptionValue;
527 } else {
528 /* FIXME: this should come from wusbhc->etd[UNSECURE].value */
529 encryption_value = 0;
530 }
531
532 /* Set the encryption type for commmunicating with the device */
533 result = usb_control_msg(wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
534 USB_REQ_SET_ENCRYPTION,
535 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
536 encryption_value, port_idx << 8 | iface_no,
537 NULL, 0, 1000 /* FIXME: arbitrary */);
538 if (result < 0)
539 dev_err(wusbhc->dev, "Can't set host's WUSB encryption for "
540 "port index %u to %s (value %d): %d\n", port_idx,
541 wusb_et_name(wusbhc->ccm1_etd->bEncryptionType),
542 wusbhc->ccm1_etd->bEncryptionValue, result);
543error_set_key:
544 return result;
545}
546
547/*
548 * Set host's GTK key
549 */
550static int __hwahc_op_set_gtk(struct wusbhc *wusbhc, u32 tkid,
551 const void *key, size_t key_size)
552{
553 u8 key_idx = wusb_key_index(0, WUSB_KEY_INDEX_TYPE_GTK,
554 WUSB_KEY_INDEX_ORIGINATOR_HOST);
555
556 return __hwahc_dev_set_key(wusbhc, 0, tkid, key, key_size, key_idx);
557}
558
559/*
560 * Get the Wire Adapter class-specific descriptor
561 *
562 * NOTE: this descriptor comes with the big bundled configuration
563 * descriptor that includes the interfaces' and endpoints', so
564 * we just look for it in the cached copy kept by the USB stack.
565 *
566 * NOTE2: We convert LE fields to CPU order.
567 */
568static int wa_fill_descr(struct wahc *wa)
569{
570 int result;
571 struct device *dev = &wa->usb_iface->dev;
572 char *itr;
573 struct usb_device *usb_dev = wa->usb_dev;
574 struct usb_descriptor_header *hdr;
575 struct usb_wa_descriptor *wa_descr;
576 size_t itr_size, actconfig_idx;
577
578 actconfig_idx = (usb_dev->actconfig - usb_dev->config) /
579 sizeof(usb_dev->config[0]);
580 itr = usb_dev->rawdescriptors[actconfig_idx];
581 itr_size = le16_to_cpu(usb_dev->actconfig->desc.wTotalLength);
582 while (itr_size >= sizeof(*hdr)) {
583 hdr = (struct usb_descriptor_header *) itr;
584 d_printf(3, dev, "Extra device descriptor: "
585 "type %02x/%u bytes @ %zu (%zu left)\n",
586 hdr->bDescriptorType, hdr->bLength,
587 (itr - usb_dev->rawdescriptors[actconfig_idx]),
588 itr_size);
589 if (hdr->bDescriptorType == USB_DT_WIRE_ADAPTER)
590 goto found;
591 itr += hdr->bLength;
592 itr_size -= hdr->bLength;
593 }
594 dev_err(dev, "cannot find Wire Adapter Class descriptor\n");
595 return -ENODEV;
596
597found:
598 result = -EINVAL;
599 if (hdr->bLength > itr_size) { /* is it available? */
600 dev_err(dev, "incomplete Wire Adapter Class descriptor "
601 "(%zu bytes left, %u needed)\n",
602 itr_size, hdr->bLength);
603 goto error;
604 }
605 if (hdr->bLength < sizeof(*wa->wa_descr)) {
606 dev_err(dev, "short Wire Adapter Class descriptor\n");
607 goto error;
608 }
609 wa->wa_descr = wa_descr = (struct usb_wa_descriptor *) hdr;
610 /* Make LE fields CPU order */
611 wa_descr->bcdWAVersion = le16_to_cpu(wa_descr->bcdWAVersion);
612 wa_descr->wNumRPipes = le16_to_cpu(wa_descr->wNumRPipes);
613 wa_descr->wRPipeMaxBlock = le16_to_cpu(wa_descr->wRPipeMaxBlock);
614 if (wa_descr->bcdWAVersion > 0x0100)
615 dev_warn(dev, "Wire Adapter v%d.%d newer than groked v1.0\n",
616 wa_descr->bcdWAVersion & 0xff00 >> 8,
617 wa_descr->bcdWAVersion & 0x00ff);
618 result = 0;
619error:
620 return result;
621}
622
623static struct hc_driver hwahc_hc_driver = {
624 .description = "hwa-hcd",
625 .product_desc = "Wireless USB HWA host controller",
626 .hcd_priv_size = sizeof(struct hwahc) - sizeof(struct usb_hcd),
627 .irq = NULL, /* FIXME */
628 .flags = HCD_USB2, /* FIXME */
629 .reset = hwahc_op_reset,
630 .start = hwahc_op_start,
631 .pci_suspend = hwahc_op_suspend,
632 .pci_resume = hwahc_op_resume,
633 .stop = hwahc_op_stop,
634 .get_frame_number = hwahc_op_get_frame_number,
635 .urb_enqueue = hwahc_op_urb_enqueue,
636 .urb_dequeue = hwahc_op_urb_dequeue,
637 .endpoint_disable = hwahc_op_endpoint_disable,
638
639 .hub_status_data = wusbhc_rh_status_data,
640 .hub_control = wusbhc_rh_control,
641 .bus_suspend = wusbhc_rh_suspend,
642 .bus_resume = wusbhc_rh_resume,
643 .start_port_reset = wusbhc_rh_start_port_reset,
644};
645
646static int hwahc_security_create(struct hwahc *hwahc)
647{
648 int result;
649 struct wusbhc *wusbhc = &hwahc->wusbhc;
650 struct usb_device *usb_dev = hwahc->wa.usb_dev;
651 struct device *dev = &usb_dev->dev;
652 struct usb_security_descriptor *secd;
653 struct usb_encryption_descriptor *etd;
654 void *itr, *top;
655 size_t itr_size, needed, bytes;
656 u8 index;
657 char buf[64];
658
659 /* Find the host's security descriptors in the config descr bundle */
660 index = (usb_dev->actconfig - usb_dev->config) /
661 sizeof(usb_dev->config[0]);
662 itr = usb_dev->rawdescriptors[index];
663 itr_size = le16_to_cpu(usb_dev->actconfig->desc.wTotalLength);
664 top = itr + itr_size;
665 result = __usb_get_extra_descriptor(usb_dev->rawdescriptors[index],
666 le16_to_cpu(usb_dev->actconfig->desc.wTotalLength),
667 USB_DT_SECURITY, (void **) &secd);
668 if (result == -1) {
669 dev_warn(dev, "BUG? WUSB host has no security descriptors\n");
670 return 0;
671 }
672 needed = sizeof(*secd);
673 if (top - (void *)secd < needed) {
674 dev_err(dev, "BUG? Not enough data to process security "
675 "descriptor header (%zu bytes left vs %zu needed)\n",
676 top - (void *) secd, needed);
677 return 0;
678 }
679 needed = le16_to_cpu(secd->wTotalLength);
680 if (top - (void *)secd < needed) {
681 dev_err(dev, "BUG? Not enough data to process security "
682 "descriptors (%zu bytes left vs %zu needed)\n",
683 top - (void *) secd, needed);
684 return 0;
685 }
686 /* Walk over the sec descriptors and store CCM1's on wusbhc */
687 itr = (void *) secd + sizeof(*secd);
688 top = (void *) secd + le16_to_cpu(secd->wTotalLength);
689 index = 0;
690 bytes = 0;
691 while (itr < top) {
692 etd = itr;
693 if (top - itr < sizeof(*etd)) {
694 dev_err(dev, "BUG: bad host security descriptor; "
695 "not enough data (%zu vs %zu left)\n",
696 top - itr, sizeof(*etd));
697 break;
698 }
699 if (etd->bLength < sizeof(*etd)) {
700 dev_err(dev, "BUG: bad host encryption descriptor; "
701 "descriptor is too short "
702 "(%zu vs %zu needed)\n",
703 (size_t)etd->bLength, sizeof(*etd));
704 break;
705 }
706 itr += etd->bLength;
707 bytes += snprintf(buf + bytes, sizeof(buf) - bytes,
708 "%s (0x%02x) ",
709 wusb_et_name(etd->bEncryptionType),
710 etd->bEncryptionValue);
711 wusbhc->ccm1_etd = etd;
712 }
713 dev_info(dev, "supported encryption types: %s\n", buf);
714 if (wusbhc->ccm1_etd == NULL) {
715 dev_err(dev, "E: host doesn't support CCM-1 crypto\n");
716 return 0;
717 }
718 /* Pretty print what we support */
719 return 0;
720}
721
722static void hwahc_security_release(struct hwahc *hwahc)
723{
724 /* nothing to do here so far... */
725}
726
727static int hwahc_create(struct hwahc *hwahc, struct usb_interface *iface)
728{
729 int result;
730 struct device *dev = &iface->dev;
731 struct wusbhc *wusbhc = &hwahc->wusbhc;
732 struct wahc *wa = &hwahc->wa;
733 struct usb_device *usb_dev = interface_to_usbdev(iface);
734
735 wa->usb_dev = usb_get_dev(usb_dev); /* bind the USB device */
736 wa->usb_iface = usb_get_intf(iface);
737 wusbhc->dev = dev;
738 wusbhc->uwb_rc = uwb_rc_get_by_grandpa(iface->dev.parent);
739 if (wusbhc->uwb_rc == NULL) {
740 result = -ENODEV;
741 dev_err(dev, "Cannot get associated UWB Host Controller\n");
742 goto error_rc_get;
743 }
744 result = wa_fill_descr(wa); /* Get the device descriptor */
745 if (result < 0)
746 goto error_fill_descriptor;
747 if (wa->wa_descr->bNumPorts > USB_MAXCHILDREN) {
748 dev_err(dev, "FIXME: USB_MAXCHILDREN too low for WUSB "
749 "adapter (%u ports)\n", wa->wa_descr->bNumPorts);
750 wusbhc->ports_max = USB_MAXCHILDREN;
751 } else {
752 wusbhc->ports_max = wa->wa_descr->bNumPorts;
753 }
754 wusbhc->mmcies_max = wa->wa_descr->bNumMMCIEs;
755 wusbhc->start = __hwahc_op_wusbhc_start;
756 wusbhc->stop = __hwahc_op_wusbhc_stop;
757 wusbhc->mmcie_add = __hwahc_op_mmcie_add;
758 wusbhc->mmcie_rm = __hwahc_op_mmcie_rm;
759 wusbhc->dev_info_set = __hwahc_op_dev_info_set;
760 wusbhc->bwa_set = __hwahc_op_bwa_set;
761 wusbhc->set_num_dnts = __hwahc_op_set_num_dnts;
762 wusbhc->set_ptk = __hwahc_op_set_ptk;
763 wusbhc->set_gtk = __hwahc_op_set_gtk;
764 result = hwahc_security_create(hwahc);
765 if (result < 0) {
766 dev_err(dev, "Can't initialize security: %d\n", result);
767 goto error_security_create;
768 }
769 wa->wusb = wusbhc; /* FIXME: ugly, need to fix */
770 result = wusbhc_create(&hwahc->wusbhc);
771 if (result < 0) {
772 dev_err(dev, "Can't create WUSB HC structures: %d\n", result);
773 goto error_wusbhc_create;
774 }
775 result = wa_create(&hwahc->wa, iface);
776 if (result < 0)
777 goto error_wa_create;
778 return 0;
779
780error_wa_create:
781 wusbhc_destroy(&hwahc->wusbhc);
782error_wusbhc_create:
783 /* WA Descr fill allocs no resources */
784error_security_create:
785error_fill_descriptor:
786 uwb_rc_put(wusbhc->uwb_rc);
787error_rc_get:
788 usb_put_intf(iface);
789 usb_put_dev(usb_dev);
790 return result;
791}
792
793static void hwahc_destroy(struct hwahc *hwahc)
794{
795 struct wusbhc *wusbhc = &hwahc->wusbhc;
796
797 d_fnstart(1, NULL, "(hwahc %p)\n", hwahc);
798 mutex_lock(&wusbhc->mutex);
799 __wa_destroy(&hwahc->wa);
800 wusbhc_destroy(&hwahc->wusbhc);
801 hwahc_security_release(hwahc);
802 hwahc->wusbhc.dev = NULL;
803 uwb_rc_put(wusbhc->uwb_rc);
804 usb_put_intf(hwahc->wa.usb_iface);
805 usb_put_dev(hwahc->wa.usb_dev);
806 mutex_unlock(&wusbhc->mutex);
807 d_fnend(1, NULL, "(hwahc %p) = void\n", hwahc);
808}
809
810static void hwahc_init(struct hwahc *hwahc)
811{
812 wa_init(&hwahc->wa);
813}
814
815static int hwahc_probe(struct usb_interface *usb_iface,
816 const struct usb_device_id *id)
817{
818 int result;
819 struct usb_hcd *usb_hcd;
820 struct wusbhc *wusbhc;
821 struct hwahc *hwahc;
822 struct device *dev = &usb_iface->dev;
823
824 d_fnstart(4, dev, "(%p, %p)\n", usb_iface, id);
825 result = -ENOMEM;
826 usb_hcd = usb_create_hcd(&hwahc_hc_driver, &usb_iface->dev, "wusb-hwa");
827 if (usb_hcd == NULL) {
828 dev_err(dev, "unable to allocate instance\n");
829 goto error_alloc;
830 }
831 usb_hcd->wireless = 1;
832 usb_hcd->flags |= HCD_FLAG_SAW_IRQ;
833 wusbhc = usb_hcd_to_wusbhc(usb_hcd);
834 hwahc = container_of(wusbhc, struct hwahc, wusbhc);
835 hwahc_init(hwahc);
836 result = hwahc_create(hwahc, usb_iface);
837 if (result < 0) {
838 dev_err(dev, "Cannot initialize internals: %d\n", result);
839 goto error_hwahc_create;
840 }
841 result = usb_add_hcd(usb_hcd, 0, 0);
842 if (result < 0) {
843 dev_err(dev, "Cannot add HCD: %d\n", result);
844 goto error_add_hcd;
845 }
846 result = wusbhc_b_create(&hwahc->wusbhc);
847 if (result < 0) {
848 dev_err(dev, "Cannot setup phase B of WUSBHC: %d\n", result);
849 goto error_wusbhc_b_create;
850 }
851 d_fnend(4, dev, "(%p, %p) = 0\n", usb_iface, id);
852 return 0;
853
854error_wusbhc_b_create:
855 usb_remove_hcd(usb_hcd);
856error_add_hcd:
857 hwahc_destroy(hwahc);
858error_hwahc_create:
859 usb_put_hcd(usb_hcd);
860error_alloc:
861 d_fnend(4, dev, "(%p, %p) = %d\n", usb_iface, id, result);
862 return result;
863}
864
865static void hwahc_disconnect(struct usb_interface *usb_iface)
866{
867 struct usb_hcd *usb_hcd;
868 struct wusbhc *wusbhc;
869 struct hwahc *hwahc;
870
871 usb_hcd = usb_get_intfdata(usb_iface);
872 wusbhc = usb_hcd_to_wusbhc(usb_hcd);
873 hwahc = container_of(wusbhc, struct hwahc, wusbhc);
874
875 d_fnstart(1, NULL, "(hwahc %p [usb_iface %p])\n", hwahc, usb_iface);
876 wusbhc_b_destroy(&hwahc->wusbhc);
877 usb_remove_hcd(usb_hcd);
878 hwahc_destroy(hwahc);
879 usb_put_hcd(usb_hcd);
880 d_fnend(1, NULL, "(hwahc %p [usb_iface %p]) = void\n", hwahc,
881 usb_iface);
882}
883
884/** USB device ID's that we handle */
885static struct usb_device_id hwahc_id_table[] = {
886 /* FIXME: use class labels for this */
887 { USB_INTERFACE_INFO(0xe0, 0x02, 0x01), },
888 {},
889};
890MODULE_DEVICE_TABLE(usb, hwahc_id_table);
891
892static struct usb_driver hwahc_driver = {
893 .name = "hwa-hc",
894 .probe = hwahc_probe,
895 .disconnect = hwahc_disconnect,
896 .id_table = hwahc_id_table,
897};
898
899static int __init hwahc_driver_init(void)
900{
901 int result;
902 result = usb_register(&hwahc_driver);
903 if (result < 0) {
904 printk(KERN_ERR "WA-CDS: Cannot register USB driver: %d\n",
905 result);
906 goto error_usb_register;
907 }
908 return 0;
909
910error_usb_register:
911 return result;
912
913}
914module_init(hwahc_driver_init);
915
916static void __exit hwahc_driver_exit(void)
917{
918 usb_deregister(&hwahc_driver);
919}
920module_exit(hwahc_driver_exit);
921
922
923MODULE_AUTHOR("Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>");
924MODULE_DESCRIPTION("Host Wired Adapter USB Host Control Driver");
925MODULE_LICENSE("GPL");
diff --git a/drivers/usb/host/whci/Kbuild b/drivers/usb/host/whci/Kbuild
new file mode 100644
index 000000000000..26a3871ea0f9
--- /dev/null
+++ b/drivers/usb/host/whci/Kbuild
@@ -0,0 +1,11 @@
1obj-$(CONFIG_USB_WHCI_HCD) += whci-hcd.o
2
3whci-hcd-y := \
4 asl.o \
5 hcd.o \
6 hw.o \
7 init.o \
8 int.o \
9 pzl.o \
10 qset.o \
11 wusb.o
diff --git a/drivers/usb/host/whci/asl.c b/drivers/usb/host/whci/asl.c
new file mode 100644
index 000000000000..4d7078e50572
--- /dev/null
+++ b/drivers/usb/host/whci/asl.c
@@ -0,0 +1,367 @@
1/*
2 * Wireless Host Controller (WHC) asynchronous schedule management.
3 *
4 * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18#include <linux/kernel.h>
19#include <linux/dma-mapping.h>
20#include <linux/uwb/umc.h>
21#include <linux/usb.h>
22#define D_LOCAL 0
23#include <linux/uwb/debug.h>
24
25#include "../../wusbcore/wusbhc.h"
26
27#include "whcd.h"
28
29#if D_LOCAL >= 4
30static void dump_asl(struct whc *whc, const char *tag)
31{
32 struct device *dev = &whc->umc->dev;
33 struct whc_qset *qset;
34
35 d_printf(4, dev, "ASL %s\n", tag);
36
37 list_for_each_entry(qset, &whc->async_list, list_node) {
38 dump_qset(qset, dev);
39 }
40}
41#else
42static inline void dump_asl(struct whc *whc, const char *tag)
43{
44}
45#endif
46
47
48static void qset_get_next_prev(struct whc *whc, struct whc_qset *qset,
49 struct whc_qset **next, struct whc_qset **prev)
50{
51 struct list_head *n, *p;
52
53 BUG_ON(list_empty(&whc->async_list));
54
55 n = qset->list_node.next;
56 if (n == &whc->async_list)
57 n = n->next;
58 p = qset->list_node.prev;
59 if (p == &whc->async_list)
60 p = p->prev;
61
62 *next = container_of(n, struct whc_qset, list_node);
63 *prev = container_of(p, struct whc_qset, list_node);
64
65}
66
67static void asl_qset_insert_begin(struct whc *whc, struct whc_qset *qset)
68{
69 list_move(&qset->list_node, &whc->async_list);
70 qset->in_sw_list = true;
71}
72
73static void asl_qset_insert(struct whc *whc, struct whc_qset *qset)
74{
75 struct whc_qset *next, *prev;
76
77 qset_clear(whc, qset);
78
79 /* Link into ASL. */
80 qset_get_next_prev(whc, qset, &next, &prev);
81 whc_qset_set_link_ptr(&qset->qh.link, next->qset_dma);
82 whc_qset_set_link_ptr(&prev->qh.link, qset->qset_dma);
83 qset->in_hw_list = true;
84}
85
86static void asl_qset_remove(struct whc *whc, struct whc_qset *qset)
87{
88 struct whc_qset *prev, *next;
89
90 qset_get_next_prev(whc, qset, &next, &prev);
91
92 list_move(&qset->list_node, &whc->async_removed_list);
93 qset->in_sw_list = false;
94
95 /*
96 * No more qsets in the ASL? The caller must stop the ASL as
97 * it's no longer valid.
98 */
99 if (list_empty(&whc->async_list))
100 return;
101
102 /* Remove from ASL. */
103 whc_qset_set_link_ptr(&prev->qh.link, next->qset_dma);
104 qset->in_hw_list = false;
105}
106
107/**
108 * process_qset - process any recently inactivated or halted qTDs in a
109 * qset.
110 *
111 * After inactive qTDs are removed, new qTDs can be added if the
112 * urb queue still contains URBs.
113 *
114 * Returns any additional WUSBCMD bits for the ASL sync command (i.e.,
115 * WUSBCMD_ASYNC_QSET_RM if a halted qset was removed).
116 */
117static uint32_t process_qset(struct whc *whc, struct whc_qset *qset)
118{
119 enum whc_update update = 0;
120 uint32_t status = 0;
121
122 while (qset->ntds) {
123 struct whc_qtd *td;
124 int t;
125
126 t = qset->td_start;
127 td = &qset->qtd[qset->td_start];
128 status = le32_to_cpu(td->status);
129
130 /*
131 * Nothing to do with a still active qTD.
132 */
133 if (status & QTD_STS_ACTIVE)
134 break;
135
136 if (status & QTD_STS_HALTED) {
137 /* Ug, an error. */
138 process_halted_qtd(whc, qset, td);
139 goto done;
140 }
141
142 /* Mmm, a completed qTD. */
143 process_inactive_qtd(whc, qset, td);
144 }
145
146 update |= qset_add_qtds(whc, qset);
147
148done:
149 /*
150 * Remove this qset from the ASL if requested, but only if has
151 * no qTDs.
152 */
153 if (qset->remove && qset->ntds == 0) {
154 asl_qset_remove(whc, qset);
155 update |= WHC_UPDATE_REMOVED;
156 }
157 return update;
158}
159
160void asl_start(struct whc *whc)
161{
162 struct whc_qset *qset;
163
164 qset = list_first_entry(&whc->async_list, struct whc_qset, list_node);
165
166 le_writeq(qset->qset_dma | QH_LINK_NTDS(8), whc->base + WUSBASYNCLISTADDR);
167
168 whc_write_wusbcmd(whc, WUSBCMD_ASYNC_EN, WUSBCMD_ASYNC_EN);
169 whci_wait_for(&whc->umc->dev, whc->base + WUSBSTS,
170 WUSBSTS_ASYNC_SCHED, WUSBSTS_ASYNC_SCHED,
171 1000, "start ASL");
172}
173
174void asl_stop(struct whc *whc)
175{
176 whc_write_wusbcmd(whc, WUSBCMD_ASYNC_EN, 0);
177 whci_wait_for(&whc->umc->dev, whc->base + WUSBSTS,
178 WUSBSTS_ASYNC_SCHED, 0,
179 1000, "stop ASL");
180}
181
182void asl_update(struct whc *whc, uint32_t wusbcmd)
183{
184 whc_write_wusbcmd(whc, wusbcmd, wusbcmd);
185 wait_event(whc->async_list_wq,
186 (le_readl(whc->base + WUSBCMD) & WUSBCMD_ASYNC_UPDATED) == 0);
187}
188
189/**
190 * scan_async_work - scan the ASL for qsets to process.
191 *
192 * Process each qset in the ASL in turn and then signal the WHC that
193 * the ASL has been updated.
194 *
195 * Then start, stop or update the asynchronous schedule as required.
196 */
197void scan_async_work(struct work_struct *work)
198{
199 struct whc *whc = container_of(work, struct whc, async_work);
200 struct whc_qset *qset, *t;
201 enum whc_update update = 0;
202
203 spin_lock_irq(&whc->lock);
204
205 dump_asl(whc, "before processing");
206
207 /*
208 * Transerve the software list backwards so new qsets can be
209 * safely inserted into the ASL without making it non-circular.
210 */
211 list_for_each_entry_safe_reverse(qset, t, &whc->async_list, list_node) {
212 if (!qset->in_hw_list) {
213 asl_qset_insert(whc, qset);
214 update |= WHC_UPDATE_ADDED;
215 }
216
217 update |= process_qset(whc, qset);
218 }
219
220 dump_asl(whc, "after processing");
221
222 spin_unlock_irq(&whc->lock);
223
224 if (update) {
225 uint32_t wusbcmd = WUSBCMD_ASYNC_UPDATED | WUSBCMD_ASYNC_SYNCED_DB;
226 if (update & WHC_UPDATE_REMOVED)
227 wusbcmd |= WUSBCMD_ASYNC_QSET_RM;
228 asl_update(whc, wusbcmd);
229 }
230
231 /*
232 * Now that the ASL is updated, complete the removal of any
233 * removed qsets.
234 */
235 spin_lock(&whc->lock);
236
237 list_for_each_entry_safe(qset, t, &whc->async_removed_list, list_node) {
238 qset_remove_complete(whc, qset);
239 }
240
241 spin_unlock(&whc->lock);
242}
243
244/**
245 * asl_urb_enqueue - queue an URB onto the asynchronous list (ASL).
246 * @whc: the WHCI host controller
247 * @urb: the URB to enqueue
248 * @mem_flags: flags for any memory allocations
249 *
250 * The qset for the endpoint is obtained and the urb queued on to it.
251 *
252 * Work is scheduled to update the hardware's view of the ASL.
253 */
254int asl_urb_enqueue(struct whc *whc, struct urb *urb, gfp_t mem_flags)
255{
256 struct whc_qset *qset;
257 int err;
258 unsigned long flags;
259
260 spin_lock_irqsave(&whc->lock, flags);
261
262 qset = get_qset(whc, urb, GFP_ATOMIC);
263 if (qset == NULL)
264 err = -ENOMEM;
265 else
266 err = qset_add_urb(whc, qset, urb, GFP_ATOMIC);
267 if (!err) {
268 usb_hcd_link_urb_to_ep(&whc->wusbhc.usb_hcd, urb);
269 if (!qset->in_sw_list)
270 asl_qset_insert_begin(whc, qset);
271 }
272
273 spin_unlock_irqrestore(&whc->lock, flags);
274
275 if (!err)
276 queue_work(whc->workqueue, &whc->async_work);
277
278 return 0;
279}
280
281/**
282 * asl_urb_dequeue - remove an URB (qset) from the async list.
283 * @whc: the WHCI host controller
284 * @urb: the URB to dequeue
285 * @status: the current status of the URB
286 *
287 * URBs that do yet have qTDs can simply be removed from the software
288 * queue, otherwise the qset must be removed from the ASL so the qTDs
289 * can be removed.
290 */
291int asl_urb_dequeue(struct whc *whc, struct urb *urb, int status)
292{
293 struct whc_urb *wurb = urb->hcpriv;
294 struct whc_qset *qset = wurb->qset;
295 struct whc_std *std, *t;
296 int ret;
297 unsigned long flags;
298
299 spin_lock_irqsave(&whc->lock, flags);
300
301 ret = usb_hcd_check_unlink_urb(&whc->wusbhc.usb_hcd, urb, status);
302 if (ret < 0)
303 goto out;
304
305 list_for_each_entry_safe(std, t, &qset->stds, list_node) {
306 if (std->urb == urb)
307 qset_free_std(whc, std);
308 else
309 std->qtd = NULL; /* so this std is re-added when the qset is */
310 }
311
312 asl_qset_remove(whc, qset);
313 wurb->status = status;
314 wurb->is_async = true;
315 queue_work(whc->workqueue, &wurb->dequeue_work);
316
317out:
318 spin_unlock_irqrestore(&whc->lock, flags);
319
320 return ret;
321}
322
323/**
324 * asl_qset_delete - delete a qset from the ASL
325 */
326void asl_qset_delete(struct whc *whc, struct whc_qset *qset)
327{
328 qset->remove = 1;
329 queue_work(whc->workqueue, &whc->async_work);
330 qset_delete(whc, qset);
331}
332
333/**
334 * asl_init - initialize the asynchronous schedule list
335 *
336 * A dummy qset with no qTDs is added to the ASL to simplify removing
337 * qsets (no need to stop the ASL when the last qset is removed).
338 */
339int asl_init(struct whc *whc)
340{
341 struct whc_qset *qset;
342
343 qset = qset_alloc(whc, GFP_KERNEL);
344 if (qset == NULL)
345 return -ENOMEM;
346
347 asl_qset_insert_begin(whc, qset);
348 asl_qset_insert(whc, qset);
349
350 return 0;
351}
352
353/**
354 * asl_clean_up - free ASL resources
355 *
356 * The ASL is stopped and empty except for the dummy qset.
357 */
358void asl_clean_up(struct whc *whc)
359{
360 struct whc_qset *qset;
361
362 if (!list_empty(&whc->async_list)) {
363 qset = list_first_entry(&whc->async_list, struct whc_qset, list_node);
364 list_del(&qset->list_node);
365 qset_free(whc, qset);
366 }
367}
diff --git a/drivers/usb/host/whci/hcd.c b/drivers/usb/host/whci/hcd.c
new file mode 100644
index 000000000000..ef3ad4dca945
--- /dev/null
+++ b/drivers/usb/host/whci/hcd.c
@@ -0,0 +1,339 @@
1/*
2 * Wireless Host Controller (WHC) driver.
3 *
4 * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18#include <linux/version.h>
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/uwb/umc.h>
22
23#include "../../wusbcore/wusbhc.h"
24
25#include "whcd.h"
26
27/*
28 * One time initialization.
29 *
30 * Nothing to do here.
31 */
32static int whc_reset(struct usb_hcd *usb_hcd)
33{
34 return 0;
35}
36
37/*
38 * Start the wireless host controller.
39 *
40 * Start device notification.
41 *
42 * Put hc into run state, set DNTS parameters.
43 */
44static int whc_start(struct usb_hcd *usb_hcd)
45{
46 struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
47 struct whc *whc = wusbhc_to_whc(wusbhc);
48 u8 bcid;
49 int ret;
50
51 mutex_lock(&wusbhc->mutex);
52
53 le_writel(WUSBINTR_GEN_CMD_DONE
54 | WUSBINTR_HOST_ERR
55 | WUSBINTR_ASYNC_SCHED_SYNCED
56 | WUSBINTR_DNTS_INT
57 | WUSBINTR_ERR_INT
58 | WUSBINTR_INT,
59 whc->base + WUSBINTR);
60
61 /* set cluster ID */
62 bcid = wusb_cluster_id_get();
63 ret = whc_set_cluster_id(whc, bcid);
64 if (ret < 0)
65 goto out;
66 wusbhc->cluster_id = bcid;
67
68 /* start HC */
69 whc_write_wusbcmd(whc, WUSBCMD_RUN, WUSBCMD_RUN);
70
71 usb_hcd->uses_new_polling = 1;
72 usb_hcd->poll_rh = 1;
73 usb_hcd->state = HC_STATE_RUNNING;
74
75out:
76 mutex_unlock(&wusbhc->mutex);
77 return ret;
78}
79
80
81/*
82 * Stop the wireless host controller.
83 *
84 * Stop device notification.
85 *
86 * Wait for pending transfer to stop? Put hc into stop state?
87 */
88static void whc_stop(struct usb_hcd *usb_hcd)
89{
90 struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
91 struct whc *whc = wusbhc_to_whc(wusbhc);
92
93 mutex_lock(&wusbhc->mutex);
94
95 wusbhc_stop(wusbhc);
96
97 /* stop HC */
98 le_writel(0, whc->base + WUSBINTR);
99 whc_write_wusbcmd(whc, WUSBCMD_RUN, 0);
100 whci_wait_for(&whc->umc->dev, whc->base + WUSBSTS,
101 WUSBSTS_HCHALTED, WUSBSTS_HCHALTED,
102 100, "HC to halt");
103
104 wusb_cluster_id_put(wusbhc->cluster_id);
105
106 mutex_unlock(&wusbhc->mutex);
107}
108
109static int whc_get_frame_number(struct usb_hcd *usb_hcd)
110{
111 /* Frame numbers are not applicable to WUSB. */
112 return -ENOSYS;
113}
114
115
116/*
117 * Queue an URB to the ASL or PZL
118 */
119static int whc_urb_enqueue(struct usb_hcd *usb_hcd, struct urb *urb,
120 gfp_t mem_flags)
121{
122 struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
123 struct whc *whc = wusbhc_to_whc(wusbhc);
124 int ret;
125
126 switch (usb_pipetype(urb->pipe)) {
127 case PIPE_INTERRUPT:
128 ret = pzl_urb_enqueue(whc, urb, mem_flags);
129 break;
130 case PIPE_ISOCHRONOUS:
131 dev_err(&whc->umc->dev, "isochronous transfers unsupported\n");
132 ret = -ENOTSUPP;
133 break;
134 case PIPE_CONTROL:
135 case PIPE_BULK:
136 default:
137 ret = asl_urb_enqueue(whc, urb, mem_flags);
138 break;
139 };
140
141 return ret;
142}
143
144/*
145 * Remove a queued URB from the ASL or PZL.
146 */
147static int whc_urb_dequeue(struct usb_hcd *usb_hcd, struct urb *urb, int status)
148{
149 struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
150 struct whc *whc = wusbhc_to_whc(wusbhc);
151 int ret;
152
153 switch (usb_pipetype(urb->pipe)) {
154 case PIPE_INTERRUPT:
155 ret = pzl_urb_dequeue(whc, urb, status);
156 break;
157 case PIPE_ISOCHRONOUS:
158 ret = -ENOTSUPP;
159 break;
160 case PIPE_CONTROL:
161 case PIPE_BULK:
162 default:
163 ret = asl_urb_dequeue(whc, urb, status);
164 break;
165 };
166
167 return ret;
168}
169
170/*
171 * Wait for all URBs to the endpoint to be completed, then delete the
172 * qset.
173 */
174static void whc_endpoint_disable(struct usb_hcd *usb_hcd,
175 struct usb_host_endpoint *ep)
176{
177 struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
178 struct whc *whc = wusbhc_to_whc(wusbhc);
179 struct whc_qset *qset;
180
181 qset = ep->hcpriv;
182 if (qset) {
183 ep->hcpriv = NULL;
184 if (usb_endpoint_xfer_bulk(&ep->desc)
185 || usb_endpoint_xfer_control(&ep->desc))
186 asl_qset_delete(whc, qset);
187 else
188 pzl_qset_delete(whc, qset);
189 }
190}
191
192static struct hc_driver whc_hc_driver = {
193 .description = "whci-hcd",
194 .product_desc = "Wireless host controller",
195 .hcd_priv_size = sizeof(struct whc) - sizeof(struct usb_hcd),
196 .irq = whc_int_handler,
197 .flags = HCD_USB2,
198
199 .reset = whc_reset,
200 .start = whc_start,
201 .stop = whc_stop,
202 .get_frame_number = whc_get_frame_number,
203 .urb_enqueue = whc_urb_enqueue,
204 .urb_dequeue = whc_urb_dequeue,
205 .endpoint_disable = whc_endpoint_disable,
206
207 .hub_status_data = wusbhc_rh_status_data,
208 .hub_control = wusbhc_rh_control,
209 .bus_suspend = wusbhc_rh_suspend,
210 .bus_resume = wusbhc_rh_resume,
211 .start_port_reset = wusbhc_rh_start_port_reset,
212};
213
214static int whc_probe(struct umc_dev *umc)
215{
216 int ret = -ENOMEM;
217 struct usb_hcd *usb_hcd;
218 struct wusbhc *wusbhc = NULL;
219 struct whc *whc = NULL;
220 struct device *dev = &umc->dev;
221
222 usb_hcd = usb_create_hcd(&whc_hc_driver, dev, "whci");
223 if (usb_hcd == NULL) {
224 dev_err(dev, "unable to create hcd\n");
225 goto error;
226 }
227
228 usb_hcd->wireless = 1;
229
230 wusbhc = usb_hcd_to_wusbhc(usb_hcd);
231 whc = wusbhc_to_whc(wusbhc);
232 whc->umc = umc;
233
234 ret = whc_init(whc);
235 if (ret)
236 goto error;
237
238 wusbhc->dev = dev;
239 wusbhc->uwb_rc = uwb_rc_get_by_grandpa(umc->dev.parent);
240 if (!wusbhc->uwb_rc) {
241 ret = -ENODEV;
242 dev_err(dev, "cannot get radio controller\n");
243 goto error;
244 }
245
246 if (whc->n_devices > USB_MAXCHILDREN) {
247 dev_warn(dev, "USB_MAXCHILDREN too low for WUSB adapter (%u ports)\n",
248 whc->n_devices);
249 wusbhc->ports_max = USB_MAXCHILDREN;
250 } else
251 wusbhc->ports_max = whc->n_devices;
252 wusbhc->mmcies_max = whc->n_mmc_ies;
253 wusbhc->start = whc_wusbhc_start;
254 wusbhc->stop = whc_wusbhc_stop;
255 wusbhc->mmcie_add = whc_mmcie_add;
256 wusbhc->mmcie_rm = whc_mmcie_rm;
257 wusbhc->dev_info_set = whc_dev_info_set;
258 wusbhc->bwa_set = whc_bwa_set;
259 wusbhc->set_num_dnts = whc_set_num_dnts;
260 wusbhc->set_ptk = whc_set_ptk;
261 wusbhc->set_gtk = whc_set_gtk;
262
263 ret = wusbhc_create(wusbhc);
264 if (ret)
265 goto error_wusbhc_create;
266
267 ret = usb_add_hcd(usb_hcd, whc->umc->irq, IRQF_SHARED);
268 if (ret) {
269 dev_err(dev, "cannot add HCD: %d\n", ret);
270 goto error_usb_add_hcd;
271 }
272
273 ret = wusbhc_b_create(wusbhc);
274 if (ret) {
275 dev_err(dev, "WUSBHC phase B setup failed: %d\n", ret);
276 goto error_wusbhc_b_create;
277 }
278
279 return 0;
280
281error_wusbhc_b_create:
282 usb_remove_hcd(usb_hcd);
283error_usb_add_hcd:
284 wusbhc_destroy(wusbhc);
285error_wusbhc_create:
286 uwb_rc_put(wusbhc->uwb_rc);
287error:
288 whc_clean_up(whc);
289 if (usb_hcd)
290 usb_put_hcd(usb_hcd);
291 return ret;
292}
293
294
295static void whc_remove(struct umc_dev *umc)
296{
297 struct usb_hcd *usb_hcd = dev_get_drvdata(&umc->dev);
298 struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
299 struct whc *whc = wusbhc_to_whc(wusbhc);
300
301 if (usb_hcd) {
302 wusbhc_b_destroy(wusbhc);
303 usb_remove_hcd(usb_hcd);
304 wusbhc_destroy(wusbhc);
305 uwb_rc_put(wusbhc->uwb_rc);
306 whc_clean_up(whc);
307 usb_put_hcd(usb_hcd);
308 }
309}
310
311static struct umc_driver whci_hc_driver = {
312 .name = "whci-hcd",
313 .cap_id = UMC_CAP_ID_WHCI_WUSB_HC,
314 .probe = whc_probe,
315 .remove = whc_remove,
316};
317
318static int __init whci_hc_driver_init(void)
319{
320 return umc_driver_register(&whci_hc_driver);
321}
322module_init(whci_hc_driver_init);
323
324static void __exit whci_hc_driver_exit(void)
325{
326 umc_driver_unregister(&whci_hc_driver);
327}
328module_exit(whci_hc_driver_exit);
329
330/* PCI device ID's that we handle (so it gets loaded) */
331static struct pci_device_id whci_hcd_id_table[] = {
332 { PCI_DEVICE_CLASS(PCI_CLASS_WIRELESS_WHCI, ~0) },
333 { /* empty last entry */ }
334};
335MODULE_DEVICE_TABLE(pci, whci_hcd_id_table);
336
337MODULE_DESCRIPTION("WHCI Wireless USB host controller driver");
338MODULE_AUTHOR("Cambridge Silicon Radio Ltd.");
339MODULE_LICENSE("GPL");
diff --git a/drivers/usb/host/whci/hw.c b/drivers/usb/host/whci/hw.c
new file mode 100644
index 000000000000..ac86e59c1225
--- /dev/null
+++ b/drivers/usb/host/whci/hw.c
@@ -0,0 +1,87 @@
1/*
2 * Wireless Host Controller (WHC) hardware access helpers.
3 *
4 * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18#include <linux/kernel.h>
19#include <linux/dma-mapping.h>
20#include <linux/uwb/umc.h>
21
22#include "../../wusbcore/wusbhc.h"
23
24#include "whcd.h"
25
26void whc_write_wusbcmd(struct whc *whc, u32 mask, u32 val)
27{
28 unsigned long flags;
29 u32 cmd;
30
31 spin_lock_irqsave(&whc->lock, flags);
32
33 cmd = le_readl(whc->base + WUSBCMD);
34 cmd = (cmd & ~mask) | val;
35 le_writel(cmd, whc->base + WUSBCMD);
36
37 spin_unlock_irqrestore(&whc->lock, flags);
38}
39
40/**
41 * whc_do_gencmd - start a generic command via the WUSBGENCMDSTS register
42 * @whc: the WHCI HC
43 * @cmd: command to start.
44 * @params: parameters for the command (the WUSBGENCMDPARAMS register value).
45 * @addr: pointer to any data for the command (may be NULL).
46 * @len: length of the data (if any).
47 */
48int whc_do_gencmd(struct whc *whc, u32 cmd, u32 params, void *addr, size_t len)
49{
50 unsigned long flags;
51 dma_addr_t dma_addr;
52 int t;
53
54 mutex_lock(&whc->mutex);
55
56 /* Wait for previous command to complete. */
57 t = wait_event_timeout(whc->cmd_wq,
58 (le_readl(whc->base + WUSBGENCMDSTS) & WUSBGENCMDSTS_ACTIVE) == 0,
59 WHC_GENCMD_TIMEOUT_MS);
60 if (t == 0) {
61 dev_err(&whc->umc->dev, "generic command timeout (%04x/%04x)\n",
62 le_readl(whc->base + WUSBGENCMDSTS),
63 le_readl(whc->base + WUSBGENCMDPARAMS));
64 return -ETIMEDOUT;
65 }
66
67 if (addr) {
68 memcpy(whc->gen_cmd_buf, addr, len);
69 dma_addr = whc->gen_cmd_buf_dma;
70 } else
71 dma_addr = 0;
72
73 /* Poke registers to start cmd. */
74 spin_lock_irqsave(&whc->lock, flags);
75
76 le_writel(params, whc->base + WUSBGENCMDPARAMS);
77 le_writeq(dma_addr, whc->base + WUSBGENADDR);
78
79 le_writel(WUSBGENCMDSTS_ACTIVE | WUSBGENCMDSTS_IOC | cmd,
80 whc->base + WUSBGENCMDSTS);
81
82 spin_unlock_irqrestore(&whc->lock, flags);
83
84 mutex_unlock(&whc->mutex);
85
86 return 0;
87}
diff --git a/drivers/usb/host/whci/init.c b/drivers/usb/host/whci/init.c
new file mode 100644
index 000000000000..34a783cb0133
--- /dev/null
+++ b/drivers/usb/host/whci/init.c
@@ -0,0 +1,188 @@
1/*
2 * Wireless Host Controller (WHC) initialization.
3 *
4 * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18#include <linux/kernel.h>
19#include <linux/dma-mapping.h>
20#include <linux/uwb/umc.h>
21
22#include "../../wusbcore/wusbhc.h"
23
24#include "whcd.h"
25
26/*
27 * Reset the host controller.
28 */
29static void whc_hw_reset(struct whc *whc)
30{
31 le_writel(WUSBCMD_WHCRESET, whc->base + WUSBCMD);
32 whci_wait_for(&whc->umc->dev, whc->base + WUSBCMD, WUSBCMD_WHCRESET, 0,
33 100, "reset");
34}
35
36static void whc_hw_init_di_buf(struct whc *whc)
37{
38 int d;
39
40 /* Disable all entries in the Device Information buffer. */
41 for (d = 0; d < whc->n_devices; d++)
42 whc->di_buf[d].addr_sec_info = WHC_DI_DISABLE;
43
44 le_writeq(whc->di_buf_dma, whc->base + WUSBDEVICEINFOADDR);
45}
46
47static void whc_hw_init_dn_buf(struct whc *whc)
48{
49 /* Clear the Device Notification buffer to ensure the V (valid)
50 * bits are clear. */
51 memset(whc->dn_buf, 0, 4096);
52
53 le_writeq(whc->dn_buf_dma, whc->base + WUSBDNTSBUFADDR);
54}
55
56int whc_init(struct whc *whc)
57{
58 u32 whcsparams;
59 int ret, i;
60 resource_size_t start, len;
61
62 spin_lock_init(&whc->lock);
63 mutex_init(&whc->mutex);
64 init_waitqueue_head(&whc->cmd_wq);
65 init_waitqueue_head(&whc->async_list_wq);
66 init_waitqueue_head(&whc->periodic_list_wq);
67 whc->workqueue = create_singlethread_workqueue(dev_name(&whc->umc->dev));
68 if (whc->workqueue == NULL) {
69 ret = -ENOMEM;
70 goto error;
71 }
72 INIT_WORK(&whc->dn_work, whc_dn_work);
73
74 INIT_WORK(&whc->async_work, scan_async_work);
75 INIT_LIST_HEAD(&whc->async_list);
76 INIT_LIST_HEAD(&whc->async_removed_list);
77
78 INIT_WORK(&whc->periodic_work, scan_periodic_work);
79 for (i = 0; i < 5; i++)
80 INIT_LIST_HEAD(&whc->periodic_list[i]);
81 INIT_LIST_HEAD(&whc->periodic_removed_list);
82
83 /* Map HC registers. */
84 start = whc->umc->resource.start;
85 len = whc->umc->resource.end - start + 1;
86 if (!request_mem_region(start, len, "whci-hc")) {
87 dev_err(&whc->umc->dev, "can't request HC region\n");
88 ret = -EBUSY;
89 goto error;
90 }
91 whc->base_phys = start;
92 whc->base = ioremap(start, len);
93 if (!whc->base) {
94 dev_err(&whc->umc->dev, "ioremap\n");
95 ret = -ENOMEM;
96 goto error;
97 }
98
99 whc_hw_reset(whc);
100
101 /* Read maximum number of devices, keys and MMC IEs. */
102 whcsparams = le_readl(whc->base + WHCSPARAMS);
103 whc->n_devices = WHCSPARAMS_TO_N_DEVICES(whcsparams);
104 whc->n_keys = WHCSPARAMS_TO_N_KEYS(whcsparams);
105 whc->n_mmc_ies = WHCSPARAMS_TO_N_MMC_IES(whcsparams);
106
107 dev_dbg(&whc->umc->dev, "N_DEVICES = %d, N_KEYS = %d, N_MMC_IES = %d\n",
108 whc->n_devices, whc->n_keys, whc->n_mmc_ies);
109
110 whc->qset_pool = dma_pool_create("qset", &whc->umc->dev,
111 sizeof(struct whc_qset), 64, 0);
112 if (whc->qset_pool == NULL) {
113 ret = -ENOMEM;
114 goto error;
115 }
116
117 ret = asl_init(whc);
118 if (ret < 0)
119 goto error;
120 ret = pzl_init(whc);
121 if (ret < 0)
122 goto error;
123
124 /* Allocate and initialize a buffer for generic commands, the
125 Device Information buffer, and the Device Notification
126 buffer. */
127
128 whc->gen_cmd_buf = dma_alloc_coherent(&whc->umc->dev, WHC_GEN_CMD_DATA_LEN,
129 &whc->gen_cmd_buf_dma, GFP_KERNEL);
130 if (whc->gen_cmd_buf == NULL) {
131 ret = -ENOMEM;
132 goto error;
133 }
134
135 whc->dn_buf = dma_alloc_coherent(&whc->umc->dev,
136 sizeof(struct dn_buf_entry) * WHC_N_DN_ENTRIES,
137 &whc->dn_buf_dma, GFP_KERNEL);
138 if (!whc->dn_buf) {
139 ret = -ENOMEM;
140 goto error;
141 }
142 whc_hw_init_dn_buf(whc);
143
144 whc->di_buf = dma_alloc_coherent(&whc->umc->dev,
145 sizeof(struct di_buf_entry) * whc->n_devices,
146 &whc->di_buf_dma, GFP_KERNEL);
147 if (!whc->di_buf) {
148 ret = -ENOMEM;
149 goto error;
150 }
151 whc_hw_init_di_buf(whc);
152
153 return 0;
154
155error:
156 whc_clean_up(whc);
157 return ret;
158}
159
160void whc_clean_up(struct whc *whc)
161{
162 resource_size_t len;
163
164 if (whc->di_buf)
165 dma_free_coherent(&whc->umc->dev, sizeof(struct di_buf_entry) * whc->n_devices,
166 whc->di_buf, whc->di_buf_dma);
167 if (whc->dn_buf)
168 dma_free_coherent(&whc->umc->dev, sizeof(struct dn_buf_entry) * WHC_N_DN_ENTRIES,
169 whc->dn_buf, whc->dn_buf_dma);
170 if (whc->gen_cmd_buf)
171 dma_free_coherent(&whc->umc->dev, WHC_GEN_CMD_DATA_LEN,
172 whc->gen_cmd_buf, whc->gen_cmd_buf_dma);
173
174 pzl_clean_up(whc);
175 asl_clean_up(whc);
176
177 if (whc->qset_pool)
178 dma_pool_destroy(whc->qset_pool);
179
180 len = whc->umc->resource.end - whc->umc->resource.start + 1;
181 if (whc->base)
182 iounmap(whc->base);
183 if (whc->base_phys)
184 release_mem_region(whc->base_phys, len);
185
186 if (whc->workqueue)
187 destroy_workqueue(whc->workqueue);
188}
diff --git a/drivers/usb/host/whci/int.c b/drivers/usb/host/whci/int.c
new file mode 100644
index 000000000000..fce01174aa9b
--- /dev/null
+++ b/drivers/usb/host/whci/int.c
@@ -0,0 +1,95 @@
1/*
2 * Wireless Host Controller (WHC) interrupt handling.
3 *
4 * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18#include <linux/version.h>
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/uwb/umc.h>
22
23#include "../../wusbcore/wusbhc.h"
24
25#include "whcd.h"
26
27static void transfer_done(struct whc *whc)
28{
29 queue_work(whc->workqueue, &whc->async_work);
30 queue_work(whc->workqueue, &whc->periodic_work);
31}
32
33irqreturn_t whc_int_handler(struct usb_hcd *hcd)
34{
35 struct wusbhc *wusbhc = usb_hcd_to_wusbhc(hcd);
36 struct whc *whc = wusbhc_to_whc(wusbhc);
37 u32 sts;
38
39 sts = le_readl(whc->base + WUSBSTS);
40 if (!(sts & WUSBSTS_INT_MASK))
41 return IRQ_NONE;
42 le_writel(sts & WUSBSTS_INT_MASK, whc->base + WUSBSTS);
43
44 if (sts & WUSBSTS_GEN_CMD_DONE)
45 wake_up(&whc->cmd_wq);
46
47 if (sts & WUSBSTS_HOST_ERR)
48 dev_err(&whc->umc->dev, "FIXME: host system error\n");
49
50 if (sts & WUSBSTS_ASYNC_SCHED_SYNCED)
51 wake_up(&whc->async_list_wq);
52
53 if (sts & WUSBSTS_PERIODIC_SCHED_SYNCED)
54 wake_up(&whc->periodic_list_wq);
55
56 if (sts & WUSBSTS_DNTS_INT)
57 queue_work(whc->workqueue, &whc->dn_work);
58
59 /*
60 * A transfer completed (see [WHCI] section 4.7.1.2 for when
61 * this occurs).
62 */
63 if (sts & (WUSBSTS_INT | WUSBSTS_ERR_INT))
64 transfer_done(whc);
65
66 return IRQ_HANDLED;
67}
68
69static int process_dn_buf(struct whc *whc)
70{
71 struct wusbhc *wusbhc = &whc->wusbhc;
72 struct dn_buf_entry *dn;
73 int processed = 0;
74
75 for (dn = whc->dn_buf; dn < whc->dn_buf + WHC_N_DN_ENTRIES; dn++) {
76 if (dn->status & WHC_DN_STATUS_VALID) {
77 wusbhc_handle_dn(wusbhc, dn->src_addr,
78 (struct wusb_dn_hdr *)dn->dn_data,
79 dn->msg_size);
80 dn->status &= ~WHC_DN_STATUS_VALID;
81 processed++;
82 }
83 }
84 return processed;
85}
86
87void whc_dn_work(struct work_struct *work)
88{
89 struct whc *whc = container_of(work, struct whc, dn_work);
90 int processed;
91
92 do {
93 processed = process_dn_buf(whc);
94 } while (processed);
95}
diff --git a/drivers/usb/host/whci/pzl.c b/drivers/usb/host/whci/pzl.c
new file mode 100644
index 000000000000..8d62df0c330b
--- /dev/null
+++ b/drivers/usb/host/whci/pzl.c
@@ -0,0 +1,398 @@
1/*
2 * Wireless Host Controller (WHC) periodic schedule management.
3 *
4 * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18#include <linux/kernel.h>
19#include <linux/dma-mapping.h>
20#include <linux/uwb/umc.h>
21#include <linux/usb.h>
22#define D_LOCAL 0
23#include <linux/uwb/debug.h>
24
25#include "../../wusbcore/wusbhc.h"
26
27#include "whcd.h"
28
29#if D_LOCAL >= 4
30static void dump_pzl(struct whc *whc, const char *tag)
31{
32 struct device *dev = &whc->umc->dev;
33 struct whc_qset *qset;
34 int period = 0;
35
36 d_printf(4, dev, "PZL %s\n", tag);
37
38 for (period = 0; period < 5; period++) {
39 d_printf(4, dev, "Period %d\n", period);
40 list_for_each_entry(qset, &whc->periodic_list[period], list_node) {
41 dump_qset(qset, dev);
42 }
43 }
44}
45#else
46static inline void dump_pzl(struct whc *whc, const char *tag)
47{
48}
49#endif
50
51static void update_pzl_pointers(struct whc *whc, int period, u64 addr)
52{
53 switch (period) {
54 case 0:
55 whc_qset_set_link_ptr(&whc->pz_list[0], addr);
56 whc_qset_set_link_ptr(&whc->pz_list[2], addr);
57 whc_qset_set_link_ptr(&whc->pz_list[4], addr);
58 whc_qset_set_link_ptr(&whc->pz_list[6], addr);
59 whc_qset_set_link_ptr(&whc->pz_list[8], addr);
60 whc_qset_set_link_ptr(&whc->pz_list[10], addr);
61 whc_qset_set_link_ptr(&whc->pz_list[12], addr);
62 whc_qset_set_link_ptr(&whc->pz_list[14], addr);
63 break;
64 case 1:
65 whc_qset_set_link_ptr(&whc->pz_list[1], addr);
66 whc_qset_set_link_ptr(&whc->pz_list[5], addr);
67 whc_qset_set_link_ptr(&whc->pz_list[9], addr);
68 whc_qset_set_link_ptr(&whc->pz_list[13], addr);
69 break;
70 case 2:
71 whc_qset_set_link_ptr(&whc->pz_list[3], addr);
72 whc_qset_set_link_ptr(&whc->pz_list[11], addr);
73 break;
74 case 3:
75 whc_qset_set_link_ptr(&whc->pz_list[7], addr);
76 break;
77 case 4:
78 whc_qset_set_link_ptr(&whc->pz_list[15], addr);
79 break;
80 }
81}
82
83/*
84 * Return the 'period' to use for this qset. The minimum interval for
85 * the endpoint is used so whatever urbs are submitted the device is
86 * polled often enough.
87 */
88static int qset_get_period(struct whc *whc, struct whc_qset *qset)
89{
90 uint8_t bInterval = qset->ep->desc.bInterval;
91
92 if (bInterval < 6)
93 bInterval = 6;
94 if (bInterval > 10)
95 bInterval = 10;
96 return bInterval - 6;
97}
98
99static void qset_insert_in_sw_list(struct whc *whc, struct whc_qset *qset)
100{
101 int period;
102
103 period = qset_get_period(whc, qset);
104
105 qset_clear(whc, qset);
106 list_move(&qset->list_node, &whc->periodic_list[period]);
107 qset->in_sw_list = true;
108}
109
110static void pzl_qset_remove(struct whc *whc, struct whc_qset *qset)
111{
112 list_move(&qset->list_node, &whc->periodic_removed_list);
113 qset->in_hw_list = false;
114 qset->in_sw_list = false;
115}
116
117/**
118 * pzl_process_qset - process any recently inactivated or halted qTDs
119 * in a qset.
120 *
121 * After inactive qTDs are removed, new qTDs can be added if the
122 * urb queue still contains URBs.
123 *
124 * Returns the schedule updates required.
125 */
126static enum whc_update pzl_process_qset(struct whc *whc, struct whc_qset *qset)
127{
128 enum whc_update update = 0;
129 uint32_t status = 0;
130
131 while (qset->ntds) {
132 struct whc_qtd *td;
133 int t;
134
135 t = qset->td_start;
136 td = &qset->qtd[qset->td_start];
137 status = le32_to_cpu(td->status);
138
139 /*
140 * Nothing to do with a still active qTD.
141 */
142 if (status & QTD_STS_ACTIVE)
143 break;
144
145 if (status & QTD_STS_HALTED) {
146 /* Ug, an error. */
147 process_halted_qtd(whc, qset, td);
148 goto done;
149 }
150
151 /* Mmm, a completed qTD. */
152 process_inactive_qtd(whc, qset, td);
153 }
154
155 update |= qset_add_qtds(whc, qset);
156
157done:
158 /*
159 * If there are no qTDs in this qset, remove it from the PZL.
160 */
161 if (qset->remove && qset->ntds == 0) {
162 pzl_qset_remove(whc, qset);
163 update |= WHC_UPDATE_REMOVED;
164 }
165
166 return update;
167}
168
169/**
170 * pzl_start - start the periodic schedule
171 * @whc: the WHCI host controller
172 *
173 * The PZL must be valid (e.g., all entries in the list should have
174 * the T bit set).
175 */
176void pzl_start(struct whc *whc)
177{
178 le_writeq(whc->pz_list_dma, whc->base + WUSBPERIODICLISTBASE);
179
180 whc_write_wusbcmd(whc, WUSBCMD_PERIODIC_EN, WUSBCMD_PERIODIC_EN);
181 whci_wait_for(&whc->umc->dev, whc->base + WUSBSTS,
182 WUSBSTS_PERIODIC_SCHED, WUSBSTS_PERIODIC_SCHED,
183 1000, "start PZL");
184}
185
186/**
187 * pzl_stop - stop the periodic schedule
188 * @whc: the WHCI host controller
189 */
190void pzl_stop(struct whc *whc)
191{
192 whc_write_wusbcmd(whc, WUSBCMD_PERIODIC_EN, 0);
193 whci_wait_for(&whc->umc->dev, whc->base + WUSBSTS,
194 WUSBSTS_PERIODIC_SCHED, 0,
195 1000, "stop PZL");
196}
197
198void pzl_update(struct whc *whc, uint32_t wusbcmd)
199{
200 whc_write_wusbcmd(whc, wusbcmd, wusbcmd);
201 wait_event(whc->periodic_list_wq,
202 (le_readl(whc->base + WUSBCMD) & WUSBCMD_PERIODIC_UPDATED) == 0);
203}
204
205static void update_pzl_hw_view(struct whc *whc)
206{
207 struct whc_qset *qset, *t;
208 int period;
209 u64 tmp_qh = 0;
210
211 for (period = 0; period < 5; period++) {
212 list_for_each_entry_safe(qset, t, &whc->periodic_list[period], list_node) {
213 whc_qset_set_link_ptr(&qset->qh.link, tmp_qh);
214 tmp_qh = qset->qset_dma;
215 qset->in_hw_list = true;
216 }
217 update_pzl_pointers(whc, period, tmp_qh);
218 }
219}
220
221/**
222 * scan_periodic_work - scan the PZL for qsets to process.
223 *
224 * Process each qset in the PZL in turn and then signal the WHC that
225 * the PZL has been updated.
226 *
227 * Then start, stop or update the periodic schedule as required.
228 */
229void scan_periodic_work(struct work_struct *work)
230{
231 struct whc *whc = container_of(work, struct whc, periodic_work);
232 struct whc_qset *qset, *t;
233 enum whc_update update = 0;
234 int period;
235
236 spin_lock_irq(&whc->lock);
237
238 dump_pzl(whc, "before processing");
239
240 for (period = 4; period >= 0; period--) {
241 list_for_each_entry_safe(qset, t, &whc->periodic_list[period], list_node) {
242 if (!qset->in_hw_list)
243 update |= WHC_UPDATE_ADDED;
244 update |= pzl_process_qset(whc, qset);
245 }
246 }
247
248 if (update & (WHC_UPDATE_ADDED | WHC_UPDATE_REMOVED))
249 update_pzl_hw_view(whc);
250
251 dump_pzl(whc, "after processing");
252
253 spin_unlock_irq(&whc->lock);
254
255 if (update) {
256 uint32_t wusbcmd = WUSBCMD_PERIODIC_UPDATED | WUSBCMD_PERIODIC_SYNCED_DB;
257 if (update & WHC_UPDATE_REMOVED)
258 wusbcmd |= WUSBCMD_PERIODIC_QSET_RM;
259 pzl_update(whc, wusbcmd);
260 }
261
262 /*
263 * Now that the PZL is updated, complete the removal of any
264 * removed qsets.
265 */
266 spin_lock(&whc->lock);
267
268 list_for_each_entry_safe(qset, t, &whc->periodic_removed_list, list_node) {
269 qset_remove_complete(whc, qset);
270 }
271
272 spin_unlock(&whc->lock);
273}
274
275/**
276 * pzl_urb_enqueue - queue an URB onto the periodic list (PZL)
277 * @whc: the WHCI host controller
278 * @urb: the URB to enqueue
279 * @mem_flags: flags for any memory allocations
280 *
281 * The qset for the endpoint is obtained and the urb queued on to it.
282 *
283 * Work is scheduled to update the hardware's view of the PZL.
284 */
285int pzl_urb_enqueue(struct whc *whc, struct urb *urb, gfp_t mem_flags)
286{
287 struct whc_qset *qset;
288 int err;
289 unsigned long flags;
290
291 spin_lock_irqsave(&whc->lock, flags);
292
293 qset = get_qset(whc, urb, GFP_ATOMIC);
294 if (qset == NULL)
295 err = -ENOMEM;
296 else
297 err = qset_add_urb(whc, qset, urb, GFP_ATOMIC);
298 if (!err) {
299 usb_hcd_link_urb_to_ep(&whc->wusbhc.usb_hcd, urb);
300 if (!qset->in_sw_list)
301 qset_insert_in_sw_list(whc, qset);
302 }
303
304 spin_unlock_irqrestore(&whc->lock, flags);
305
306 if (!err)
307 queue_work(whc->workqueue, &whc->periodic_work);
308
309 return 0;
310}
311
312/**
313 * pzl_urb_dequeue - remove an URB (qset) from the periodic list
314 * @whc: the WHCI host controller
315 * @urb: the URB to dequeue
316 * @status: the current status of the URB
317 *
318 * URBs that do yet have qTDs can simply be removed from the software
319 * queue, otherwise the qset must be removed so the qTDs can be safely
320 * removed.
321 */
322int pzl_urb_dequeue(struct whc *whc, struct urb *urb, int status)
323{
324 struct whc_urb *wurb = urb->hcpriv;
325 struct whc_qset *qset = wurb->qset;
326 struct whc_std *std, *t;
327 int ret;
328 unsigned long flags;
329
330 spin_lock_irqsave(&whc->lock, flags);
331
332 ret = usb_hcd_check_unlink_urb(&whc->wusbhc.usb_hcd, urb, status);
333 if (ret < 0)
334 goto out;
335
336 list_for_each_entry_safe(std, t, &qset->stds, list_node) {
337 if (std->urb == urb)
338 qset_free_std(whc, std);
339 else
340 std->qtd = NULL; /* so this std is re-added when the qset is */
341 }
342
343 pzl_qset_remove(whc, qset);
344 wurb->status = status;
345 wurb->is_async = false;
346 queue_work(whc->workqueue, &wurb->dequeue_work);
347
348out:
349 spin_unlock_irqrestore(&whc->lock, flags);
350
351 return ret;
352}
353
354/**
355 * pzl_qset_delete - delete a qset from the PZL
356 */
357void pzl_qset_delete(struct whc *whc, struct whc_qset *qset)
358{
359 qset->remove = 1;
360 queue_work(whc->workqueue, &whc->periodic_work);
361 qset_delete(whc, qset);
362}
363
364
365/**
366 * pzl_init - initialize the periodic zone list
367 * @whc: the WHCI host controller
368 */
369int pzl_init(struct whc *whc)
370{
371 int i;
372
373 whc->pz_list = dma_alloc_coherent(&whc->umc->dev, sizeof(u64) * 16,
374 &whc->pz_list_dma, GFP_KERNEL);
375 if (whc->pz_list == NULL)
376 return -ENOMEM;
377
378 /* Set T bit on all elements in PZL. */
379 for (i = 0; i < 16; i++)
380 whc->pz_list[i] = cpu_to_le64(QH_LINK_NTDS(8) | QH_LINK_T);
381
382 le_writeq(whc->pz_list_dma, whc->base + WUSBPERIODICLISTBASE);
383
384 return 0;
385}
386
387/**
388 * pzl_clean_up - free PZL resources
389 * @whc: the WHCI host controller
390 *
391 * The PZL is stopped and empty.
392 */
393void pzl_clean_up(struct whc *whc)
394{
395 if (whc->pz_list)
396 dma_free_coherent(&whc->umc->dev, sizeof(u64) * 16, whc->pz_list,
397 whc->pz_list_dma);
398}
diff --git a/drivers/usb/host/whci/qset.c b/drivers/usb/host/whci/qset.c
new file mode 100644
index 000000000000..0420037d2e18
--- /dev/null
+++ b/drivers/usb/host/whci/qset.c
@@ -0,0 +1,567 @@
1/*
2 * Wireless Host Controller (WHC) qset management.
3 *
4 * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18#include <linux/kernel.h>
19#include <linux/dma-mapping.h>
20#include <linux/uwb/umc.h>
21#include <linux/usb.h>
22
23#include "../../wusbcore/wusbhc.h"
24
25#include "whcd.h"
26
27void dump_qset(struct whc_qset *qset, struct device *dev)
28{
29 struct whc_std *std;
30 struct urb *urb = NULL;
31 int i;
32
33 dev_dbg(dev, "qset %08x\n", (u32)qset->qset_dma);
34 dev_dbg(dev, " -> %08x\n", (u32)qset->qh.link);
35 dev_dbg(dev, " info: %08x %08x %08x\n",
36 qset->qh.info1, qset->qh.info2, qset->qh.info3);
37 dev_dbg(dev, " sts: %04x errs: %d\n", qset->qh.status, qset->qh.err_count);
38 dev_dbg(dev, " TD: sts: %08x opts: %08x\n",
39 qset->qh.overlay.qtd.status, qset->qh.overlay.qtd.options);
40
41 for (i = 0; i < WHCI_QSET_TD_MAX; i++) {
42 dev_dbg(dev, " %c%c TD[%d]: sts: %08x opts: %08x ptr: %08x\n",
43 i == qset->td_start ? 'S' : ' ',
44 i == qset->td_end ? 'E' : ' ',
45 i, qset->qtd[i].status, qset->qtd[i].options,
46 (u32)qset->qtd[i].page_list_ptr);
47 }
48 dev_dbg(dev, " ntds: %d\n", qset->ntds);
49 list_for_each_entry(std, &qset->stds, list_node) {
50 if (urb != std->urb) {
51 urb = std->urb;
52 dev_dbg(dev, " urb %p transferred: %d bytes\n", urb,
53 urb->actual_length);
54 }
55 if (std->qtd)
56 dev_dbg(dev, " sTD[%td]: %zu bytes @ %08x\n",
57 std->qtd - &qset->qtd[0],
58 std->len, std->num_pointers ?
59 (u32)(std->pl_virt[0].buf_ptr) : (u32)std->dma_addr);
60 else
61 dev_dbg(dev, " sTD[-]: %zd bytes @ %08x\n",
62 std->len, std->num_pointers ?
63 (u32)(std->pl_virt[0].buf_ptr) : (u32)std->dma_addr);
64 }
65}
66
67struct whc_qset *qset_alloc(struct whc *whc, gfp_t mem_flags)
68{
69 struct whc_qset *qset;
70 dma_addr_t dma;
71
72 qset = dma_pool_alloc(whc->qset_pool, mem_flags, &dma);
73 if (qset == NULL)
74 return NULL;
75 memset(qset, 0, sizeof(struct whc_qset));
76
77 qset->qset_dma = dma;
78 qset->whc = whc;
79
80 INIT_LIST_HEAD(&qset->list_node);
81 INIT_LIST_HEAD(&qset->stds);
82
83 return qset;
84}
85
86/**
87 * qset_fill_qh - fill the static endpoint state in a qset's QHead
88 * @qset: the qset whose QH needs initializing with static endpoint
89 * state
90 * @urb: an urb for a transfer to this endpoint
91 */
92static void qset_fill_qh(struct whc_qset *qset, struct urb *urb)
93{
94 struct usb_device *usb_dev = urb->dev;
95 struct usb_wireless_ep_comp_descriptor *epcd;
96 bool is_out;
97
98 is_out = usb_pipeout(urb->pipe);
99
100 epcd = (struct usb_wireless_ep_comp_descriptor *)qset->ep->extra;
101
102 if (epcd) {
103 qset->max_seq = epcd->bMaxSequence;
104 qset->max_burst = epcd->bMaxBurst;
105 } else {
106 qset->max_seq = 2;
107 qset->max_burst = 1;
108 }
109
110 qset->qh.info1 = cpu_to_le32(
111 QH_INFO1_EP(usb_pipeendpoint(urb->pipe))
112 | (is_out ? QH_INFO1_DIR_OUT : QH_INFO1_DIR_IN)
113 | usb_pipe_to_qh_type(urb->pipe)
114 | QH_INFO1_DEV_INFO_IDX(wusb_port_no_to_idx(usb_dev->portnum))
115 | QH_INFO1_MAX_PKT_LEN(usb_maxpacket(urb->dev, urb->pipe, is_out))
116 );
117 qset->qh.info2 = cpu_to_le32(
118 QH_INFO2_BURST(qset->max_burst)
119 | QH_INFO2_DBP(0)
120 | QH_INFO2_MAX_COUNT(3)
121 | QH_INFO2_MAX_RETRY(3)
122 | QH_INFO2_MAX_SEQ(qset->max_seq - 1)
123 );
124 /* FIXME: where can we obtain these Tx parameters from? Why
125 * doesn't the chip know what Tx power to use? It knows the Rx
126 * strength and can presumably guess the Tx power required
127 * from that? */
128 qset->qh.info3 = cpu_to_le32(
129 QH_INFO3_TX_RATE_53_3
130 | QH_INFO3_TX_PWR(0) /* 0 == max power */
131 );
132}
133
134/**
135 * qset_clear - clear fields in a qset so it may be reinserted into a
136 * schedule
137 */
138void qset_clear(struct whc *whc, struct whc_qset *qset)
139{
140 qset->td_start = qset->td_end = qset->ntds = 0;
141 qset->remove = 0;
142
143 qset->qh.link = cpu_to_le32(QH_LINK_NTDS(8) | QH_LINK_T);
144 qset->qh.status = cpu_to_le16(QH_STATUS_ICUR(qset->td_start));
145 qset->qh.err_count = 0;
146 qset->qh.cur_window = cpu_to_le32((1 << qset->max_burst) - 1);
147 qset->qh.scratch[0] = 0;
148 qset->qh.scratch[1] = 0;
149 qset->qh.scratch[2] = 0;
150
151 memset(&qset->qh.overlay, 0, sizeof(qset->qh.overlay));
152
153 init_completion(&qset->remove_complete);
154}
155
156/**
157 * get_qset - get the qset for an async endpoint
158 *
159 * A new qset is created if one does not already exist.
160 */
161struct whc_qset *get_qset(struct whc *whc, struct urb *urb,
162 gfp_t mem_flags)
163{
164 struct whc_qset *qset;
165
166 qset = urb->ep->hcpriv;
167 if (qset == NULL) {
168 qset = qset_alloc(whc, mem_flags);
169 if (qset == NULL)
170 return NULL;
171
172 qset->ep = urb->ep;
173 urb->ep->hcpriv = qset;
174 qset_fill_qh(qset, urb);
175 }
176 return qset;
177}
178
179void qset_remove_complete(struct whc *whc, struct whc_qset *qset)
180{
181 list_del_init(&qset->list_node);
182 complete(&qset->remove_complete);
183}
184
185/**
186 * qset_add_qtds - add qTDs for an URB to a qset
187 *
188 * Returns true if the list (ASL/PZL) must be updated because (for a
189 * WHCI 0.95 controller) an activated qTD was pointed to be iCur.
190 */
191enum whc_update qset_add_qtds(struct whc *whc, struct whc_qset *qset)
192{
193 struct whc_std *std;
194 enum whc_update update = 0;
195
196 list_for_each_entry(std, &qset->stds, list_node) {
197 struct whc_qtd *qtd;
198 uint32_t status;
199
200 if (qset->ntds >= WHCI_QSET_TD_MAX
201 || (qset->pause_after_urb && std->urb != qset->pause_after_urb))
202 break;
203
204 if (std->qtd)
205 continue; /* already has a qTD */
206
207 qtd = std->qtd = &qset->qtd[qset->td_end];
208
209 /* Fill in setup bytes for control transfers. */
210 if (usb_pipecontrol(std->urb->pipe))
211 memcpy(qtd->setup, std->urb->setup_packet, 8);
212
213 status = QTD_STS_ACTIVE | QTD_STS_LEN(std->len);
214
215 if (whc_std_last(std) && usb_pipeout(std->urb->pipe))
216 status |= QTD_STS_LAST_PKT;
217
218 /*
219 * For an IN transfer the iAlt field should be set so
220 * the h/w will automatically advance to the next
221 * transfer. However, if there are 8 or more TDs
222 * remaining in this transfer then iAlt cannot be set
223 * as it could point to somewhere in this transfer.
224 */
225 if (std->ntds_remaining < WHCI_QSET_TD_MAX) {
226 int ialt;
227 ialt = (qset->td_end + std->ntds_remaining) % WHCI_QSET_TD_MAX;
228 status |= QTD_STS_IALT(ialt);
229 } else if (usb_pipein(std->urb->pipe))
230 qset->pause_after_urb = std->urb;
231
232 if (std->num_pointers)
233 qtd->options = cpu_to_le32(QTD_OPT_IOC);
234 else
235 qtd->options = cpu_to_le32(QTD_OPT_IOC | QTD_OPT_SMALL);
236 qtd->page_list_ptr = cpu_to_le64(std->dma_addr);
237
238 qtd->status = cpu_to_le32(status);
239
240 if (QH_STATUS_TO_ICUR(qset->qh.status) == qset->td_end)
241 update = WHC_UPDATE_UPDATED;
242
243 if (++qset->td_end >= WHCI_QSET_TD_MAX)
244 qset->td_end = 0;
245 qset->ntds++;
246 }
247
248 return update;
249}
250
251/**
252 * qset_remove_qtd - remove the first qTD from a qset.
253 *
254 * The qTD might be still active (if it's part of a IN URB that
255 * resulted in a short read) so ensure it's deactivated.
256 */
257static void qset_remove_qtd(struct whc *whc, struct whc_qset *qset)
258{
259 qset->qtd[qset->td_start].status = 0;
260
261 if (++qset->td_start >= WHCI_QSET_TD_MAX)
262 qset->td_start = 0;
263 qset->ntds--;
264}
265
266/**
267 * qset_free_std - remove an sTD and free it.
268 * @whc: the WHCI host controller
269 * @std: the sTD to remove and free.
270 */
271void qset_free_std(struct whc *whc, struct whc_std *std)
272{
273 list_del(&std->list_node);
274 if (std->num_pointers) {
275 dma_unmap_single(whc->wusbhc.dev, std->dma_addr,
276 std->num_pointers * sizeof(struct whc_page_list_entry),
277 DMA_TO_DEVICE);
278 kfree(std->pl_virt);
279 }
280
281 kfree(std);
282}
283
284/**
285 * qset_remove_qtds - remove an URB's qTDs (and sTDs).
286 */
287static void qset_remove_qtds(struct whc *whc, struct whc_qset *qset,
288 struct urb *urb)
289{
290 struct whc_std *std, *t;
291
292 list_for_each_entry_safe(std, t, &qset->stds, list_node) {
293 if (std->urb != urb)
294 break;
295 if (std->qtd != NULL)
296 qset_remove_qtd(whc, qset);
297 qset_free_std(whc, std);
298 }
299}
300
301/**
302 * qset_free_stds - free any remaining sTDs for an URB.
303 */
304static void qset_free_stds(struct whc_qset *qset, struct urb *urb)
305{
306 struct whc_std *std, *t;
307
308 list_for_each_entry_safe(std, t, &qset->stds, list_node) {
309 if (std->urb == urb)
310 qset_free_std(qset->whc, std);
311 }
312}
313
314static int qset_fill_page_list(struct whc *whc, struct whc_std *std, gfp_t mem_flags)
315{
316 dma_addr_t dma_addr = std->dma_addr;
317 dma_addr_t sp, ep;
318 size_t std_len = std->len;
319 size_t pl_len;
320 int p;
321
322 sp = ALIGN(dma_addr, WHCI_PAGE_SIZE);
323 ep = dma_addr + std_len;
324 std->num_pointers = DIV_ROUND_UP(ep - sp, WHCI_PAGE_SIZE);
325
326 pl_len = std->num_pointers * sizeof(struct whc_page_list_entry);
327 std->pl_virt = kmalloc(pl_len, mem_flags);
328 if (std->pl_virt == NULL)
329 return -ENOMEM;
330 std->dma_addr = dma_map_single(whc->wusbhc.dev, std->pl_virt, pl_len, DMA_TO_DEVICE);
331
332 for (p = 0; p < std->num_pointers; p++) {
333 std->pl_virt[p].buf_ptr = cpu_to_le64(dma_addr);
334 dma_addr = ALIGN(dma_addr + WHCI_PAGE_SIZE, WHCI_PAGE_SIZE);
335 }
336
337 return 0;
338}
339
340/**
341 * urb_dequeue_work - executes asl/pzl update and gives back the urb to the system.
342 */
343static void urb_dequeue_work(struct work_struct *work)
344{
345 struct whc_urb *wurb = container_of(work, struct whc_urb, dequeue_work);
346 struct whc_qset *qset = wurb->qset;
347 struct whc *whc = qset->whc;
348 unsigned long flags;
349
350 if (wurb->is_async == true)
351 asl_update(whc, WUSBCMD_ASYNC_UPDATED
352 | WUSBCMD_ASYNC_SYNCED_DB
353 | WUSBCMD_ASYNC_QSET_RM);
354 else
355 pzl_update(whc, WUSBCMD_PERIODIC_UPDATED
356 | WUSBCMD_PERIODIC_SYNCED_DB
357 | WUSBCMD_PERIODIC_QSET_RM);
358
359 spin_lock_irqsave(&whc->lock, flags);
360 qset_remove_urb(whc, qset, wurb->urb, wurb->status);
361 spin_unlock_irqrestore(&whc->lock, flags);
362}
363
364/**
365 * qset_add_urb - add an urb to the qset's queue.
366 *
367 * The URB is chopped into sTDs, one for each qTD that will required.
368 * At least one qTD (and sTD) is required even if the transfer has no
369 * data (e.g., for some control transfers).
370 */
371int qset_add_urb(struct whc *whc, struct whc_qset *qset, struct urb *urb,
372 gfp_t mem_flags)
373{
374 struct whc_urb *wurb;
375 int remaining = urb->transfer_buffer_length;
376 u64 transfer_dma = urb->transfer_dma;
377 int ntds_remaining;
378
379 ntds_remaining = DIV_ROUND_UP(remaining, QTD_MAX_XFER_SIZE);
380 if (ntds_remaining == 0)
381 ntds_remaining = 1;
382
383 wurb = kzalloc(sizeof(struct whc_urb), mem_flags);
384 if (wurb == NULL)
385 goto err_no_mem;
386 urb->hcpriv = wurb;
387 wurb->qset = qset;
388 wurb->urb = urb;
389 INIT_WORK(&wurb->dequeue_work, urb_dequeue_work);
390
391 while (ntds_remaining) {
392 struct whc_std *std;
393 size_t std_len;
394
395 std = kmalloc(sizeof(struct whc_std), mem_flags);
396 if (std == NULL)
397 goto err_no_mem;
398
399 std_len = remaining;
400 if (std_len > QTD_MAX_XFER_SIZE)
401 std_len = QTD_MAX_XFER_SIZE;
402
403 std->urb = urb;
404 std->dma_addr = transfer_dma;
405 std->len = std_len;
406 std->ntds_remaining = ntds_remaining;
407 std->qtd = NULL;
408
409 INIT_LIST_HEAD(&std->list_node);
410 list_add_tail(&std->list_node, &qset->stds);
411
412 if (std_len > WHCI_PAGE_SIZE) {
413 if (qset_fill_page_list(whc, std, mem_flags) < 0)
414 goto err_no_mem;
415 } else
416 std->num_pointers = 0;
417
418 ntds_remaining--;
419 remaining -= std_len;
420 transfer_dma += std_len;
421 }
422
423 return 0;
424
425err_no_mem:
426 qset_free_stds(qset, urb);
427 return -ENOMEM;
428}
429
430/**
431 * qset_remove_urb - remove an URB from the urb queue.
432 *
433 * The URB is returned to the USB subsystem.
434 */
435void qset_remove_urb(struct whc *whc, struct whc_qset *qset,
436 struct urb *urb, int status)
437{
438 struct wusbhc *wusbhc = &whc->wusbhc;
439 struct whc_urb *wurb = urb->hcpriv;
440
441 usb_hcd_unlink_urb_from_ep(&wusbhc->usb_hcd, urb);
442 /* Drop the lock as urb->complete() may enqueue another urb. */
443 spin_unlock(&whc->lock);
444 wusbhc_giveback_urb(wusbhc, urb, status);
445 spin_lock(&whc->lock);
446
447 kfree(wurb);
448}
449
450/**
451 * get_urb_status_from_qtd - get the completed urb status from qTD status
452 * @urb: completed urb
453 * @status: qTD status
454 */
455static int get_urb_status_from_qtd(struct urb *urb, u32 status)
456{
457 if (status & QTD_STS_HALTED) {
458 if (status & QTD_STS_DBE)
459 return usb_pipein(urb->pipe) ? -ENOSR : -ECOMM;
460 else if (status & QTD_STS_BABBLE)
461 return -EOVERFLOW;
462 else if (status & QTD_STS_RCE)
463 return -ETIME;
464 return -EPIPE;
465 }
466 if (usb_pipein(urb->pipe)
467 && (urb->transfer_flags & URB_SHORT_NOT_OK)
468 && urb->actual_length < urb->transfer_buffer_length)
469 return -EREMOTEIO;
470 return 0;
471}
472
473/**
474 * process_inactive_qtd - process an inactive (but not halted) qTD.
475 *
476 * Update the urb with the transfer bytes from the qTD, if the urb is
477 * completely transfered or (in the case of an IN only) the LPF is
478 * set, then the transfer is complete and the urb should be returned
479 * to the system.
480 */
481void process_inactive_qtd(struct whc *whc, struct whc_qset *qset,
482 struct whc_qtd *qtd)
483{
484 struct whc_std *std = list_first_entry(&qset->stds, struct whc_std, list_node);
485 struct urb *urb = std->urb;
486 uint32_t status;
487 bool complete;
488
489 status = le32_to_cpu(qtd->status);
490
491 urb->actual_length += std->len - QTD_STS_TO_LEN(status);
492
493 if (usb_pipein(urb->pipe) && (status & QTD_STS_LAST_PKT))
494 complete = true;
495 else
496 complete = whc_std_last(std);
497
498 qset_remove_qtd(whc, qset);
499 qset_free_std(whc, std);
500
501 /*
502 * Transfers for this URB are complete? Then return it to the
503 * USB subsystem.
504 */
505 if (complete) {
506 qset_remove_qtds(whc, qset, urb);
507 qset_remove_urb(whc, qset, urb, get_urb_status_from_qtd(urb, status));
508
509 /*
510 * If iAlt isn't valid then the hardware didn't
511 * advance iCur. Adjust the start and end pointers to
512 * match iCur.
513 */
514 if (!(status & QTD_STS_IALT_VALID))
515 qset->td_start = qset->td_end
516 = QH_STATUS_TO_ICUR(le16_to_cpu(qset->qh.status));
517 qset->pause_after_urb = NULL;
518 }
519}
520
521/**
522 * process_halted_qtd - process a qset with a halted qtd
523 *
524 * Remove all the qTDs for the failed URB and return the failed URB to
525 * the USB subsystem. Then remove all other qTDs so the qset can be
526 * removed.
527 *
528 * FIXME: this is the point where rate adaptation can be done. If a
529 * transfer failed because it exceeded the maximum number of retries
530 * then it could be reactivated with a slower rate without having to
531 * remove the qset.
532 */
533void process_halted_qtd(struct whc *whc, struct whc_qset *qset,
534 struct whc_qtd *qtd)
535{
536 struct whc_std *std = list_first_entry(&qset->stds, struct whc_std, list_node);
537 struct urb *urb = std->urb;
538 int urb_status;
539
540 urb_status = get_urb_status_from_qtd(urb, le32_to_cpu(qtd->status));
541
542 qset_remove_qtds(whc, qset, urb);
543 qset_remove_urb(whc, qset, urb, urb_status);
544
545 list_for_each_entry(std, &qset->stds, list_node) {
546 if (qset->ntds == 0)
547 break;
548 qset_remove_qtd(whc, qset);
549 std->qtd = NULL;
550 }
551
552 qset->remove = 1;
553}
554
555void qset_free(struct whc *whc, struct whc_qset *qset)
556{
557 dma_pool_free(whc->qset_pool, qset, qset->qset_dma);
558}
559
560/**
561 * qset_delete - wait for a qset to be unused, then free it.
562 */
563void qset_delete(struct whc *whc, struct whc_qset *qset)
564{
565 wait_for_completion(&qset->remove_complete);
566 qset_free(whc, qset);
567}
diff --git a/drivers/usb/host/whci/whcd.h b/drivers/usb/host/whci/whcd.h
new file mode 100644
index 000000000000..1d2a53bd39fd
--- /dev/null
+++ b/drivers/usb/host/whci/whcd.h
@@ -0,0 +1,197 @@
1/*
2 * Wireless Host Controller (WHC) private header.
3 *
4 * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301, USA.
19 */
20#ifndef __WHCD_H
21#define __WHCD_H
22
23#include <linux/uwb/whci.h>
24#include <linux/workqueue.h>
25
26#include "whci-hc.h"
27
28/* Generic command timeout. */
29#define WHC_GENCMD_TIMEOUT_MS 100
30
31
32struct whc {
33 struct wusbhc wusbhc;
34 struct umc_dev *umc;
35
36 resource_size_t base_phys;
37 void __iomem *base;
38 int irq;
39
40 u8 n_devices;
41 u8 n_keys;
42 u8 n_mmc_ies;
43
44 u64 *pz_list;
45 struct dn_buf_entry *dn_buf;
46 struct di_buf_entry *di_buf;
47 dma_addr_t pz_list_dma;
48 dma_addr_t dn_buf_dma;
49 dma_addr_t di_buf_dma;
50
51 spinlock_t lock;
52 struct mutex mutex;
53
54 void * gen_cmd_buf;
55 dma_addr_t gen_cmd_buf_dma;
56 wait_queue_head_t cmd_wq;
57
58 struct workqueue_struct *workqueue;
59 struct work_struct dn_work;
60
61 struct dma_pool *qset_pool;
62
63 struct list_head async_list;
64 struct list_head async_removed_list;
65 wait_queue_head_t async_list_wq;
66 struct work_struct async_work;
67
68 struct list_head periodic_list[5];
69 struct list_head periodic_removed_list;
70 wait_queue_head_t periodic_list_wq;
71 struct work_struct periodic_work;
72};
73
74#define wusbhc_to_whc(w) (container_of((w), struct whc, wusbhc))
75
76/**
77 * struct whc_std - a software TD.
78 * @urb: the URB this sTD is for.
79 * @offset: start of the URB's data for this TD.
80 * @len: the length of data in the associated TD.
81 * @ntds_remaining: number of TDs (starting from this one) in this transfer.
82 *
83 * Queued URBs may require more TDs than are available in a qset so we
84 * use a list of these "software TDs" (sTDs) to hold per-TD data.
85 */
86struct whc_std {
87 struct urb *urb;
88 size_t len;
89 int ntds_remaining;
90 struct whc_qtd *qtd;
91
92 struct list_head list_node;
93 int num_pointers;
94 dma_addr_t dma_addr;
95 struct whc_page_list_entry *pl_virt;
96};
97
98/**
99 * struct whc_urb - per URB host controller structure.
100 * @urb: the URB this struct is for.
101 * @qset: the qset associated to the URB.
102 * @dequeue_work: the work to remove the URB when dequeued.
103 * @is_async: the URB belongs to async sheduler or not.
104 * @status: the status to be returned when calling wusbhc_giveback_urb.
105 */
106struct whc_urb {
107 struct urb *urb;
108 struct whc_qset *qset;
109 struct work_struct dequeue_work;
110 bool is_async;
111 int status;
112};
113
114/**
115 * whc_std_last - is this sTD the URB's last?
116 * @std: the sTD to check.
117 */
118static inline bool whc_std_last(struct whc_std *std)
119{
120 return std->ntds_remaining <= 1;
121}
122
123enum whc_update {
124 WHC_UPDATE_ADDED = 0x01,
125 WHC_UPDATE_REMOVED = 0x02,
126 WHC_UPDATE_UPDATED = 0x04,
127};
128
129/* init.c */
130int whc_init(struct whc *whc);
131void whc_clean_up(struct whc *whc);
132
133/* hw.c */
134void whc_write_wusbcmd(struct whc *whc, u32 mask, u32 val);
135int whc_do_gencmd(struct whc *whc, u32 cmd, u32 params, void *addr, size_t len);
136
137/* wusb.c */
138int whc_wusbhc_start(struct wusbhc *wusbhc);
139void whc_wusbhc_stop(struct wusbhc *wusbhc);
140int whc_mmcie_add(struct wusbhc *wusbhc, u8 interval, u8 repeat_cnt,
141 u8 handle, struct wuie_hdr *wuie);
142int whc_mmcie_rm(struct wusbhc *wusbhc, u8 handle);
143int whc_bwa_set(struct wusbhc *wusbhc, s8 stream_index, const struct uwb_mas_bm *mas_bm);
144int whc_dev_info_set(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev);
145int whc_set_num_dnts(struct wusbhc *wusbhc, u8 interval, u8 slots);
146int whc_set_ptk(struct wusbhc *wusbhc, u8 port_idx, u32 tkid,
147 const void *ptk, size_t key_size);
148int whc_set_gtk(struct wusbhc *wusbhc, u32 tkid,
149 const void *gtk, size_t key_size);
150int whc_set_cluster_id(struct whc *whc, u8 bcid);
151
152/* int.c */
153irqreturn_t whc_int_handler(struct usb_hcd *hcd);
154void whc_dn_work(struct work_struct *work);
155
156/* asl.c */
157void asl_start(struct whc *whc);
158void asl_stop(struct whc *whc);
159int asl_init(struct whc *whc);
160void asl_clean_up(struct whc *whc);
161int asl_urb_enqueue(struct whc *whc, struct urb *urb, gfp_t mem_flags);
162int asl_urb_dequeue(struct whc *whc, struct urb *urb, int status);
163void asl_qset_delete(struct whc *whc, struct whc_qset *qset);
164void scan_async_work(struct work_struct *work);
165
166/* pzl.c */
167int pzl_init(struct whc *whc);
168void pzl_clean_up(struct whc *whc);
169void pzl_start(struct whc *whc);
170void pzl_stop(struct whc *whc);
171int pzl_urb_enqueue(struct whc *whc, struct urb *urb, gfp_t mem_flags);
172int pzl_urb_dequeue(struct whc *whc, struct urb *urb, int status);
173void pzl_qset_delete(struct whc *whc, struct whc_qset *qset);
174void scan_periodic_work(struct work_struct *work);
175
176/* qset.c */
177struct whc_qset *qset_alloc(struct whc *whc, gfp_t mem_flags);
178void qset_free(struct whc *whc, struct whc_qset *qset);
179struct whc_qset *get_qset(struct whc *whc, struct urb *urb, gfp_t mem_flags);
180void qset_delete(struct whc *whc, struct whc_qset *qset);
181void qset_clear(struct whc *whc, struct whc_qset *qset);
182int qset_add_urb(struct whc *whc, struct whc_qset *qset, struct urb *urb,
183 gfp_t mem_flags);
184void qset_free_std(struct whc *whc, struct whc_std *std);
185void qset_remove_urb(struct whc *whc, struct whc_qset *qset,
186 struct urb *urb, int status);
187void process_halted_qtd(struct whc *whc, struct whc_qset *qset,
188 struct whc_qtd *qtd);
189void process_inactive_qtd(struct whc *whc, struct whc_qset *qset,
190 struct whc_qtd *qtd);
191enum whc_update qset_add_qtds(struct whc *whc, struct whc_qset *qset);
192void qset_remove_complete(struct whc *whc, struct whc_qset *qset);
193void dump_qset(struct whc_qset *qset, struct device *dev);
194void pzl_update(struct whc *whc, uint32_t wusbcmd);
195void asl_update(struct whc *whc, uint32_t wusbcmd);
196
197#endif /* #ifndef __WHCD_H */
diff --git a/drivers/usb/host/whci/whci-hc.h b/drivers/usb/host/whci/whci-hc.h
new file mode 100644
index 000000000000..bff1eb7a35cf
--- /dev/null
+++ b/drivers/usb/host/whci/whci-hc.h
@@ -0,0 +1,416 @@
1/*
2 * Wireless Host Controller (WHC) data structures.
3 *
4 * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301, USA.
19 */
20#ifndef _WHCI_WHCI_HC_H
21#define _WHCI_WHCI_HC_H
22
23#include <linux/list.h>
24
25/**
26 * WHCI_PAGE_SIZE - page size use by WHCI
27 *
28 * WHCI assumes that host system uses pages of 4096 octets.
29 */
30#define WHCI_PAGE_SIZE 4096
31
32
33/**
34 * QTD_MAX_TXFER_SIZE - max number of bytes to transfer with a single
35 * qtd.
36 *
37 * This is 2^20 - 1.
38 */
39#define QTD_MAX_XFER_SIZE 1048575
40
41
42/**
43 * struct whc_qtd - Queue Element Transfer Descriptors (qTD)
44 *
45 * This describes the data for a bulk, control or interrupt transfer.
46 *
47 * [WHCI] section 3.2.4
48 */
49struct whc_qtd {
50 __le32 status; /*< remaining transfer len and transfer status */
51 __le32 options;
52 __le64 page_list_ptr; /*< physical pointer to data buffer page list*/
53 __u8 setup[8]; /*< setup data for control transfers */
54} __attribute__((packed));
55
56#define QTD_STS_ACTIVE (1 << 31) /* enable execution of transaction */
57#define QTD_STS_HALTED (1 << 30) /* transfer halted */
58#define QTD_STS_DBE (1 << 29) /* data buffer error */
59#define QTD_STS_BABBLE (1 << 28) /* babble detected */
60#define QTD_STS_RCE (1 << 27) /* retry count exceeded */
61#define QTD_STS_LAST_PKT (1 << 26) /* set Last Packet Flag in WUSB header */
62#define QTD_STS_INACTIVE (1 << 25) /* queue set is marked inactive */
63#define QTD_STS_IALT_VALID (1 << 23) /* iAlt field is valid */
64#define QTD_STS_IALT(i) (QTD_STS_IALT_VALID | ((i) << 20)) /* iAlt field */
65#define QTD_STS_LEN(l) ((l) << 0) /* transfer length */
66#define QTD_STS_TO_LEN(s) ((s) & 0x000fffff)
67
68#define QTD_OPT_IOC (1 << 1) /* page_list_ptr points to buffer directly */
69#define QTD_OPT_SMALL (1 << 0) /* interrupt on complete */
70
71/**
72 * struct whc_itd - Isochronous Queue Element Transfer Descriptors (iTD)
73 *
74 * This describes the data and other parameters for an isochronous
75 * transfer.
76 *
77 * [WHCI] section 3.2.5
78 */
79struct whc_itd {
80 __le16 presentation_time; /*< presentation time for OUT transfers */
81 __u8 num_segments; /*< number of data segments in segment list */
82 __u8 status; /*< command execution status */
83 __le32 options; /*< misc transfer options */
84 __le64 page_list_ptr; /*< physical pointer to data buffer page list */
85 __le64 seg_list_ptr; /*< physical pointer to segment list */
86} __attribute__((packed));
87
88#define ITD_STS_ACTIVE (1 << 7) /* enable execution of transaction */
89#define ITD_STS_DBE (1 << 5) /* data buffer error */
90#define ITD_STS_BABBLE (1 << 4) /* babble detected */
91#define ITD_STS_INACTIVE (1 << 1) /* queue set is marked inactive */
92
93#define ITD_OPT_IOC (1 << 1) /* interrupt on complete */
94#define ITD_OPT_SMALL (1 << 0) /* page_list_ptr points to buffer directly */
95
96/**
97 * Page list entry.
98 *
99 * A TD's page list must contain sufficient page list entries for the
100 * total data length in the TD.
101 *
102 * [WHCI] section 3.2.4.3
103 */
104struct whc_page_list_entry {
105 __le64 buf_ptr; /*< physical pointer to buffer */
106} __attribute__((packed));
107
108/**
109 * struct whc_seg_list_entry - Segment list entry.
110 *
111 * Describes a portion of the data buffer described in the containing
112 * qTD's page list.
113 *
114 * seg_ptr = qtd->page_list_ptr[qtd->seg_list_ptr[seg].idx].buf_ptr
115 * + qtd->seg_list_ptr[seg].offset;
116 *
117 * Segments can't cross page boundries.
118 *
119 * [WHCI] section 3.2.5.5
120 */
121struct whc_seg_list_entry {
122 __le16 len; /*< segment length */
123 __u8 idx; /*< index into page list */
124 __u8 status; /*< segment status */
125 __le16 offset; /*< 12 bit offset into page */
126} __attribute__((packed));
127
128/**
129 * struct whc_qhead - endpoint and status information for a qset.
130 *
131 * [WHCI] section 3.2.6
132 */
133struct whc_qhead {
134 __le64 link; /*< next qset in list */
135 __le32 info1;
136 __le32 info2;
137 __le32 info3;
138 __le16 status;
139 __le16 err_count; /*< transaction error count */
140 __le32 cur_window;
141 __le32 scratch[3]; /*< h/w scratch area */
142 union {
143 struct whc_qtd qtd;
144 struct whc_itd itd;
145 } overlay;
146} __attribute__((packed));
147
148#define QH_LINK_PTR_MASK (~0x03Full)
149#define QH_LINK_PTR(ptr) ((ptr) & QH_LINK_PTR_MASK)
150#define QH_LINK_IQS (1 << 4) /* isochronous queue set */
151#define QH_LINK_NTDS(n) (((n) - 1) << 1) /* number of TDs in queue set */
152#define QH_LINK_T (1 << 0) /* last queue set in periodic schedule list */
153
154#define QH_INFO1_EP(e) ((e) << 0) /* endpoint number */
155#define QH_INFO1_DIR_IN (1 << 4) /* IN transfer */
156#define QH_INFO1_DIR_OUT (0 << 4) /* OUT transfer */
157#define QH_INFO1_TR_TYPE_CTRL (0x0 << 5) /* control transfer */
158#define QH_INFO1_TR_TYPE_ISOC (0x1 << 5) /* isochronous transfer */
159#define QH_INFO1_TR_TYPE_BULK (0x2 << 5) /* bulk transfer */
160#define QH_INFO1_TR_TYPE_INT (0x3 << 5) /* interrupt */
161#define QH_INFO1_TR_TYPE_LP_INT (0x7 << 5) /* low power interrupt */
162#define QH_INFO1_DEV_INFO_IDX(i) ((i) << 8) /* index into device info buffer */
163#define QH_INFO1_SET_INACTIVE (1 << 15) /* set inactive after transfer */
164#define QH_INFO1_MAX_PKT_LEN(l) ((l) << 16) /* maximum packet length */
165
166#define QH_INFO2_BURST(b) ((b) << 0) /* maximum burst length */
167#define QH_INFO2_DBP(p) ((p) << 5) /* data burst policy (see [WUSB] table 5-7) */
168#define QH_INFO2_MAX_COUNT(c) ((c) << 8) /* max isoc/int pkts per zone */
169#define QH_INFO2_RQS (1 << 15) /* reactivate queue set */
170#define QH_INFO2_MAX_RETRY(r) ((r) << 16) /* maximum transaction retries */
171#define QH_INFO2_MAX_SEQ(s) ((s) << 20) /* maximum sequence number */
172#define QH_INFO3_MAX_DELAY(d) ((d) << 0) /* maximum stream delay in 125 us units (isoc only) */
173#define QH_INFO3_INTERVAL(i) ((i) << 16) /* segment interval in 125 us units (isoc only) */
174
175#define QH_INFO3_TX_RATE_53_3 (0 << 24)
176#define QH_INFO3_TX_RATE_80 (1 << 24)
177#define QH_INFO3_TX_RATE_106_7 (2 << 24)
178#define QH_INFO3_TX_RATE_160 (3 << 24)
179#define QH_INFO3_TX_RATE_200 (4 << 24)
180#define QH_INFO3_TX_RATE_320 (5 << 24)
181#define QH_INFO3_TX_RATE_400 (6 << 24)
182#define QH_INFO3_TX_RATE_480 (7 << 24)
183#define QH_INFO3_TX_PWR(p) ((p) << 29) /* transmit power (see [WUSB] section 5.2.1.2) */
184
185#define QH_STATUS_FLOW_CTRL (1 << 15)
186#define QH_STATUS_ICUR(i) ((i) << 5)
187#define QH_STATUS_TO_ICUR(s) (((s) >> 5) & 0x7)
188
189/**
190 * usb_pipe_to_qh_type - USB core pipe type to QH transfer type
191 *
192 * Returns the QH type field for a USB core pipe type.
193 */
194static inline unsigned usb_pipe_to_qh_type(unsigned pipe)
195{
196 static const unsigned type[] = {
197 [PIPE_ISOCHRONOUS] = QH_INFO1_TR_TYPE_ISOC,
198 [PIPE_INTERRUPT] = QH_INFO1_TR_TYPE_INT,
199 [PIPE_CONTROL] = QH_INFO1_TR_TYPE_CTRL,
200 [PIPE_BULK] = QH_INFO1_TR_TYPE_BULK,
201 };
202 return type[usb_pipetype(pipe)];
203}
204
205/**
206 * Maxiumum number of TDs in a qset.
207 */
208#define WHCI_QSET_TD_MAX 8
209
210/**
211 * struct whc_qset - WUSB data transfers to a specific endpoint
212 * @qh: the QHead of this qset
213 * @qtd: up to 8 qTDs (for qsets for control, bulk and interrupt
214 * transfers)
215 * @itd: up to 8 iTDs (for qsets for isochronous transfers)
216 * @qset_dma: DMA address for this qset
217 * @whc: WHCI HC this qset is for
218 * @ep: endpoint
219 * @stds: list of sTDs queued to this qset
220 * @ntds: number of qTDs queued (not necessarily the same as nTDs
221 * field in the QH)
222 * @td_start: index of the first qTD in the list
223 * @td_end: index of next free qTD in the list (provided
224 * ntds < WHCI_QSET_TD_MAX)
225 *
226 * Queue Sets (qsets) are added to the asynchronous schedule list
227 * (ASL) or the periodic zone list (PZL).
228 *
229 * qsets may contain up to 8 TDs (either qTDs or iTDs as appropriate).
230 * Each TD may refer to at most 1 MiB of data. If a single transfer
231 * has > 8MiB of data, TDs can be reused as they are completed since
232 * the TD list is used as a circular buffer. Similarly, several
233 * (smaller) transfers may be queued in a qset.
234 *
235 * WHCI controllers may cache portions of the qsets in the ASL and
236 * PZL, requiring the WHCD to inform the WHC that the lists have been
237 * updated (fields changed or qsets inserted or removed). For safe
238 * insertion and removal of qsets from the lists the schedule must be
239 * stopped to avoid races in updating the QH link pointers.
240 *
241 * Since the HC is free to execute qsets in any order, all transfers
242 * to an endpoint should use the same qset to ensure transfers are
243 * executed in the order they're submitted.
244 *
245 * [WHCI] section 3.2.3
246 */
247struct whc_qset {
248 struct whc_qhead qh;
249 union {
250 struct whc_qtd qtd[WHCI_QSET_TD_MAX];
251 struct whc_itd itd[WHCI_QSET_TD_MAX];
252 };
253
254 /* private data for WHCD */
255 dma_addr_t qset_dma;
256 struct whc *whc;
257 struct usb_host_endpoint *ep;
258 struct list_head stds;
259 int ntds;
260 int td_start;
261 int td_end;
262 struct list_head list_node;
263 unsigned in_sw_list:1;
264 unsigned in_hw_list:1;
265 unsigned remove:1;
266 struct urb *pause_after_urb;
267 struct completion remove_complete;
268 int max_burst;
269 int max_seq;
270};
271
272static inline void whc_qset_set_link_ptr(u64 *ptr, u64 target)
273{
274 if (target)
275 *ptr = (*ptr & ~(QH_LINK_PTR_MASK | QH_LINK_T)) | QH_LINK_PTR(target);
276 else
277 *ptr = QH_LINK_T;
278}
279
280/**
281 * struct di_buf_entry - Device Information (DI) buffer entry.
282 *
283 * There's one of these per connected device.
284 */
285struct di_buf_entry {
286 __le32 availability_info[8]; /*< MAS availability information, one MAS per bit */
287 __le32 addr_sec_info; /*< addressing and security info */
288 __le32 reserved[7];
289} __attribute__((packed));
290
291#define WHC_DI_SECURE (1 << 31)
292#define WHC_DI_DISABLE (1 << 30)
293#define WHC_DI_KEY_IDX(k) ((k) << 8)
294#define WHC_DI_KEY_IDX_MASK 0x0000ff00
295#define WHC_DI_DEV_ADDR(a) ((a) << 0)
296#define WHC_DI_DEV_ADDR_MASK 0x000000ff
297
298/**
299 * struct dn_buf_entry - Device Notification (DN) buffer entry.
300 *
301 * [WHCI] section 3.2.8
302 */
303struct dn_buf_entry {
304 __u8 msg_size; /*< number of octets of valid DN data */
305 __u8 reserved1;
306 __u8 src_addr; /*< source address */
307 __u8 status; /*< buffer entry status */
308 __le32 tkid; /*< TKID for source device, valid if secure bit is set */
309 __u8 dn_data[56]; /*< up to 56 octets of DN data */
310} __attribute__((packed));
311
312#define WHC_DN_STATUS_VALID (1 << 7) /* buffer entry is valid */
313#define WHC_DN_STATUS_SECURE (1 << 6) /* notification received using secure frame */
314
315#define WHC_N_DN_ENTRIES (4096 / sizeof(struct dn_buf_entry))
316
317/* The Add MMC IE WUSB Generic Command may take up to 256 bytes of
318 data. [WHCI] section 2.4.7. */
319#define WHC_GEN_CMD_DATA_LEN 256
320
321/*
322 * HC registers.
323 *
324 * [WHCI] section 2.4
325 */
326
327#define WHCIVERSION 0x00
328
329#define WHCSPARAMS 0x04
330# define WHCSPARAMS_TO_N_MMC_IES(p) (((p) >> 16) & 0xff)
331# define WHCSPARAMS_TO_N_KEYS(p) (((p) >> 8) & 0xff)
332# define WHCSPARAMS_TO_N_DEVICES(p) (((p) >> 0) & 0x7f)
333
334#define WUSBCMD 0x08
335# define WUSBCMD_BCID(b) ((b) << 16)
336# define WUSBCMD_BCID_MASK (0xff << 16)
337# define WUSBCMD_ASYNC_QSET_RM (1 << 12)
338# define WUSBCMD_PERIODIC_QSET_RM (1 << 11)
339# define WUSBCMD_WUSBSI(s) ((s) << 8)
340# define WUSBCMD_WUSBSI_MASK (0x7 << 8)
341# define WUSBCMD_ASYNC_SYNCED_DB (1 << 7)
342# define WUSBCMD_PERIODIC_SYNCED_DB (1 << 6)
343# define WUSBCMD_ASYNC_UPDATED (1 << 5)
344# define WUSBCMD_PERIODIC_UPDATED (1 << 4)
345# define WUSBCMD_ASYNC_EN (1 << 3)
346# define WUSBCMD_PERIODIC_EN (1 << 2)
347# define WUSBCMD_WHCRESET (1 << 1)
348# define WUSBCMD_RUN (1 << 0)
349
350#define WUSBSTS 0x0c
351# define WUSBSTS_ASYNC_SCHED (1 << 15)
352# define WUSBSTS_PERIODIC_SCHED (1 << 14)
353# define WUSBSTS_DNTS_SCHED (1 << 13)
354# define WUSBSTS_HCHALTED (1 << 12)
355# define WUSBSTS_GEN_CMD_DONE (1 << 9)
356# define WUSBSTS_CHAN_TIME_ROLLOVER (1 << 8)
357# define WUSBSTS_DNTS_OVERFLOW (1 << 7)
358# define WUSBSTS_BPST_ADJUSTMENT_CHANGED (1 << 6)
359# define WUSBSTS_HOST_ERR (1 << 5)
360# define WUSBSTS_ASYNC_SCHED_SYNCED (1 << 4)
361# define WUSBSTS_PERIODIC_SCHED_SYNCED (1 << 3)
362# define WUSBSTS_DNTS_INT (1 << 2)
363# define WUSBSTS_ERR_INT (1 << 1)
364# define WUSBSTS_INT (1 << 0)
365# define WUSBSTS_INT_MASK 0x3ff
366
367#define WUSBINTR 0x10
368# define WUSBINTR_GEN_CMD_DONE (1 << 9)
369# define WUSBINTR_CHAN_TIME_ROLLOVER (1 << 8)
370# define WUSBINTR_DNTS_OVERFLOW (1 << 7)
371# define WUSBINTR_BPST_ADJUSTMENT_CHANGED (1 << 6)
372# define WUSBINTR_HOST_ERR (1 << 5)
373# define WUSBINTR_ASYNC_SCHED_SYNCED (1 << 4)
374# define WUSBINTR_PERIODIC_SCHED_SYNCED (1 << 3)
375# define WUSBINTR_DNTS_INT (1 << 2)
376# define WUSBINTR_ERR_INT (1 << 1)
377# define WUSBINTR_INT (1 << 0)
378# define WUSBINTR_ALL 0x3ff
379
380#define WUSBGENCMDSTS 0x14
381# define WUSBGENCMDSTS_ACTIVE (1 << 31)
382# define WUSBGENCMDSTS_ERROR (1 << 24)
383# define WUSBGENCMDSTS_IOC (1 << 23)
384# define WUSBGENCMDSTS_MMCIE_ADD 0x01
385# define WUSBGENCMDSTS_MMCIE_RM 0x02
386# define WUSBGENCMDSTS_SET_MAS 0x03
387# define WUSBGENCMDSTS_CHAN_STOP 0x04
388# define WUSBGENCMDSTS_RWP_EN 0x05
389
390#define WUSBGENCMDPARAMS 0x18
391#define WUSBGENADDR 0x20
392#define WUSBASYNCLISTADDR 0x28
393#define WUSBDNTSBUFADDR 0x30
394#define WUSBDEVICEINFOADDR 0x38
395
396#define WUSBSETSECKEYCMD 0x40
397# define WUSBSETSECKEYCMD_SET (1 << 31)
398# define WUSBSETSECKEYCMD_ERASE (1 << 30)
399# define WUSBSETSECKEYCMD_GTK (1 << 8)
400# define WUSBSETSECKEYCMD_IDX(i) ((i) << 0)
401
402#define WUSBTKID 0x44
403#define WUSBSECKEY 0x48
404#define WUSBPERIODICLISTBASE 0x58
405#define WUSBMASINDEX 0x60
406
407#define WUSBDNTSCTRL 0x64
408# define WUSBDNTSCTRL_ACTIVE (1 << 31)
409# define WUSBDNTSCTRL_INTERVAL(i) ((i) << 8)
410# define WUSBDNTSCTRL_SLOTS(s) ((s) << 0)
411
412#define WUSBTIME 0x68
413#define WUSBBPST 0x6c
414#define WUSBDIBUPDATED 0x70
415
416#endif /* #ifndef _WHCI_WHCI_HC_H */
diff --git a/drivers/usb/host/whci/wusb.c b/drivers/usb/host/whci/wusb.c
new file mode 100644
index 000000000000..66e4ddcd961d
--- /dev/null
+++ b/drivers/usb/host/whci/wusb.c
@@ -0,0 +1,241 @@
1/*
2 * Wireless Host Controller (WHC) WUSB operations.
3 *
4 * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18#include <linux/version.h>
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/uwb/umc.h>
22#define D_LOCAL 1
23#include <linux/uwb/debug.h>
24
25#include "../../wusbcore/wusbhc.h"
26
27#include "whcd.h"
28
29#if D_LOCAL >= 1
30static void dump_di(struct whc *whc, int idx)
31{
32 struct di_buf_entry *di = &whc->di_buf[idx];
33 struct device *dev = &whc->umc->dev;
34 char buf[128];
35
36 bitmap_scnprintf(buf, sizeof(buf), (unsigned long *)di->availability_info, UWB_NUM_MAS);
37
38 d_printf(1, dev, "DI[%d]\n", idx);
39 d_printf(1, dev, " availability: %s\n", buf);
40 d_printf(1, dev, " %c%c key idx: %d dev addr: %d\n",
41 (di->addr_sec_info & WHC_DI_SECURE) ? 'S' : ' ',
42 (di->addr_sec_info & WHC_DI_DISABLE) ? 'D' : ' ',
43 (di->addr_sec_info & WHC_DI_KEY_IDX_MASK) >> 8,
44 (di->addr_sec_info & WHC_DI_DEV_ADDR_MASK));
45}
46#else
47static inline void dump_di(struct whc *whc, int idx)
48{
49}
50#endif
51
52static int whc_update_di(struct whc *whc, int idx)
53{
54 int offset = idx / 32;
55 u32 bit = 1 << (idx % 32);
56
57 dump_di(whc, idx);
58
59 le_writel(bit, whc->base + WUSBDIBUPDATED + offset);
60
61 return whci_wait_for(&whc->umc->dev,
62 whc->base + WUSBDIBUPDATED + offset, bit, 0,
63 100, "DI update");
64}
65
66/*
67 * WHCI starts and stops MMCs based on there being a valid GTK so
68 * these need only start/stop the asynchronous and periodic schedules.
69 */
70
71int whc_wusbhc_start(struct wusbhc *wusbhc)
72{
73 struct whc *whc = wusbhc_to_whc(wusbhc);
74
75 asl_start(whc);
76 pzl_start(whc);
77
78 return 0;
79}
80
81void whc_wusbhc_stop(struct wusbhc *wusbhc)
82{
83 struct whc *whc = wusbhc_to_whc(wusbhc);
84
85 pzl_stop(whc);
86 asl_stop(whc);
87}
88
89int whc_mmcie_add(struct wusbhc *wusbhc, u8 interval, u8 repeat_cnt,
90 u8 handle, struct wuie_hdr *wuie)
91{
92 struct whc *whc = wusbhc_to_whc(wusbhc);
93 u32 params;
94
95 params = (interval << 24)
96 | (repeat_cnt << 16)
97 | (wuie->bLength << 8)
98 | handle;
99
100 return whc_do_gencmd(whc, WUSBGENCMDSTS_MMCIE_ADD, params, wuie, wuie->bLength);
101}
102
103int whc_mmcie_rm(struct wusbhc *wusbhc, u8 handle)
104{
105 struct whc *whc = wusbhc_to_whc(wusbhc);
106 u32 params;
107
108 params = handle;
109
110 return whc_do_gencmd(whc, WUSBGENCMDSTS_MMCIE_RM, params, NULL, 0);
111}
112
113int whc_bwa_set(struct wusbhc *wusbhc, s8 stream_index, const struct uwb_mas_bm *mas_bm)
114{
115 struct whc *whc = wusbhc_to_whc(wusbhc);
116
117 if (stream_index >= 0)
118 whc_write_wusbcmd(whc, WUSBCMD_WUSBSI_MASK, WUSBCMD_WUSBSI(stream_index));
119
120 return whc_do_gencmd(whc, WUSBGENCMDSTS_SET_MAS, 0, (void *)mas_bm, sizeof(*mas_bm));
121}
122
123int whc_dev_info_set(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
124{
125 struct whc *whc = wusbhc_to_whc(wusbhc);
126 int idx = wusb_dev->port_idx;
127 struct di_buf_entry *di = &whc->di_buf[idx];
128 int ret;
129
130 mutex_lock(&whc->mutex);
131
132 uwb_mas_bm_copy_le(di->availability_info, &wusb_dev->availability);
133 di->addr_sec_info &= ~(WHC_DI_DISABLE | WHC_DI_DEV_ADDR_MASK);
134 di->addr_sec_info |= WHC_DI_DEV_ADDR(wusb_dev->addr);
135
136 ret = whc_update_di(whc, idx);
137
138 mutex_unlock(&whc->mutex);
139
140 return ret;
141}
142
143/*
144 * Set the number of Device Notification Time Slots (DNTS) and enable
145 * device notifications.
146 */
147int whc_set_num_dnts(struct wusbhc *wusbhc, u8 interval, u8 slots)
148{
149 struct whc *whc = wusbhc_to_whc(wusbhc);
150 u32 dntsctrl;
151
152 dntsctrl = WUSBDNTSCTRL_ACTIVE
153 | WUSBDNTSCTRL_INTERVAL(interval)
154 | WUSBDNTSCTRL_SLOTS(slots);
155
156 le_writel(dntsctrl, whc->base + WUSBDNTSCTRL);
157
158 return 0;
159}
160
161static int whc_set_key(struct whc *whc, u8 key_index, uint32_t tkid,
162 const void *key, size_t key_size, bool is_gtk)
163{
164 uint32_t setkeycmd;
165 uint32_t seckey[4];
166 int i;
167 int ret;
168
169 memcpy(seckey, key, key_size);
170 setkeycmd = WUSBSETSECKEYCMD_SET | WUSBSETSECKEYCMD_IDX(key_index);
171 if (is_gtk)
172 setkeycmd |= WUSBSETSECKEYCMD_GTK;
173
174 le_writel(tkid, whc->base + WUSBTKID);
175 for (i = 0; i < 4; i++)
176 le_writel(seckey[i], whc->base + WUSBSECKEY + 4*i);
177 le_writel(setkeycmd, whc->base + WUSBSETSECKEYCMD);
178
179 ret = whci_wait_for(&whc->umc->dev, whc->base + WUSBSETSECKEYCMD,
180 WUSBSETSECKEYCMD_SET, 0, 100, "set key");
181
182 return ret;
183}
184
185/**
186 * whc_set_ptk - set the PTK to use for a device.
187 *
188 * The index into the key table for this PTK is the same as the
189 * device's port index.
190 */
191int whc_set_ptk(struct wusbhc *wusbhc, u8 port_idx, u32 tkid,
192 const void *ptk, size_t key_size)
193{
194 struct whc *whc = wusbhc_to_whc(wusbhc);
195 struct di_buf_entry *di = &whc->di_buf[port_idx];
196 int ret;
197
198 mutex_lock(&whc->mutex);
199
200 if (ptk) {
201 ret = whc_set_key(whc, port_idx, tkid, ptk, key_size, false);
202 if (ret)
203 goto out;
204
205 di->addr_sec_info &= ~WHC_DI_KEY_IDX_MASK;
206 di->addr_sec_info |= WHC_DI_SECURE | WHC_DI_KEY_IDX(port_idx);
207 } else
208 di->addr_sec_info &= ~WHC_DI_SECURE;
209
210 ret = whc_update_di(whc, port_idx);
211out:
212 mutex_unlock(&whc->mutex);
213 return ret;
214}
215
216/**
217 * whc_set_gtk - set the GTK for subsequent broadcast packets
218 *
219 * The GTK is stored in the last entry in the key table (the previous
220 * N_DEVICES entries are for the per-device PTKs).
221 */
222int whc_set_gtk(struct wusbhc *wusbhc, u32 tkid,
223 const void *gtk, size_t key_size)
224{
225 struct whc *whc = wusbhc_to_whc(wusbhc);
226 int ret;
227
228 mutex_lock(&whc->mutex);
229
230 ret = whc_set_key(whc, whc->n_devices, tkid, gtk, key_size, true);
231
232 mutex_unlock(&whc->mutex);
233
234 return ret;
235}
236
237int whc_set_cluster_id(struct whc *whc, u8 bcid)
238{
239 whc_write_wusbcmd(whc, WUSBCMD_BCID_MASK, WUSBCMD_BCID(bcid));
240 return 0;
241}
diff --git a/drivers/usb/wusbcore/Kconfig b/drivers/usb/wusbcore/Kconfig
new file mode 100644
index 000000000000..eb09a0a14a80
--- /dev/null
+++ b/drivers/usb/wusbcore/Kconfig
@@ -0,0 +1,41 @@
1#
2# Wireless USB Core configuration
3#
4config USB_WUSB
5 tristate "Enable Wireless USB extensions (EXPERIMENTAL)"
6 depends on EXPERIMENTAL
7 depends on USB
8 select UWB
9 select CRYPTO
10 select CRYPTO_BLKCIPHER
11 select CRYPTO_CBC
12 select CRYPTO_MANAGER
13 select CRYPTO_AES
14 help
15 Enable the host-side support for Wireless USB.
16
17 To compile this support select Y (built in). It is safe to
18 select even if you don't have the hardware.
19
20config USB_WUSB_CBAF
21 tristate "Support WUSB Cable Based Association (CBA)"
22 depends on USB
23 help
24 Some WUSB devices support Cable Based Association. It's used to
25 enable the secure communication between the host and the
26 device.
27
28 Enable this option if your WUSB device must to be connected
29 via wired USB before establishing a wireless link.
30
31 It is safe to select even if you don't have a compatible
32 hardware.
33
34config USB_WUSB_CBAF_DEBUG
35 bool "Enable CBA debug messages"
36 depends on USB_WUSB_CBAF
37 help
38 Say Y here if you want the CBA to produce a bunch of debug messages
39 to the system log. Select this if you are having a problem with
40 CBA support and want to see more of what is going on.
41
diff --git a/drivers/usb/wusbcore/Makefile b/drivers/usb/wusbcore/Makefile
new file mode 100644
index 000000000000..75f1ade66258
--- /dev/null
+++ b/drivers/usb/wusbcore/Makefile
@@ -0,0 +1,26 @@
1obj-$(CONFIG_USB_WUSB) += wusbcore.o
2obj-$(CONFIG_USB_HWA_HCD) += wusb-wa.o
3obj-$(CONFIG_USB_WUSB_CBAF) += wusb-cbaf.o
4
5
6wusbcore-objs := \
7 crypto.o \
8 devconnect.o \
9 dev-sysfs.o \
10 mmc.o \
11 pal.o \
12 rh.o \
13 reservation.o \
14 security.o \
15 wusbhc.o
16
17wusb-cbaf-objs := cbaf.o
18
19wusb-wa-objs := wa-hc.o \
20 wa-nep.o \
21 wa-rpipe.o \
22 wa-xfer.o
23
24ifeq ($(CONFIG_USB_WUSB_CBAF_DEBUG),y)
25EXTRA_CFLAGS += -DDEBUG
26endif
diff --git a/drivers/usb/wusbcore/cbaf.c b/drivers/usb/wusbcore/cbaf.c
new file mode 100644
index 000000000000..ab4788d1785a
--- /dev/null
+++ b/drivers/usb/wusbcore/cbaf.c
@@ -0,0 +1,673 @@
1/*
2 * Wireless USB - Cable Based Association
3 *
4 *
5 * Copyright (C) 2006 Intel Corporation
6 * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
7 * Copyright (C) 2008 Cambridge Silicon Radio Ltd.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License version
11 * 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301, USA.
22 *
23 *
24 * WUSB devices have to be paired (associated in WUSB lingo) so
25 * that they can connect to the system.
26 *
27 * One way of pairing is using CBA-Cable Based Association. First
28 * time you plug the device with a cable, association is done between
29 * host and device and subsequent times, you can connect wirelessly
30 * without having to associate again. That's the idea.
31 *
32 * This driver does nothing Earth shattering. It just provides an
33 * interface to chat with the wire-connected device so we can get a
34 * CDID (device ID) that might have been previously associated to a
35 * CHID (host ID) and to set up a new <CHID,CDID,CK> triplet
36 * (connection context), with the CK being the secret, or connection
37 * key. This is the pairing data.
38 *
39 * When a device with the CBA capability connects, the probe routine
40 * just creates a bunch of sysfs files that a user space enumeration
41 * manager uses to allow it to connect wirelessly to the system or not.
42 *
43 * The process goes like this:
44 *
45 * 1. Device plugs, cbaf is loaded, notifications happen.
46 *
47 * 2. The connection manager (CM) sees a device with CBAF capability
48 * (the wusb_chid etc. files in /sys/devices/blah/OURDEVICE).
49 *
50 * 3. The CM writes the host name, supported band groups, and the CHID
51 * (host ID) into the wusb_host_name, wusb_host_band_groups and
52 * wusb_chid files. These get sent to the device and the CDID (if
53 * any) for this host is requested.
54 *
55 * 4. The CM can verify that the device's supported band groups
56 * (wusb_device_band_groups) are compatible with the host.
57 *
58 * 5. The CM reads the wusb_cdid file.
59 *
60 * 6. The CM looks up its database
61 *
62 * 6.1 If it has a matching CHID,CDID entry, the device has been
63 * authorized before (paired) and nothing further needs to be
64 * done.
65 *
66 * 6.2 If the CDID is zero (or the CM doesn't find a matching CDID in
67 * its database), the device is assumed to be not known. The CM
68 * may associate the host with device by: writing a randomly
69 * generated CDID to wusb_cdid and then a random CK to wusb_ck
70 * (this uploads the new CC to the device).
71 *
72 * CMD may choose to prompt the user before associating with a new
73 * device.
74 *
75 * 7. Device is unplugged.
76 *
77 * When the device tries to connect wirelessly, it will present its
78 * CDID to the WUSB host controller. The CM will query the
79 * database. If the CHID/CDID pair found, it will (with a 4-way
80 * handshake) challenge the device to demonstrate it has the CK secret
81 * key (from our database) without actually exchanging it. Once
82 * satisfied, crypto keys are derived from the CK, the device is
83 * connected and all communication is encrypted.
84 *
85 * References:
86 * [WUSB-AM] Association Models Supplement to the Certified Wireless
87 * Universal Serial Bus Specification, version 1.0.
88 */
89#include <linux/module.h>
90#include <linux/ctype.h>
91#include <linux/version.h>
92#include <linux/usb.h>
93#include <linux/interrupt.h>
94#include <linux/delay.h>
95#include <linux/random.h>
96#include <linux/mutex.h>
97#include <linux/uwb.h>
98#include <linux/usb/wusb.h>
99#include <linux/usb/association.h>
100
101#define CBA_NAME_LEN 0x40 /* [WUSB-AM] table 4-7 */
102
103/* An instance of a Cable-Based-Association-Framework device */
104struct cbaf {
105 struct usb_device *usb_dev;
106 struct usb_interface *usb_iface;
107 void *buffer;
108 size_t buffer_size;
109
110 struct wusb_ckhdid chid;
111 char host_name[CBA_NAME_LEN];
112 u16 host_band_groups;
113
114 struct wusb_ckhdid cdid;
115 char device_name[CBA_NAME_LEN];
116 u16 device_band_groups;
117
118 struct wusb_ckhdid ck;
119};
120
121/*
122 * Verify that a CBAF USB-interface has what we need
123 *
124 * According to [WUSB-AM], CBA devices should provide at least two
125 * interfaces:
126 * - RETRIEVE_HOST_INFO
127 * - ASSOCIATE
128 *
129 * If the device doesn't provide these interfaces, we do not know how
130 * to deal with it.
131 */
132static int cbaf_check(struct cbaf *cbaf)
133{
134 int result;
135 struct device *dev = &cbaf->usb_iface->dev;
136 struct wusb_cbaf_assoc_info *assoc_info;
137 struct wusb_cbaf_assoc_request *assoc_request;
138 size_t assoc_size;
139 void *itr, *top;
140 int ar_rhi = 0, ar_assoc = 0;
141
142 result = usb_control_msg(
143 cbaf->usb_dev, usb_rcvctrlpipe(cbaf->usb_dev, 0),
144 CBAF_REQ_GET_ASSOCIATION_INFORMATION,
145 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
146 0, cbaf->usb_iface->cur_altsetting->desc.bInterfaceNumber,
147 cbaf->buffer, cbaf->buffer_size, 1000 /* FIXME: arbitrary */);
148 if (result < 0) {
149 dev_err(dev, "Cannot get available association types: %d\n",
150 result);
151 return result;
152 }
153
154 assoc_info = cbaf->buffer;
155 if (result < sizeof(*assoc_info)) {
156 dev_err(dev, "Not enough data to decode association info "
157 "header (%zu vs %zu bytes required)\n",
158 (size_t)result, sizeof(*assoc_info));
159 return result;
160 }
161
162 assoc_size = le16_to_cpu(assoc_info->Length);
163 if (result < assoc_size) {
164 dev_err(dev, "Not enough data to decode association info "
165 "(%zu vs %zu bytes required)\n",
166 (size_t)assoc_size, sizeof(*assoc_info));
167 return result;
168 }
169 /*
170 * From now on, we just verify, but won't error out unless we
171 * don't find the AR_TYPE_WUSB_{RETRIEVE_HOST_INFO,ASSOCIATE}
172 * types.
173 */
174 itr = cbaf->buffer + sizeof(*assoc_info);
175 top = cbaf->buffer + assoc_size;
176 dev_dbg(dev, "Found %u association requests (%zu bytes)\n",
177 assoc_info->NumAssociationRequests, assoc_size);
178
179 while (itr < top) {
180 u16 ar_type, ar_subtype;
181 u32 ar_size;
182 const char *ar_name;
183
184 assoc_request = itr;
185
186 if (top - itr < sizeof(*assoc_request)) {
187 dev_err(dev, "Not enough data to decode associaton "
188 "request (%zu vs %zu bytes needed)\n",
189 top - itr, sizeof(*assoc_request));
190 break;
191 }
192
193 ar_type = le16_to_cpu(assoc_request->AssociationTypeId);
194 ar_subtype = le16_to_cpu(assoc_request->AssociationSubTypeId);
195 ar_size = le32_to_cpu(assoc_request->AssociationTypeInfoSize);
196 ar_name = "unknown";
197
198 switch (ar_type) {
199 case AR_TYPE_WUSB:
200 /* Verify we have what is mandated by [WUSB-AM]. */
201 switch (ar_subtype) {
202 case AR_TYPE_WUSB_RETRIEVE_HOST_INFO:
203 ar_name = "RETRIEVE_HOST_INFO";
204 ar_rhi = 1;
205 break;
206 case AR_TYPE_WUSB_ASSOCIATE:
207 /* send assoc data */
208 ar_name = "ASSOCIATE";
209 ar_assoc = 1;
210 break;
211 };
212 break;
213 };
214
215 dev_dbg(dev, "Association request #%02u: 0x%04x/%04x "
216 "(%zu bytes): %s\n",
217 assoc_request->AssociationDataIndex, ar_type,
218 ar_subtype, (size_t)ar_size, ar_name);
219
220 itr += sizeof(*assoc_request);
221 }
222
223 if (!ar_rhi) {
224 dev_err(dev, "Missing RETRIEVE_HOST_INFO association "
225 "request\n");
226 return -EINVAL;
227 }
228 if (!ar_assoc) {
229 dev_err(dev, "Missing ASSOCIATE association request\n");
230 return -EINVAL;
231 }
232
233 return 0;
234}
235
236static const struct wusb_cbaf_host_info cbaf_host_info_defaults = {
237 .AssociationTypeId_hdr = WUSB_AR_AssociationTypeId,
238 .AssociationTypeId = cpu_to_le16(AR_TYPE_WUSB),
239 .AssociationSubTypeId_hdr = WUSB_AR_AssociationSubTypeId,
240 .AssociationSubTypeId = cpu_to_le16(AR_TYPE_WUSB_RETRIEVE_HOST_INFO),
241 .CHID_hdr = WUSB_AR_CHID,
242 .LangID_hdr = WUSB_AR_LangID,
243 .HostFriendlyName_hdr = WUSB_AR_HostFriendlyName,
244};
245
246/* Send WUSB host information (CHID and name) to a CBAF device */
247static int cbaf_send_host_info(struct cbaf *cbaf)
248{
249 struct wusb_cbaf_host_info *hi;
250 size_t name_len;
251 size_t hi_size;
252
253 hi = cbaf->buffer;
254 memset(hi, 0, sizeof(*hi));
255 *hi = cbaf_host_info_defaults;
256 hi->CHID = cbaf->chid;
257 hi->LangID = 0; /* FIXME: I guess... */
258 strlcpy(hi->HostFriendlyName, cbaf->host_name, CBA_NAME_LEN);
259 name_len = strlen(cbaf->host_name);
260 hi->HostFriendlyName_hdr.len = cpu_to_le16(name_len);
261 hi_size = sizeof(*hi) + name_len;
262
263 return usb_control_msg(cbaf->usb_dev, usb_sndctrlpipe(cbaf->usb_dev, 0),
264 CBAF_REQ_SET_ASSOCIATION_RESPONSE,
265 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
266 0x0101,
267 cbaf->usb_iface->cur_altsetting->desc.bInterfaceNumber,
268 hi, hi_size, 1000 /* FIXME: arbitrary */);
269}
270
271/*
272 * Get device's information (CDID) associated to CHID
273 *
274 * The device will return it's information (CDID, name, bandgroups)
275 * associated to the CHID we have set before, or 0 CDID and default
276 * name and bandgroup if no CHID set or unknown.
277 */
278static int cbaf_cdid_get(struct cbaf *cbaf)
279{
280 int result;
281 struct device *dev = &cbaf->usb_iface->dev;
282 struct wusb_cbaf_device_info *di;
283 size_t needed;
284
285 di = cbaf->buffer;
286 result = usb_control_msg(
287 cbaf->usb_dev, usb_rcvctrlpipe(cbaf->usb_dev, 0),
288 CBAF_REQ_GET_ASSOCIATION_REQUEST,
289 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
290 0x0200, cbaf->usb_iface->cur_altsetting->desc.bInterfaceNumber,
291 di, cbaf->buffer_size, 1000 /* FIXME: arbitrary */);
292 if (result < 0) {
293 dev_err(dev, "Cannot request device information: %d\n", result);
294 return result;
295 }
296
297 needed = result < sizeof(*di) ? sizeof(*di) : le32_to_cpu(di->Length);
298 if (result < needed) {
299 dev_err(dev, "Not enough data in DEVICE_INFO reply (%zu vs "
300 "%zu bytes needed)\n", (size_t)result, needed);
301 return result;
302 }
303
304 strlcpy(cbaf->device_name, di->DeviceFriendlyName, CBA_NAME_LEN);
305 cbaf->cdid = di->CDID;
306 cbaf->device_band_groups = le16_to_cpu(di->BandGroups);
307
308 return 0;
309}
310
311static ssize_t cbaf_wusb_chid_show(struct device *dev,
312 struct device_attribute *attr,
313 char *buf)
314{
315 struct usb_interface *iface = to_usb_interface(dev);
316 struct cbaf *cbaf = usb_get_intfdata(iface);
317 char pr_chid[WUSB_CKHDID_STRSIZE];
318
319 ckhdid_printf(pr_chid, sizeof(pr_chid), &cbaf->chid);
320 return scnprintf(buf, PAGE_SIZE, "%s\n", pr_chid);
321}
322
323static ssize_t cbaf_wusb_chid_store(struct device *dev,
324 struct device_attribute *attr,
325 const char *buf, size_t size)
326{
327 ssize_t result;
328 struct usb_interface *iface = to_usb_interface(dev);
329 struct cbaf *cbaf = usb_get_intfdata(iface);
330
331 result = sscanf(buf,
332 "%02hhx %02hhx %02hhx %02hhx "
333 "%02hhx %02hhx %02hhx %02hhx "
334 "%02hhx %02hhx %02hhx %02hhx "
335 "%02hhx %02hhx %02hhx %02hhx",
336 &cbaf->chid.data[0] , &cbaf->chid.data[1],
337 &cbaf->chid.data[2] , &cbaf->chid.data[3],
338 &cbaf->chid.data[4] , &cbaf->chid.data[5],
339 &cbaf->chid.data[6] , &cbaf->chid.data[7],
340 &cbaf->chid.data[8] , &cbaf->chid.data[9],
341 &cbaf->chid.data[10], &cbaf->chid.data[11],
342 &cbaf->chid.data[12], &cbaf->chid.data[13],
343 &cbaf->chid.data[14], &cbaf->chid.data[15]);
344
345 if (result != 16)
346 return -EINVAL;
347
348 result = cbaf_send_host_info(cbaf);
349 if (result < 0)
350 return result;
351 result = cbaf_cdid_get(cbaf);
352 if (result < 0)
353 return -result;
354 return size;
355}
356static DEVICE_ATTR(wusb_chid, 0600, cbaf_wusb_chid_show, cbaf_wusb_chid_store);
357
358static ssize_t cbaf_wusb_host_name_show(struct device *dev,
359 struct device_attribute *attr,
360 char *buf)
361{
362 struct usb_interface *iface = to_usb_interface(dev);
363 struct cbaf *cbaf = usb_get_intfdata(iface);
364
365 return scnprintf(buf, PAGE_SIZE, "%s\n", cbaf->host_name);
366}
367
368static ssize_t cbaf_wusb_host_name_store(struct device *dev,
369 struct device_attribute *attr,
370 const char *buf, size_t size)
371{
372 ssize_t result;
373 struct usb_interface *iface = to_usb_interface(dev);
374 struct cbaf *cbaf = usb_get_intfdata(iface);
375
376 result = sscanf(buf, "%63s", cbaf->host_name);
377 if (result != 1)
378 return -EINVAL;
379
380 return size;
381}
382static DEVICE_ATTR(wusb_host_name, 0600, cbaf_wusb_host_name_show,
383 cbaf_wusb_host_name_store);
384
385static ssize_t cbaf_wusb_host_band_groups_show(struct device *dev,
386 struct device_attribute *attr,
387 char *buf)
388{
389 struct usb_interface *iface = to_usb_interface(dev);
390 struct cbaf *cbaf = usb_get_intfdata(iface);
391
392 return scnprintf(buf, PAGE_SIZE, "0x%04x\n", cbaf->host_band_groups);
393}
394
395static ssize_t cbaf_wusb_host_band_groups_store(struct device *dev,
396 struct device_attribute *attr,
397 const char *buf, size_t size)
398{
399 ssize_t result;
400 struct usb_interface *iface = to_usb_interface(dev);
401 struct cbaf *cbaf = usb_get_intfdata(iface);
402 u16 band_groups = 0;
403
404 result = sscanf(buf, "%04hx", &band_groups);
405 if (result != 1)
406 return -EINVAL;
407
408 cbaf->host_band_groups = band_groups;
409
410 return size;
411}
412
413static DEVICE_ATTR(wusb_host_band_groups, 0600,
414 cbaf_wusb_host_band_groups_show,
415 cbaf_wusb_host_band_groups_store);
416
417static const struct wusb_cbaf_device_info cbaf_device_info_defaults = {
418 .Length_hdr = WUSB_AR_Length,
419 .CDID_hdr = WUSB_AR_CDID,
420 .BandGroups_hdr = WUSB_AR_BandGroups,
421 .LangID_hdr = WUSB_AR_LangID,
422 .DeviceFriendlyName_hdr = WUSB_AR_DeviceFriendlyName,
423};
424
425static ssize_t cbaf_wusb_cdid_show(struct device *dev,
426 struct device_attribute *attr, char *buf)
427{
428 struct usb_interface *iface = to_usb_interface(dev);
429 struct cbaf *cbaf = usb_get_intfdata(iface);
430 char pr_cdid[WUSB_CKHDID_STRSIZE];
431
432 ckhdid_printf(pr_cdid, sizeof(pr_cdid), &cbaf->cdid);
433 return scnprintf(buf, PAGE_SIZE, "%s\n", pr_cdid);
434}
435
436static ssize_t cbaf_wusb_cdid_store(struct device *dev,
437 struct device_attribute *attr,
438 const char *buf, size_t size)
439{
440 ssize_t result;
441 struct usb_interface *iface = to_usb_interface(dev);
442 struct cbaf *cbaf = usb_get_intfdata(iface);
443 struct wusb_ckhdid cdid;
444
445 result = sscanf(buf,
446 "%02hhx %02hhx %02hhx %02hhx "
447 "%02hhx %02hhx %02hhx %02hhx "
448 "%02hhx %02hhx %02hhx %02hhx "
449 "%02hhx %02hhx %02hhx %02hhx",
450 &cdid.data[0] , &cdid.data[1],
451 &cdid.data[2] , &cdid.data[3],
452 &cdid.data[4] , &cdid.data[5],
453 &cdid.data[6] , &cdid.data[7],
454 &cdid.data[8] , &cdid.data[9],
455 &cdid.data[10], &cdid.data[11],
456 &cdid.data[12], &cdid.data[13],
457 &cdid.data[14], &cdid.data[15]);
458 if (result != 16)
459 return -EINVAL;
460
461 cbaf->cdid = cdid;
462
463 return size;
464}
465static DEVICE_ATTR(wusb_cdid, 0600, cbaf_wusb_cdid_show, cbaf_wusb_cdid_store);
466
467static ssize_t cbaf_wusb_device_band_groups_show(struct device *dev,
468 struct device_attribute *attr,
469 char *buf)
470{
471 struct usb_interface *iface = to_usb_interface(dev);
472 struct cbaf *cbaf = usb_get_intfdata(iface);
473
474 return scnprintf(buf, PAGE_SIZE, "0x%04x\n", cbaf->device_band_groups);
475}
476
477static DEVICE_ATTR(wusb_device_band_groups, 0600,
478 cbaf_wusb_device_band_groups_show,
479 NULL);
480
481static ssize_t cbaf_wusb_device_name_show(struct device *dev,
482 struct device_attribute *attr,
483 char *buf)
484{
485 struct usb_interface *iface = to_usb_interface(dev);
486 struct cbaf *cbaf = usb_get_intfdata(iface);
487
488 return scnprintf(buf, PAGE_SIZE, "%s\n", cbaf->device_name);
489}
490static DEVICE_ATTR(wusb_device_name, 0600, cbaf_wusb_device_name_show, NULL);
491
492static const struct wusb_cbaf_cc_data cbaf_cc_data_defaults = {
493 .AssociationTypeId_hdr = WUSB_AR_AssociationTypeId,
494 .AssociationTypeId = cpu_to_le16(AR_TYPE_WUSB),
495 .AssociationSubTypeId_hdr = WUSB_AR_AssociationSubTypeId,
496 .AssociationSubTypeId = cpu_to_le16(AR_TYPE_WUSB_ASSOCIATE),
497 .Length_hdr = WUSB_AR_Length,
498 .Length = cpu_to_le32(sizeof(struct wusb_cbaf_cc_data)),
499 .ConnectionContext_hdr = WUSB_AR_ConnectionContext,
500 .BandGroups_hdr = WUSB_AR_BandGroups,
501};
502
503static const struct wusb_cbaf_cc_data_fail cbaf_cc_data_fail_defaults = {
504 .AssociationTypeId_hdr = WUSB_AR_AssociationTypeId,
505 .AssociationSubTypeId_hdr = WUSB_AR_AssociationSubTypeId,
506 .Length_hdr = WUSB_AR_Length,
507 .AssociationStatus_hdr = WUSB_AR_AssociationStatus,
508};
509
510/*
511 * Send a new CC to the device.
512 */
513static int cbaf_cc_upload(struct cbaf *cbaf)
514{
515 int result;
516 struct device *dev = &cbaf->usb_iface->dev;
517 struct wusb_cbaf_cc_data *ccd;
518 char pr_cdid[WUSB_CKHDID_STRSIZE];
519
520 ccd = cbaf->buffer;
521 *ccd = cbaf_cc_data_defaults;
522 ccd->CHID = cbaf->chid;
523 ccd->CDID = cbaf->cdid;
524 ccd->CK = cbaf->ck;
525 ccd->BandGroups = cpu_to_le16(cbaf->host_band_groups);
526
527 dev_dbg(dev, "Trying to upload CC:\n");
528 ckhdid_printf(pr_cdid, sizeof(pr_cdid), &ccd->CHID);
529 dev_dbg(dev, " CHID %s\n", pr_cdid);
530 ckhdid_printf(pr_cdid, sizeof(pr_cdid), &ccd->CDID);
531 dev_dbg(dev, " CDID %s\n", pr_cdid);
532 dev_dbg(dev, " Bandgroups 0x%04x\n", cbaf->host_band_groups);
533
534 result = usb_control_msg(
535 cbaf->usb_dev, usb_sndctrlpipe(cbaf->usb_dev, 0),
536 CBAF_REQ_SET_ASSOCIATION_RESPONSE,
537 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
538 0x0201, cbaf->usb_iface->cur_altsetting->desc.bInterfaceNumber,
539 ccd, sizeof(*ccd), 1000 /* FIXME: arbitrary */);
540
541 return result;
542}
543
544static ssize_t cbaf_wusb_ck_store(struct device *dev,
545 struct device_attribute *attr,
546 const char *buf, size_t size)
547{
548 ssize_t result;
549 struct usb_interface *iface = to_usb_interface(dev);
550 struct cbaf *cbaf = usb_get_intfdata(iface);
551
552 result = sscanf(buf,
553 "%02hhx %02hhx %02hhx %02hhx "
554 "%02hhx %02hhx %02hhx %02hhx "
555 "%02hhx %02hhx %02hhx %02hhx "
556 "%02hhx %02hhx %02hhx %02hhx",
557 &cbaf->ck.data[0] , &cbaf->ck.data[1],
558 &cbaf->ck.data[2] , &cbaf->ck.data[3],
559 &cbaf->ck.data[4] , &cbaf->ck.data[5],
560 &cbaf->ck.data[6] , &cbaf->ck.data[7],
561 &cbaf->ck.data[8] , &cbaf->ck.data[9],
562 &cbaf->ck.data[10], &cbaf->ck.data[11],
563 &cbaf->ck.data[12], &cbaf->ck.data[13],
564 &cbaf->ck.data[14], &cbaf->ck.data[15]);
565 if (result != 16)
566 return -EINVAL;
567
568 result = cbaf_cc_upload(cbaf);
569 if (result < 0)
570 return result;
571
572 return size;
573}
574static DEVICE_ATTR(wusb_ck, 0600, NULL, cbaf_wusb_ck_store);
575
576static struct attribute *cbaf_dev_attrs[] = {
577 &dev_attr_wusb_host_name.attr,
578 &dev_attr_wusb_host_band_groups.attr,
579 &dev_attr_wusb_chid.attr,
580 &dev_attr_wusb_cdid.attr,
581 &dev_attr_wusb_device_name.attr,
582 &dev_attr_wusb_device_band_groups.attr,
583 &dev_attr_wusb_ck.attr,
584 NULL,
585};
586
587static struct attribute_group cbaf_dev_attr_group = {
588 .name = NULL, /* we want them in the same directory */
589 .attrs = cbaf_dev_attrs,
590};
591
592static int cbaf_probe(struct usb_interface *iface,
593 const struct usb_device_id *id)
594{
595 struct cbaf *cbaf;
596 struct device *dev = &iface->dev;
597 int result = -ENOMEM;
598
599 cbaf = kzalloc(sizeof(*cbaf), GFP_KERNEL);
600 if (cbaf == NULL)
601 goto error_kzalloc;
602 cbaf->buffer = kmalloc(512, GFP_KERNEL);
603 if (cbaf->buffer == NULL)
604 goto error_kmalloc_buffer;
605
606 cbaf->buffer_size = 512;
607 cbaf->usb_dev = usb_get_dev(interface_to_usbdev(iface));
608 cbaf->usb_iface = usb_get_intf(iface);
609 result = cbaf_check(cbaf);
610 if (result < 0) {
611 dev_err(dev, "This device is not WUSB-CBAF compliant"
612 "and is not supported yet.\n");
613 goto error_check;
614 }
615
616 result = sysfs_create_group(&dev->kobj, &cbaf_dev_attr_group);
617 if (result < 0) {
618 dev_err(dev, "Can't register sysfs attr group: %d\n", result);
619 goto error_create_group;
620 }
621 usb_set_intfdata(iface, cbaf);
622 return 0;
623
624error_create_group:
625error_check:
626 kfree(cbaf->buffer);
627error_kmalloc_buffer:
628 kfree(cbaf);
629error_kzalloc:
630 return result;
631}
632
633static void cbaf_disconnect(struct usb_interface *iface)
634{
635 struct cbaf *cbaf = usb_get_intfdata(iface);
636 struct device *dev = &iface->dev;
637 sysfs_remove_group(&dev->kobj, &cbaf_dev_attr_group);
638 usb_set_intfdata(iface, NULL);
639 usb_put_intf(iface);
640 kfree(cbaf->buffer);
641 /* paranoia: clean up crypto keys */
642 memset(cbaf, 0, sizeof(*cbaf));
643 kfree(cbaf);
644}
645
646static struct usb_device_id cbaf_id_table[] = {
647 { USB_INTERFACE_INFO(0xef, 0x03, 0x01), },
648 { },
649};
650MODULE_DEVICE_TABLE(usb, cbaf_id_table);
651
652static struct usb_driver cbaf_driver = {
653 .name = "wusb-cbaf",
654 .id_table = cbaf_id_table,
655 .probe = cbaf_probe,
656 .disconnect = cbaf_disconnect,
657};
658
659static int __init cbaf_driver_init(void)
660{
661 return usb_register(&cbaf_driver);
662}
663module_init(cbaf_driver_init);
664
665static void __exit cbaf_driver_exit(void)
666{
667 usb_deregister(&cbaf_driver);
668}
669module_exit(cbaf_driver_exit);
670
671MODULE_AUTHOR("Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>");
672MODULE_DESCRIPTION("Wireless USB Cable Based Association");
673MODULE_LICENSE("GPL");
diff --git a/drivers/usb/wusbcore/crypto.c b/drivers/usb/wusbcore/crypto.c
new file mode 100644
index 000000000000..c36c4389baae
--- /dev/null
+++ b/drivers/usb/wusbcore/crypto.c
@@ -0,0 +1,538 @@
1/*
2 * Ultra Wide Band
3 * AES-128 CCM Encryption
4 *
5 * Copyright (C) 2007 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 * We don't do any encryption here; we use the Linux Kernel's AES-128
24 * crypto modules to construct keys and payload blocks in a way
25 * defined by WUSB1.0[6]. Check the erratas, as typos are are patched
26 * there.
27 *
28 * Thanks a zillion to John Keys for his help and clarifications over
29 * the designed-by-a-committee text.
30 *
31 * So the idea is that there is this basic Pseudo-Random-Function
32 * defined in WUSB1.0[6.5] which is the core of everything. It works
33 * by tweaking some blocks, AES crypting them and then xoring
34 * something else with them (this seems to be called CBC(AES) -- can
35 * you tell I know jack about crypto?). So we just funnel it into the
36 * Linux Crypto API.
37 *
38 * We leave a crypto test module so we can verify that vectors match,
39 * every now and then.
40 *
41 * Block size: 16 bytes -- AES seems to do things in 'block sizes'. I
42 * am learning a lot...
43 *
44 * Conveniently, some data structures that need to be
45 * funneled through AES are...16 bytes in size!
46 */
47
48#include <linux/crypto.h>
49#include <linux/module.h>
50#include <linux/err.h>
51#include <linux/uwb.h>
52#include <linux/usb/wusb.h>
53#include <linux/scatterlist.h>
54#define D_LOCAL 0
55#include <linux/uwb/debug.h>
56
57
58/*
59 * Block of data, as understood by AES-CCM
60 *
61 * The code assumes this structure is nothing but a 16 byte array
62 * (packed in a struct to avoid common mess ups that I usually do with
63 * arrays and enforcing type checking).
64 */
65struct aes_ccm_block {
66 u8 data[16];
67} __attribute__((packed));
68
69/*
70 * Counter-mode Blocks (WUSB1.0[6.4])
71 *
72 * According to CCM (or so it seems), for the purpose of calculating
73 * the MIC, the message is broken in N counter-mode blocks, B0, B1,
74 * ... BN.
75 *
76 * B0 contains flags, the CCM nonce and l(m).
77 *
78 * B1 contains l(a), the MAC header, the encryption offset and padding.
79 *
80 * If EO is nonzero, additional blocks are built from payload bytes
81 * until EO is exahusted (FIXME: padding to 16 bytes, I guess). The
82 * padding is not xmitted.
83 */
84
85/* WUSB1.0[T6.4] */
86struct aes_ccm_b0 {
87 u8 flags; /* 0x59, per CCM spec */
88 struct aes_ccm_nonce ccm_nonce;
89 __be16 lm;
90} __attribute__((packed));
91
92/* WUSB1.0[T6.5] */
93struct aes_ccm_b1 {
94 __be16 la;
95 u8 mac_header[10];
96 __le16 eo;
97 u8 security_reserved; /* This is always zero */
98 u8 padding; /* 0 */
99} __attribute__((packed));
100
101/*
102 * Encryption Blocks (WUSB1.0[6.4.4])
103 *
104 * CCM uses Ax blocks to generate a keystream with which the MIC and
105 * the message's payload are encoded. A0 always encrypts/decrypts the
106 * MIC. Ax (x>0) are used for the sucesive payload blocks.
107 *
108 * The x is the counter, and is increased for each block.
109 */
110struct aes_ccm_a {
111 u8 flags; /* 0x01, per CCM spec */
112 struct aes_ccm_nonce ccm_nonce;
113 __be16 counter; /* Value of x */
114} __attribute__((packed));
115
116static void bytewise_xor(void *_bo, const void *_bi1, const void *_bi2,
117 size_t size)
118{
119 u8 *bo = _bo;
120 const u8 *bi1 = _bi1, *bi2 = _bi2;
121 size_t itr;
122 for (itr = 0; itr < size; itr++)
123 bo[itr] = bi1[itr] ^ bi2[itr];
124}
125
126/*
127 * CC-MAC function WUSB1.0[6.5]
128 *
129 * Take a data string and produce the encrypted CBC Counter-mode MIC
130 *
131 * Note the names for most function arguments are made to (more or
132 * less) match those used in the pseudo-function definition given in
133 * WUSB1.0[6.5].
134 *
135 * @tfm_cbc: CBC(AES) blkcipher handle (initialized)
136 *
137 * @tfm_aes: AES cipher handle (initialized)
138 *
139 * @mic: buffer for placing the computed MIC (Message Integrity
140 * Code). This is exactly 8 bytes, and we expect the buffer to
141 * be at least eight bytes in length.
142 *
143 * @key: 128 bit symmetric key
144 *
145 * @n: CCM nonce
146 *
147 * @a: ASCII string, 14 bytes long (I guess zero padded if needed;
148 * we use exactly 14 bytes).
149 *
150 * @b: data stream to be processed; cannot be a global or const local
151 * (will confuse the scatterlists)
152 *
153 * @blen: size of b...
154 *
155 * Still not very clear how this is done, but looks like this: we
156 * create block B0 (as WUSB1.0[6.5] says), then we AES-crypt it with
157 * @key. We bytewise xor B0 with B1 (1) and AES-crypt that. Then we
158 * take the payload and divide it in blocks (16 bytes), xor them with
159 * the previous crypto result (16 bytes) and crypt it, repeat the next
160 * block with the output of the previous one, rinse wash (I guess this
161 * is what AES CBC mode means...but I truly have no idea). So we use
162 * the CBC(AES) blkcipher, that does precisely that. The IV (Initial
163 * Vector) is 16 bytes and is set to zero, so
164 *
165 * See rfc3610. Linux crypto has a CBC implementation, but the
166 * documentation is scarce, to say the least, and the example code is
167 * so intricated that is difficult to understand how things work. Most
168 * of this is guess work -- bite me.
169 *
170 * (1) Created as 6.5 says, again, using as l(a) 'Blen + 14', and
171 * using the 14 bytes of @a to fill up
172 * b1.{mac_header,e0,security_reserved,padding}.
173 *
174 * NOTE: The definiton of l(a) in WUSB1.0[6.5] vs the definition of
175 * l(m) is orthogonal, they bear no relationship, so it is not
176 * in conflict with the parameter's relation that
177 * WUSB1.0[6.4.2]) defines.
178 *
179 * NOTE: WUSB1.0[A.1]: Host Nonce is missing a nibble? (1e); fixed in
180 * first errata released on 2005/07.
181 *
182 * NOTE: we need to clean IV to zero at each invocation to make sure
183 * we start with a fresh empty Initial Vector, so that the CBC
184 * works ok.
185 *
186 * NOTE: blen is not aligned to a block size, we'll pad zeros, that's
187 * what sg[4] is for. Maybe there is a smarter way to do this.
188 */
189static int wusb_ccm_mac(struct crypto_blkcipher *tfm_cbc,
190 struct crypto_cipher *tfm_aes, void *mic,
191 const struct aes_ccm_nonce *n,
192 const struct aes_ccm_label *a, const void *b,
193 size_t blen)
194{
195 int result = 0;
196 struct blkcipher_desc desc;
197 struct aes_ccm_b0 b0;
198 struct aes_ccm_b1 b1;
199 struct aes_ccm_a ax;
200 struct scatterlist sg[4], sg_dst;
201 void *iv, *dst_buf;
202 size_t ivsize, dst_size;
203 const u8 bzero[16] = { 0 };
204 size_t zero_padding;
205
206 d_fnstart(3, NULL, "(tfm_cbc %p, tfm_aes %p, mic %p, "
207 "n %p, a %p, b %p, blen %zu)\n",
208 tfm_cbc, tfm_aes, mic, n, a, b, blen);
209 /*
210 * These checks should be compile time optimized out
211 * ensure @a fills b1's mac_header and following fields
212 */
213 WARN_ON(sizeof(*a) != sizeof(b1) - sizeof(b1.la));
214 WARN_ON(sizeof(b0) != sizeof(struct aes_ccm_block));
215 WARN_ON(sizeof(b1) != sizeof(struct aes_ccm_block));
216 WARN_ON(sizeof(ax) != sizeof(struct aes_ccm_block));
217
218 result = -ENOMEM;
219 zero_padding = sizeof(struct aes_ccm_block)
220 - blen % sizeof(struct aes_ccm_block);
221 zero_padding = blen % sizeof(struct aes_ccm_block);
222 if (zero_padding)
223 zero_padding = sizeof(struct aes_ccm_block) - zero_padding;
224 dst_size = blen + sizeof(b0) + sizeof(b1) + zero_padding;
225 dst_buf = kzalloc(dst_size, GFP_KERNEL);
226 if (dst_buf == NULL) {
227 printk(KERN_ERR "E: can't alloc destination buffer\n");
228 goto error_dst_buf;
229 }
230
231 iv = crypto_blkcipher_crt(tfm_cbc)->iv;
232 ivsize = crypto_blkcipher_ivsize(tfm_cbc);
233 memset(iv, 0, ivsize);
234
235 /* Setup B0 */
236 b0.flags = 0x59; /* Format B0 */
237 b0.ccm_nonce = *n;
238 b0.lm = cpu_to_be16(0); /* WUSB1.0[6.5] sez l(m) is 0 */
239
240 /* Setup B1
241 *
242 * The WUSB spec is anything but clear! WUSB1.0[6.5]
243 * says that to initialize B1 from A with 'l(a) = blen +
244 * 14'--after clarification, it means to use A's contents
245 * for MAC Header, EO, sec reserved and padding.
246 */
247 b1.la = cpu_to_be16(blen + 14);
248 memcpy(&b1.mac_header, a, sizeof(*a));
249
250 d_printf(4, NULL, "I: B0 (%zu bytes)\n", sizeof(b0));
251 d_dump(4, NULL, &b0, sizeof(b0));
252 d_printf(4, NULL, "I: B1 (%zu bytes)\n", sizeof(b1));
253 d_dump(4, NULL, &b1, sizeof(b1));
254 d_printf(4, NULL, "I: B (%zu bytes)\n", blen);
255 d_dump(4, NULL, b, blen);
256 d_printf(4, NULL, "I: B 0-padding (%zu bytes)\n", zero_padding);
257 d_printf(4, NULL, "D: IV before crypto (%zu)\n", ivsize);
258 d_dump(4, NULL, iv, ivsize);
259
260 sg_init_table(sg, ARRAY_SIZE(sg));
261 sg_set_buf(&sg[0], &b0, sizeof(b0));
262 sg_set_buf(&sg[1], &b1, sizeof(b1));
263 sg_set_buf(&sg[2], b, blen);
264 /* 0 if well behaved :) */
265 sg_set_buf(&sg[3], bzero, zero_padding);
266 sg_init_one(&sg_dst, dst_buf, dst_size);
267
268 desc.tfm = tfm_cbc;
269 desc.flags = 0;
270 result = crypto_blkcipher_encrypt(&desc, &sg_dst, sg, dst_size);
271 if (result < 0) {
272 printk(KERN_ERR "E: can't compute CBC-MAC tag (MIC): %d\n",
273 result);
274 goto error_cbc_crypt;
275 }
276 d_printf(4, NULL, "D: MIC tag\n");
277 d_dump(4, NULL, iv, ivsize);
278
279 /* Now we crypt the MIC Tag (*iv) with Ax -- values per WUSB1.0[6.5]
280 * The procedure is to AES crypt the A0 block and XOR the MIC
281 * Tag agains it; we only do the first 8 bytes and place it
282 * directly in the destination buffer.
283 *
284 * POS Crypto API: size is assumed to be AES's block size.
285 * Thanks for documenting it -- tip taken from airo.c
286 */
287 ax.flags = 0x01; /* as per WUSB 1.0 spec */
288 ax.ccm_nonce = *n;
289 ax.counter = 0;
290 crypto_cipher_encrypt_one(tfm_aes, (void *)&ax, (void *)&ax);
291 bytewise_xor(mic, &ax, iv, 8);
292 d_printf(4, NULL, "D: CTR[MIC]\n");
293 d_dump(4, NULL, &ax, 8);
294 d_printf(4, NULL, "D: CCM-MIC tag\n");
295 d_dump(4, NULL, mic, 8);
296 result = 8;
297error_cbc_crypt:
298 kfree(dst_buf);
299error_dst_buf:
300 d_fnend(3, NULL, "(tfm_cbc %p, tfm_aes %p, mic %p, "
301 "n %p, a %p, b %p, blen %zu)\n",
302 tfm_cbc, tfm_aes, mic, n, a, b, blen);
303 return result;
304}
305
306/*
307 * WUSB Pseudo Random Function (WUSB1.0[6.5])
308 *
309 * @b: buffer to the source data; cannot be a global or const local
310 * (will confuse the scatterlists)
311 */
312ssize_t wusb_prf(void *out, size_t out_size,
313 const u8 key[16], const struct aes_ccm_nonce *_n,
314 const struct aes_ccm_label *a,
315 const void *b, size_t blen, size_t len)
316{
317 ssize_t result, bytes = 0, bitr;
318 struct aes_ccm_nonce n = *_n;
319 struct crypto_blkcipher *tfm_cbc;
320 struct crypto_cipher *tfm_aes;
321 u64 sfn = 0;
322 __le64 sfn_le;
323
324 d_fnstart(3, NULL, "(out %p, out_size %zu, key %p, _n %p, "
325 "a %p, b %p, blen %zu, len %zu)\n", out, out_size,
326 key, _n, a, b, blen, len);
327
328 tfm_cbc = crypto_alloc_blkcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC);
329 if (IS_ERR(tfm_cbc)) {
330 result = PTR_ERR(tfm_cbc);
331 printk(KERN_ERR "E: can't load CBC(AES): %d\n", (int)result);
332 goto error_alloc_cbc;
333 }
334 result = crypto_blkcipher_setkey(tfm_cbc, key, 16);
335 if (result < 0) {
336 printk(KERN_ERR "E: can't set CBC key: %d\n", (int)result);
337 goto error_setkey_cbc;
338 }
339
340 tfm_aes = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
341 if (IS_ERR(tfm_aes)) {
342 result = PTR_ERR(tfm_aes);
343 printk(KERN_ERR "E: can't load AES: %d\n", (int)result);
344 goto error_alloc_aes;
345 }
346 result = crypto_cipher_setkey(tfm_aes, key, 16);
347 if (result < 0) {
348 printk(KERN_ERR "E: can't set AES key: %d\n", (int)result);
349 goto error_setkey_aes;
350 }
351
352 for (bitr = 0; bitr < (len + 63) / 64; bitr++) {
353 sfn_le = cpu_to_le64(sfn++);
354 memcpy(&n.sfn, &sfn_le, sizeof(n.sfn)); /* n.sfn++... */
355 result = wusb_ccm_mac(tfm_cbc, tfm_aes, out + bytes,
356 &n, a, b, blen);
357 if (result < 0)
358 goto error_ccm_mac;
359 bytes += result;
360 }
361 result = bytes;
362error_ccm_mac:
363error_setkey_aes:
364 crypto_free_cipher(tfm_aes);
365error_alloc_aes:
366error_setkey_cbc:
367 crypto_free_blkcipher(tfm_cbc);
368error_alloc_cbc:
369 d_fnend(3, NULL, "(out %p, out_size %zu, key %p, _n %p, "
370 "a %p, b %p, blen %zu, len %zu) = %d\n", out, out_size,
371 key, _n, a, b, blen, len, (int)bytes);
372 return result;
373}
374
375/* WUSB1.0[A.2] test vectors */
376static const u8 stv_hsmic_key[16] = {
377 0x4b, 0x79, 0xa3, 0xcf, 0xe5, 0x53, 0x23, 0x9d,
378 0xd7, 0xc1, 0x6d, 0x1c, 0x2d, 0xab, 0x6d, 0x3f
379};
380
381static const struct aes_ccm_nonce stv_hsmic_n = {
382 .sfn = { 0 },
383 .tkid = { 0x76, 0x98, 0x01, },
384 .dest_addr = { .data = { 0xbe, 0x00 } },
385 .src_addr = { .data = { 0x76, 0x98 } },
386};
387
388/*
389 * Out-of-band MIC Generation verification code
390 *
391 */
392static int wusb_oob_mic_verify(void)
393{
394 int result;
395 u8 mic[8];
396 /* WUSB1.0[A.2] test vectors
397 *
398 * Need to keep it in the local stack as GCC 4.1.3something
399 * messes up and generates noise.
400 */
401 struct usb_handshake stv_hsmic_hs = {
402 .bMessageNumber = 2,
403 .bStatus = 00,
404 .tTKID = { 0x76, 0x98, 0x01 },
405 .bReserved = 00,
406 .CDID = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
407 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
408 0x3c, 0x3d, 0x3e, 0x3f },
409 .nonce = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
410 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
411 0x2c, 0x2d, 0x2e, 0x2f },
412 .MIC = { 0x75, 0x6a, 0x97, 0x51, 0x0c, 0x8c,
413 0x14, 0x7b } ,
414 };
415 size_t hs_size;
416
417 result = wusb_oob_mic(mic, stv_hsmic_key, &stv_hsmic_n, &stv_hsmic_hs);
418 if (result < 0)
419 printk(KERN_ERR "E: WUSB OOB MIC test: failed: %d\n", result);
420 else if (memcmp(stv_hsmic_hs.MIC, mic, sizeof(mic))) {
421 printk(KERN_ERR "E: OOB MIC test: "
422 "mismatch between MIC result and WUSB1.0[A2]\n");
423 hs_size = sizeof(stv_hsmic_hs) - sizeof(stv_hsmic_hs.MIC);
424 printk(KERN_ERR "E: Handshake2 in: (%zu bytes)\n", hs_size);
425 dump_bytes(NULL, &stv_hsmic_hs, hs_size);
426 printk(KERN_ERR "E: CCM Nonce in: (%zu bytes)\n",
427 sizeof(stv_hsmic_n));
428 dump_bytes(NULL, &stv_hsmic_n, sizeof(stv_hsmic_n));
429 printk(KERN_ERR "E: MIC out:\n");
430 dump_bytes(NULL, mic, sizeof(mic));
431 printk(KERN_ERR "E: MIC out (from WUSB1.0[A.2]):\n");
432 dump_bytes(NULL, stv_hsmic_hs.MIC, sizeof(stv_hsmic_hs.MIC));
433 result = -EINVAL;
434 } else
435 result = 0;
436 return result;
437}
438
439/*
440 * Test vectors for Key derivation
441 *
442 * These come from WUSB1.0[6.5.1], the vectors in WUSB1.0[A.1]
443 * (errata corrected in 2005/07).
444 */
445static const u8 stv_key_a1[16] __attribute__ ((__aligned__(4))) = {
446 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87,
447 0x78, 0x69, 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f
448};
449
450static const struct aes_ccm_nonce stv_keydvt_n_a1 = {
451 .sfn = { 0 },
452 .tkid = { 0x76, 0x98, 0x01, },
453 .dest_addr = { .data = { 0xbe, 0x00 } },
454 .src_addr = { .data = { 0x76, 0x98 } },
455};
456
457static const struct wusb_keydvt_out stv_keydvt_out_a1 = {
458 .kck = {
459 0x4b, 0x79, 0xa3, 0xcf, 0xe5, 0x53, 0x23, 0x9d,
460 0xd7, 0xc1, 0x6d, 0x1c, 0x2d, 0xab, 0x6d, 0x3f
461 },
462 .ptk = {
463 0xc8, 0x70, 0x62, 0x82, 0xb6, 0x7c, 0xe9, 0x06,
464 0x7b, 0xc5, 0x25, 0x69, 0xf2, 0x36, 0x61, 0x2d
465 }
466};
467
468/*
469 * Performa a test to make sure we match the vectors defined in
470 * WUSB1.0[A.1](Errata2006/12)
471 */
472static int wusb_key_derive_verify(void)
473{
474 int result = 0;
475 struct wusb_keydvt_out keydvt_out;
476 /* These come from WUSB1.0[A.1] + 2006/12 errata
477 * NOTE: can't make this const or global -- somehow it seems
478 * the scatterlists for crypto get confused and we get
479 * bad data. There is no doc on this... */
480 struct wusb_keydvt_in stv_keydvt_in_a1 = {
481 .hnonce = {
482 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
483 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
484 },
485 .dnonce = {
486 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
487 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f
488 }
489 };
490
491 result = wusb_key_derive(&keydvt_out, stv_key_a1, &stv_keydvt_n_a1,
492 &stv_keydvt_in_a1);
493 if (result < 0)
494 printk(KERN_ERR "E: WUSB key derivation test: "
495 "derivation failed: %d\n", result);
496 if (memcmp(&stv_keydvt_out_a1, &keydvt_out, sizeof(keydvt_out))) {
497 printk(KERN_ERR "E: WUSB key derivation test: "
498 "mismatch between key derivation result "
499 "and WUSB1.0[A1] Errata 2006/12\n");
500 printk(KERN_ERR "E: keydvt in: key (%zu bytes)\n",
501 sizeof(stv_key_a1));
502 dump_bytes(NULL, stv_key_a1, sizeof(stv_key_a1));
503 printk(KERN_ERR "E: keydvt in: nonce (%zu bytes)\n",
504 sizeof(stv_keydvt_n_a1));
505 dump_bytes(NULL, &stv_keydvt_n_a1, sizeof(stv_keydvt_n_a1));
506 printk(KERN_ERR "E: keydvt in: hnonce & dnonce (%zu bytes)\n",
507 sizeof(stv_keydvt_in_a1));
508 dump_bytes(NULL, &stv_keydvt_in_a1, sizeof(stv_keydvt_in_a1));
509 printk(KERN_ERR "E: keydvt out: KCK\n");
510 dump_bytes(NULL, &keydvt_out.kck, sizeof(keydvt_out.kck));
511 printk(KERN_ERR "E: keydvt out: PTK\n");
512 dump_bytes(NULL, &keydvt_out.ptk, sizeof(keydvt_out.ptk));
513 result = -EINVAL;
514 } else
515 result = 0;
516 return result;
517}
518
519/*
520 * Initialize crypto system
521 *
522 * FIXME: we do nothing now, other than verifying. Later on we'll
523 * cache the encryption stuff, so that's why we have a separate init.
524 */
525int wusb_crypto_init(void)
526{
527 int result;
528
529 result = wusb_key_derive_verify();
530 if (result < 0)
531 return result;
532 return wusb_oob_mic_verify();
533}
534
535void wusb_crypto_exit(void)
536{
537 /* FIXME: free cached crypto transforms */
538}
diff --git a/drivers/usb/wusbcore/dev-sysfs.c b/drivers/usb/wusbcore/dev-sysfs.c
new file mode 100644
index 000000000000..7897a19652e5
--- /dev/null
+++ b/drivers/usb/wusbcore/dev-sysfs.c
@@ -0,0 +1,143 @@
1/*
2 * WUSB devices
3 * sysfs bindings
4 *
5 * Copyright (C) 2007 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 * Get them out of the way...
24 */
25
26#include <linux/jiffies.h>
27#include <linux/ctype.h>
28#include <linux/workqueue.h>
29#include "wusbhc.h"
30
31#undef D_LOCAL
32#define D_LOCAL 4
33#include <linux/uwb/debug.h>
34
35static ssize_t wusb_disconnect_store(struct device *dev,
36 struct device_attribute *attr,
37 const char *buf, size_t size)
38{
39 struct usb_device *usb_dev;
40 struct wusbhc *wusbhc;
41 unsigned command;
42 u8 port_idx;
43
44 if (sscanf(buf, "%u", &command) != 1)
45 return -EINVAL;
46 if (command == 0)
47 return size;
48 usb_dev = to_usb_device(dev);
49 wusbhc = wusbhc_get_by_usb_dev(usb_dev);
50 if (wusbhc == NULL)
51 return -ENODEV;
52
53 mutex_lock(&wusbhc->mutex);
54 port_idx = wusb_port_no_to_idx(usb_dev->portnum);
55 __wusbhc_dev_disable(wusbhc, port_idx);
56 mutex_unlock(&wusbhc->mutex);
57 wusbhc_put(wusbhc);
58 return size;
59}
60static DEVICE_ATTR(wusb_disconnect, 0200, NULL, wusb_disconnect_store);
61
62static ssize_t wusb_cdid_show(struct device *dev,
63 struct device_attribute *attr, char *buf)
64{
65 ssize_t result;
66 struct wusb_dev *wusb_dev;
67
68 wusb_dev = wusb_dev_get_by_usb_dev(to_usb_device(dev));
69 if (wusb_dev == NULL)
70 return -ENODEV;
71 result = ckhdid_printf(buf, PAGE_SIZE, &wusb_dev->cdid);
72 strcat(buf, "\n");
73 wusb_dev_put(wusb_dev);
74 return result + 1;
75}
76static DEVICE_ATTR(wusb_cdid, 0444, wusb_cdid_show, NULL);
77
78static ssize_t wusb_ck_store(struct device *dev,
79 struct device_attribute *attr,
80 const char *buf, size_t size)
81{
82 int result;
83 struct usb_device *usb_dev;
84 struct wusbhc *wusbhc;
85 struct wusb_ckhdid ck;
86
87 result = sscanf(buf,
88 "%02hhx %02hhx %02hhx %02hhx "
89 "%02hhx %02hhx %02hhx %02hhx "
90 "%02hhx %02hhx %02hhx %02hhx "
91 "%02hhx %02hhx %02hhx %02hhx\n",
92 &ck.data[0] , &ck.data[1],
93 &ck.data[2] , &ck.data[3],
94 &ck.data[4] , &ck.data[5],
95 &ck.data[6] , &ck.data[7],
96 &ck.data[8] , &ck.data[9],
97 &ck.data[10], &ck.data[11],
98 &ck.data[12], &ck.data[13],
99 &ck.data[14], &ck.data[15]);
100 if (result != 16)
101 return -EINVAL;
102
103 usb_dev = to_usb_device(dev);
104 wusbhc = wusbhc_get_by_usb_dev(usb_dev);
105 if (wusbhc == NULL)
106 return -ENODEV;
107 result = wusb_dev_4way_handshake(wusbhc, usb_dev->wusb_dev, &ck);
108 memset(&ck, 0, sizeof(ck));
109 wusbhc_put(wusbhc);
110 return result < 0 ? result : size;
111}
112static DEVICE_ATTR(wusb_ck, 0200, NULL, wusb_ck_store);
113
114static struct attribute *wusb_dev_attrs[] = {
115 &dev_attr_wusb_disconnect.attr,
116 &dev_attr_wusb_cdid.attr,
117 &dev_attr_wusb_ck.attr,
118 NULL,
119};
120
121static struct attribute_group wusb_dev_attr_group = {
122 .name = NULL, /* we want them in the same directory */
123 .attrs = wusb_dev_attrs,
124};
125
126int wusb_dev_sysfs_add(struct wusbhc *wusbhc, struct usb_device *usb_dev,
127 struct wusb_dev *wusb_dev)
128{
129 int result = sysfs_create_group(&usb_dev->dev.kobj,
130 &wusb_dev_attr_group);
131 struct device *dev = &usb_dev->dev;
132 if (result < 0)
133 dev_err(dev, "Cannot register WUSB-dev attributes: %d\n",
134 result);
135 return result;
136}
137
138void wusb_dev_sysfs_rm(struct wusb_dev *wusb_dev)
139{
140 struct usb_device *usb_dev = wusb_dev->usb_dev;
141 if (usb_dev)
142 sysfs_remove_group(&usb_dev->dev.kobj, &wusb_dev_attr_group);
143}
diff --git a/drivers/usb/wusbcore/devconnect.c b/drivers/usb/wusbcore/devconnect.c
new file mode 100644
index 000000000000..30d7020e1c50
--- /dev/null
+++ b/drivers/usb/wusbcore/devconnect.c
@@ -0,0 +1,1314 @@
1/*
2 * WUSB Wire Adapter: Control/Data Streaming Interface (WUSB[8])
3 * Device Connect handling
4 *
5 * Copyright (C) 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 * FIXME: docs
24 * FIXME: this file needs to be broken up, it's grown too big
25 *
26 *
27 * WUSB1.0[7.1, 7.5.1, ]
28 *
29 * WUSB device connection is kind of messy. Some background:
30 *
31 * When a device wants to connect it scans the UWB radio channels
32 * looking for a WUSB Channel; a WUSB channel is defined by MMCs
33 * (Micro Managed Commands or something like that) [see
34 * Design-overview for more on this] .
35 *
36 * So, device scans the radio, finds MMCs and thus a host and checks
37 * when the next DNTS is. It sends a Device Notification Connect
38 * (DN_Connect); the host picks it up (through nep.c and notif.c, ends
39 * up in wusb_devconnect_ack(), which creates a wusb_dev structure in
40 * wusbhc->port[port_number].wusb_dev), assigns an unauth address
41 * to the device (this means from 0x80 to 0xfe) and sends, in the MMC
42 * a Connect Ack Information Element (ConnAck IE).
43 *
44 * So now the device now has a WUSB address. From now on, we use
45 * that to talk to it in the RPipes.
46 *
47 * ASSUMPTIONS:
48 *
49 * - We use the the as device address the port number where it is
50 * connected (port 0 doesn't exist). For unauth, it is 128 + that.
51 *
52 * ROADMAP:
53 *
54 * This file contains the logic for doing that--entry points:
55 *
56 * wusb_devconnect_ack() Ack a device until _acked() called.
57 * Called by notif.c:wusb_handle_dn_connect()
58 * when a DN_Connect is received.
59 *
60 * wusbhc_devconnect_auth() Called by rh.c:wusbhc_rh_port_reset() when
61 * doing the device connect sequence.
62 *
63 * wusb_devconnect_acked() Ack done, release resources.
64 *
65 * wusb_handle_dn_alive() Called by notif.c:wusb_handle_dn()
66 * for processing a DN_Alive pong from a device.
67 *
68 * wusb_handle_dn_disconnect()Called by notif.c:wusb_handle_dn() to
69 * process a disconenct request from a
70 * device.
71 *
72 * wusb_dev_reset() Called by rh.c:wusbhc_rh_port_reset() when
73 * resetting a device.
74 *
75 * __wusb_dev_disable() Called by rh.c:wusbhc_rh_clear_port_feat() when
76 * disabling a port.
77 *
78 * wusb_devconnect_create() Called when creating the host by
79 * lc.c:wusbhc_create().
80 *
81 * wusb_devconnect_destroy() Cleanup called removing the host. Called
82 * by lc.c:wusbhc_destroy().
83 *
84 * Each Wireless USB host maintains a list of DN_Connect requests
85 * (actually we maintain a list of pending Connect Acks, the
86 * wusbhc->ca_list).
87 *
88 * LIFE CYCLE OF port->wusb_dev
89 *
90 * Before the @wusbhc structure put()s the reference it owns for
91 * port->wusb_dev [and clean the wusb_dev pointer], it needs to
92 * lock @wusbhc->mutex.
93 */
94
95#include <linux/jiffies.h>
96#include <linux/ctype.h>
97#include <linux/workqueue.h>
98#include "wusbhc.h"
99
100#undef D_LOCAL
101#define D_LOCAL 1
102#include <linux/uwb/debug.h>
103
104static void wusbhc_devconnect_acked_work(struct work_struct *work);
105
106static void wusb_dev_free(struct wusb_dev *wusb_dev)
107{
108 if (wusb_dev) {
109 kfree(wusb_dev->set_gtk_req);
110 usb_free_urb(wusb_dev->set_gtk_urb);
111 kfree(wusb_dev);
112 }
113}
114
115static struct wusb_dev *wusb_dev_alloc(struct wusbhc *wusbhc)
116{
117 struct wusb_dev *wusb_dev;
118 struct urb *urb;
119 struct usb_ctrlrequest *req;
120
121 wusb_dev = kzalloc(sizeof(*wusb_dev), GFP_KERNEL);
122 if (wusb_dev == NULL)
123 goto err;
124
125 wusb_dev->wusbhc = wusbhc;
126
127 INIT_WORK(&wusb_dev->devconnect_acked_work, wusbhc_devconnect_acked_work);
128
129 urb = usb_alloc_urb(0, GFP_KERNEL);
130 if (urb == NULL)
131 goto err;
132
133 req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
134 if (req == NULL)
135 goto err;
136
137 req->bRequestType = USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE;
138 req->bRequest = USB_REQ_SET_DESCRIPTOR;
139 req->wValue = cpu_to_le16(USB_DT_KEY << 8 | wusbhc->gtk_index);
140 req->wIndex = 0;
141 req->wLength = cpu_to_le16(wusbhc->gtk.descr.bLength);
142
143 wusb_dev->set_gtk_urb = urb;
144 wusb_dev->set_gtk_req = req;
145
146 return wusb_dev;
147err:
148 wusb_dev_free(wusb_dev);
149 return NULL;
150}
151
152
153/*
154 * Using the Connect-Ack list, fill out the @wusbhc Connect-Ack WUSB IE
155 * properly so that it can be added to the MMC.
156 *
157 * We just get the @wusbhc->ca_list and fill out the first four ones or
158 * less (per-spec WUSB1.0[7.5, before T7-38). If the ConnectAck WUSB
159 * IE is not allocated, we alloc it.
160 *
161 * @wusbhc->mutex must be taken
162 */
163static void wusbhc_fill_cack_ie(struct wusbhc *wusbhc)
164{
165 unsigned cnt;
166 struct wusb_dev *dev_itr;
167 struct wuie_connect_ack *cack_ie;
168
169 cack_ie = &wusbhc->cack_ie;
170 cnt = 0;
171 list_for_each_entry(dev_itr, &wusbhc->cack_list, cack_node) {
172 cack_ie->blk[cnt].CDID = dev_itr->cdid;
173 cack_ie->blk[cnt].bDeviceAddress = dev_itr->addr;
174 if (++cnt >= WUIE_ELT_MAX)
175 break;
176 }
177 cack_ie->hdr.bLength = sizeof(cack_ie->hdr)
178 + cnt * sizeof(cack_ie->blk[0]);
179}
180
181/*
182 * Register a new device that wants to connect
183 *
184 * A new device wants to connect, so we add it to the Connect-Ack
185 * list. We give it an address in the unauthorized range (bit 8 set);
186 * user space will have to drive authorization further on.
187 *
188 * @dev_addr: address to use for the device (which is also the port
189 * number).
190 *
191 * @wusbhc->mutex must be taken
192 */
193static struct wusb_dev *wusbhc_cack_add(struct wusbhc *wusbhc,
194 struct wusb_dn_connect *dnc,
195 const char *pr_cdid, u8 port_idx)
196{
197 struct device *dev = wusbhc->dev;
198 struct wusb_dev *wusb_dev;
199 int new_connection = wusb_dn_connect_new_connection(dnc);
200 u8 dev_addr;
201 int result;
202
203 d_fnstart(3, dev, "(wusbhc %p port_idx %d)\n", wusbhc, port_idx);
204 /* Is it registered already? */
205 list_for_each_entry(wusb_dev, &wusbhc->cack_list, cack_node)
206 if (!memcmp(&wusb_dev->cdid, &dnc->CDID,
207 sizeof(wusb_dev->cdid)))
208 return wusb_dev;
209 /* We don't have it, create an entry, register it */
210 wusb_dev = wusb_dev_alloc(wusbhc);
211 if (wusb_dev == NULL) {
212 if (printk_ratelimit())
213 dev_err(dev, "DN CONNECT: no memory to process %s's %s "
214 "request\n", pr_cdid,
215 new_connection ? "connect" : "reconnect");
216 return NULL;
217 }
218 wusb_dev_init(wusb_dev);
219 wusb_dev->cdid = dnc->CDID;
220 wusb_dev->port_idx = port_idx;
221
222 /*
223 * Devices are always available within the cluster reservation
224 * and since the hardware will take the intersection of the
225 * per-device availability and the cluster reservation, the
226 * per-device availability can simply be set to always
227 * available.
228 */
229 bitmap_fill(wusb_dev->availability.bm, UWB_NUM_MAS);
230
231 /* FIXME: handle reconnects instead of assuming connects are
232 always new. */
233 if (1 && new_connection == 0)
234 new_connection = 1;
235 if (new_connection) {
236 dev_addr = (port_idx + 2) | WUSB_DEV_ADDR_UNAUTH;
237
238 dev_info(dev, "Connecting new WUSB device to address %u, "
239 "port %u\n", dev_addr, port_idx);
240
241 result = wusb_set_dev_addr(wusbhc, wusb_dev, dev_addr);
242 if (result < 0)
243 return NULL;
244 }
245 wusb_dev->entry_ts = jiffies;
246 list_add_tail(&wusb_dev->cack_node, &wusbhc->cack_list);
247 wusbhc->cack_count++;
248 wusbhc_fill_cack_ie(wusbhc);
249 d_fnend(3, dev, "(wusbhc %p port_idx %d)\n", wusbhc, port_idx);
250 return wusb_dev;
251}
252
253/*
254 * Remove a Connect-Ack context entry from the HCs view
255 *
256 * @wusbhc->mutex must be taken
257 */
258static void wusbhc_cack_rm(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
259{
260 struct device *dev = wusbhc->dev;
261 d_fnstart(3, dev, "(wusbhc %p wusb_dev %p)\n", wusbhc, wusb_dev);
262 list_del_init(&wusb_dev->cack_node);
263 wusbhc->cack_count--;
264 wusbhc_fill_cack_ie(wusbhc);
265 d_fnend(3, dev, "(wusbhc %p wusb_dev %p) = void\n", wusbhc, wusb_dev);
266}
267
268/*
269 * @wusbhc->mutex must be taken */
270static
271void wusbhc_devconnect_acked(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
272{
273 struct device *dev = wusbhc->dev;
274 d_fnstart(3, dev, "(wusbhc %p wusb_dev %p)\n", wusbhc, wusb_dev);
275 wusbhc_cack_rm(wusbhc, wusb_dev);
276 if (wusbhc->cack_count)
277 wusbhc_mmcie_set(wusbhc, 0, 0, &wusbhc->cack_ie.hdr);
278 else
279 wusbhc_mmcie_rm(wusbhc, &wusbhc->cack_ie.hdr);
280 d_fnend(3, dev, "(wusbhc %p wusb_dev %p) = void\n", wusbhc, wusb_dev);
281}
282
283static void wusbhc_devconnect_acked_work(struct work_struct *work)
284{
285 struct wusb_dev *wusb_dev = container_of(work, struct wusb_dev,
286 devconnect_acked_work);
287 struct wusbhc *wusbhc = wusb_dev->wusbhc;
288
289 mutex_lock(&wusbhc->mutex);
290 wusbhc_devconnect_acked(wusbhc, wusb_dev);
291 mutex_unlock(&wusbhc->mutex);
292}
293
294/*
295 * Ack a device for connection
296 *
297 * FIXME: docs
298 *
299 * @pr_cdid: Printable CDID...hex Use @dnc->cdid for the real deal.
300 *
301 * So we get the connect ack IE (may have been allocated already),
302 * find an empty connect block, an empty virtual port, create an
303 * address with it (see below), make it an unauth addr [bit 7 set] and
304 * set the MMC.
305 *
306 * Addresses: because WUSB hosts have no downstream hubs, we can do a
307 * 1:1 mapping between 'port number' and device
308 * address. This simplifies many things, as during this
309 * initial connect phase the USB stack has no knoledge of
310 * the device and hasn't assigned an address yet--we know
311 * USB's choose_address() will use the same euristics we
312 * use here, so we can assume which address will be assigned.
313 *
314 * USB stack always assigns address 1 to the root hub, so
315 * to the port number we add 2 (thus virtual port #0 is
316 * addr #2).
317 *
318 * @wusbhc shall be referenced
319 */
320static
321void wusbhc_devconnect_ack(struct wusbhc *wusbhc, struct wusb_dn_connect *dnc,
322 const char *pr_cdid)
323{
324 int result;
325 struct device *dev = wusbhc->dev;
326 struct wusb_dev *wusb_dev;
327 struct wusb_port *port;
328 unsigned idx, devnum;
329
330 d_fnstart(3, dev, "(%p, %p, %s)\n", wusbhc, dnc, pr_cdid);
331 mutex_lock(&wusbhc->mutex);
332
333 /* Check we are not handling it already */
334 for (idx = 0; idx < wusbhc->ports_max; idx++) {
335 port = wusb_port_by_idx(wusbhc, idx);
336 if (port->wusb_dev
337 && !memcmp(&dnc->CDID, &port->wusb_dev->cdid,
338 sizeof(dnc->CDID))) {
339 if (printk_ratelimit())
340 dev_err(dev, "Already handling dev %s "
341 " (it might be slow)\n", pr_cdid);
342 goto error_unlock;
343 }
344 }
345 /* Look up those fake ports we have for a free one */
346 for (idx = 0; idx < wusbhc->ports_max; idx++) {
347 port = wusb_port_by_idx(wusbhc, idx);
348 if ((port->status & USB_PORT_STAT_POWER)
349 && !(port->status & USB_PORT_STAT_CONNECTION))
350 break;
351 }
352 if (idx >= wusbhc->ports_max) {
353 dev_err(dev, "Host controller can't connect more devices "
354 "(%u already connected); device %s rejected\n",
355 wusbhc->ports_max, pr_cdid);
356 /* NOTE: we could send a WUIE_Disconnect here, but we haven't
357 * event acked, so the device will eventually timeout the
358 * connection, right? */
359 goto error_unlock;
360 }
361
362 devnum = idx + 2;
363
364 /* Make sure we are using no crypto on that "virtual port" */
365 wusbhc->set_ptk(wusbhc, idx, 0, NULL, 0);
366
367 /* Grab a filled in Connect-Ack context, fill out the
368 * Connect-Ack Wireless USB IE, set the MMC */
369 wusb_dev = wusbhc_cack_add(wusbhc, dnc, pr_cdid, idx);
370 if (wusb_dev == NULL)
371 goto error_unlock;
372 result = wusbhc_mmcie_set(wusbhc, 0, 0, &wusbhc->cack_ie.hdr);
373 if (result < 0)
374 goto error_unlock;
375 /* Give the device at least 2ms (WUSB1.0[7.5.1p3]), let's do
376 * three for a good measure */
377 msleep(3);
378 port->wusb_dev = wusb_dev;
379 port->status |= USB_PORT_STAT_CONNECTION;
380 port->change |= USB_PORT_STAT_C_CONNECTION;
381 port->reset_count = 0;
382 /* Now the port status changed to connected; khubd will
383 * pick the change up and try to reset the port to bring it to
384 * the enabled state--so this process returns up to the stack
385 * and it calls back into wusbhc_rh_port_reset() who will call
386 * devconnect_auth().
387 */
388error_unlock:
389 mutex_unlock(&wusbhc->mutex);
390 d_fnend(3, dev, "(%p, %p, %s) = void\n", wusbhc, dnc, pr_cdid);
391 return;
392
393}
394
395/*
396 * Disconnect a Wireless USB device from its fake port
397 *
398 * Marks the port as disconnected so that khubd can pick up the change
399 * and drops our knowledge about the device.
400 *
401 * Assumes there is a device connected
402 *
403 * @port_index: zero based port number
404 *
405 * NOTE: @wusbhc->mutex is locked
406 *
407 * WARNING: From here it is not very safe to access anything hanging off
408 * wusb_dev
409 */
410static void __wusbhc_dev_disconnect(struct wusbhc *wusbhc,
411 struct wusb_port *port)
412{
413 struct device *dev = wusbhc->dev;
414 struct wusb_dev *wusb_dev = port->wusb_dev;
415
416 d_fnstart(3, dev, "(wusbhc %p, port %p)\n", wusbhc, port);
417 port->status &= ~(USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE
418 | USB_PORT_STAT_SUSPEND | USB_PORT_STAT_RESET
419 | USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED);
420 port->change |= USB_PORT_STAT_C_CONNECTION | USB_PORT_STAT_C_ENABLE;
421 if (wusb_dev) {
422 if (!list_empty(&wusb_dev->cack_node))
423 list_del_init(&wusb_dev->cack_node);
424 /* For the one in cack_add() */
425 wusb_dev_put(wusb_dev);
426 }
427 port->wusb_dev = NULL;
428 /* don't reset the reset_count to zero or wusbhc_rh_port_reset will get
429 * confused! We only reset to zero when we connect a new device.
430 */
431
432 /* After a device disconnects, change the GTK (see [WUSB]
433 * section 6.2.11.2). */
434 wusbhc_gtk_rekey(wusbhc);
435
436 d_fnend(3, dev, "(wusbhc %p, port %p) = void\n", wusbhc, port);
437 /* The Wireless USB part has forgotten about the device already; now
438 * khubd's timer will pick up the disconnection and remove the USB
439 * device from the system
440 */
441}
442
443/*
444 * Authenticate a device into the WUSB Cluster
445 *
446 * Called from the Root Hub code (rh.c:wusbhc_rh_port_reset()) when
447 * asking for a reset on a port that is not enabled (ie: first connect
448 * on the port).
449 *
450 * Performs the 4way handshake to allow the device to comunicate w/ the
451 * WUSB Cluster securely; once done, issue a request to the device for
452 * it to change to address 0.
453 *
454 * This mimics the reset step of Wired USB that once resetting a
455 * device, leaves the port in enabled state and the dev with the
456 * default address (0).
457 *
458 * WUSB1.0[7.1.2]
459 *
460 * @port_idx: port where the change happened--This is the index into
461 * the wusbhc port array, not the USB port number.
462 */
463int wusbhc_devconnect_auth(struct wusbhc *wusbhc, u8 port_idx)
464{
465 struct device *dev = wusbhc->dev;
466 struct wusb_port *port = wusb_port_by_idx(wusbhc, port_idx);
467
468 d_fnstart(3, dev, "(%p, %u)\n", wusbhc, port_idx);
469 port->status &= ~USB_PORT_STAT_RESET;
470 port->status |= USB_PORT_STAT_ENABLE;
471 port->change |= USB_PORT_STAT_C_RESET | USB_PORT_STAT_C_ENABLE;
472 d_fnend(3, dev, "(%p, %u) = 0\n", wusbhc, port_idx);
473 return 0;
474}
475
476/*
477 * Refresh the list of keep alives to emit in the MMC
478 *
479 * Some devices don't respond to keep alives unless they've been
480 * authenticated, so skip unauthenticated devices.
481 *
482 * We only publish the first four devices that have a coming timeout
483 * condition. Then when we are done processing those, we go for the
484 * next ones. We ignore the ones that have timed out already (they'll
485 * be purged).
486 *
487 * This might cause the first devices to timeout the last devices in
488 * the port array...FIXME: come up with a better algorithm?
489 *
490 * Note we can't do much about MMC's ops errors; we hope next refresh
491 * will kind of handle it.
492 *
493 * NOTE: @wusbhc->mutex is locked
494 */
495static void __wusbhc_keep_alive(struct wusbhc *wusbhc)
496{
497 int result;
498 struct device *dev = wusbhc->dev;
499 unsigned cnt;
500 struct wusb_dev *wusb_dev;
501 struct wusb_port *wusb_port;
502 struct wuie_keep_alive *ie = &wusbhc->keep_alive_ie;
503 unsigned keep_alives, old_keep_alives;
504
505 d_fnstart(5, dev, "(wusbhc %p)\n", wusbhc);
506 old_keep_alives = ie->hdr.bLength - sizeof(ie->hdr);
507 keep_alives = 0;
508 for (cnt = 0;
509 keep_alives <= WUIE_ELT_MAX && cnt < wusbhc->ports_max;
510 cnt++) {
511 unsigned tt = msecs_to_jiffies(wusbhc->trust_timeout);
512
513 wusb_port = wusb_port_by_idx(wusbhc, cnt);
514 wusb_dev = wusb_port->wusb_dev;
515
516 if (wusb_dev == NULL)
517 continue;
518 if (wusb_dev->usb_dev == NULL || !wusb_dev->usb_dev->authenticated)
519 continue;
520
521 if (time_after(jiffies, wusb_dev->entry_ts + tt)) {
522 dev_err(dev, "KEEPALIVE: device %u timed out\n",
523 wusb_dev->addr);
524 __wusbhc_dev_disconnect(wusbhc, wusb_port);
525 } else if (time_after(jiffies, wusb_dev->entry_ts + tt/2)) {
526 /* Approaching timeout cut out, need to refresh */
527 ie->bDeviceAddress[keep_alives++] = wusb_dev->addr;
528 }
529 }
530 if (keep_alives & 0x1) /* pad to even number ([WUSB] section 7.5.9) */
531 ie->bDeviceAddress[keep_alives++] = 0x7f;
532 ie->hdr.bLength = sizeof(ie->hdr) +
533 keep_alives*sizeof(ie->bDeviceAddress[0]);
534 if (keep_alives > 0) {
535 result = wusbhc_mmcie_set(wusbhc, 10, 5, &ie->hdr);
536 if (result < 0 && printk_ratelimit())
537 dev_err(dev, "KEEPALIVE: can't set MMC: %d\n", result);
538 } else if (old_keep_alives != 0)
539 wusbhc_mmcie_rm(wusbhc, &ie->hdr);
540 d_fnend(5, dev, "(wusbhc %p) = void\n", wusbhc);
541}
542
543/*
544 * Do a run through all devices checking for timeouts
545 */
546static void wusbhc_keep_alive_run(struct work_struct *ws)
547{
548 struct delayed_work *dw =
549 container_of(ws, struct delayed_work, work);
550 struct wusbhc *wusbhc =
551 container_of(dw, struct wusbhc, keep_alive_timer);
552
553 d_fnstart(5, wusbhc->dev, "(wusbhc %p)\n", wusbhc);
554 if (wusbhc->active) {
555 mutex_lock(&wusbhc->mutex);
556 __wusbhc_keep_alive(wusbhc);
557 mutex_unlock(&wusbhc->mutex);
558 queue_delayed_work(wusbd, &wusbhc->keep_alive_timer,
559 (wusbhc->trust_timeout * CONFIG_HZ)/1000/2);
560 }
561 d_fnend(5, wusbhc->dev, "(wusbhc %p) = void\n", wusbhc);
562 return;
563}
564
565/*
566 * Find the wusb_dev from its device address.
567 *
568 * The device can be found directly from the address (see
569 * wusb_cack_add() for where the device address is set to port_idx
570 * +2), except when the address is zero.
571 */
572static struct wusb_dev *wusbhc_find_dev_by_addr(struct wusbhc *wusbhc, u8 addr)
573{
574 int p;
575
576 if (addr == 0xff) /* unconnected */
577 return NULL;
578
579 if (addr > 0) {
580 int port = (addr & ~0x80) - 2;
581 if (port < 0 || port >= wusbhc->ports_max)
582 return NULL;
583 return wusb_port_by_idx(wusbhc, port)->wusb_dev;
584 }
585
586 /* Look for the device with address 0. */
587 for (p = 0; p < wusbhc->ports_max; p++) {
588 struct wusb_dev *wusb_dev = wusb_port_by_idx(wusbhc, p)->wusb_dev;
589 if (wusb_dev && wusb_dev->addr == addr)
590 return wusb_dev;
591 }
592 return NULL;
593}
594
595/*
596 * Handle a DN_Alive notification (WUSB1.0[7.6.1])
597 *
598 * This just updates the device activity timestamp and then refreshes
599 * the keep alive IE.
600 *
601 * @wusbhc shall be referenced and unlocked
602 */
603static void wusbhc_handle_dn_alive(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
604{
605 struct device *dev = wusbhc->dev;
606
607 d_printf(2, dev, "DN ALIVE: device 0x%02x pong\n", wusb_dev->addr);
608
609 mutex_lock(&wusbhc->mutex);
610 wusb_dev->entry_ts = jiffies;
611 __wusbhc_keep_alive(wusbhc);
612 mutex_unlock(&wusbhc->mutex);
613}
614
615/*
616 * Handle a DN_Connect notification (WUSB1.0[7.6.1])
617 *
618 * @wusbhc
619 * @pkt_hdr
620 * @size: Size of the buffer where the notification resides; if the
621 * notification data suggests there should be more data than
622 * available, an error will be signaled and the whole buffer
623 * consumed.
624 *
625 * @wusbhc->mutex shall be held
626 */
627static void wusbhc_handle_dn_connect(struct wusbhc *wusbhc,
628 struct wusb_dn_hdr *dn_hdr,
629 size_t size)
630{
631 struct device *dev = wusbhc->dev;
632 struct wusb_dn_connect *dnc;
633 char pr_cdid[WUSB_CKHDID_STRSIZE];
634 static const char *beacon_behaviour[] = {
635 "reserved",
636 "self-beacon",
637 "directed-beacon",
638 "no-beacon"
639 };
640
641 d_fnstart(3, dev, "(%p, %p, %zu)\n", wusbhc, dn_hdr, size);
642 if (size < sizeof(*dnc)) {
643 dev_err(dev, "DN CONNECT: short notification (%zu < %zu)\n",
644 size, sizeof(*dnc));
645 goto out;
646 }
647
648 dnc = container_of(dn_hdr, struct wusb_dn_connect, hdr);
649 ckhdid_printf(pr_cdid, sizeof(pr_cdid), &dnc->CDID);
650 dev_info(dev, "DN CONNECT: device %s @ %x (%s) wants to %s\n",
651 pr_cdid,
652 wusb_dn_connect_prev_dev_addr(dnc),
653 beacon_behaviour[wusb_dn_connect_beacon_behavior(dnc)],
654 wusb_dn_connect_new_connection(dnc) ? "connect" : "reconnect");
655 /* ACK the connect */
656 wusbhc_devconnect_ack(wusbhc, dnc, pr_cdid);
657out:
658 d_fnend(3, dev, "(%p, %p, %zu) = void\n",
659 wusbhc, dn_hdr, size);
660 return;
661}
662
663/*
664 * Handle a DN_Disconnect notification (WUSB1.0[7.6.1])
665 *
666 * Device is going down -- do the disconnect.
667 *
668 * @wusbhc shall be referenced and unlocked
669 */
670static void wusbhc_handle_dn_disconnect(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
671{
672 struct device *dev = wusbhc->dev;
673
674 dev_info(dev, "DN DISCONNECT: device 0x%02x going down\n", wusb_dev->addr);
675
676 mutex_lock(&wusbhc->mutex);
677 __wusbhc_dev_disconnect(wusbhc, wusb_port_by_idx(wusbhc, wusb_dev->port_idx));
678 mutex_unlock(&wusbhc->mutex);
679}
680
681/*
682 * Reset a WUSB device on a HWA
683 *
684 * @wusbhc
685 * @port_idx Index of the port where the device is
686 *
687 * In Wireless USB, a reset is more or less equivalent to a full
688 * disconnect; so we just do a full disconnect and send the device a
689 * Device Reset IE (WUSB1.0[7.5.11]) giving it a few millisecs (6 MMCs).
690 *
691 * @wusbhc should be refcounted and unlocked
692 */
693int wusbhc_dev_reset(struct wusbhc *wusbhc, u8 port_idx)
694{
695 int result;
696 struct device *dev = wusbhc->dev;
697 struct wusb_dev *wusb_dev;
698 struct wuie_reset *ie;
699
700 d_fnstart(3, dev, "(%p, %u)\n", wusbhc, port_idx);
701 mutex_lock(&wusbhc->mutex);
702 result = 0;
703 wusb_dev = wusb_port_by_idx(wusbhc, port_idx)->wusb_dev;
704 if (wusb_dev == NULL) {
705 /* reset no device? ignore */
706 dev_dbg(dev, "RESET: no device at port %u, ignoring\n",
707 port_idx);
708 goto error_unlock;
709 }
710 result = -ENOMEM;
711 ie = kzalloc(sizeof(*ie), GFP_KERNEL);
712 if (ie == NULL)
713 goto error_unlock;
714 ie->hdr.bLength = sizeof(ie->hdr) + sizeof(ie->CDID);
715 ie->hdr.bIEIdentifier = WUIE_ID_RESET_DEVICE;
716 ie->CDID = wusb_dev->cdid;
717 result = wusbhc_mmcie_set(wusbhc, 0xff, 6, &ie->hdr);
718 if (result < 0) {
719 dev_err(dev, "RESET: cant's set MMC: %d\n", result);
720 goto error_kfree;
721 }
722 __wusbhc_dev_disconnect(wusbhc, wusb_port_by_idx(wusbhc, port_idx));
723
724 /* 120ms, hopefully 6 MMCs (FIXME) */
725 msleep(120);
726 wusbhc_mmcie_rm(wusbhc, &ie->hdr);
727error_kfree:
728 kfree(ie);
729error_unlock:
730 mutex_unlock(&wusbhc->mutex);
731 d_fnend(3, dev, "(%p, %u) = %d\n", wusbhc, port_idx, result);
732 return result;
733}
734
735/*
736 * Handle a Device Notification coming a host
737 *
738 * The Device Notification comes from a host (HWA, DWA or WHCI)
739 * wrapped in a set of headers. Somebody else has peeled off those
740 * headers for us and we just get one Device Notifications.
741 *
742 * Invalid DNs (e.g., too short) are discarded.
743 *
744 * @wusbhc shall be referenced
745 *
746 * FIXMES:
747 * - implement priorities as in WUSB1.0[Table 7-55]?
748 */
749void wusbhc_handle_dn(struct wusbhc *wusbhc, u8 srcaddr,
750 struct wusb_dn_hdr *dn_hdr, size_t size)
751{
752 struct device *dev = wusbhc->dev;
753 struct wusb_dev *wusb_dev;
754
755 d_fnstart(3, dev, "(%p, %p)\n", wusbhc, dn_hdr);
756
757 if (size < sizeof(struct wusb_dn_hdr)) {
758 dev_err(dev, "DN data shorter than DN header (%d < %d)\n",
759 (int)size, (int)sizeof(struct wusb_dn_hdr));
760 goto out;
761 }
762
763 wusb_dev = wusbhc_find_dev_by_addr(wusbhc, srcaddr);
764 if (wusb_dev == NULL && dn_hdr->bType != WUSB_DN_CONNECT) {
765 dev_dbg(dev, "ignoring DN %d from unconnected device %02x\n",
766 dn_hdr->bType, srcaddr);
767 goto out;
768 }
769
770 switch (dn_hdr->bType) {
771 case WUSB_DN_CONNECT:
772 wusbhc_handle_dn_connect(wusbhc, dn_hdr, size);
773 break;
774 case WUSB_DN_ALIVE:
775 wusbhc_handle_dn_alive(wusbhc, wusb_dev);
776 break;
777 case WUSB_DN_DISCONNECT:
778 wusbhc_handle_dn_disconnect(wusbhc, wusb_dev);
779 break;
780 case WUSB_DN_MASAVAILCHANGED:
781 case WUSB_DN_RWAKE:
782 case WUSB_DN_SLEEP:
783 /* FIXME: handle these DNs. */
784 break;
785 case WUSB_DN_EPRDY:
786 /* The hardware handles these. */
787 break;
788 default:
789 dev_warn(dev, "unknown DN %u (%d octets) from %u\n",
790 dn_hdr->bType, (int)size, srcaddr);
791 }
792out:
793 d_fnend(3, dev, "(%p, %p) = void\n", wusbhc, dn_hdr);
794 return;
795}
796EXPORT_SYMBOL_GPL(wusbhc_handle_dn);
797
798/*
799 * Disconnect a WUSB device from a the cluster
800 *
801 * @wusbhc
802 * @port Fake port where the device is (wusbhc index, not USB port number).
803 *
804 * In Wireless USB, a disconnect is basically telling the device he is
805 * being disconnected and forgetting about him.
806 *
807 * We send the device a Device Disconnect IE (WUSB1.0[7.5.11]) for 100
808 * ms and then keep going.
809 *
810 * We don't do much in case of error; we always pretend we disabled
811 * the port and disconnected the device. If physically the request
812 * didn't get there (many things can fail in the way there), the stack
813 * will reject the device's communication attempts.
814 *
815 * @wusbhc should be refcounted and locked
816 */
817void __wusbhc_dev_disable(struct wusbhc *wusbhc, u8 port_idx)
818{
819 int result;
820 struct device *dev = wusbhc->dev;
821 struct wusb_dev *wusb_dev;
822 struct wuie_disconnect *ie;
823
824 d_fnstart(3, dev, "(%p, %u)\n", wusbhc, port_idx);
825 result = 0;
826 wusb_dev = wusb_port_by_idx(wusbhc, port_idx)->wusb_dev;
827 if (wusb_dev == NULL) {
828 /* reset no device? ignore */
829 dev_dbg(dev, "DISCONNECT: no device at port %u, ignoring\n",
830 port_idx);
831 goto error;
832 }
833 __wusbhc_dev_disconnect(wusbhc, wusb_port_by_idx(wusbhc, port_idx));
834
835 result = -ENOMEM;
836 ie = kzalloc(sizeof(*ie), GFP_KERNEL);
837 if (ie == NULL)
838 goto error;
839 ie->hdr.bLength = sizeof(*ie);
840 ie->hdr.bIEIdentifier = WUIE_ID_DEVICE_DISCONNECT;
841 ie->bDeviceAddress = wusb_dev->addr;
842 result = wusbhc_mmcie_set(wusbhc, 0, 0, &ie->hdr);
843 if (result < 0) {
844 dev_err(dev, "DISCONNECT: can't set MMC: %d\n", result);
845 goto error_kfree;
846 }
847
848 /* 120ms, hopefully 6 MMCs */
849 msleep(100);
850 wusbhc_mmcie_rm(wusbhc, &ie->hdr);
851error_kfree:
852 kfree(ie);
853error:
854 d_fnend(3, dev, "(%p, %u) = %d\n", wusbhc, port_idx, result);
855 return;
856}
857
858static void wusb_cap_descr_printf(const unsigned level, struct device *dev,
859 const struct usb_wireless_cap_descriptor *wcd)
860{
861 d_printf(level, dev,
862 "WUSB Capability Descriptor\n"
863 " bDevCapabilityType 0x%02x\n"
864 " bmAttributes 0x%02x\n"
865 " wPhyRates 0x%04x\n"
866 " bmTFITXPowerInfo 0x%02x\n"
867 " bmFFITXPowerInfo 0x%02x\n"
868 " bmBandGroup 0x%04x\n"
869 " bReserved 0x%02x\n",
870 wcd->bDevCapabilityType,
871 wcd->bmAttributes,
872 le16_to_cpu(wcd->wPHYRates),
873 wcd->bmTFITXPowerInfo,
874 wcd->bmFFITXPowerInfo,
875 wcd->bmBandGroup,
876 wcd->bReserved);
877}
878
879/*
880 * Walk over the BOS descriptor, verify and grok it
881 *
882 * @usb_dev: referenced
883 * @wusb_dev: referenced and unlocked
884 *
885 * The BOS descriptor is defined at WUSB1.0[7.4.1], and it defines a
886 * "flexible" way to wrap all kinds of descriptors inside an standard
887 * descriptor (wonder why they didn't use normal descriptors,
888 * btw). Not like they lack code.
889 *
890 * At the end we go to look for the WUSB Device Capabilities
891 * (WUSB1.0[7.4.1.1]) that is wrapped in a device capability descriptor
892 * that is part of the BOS descriptor set. That tells us what does the
893 * device support (dual role, beacon type, UWB PHY rates).
894 */
895static int wusb_dev_bos_grok(struct usb_device *usb_dev,
896 struct wusb_dev *wusb_dev,
897 struct usb_bos_descriptor *bos, size_t desc_size)
898{
899 ssize_t result;
900 struct device *dev = &usb_dev->dev;
901 void *itr, *top;
902
903 /* Walk over BOS capabilities, verify them */
904 itr = (void *)bos + sizeof(*bos);
905 top = itr + desc_size - sizeof(*bos);
906 while (itr < top) {
907 struct usb_dev_cap_header *cap_hdr = itr;
908 size_t cap_size;
909 u8 cap_type;
910 if (top - itr < sizeof(*cap_hdr)) {
911 dev_err(dev, "Device BUG? premature end of BOS header "
912 "data [offset 0x%02x]: only %zu bytes left\n",
913 (int)(itr - (void *)bos), top - itr);
914 result = -ENOSPC;
915 goto error_bad_cap;
916 }
917 cap_size = cap_hdr->bLength;
918 cap_type = cap_hdr->bDevCapabilityType;
919 d_printf(4, dev, "BOS Capability: 0x%02x (%zu bytes)\n",
920 cap_type, cap_size);
921 if (cap_size == 0)
922 break;
923 if (cap_size > top - itr) {
924 dev_err(dev, "Device BUG? premature end of BOS data "
925 "[offset 0x%02x cap %02x %zu bytes]: "
926 "only %zu bytes left\n",
927 (int)(itr - (void *)bos),
928 cap_type, cap_size, top - itr);
929 result = -EBADF;
930 goto error_bad_cap;
931 }
932 d_dump(3, dev, itr, cap_size);
933 switch (cap_type) {
934 case USB_CAP_TYPE_WIRELESS_USB:
935 if (cap_size != sizeof(*wusb_dev->wusb_cap_descr))
936 dev_err(dev, "Device BUG? WUSB Capability "
937 "descriptor is %zu bytes vs %zu "
938 "needed\n", cap_size,
939 sizeof(*wusb_dev->wusb_cap_descr));
940 else {
941 wusb_dev->wusb_cap_descr = itr;
942 wusb_cap_descr_printf(3, dev, itr);
943 }
944 break;
945 default:
946 dev_err(dev, "BUG? Unknown BOS capability 0x%02x "
947 "(%zu bytes) at offset 0x%02x\n", cap_type,
948 cap_size, (int)(itr - (void *)bos));
949 }
950 itr += cap_size;
951 }
952 result = 0;
953error_bad_cap:
954 return result;
955}
956
957/*
958 * Add information from the BOS descriptors to the device
959 *
960 * @usb_dev: referenced
961 * @wusb_dev: referenced and unlocked
962 *
963 * So what we do is we alloc a space for the BOS descriptor of 64
964 * bytes; read the first four bytes which include the wTotalLength
965 * field (WUSB1.0[T7-26]) and if it fits in those 64 bytes, read the
966 * whole thing. If not we realloc to that size.
967 *
968 * Then we call the groking function, that will fill up
969 * wusb_dev->wusb_cap_descr, which is what we'll need later on.
970 */
971static int wusb_dev_bos_add(struct usb_device *usb_dev,
972 struct wusb_dev *wusb_dev)
973{
974 ssize_t result;
975 struct device *dev = &usb_dev->dev;
976 struct usb_bos_descriptor *bos;
977 size_t alloc_size = 32, desc_size = 4;
978
979 bos = kmalloc(alloc_size, GFP_KERNEL);
980 if (bos == NULL)
981 return -ENOMEM;
982 result = usb_get_descriptor(usb_dev, USB_DT_BOS, 0, bos, desc_size);
983 if (result < 4) {
984 dev_err(dev, "Can't get BOS descriptor or too short: %zd\n",
985 result);
986 goto error_get_descriptor;
987 }
988 desc_size = le16_to_cpu(bos->wTotalLength);
989 if (desc_size >= alloc_size) {
990 kfree(bos);
991 alloc_size = desc_size;
992 bos = kmalloc(alloc_size, GFP_KERNEL);
993 if (bos == NULL)
994 return -ENOMEM;
995 }
996 result = usb_get_descriptor(usb_dev, USB_DT_BOS, 0, bos, desc_size);
997 if (result < 0 || result != desc_size) {
998 dev_err(dev, "Can't get BOS descriptor or too short (need "
999 "%zu bytes): %zd\n", desc_size, result);
1000 goto error_get_descriptor;
1001 }
1002 if (result < sizeof(*bos)
1003 || le16_to_cpu(bos->wTotalLength) != desc_size) {
1004 dev_err(dev, "Can't get BOS descriptor or too short (need "
1005 "%zu bytes): %zd\n", desc_size, result);
1006 goto error_get_descriptor;
1007 }
1008 d_printf(2, dev, "Got BOS descriptor %zd bytes, %u capabilities\n",
1009 result, bos->bNumDeviceCaps);
1010 d_dump(2, dev, bos, result);
1011 result = wusb_dev_bos_grok(usb_dev, wusb_dev, bos, result);
1012 if (result < 0)
1013 goto error_bad_bos;
1014 wusb_dev->bos = bos;
1015 return 0;
1016
1017error_bad_bos:
1018error_get_descriptor:
1019 kfree(bos);
1020 wusb_dev->wusb_cap_descr = NULL;
1021 return result;
1022}
1023
1024static void wusb_dev_bos_rm(struct wusb_dev *wusb_dev)
1025{
1026 kfree(wusb_dev->bos);
1027 wusb_dev->wusb_cap_descr = NULL;
1028};
1029
1030static struct usb_wireless_cap_descriptor wusb_cap_descr_default = {
1031 .bLength = sizeof(wusb_cap_descr_default),
1032 .bDescriptorType = USB_DT_DEVICE_CAPABILITY,
1033 .bDevCapabilityType = USB_CAP_TYPE_WIRELESS_USB,
1034
1035 .bmAttributes = USB_WIRELESS_BEACON_NONE,
1036 .wPHYRates = cpu_to_le16(USB_WIRELESS_PHY_53),
1037 .bmTFITXPowerInfo = 0,
1038 .bmFFITXPowerInfo = 0,
1039 .bmBandGroup = cpu_to_le16(0x0001), /* WUSB1.0[7.4.1] bottom */
1040 .bReserved = 0
1041};
1042
1043/*
1044 * USB stack's device addition Notifier Callback
1045 *
1046 * Called from drivers/usb/core/hub.c when a new device is added; we
1047 * use this hook to perform certain WUSB specific setup work on the
1048 * new device. As well, it is the first time we can connect the
1049 * wusb_dev and the usb_dev. So we note it down in wusb_dev and take a
1050 * reference that we'll drop.
1051 *
1052 * First we need to determine if the device is a WUSB device (else we
1053 * ignore it). For that we use the speed setting (USB_SPEED_VARIABLE)
1054 * [FIXME: maybe we'd need something more definitive]. If so, we track
1055 * it's usb_busd and from there, the WUSB HC.
1056 *
1057 * Because all WUSB HCs are contained in a 'struct wusbhc', voila, we
1058 * get the wusbhc for the device.
1059 *
1060 * We have a reference on @usb_dev (as we are called at the end of its
1061 * enumeration).
1062 *
1063 * NOTE: @usb_dev locked
1064 */
1065static void wusb_dev_add_ncb(struct usb_device *usb_dev)
1066{
1067 int result = 0;
1068 struct wusb_dev *wusb_dev;
1069 struct wusbhc *wusbhc;
1070 struct device *dev = &usb_dev->dev;
1071 u8 port_idx;
1072
1073 if (usb_dev->wusb == 0 || usb_dev->devnum == 1)
1074 return; /* skip non wusb and wusb RHs */
1075
1076 d_fnstart(3, dev, "(usb_dev %p)\n", usb_dev);
1077
1078 wusbhc = wusbhc_get_by_usb_dev(usb_dev);
1079 if (wusbhc == NULL)
1080 goto error_nodev;
1081 mutex_lock(&wusbhc->mutex);
1082 wusb_dev = __wusb_dev_get_by_usb_dev(wusbhc, usb_dev);
1083 port_idx = wusb_port_no_to_idx(usb_dev->portnum);
1084 mutex_unlock(&wusbhc->mutex);
1085 if (wusb_dev == NULL)
1086 goto error_nodev;
1087 wusb_dev->usb_dev = usb_get_dev(usb_dev);
1088 usb_dev->wusb_dev = wusb_dev_get(wusb_dev);
1089 result = wusb_dev_sec_add(wusbhc, usb_dev, wusb_dev);
1090 if (result < 0) {
1091 dev_err(dev, "Cannot enable security: %d\n", result);
1092 goto error_sec_add;
1093 }
1094 /* Now query the device for it's BOS and attach it to wusb_dev */
1095 result = wusb_dev_bos_add(usb_dev, wusb_dev);
1096 if (result < 0) {
1097 dev_err(dev, "Cannot get BOS descriptors: %d\n", result);
1098 goto error_bos_add;
1099 }
1100 result = wusb_dev_sysfs_add(wusbhc, usb_dev, wusb_dev);
1101 if (result < 0)
1102 goto error_add_sysfs;
1103out:
1104 wusb_dev_put(wusb_dev);
1105 wusbhc_put(wusbhc);
1106error_nodev:
1107 d_fnend(3, dev, "(usb_dev %p) = void\n", usb_dev);
1108 return;
1109
1110 wusb_dev_sysfs_rm(wusb_dev);
1111error_add_sysfs:
1112 wusb_dev_bos_rm(wusb_dev);
1113error_bos_add:
1114 wusb_dev_sec_rm(wusb_dev);
1115error_sec_add:
1116 mutex_lock(&wusbhc->mutex);
1117 __wusbhc_dev_disconnect(wusbhc, wusb_port_by_idx(wusbhc, port_idx));
1118 mutex_unlock(&wusbhc->mutex);
1119 goto out;
1120}
1121
1122/*
1123 * Undo all the steps done at connection by the notifier callback
1124 *
1125 * NOTE: @usb_dev locked
1126 */
1127static void wusb_dev_rm_ncb(struct usb_device *usb_dev)
1128{
1129 struct wusb_dev *wusb_dev = usb_dev->wusb_dev;
1130
1131 if (usb_dev->wusb == 0 || usb_dev->devnum == 1)
1132 return; /* skip non wusb and wusb RHs */
1133
1134 wusb_dev_sysfs_rm(wusb_dev);
1135 wusb_dev_bos_rm(wusb_dev);
1136 wusb_dev_sec_rm(wusb_dev);
1137 wusb_dev->usb_dev = NULL;
1138 usb_dev->wusb_dev = NULL;
1139 wusb_dev_put(wusb_dev);
1140 usb_put_dev(usb_dev);
1141}
1142
1143/*
1144 * Handle notifications from the USB stack (notifier call back)
1145 *
1146 * This is called when the USB stack does a
1147 * usb_{bus,device}_{add,remove}() so we can do WUSB specific
1148 * handling. It is called with [for the case of
1149 * USB_DEVICE_{ADD,REMOVE} with the usb_dev locked.
1150 */
1151int wusb_usb_ncb(struct notifier_block *nb, unsigned long val,
1152 void *priv)
1153{
1154 int result = NOTIFY_OK;
1155
1156 switch (val) {
1157 case USB_DEVICE_ADD:
1158 wusb_dev_add_ncb(priv);
1159 break;
1160 case USB_DEVICE_REMOVE:
1161 wusb_dev_rm_ncb(priv);
1162 break;
1163 case USB_BUS_ADD:
1164 /* ignore (for now) */
1165 case USB_BUS_REMOVE:
1166 break;
1167 default:
1168 WARN_ON(1);
1169 result = NOTIFY_BAD;
1170 };
1171 return result;
1172}
1173
1174/*
1175 * Return a referenced wusb_dev given a @wusbhc and @usb_dev
1176 */
1177struct wusb_dev *__wusb_dev_get_by_usb_dev(struct wusbhc *wusbhc,
1178 struct usb_device *usb_dev)
1179{
1180 struct wusb_dev *wusb_dev;
1181 u8 port_idx;
1182
1183 port_idx = wusb_port_no_to_idx(usb_dev->portnum);
1184 BUG_ON(port_idx > wusbhc->ports_max);
1185 wusb_dev = wusb_port_by_idx(wusbhc, port_idx)->wusb_dev;
1186 if (wusb_dev != NULL) /* ops, device is gone */
1187 wusb_dev_get(wusb_dev);
1188 return wusb_dev;
1189}
1190EXPORT_SYMBOL_GPL(__wusb_dev_get_by_usb_dev);
1191
1192void wusb_dev_destroy(struct kref *_wusb_dev)
1193{
1194 struct wusb_dev *wusb_dev
1195 = container_of(_wusb_dev, struct wusb_dev, refcnt);
1196 list_del_init(&wusb_dev->cack_node);
1197 wusb_dev_free(wusb_dev);
1198 d_fnend(1, NULL, "%s (wusb_dev %p) = void\n", __func__, wusb_dev);
1199}
1200EXPORT_SYMBOL_GPL(wusb_dev_destroy);
1201
1202/*
1203 * Create all the device connect handling infrastructure
1204 *
1205 * This is basically the device info array, Connect Acknowledgement
1206 * (cack) lists, keep-alive timers (and delayed work thread).
1207 */
1208int wusbhc_devconnect_create(struct wusbhc *wusbhc)
1209{
1210 d_fnstart(3, wusbhc->dev, "(wusbhc %p)\n", wusbhc);
1211
1212 wusbhc->keep_alive_ie.hdr.bIEIdentifier = WUIE_ID_KEEP_ALIVE;
1213 wusbhc->keep_alive_ie.hdr.bLength = sizeof(wusbhc->keep_alive_ie.hdr);
1214 INIT_DELAYED_WORK(&wusbhc->keep_alive_timer, wusbhc_keep_alive_run);
1215
1216 wusbhc->cack_ie.hdr.bIEIdentifier = WUIE_ID_CONNECTACK;
1217 wusbhc->cack_ie.hdr.bLength = sizeof(wusbhc->cack_ie.hdr);
1218 INIT_LIST_HEAD(&wusbhc->cack_list);
1219
1220 d_fnend(3, wusbhc->dev, "(wusbhc %p) = void\n", wusbhc);
1221 return 0;
1222}
1223
1224/*
1225 * Release all resources taken by the devconnect stuff
1226 */
1227void wusbhc_devconnect_destroy(struct wusbhc *wusbhc)
1228{
1229 d_fnstart(3, wusbhc->dev, "(wusbhc %p)\n", wusbhc);
1230 d_fnend(3, wusbhc->dev, "(wusbhc %p) = void\n", wusbhc);
1231}
1232
1233/*
1234 * wusbhc_devconnect_start - start accepting device connections
1235 * @wusbhc: the WUSB HC
1236 *
1237 * Sets the Host Info IE to accept all new connections.
1238 *
1239 * FIXME: This also enables the keep alives but this is not necessary
1240 * until there are connected and authenticated devices.
1241 */
1242int wusbhc_devconnect_start(struct wusbhc *wusbhc,
1243 const struct wusb_ckhdid *chid)
1244{
1245 struct device *dev = wusbhc->dev;
1246 struct wuie_host_info *hi;
1247 int result;
1248
1249 hi = kzalloc(sizeof(*hi), GFP_KERNEL);
1250 if (hi == NULL)
1251 return -ENOMEM;
1252
1253 hi->hdr.bLength = sizeof(*hi);
1254 hi->hdr.bIEIdentifier = WUIE_ID_HOST_INFO;
1255 hi->attributes = cpu_to_le16((wusbhc->rsv->stream << 3) | WUIE_HI_CAP_ALL);
1256 hi->CHID = *chid;
1257 result = wusbhc_mmcie_set(wusbhc, 0, 0, &hi->hdr);
1258 if (result < 0) {
1259 dev_err(dev, "Cannot add Host Info MMCIE: %d\n", result);
1260 goto error_mmcie_set;
1261 }
1262 wusbhc->wuie_host_info = hi;
1263
1264 queue_delayed_work(wusbd, &wusbhc->keep_alive_timer,
1265 (wusbhc->trust_timeout*CONFIG_HZ)/1000/2);
1266
1267 return 0;
1268
1269error_mmcie_set:
1270 kfree(hi);
1271 return result;
1272}
1273
1274/*
1275 * wusbhc_devconnect_stop - stop managing connected devices
1276 * @wusbhc: the WUSB HC
1277 *
1278 * Removes the Host Info IE and stops the keep alives.
1279 *
1280 * FIXME: should this disconnect all devices?
1281 */
1282void wusbhc_devconnect_stop(struct wusbhc *wusbhc)
1283{
1284 cancel_delayed_work_sync(&wusbhc->keep_alive_timer);
1285 WARN_ON(!list_empty(&wusbhc->cack_list));
1286
1287 wusbhc_mmcie_rm(wusbhc, &wusbhc->wuie_host_info->hdr);
1288 kfree(wusbhc->wuie_host_info);
1289 wusbhc->wuie_host_info = NULL;
1290}
1291
1292/*
1293 * wusb_set_dev_addr - set the WUSB device address used by the host
1294 * @wusbhc: the WUSB HC the device is connect to
1295 * @wusb_dev: the WUSB device
1296 * @addr: new device address
1297 */
1298int wusb_set_dev_addr(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev, u8 addr)
1299{
1300 int result;
1301
1302 wusb_dev->addr = addr;
1303 result = wusbhc->dev_info_set(wusbhc, wusb_dev);
1304 if (result < 0)
1305 dev_err(wusbhc->dev, "device %d: failed to set device "
1306 "address\n", wusb_dev->port_idx);
1307 else
1308 dev_info(wusbhc->dev, "device %d: %s addr %u\n",
1309 wusb_dev->port_idx,
1310 (addr & WUSB_DEV_ADDR_UNAUTH) ? "unauth" : "auth",
1311 wusb_dev->addr);
1312
1313 return result;
1314}
diff --git a/drivers/usb/wusbcore/mmc.c b/drivers/usb/wusbcore/mmc.c
new file mode 100644
index 000000000000..e5390b77aaaa
--- /dev/null
+++ b/drivers/usb/wusbcore/mmc.c
@@ -0,0 +1,329 @@
1/*
2 * WUSB Wire Adapter: Control/Data Streaming Interface (WUSB[8])
3 * MMC (Microscheduled Management Command) handling
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 * WUIEs and MMC IEs...well, they are almost the same at the end. MMC
24 * IEs are Wireless USB IEs that go into the MMC period...[what is
25 * that? look in Design-overview.txt].
26 *
27 *
28 * This is a simple subsystem to keep track of which IEs are being
29 * sent by the host in the MMC period.
30 *
31 * For each WUIE we ask to send, we keep it in an array, so we can
32 * request its removal later, or replace the content. They are tracked
33 * by pointer, so be sure to use the same pointer if you want to
34 * remove it or update the contents.
35 *
36 * FIXME:
37 * - add timers that autoremove intervalled IEs?
38 */
39#include <linux/usb/wusb.h>
40#include "wusbhc.h"
41
42/* Initialize the MMCIEs handling mechanism */
43int wusbhc_mmcie_create(struct wusbhc *wusbhc)
44{
45 u8 mmcies = wusbhc->mmcies_max;
46 wusbhc->mmcie = kzalloc(mmcies * sizeof(wusbhc->mmcie[0]), GFP_KERNEL);
47 if (wusbhc->mmcie == NULL)
48 return -ENOMEM;
49 mutex_init(&wusbhc->mmcie_mutex);
50 return 0;
51}
52
53/* Release resources used by the MMCIEs handling mechanism */
54void wusbhc_mmcie_destroy(struct wusbhc *wusbhc)
55{
56 kfree(wusbhc->mmcie);
57}
58
59/*
60 * Add or replace an MMC Wireless USB IE.
61 *
62 * @interval: See WUSB1.0[8.5.3.1]
63 * @repeat_cnt: See WUSB1.0[8.5.3.1]
64 * @handle: See WUSB1.0[8.5.3.1]
65 * @wuie: Pointer to the header of the WUSB IE data to add.
66 * MUST BE allocated in a kmalloc buffer (no stack or
67 * vmalloc).
68 * THE CALLER ALWAYS OWNS THE POINTER (we don't free it
69 * on remove, we just forget about it).
70 * @returns: 0 if ok, < 0 errno code on error.
71 *
72 * Goes over the *whole* @wusbhc->mmcie array looking for (a) the
73 * first free spot and (b) if @wuie is already in the array (aka:
74 * transmitted in the MMCs) the spot were it is.
75 *
76 * If present, we "overwrite it" (update).
77 *
78 *
79 * NOTE: Need special ordering rules -- see below WUSB1.0 Table 7-38.
80 * The host uses the handle as the 'sort' index. We
81 * allocate the last one always for the WUIE_ID_HOST_INFO, and
82 * the rest, first come first serve in inverse order.
83 *
84 * Host software must make sure that it adds the other IEs in
85 * the right order... the host hardware is responsible for
86 * placing the WCTA IEs in the right place with the other IEs
87 * set by host software.
88 *
89 * NOTE: we can access wusbhc->wa_descr without locking because it is
90 * read only.
91 */
92int wusbhc_mmcie_set(struct wusbhc *wusbhc, u8 interval, u8 repeat_cnt,
93 struct wuie_hdr *wuie)
94{
95 int result = -ENOBUFS;
96 struct device *dev = wusbhc->dev;
97 unsigned handle, itr;
98
99 /* Search a handle, taking into account the ordering */
100 mutex_lock(&wusbhc->mmcie_mutex);
101 switch (wuie->bIEIdentifier) {
102 case WUIE_ID_HOST_INFO:
103 /* Always last */
104 handle = wusbhc->mmcies_max - 1;
105 break;
106 case WUIE_ID_ISOCH_DISCARD:
107 dev_err(wusbhc->dev, "Special ordering case for WUIE ID 0x%x "
108 "unimplemented\n", wuie->bIEIdentifier);
109 result = -ENOSYS;
110 goto error_unlock;
111 default:
112 /* search for it or find the last empty slot */
113 handle = ~0;
114 for (itr = 0; itr < wusbhc->mmcies_max - 1; itr++) {
115 if (wusbhc->mmcie[itr] == wuie) {
116 handle = itr;
117 break;
118 }
119 if (wusbhc->mmcie[itr] == NULL)
120 handle = itr;
121 }
122 if (handle == ~0) {
123 if (printk_ratelimit())
124 dev_err(dev, "MMC handle space exhausted\n");
125 goto error_unlock;
126 }
127 }
128 result = (wusbhc->mmcie_add)(wusbhc, interval, repeat_cnt, handle,
129 wuie);
130 if (result >= 0)
131 wusbhc->mmcie[handle] = wuie;
132error_unlock:
133 mutex_unlock(&wusbhc->mmcie_mutex);
134 return result;
135}
136EXPORT_SYMBOL_GPL(wusbhc_mmcie_set);
137
138/*
139 * Remove an MMC IE previously added with wusbhc_mmcie_set()
140 *
141 * @wuie Pointer used to add the WUIE
142 */
143void wusbhc_mmcie_rm(struct wusbhc *wusbhc, struct wuie_hdr *wuie)
144{
145 int result;
146 struct device *dev = wusbhc->dev;
147 unsigned handle, itr;
148
149 mutex_lock(&wusbhc->mmcie_mutex);
150 for (itr = 0; itr < wusbhc->mmcies_max; itr++)
151 if (wusbhc->mmcie[itr] == wuie) {
152 handle = itr;
153 goto found;
154 }
155 mutex_unlock(&wusbhc->mmcie_mutex);
156 return;
157
158found:
159 result = (wusbhc->mmcie_rm)(wusbhc, handle);
160 if (result == 0)
161 wusbhc->mmcie[itr] = NULL;
162 else if (printk_ratelimit())
163 dev_err(dev, "MMC: Failed to remove IE %p (0x%02x)\n",
164 wuie, wuie->bIEIdentifier);
165 mutex_unlock(&wusbhc->mmcie_mutex);
166 return;
167}
168EXPORT_SYMBOL_GPL(wusbhc_mmcie_rm);
169
170/*
171 * wusbhc_start - start transmitting MMCs and accepting connections
172 * @wusbhc: the HC to start
173 * @chid: the CHID to use for this host
174 *
175 * Establishes a cluster reservation, enables device connections, and
176 * starts MMCs with appropriate DNTS parameters.
177 */
178int wusbhc_start(struct wusbhc *wusbhc, const struct wusb_ckhdid *chid)
179{
180 int result;
181 struct device *dev = wusbhc->dev;
182
183 WARN_ON(wusbhc->wuie_host_info != NULL);
184
185 result = wusbhc_rsv_establish(wusbhc);
186 if (result < 0) {
187 dev_err(dev, "cannot establish cluster reservation: %d\n",
188 result);
189 goto error_rsv_establish;
190 }
191
192 result = wusbhc_devconnect_start(wusbhc, chid);
193 if (result < 0) {
194 dev_err(dev, "error enabling device connections: %d\n", result);
195 goto error_devconnect_start;
196 }
197
198 result = wusbhc_sec_start(wusbhc);
199 if (result < 0) {
200 dev_err(dev, "error starting security in the HC: %d\n", result);
201 goto error_sec_start;
202 }
203 /* FIXME: the choice of the DNTS parameters is somewhat
204 * arbitrary */
205 result = wusbhc->set_num_dnts(wusbhc, 0, 15);
206 if (result < 0) {
207 dev_err(dev, "Cannot set DNTS parameters: %d\n", result);
208 goto error_set_num_dnts;
209 }
210 result = wusbhc->start(wusbhc);
211 if (result < 0) {
212 dev_err(dev, "error starting wusbch: %d\n", result);
213 goto error_wusbhc_start;
214 }
215 wusbhc->active = 1;
216 return 0;
217
218error_wusbhc_start:
219 wusbhc_sec_stop(wusbhc);
220error_set_num_dnts:
221error_sec_start:
222 wusbhc_devconnect_stop(wusbhc);
223error_devconnect_start:
224 wusbhc_rsv_terminate(wusbhc);
225error_rsv_establish:
226 return result;
227}
228
229/*
230 * Disconnect all from the WUSB Channel
231 *
232 * Send a Host Disconnect IE in the MMC, wait, don't send it any more
233 */
234static int __wusbhc_host_disconnect_ie(struct wusbhc *wusbhc)
235{
236 int result = -ENOMEM;
237 struct wuie_host_disconnect *host_disconnect_ie;
238 might_sleep();
239 host_disconnect_ie = kmalloc(sizeof(*host_disconnect_ie), GFP_KERNEL);
240 if (host_disconnect_ie == NULL)
241 goto error_alloc;
242 host_disconnect_ie->hdr.bLength = sizeof(*host_disconnect_ie);
243 host_disconnect_ie->hdr.bIEIdentifier = WUIE_ID_HOST_DISCONNECT;
244 result = wusbhc_mmcie_set(wusbhc, 0, 0, &host_disconnect_ie->hdr);
245 if (result < 0)
246 goto error_mmcie_set;
247
248 /* WUSB1.0[8.5.3.1 & 7.5.2] */
249 msleep(100);
250 wusbhc_mmcie_rm(wusbhc, &host_disconnect_ie->hdr);
251error_mmcie_set:
252 kfree(host_disconnect_ie);
253error_alloc:
254 return result;
255}
256
257/*
258 * wusbhc_stop - stop transmitting MMCs
259 * @wusbhc: the HC to stop
260 *
261 * Send a Host Disconnect IE, wait, remove all the MMCs (stop sending MMCs).
262 *
263 * If we can't allocate a Host Stop IE, screw it, we don't notify the
264 * devices we are disconnecting...
265 */
266void wusbhc_stop(struct wusbhc *wusbhc)
267{
268 if (wusbhc->active) {
269 wusbhc->active = 0;
270 wusbhc->stop(wusbhc);
271 wusbhc_sec_stop(wusbhc);
272 __wusbhc_host_disconnect_ie(wusbhc);
273 wusbhc_devconnect_stop(wusbhc);
274 wusbhc_rsv_terminate(wusbhc);
275 }
276}
277EXPORT_SYMBOL_GPL(wusbhc_stop);
278
279/*
280 * Change the CHID in a WUSB Channel
281 *
282 * If it is just a new CHID, send a Host Disconnect IE and then change
283 * the CHID IE.
284 */
285static int __wusbhc_chid_change(struct wusbhc *wusbhc,
286 const struct wusb_ckhdid *chid)
287{
288 int result = -ENOSYS;
289 struct device *dev = wusbhc->dev;
290 dev_err(dev, "%s() not implemented yet\n", __func__);
291 return result;
292
293 BUG_ON(wusbhc->wuie_host_info == NULL);
294 __wusbhc_host_disconnect_ie(wusbhc);
295 wusbhc->wuie_host_info->CHID = *chid;
296 result = wusbhc_mmcie_set(wusbhc, 0, 0, &wusbhc->wuie_host_info->hdr);
297 if (result < 0)
298 dev_err(dev, "Can't update Host Info WUSB IE: %d\n", result);
299 return result;
300}
301
302/*
303 * Set/reset/update a new CHID
304 *
305 * Depending on the previous state of the MMCs, start, stop or change
306 * the sent MMC. This effectively switches the host controller on and
307 * off (radio wise).
308 */
309int wusbhc_chid_set(struct wusbhc *wusbhc, const struct wusb_ckhdid *chid)
310{
311 int result = 0;
312
313 if (memcmp(chid, &wusb_ckhdid_zero, sizeof(chid)) == 0)
314 chid = NULL;
315
316 mutex_lock(&wusbhc->mutex);
317 if (wusbhc->active) {
318 if (chid)
319 result = __wusbhc_chid_change(wusbhc, chid);
320 else
321 wusbhc_stop(wusbhc);
322 } else {
323 if (chid)
324 wusbhc_start(wusbhc, chid);
325 }
326 mutex_unlock(&wusbhc->mutex);
327 return result;
328}
329EXPORT_SYMBOL_GPL(wusbhc_chid_set);
diff --git a/drivers/usb/wusbcore/pal.c b/drivers/usb/wusbcore/pal.c
new file mode 100644
index 000000000000..7cc51e9905cf
--- /dev/null
+++ b/drivers/usb/wusbcore/pal.c
@@ -0,0 +1,42 @@
1/*
2 * Wireless USB Host Controller
3 * UWB Protocol Adaptation Layer (PAL) glue.
4 *
5 * Copyright (C) 2008 Cambridge Silicon Radio Ltd.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License version
9 * 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19#include "wusbhc.h"
20
21/**
22 * wusbhc_pal_register - register the WUSB HC as a UWB PAL
23 * @wusbhc: the WUSB HC
24 */
25int wusbhc_pal_register(struct wusbhc *wusbhc)
26{
27 uwb_pal_init(&wusbhc->pal);
28
29 wusbhc->pal.name = "wusbhc";
30 wusbhc->pal.device = wusbhc->usb_hcd.self.controller;
31
32 return uwb_pal_register(wusbhc->uwb_rc, &wusbhc->pal);
33}
34
35/**
36 * wusbhc_pal_register - unregister the WUSB HC as a UWB PAL
37 * @wusbhc: the WUSB HC
38 */
39void wusbhc_pal_unregister(struct wusbhc *wusbhc)
40{
41 uwb_pal_unregister(wusbhc->uwb_rc, &wusbhc->pal);
42}
diff --git a/drivers/usb/wusbcore/reservation.c b/drivers/usb/wusbcore/reservation.c
new file mode 100644
index 000000000000..fc63e77ded2d
--- /dev/null
+++ b/drivers/usb/wusbcore/reservation.c
@@ -0,0 +1,115 @@
1/*
2 * WUSB cluster reservation management
3 *
4 * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18#include <linux/kernel.h>
19#include <linux/uwb.h>
20
21#include "wusbhc.h"
22
23/*
24 * WUSB cluster reservations are multicast reservations with the
25 * broadcast cluster ID (BCID) as the target DevAddr.
26 *
27 * FIXME: consider adjusting the reservation depending on what devices
28 * are attached.
29 */
30
31static int wusbhc_bwa_set(struct wusbhc *wusbhc, u8 stream,
32 const struct uwb_mas_bm *mas)
33{
34 if (mas == NULL)
35 mas = &uwb_mas_bm_zero;
36 return wusbhc->bwa_set(wusbhc, stream, mas);
37}
38
39/**
40 * wusbhc_rsv_complete_cb - WUSB HC reservation complete callback
41 * @rsv: the reservation
42 *
43 * Either set or clear the HC's view of the reservation.
44 *
45 * FIXME: when a reservation is denied the HC should be stopped.
46 */
47static void wusbhc_rsv_complete_cb(struct uwb_rsv *rsv)
48{
49 struct wusbhc *wusbhc = rsv->pal_priv;
50 struct device *dev = wusbhc->dev;
51 char buf[72];
52
53 switch (rsv->state) {
54 case UWB_RSV_STATE_O_ESTABLISHED:
55 bitmap_scnprintf(buf, sizeof(buf), rsv->mas.bm, UWB_NUM_MAS);
56 dev_dbg(dev, "established reservation: %s\n", buf);
57 wusbhc_bwa_set(wusbhc, rsv->stream, &rsv->mas);
58 break;
59 case UWB_RSV_STATE_NONE:
60 dev_dbg(dev, "removed reservation\n");
61 wusbhc_bwa_set(wusbhc, 0, NULL);
62 wusbhc->rsv = NULL;
63 break;
64 default:
65 dev_dbg(dev, "unexpected reservation state: %d\n", rsv->state);
66 break;
67 }
68}
69
70
71/**
72 * wusbhc_rsv_establish - establish a reservation for the cluster
73 * @wusbhc: the WUSB HC requesting a bandwith reservation
74 */
75int wusbhc_rsv_establish(struct wusbhc *wusbhc)
76{
77 struct uwb_rc *rc = wusbhc->uwb_rc;
78 struct uwb_rsv *rsv;
79 struct uwb_dev_addr bcid;
80 int ret;
81
82 rsv = uwb_rsv_create(rc, wusbhc_rsv_complete_cb, wusbhc);
83 if (rsv == NULL)
84 return -ENOMEM;
85
86 bcid.data[0] = wusbhc->cluster_id;
87 bcid.data[1] = 0;
88
89 rsv->owner = &rc->uwb_dev;
90 rsv->target.type = UWB_RSV_TARGET_DEVADDR;
91 rsv->target.devaddr = bcid;
92 rsv->type = UWB_DRP_TYPE_PRIVATE;
93 rsv->max_mas = 256;
94 rsv->min_mas = 16; /* one MAS per zone? */
95 rsv->sparsity = 16; /* at least one MAS in each zone? */
96 rsv->is_multicast = true;
97
98 ret = uwb_rsv_establish(rsv);
99 if (ret == 0)
100 wusbhc->rsv = rsv;
101 else
102 uwb_rsv_destroy(rsv);
103 return ret;
104}
105
106
107/**
108 * wusbhc_rsv_terminate - terminate any cluster reservation
109 * @wusbhc: the WUSB host whose reservation is to be terminated
110 */
111void wusbhc_rsv_terminate(struct wusbhc *wusbhc)
112{
113 if (wusbhc->rsv)
114 uwb_rsv_terminate(wusbhc->rsv);
115}
diff --git a/drivers/usb/wusbcore/rh.c b/drivers/usb/wusbcore/rh.c
new file mode 100644
index 000000000000..267a64325106
--- /dev/null
+++ b/drivers/usb/wusbcore/rh.c
@@ -0,0 +1,477 @@
1/*
2 * Wireless USB Host Controller
3 * Root Hub operations
4 *
5 *
6 * Copyright (C) 2005-2006 Intel Corporation
7 * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License version
11 * 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301, USA.
22 *
23 *
24 * We fake a root hub that has fake ports (as many as simultaneous
25 * devices the Wireless USB Host Controller can deal with). For each
26 * port we keep an state in @wusbhc->port[index] identical to the one
27 * specified in the USB2.0[ch11] spec and some extra device
28 * information that complements the one in 'struct usb_device' (as
29 * this lacs a hcpriv pointer).
30 *
31 * Note this is common to WHCI and HWA host controllers.
32 *
33 * Through here we enable most of the state changes that the USB stack
34 * will use to connect or disconnect devices. We need to do some
35 * forced adaptation of Wireless USB device states vs. wired:
36 *
37 * USB: WUSB:
38 *
39 * Port Powered-off port slot n/a
40 * Powered-on port slot available
41 * Disconnected port slot available
42 * Connected port slot assigned device
43 * device sent DN_Connect
44 * device was authenticated
45 * Enabled device is authenticated, transitioned
46 * from unauth -> auth -> default address
47 * -> enabled
48 * Reset disconnect
49 * Disable disconnect
50 *
51 * This maps the standard USB port states with the WUSB device states
52 * so we can fake ports without having to modify the USB stack.
53 *
54 * FIXME: this process will change in the future
55 *
56 *
57 * ENTRY POINTS
58 *
59 * Our entry points into here are, as in hcd.c, the USB stack root hub
60 * ops defined in the usb_hcd struct:
61 *
62 * wusbhc_rh_status_data() Provide hub and port status data bitmap
63 *
64 * wusbhc_rh_control() Execution of all the major requests
65 * you can do to a hub (Set|Clear
66 * features, get descriptors, status, etc).
67 *
68 * wusbhc_rh_[suspend|resume]() That
69 *
70 * wusbhc_rh_start_port_reset() ??? unimplemented
71 */
72#include "wusbhc.h"
73
74#define D_LOCAL 0
75#include <linux/uwb/debug.h>
76
77/*
78 * Reset a fake port
79 *
80 * This can be called to reset a port from any other state or to reset
81 * it when connecting. In Wireless USB they are different; when doing
82 * a new connect that involves going over the authentication. When
83 * just reseting, its a different story.
84 *
85 * The Linux USB stack resets a port twice before it considers it
86 * enabled, so we have to detect and ignore that.
87 *
88 * @wusbhc is assumed referenced and @wusbhc->mutex unlocked.
89 *
90 * Supposedly we are the only thread accesing @wusbhc->port; in any
91 * case, maybe we should move the mutex locking from
92 * wusbhc_devconnect_auth() to here.
93 *
94 * @port_idx refers to the wusbhc's port index, not the USB port number
95 */
96static int wusbhc_rh_port_reset(struct wusbhc *wusbhc, u8 port_idx)
97{
98 int result = 0;
99 struct wusb_port *port = wusb_port_by_idx(wusbhc, port_idx);
100
101 d_fnstart(3, wusbhc->dev, "(wusbhc %p port_idx %u)\n",
102 wusbhc, port_idx);
103 if (port->reset_count == 0) {
104 wusbhc_devconnect_auth(wusbhc, port_idx);
105 port->reset_count++;
106 } else if (port->reset_count == 1)
107 /* see header */
108 d_printf(2, wusbhc->dev, "Ignoring second reset on port_idx "
109 "%u\n", port_idx);
110 else
111 result = wusbhc_dev_reset(wusbhc, port_idx);
112 d_fnend(3, wusbhc->dev, "(wusbhc %p port_idx %u) = %d\n",
113 wusbhc, port_idx, result);
114 return result;
115}
116
117/*
118 * Return the hub change status bitmap
119 *
120 * The bits in the change status bitmap are cleared when a
121 * ClearPortFeature request is issued (USB2.0[11.12.3,11.12.4].
122 *
123 * @wusbhc is assumed referenced and @wusbhc->mutex unlocked.
124 *
125 * WARNING!! This gets called from atomic context; we cannot get the
126 * mutex--the only race condition we can find is some bit
127 * changing just after we copy it, which shouldn't be too
128 * big of a problem [and we can't make it an spinlock
129 * because other parts need to take it and sleep] .
130 *
131 * @usb_hcd is refcounted, so it won't dissapear under us
132 * and before killing a host, the polling of the root hub
133 * would be stopped anyway.
134 */
135int wusbhc_rh_status_data(struct usb_hcd *usb_hcd, char *_buf)
136{
137 struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
138 size_t cnt, size;
139 unsigned long *buf = (unsigned long *) _buf;
140
141 d_fnstart(1, wusbhc->dev, "(wusbhc %p)\n", wusbhc);
142 /* WE DON'T LOCK, see comment */
143 size = wusbhc->ports_max + 1 /* hub bit */;
144 size = (size + 8 - 1) / 8; /* round to bytes */
145 for (cnt = 0; cnt < wusbhc->ports_max; cnt++)
146 if (wusb_port_by_idx(wusbhc, cnt)->change)
147 set_bit(cnt + 1, buf);
148 else
149 clear_bit(cnt + 1, buf);
150 d_fnend(1, wusbhc->dev, "(wusbhc %p) %u, buffer:\n", wusbhc, (int)size);
151 d_dump(1, wusbhc->dev, _buf, size);
152 return size;
153}
154EXPORT_SYMBOL_GPL(wusbhc_rh_status_data);
155
156/*
157 * Return the hub's desciptor
158 *
159 * NOTE: almost cut and paste from ehci-hub.c
160 *
161 * @wusbhc is assumed referenced and @wusbhc->mutex unlocked
162 */
163static int wusbhc_rh_get_hub_descr(struct wusbhc *wusbhc, u16 wValue,
164 u16 wIndex,
165 struct usb_hub_descriptor *descr,
166 u16 wLength)
167{
168 u16 temp = 1 + (wusbhc->ports_max / 8);
169 u8 length = 7 + 2 * temp;
170
171 if (wLength < length)
172 return -ENOSPC;
173 descr->bDescLength = 7 + 2 * temp;
174 descr->bDescriptorType = 0x29; /* HUB type */
175 descr->bNbrPorts = wusbhc->ports_max;
176 descr->wHubCharacteristics = cpu_to_le16(
177 0x00 /* All ports power at once */
178 | 0x00 /* not part of compound device */
179 | 0x10 /* No overcurrent protection */
180 | 0x00 /* 8 FS think time FIXME ?? */
181 | 0x00); /* No port indicators */
182 descr->bPwrOn2PwrGood = 0;
183 descr->bHubContrCurrent = 0;
184 /* two bitmaps: ports removable, and usb 1.0 legacy PortPwrCtrlMask */
185 memset(&descr->bitmap[0], 0, temp);
186 memset(&descr->bitmap[temp], 0xff, temp);
187 return 0;
188}
189
190/*
191 * Clear a hub feature
192 *
193 * @wusbhc is assumed referenced and @wusbhc->mutex unlocked.
194 *
195 * Nothing to do, so no locking needed ;)
196 */
197static int wusbhc_rh_clear_hub_feat(struct wusbhc *wusbhc, u16 feature)
198{
199 int result;
200 struct device *dev = wusbhc->dev;
201
202 d_fnstart(4, dev, "(%p, feature 0x%04u)\n", wusbhc, feature);
203 switch (feature) {
204 case C_HUB_LOCAL_POWER:
205 /* FIXME: maybe plug bit 0 to the power input status,
206 * if any?
207 * see wusbhc_rh_get_hub_status() */
208 case C_HUB_OVER_CURRENT:
209 result = 0;
210 break;
211 default:
212 result = -EPIPE;
213 }
214 d_fnend(4, dev, "(%p, feature 0x%04u), %d\n", wusbhc, feature, result);
215 return result;
216}
217
218/*
219 * Return hub status (it is always zero...)
220 *
221 * @wusbhc is assumed referenced and @wusbhc->mutex unlocked.
222 *
223 * Nothing to do, so no locking needed ;)
224 */
225static int wusbhc_rh_get_hub_status(struct wusbhc *wusbhc, u32 *buf,
226 u16 wLength)
227{
228 /* FIXME: maybe plug bit 0 to the power input status (if any)? */
229 *buf = 0;
230 return 0;
231}
232
233/*
234 * Set a port feature
235 *
236 * @wusbhc is assumed referenced and @wusbhc->mutex unlocked.
237 */
238static int wusbhc_rh_set_port_feat(struct wusbhc *wusbhc, u16 feature,
239 u8 selector, u8 port_idx)
240{
241 int result = -EINVAL;
242 struct device *dev = wusbhc->dev;
243
244 d_fnstart(4, dev, "(feat 0x%04u, selector 0x%u, port_idx %d)\n",
245 feature, selector, port_idx);
246
247 if (port_idx > wusbhc->ports_max)
248 goto error;
249
250 switch (feature) {
251 /* According to USB2.0[11.24.2.13]p2, these features
252 * are not required to be implemented. */
253 case USB_PORT_FEAT_C_OVER_CURRENT:
254 case USB_PORT_FEAT_C_ENABLE:
255 case USB_PORT_FEAT_C_SUSPEND:
256 case USB_PORT_FEAT_C_CONNECTION:
257 case USB_PORT_FEAT_C_RESET:
258 result = 0;
259 break;
260
261 case USB_PORT_FEAT_POWER:
262 /* No such thing, but we fake it works */
263 mutex_lock(&wusbhc->mutex);
264 wusb_port_by_idx(wusbhc, port_idx)->status |= USB_PORT_STAT_POWER;
265 mutex_unlock(&wusbhc->mutex);
266 result = 0;
267 break;
268 case USB_PORT_FEAT_RESET:
269 result = wusbhc_rh_port_reset(wusbhc, port_idx);
270 break;
271 case USB_PORT_FEAT_ENABLE:
272 case USB_PORT_FEAT_SUSPEND:
273 dev_err(dev, "(port_idx %d) set feat %d/%d UNIMPLEMENTED\n",
274 port_idx, feature, selector);
275 result = -ENOSYS;
276 break;
277 default:
278 dev_err(dev, "(port_idx %d) set feat %d/%d UNKNOWN\n",
279 port_idx, feature, selector);
280 result = -EPIPE;
281 break;
282 }
283error:
284 d_fnend(4, dev, "(feat 0x%04u, selector 0x%u, port_idx %d) = %d\n",
285 feature, selector, port_idx, result);
286 return result;
287}
288
289/*
290 * Clear a port feature...
291 *
292 * @wusbhc is assumed referenced and @wusbhc->mutex unlocked.
293 */
294static int wusbhc_rh_clear_port_feat(struct wusbhc *wusbhc, u16 feature,
295 u8 selector, u8 port_idx)
296{
297 int result = -EINVAL;
298 struct device *dev = wusbhc->dev;
299
300 d_fnstart(4, dev, "(wusbhc %p feat 0x%04x selector %d port_idx %d)\n",
301 wusbhc, feature, selector, port_idx);
302
303 if (port_idx > wusbhc->ports_max)
304 goto error;
305
306 mutex_lock(&wusbhc->mutex);
307 result = 0;
308 switch (feature) {
309 case USB_PORT_FEAT_POWER: /* fake port always on */
310 /* According to USB2.0[11.24.2.7.1.4], no need to implement? */
311 case USB_PORT_FEAT_C_OVER_CURRENT:
312 break;
313 case USB_PORT_FEAT_C_RESET:
314 wusb_port_by_idx(wusbhc, port_idx)->change &= ~USB_PORT_STAT_C_RESET;
315 break;
316 case USB_PORT_FEAT_C_CONNECTION:
317 wusb_port_by_idx(wusbhc, port_idx)->change &= ~USB_PORT_STAT_C_CONNECTION;
318 break;
319 case USB_PORT_FEAT_ENABLE:
320 __wusbhc_dev_disable(wusbhc, port_idx);
321 break;
322 case USB_PORT_FEAT_C_ENABLE:
323 wusb_port_by_idx(wusbhc, port_idx)->change &= ~USB_PORT_STAT_C_ENABLE;
324 break;
325 case USB_PORT_FEAT_SUSPEND:
326 case USB_PORT_FEAT_C_SUSPEND:
327 case 0xffff: /* ??? FIXME */
328 dev_err(dev, "(port_idx %d) Clear feat %d/%d UNIMPLEMENTED\n",
329 port_idx, feature, selector);
330 /* dump_stack(); */
331 result = -ENOSYS;
332 break;
333 default:
334 dev_err(dev, "(port_idx %d) Clear feat %d/%d UNKNOWN\n",
335 port_idx, feature, selector);
336 result = -EPIPE;
337 break;
338 }
339 mutex_unlock(&wusbhc->mutex);
340error:
341 d_fnend(4, dev, "(wusbhc %p feat 0x%04x selector %d port_idx %d) = "
342 "%d\n", wusbhc, feature, selector, port_idx, result);
343 return result;
344}
345
346/*
347 * Return the port's status
348 *
349 * @wusbhc is assumed referenced and @wusbhc->mutex unlocked.
350 */
351static int wusbhc_rh_get_port_status(struct wusbhc *wusbhc, u16 port_idx,
352 u32 *_buf, u16 wLength)
353{
354 int result = -EINVAL;
355 u16 *buf = (u16 *) _buf;
356
357 d_fnstart(1, wusbhc->dev, "(wusbhc %p port_idx %u wLength %u)\n",
358 wusbhc, port_idx, wLength);
359 if (port_idx > wusbhc->ports_max)
360 goto error;
361 mutex_lock(&wusbhc->mutex);
362 buf[0] = cpu_to_le16(wusb_port_by_idx(wusbhc, port_idx)->status);
363 buf[1] = cpu_to_le16(wusb_port_by_idx(wusbhc, port_idx)->change);
364 result = 0;
365 mutex_unlock(&wusbhc->mutex);
366error:
367 d_fnend(1, wusbhc->dev, "(wusbhc %p) = %d, buffer:\n", wusbhc, result);
368 d_dump(1, wusbhc->dev, _buf, wLength);
369 return result;
370}
371
372/*
373 * Entry point for Root Hub operations
374 *
375 * @wusbhc is assumed referenced and @wusbhc->mutex unlocked.
376 */
377int wusbhc_rh_control(struct usb_hcd *usb_hcd, u16 reqntype, u16 wValue,
378 u16 wIndex, char *buf, u16 wLength)
379{
380 int result = -ENOSYS;
381 struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
382
383 switch (reqntype) {
384 case GetHubDescriptor:
385 result = wusbhc_rh_get_hub_descr(
386 wusbhc, wValue, wIndex,
387 (struct usb_hub_descriptor *) buf, wLength);
388 break;
389 case ClearHubFeature:
390 result = wusbhc_rh_clear_hub_feat(wusbhc, wValue);
391 break;
392 case GetHubStatus:
393 result = wusbhc_rh_get_hub_status(wusbhc, (u32 *)buf, wLength);
394 break;
395
396 case SetPortFeature:
397 result = wusbhc_rh_set_port_feat(wusbhc, wValue, wIndex >> 8,
398 (wIndex & 0xff) - 1);
399 break;
400 case ClearPortFeature:
401 result = wusbhc_rh_clear_port_feat(wusbhc, wValue, wIndex >> 8,
402 (wIndex & 0xff) - 1);
403 break;
404 case GetPortStatus:
405 result = wusbhc_rh_get_port_status(wusbhc, wIndex - 1,
406 (u32 *)buf, wLength);
407 break;
408
409 case SetHubFeature:
410 default:
411 dev_err(wusbhc->dev, "%s (%p [%p], %x, %x, %x, %p, %x) "
412 "UNIMPLEMENTED\n", __func__, usb_hcd, wusbhc, reqntype,
413 wValue, wIndex, buf, wLength);
414 /* dump_stack(); */
415 result = -ENOSYS;
416 }
417 return result;
418}
419EXPORT_SYMBOL_GPL(wusbhc_rh_control);
420
421int wusbhc_rh_suspend(struct usb_hcd *usb_hcd)
422{
423 struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
424 dev_err(wusbhc->dev, "%s (%p [%p]) UNIMPLEMENTED\n", __func__,
425 usb_hcd, wusbhc);
426 /* dump_stack(); */
427 return -ENOSYS;
428}
429EXPORT_SYMBOL_GPL(wusbhc_rh_suspend);
430
431int wusbhc_rh_resume(struct usb_hcd *usb_hcd)
432{
433 struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
434 dev_err(wusbhc->dev, "%s (%p [%p]) UNIMPLEMENTED\n", __func__,
435 usb_hcd, wusbhc);
436 /* dump_stack(); */
437 return -ENOSYS;
438}
439EXPORT_SYMBOL_GPL(wusbhc_rh_resume);
440
441int wusbhc_rh_start_port_reset(struct usb_hcd *usb_hcd, unsigned port_idx)
442{
443 struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
444 dev_err(wusbhc->dev, "%s (%p [%p], port_idx %u) UNIMPLEMENTED\n",
445 __func__, usb_hcd, wusbhc, port_idx);
446 WARN_ON(1);
447 return -ENOSYS;
448}
449EXPORT_SYMBOL_GPL(wusbhc_rh_start_port_reset);
450
451static void wusb_port_init(struct wusb_port *port)
452{
453 port->status |= USB_PORT_STAT_HIGH_SPEED;
454}
455
456/*
457 * Alloc fake port specific fields and status.
458 */
459int wusbhc_rh_create(struct wusbhc *wusbhc)
460{
461 int result = -ENOMEM;
462 size_t port_size, itr;
463 port_size = wusbhc->ports_max * sizeof(wusbhc->port[0]);
464 wusbhc->port = kzalloc(port_size, GFP_KERNEL);
465 if (wusbhc->port == NULL)
466 goto error_port_alloc;
467 for (itr = 0; itr < wusbhc->ports_max; itr++)
468 wusb_port_init(&wusbhc->port[itr]);
469 result = 0;
470error_port_alloc:
471 return result;
472}
473
474void wusbhc_rh_destroy(struct wusbhc *wusbhc)
475{
476 kfree(wusbhc->port);
477}
diff --git a/drivers/usb/wusbcore/security.c b/drivers/usb/wusbcore/security.c
new file mode 100644
index 000000000000..a101cad6a8d4
--- /dev/null
+++ b/drivers/usb/wusbcore/security.c
@@ -0,0 +1,642 @@
1/*
2 * Wireless USB Host Controller
3 * Security support: encryption enablement, etc
4 *
5 * Copyright (C) 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 * FIXME: docs
24 */
25#include <linux/types.h>
26#include <linux/usb/ch9.h>
27#include <linux/random.h>
28#include "wusbhc.h"
29
30/*
31 * DEBUG & SECURITY WARNING!!!!
32 *
33 * If you enable this past 1, the debug code will weaken the
34 * cryptographic safety of the system (on purpose, for debugging).
35 *
36 * Weaken means:
37 * we print secret keys and intermediate values all the way,
38 */
39#undef D_LOCAL
40#define D_LOCAL 2
41#include <linux/uwb/debug.h>
42
43static void wusbhc_set_gtk_callback(struct urb *urb);
44static void wusbhc_gtk_rekey_done_work(struct work_struct *work);
45
46int wusbhc_sec_create(struct wusbhc *wusbhc)
47{
48 wusbhc->gtk.descr.bLength = sizeof(wusbhc->gtk.descr) + sizeof(wusbhc->gtk.data);
49 wusbhc->gtk.descr.bDescriptorType = USB_DT_KEY;
50 wusbhc->gtk.descr.bReserved = 0;
51
52 wusbhc->gtk_index = wusb_key_index(0, WUSB_KEY_INDEX_TYPE_GTK,
53 WUSB_KEY_INDEX_ORIGINATOR_HOST);
54
55 INIT_WORK(&wusbhc->gtk_rekey_done_work, wusbhc_gtk_rekey_done_work);
56
57 return 0;
58}
59
60
61/* Called when the HC is destroyed */
62void wusbhc_sec_destroy(struct wusbhc *wusbhc)
63{
64}
65
66
67/**
68 * wusbhc_next_tkid - generate a new, currently unused, TKID
69 * @wusbhc: the WUSB host controller
70 * @wusb_dev: the device whose PTK the TKID is for
71 * (or NULL for a TKID for a GTK)
72 *
73 * The generated TKID consist of two parts: the device's authenicated
74 * address (or 0 or a GTK); and an incrementing number. This ensures
75 * that TKIDs cannot be shared between devices and by the time the
76 * incrementing number wraps around the older TKIDs will no longer be
77 * in use (a maximum of two keys may be active at any one time).
78 */
79static u32 wusbhc_next_tkid(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
80{
81 u32 *tkid;
82 u32 addr;
83
84 if (wusb_dev == NULL) {
85 tkid = &wusbhc->gtk_tkid;
86 addr = 0;
87 } else {
88 tkid = &wusb_port_by_idx(wusbhc, wusb_dev->port_idx)->ptk_tkid;
89 addr = wusb_dev->addr & 0x7f;
90 }
91
92 *tkid = (addr << 8) | ((*tkid + 1) & 0xff);
93
94 return *tkid;
95}
96
97static void wusbhc_generate_gtk(struct wusbhc *wusbhc)
98{
99 const size_t key_size = sizeof(wusbhc->gtk.data);
100 u32 tkid;
101
102 tkid = wusbhc_next_tkid(wusbhc, NULL);
103
104 wusbhc->gtk.descr.tTKID[0] = (tkid >> 0) & 0xff;
105 wusbhc->gtk.descr.tTKID[1] = (tkid >> 8) & 0xff;
106 wusbhc->gtk.descr.tTKID[2] = (tkid >> 16) & 0xff;
107
108 get_random_bytes(wusbhc->gtk.descr.bKeyData, key_size);
109}
110
111/**
112 * wusbhc_sec_start - start the security management process
113 * @wusbhc: the WUSB host controller
114 *
115 * Generate and set an initial GTK on the host controller.
116 *
117 * Called when the HC is started.
118 */
119int wusbhc_sec_start(struct wusbhc *wusbhc)
120{
121 const size_t key_size = sizeof(wusbhc->gtk.data);
122 int result;
123
124 wusbhc_generate_gtk(wusbhc);
125
126 result = wusbhc->set_gtk(wusbhc, wusbhc->gtk_tkid,
127 &wusbhc->gtk.descr.bKeyData, key_size);
128 if (result < 0)
129 dev_err(wusbhc->dev, "cannot set GTK for the host: %d\n",
130 result);
131
132 return result;
133}
134
135/**
136 * wusbhc_sec_stop - stop the security management process
137 * @wusbhc: the WUSB host controller
138 *
139 * Wait for any pending GTK rekeys to stop.
140 */
141void wusbhc_sec_stop(struct wusbhc *wusbhc)
142{
143 cancel_work_sync(&wusbhc->gtk_rekey_done_work);
144}
145
146
147/** @returns encryption type name */
148const char *wusb_et_name(u8 x)
149{
150 switch (x) {
151 case USB_ENC_TYPE_UNSECURE: return "unsecure";
152 case USB_ENC_TYPE_WIRED: return "wired";
153 case USB_ENC_TYPE_CCM_1: return "CCM-1";
154 case USB_ENC_TYPE_RSA_1: return "RSA-1";
155 default: return "unknown";
156 }
157}
158EXPORT_SYMBOL_GPL(wusb_et_name);
159
160/*
161 * Set the device encryption method
162 *
163 * We tell the device which encryption method to use; we do this when
164 * setting up the device's security.
165 */
166static int wusb_dev_set_encryption(struct usb_device *usb_dev, int value)
167{
168 int result;
169 struct device *dev = &usb_dev->dev;
170 struct wusb_dev *wusb_dev = usb_dev->wusb_dev;
171
172 if (value) {
173 value = wusb_dev->ccm1_etd.bEncryptionValue;
174 } else {
175 /* FIXME: should be wusb_dev->etd[UNSECURE].bEncryptionValue */
176 value = 0;
177 }
178 /* Set device's */
179 result = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
180 USB_REQ_SET_ENCRYPTION,
181 USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
182 value, 0, NULL, 0, 1000 /* FIXME: arbitrary */);
183 if (result < 0)
184 dev_err(dev, "Can't set device's WUSB encryption to "
185 "%s (value %d): %d\n",
186 wusb_et_name(wusb_dev->ccm1_etd.bEncryptionType),
187 wusb_dev->ccm1_etd.bEncryptionValue, result);
188 return result;
189}
190
191/*
192 * Set the GTK to be used by a device.
193 *
194 * The device must be authenticated.
195 */
196static int wusb_dev_set_gtk(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
197{
198 struct usb_device *usb_dev = wusb_dev->usb_dev;
199
200 return usb_control_msg(
201 usb_dev, usb_sndctrlpipe(usb_dev, 0),
202 USB_REQ_SET_DESCRIPTOR,
203 USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
204 USB_DT_KEY << 8 | wusbhc->gtk_index, 0,
205 &wusbhc->gtk.descr, wusbhc->gtk.descr.bLength,
206 1000);
207}
208
209
210/* FIXME: prototype for adding security */
211int wusb_dev_sec_add(struct wusbhc *wusbhc,
212 struct usb_device *usb_dev, struct wusb_dev *wusb_dev)
213{
214 int result, bytes, secd_size;
215 struct device *dev = &usb_dev->dev;
216 struct usb_security_descriptor secd;
217 const struct usb_encryption_descriptor *etd, *ccm1_etd = NULL;
218 void *secd_buf;
219 const void *itr, *top;
220 char buf[64];
221
222 d_fnstart(3, dev, "(usb_dev %p, wusb_dev %p)\n", usb_dev, wusb_dev);
223 result = usb_get_descriptor(usb_dev, USB_DT_SECURITY,
224 0, &secd, sizeof(secd));
225 if (result < sizeof(secd)) {
226 dev_err(dev, "Can't read security descriptor or "
227 "not enough data: %d\n", result);
228 goto error_secd;
229 }
230 secd_size = le16_to_cpu(secd.wTotalLength);
231 d_printf(5, dev, "got %d bytes of sec descriptor, total is %d\n",
232 result, secd_size);
233 secd_buf = kmalloc(secd_size, GFP_KERNEL);
234 if (secd_buf == NULL) {
235 dev_err(dev, "Can't allocate space for security descriptors\n");
236 goto error_secd_alloc;
237 }
238 result = usb_get_descriptor(usb_dev, USB_DT_SECURITY,
239 0, secd_buf, secd_size);
240 if (result < secd_size) {
241 dev_err(dev, "Can't read security descriptor or "
242 "not enough data: %d\n", result);
243 goto error_secd_all;
244 }
245 d_printf(5, dev, "got %d bytes of sec descriptors\n", result);
246 bytes = 0;
247 itr = secd_buf + sizeof(secd);
248 top = secd_buf + result;
249 while (itr < top) {
250 etd = itr;
251 if (top - itr < sizeof(*etd)) {
252 dev_err(dev, "BUG: bad device security descriptor; "
253 "not enough data (%zu vs %zu bytes left)\n",
254 top - itr, sizeof(*etd));
255 break;
256 }
257 if (etd->bLength < sizeof(*etd)) {
258 dev_err(dev, "BUG: bad device encryption descriptor; "
259 "descriptor is too short "
260 "(%u vs %zu needed)\n",
261 etd->bLength, sizeof(*etd));
262 break;
263 }
264 itr += etd->bLength;
265 bytes += snprintf(buf + bytes, sizeof(buf) - bytes,
266 "%s (0x%02x/%02x) ",
267 wusb_et_name(etd->bEncryptionType),
268 etd->bEncryptionValue, etd->bAuthKeyIndex);
269 if (etd->bEncryptionType == USB_ENC_TYPE_CCM_1)
270 ccm1_etd = etd;
271 }
272 /* This code only supports CCM1 as of now. */
273 /* FIXME: user has to choose which sec mode to use?
274 * In theory we want CCM */
275 if (ccm1_etd == NULL) {
276 dev_err(dev, "WUSB device doesn't support CCM1 encryption, "
277 "can't use!\n");
278 result = -EINVAL;
279 goto error_no_ccm1;
280 }
281 wusb_dev->ccm1_etd = *ccm1_etd;
282 dev_info(dev, "supported encryption: %s; using %s (0x%02x/%02x)\n",
283 buf, wusb_et_name(ccm1_etd->bEncryptionType),
284 ccm1_etd->bEncryptionValue, ccm1_etd->bAuthKeyIndex);
285 result = 0;
286 kfree(secd_buf);
287out:
288 d_fnend(3, dev, "(usb_dev %p, wusb_dev %p) = %d\n",
289 usb_dev, wusb_dev, result);
290 return result;
291
292
293error_no_ccm1:
294error_secd_all:
295 kfree(secd_buf);
296error_secd_alloc:
297error_secd:
298 goto out;
299}
300
301void wusb_dev_sec_rm(struct wusb_dev *wusb_dev)
302{
303 /* Nothing so far */
304}
305
306static void hs_printk(unsigned level, struct device *dev,
307 struct usb_handshake *hs)
308{
309 d_printf(level, dev,
310 " bMessageNumber: %u\n"
311 " bStatus: %u\n"
312 " tTKID: %02x %02x %02x\n"
313 " CDID: %02x %02x %02x %02x %02x %02x %02x %02x\n"
314 " %02x %02x %02x %02x %02x %02x %02x %02x\n"
315 " nonce: %02x %02x %02x %02x %02x %02x %02x %02x\n"
316 " %02x %02x %02x %02x %02x %02x %02x %02x\n"
317 " MIC: %02x %02x %02x %02x %02x %02x %02x %02x\n",
318 hs->bMessageNumber, hs->bStatus,
319 hs->tTKID[2], hs->tTKID[1], hs->tTKID[0],
320 hs->CDID[0], hs->CDID[1], hs->CDID[2], hs->CDID[3],
321 hs->CDID[4], hs->CDID[5], hs->CDID[6], hs->CDID[7],
322 hs->CDID[8], hs->CDID[9], hs->CDID[10], hs->CDID[11],
323 hs->CDID[12], hs->CDID[13], hs->CDID[14], hs->CDID[15],
324 hs->nonce[0], hs->nonce[1], hs->nonce[2], hs->nonce[3],
325 hs->nonce[4], hs->nonce[5], hs->nonce[6], hs->nonce[7],
326 hs->nonce[8], hs->nonce[9], hs->nonce[10], hs->nonce[11],
327 hs->nonce[12], hs->nonce[13], hs->nonce[14], hs->nonce[15],
328 hs->MIC[0], hs->MIC[1], hs->MIC[2], hs->MIC[3],
329 hs->MIC[4], hs->MIC[5], hs->MIC[6], hs->MIC[7]);
330}
331
332/**
333 * Update the address of an unauthenticated WUSB device
334 *
335 * Once we have successfully authenticated, we take it to addr0 state
336 * and then to a normal address.
337 *
338 * Before the device's address (as known by it) was usb_dev->devnum |
339 * 0x80 (unauthenticated address). With this we update it to usb_dev->devnum.
340 */
341static int wusb_dev_update_address(struct wusbhc *wusbhc,
342 struct wusb_dev *wusb_dev)
343{
344 int result = -ENOMEM;
345 struct usb_device *usb_dev = wusb_dev->usb_dev;
346 struct device *dev = &usb_dev->dev;
347 u8 new_address = wusb_dev->addr & 0x7F;
348
349 /* Set address 0 */
350 result = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
351 USB_REQ_SET_ADDRESS, 0,
352 0, 0, NULL, 0, 1000 /* FIXME: arbitrary */);
353 if (result < 0) {
354 dev_err(dev, "auth failed: can't set address 0: %d\n",
355 result);
356 goto error_addr0;
357 }
358 result = wusb_set_dev_addr(wusbhc, wusb_dev, 0);
359 if (result < 0)
360 goto error_addr0;
361 usb_ep0_reinit(usb_dev);
362
363 /* Set new (authenticated) address. */
364 result = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
365 USB_REQ_SET_ADDRESS, 0,
366 new_address, 0, NULL, 0,
367 1000 /* FIXME: arbitrary */);
368 if (result < 0) {
369 dev_err(dev, "auth failed: can't set address %u: %d\n",
370 new_address, result);
371 goto error_addr;
372 }
373 result = wusb_set_dev_addr(wusbhc, wusb_dev, new_address);
374 if (result < 0)
375 goto error_addr;
376 usb_ep0_reinit(usb_dev);
377 usb_dev->authenticated = 1;
378error_addr:
379error_addr0:
380 return result;
381}
382
383/*
384 *
385 *
386 */
387/* FIXME: split and cleanup */
388int wusb_dev_4way_handshake(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev,
389 struct wusb_ckhdid *ck)
390{
391 int result = -ENOMEM;
392 struct usb_device *usb_dev = wusb_dev->usb_dev;
393 struct device *dev = &usb_dev->dev;
394 u32 tkid;
395 __le32 tkid_le;
396 struct usb_handshake *hs;
397 struct aes_ccm_nonce ccm_n;
398 u8 mic[8];
399 struct wusb_keydvt_in keydvt_in;
400 struct wusb_keydvt_out keydvt_out;
401
402 hs = kzalloc(3*sizeof(hs[0]), GFP_KERNEL);
403 if (hs == NULL) {
404 dev_err(dev, "can't allocate handshake data\n");
405 goto error_kzalloc;
406 }
407
408 /* We need to turn encryption before beginning the 4way
409 * hshake (WUSB1.0[.3.2.2]) */
410 result = wusb_dev_set_encryption(usb_dev, 1);
411 if (result < 0)
412 goto error_dev_set_encryption;
413
414 tkid = wusbhc_next_tkid(wusbhc, wusb_dev);
415 tkid_le = cpu_to_le32(tkid);
416
417 hs[0].bMessageNumber = 1;
418 hs[0].bStatus = 0;
419 memcpy(hs[0].tTKID, &tkid_le, sizeof(hs[0].tTKID));
420 hs[0].bReserved = 0;
421 memcpy(hs[0].CDID, &wusb_dev->cdid, sizeof(hs[0].CDID));
422 get_random_bytes(&hs[0].nonce, sizeof(hs[0].nonce));
423 memset(hs[0].MIC, 0, sizeof(hs[0].MIC)); /* Per WUSB1.0[T7-22] */
424
425 d_printf(1, dev, "I: sending hs1:\n");
426 hs_printk(2, dev, &hs[0]);
427
428 result = usb_control_msg(
429 usb_dev, usb_sndctrlpipe(usb_dev, 0),
430 USB_REQ_SET_HANDSHAKE,
431 USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
432 1, 0, &hs[0], sizeof(hs[0]), 1000 /* FIXME: arbitrary */);
433 if (result < 0) {
434 dev_err(dev, "Handshake1: request failed: %d\n", result);
435 goto error_hs1;
436 }
437
438 /* Handshake 2, from the device -- need to verify fields */
439 result = usb_control_msg(
440 usb_dev, usb_rcvctrlpipe(usb_dev, 0),
441 USB_REQ_GET_HANDSHAKE,
442 USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
443 2, 0, &hs[1], sizeof(hs[1]), 1000 /* FIXME: arbitrary */);
444 if (result < 0) {
445 dev_err(dev, "Handshake2: request failed: %d\n", result);
446 goto error_hs2;
447 }
448 d_printf(1, dev, "got HS2:\n");
449 hs_printk(2, dev, &hs[1]);
450
451 result = -EINVAL;
452 if (hs[1].bMessageNumber != 2) {
453 dev_err(dev, "Handshake2 failed: bad message number %u\n",
454 hs[1].bMessageNumber);
455 goto error_hs2;
456 }
457 if (hs[1].bStatus != 0) {
458 dev_err(dev, "Handshake2 failed: bad status %u\n",
459 hs[1].bStatus);
460 goto error_hs2;
461 }
462 if (memcmp(hs[0].tTKID, hs[1].tTKID, sizeof(hs[0].tTKID))) {
463 dev_err(dev, "Handshake2 failed: TKID mismatch "
464 "(#1 0x%02x%02x%02x vs #2 0x%02x%02x%02x)\n",
465 hs[0].tTKID[0], hs[0].tTKID[1], hs[0].tTKID[2],
466 hs[1].tTKID[0], hs[1].tTKID[1], hs[1].tTKID[2]);
467 goto error_hs2;
468 }
469 if (memcmp(hs[0].CDID, hs[1].CDID, sizeof(hs[0].CDID))) {
470 dev_err(dev, "Handshake2 failed: CDID mismatch\n");
471 goto error_hs2;
472 }
473
474 /* Setup the CCM nonce */
475 memset(&ccm_n.sfn, 0, sizeof(ccm_n.sfn)); /* Per WUSB1.0[6.5.2] */
476 memcpy(ccm_n.tkid, &tkid_le, sizeof(ccm_n.tkid));
477 ccm_n.src_addr = wusbhc->uwb_rc->uwb_dev.dev_addr;
478 ccm_n.dest_addr.data[0] = wusb_dev->addr;
479 ccm_n.dest_addr.data[1] = 0;
480
481 /* Derive the KCK and PTK from CK, the CCM, H and D nonces */
482 memcpy(keydvt_in.hnonce, hs[0].nonce, sizeof(keydvt_in.hnonce));
483 memcpy(keydvt_in.dnonce, hs[1].nonce, sizeof(keydvt_in.dnonce));
484 result = wusb_key_derive(&keydvt_out, ck->data, &ccm_n, &keydvt_in);
485 if (result < 0) {
486 dev_err(dev, "Handshake2 failed: cannot derive keys: %d\n",
487 result);
488 goto error_hs2;
489 }
490 d_printf(2, dev, "KCK:\n");
491 d_dump(2, dev, keydvt_out.kck, sizeof(keydvt_out.kck));
492 d_printf(2, dev, "PTK:\n");
493 d_dump(2, dev, keydvt_out.ptk, sizeof(keydvt_out.ptk));
494
495 /* Compute MIC and verify it */
496 result = wusb_oob_mic(mic, keydvt_out.kck, &ccm_n, &hs[1]);
497 if (result < 0) {
498 dev_err(dev, "Handshake2 failed: cannot compute MIC: %d\n",
499 result);
500 goto error_hs2;
501 }
502
503 d_printf(2, dev, "MIC:\n");
504 d_dump(2, dev, mic, sizeof(mic));
505 if (memcmp(hs[1].MIC, mic, sizeof(hs[1].MIC))) {
506 dev_err(dev, "Handshake2 failed: MIC mismatch\n");
507 goto error_hs2;
508 }
509
510 /* Send Handshake3 */
511 hs[2].bMessageNumber = 3;
512 hs[2].bStatus = 0;
513 memcpy(hs[2].tTKID, &tkid_le, sizeof(hs[2].tTKID));
514 hs[2].bReserved = 0;
515 memcpy(hs[2].CDID, &wusb_dev->cdid, sizeof(hs[2].CDID));
516 memcpy(hs[2].nonce, hs[0].nonce, sizeof(hs[2].nonce));
517 result = wusb_oob_mic(hs[2].MIC, keydvt_out.kck, &ccm_n, &hs[2]);
518 if (result < 0) {
519 dev_err(dev, "Handshake3 failed: cannot compute MIC: %d\n",
520 result);
521 goto error_hs2;
522 }
523
524 d_printf(1, dev, "I: sending hs3:\n");
525 hs_printk(2, dev, &hs[2]);
526
527 result = usb_control_msg(
528 usb_dev, usb_sndctrlpipe(usb_dev, 0),
529 USB_REQ_SET_HANDSHAKE,
530 USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
531 3, 0, &hs[2], sizeof(hs[2]), 1000 /* FIXME: arbitrary */);
532 if (result < 0) {
533 dev_err(dev, "Handshake3: request failed: %d\n", result);
534 goto error_hs3;
535 }
536
537 d_printf(1, dev, "I: turning on encryption on host for device\n");
538 d_dump(2, dev, keydvt_out.ptk, sizeof(keydvt_out.ptk));
539 result = wusbhc->set_ptk(wusbhc, wusb_dev->port_idx, tkid,
540 keydvt_out.ptk, sizeof(keydvt_out.ptk));
541 if (result < 0)
542 goto error_wusbhc_set_ptk;
543
544 d_printf(1, dev, "I: setting a GTK\n");
545 result = wusb_dev_set_gtk(wusbhc, wusb_dev);
546 if (result < 0) {
547 dev_err(dev, "Set GTK for device: request failed: %d\n",
548 result);
549 goto error_wusbhc_set_gtk;
550 }
551
552 /* Update the device's address from unauth to auth */
553 if (usb_dev->authenticated == 0) {
554 d_printf(1, dev, "I: updating addres to auth from non-auth\n");
555 result = wusb_dev_update_address(wusbhc, wusb_dev);
556 if (result < 0)
557 goto error_dev_update_address;
558 }
559 result = 0;
560 d_printf(1, dev, "I: 4way handshke done, device authenticated\n");
561
562error_dev_update_address:
563error_wusbhc_set_gtk:
564error_wusbhc_set_ptk:
565error_hs3:
566error_hs2:
567error_hs1:
568 memset(hs, 0, 3*sizeof(hs[0]));
569 memset(&keydvt_out, 0, sizeof(keydvt_out));
570 memset(&keydvt_in, 0, sizeof(keydvt_in));
571 memset(&ccm_n, 0, sizeof(ccm_n));
572 memset(mic, 0, sizeof(mic));
573 if (result < 0) {
574 /* error path */
575 wusb_dev_set_encryption(usb_dev, 0);
576 }
577error_dev_set_encryption:
578 kfree(hs);
579error_kzalloc:
580 return result;
581}
582
583/*
584 * Once all connected and authenticated devices have received the new
585 * GTK, switch the host to using it.
586 */
587static void wusbhc_gtk_rekey_done_work(struct work_struct *work)
588{
589 struct wusbhc *wusbhc = container_of(work, struct wusbhc, gtk_rekey_done_work);
590 size_t key_size = sizeof(wusbhc->gtk.data);
591
592 mutex_lock(&wusbhc->mutex);
593
594 if (--wusbhc->pending_set_gtks == 0)
595 wusbhc->set_gtk(wusbhc, wusbhc->gtk_tkid, &wusbhc->gtk.descr.bKeyData, key_size);
596
597 mutex_unlock(&wusbhc->mutex);
598}
599
600static void wusbhc_set_gtk_callback(struct urb *urb)
601{
602 struct wusbhc *wusbhc = urb->context;
603
604 queue_work(wusbd, &wusbhc->gtk_rekey_done_work);
605}
606
607/**
608 * wusbhc_gtk_rekey - generate and distribute a new GTK
609 * @wusbhc: the WUSB host controller
610 *
611 * Generate a new GTK and distribute it to all connected and
612 * authenticated devices. When all devices have the new GTK, the host
613 * starts using it.
614 *
615 * This must be called after every device disconnect (see [WUSB]
616 * section 6.2.11.2).
617 */
618void wusbhc_gtk_rekey(struct wusbhc *wusbhc)
619{
620 static const size_t key_size = sizeof(wusbhc->gtk.data);
621 int p;
622
623 wusbhc_generate_gtk(wusbhc);
624
625 for (p = 0; p < wusbhc->ports_max; p++) {
626 struct wusb_dev *wusb_dev;
627
628 wusb_dev = wusbhc->port[p].wusb_dev;
629 if (!wusb_dev || !wusb_dev->usb_dev | !wusb_dev->usb_dev->authenticated)
630 continue;
631
632 usb_fill_control_urb(wusb_dev->set_gtk_urb, wusb_dev->usb_dev,
633 usb_sndctrlpipe(wusb_dev->usb_dev, 0),
634 (void *)wusb_dev->set_gtk_req,
635 &wusbhc->gtk.descr, wusbhc->gtk.descr.bLength,
636 wusbhc_set_gtk_callback, wusbhc);
637 if (usb_submit_urb(wusb_dev->set_gtk_urb, GFP_KERNEL) == 0)
638 wusbhc->pending_set_gtks++;
639 }
640 if (wusbhc->pending_set_gtks == 0)
641 wusbhc->set_gtk(wusbhc, wusbhc->gtk_tkid, &wusbhc->gtk.descr.bKeyData, key_size);
642}
diff --git a/drivers/usb/wusbcore/wa-hc.c b/drivers/usb/wusbcore/wa-hc.c
new file mode 100644
index 000000000000..9d04722415bb
--- /dev/null
+++ b/drivers/usb/wusbcore/wa-hc.c
@@ -0,0 +1,95 @@
1/*
2 * Wire Adapter Host Controller Driver
3 * Common items to HWA and DWA based HCDs
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 * FIXME: docs
24 */
25#include "wusbhc.h"
26#include "wa-hc.h"
27
28/**
29 * Assumes
30 *
31 * wa->usb_dev and wa->usb_iface initialized and refcounted,
32 * wa->wa_descr initialized.
33 */
34int wa_create(struct wahc *wa, struct usb_interface *iface)
35{
36 int result;
37 struct device *dev = &iface->dev;
38
39 result = wa_rpipes_create(wa);
40 if (result < 0)
41 goto error_rpipes_create;
42 /* Fill up Data Transfer EP pointers */
43 wa->dti_epd = &iface->cur_altsetting->endpoint[1].desc;
44 wa->dto_epd = &iface->cur_altsetting->endpoint[2].desc;
45 wa->xfer_result_size = le16_to_cpu(wa->dti_epd->wMaxPacketSize);
46 wa->xfer_result = kmalloc(wa->xfer_result_size, GFP_KERNEL);
47 if (wa->xfer_result == NULL)
48 goto error_xfer_result_alloc;
49 result = wa_nep_create(wa, iface);
50 if (result < 0) {
51 dev_err(dev, "WA-CDS: can't initialize notif endpoint: %d\n",
52 result);
53 goto error_nep_create;
54 }
55 return 0;
56
57error_nep_create:
58 kfree(wa->xfer_result);
59error_xfer_result_alloc:
60 wa_rpipes_destroy(wa);
61error_rpipes_create:
62 return result;
63}
64EXPORT_SYMBOL_GPL(wa_create);
65
66
67void __wa_destroy(struct wahc *wa)
68{
69 if (wa->dti_urb) {
70 usb_kill_urb(wa->dti_urb);
71 usb_put_urb(wa->dti_urb);
72 usb_kill_urb(wa->buf_in_urb);
73 usb_put_urb(wa->buf_in_urb);
74 }
75 kfree(wa->xfer_result);
76 wa_nep_destroy(wa);
77 wa_rpipes_destroy(wa);
78}
79EXPORT_SYMBOL_GPL(__wa_destroy);
80
81/**
82 * wa_reset_all - reset the WA device
83 * @wa: the WA to be reset
84 *
85 * For HWAs the radio controller and all other PALs are also reset.
86 */
87void wa_reset_all(struct wahc *wa)
88{
89 /* FIXME: assuming HWA. */
90 wusbhc_reset_all(wa->wusb);
91}
92
93MODULE_AUTHOR("Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>");
94MODULE_DESCRIPTION("Wireless USB Wire Adapter core");
95MODULE_LICENSE("GPL");
diff --git a/drivers/usb/wusbcore/wa-hc.h b/drivers/usb/wusbcore/wa-hc.h
new file mode 100644
index 000000000000..586d350cdb4d
--- /dev/null
+++ b/drivers/usb/wusbcore/wa-hc.h
@@ -0,0 +1,417 @@
1/*
2 * HWA Host Controller Driver
3 * Wire Adapter Control/Data Streaming Iface (WUSB1.0[8])
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 * This driver implements a USB Host Controller (struct usb_hcd) for a
24 * Wireless USB Host Controller based on the Wireless USB 1.0
25 * Host-Wire-Adapter specification (in layman terms, a USB-dongle that
26 * implements a Wireless USB host).
27 *
28 * Check out the Design-overview.txt file in the source documentation
29 * for other details on the implementation.
30 *
31 * Main blocks:
32 *
33 * driver glue with the driver API, workqueue daemon
34 *
35 * lc RC instance life cycle management (create, destroy...)
36 *
37 * hcd glue with the USB API Host Controller Interface API.
38 *
39 * nep Notification EndPoint managent: collect notifications
40 * and queue them with the workqueue daemon.
41 *
42 * Handle notifications as coming from the NEP. Sends them
43 * off others to their respective modules (eg: connect,
44 * disconnect and reset go to devconnect).
45 *
46 * rpipe Remote Pipe management; rpipe is what we use to write
47 * to an endpoint on a WUSB device that is connected to a
48 * HWA RC.
49 *
50 * xfer Transfer managment -- this is all the code that gets a
51 * buffer and pushes it to a device (or viceversa). *
52 *
53 * Some day a lot of this code will be shared between this driver and
54 * the drivers for DWA (xfer, rpipe).
55 *
56 * All starts at driver.c:hwahc_probe(), when one of this guys is
57 * connected. hwahc_disconnect() stops it.
58 *
59 * During operation, the main driver is devices connecting or
60 * disconnecting. They cause the HWA RC to send notifications into
61 * nep.c:hwahc_nep_cb() that will dispatch them to
62 * notif.c:wa_notif_dispatch(). From there they will fan to cause
63 * device connects, disconnects, etc.
64 *
65 * Note much of the activity is difficult to follow. For example a
66 * device connect goes to devconnect, which will cause the "fake" root
67 * hub port to show a connect and stop there. Then khubd will notice
68 * and call into the rh.c:hwahc_rc_port_reset() code to authenticate
69 * the device (and this might require user intervention) and enable
70 * the port.
71 *
72 * We also have a timer workqueue going from devconnect.c that
73 * schedules in hwahc_devconnect_create().
74 *
75 * The rest of the traffic is in the usual entry points of a USB HCD,
76 * which are hooked up in driver.c:hwahc_rc_driver, and defined in
77 * hcd.c.
78 */
79
80#ifndef __HWAHC_INTERNAL_H__
81#define __HWAHC_INTERNAL_H__
82
83#include <linux/completion.h>
84#include <linux/usb.h>
85#include <linux/mutex.h>
86#include <linux/spinlock.h>
87#include <linux/uwb.h>
88#include <linux/usb/wusb.h>
89#include <linux/usb/wusb-wa.h>
90
91struct wusbhc;
92struct wahc;
93extern void wa_urb_enqueue_run(struct work_struct *ws);
94
95/**
96 * RPipe instance
97 *
98 * @descr's fields are kept in LE, as we need to send it back and
99 * forth.
100 *
101 * @wa is referenced when set
102 *
103 * @segs_available is the number of requests segments that still can
104 * be submitted to the controller without overloading
105 * it. It is initialized to descr->wRequests when
106 * aiming.
107 *
108 * A rpipe supports a max of descr->wRequests at the same time; before
109 * submitting seg_lock has to be taken. If segs_avail > 0, then we can
110 * submit; if not, we have to queue them.
111 */
112struct wa_rpipe {
113 struct kref refcnt;
114 struct usb_rpipe_descriptor descr;
115 struct usb_host_endpoint *ep;
116 struct wahc *wa;
117 spinlock_t seg_lock;
118 struct list_head seg_list;
119 atomic_t segs_available;
120 u8 buffer[1]; /* For reads/writes on USB */
121};
122
123
124/**
125 * Instance of a HWA Host Controller
126 *
127 * Except where a more specific lock/mutex applies or atomic, all
128 * fields protected by @mutex.
129 *
130 * @wa_descr Can be accessed without locking because it is in
131 * the same area where the device descriptors were
132 * read, so it is guaranteed to exist umodified while
133 * the device exists.
134 *
135 * Endianess has been converted to CPU's.
136 *
137 * @nep_* can be accessed without locking as its processing is
138 * serialized; we submit a NEP URB and it comes to
139 * hwahc_nep_cb(), which won't issue another URB until it is
140 * done processing it.
141 *
142 * @xfer_list:
143 *
144 * List of active transfers to verify existence from a xfer id
145 * gotten from the xfer result message. Can't use urb->list because
146 * it goes by endpoint, and we don't know the endpoint at the time
147 * when we get the xfer result message. We can't really rely on the
148 * pointer (will have to change for 64 bits) as the xfer id is 32 bits.
149 *
150 * @xfer_delayed_list: List of transfers that need to be started
151 * (with a workqueue, because they were
152 * submitted from an atomic context).
153 *
154 * FIXME: this needs to be layered up: a wusbhc layer (for sharing
155 * comonalities with WHCI), a wa layer (for sharing
156 * comonalities with DWA-RC).
157 */
158struct wahc {
159 struct usb_device *usb_dev;
160 struct usb_interface *usb_iface;
161
162 /* HC to deliver notifications */
163 union {
164 struct wusbhc *wusb;
165 struct dwahc *dwa;
166 };
167
168 const struct usb_endpoint_descriptor *dto_epd, *dti_epd;
169 const struct usb_wa_descriptor *wa_descr;
170
171 struct urb *nep_urb; /* Notification EndPoint [lockless] */
172 struct edc nep_edc;
173 void *nep_buffer;
174 size_t nep_buffer_size;
175
176 atomic_t notifs_queued;
177
178 u16 rpipes;
179 unsigned long *rpipe_bm; /* rpipe usage bitmap */
180 spinlock_t rpipe_bm_lock; /* protect rpipe_bm */
181 struct mutex rpipe_mutex; /* assigning resources to endpoints */
182
183 struct urb *dti_urb; /* URB for reading xfer results */
184 struct urb *buf_in_urb; /* URB for reading data in */
185 struct edc dti_edc; /* DTI error density counter */
186 struct wa_xfer_result *xfer_result; /* real size = dti_ep maxpktsize */
187 size_t xfer_result_size;
188
189 s32 status; /* For reading status */
190
191 struct list_head xfer_list;
192 struct list_head xfer_delayed_list;
193 spinlock_t xfer_list_lock;
194 struct work_struct xfer_work;
195 atomic_t xfer_id_count;
196};
197
198
199extern int wa_create(struct wahc *wa, struct usb_interface *iface);
200extern void __wa_destroy(struct wahc *wa);
201void wa_reset_all(struct wahc *wa);
202
203
204/* Miscellaneous constants */
205enum {
206 /** Max number of EPROTO errors we tolerate on the NEP in a
207 * period of time */
208 HWAHC_EPROTO_MAX = 16,
209 /** Period of time for EPROTO errors (in jiffies) */
210 HWAHC_EPROTO_PERIOD = 4 * HZ,
211};
212
213
214/* Notification endpoint handling */
215extern int wa_nep_create(struct wahc *, struct usb_interface *);
216extern void wa_nep_destroy(struct wahc *);
217
218static inline int wa_nep_arm(struct wahc *wa, gfp_t gfp_mask)
219{
220 struct urb *urb = wa->nep_urb;
221 urb->transfer_buffer = wa->nep_buffer;
222 urb->transfer_buffer_length = wa->nep_buffer_size;
223 return usb_submit_urb(urb, gfp_mask);
224}
225
226static inline void wa_nep_disarm(struct wahc *wa)
227{
228 usb_kill_urb(wa->nep_urb);
229}
230
231
232/* RPipes */
233static inline void wa_rpipe_init(struct wahc *wa)
234{
235 spin_lock_init(&wa->rpipe_bm_lock);
236 mutex_init(&wa->rpipe_mutex);
237}
238
239static inline void wa_init(struct wahc *wa)
240{
241 edc_init(&wa->nep_edc);
242 atomic_set(&wa->notifs_queued, 0);
243 wa_rpipe_init(wa);
244 edc_init(&wa->dti_edc);
245 INIT_LIST_HEAD(&wa->xfer_list);
246 INIT_LIST_HEAD(&wa->xfer_delayed_list);
247 spin_lock_init(&wa->xfer_list_lock);
248 INIT_WORK(&wa->xfer_work, wa_urb_enqueue_run);
249 atomic_set(&wa->xfer_id_count, 1);
250}
251
252/**
253 * Destroy a pipe (when refcount drops to zero)
254 *
255 * Assumes it has been moved to the "QUIESCING" state.
256 */
257struct wa_xfer;
258extern void rpipe_destroy(struct kref *_rpipe);
259static inline
260void __rpipe_get(struct wa_rpipe *rpipe)
261{
262 kref_get(&rpipe->refcnt);
263}
264extern int rpipe_get_by_ep(struct wahc *, struct usb_host_endpoint *,
265 struct urb *, gfp_t);
266static inline void rpipe_put(struct wa_rpipe *rpipe)
267{
268 kref_put(&rpipe->refcnt, rpipe_destroy);
269
270}
271extern void rpipe_ep_disable(struct wahc *, struct usb_host_endpoint *);
272extern int wa_rpipes_create(struct wahc *);
273extern void wa_rpipes_destroy(struct wahc *);
274static inline void rpipe_avail_dec(struct wa_rpipe *rpipe)
275{
276 atomic_dec(&rpipe->segs_available);
277}
278
279/**
280 * Returns true if the rpipe is ready to submit more segments.
281 */
282static inline int rpipe_avail_inc(struct wa_rpipe *rpipe)
283{
284 return atomic_inc_return(&rpipe->segs_available) > 0
285 && !list_empty(&rpipe->seg_list);
286}
287
288
289/* Transferring data */
290extern int wa_urb_enqueue(struct wahc *, struct usb_host_endpoint *,
291 struct urb *, gfp_t);
292extern int wa_urb_dequeue(struct wahc *, struct urb *);
293extern void wa_handle_notif_xfer(struct wahc *, struct wa_notif_hdr *);
294
295
296/* Misc
297 *
298 * FIXME: Refcounting for the actual @hwahc object is not correct; I
299 * mean, this should be refcounting on the HCD underneath, but
300 * it is not. In any case, the semantics for HCD refcounting
301 * are *weird*...on refcount reaching zero it just frees
302 * it...no RC specific function is called...unless I miss
303 * something.
304 *
305 * FIXME: has to go away in favour of an 'struct' hcd based sollution
306 */
307static inline struct wahc *wa_get(struct wahc *wa)
308{
309 usb_get_intf(wa->usb_iface);
310 return wa;
311}
312
313static inline void wa_put(struct wahc *wa)
314{
315 usb_put_intf(wa->usb_iface);
316}
317
318
319static inline int __wa_feature(struct wahc *wa, unsigned op, u16 feature)
320{
321 return usb_control_msg(wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
322 op ? USB_REQ_SET_FEATURE : USB_REQ_CLEAR_FEATURE,
323 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
324 feature,
325 wa->usb_iface->cur_altsetting->desc.bInterfaceNumber,
326 NULL, 0, 1000 /* FIXME: arbitrary */);
327}
328
329
330static inline int __wa_set_feature(struct wahc *wa, u16 feature)
331{
332 return __wa_feature(wa, 1, feature);
333}
334
335
336static inline int __wa_clear_feature(struct wahc *wa, u16 feature)
337{
338 return __wa_feature(wa, 0, feature);
339}
340
341
342/**
343 * Return the status of a Wire Adapter
344 *
345 * @wa: Wire Adapter instance
346 * @returns < 0 errno code on error, or status bitmap as described
347 * in WUSB1.0[8.3.1.6].
348 *
349 * NOTE: need malloc, some arches don't take USB from the stack
350 */
351static inline
352s32 __wa_get_status(struct wahc *wa)
353{
354 s32 result;
355 result = usb_control_msg(
356 wa->usb_dev, usb_rcvctrlpipe(wa->usb_dev, 0),
357 USB_REQ_GET_STATUS,
358 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
359 0, wa->usb_iface->cur_altsetting->desc.bInterfaceNumber,
360 &wa->status, sizeof(wa->status),
361 1000 /* FIXME: arbitrary */);
362 if (result >= 0)
363 result = wa->status;
364 return result;
365}
366
367
368/**
369 * Waits until the Wire Adapter's status matches @mask/@value
370 *
371 * @wa: Wire Adapter instance.
372 * @returns < 0 errno code on error, otherwise status.
373 *
374 * Loop until the WAs status matches the mask and value (status & mask
375 * == value). Timeout if it doesn't happen.
376 *
377 * FIXME: is there an official specification on how long status
378 * changes can take?
379 */
380static inline s32 __wa_wait_status(struct wahc *wa, u32 mask, u32 value)
381{
382 s32 result;
383 unsigned loops = 10;
384 do {
385 msleep(50);
386 result = __wa_get_status(wa);
387 if ((result & mask) == value)
388 break;
389 if (loops-- == 0) {
390 result = -ETIMEDOUT;
391 break;
392 }
393 } while (result >= 0);
394 return result;
395}
396
397
398/** Command @hwahc to stop, @returns 0 if ok, < 0 errno code on error */
399static inline int __wa_stop(struct wahc *wa)
400{
401 int result;
402 struct device *dev = &wa->usb_iface->dev;
403
404 result = __wa_clear_feature(wa, WA_ENABLE);
405 if (result < 0 && result != -ENODEV) {
406 dev_err(dev, "error commanding HC to stop: %d\n", result);
407 goto out;
408 }
409 result = __wa_wait_status(wa, WA_ENABLE, 0);
410 if (result < 0 && result != -ENODEV)
411 dev_err(dev, "error waiting for HC to stop: %d\n", result);
412out:
413 return 0;
414}
415
416
417#endif /* #ifndef __HWAHC_INTERNAL_H__ */
diff --git a/drivers/usb/wusbcore/wa-nep.c b/drivers/usb/wusbcore/wa-nep.c
new file mode 100644
index 000000000000..3f542990c73f
--- /dev/null
+++ b/drivers/usb/wusbcore/wa-nep.c
@@ -0,0 +1,310 @@
1/*
2 * WUSB Wire Adapter: Control/Data Streaming Interface (WUSB[8])
3 * Notification EndPoint support
4 *
5 * Copyright (C) 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 * This part takes care of getting the notification from the hw
24 * only and dispatching through wusbwad into
25 * wa_notif_dispatch. Handling is done there.
26 *
27 * WA notifications are limited in size; most of them are three or
28 * four bytes long, and the longest is the HWA Device Notification,
29 * which would not exceed 38 bytes (DNs are limited in payload to 32
30 * bytes plus 3 bytes header (WUSB1.0[7.6p2]), plus 3 bytes HWA
31 * header (WUSB1.0[8.5.4.2]).
32 *
33 * It is not clear if more than one Device Notification can be packed
34 * in a HWA Notification, I assume no because of the wording in
35 * WUSB1.0[8.5.4.2]. In any case, the bigger any notification could
36 * get is 256 bytes (as the bLength field is a byte).
37 *
38 * So what we do is we have this buffer and read into it; when a
39 * notification arrives we schedule work to a specific, single thread
40 * workqueue (so notifications are serialized) and copy the
41 * notification data. After scheduling the work, we rearm the read from
42 * the notification endpoint.
43 *
44 * Entry points here are:
45 *
46 * wa_nep_[create|destroy]() To initialize/release this subsystem
47 *
48 * wa_nep_cb() Callback for the notification
49 * endpoint; when data is ready, this
50 * does the dispatching.
51 */
52#include <linux/workqueue.h>
53#include <linux/ctype.h>
54#include <linux/uwb/debug.h>
55#include "wa-hc.h"
56#include "wusbhc.h"
57
58/* Structure for queueing notifications to the workqueue */
59struct wa_notif_work {
60 struct work_struct work;
61 struct wahc *wa;
62 size_t size;
63 u8 data[];
64};
65
66/*
67 * Process incoming notifications from the WA's Notification EndPoint
68 * [the wuswad daemon, basically]
69 *
70 * @_nw: Pointer to a descriptor which has the pointer to the
71 * @wa, the size of the buffer and the work queue
72 * structure (so we can free all when done).
73 * @returns 0 if ok, < 0 errno code on error.
74 *
75 * All notifications follow the same format; they need to start with a
76 * 'struct wa_notif_hdr' header, so it is easy to parse through
77 * them. We just break the buffer in individual notifications (the
78 * standard doesn't say if it can be done or is forbidden, so we are
79 * cautious) and dispatch each.
80 *
81 * So the handling layers are is:
82 *
83 * WA specific notification (from NEP)
84 * Device Notification Received -> wa_handle_notif_dn()
85 * WUSB Device notification generic handling
86 * BPST Adjustment -> wa_handle_notif_bpst_adj()
87 * ... -> ...
88 *
89 * @wa has to be referenced
90 */
91static void wa_notif_dispatch(struct work_struct *ws)
92{
93 void *itr;
94 u8 missing = 0;
95 struct wa_notif_work *nw = container_of(ws, struct wa_notif_work, work);
96 struct wahc *wa = nw->wa;
97 struct wa_notif_hdr *notif_hdr;
98 size_t size;
99
100 struct device *dev = &wa->usb_iface->dev;
101
102#if 0
103 /* FIXME: need to check for this??? */
104 if (usb_hcd->state == HC_STATE_QUIESCING) /* Going down? */
105 goto out; /* screw it */
106#endif
107 atomic_dec(&wa->notifs_queued); /* Throttling ctl */
108 dev = &wa->usb_iface->dev;
109 size = nw->size;
110 itr = nw->data;
111
112 while (size) {
113 if (size < sizeof(*notif_hdr)) {
114 missing = sizeof(*notif_hdr) - size;
115 goto exhausted_buffer;
116 }
117 notif_hdr = itr;
118 if (size < notif_hdr->bLength)
119 goto exhausted_buffer;
120 itr += notif_hdr->bLength;
121 size -= notif_hdr->bLength;
122 /* Dispatch the notification [don't use itr or size!] */
123 switch (notif_hdr->bNotifyType) {
124 case HWA_NOTIF_DN: {
125 struct hwa_notif_dn *hwa_dn;
126 hwa_dn = container_of(notif_hdr, struct hwa_notif_dn,
127 hdr);
128 wusbhc_handle_dn(wa->wusb, hwa_dn->bSourceDeviceAddr,
129 hwa_dn->dndata,
130 notif_hdr->bLength - sizeof(*hwa_dn));
131 break;
132 }
133 case WA_NOTIF_TRANSFER:
134 wa_handle_notif_xfer(wa, notif_hdr);
135 break;
136 case DWA_NOTIF_RWAKE:
137 case DWA_NOTIF_PORTSTATUS:
138 case HWA_NOTIF_BPST_ADJ:
139 /* FIXME: unimplemented WA NOTIFs */
140 /* fallthru */
141 default:
142 if (printk_ratelimit()) {
143 dev_err(dev, "HWA: unknown notification 0x%x, "
144 "%zu bytes; discarding\n",
145 notif_hdr->bNotifyType,
146 (size_t)notif_hdr->bLength);
147 dump_bytes(dev, notif_hdr, 16);
148 }
149 break;
150 }
151 }
152out:
153 wa_put(wa);
154 kfree(nw);
155 return;
156
157 /* THIS SHOULD NOT HAPPEN
158 *
159 * Buffer exahusted with partial data remaining; just warn and
160 * discard the data, as this should not happen.
161 */
162exhausted_buffer:
163 if (!printk_ratelimit())
164 goto out;
165 dev_warn(dev, "HWA: device sent short notification, "
166 "%d bytes missing; discarding %d bytes.\n",
167 missing, (int)size);
168 dump_bytes(dev, itr, size);
169 goto out;
170}
171
172/*
173 * Deliver incoming WA notifications to the wusbwa workqueue
174 *
175 * @wa: Pointer the Wire Adapter Controller Data Streaming
176 * instance (part of an 'struct usb_hcd').
177 * @size: Size of the received buffer
178 * @returns 0 if ok, < 0 errno code on error.
179 *
180 * The input buffer is @wa->nep_buffer, with @size bytes
181 * (guaranteed to fit in the allocated space,
182 * @wa->nep_buffer_size).
183 */
184static int wa_nep_queue(struct wahc *wa, size_t size)
185{
186 int result = 0;
187 struct device *dev = &wa->usb_iface->dev;
188 struct wa_notif_work *nw;
189
190 /* dev_fnstart(dev, "(wa %p, size %zu)\n", wa, size); */
191 BUG_ON(size > wa->nep_buffer_size);
192 if (size == 0)
193 goto out;
194 if (atomic_read(&wa->notifs_queued) > 200) {
195 if (printk_ratelimit())
196 dev_err(dev, "Too many notifications queued, "
197 "throttling back\n");
198 goto out;
199 }
200 nw = kzalloc(sizeof(*nw) + size, GFP_ATOMIC);
201 if (nw == NULL) {
202 if (printk_ratelimit())
203 dev_err(dev, "No memory to queue notification\n");
204 goto out;
205 }
206 INIT_WORK(&nw->work, wa_notif_dispatch);
207 nw->wa = wa_get(wa);
208 nw->size = size;
209 memcpy(nw->data, wa->nep_buffer, size);
210 atomic_inc(&wa->notifs_queued); /* Throttling ctl */
211 queue_work(wusbd, &nw->work);
212out:
213 /* dev_fnend(dev, "(wa %p, size %zu) = result\n", wa, size, result); */
214 return result;
215}
216
217/*
218 * Callback for the notification event endpoint
219 *
220 * Check's that everything is fine and then passes the data to be
221 * queued to the workqueue.
222 */
223static void wa_nep_cb(struct urb *urb)
224{
225 int result;
226 struct wahc *wa = urb->context;
227 struct device *dev = &wa->usb_iface->dev;
228
229 switch (result = urb->status) {
230 case 0:
231 result = wa_nep_queue(wa, urb->actual_length);
232 if (result < 0)
233 dev_err(dev, "NEP: unable to process notification(s): "
234 "%d\n", result);
235 break;
236 case -ECONNRESET: /* Not an error, but a controlled situation; */
237 case -ENOENT: /* (we killed the URB)...so, no broadcast */
238 case -ESHUTDOWN:
239 dev_dbg(dev, "NEP: going down %d\n", urb->status);
240 goto out;
241 default: /* On general errors, we retry unless it gets ugly */
242 if (edc_inc(&wa->nep_edc, EDC_MAX_ERRORS,
243 EDC_ERROR_TIMEFRAME)) {
244 dev_err(dev, "NEP: URB max acceptable errors "
245 "exceeded, resetting device\n");
246 wa_reset_all(wa);
247 goto out;
248 }
249 dev_err(dev, "NEP: URB error %d\n", urb->status);
250 }
251 result = wa_nep_arm(wa, GFP_ATOMIC);
252 if (result < 0) {
253 dev_err(dev, "NEP: cannot submit URB: %d\n", result);
254 wa_reset_all(wa);
255 }
256out:
257 return;
258}
259
260/*
261 * Initialize @wa's notification and event's endpoint stuff
262 *
263 * This includes the allocating the read buffer, the context ID
264 * allocation bitmap, the URB and submitting the URB.
265 */
266int wa_nep_create(struct wahc *wa, struct usb_interface *iface)
267{
268 int result;
269 struct usb_endpoint_descriptor *epd;
270 struct usb_device *usb_dev = interface_to_usbdev(iface);
271 struct device *dev = &iface->dev;
272
273 edc_init(&wa->nep_edc);
274 epd = &iface->cur_altsetting->endpoint[0].desc;
275 wa->nep_buffer_size = 1024;
276 wa->nep_buffer = kmalloc(wa->nep_buffer_size, GFP_KERNEL);
277 if (wa->nep_buffer == NULL) {
278 dev_err(dev, "Unable to allocate notification's read buffer\n");
279 goto error_nep_buffer;
280 }
281 wa->nep_urb = usb_alloc_urb(0, GFP_KERNEL);
282 if (wa->nep_urb == NULL) {
283 dev_err(dev, "Unable to allocate notification URB\n");
284 goto error_urb_alloc;
285 }
286 usb_fill_int_urb(wa->nep_urb, usb_dev,
287 usb_rcvintpipe(usb_dev, epd->bEndpointAddress),
288 wa->nep_buffer, wa->nep_buffer_size,
289 wa_nep_cb, wa, epd->bInterval);
290 result = wa_nep_arm(wa, GFP_KERNEL);
291 if (result < 0) {
292 dev_err(dev, "Cannot submit notification URB: %d\n", result);
293 goto error_nep_arm;
294 }
295 return 0;
296
297error_nep_arm:
298 usb_free_urb(wa->nep_urb);
299error_urb_alloc:
300 kfree(wa->nep_buffer);
301error_nep_buffer:
302 return -ENOMEM;
303}
304
305void wa_nep_destroy(struct wahc *wa)
306{
307 wa_nep_disarm(wa);
308 usb_free_urb(wa->nep_urb);
309 kfree(wa->nep_buffer);
310}
diff --git a/drivers/usb/wusbcore/wa-rpipe.c b/drivers/usb/wusbcore/wa-rpipe.c
new file mode 100644
index 000000000000..f18e4aae66e9
--- /dev/null
+++ b/drivers/usb/wusbcore/wa-rpipe.c
@@ -0,0 +1,562 @@
1/*
2 * WUSB Wire Adapter
3 * rpipe management
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 * FIXME: docs
24 *
25 * RPIPE
26 *
27 * Targetted at different downstream endpoints
28 *
29 * Descriptor: use to config the remote pipe.
30 *
31 * The number of blocks could be dynamic (wBlocks in descriptor is
32 * 0)--need to schedule them then.
33 *
34 * Each bit in wa->rpipe_bm represents if an rpipe is being used or
35 * not. Rpipes are represented with a 'struct wa_rpipe' that is
36 * attached to the hcpriv member of a 'struct usb_host_endpoint'.
37 *
38 * When you need to xfer data to an endpoint, you get an rpipe for it
39 * with wa_ep_rpipe_get(), which gives you a reference to the rpipe
40 * and keeps a single one (the first one) with the endpoint. When you
41 * are done transferring, you drop that reference. At the end the
42 * rpipe is always allocated and bound to the endpoint. There it might
43 * be recycled when not used.
44 *
45 * Addresses:
46 *
47 * We use a 1:1 mapping mechanism between port address (0 based
48 * index, actually) and the address. The USB stack knows about this.
49 *
50 * USB Stack port number 4 (1 based)
51 * WUSB code port index 3 (0 based)
52 * USB Addresss 5 (2 based -- 0 is for default, 1 for root hub)
53 *
54 * Now, because we don't use the concept as default address exactly
55 * like the (wired) USB code does, we need to kind of skip it. So we
56 * never take addresses from the urb->pipe, but from the
57 * urb->dev->devnum, to make sure that we always have the right
58 * destination address.
59 */
60#include <linux/init.h>
61#include <asm/atomic.h>
62#include <linux/bitmap.h>
63#include "wusbhc.h"
64#include "wa-hc.h"
65
66#define D_LOCAL 0
67#include <linux/uwb/debug.h>
68
69
70static int __rpipe_get_descr(struct wahc *wa,
71 struct usb_rpipe_descriptor *descr, u16 index)
72{
73 ssize_t result;
74 struct device *dev = &wa->usb_iface->dev;
75
76 /* Get the RPIPE descriptor -- we cannot use the usb_get_descriptor()
77 * function because the arguments are different.
78 */
79 d_printf(1, dev, "rpipe %u: get descr\n", index);
80 result = usb_control_msg(
81 wa->usb_dev, usb_rcvctrlpipe(wa->usb_dev, 0),
82 USB_REQ_GET_DESCRIPTOR,
83 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_RPIPE,
84 USB_DT_RPIPE<<8, index, descr, sizeof(*descr),
85 1000 /* FIXME: arbitrary */);
86 if (result < 0) {
87 dev_err(dev, "rpipe %u: get descriptor failed: %d\n",
88 index, (int)result);
89 goto error;
90 }
91 if (result < sizeof(*descr)) {
92 dev_err(dev, "rpipe %u: got short descriptor "
93 "(%zd vs %zd bytes needed)\n",
94 index, result, sizeof(*descr));
95 result = -EINVAL;
96 goto error;
97 }
98 result = 0;
99
100error:
101 return result;
102}
103
104/*
105 *
106 * The descriptor is assumed to be properly initialized (ie: you got
107 * it through __rpipe_get_descr()).
108 */
109static int __rpipe_set_descr(struct wahc *wa,
110 struct usb_rpipe_descriptor *descr, u16 index)
111{
112 ssize_t result;
113 struct device *dev = &wa->usb_iface->dev;
114
115 /* we cannot use the usb_get_descriptor() function because the
116 * arguments are different.
117 */
118 d_printf(1, dev, "rpipe %u: set descr\n", index);
119 result = usb_control_msg(
120 wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
121 USB_REQ_SET_DESCRIPTOR,
122 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_RPIPE,
123 USB_DT_RPIPE<<8, index, descr, sizeof(*descr),
124 HZ / 10);
125 if (result < 0) {
126 dev_err(dev, "rpipe %u: set descriptor failed: %d\n",
127 index, (int)result);
128 goto error;
129 }
130 if (result < sizeof(*descr)) {
131 dev_err(dev, "rpipe %u: sent short descriptor "
132 "(%zd vs %zd bytes required)\n",
133 index, result, sizeof(*descr));
134 result = -EINVAL;
135 goto error;
136 }
137 result = 0;
138
139error:
140 return result;
141
142}
143
144static void rpipe_init(struct wa_rpipe *rpipe)
145{
146 kref_init(&rpipe->refcnt);
147 spin_lock_init(&rpipe->seg_lock);
148 INIT_LIST_HEAD(&rpipe->seg_list);
149}
150
151static unsigned rpipe_get_idx(struct wahc *wa, unsigned rpipe_idx)
152{
153 unsigned long flags;
154
155 spin_lock_irqsave(&wa->rpipe_bm_lock, flags);
156 rpipe_idx = find_next_zero_bit(wa->rpipe_bm, wa->rpipes, rpipe_idx);
157 if (rpipe_idx < wa->rpipes)
158 set_bit(rpipe_idx, wa->rpipe_bm);
159 spin_unlock_irqrestore(&wa->rpipe_bm_lock, flags);
160
161 return rpipe_idx;
162}
163
164static void rpipe_put_idx(struct wahc *wa, unsigned rpipe_idx)
165{
166 unsigned long flags;
167
168 spin_lock_irqsave(&wa->rpipe_bm_lock, flags);
169 clear_bit(rpipe_idx, wa->rpipe_bm);
170 spin_unlock_irqrestore(&wa->rpipe_bm_lock, flags);
171}
172
173void rpipe_destroy(struct kref *_rpipe)
174{
175 struct wa_rpipe *rpipe = container_of(_rpipe, struct wa_rpipe, refcnt);
176 u8 index = le16_to_cpu(rpipe->descr.wRPipeIndex);
177 d_fnstart(1, NULL, "(rpipe %p %u)\n", rpipe, index);
178 if (rpipe->ep)
179 rpipe->ep->hcpriv = NULL;
180 rpipe_put_idx(rpipe->wa, index);
181 wa_put(rpipe->wa);
182 kfree(rpipe);
183 d_fnend(1, NULL, "(rpipe %p %u)\n", rpipe, index);
184}
185EXPORT_SYMBOL_GPL(rpipe_destroy);
186
187/*
188 * Locate an idle rpipe, create an structure for it and return it
189 *
190 * @wa is referenced and unlocked
191 * @crs enum rpipe_attr, required endpoint characteristics
192 *
193 * The rpipe can be used only sequentially (not in parallel).
194 *
195 * The rpipe is moved into the "ready" state.
196 */
197static int rpipe_get_idle(struct wa_rpipe **prpipe, struct wahc *wa, u8 crs,
198 gfp_t gfp)
199{
200 int result;
201 unsigned rpipe_idx;
202 struct wa_rpipe *rpipe;
203 struct device *dev = &wa->usb_iface->dev;
204
205 d_fnstart(3, dev, "(wa %p crs 0x%02x)\n", wa, crs);
206 rpipe = kzalloc(sizeof(*rpipe), gfp);
207 if (rpipe == NULL)
208 return -ENOMEM;
209 rpipe_init(rpipe);
210
211 /* Look for an idle pipe */
212 for (rpipe_idx = 0; rpipe_idx < wa->rpipes; rpipe_idx++) {
213 rpipe_idx = rpipe_get_idx(wa, rpipe_idx);
214 if (rpipe_idx >= wa->rpipes) /* no more pipes :( */
215 break;
216 result = __rpipe_get_descr(wa, &rpipe->descr, rpipe_idx);
217 if (result < 0)
218 dev_err(dev, "Can't get descriptor for rpipe %u: %d\n",
219 rpipe_idx, result);
220 else if ((rpipe->descr.bmCharacteristics & crs) != 0)
221 goto found;
222 rpipe_put_idx(wa, rpipe_idx);
223 }
224 *prpipe = NULL;
225 kfree(rpipe);
226 d_fnend(3, dev, "(wa %p crs 0x%02x) = -ENXIO\n", wa, crs);
227 return -ENXIO;
228
229found:
230 set_bit(rpipe_idx, wa->rpipe_bm);
231 rpipe->wa = wa_get(wa);
232 *prpipe = rpipe;
233 d_fnstart(3, dev, "(wa %p crs 0x%02x) = 0\n", wa, crs);
234 return 0;
235}
236
237static int __rpipe_reset(struct wahc *wa, unsigned index)
238{
239 int result;
240 struct device *dev = &wa->usb_iface->dev;
241
242 d_printf(1, dev, "rpipe %u: reset\n", index);
243 result = usb_control_msg(
244 wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
245 USB_REQ_RPIPE_RESET,
246 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_RPIPE,
247 0, index, NULL, 0, 1000 /* FIXME: arbitrary */);
248 if (result < 0)
249 dev_err(dev, "rpipe %u: reset failed: %d\n",
250 index, result);
251 return result;
252}
253
254/*
255 * Fake companion descriptor for ep0
256 *
257 * See WUSB1.0[7.4.4], most of this is zero for bulk/int/ctl
258 */
259static struct usb_wireless_ep_comp_descriptor epc0 = {
260 .bLength = sizeof(epc0),
261 .bDescriptorType = USB_DT_WIRELESS_ENDPOINT_COMP,
262/* .bMaxBurst = 1, */
263 .bMaxSequence = 31,
264};
265
266/*
267 * Look for EP companion descriptor
268 *
269 * Get there, look for Inara in the endpoint's extra descriptors
270 */
271static struct usb_wireless_ep_comp_descriptor *rpipe_epc_find(
272 struct device *dev, struct usb_host_endpoint *ep)
273{
274 void *itr;
275 size_t itr_size;
276 struct usb_descriptor_header *hdr;
277 struct usb_wireless_ep_comp_descriptor *epcd;
278
279 d_fnstart(3, dev, "(ep %p)\n", ep);
280 if (ep->desc.bEndpointAddress == 0) {
281 epcd = &epc0;
282 goto out;
283 }
284 itr = ep->extra;
285 itr_size = ep->extralen;
286 epcd = NULL;
287 while (itr_size > 0) {
288 if (itr_size < sizeof(*hdr)) {
289 dev_err(dev, "HW Bug? ep 0x%02x: extra descriptors "
290 "at offset %zu: only %zu bytes left\n",
291 ep->desc.bEndpointAddress,
292 itr - (void *) ep->extra, itr_size);
293 break;
294 }
295 hdr = itr;
296 if (hdr->bDescriptorType == USB_DT_WIRELESS_ENDPOINT_COMP) {
297 epcd = itr;
298 break;
299 }
300 if (hdr->bLength > itr_size) {
301 dev_err(dev, "HW Bug? ep 0x%02x: extra descriptor "
302 "at offset %zu (type 0x%02x) "
303 "length %d but only %zu bytes left\n",
304 ep->desc.bEndpointAddress,
305 itr - (void *) ep->extra, hdr->bDescriptorType,
306 hdr->bLength, itr_size);
307 break;
308 }
309 itr += hdr->bLength;
310 itr_size -= hdr->bDescriptorType;
311 }
312out:
313 d_fnend(3, dev, "(ep %p) = %p\n", ep, epcd);
314 return epcd;
315}
316
317/*
318 * Aim an rpipe to its device & endpoint destination
319 *
320 * Make sure we change the address to unauthenticathed if the device
321 * is WUSB and it is not authenticated.
322 */
323static int rpipe_aim(struct wa_rpipe *rpipe, struct wahc *wa,
324 struct usb_host_endpoint *ep, struct urb *urb, gfp_t gfp)
325{
326 int result = -ENOMSG; /* better code for lack of companion? */
327 struct device *dev = &wa->usb_iface->dev;
328 struct usb_device *usb_dev = urb->dev;
329 struct usb_wireless_ep_comp_descriptor *epcd;
330 u8 unauth;
331
332 d_fnstart(3, dev, "(rpipe %p wa %p ep %p, urb %p)\n",
333 rpipe, wa, ep, urb);
334 epcd = rpipe_epc_find(dev, ep);
335 if (epcd == NULL) {
336 dev_err(dev, "ep 0x%02x: can't find companion descriptor\n",
337 ep->desc.bEndpointAddress);
338 goto error;
339 }
340 unauth = usb_dev->wusb && !usb_dev->authenticated ? 0x80 : 0;
341 __rpipe_reset(wa, le16_to_cpu(rpipe->descr.wRPipeIndex));
342 atomic_set(&rpipe->segs_available, le16_to_cpu(rpipe->descr.wRequests));
343 /* FIXME: block allocation system; request with queuing and timeout */
344 /* FIXME: compute so seg_size > ep->maxpktsize */
345 rpipe->descr.wBlocks = cpu_to_le16(16); /* given */
346 /* ep0 maxpktsize is 0x200 (WUSB1.0[4.8.1]) */
347 rpipe->descr.wMaxPacketSize = cpu_to_le16(ep->desc.wMaxPacketSize);
348 rpipe->descr.bHSHubAddress = 0; /* reserved: zero */
349 rpipe->descr.bHSHubPort = wusb_port_no_to_idx(urb->dev->portnum);
350 /* FIXME: use maximum speed as supported or recommended by device */
351 rpipe->descr.bSpeed = usb_pipeendpoint(urb->pipe) == 0 ?
352 UWB_PHY_RATE_53 : UWB_PHY_RATE_200;
353 d_printf(2, dev, "addr %u (0x%02x) rpipe #%u ep# %u speed %d\n",
354 urb->dev->devnum, urb->dev->devnum | unauth,
355 le16_to_cpu(rpipe->descr.wRPipeIndex),
356 usb_pipeendpoint(urb->pipe), rpipe->descr.bSpeed);
357 /* see security.c:wusb_update_address() */
358 if (unlikely(urb->dev->devnum == 0x80))
359 rpipe->descr.bDeviceAddress = 0;
360 else
361 rpipe->descr.bDeviceAddress = urb->dev->devnum | unauth;
362 rpipe->descr.bEndpointAddress = ep->desc.bEndpointAddress;
363 /* FIXME: bDataSequence */
364 rpipe->descr.bDataSequence = 0;
365 /* FIXME: dwCurrentWindow */
366 rpipe->descr.dwCurrentWindow = cpu_to_le32(1);
367 /* FIXME: bMaxDataSequence */
368 rpipe->descr.bMaxDataSequence = epcd->bMaxSequence - 1;
369 rpipe->descr.bInterval = ep->desc.bInterval;
370 /* FIXME: bOverTheAirInterval */
371 rpipe->descr.bOverTheAirInterval = 0; /* 0 if not isoc */
372 /* FIXME: xmit power & preamble blah blah */
373 rpipe->descr.bmAttribute = ep->desc.bmAttributes & 0x03;
374 /* rpipe->descr.bmCharacteristics RO */
375 /* FIXME: bmRetryOptions */
376 rpipe->descr.bmRetryOptions = 15;
377 /* FIXME: use for assessing link quality? */
378 rpipe->descr.wNumTransactionErrors = 0;
379 result = __rpipe_set_descr(wa, &rpipe->descr,
380 le16_to_cpu(rpipe->descr.wRPipeIndex));
381 if (result < 0) {
382 dev_err(dev, "Cannot aim rpipe: %d\n", result);
383 goto error;
384 }
385 result = 0;
386error:
387 d_fnend(3, dev, "(rpipe %p wa %p ep %p urb %p) = %d\n",
388 rpipe, wa, ep, urb, result);
389 return result;
390}
391
392/*
393 * Check an aimed rpipe to make sure it points to where we want
394 *
395 * We use bit 19 of the Linux USB pipe bitmap for unauth vs auth
396 * space; when it is like that, we or 0x80 to make an unauth address.
397 */
398static int rpipe_check_aim(const struct wa_rpipe *rpipe, const struct wahc *wa,
399 const struct usb_host_endpoint *ep,
400 const struct urb *urb, gfp_t gfp)
401{
402 int result = 0; /* better code for lack of companion? */
403 struct device *dev = &wa->usb_iface->dev;
404 struct usb_device *usb_dev = urb->dev;
405 u8 unauth = (usb_dev->wusb && !usb_dev->authenticated) ? 0x80 : 0;
406 u8 portnum = wusb_port_no_to_idx(urb->dev->portnum);
407
408 d_fnstart(3, dev, "(rpipe %p wa %p ep %p, urb %p)\n",
409 rpipe, wa, ep, urb);
410#define AIM_CHECK(rdf, val, text) \
411 do { \
412 if (rpipe->descr.rdf != (val)) { \
413 dev_err(dev, \
414 "rpipe aim discrepancy: " #rdf " " text "\n", \
415 rpipe->descr.rdf, (val)); \
416 result = -EINVAL; \
417 WARN_ON(1); \
418 } \
419 } while (0)
420 AIM_CHECK(wMaxPacketSize, cpu_to_le16(ep->desc.wMaxPacketSize),
421 "(%u vs %u)");
422 AIM_CHECK(bHSHubPort, portnum, "(%u vs %u)");
423 AIM_CHECK(bSpeed, usb_pipeendpoint(urb->pipe) == 0 ?
424 UWB_PHY_RATE_53 : UWB_PHY_RATE_200,
425 "(%u vs %u)");
426 AIM_CHECK(bDeviceAddress, urb->dev->devnum | unauth, "(%u vs %u)");
427 AIM_CHECK(bEndpointAddress, ep->desc.bEndpointAddress, "(%u vs %u)");
428 AIM_CHECK(bInterval, ep->desc.bInterval, "(%u vs %u)");
429 AIM_CHECK(bmAttribute, ep->desc.bmAttributes & 0x03, "(%u vs %u)");
430#undef AIM_CHECK
431 return result;
432}
433
434#ifndef CONFIG_BUG
435#define CONFIG_BUG 0
436#endif
437
438/*
439 * Make sure there is an rpipe allocated for an endpoint
440 *
441 * If already allocated, we just refcount it; if not, we get an
442 * idle one, aim it to the right location and take it.
443 *
444 * Attaches to ep->hcpriv and rpipe->ep to ep.
445 */
446int rpipe_get_by_ep(struct wahc *wa, struct usb_host_endpoint *ep,
447 struct urb *urb, gfp_t gfp)
448{
449 int result = 0;
450 struct device *dev = &wa->usb_iface->dev;
451 struct wa_rpipe *rpipe;
452 u8 eptype;
453
454 d_fnstart(3, dev, "(wa %p ep %p urb %p gfp 0x%08x)\n", wa, ep, urb,
455 gfp);
456 mutex_lock(&wa->rpipe_mutex);
457 rpipe = ep->hcpriv;
458 if (rpipe != NULL) {
459 if (CONFIG_BUG == 1) {
460 result = rpipe_check_aim(rpipe, wa, ep, urb, gfp);
461 if (result < 0)
462 goto error;
463 }
464 __rpipe_get(rpipe);
465 d_printf(2, dev, "ep 0x%02x: reusing rpipe %u\n",
466 ep->desc.bEndpointAddress,
467 le16_to_cpu(rpipe->descr.wRPipeIndex));
468 } else {
469 /* hmm, assign idle rpipe, aim it */
470 result = -ENOBUFS;
471 eptype = ep->desc.bmAttributes & 0x03;
472 result = rpipe_get_idle(&rpipe, wa, 1 << eptype, gfp);
473 if (result < 0)
474 goto error;
475 result = rpipe_aim(rpipe, wa, ep, urb, gfp);
476 if (result < 0) {
477 rpipe_put(rpipe);
478 goto error;
479 }
480 ep->hcpriv = rpipe;
481 rpipe->ep = ep;
482 __rpipe_get(rpipe); /* for caching into ep->hcpriv */
483 d_printf(2, dev, "ep 0x%02x: using rpipe %u\n",
484 ep->desc.bEndpointAddress,
485 le16_to_cpu(rpipe->descr.wRPipeIndex));
486 }
487 d_dump(4, dev, &rpipe->descr, sizeof(rpipe->descr));
488error:
489 mutex_unlock(&wa->rpipe_mutex);
490 d_fnend(3, dev, "(wa %p ep %p urb %p gfp 0x%08x)\n", wa, ep, urb, gfp);
491 return result;
492}
493
494/*
495 * Allocate the bitmap for each rpipe.
496 */
497int wa_rpipes_create(struct wahc *wa)
498{
499 wa->rpipes = wa->wa_descr->wNumRPipes;
500 wa->rpipe_bm = kzalloc(BITS_TO_LONGS(wa->rpipes)*sizeof(unsigned long),
501 GFP_KERNEL);
502 if (wa->rpipe_bm == NULL)
503 return -ENOMEM;
504 return 0;
505}
506
507void wa_rpipes_destroy(struct wahc *wa)
508{
509 struct device *dev = &wa->usb_iface->dev;
510 d_fnstart(3, dev, "(wa %p)\n", wa);
511 if (!bitmap_empty(wa->rpipe_bm, wa->rpipes)) {
512 char buf[256];
513 WARN_ON(1);
514 bitmap_scnprintf(buf, sizeof(buf), wa->rpipe_bm, wa->rpipes);
515 dev_err(dev, "BUG: pipes not released on exit: %s\n", buf);
516 }
517 kfree(wa->rpipe_bm);
518 d_fnend(3, dev, "(wa %p)\n", wa);
519}
520
521/*
522 * Release resources allocated for an endpoint
523 *
524 * If there is an associated rpipe to this endpoint, Abort any pending
525 * transfers and put it. If the rpipe ends up being destroyed,
526 * __rpipe_destroy() will cleanup ep->hcpriv.
527 *
528 * This is called before calling hcd->stop(), so you don't need to do
529 * anything else in there.
530 */
531void rpipe_ep_disable(struct wahc *wa, struct usb_host_endpoint *ep)
532{
533 struct device *dev = &wa->usb_iface->dev;
534 struct wa_rpipe *rpipe;
535 d_fnstart(2, dev, "(wa %p ep %p)\n", wa, ep);
536 mutex_lock(&wa->rpipe_mutex);
537 rpipe = ep->hcpriv;
538 if (rpipe != NULL) {
539 unsigned rc = atomic_read(&rpipe->refcnt.refcount);
540 int result;
541 u16 index = le16_to_cpu(rpipe->descr.wRPipeIndex);
542
543 if (rc != 1)
544 d_printf(1, dev, "(wa %p ep %p) rpipe %p refcnt %u\n",
545 wa, ep, rpipe, rc);
546
547 d_printf(1, dev, "rpipe %u: abort\n", index);
548 result = usb_control_msg(
549 wa->usb_dev, usb_rcvctrlpipe(wa->usb_dev, 0),
550 USB_REQ_RPIPE_ABORT,
551 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_RPIPE,
552 0, index, NULL, 0, 1000 /* FIXME: arbitrary */);
553 if (result < 0 && result != -ENODEV /* dev is gone */)
554 d_printf(1, dev, "(wa %p rpipe %u): abort failed: %d\n",
555 wa, index, result);
556 rpipe_put(rpipe);
557 }
558 mutex_unlock(&wa->rpipe_mutex);
559 d_fnend(2, dev, "(wa %p ep %p)\n", wa, ep);
560 return;
561}
562EXPORT_SYMBOL_GPL(rpipe_ep_disable);
diff --git a/drivers/usb/wusbcore/wa-xfer.c b/drivers/usb/wusbcore/wa-xfer.c
new file mode 100644
index 000000000000..7d192f3e6742
--- /dev/null
+++ b/drivers/usb/wusbcore/wa-xfer.c
@@ -0,0 +1,1709 @@
1/*
2 * WUSB Wire Adapter
3 * Data transfer and URB enqueing
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 * How transfers work: get a buffer, break it up in segments (segment
24 * size is a multiple of the maxpacket size). For each segment issue a
25 * segment request (struct wa_xfer_*), then send the data buffer if
26 * out or nothing if in (all over the DTO endpoint).
27 *
28 * For each submitted segment request, a notification will come over
29 * the NEP endpoint and a transfer result (struct xfer_result) will
30 * arrive in the DTI URB. Read it, get the xfer ID, see if there is
31 * data coming (inbound transfer), schedule a read and handle it.
32 *
33 * Sounds simple, it is a pain to implement.
34 *
35 *
36 * ENTRY POINTS
37 *
38 * FIXME
39 *
40 * LIFE CYCLE / STATE DIAGRAM
41 *
42 * FIXME
43 *
44 * THIS CODE IS DISGUSTING
45 *
46 * Warned you are; it's my second try and still not happy with it.
47 *
48 * NOTES:
49 *
50 * - No iso
51 *
52 * - Supports DMA xfers, control, bulk and maybe interrupt
53 *
54 * - Does not recycle unused rpipes
55 *
56 * An rpipe is assigned to an endpoint the first time it is used,
57 * and then it's there, assigned, until the endpoint is disabled
58 * (destroyed [{h,d}wahc_op_ep_disable()]. The assignment of the
59 * rpipe to the endpoint is done under the wa->rpipe_sem semaphore
60 * (should be a mutex).
61 *
62 * Two methods it could be done:
63 *
64 * (a) set up a timer everytime an rpipe's use count drops to 1
65 * (which means unused) or when a transfer ends. Reset the
66 * timer when a xfer is queued. If the timer expires, release
67 * the rpipe [see rpipe_ep_disable()].
68 *
69 * (b) when looking for free rpipes to attach [rpipe_get_by_ep()],
70 * when none are found go over the list, check their endpoint
71 * and their activity record (if no last-xfer-done-ts in the
72 * last x seconds) take it
73 *
74 * However, due to the fact that we have a set of limited
75 * resources (max-segments-at-the-same-time per xfer,
76 * xfers-per-ripe, blocks-per-rpipe, rpipes-per-host), at the end
77 * we are going to have to rebuild all this based on an scheduler,
78 * to where we have a list of transactions to do and based on the
79 * availability of the different requried components (blocks,
80 * rpipes, segment slots, etc), we go scheduling them. Painful.
81 */
82#include <linux/init.h>
83#include <linux/spinlock.h>
84#include <linux/hash.h>
85#include "wa-hc.h"
86#include "wusbhc.h"
87
88#undef D_LOCAL
89#define D_LOCAL 0 /* 0 disabled, > 0 different levels... */
90#include <linux/uwb/debug.h>
91
92enum {
93 WA_SEGS_MAX = 255,
94};
95
96enum wa_seg_status {
97 WA_SEG_NOTREADY,
98 WA_SEG_READY,
99 WA_SEG_DELAYED,
100 WA_SEG_SUBMITTED,
101 WA_SEG_PENDING,
102 WA_SEG_DTI_PENDING,
103 WA_SEG_DONE,
104 WA_SEG_ERROR,
105 WA_SEG_ABORTED,
106};
107
108static void wa_xfer_delayed_run(struct wa_rpipe *);
109
110/*
111 * Life cycle governed by 'struct urb' (the refcount of the struct is
112 * that of the 'struct urb' and usb_free_urb() would free the whole
113 * struct).
114 */
115struct wa_seg {
116 struct urb urb;
117 struct urb *dto_urb; /* for data output? */
118 struct list_head list_node; /* for rpipe->req_list */
119 struct wa_xfer *xfer; /* out xfer */
120 u8 index; /* which segment we are */
121 enum wa_seg_status status;
122 ssize_t result; /* bytes xfered or error */
123 struct wa_xfer_hdr xfer_hdr;
124 u8 xfer_extra[]; /* xtra space for xfer_hdr_ctl */
125};
126
127static void wa_seg_init(struct wa_seg *seg)
128{
129 /* usb_init_urb() repeats a lot of work, so we do it here */
130 kref_init(&seg->urb.kref);
131}
132
133/*
134 * Protected by xfer->lock
135 *
136 */
137struct wa_xfer {
138 struct kref refcnt;
139 struct list_head list_node;
140 spinlock_t lock;
141 u32 id;
142
143 struct wahc *wa; /* Wire adapter we are plugged to */
144 struct usb_host_endpoint *ep;
145 struct urb *urb; /* URB we are transfering for */
146 struct wa_seg **seg; /* transfer segments */
147 u8 segs, segs_submitted, segs_done;
148 unsigned is_inbound:1;
149 unsigned is_dma:1;
150 size_t seg_size;
151 int result;
152
153 gfp_t gfp; /* allocation mask */
154
155 struct wusb_dev *wusb_dev; /* for activity timestamps */
156};
157
158static inline void wa_xfer_init(struct wa_xfer *xfer)
159{
160 kref_init(&xfer->refcnt);
161 INIT_LIST_HEAD(&xfer->list_node);
162 spin_lock_init(&xfer->lock);
163}
164
165/*
166 * Destory a transfer structure
167 *
168 * Note that the xfer->seg[index] thingies follow the URB life cycle,
169 * so we need to put them, not free them.
170 */
171static void wa_xfer_destroy(struct kref *_xfer)
172{
173 struct wa_xfer *xfer = container_of(_xfer, struct wa_xfer, refcnt);
174 if (xfer->seg) {
175 unsigned cnt;
176 for (cnt = 0; cnt < xfer->segs; cnt++) {
177 if (xfer->is_inbound)
178 usb_put_urb(xfer->seg[cnt]->dto_urb);
179 usb_put_urb(&xfer->seg[cnt]->urb);
180 }
181 }
182 kfree(xfer);
183 d_printf(2, NULL, "xfer %p destroyed\n", xfer);
184}
185
186static void wa_xfer_get(struct wa_xfer *xfer)
187{
188 kref_get(&xfer->refcnt);
189}
190
191static void wa_xfer_put(struct wa_xfer *xfer)
192{
193 d_fnstart(3, NULL, "(xfer %p) -- ref count bef put %d\n",
194 xfer, atomic_read(&xfer->refcnt.refcount));
195 kref_put(&xfer->refcnt, wa_xfer_destroy);
196 d_fnend(3, NULL, "(xfer %p) = void\n", xfer);
197}
198
199/*
200 * xfer is referenced
201 *
202 * xfer->lock has to be unlocked
203 *
204 * We take xfer->lock for setting the result; this is a barrier
205 * against drivers/usb/core/hcd.c:unlink1() being called after we call
206 * usb_hcd_giveback_urb() and wa_urb_dequeue() trying to get a
207 * reference to the transfer.
208 */
209static void wa_xfer_giveback(struct wa_xfer *xfer)
210{
211 unsigned long flags;
212 d_fnstart(3, NULL, "(xfer %p)\n", xfer);
213 spin_lock_irqsave(&xfer->wa->xfer_list_lock, flags);
214 list_del_init(&xfer->list_node);
215 spin_unlock_irqrestore(&xfer->wa->xfer_list_lock, flags);
216 /* FIXME: segmentation broken -- kills DWA */
217 wusbhc_giveback_urb(xfer->wa->wusb, xfer->urb, xfer->result);
218 wa_put(xfer->wa);
219 wa_xfer_put(xfer);
220 d_fnend(3, NULL, "(xfer %p) = void\n", xfer);
221}
222
223/*
224 * xfer is referenced
225 *
226 * xfer->lock has to be unlocked
227 */
228static void wa_xfer_completion(struct wa_xfer *xfer)
229{
230 d_fnstart(3, NULL, "(xfer %p)\n", xfer);
231 if (xfer->wusb_dev)
232 wusb_dev_put(xfer->wusb_dev);
233 rpipe_put(xfer->ep->hcpriv);
234 wa_xfer_giveback(xfer);
235 d_fnend(3, NULL, "(xfer %p) = void\n", xfer);
236 return;
237}
238
239/*
240 * If transfer is done, wrap it up and return true
241 *
242 * xfer->lock has to be locked
243 */
244static unsigned __wa_xfer_is_done(struct wa_xfer *xfer)
245{
246 unsigned result, cnt;
247 struct wa_seg *seg;
248 struct urb *urb = xfer->urb;
249 unsigned found_short = 0;
250
251 d_fnstart(3, NULL, "(xfer %p)\n", xfer);
252 result = xfer->segs_done == xfer->segs_submitted;
253 if (result == 0)
254 goto out;
255 urb->actual_length = 0;
256 for (cnt = 0; cnt < xfer->segs; cnt++) {
257 seg = xfer->seg[cnt];
258 switch (seg->status) {
259 case WA_SEG_DONE:
260 if (found_short && seg->result > 0) {
261 if (printk_ratelimit())
262 printk(KERN_ERR "xfer %p#%u: bad short "
263 "segments (%zu)\n", xfer, cnt,
264 seg->result);
265 urb->status = -EINVAL;
266 goto out;
267 }
268 urb->actual_length += seg->result;
269 if (seg->result < xfer->seg_size
270 && cnt != xfer->segs-1)
271 found_short = 1;
272 d_printf(2, NULL, "xfer %p#%u: DONE short %d "
273 "result %zu urb->actual_length %d\n",
274 xfer, seg->index, found_short, seg->result,
275 urb->actual_length);
276 break;
277 case WA_SEG_ERROR:
278 xfer->result = seg->result;
279 d_printf(2, NULL, "xfer %p#%u: ERROR result %zu\n",
280 xfer, seg->index, seg->result);
281 goto out;
282 case WA_SEG_ABORTED:
283 WARN_ON(urb->status != -ECONNRESET
284 && urb->status != -ENOENT);
285 d_printf(2, NULL, "xfer %p#%u ABORTED: result %d\n",
286 xfer, seg->index, urb->status);
287 xfer->result = urb->status;
288 goto out;
289 default:
290 /* if (printk_ratelimit()) */
291 printk(KERN_ERR "xfer %p#%u: "
292 "is_done bad state %d\n",
293 xfer, cnt, seg->status);
294 xfer->result = -EINVAL;
295 WARN_ON(1);
296 goto out;
297 }
298 }
299 xfer->result = 0;
300out:
301 d_fnend(3, NULL, "(xfer %p) = void\n", xfer);
302 return result;
303}
304
305/*
306 * Initialize a transfer's ID
307 *
308 * We need to use a sequential number; if we use the pointer or the
309 * hash of the pointer, it can repeat over sequential transfers and
310 * then it will confuse the HWA....wonder why in hell they put a 32
311 * bit handle in there then.
312 */
313static void wa_xfer_id_init(struct wa_xfer *xfer)
314{
315 xfer->id = atomic_add_return(1, &xfer->wa->xfer_id_count);
316}
317
318/*
319 * Return the xfer's ID associated with xfer
320 *
321 * Need to generate a
322 */
323static u32 wa_xfer_id(struct wa_xfer *xfer)
324{
325 return xfer->id;
326}
327
328/*
329 * Search for a transfer list ID on the HCD's URB list
330 *
331 * For 32 bit architectures, we use the pointer itself; for 64 bits, a
332 * 32-bit hash of the pointer.
333 *
334 * @returns NULL if not found.
335 */
336static struct wa_xfer *wa_xfer_get_by_id(struct wahc *wa, u32 id)
337{
338 unsigned long flags;
339 struct wa_xfer *xfer_itr;
340 spin_lock_irqsave(&wa->xfer_list_lock, flags);
341 list_for_each_entry(xfer_itr, &wa->xfer_list, list_node) {
342 if (id == xfer_itr->id) {
343 wa_xfer_get(xfer_itr);
344 goto out;
345 }
346 }
347 xfer_itr = NULL;
348out:
349 spin_unlock_irqrestore(&wa->xfer_list_lock, flags);
350 return xfer_itr;
351}
352
353struct wa_xfer_abort_buffer {
354 struct urb urb;
355 struct wa_xfer_abort cmd;
356};
357
358static void __wa_xfer_abort_cb(struct urb *urb)
359{
360 struct wa_xfer_abort_buffer *b = urb->context;
361 usb_put_urb(&b->urb);
362}
363
364/*
365 * Aborts an ongoing transaction
366 *
367 * Assumes the transfer is referenced and locked and in a submitted
368 * state (mainly that there is an endpoint/rpipe assigned).
369 *
370 * The callback (see above) does nothing but freeing up the data by
371 * putting the URB. Because the URB is allocated at the head of the
372 * struct, the whole space we allocated is kfreed.
373 *
374 * We'll get an 'aborted transaction' xfer result on DTI, that'll
375 * politely ignore because at this point the transaction has been
376 * marked as aborted already.
377 */
378static void __wa_xfer_abort(struct wa_xfer *xfer)
379{
380 int result;
381 struct device *dev = &xfer->wa->usb_iface->dev;
382 struct wa_xfer_abort_buffer *b;
383 struct wa_rpipe *rpipe = xfer->ep->hcpriv;
384
385 b = kmalloc(sizeof(*b), GFP_ATOMIC);
386 if (b == NULL)
387 goto error_kmalloc;
388 b->cmd.bLength = sizeof(b->cmd);
389 b->cmd.bRequestType = WA_XFER_ABORT;
390 b->cmd.wRPipe = rpipe->descr.wRPipeIndex;
391 b->cmd.dwTransferID = wa_xfer_id(xfer);
392
393 usb_init_urb(&b->urb);
394 usb_fill_bulk_urb(&b->urb, xfer->wa->usb_dev,
395 usb_sndbulkpipe(xfer->wa->usb_dev,
396 xfer->wa->dto_epd->bEndpointAddress),
397 &b->cmd, sizeof(b->cmd), __wa_xfer_abort_cb, b);
398 result = usb_submit_urb(&b->urb, GFP_ATOMIC);
399 if (result < 0)
400 goto error_submit;
401 return; /* callback frees! */
402
403
404error_submit:
405 if (printk_ratelimit())
406 dev_err(dev, "xfer %p: Can't submit abort request: %d\n",
407 xfer, result);
408 kfree(b);
409error_kmalloc:
410 return;
411
412}
413
414/*
415 *
416 * @returns < 0 on error, transfer segment request size if ok
417 */
418static ssize_t __wa_xfer_setup_sizes(struct wa_xfer *xfer,
419 enum wa_xfer_type *pxfer_type)
420{
421 ssize_t result;
422 struct device *dev = &xfer->wa->usb_iface->dev;
423 size_t maxpktsize;
424 struct urb *urb = xfer->urb;
425 struct wa_rpipe *rpipe = xfer->ep->hcpriv;
426
427 d_fnstart(3, dev, "(xfer %p [rpipe %p] urb %p)\n",
428 xfer, rpipe, urb);
429 switch (rpipe->descr.bmAttribute & 0x3) {
430 case USB_ENDPOINT_XFER_CONTROL:
431 *pxfer_type = WA_XFER_TYPE_CTL;
432 result = sizeof(struct wa_xfer_ctl);
433 break;
434 case USB_ENDPOINT_XFER_INT:
435 case USB_ENDPOINT_XFER_BULK:
436 *pxfer_type = WA_XFER_TYPE_BI;
437 result = sizeof(struct wa_xfer_bi);
438 break;
439 case USB_ENDPOINT_XFER_ISOC:
440 dev_err(dev, "FIXME: ISOC not implemented\n");
441 result = -ENOSYS;
442 goto error;
443 default:
444 /* never happens */
445 BUG();
446 result = -EINVAL; /* shut gcc up */
447 };
448 xfer->is_inbound = urb->pipe & USB_DIR_IN ? 1 : 0;
449 xfer->is_dma = urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP ? 1 : 0;
450 xfer->seg_size = le16_to_cpu(rpipe->descr.wBlocks)
451 * 1 << (xfer->wa->wa_descr->bRPipeBlockSize - 1);
452 /* Compute the segment size and make sure it is a multiple of
453 * the maxpktsize (WUSB1.0[8.3.3.1])...not really too much of
454 * a check (FIXME) */
455 maxpktsize = le16_to_cpu(rpipe->descr.wMaxPacketSize);
456 if (xfer->seg_size < maxpktsize) {
457 dev_err(dev, "HW BUG? seg_size %zu smaller than maxpktsize "
458 "%zu\n", xfer->seg_size, maxpktsize);
459 result = -EINVAL;
460 goto error;
461 }
462 xfer->seg_size = (xfer->seg_size / maxpktsize) * maxpktsize;
463 xfer->segs = (urb->transfer_buffer_length + xfer->seg_size - 1)
464 / xfer->seg_size;
465 if (xfer->segs >= WA_SEGS_MAX) {
466 dev_err(dev, "BUG? ops, number of segments %d bigger than %d\n",
467 (int)(urb->transfer_buffer_length / xfer->seg_size),
468 WA_SEGS_MAX);
469 result = -EINVAL;
470 goto error;
471 }
472 if (xfer->segs == 0 && *pxfer_type == WA_XFER_TYPE_CTL)
473 xfer->segs = 1;
474error:
475 d_fnend(3, dev, "(xfer %p [rpipe %p] urb %p) = %d\n",
476 xfer, rpipe, urb, (int)result);
477 return result;
478}
479
480/** Fill in the common request header and xfer-type specific data. */
481static void __wa_xfer_setup_hdr0(struct wa_xfer *xfer,
482 struct wa_xfer_hdr *xfer_hdr0,
483 enum wa_xfer_type xfer_type,
484 size_t xfer_hdr_size)
485{
486 struct wa_rpipe *rpipe = xfer->ep->hcpriv;
487
488 xfer_hdr0 = &xfer->seg[0]->xfer_hdr;
489 xfer_hdr0->bLength = xfer_hdr_size;
490 xfer_hdr0->bRequestType = xfer_type;
491 xfer_hdr0->wRPipe = rpipe->descr.wRPipeIndex;
492 xfer_hdr0->dwTransferID = wa_xfer_id(xfer);
493 xfer_hdr0->bTransferSegment = 0;
494 switch (xfer_type) {
495 case WA_XFER_TYPE_CTL: {
496 struct wa_xfer_ctl *xfer_ctl =
497 container_of(xfer_hdr0, struct wa_xfer_ctl, hdr);
498 xfer_ctl->bmAttribute = xfer->is_inbound ? 1 : 0;
499 BUG_ON(xfer->urb->transfer_flags & URB_NO_SETUP_DMA_MAP
500 && xfer->urb->setup_packet == NULL);
501 memcpy(&xfer_ctl->baSetupData, xfer->urb->setup_packet,
502 sizeof(xfer_ctl->baSetupData));
503 break;
504 }
505 case WA_XFER_TYPE_BI:
506 break;
507 case WA_XFER_TYPE_ISO:
508 printk(KERN_ERR "FIXME: ISOC not implemented\n");
509 default:
510 BUG();
511 };
512}
513
514/*
515 * Callback for the OUT data phase of the segment request
516 *
517 * Check wa_seg_cb(); most comments also apply here because this
518 * function does almost the same thing and they work closely
519 * together.
520 *
521 * If the seg request has failed but this DTO phase has suceeded,
522 * wa_seg_cb() has already failed the segment and moved the
523 * status to WA_SEG_ERROR, so this will go through 'case 0' and
524 * effectively do nothing.
525 */
526static void wa_seg_dto_cb(struct urb *urb)
527{
528 struct wa_seg *seg = urb->context;
529 struct wa_xfer *xfer = seg->xfer;
530 struct wahc *wa;
531 struct device *dev;
532 struct wa_rpipe *rpipe;
533 unsigned long flags;
534 unsigned rpipe_ready = 0;
535 u8 done = 0;
536
537 d_fnstart(3, NULL, "(urb %p [%d])\n", urb, urb->status);
538 switch (urb->status) {
539 case 0:
540 spin_lock_irqsave(&xfer->lock, flags);
541 wa = xfer->wa;
542 dev = &wa->usb_iface->dev;
543 d_printf(2, dev, "xfer %p#%u: data out done (%d bytes)\n",
544 xfer, seg->index, urb->actual_length);
545 if (seg->status < WA_SEG_PENDING)
546 seg->status = WA_SEG_PENDING;
547 seg->result = urb->actual_length;
548 spin_unlock_irqrestore(&xfer->lock, flags);
549 break;
550 case -ECONNRESET: /* URB unlinked; no need to do anything */
551 case -ENOENT: /* as it was done by the who unlinked us */
552 break;
553 default: /* Other errors ... */
554 spin_lock_irqsave(&xfer->lock, flags);
555 wa = xfer->wa;
556 dev = &wa->usb_iface->dev;
557 rpipe = xfer->ep->hcpriv;
558 if (printk_ratelimit())
559 dev_err(dev, "xfer %p#%u: data out error %d\n",
560 xfer, seg->index, urb->status);
561 if (edc_inc(&wa->nep_edc, EDC_MAX_ERRORS,
562 EDC_ERROR_TIMEFRAME)){
563 dev_err(dev, "DTO: URB max acceptable errors "
564 "exceeded, resetting device\n");
565 wa_reset_all(wa);
566 }
567 if (seg->status != WA_SEG_ERROR) {
568 seg->status = WA_SEG_ERROR;
569 seg->result = urb->status;
570 xfer->segs_done++;
571 __wa_xfer_abort(xfer);
572 rpipe_ready = rpipe_avail_inc(rpipe);
573 done = __wa_xfer_is_done(xfer);
574 }
575 spin_unlock_irqrestore(&xfer->lock, flags);
576 if (done)
577 wa_xfer_completion(xfer);
578 if (rpipe_ready)
579 wa_xfer_delayed_run(rpipe);
580 }
581 d_fnend(3, NULL, "(urb %p [%d]) = void\n", urb, urb->status);
582}
583
584/*
585 * Callback for the segment request
586 *
587 * If succesful transition state (unless already transitioned or
588 * outbound transfer); otherwise, take a note of the error, mark this
589 * segment done and try completion.
590 *
591 * Note we don't access until we are sure that the transfer hasn't
592 * been cancelled (ECONNRESET, ENOENT), which could mean that
593 * seg->xfer could be already gone.
594 *
595 * We have to check before setting the status to WA_SEG_PENDING
596 * because sometimes the xfer result callback arrives before this
597 * callback (geeeeeeze), so it might happen that we are already in
598 * another state. As well, we don't set it if the transfer is inbound,
599 * as in that case, wa_seg_dto_cb will do it when the OUT data phase
600 * finishes.
601 */
602static void wa_seg_cb(struct urb *urb)
603{
604 struct wa_seg *seg = urb->context;
605 struct wa_xfer *xfer = seg->xfer;
606 struct wahc *wa;
607 struct device *dev;
608 struct wa_rpipe *rpipe;
609 unsigned long flags;
610 unsigned rpipe_ready;
611 u8 done = 0;
612
613 d_fnstart(3, NULL, "(urb %p [%d])\n", urb, urb->status);
614 switch (urb->status) {
615 case 0:
616 spin_lock_irqsave(&xfer->lock, flags);
617 wa = xfer->wa;
618 dev = &wa->usb_iface->dev;
619 d_printf(2, dev, "xfer %p#%u: request done\n",
620 xfer, seg->index);
621 if (xfer->is_inbound && seg->status < WA_SEG_PENDING)
622 seg->status = WA_SEG_PENDING;
623 spin_unlock_irqrestore(&xfer->lock, flags);
624 break;
625 case -ECONNRESET: /* URB unlinked; no need to do anything */
626 case -ENOENT: /* as it was done by the who unlinked us */
627 break;
628 default: /* Other errors ... */
629 spin_lock_irqsave(&xfer->lock, flags);
630 wa = xfer->wa;
631 dev = &wa->usb_iface->dev;
632 rpipe = xfer->ep->hcpriv;
633 if (printk_ratelimit())
634 dev_err(dev, "xfer %p#%u: request error %d\n",
635 xfer, seg->index, urb->status);
636 if (edc_inc(&wa->nep_edc, EDC_MAX_ERRORS,
637 EDC_ERROR_TIMEFRAME)){
638 dev_err(dev, "DTO: URB max acceptable errors "
639 "exceeded, resetting device\n");
640 wa_reset_all(wa);
641 }
642 usb_unlink_urb(seg->dto_urb);
643 seg->status = WA_SEG_ERROR;
644 seg->result = urb->status;
645 xfer->segs_done++;
646 __wa_xfer_abort(xfer);
647 rpipe_ready = rpipe_avail_inc(rpipe);
648 done = __wa_xfer_is_done(xfer);
649 spin_unlock_irqrestore(&xfer->lock, flags);
650 if (done)
651 wa_xfer_completion(xfer);
652 if (rpipe_ready)
653 wa_xfer_delayed_run(rpipe);
654 }
655 d_fnend(3, NULL, "(urb %p [%d]) = void\n", urb, urb->status);
656}
657
658/*
659 * Allocate the segs array and initialize each of them
660 *
661 * The segments are freed by wa_xfer_destroy() when the xfer use count
662 * drops to zero; however, because each segment is given the same life
663 * cycle as the USB URB it contains, it is actually freed by
664 * usb_put_urb() on the contained USB URB (twisted, eh?).
665 */
666static int __wa_xfer_setup_segs(struct wa_xfer *xfer, size_t xfer_hdr_size)
667{
668 int result, cnt;
669 size_t alloc_size = sizeof(*xfer->seg[0])
670 - sizeof(xfer->seg[0]->xfer_hdr) + xfer_hdr_size;
671 struct usb_device *usb_dev = xfer->wa->usb_dev;
672 const struct usb_endpoint_descriptor *dto_epd = xfer->wa->dto_epd;
673 struct wa_seg *seg;
674 size_t buf_itr, buf_size, buf_itr_size;
675
676 result = -ENOMEM;
677 xfer->seg = kzalloc(xfer->segs * sizeof(xfer->seg[0]), GFP_ATOMIC);
678 if (xfer->seg == NULL)
679 goto error_segs_kzalloc;
680 buf_itr = 0;
681 buf_size = xfer->urb->transfer_buffer_length;
682 for (cnt = 0; cnt < xfer->segs; cnt++) {
683 seg = xfer->seg[cnt] = kzalloc(alloc_size, GFP_ATOMIC);
684 if (seg == NULL)
685 goto error_seg_kzalloc;
686 wa_seg_init(seg);
687 seg->xfer = xfer;
688 seg->index = cnt;
689 usb_fill_bulk_urb(&seg->urb, usb_dev,
690 usb_sndbulkpipe(usb_dev,
691 dto_epd->bEndpointAddress),
692 &seg->xfer_hdr, xfer_hdr_size,
693 wa_seg_cb, seg);
694 buf_itr_size = buf_size > xfer->seg_size ?
695 xfer->seg_size : buf_size;
696 if (xfer->is_inbound == 0 && buf_size > 0) {
697 seg->dto_urb = usb_alloc_urb(0, GFP_ATOMIC);
698 if (seg->dto_urb == NULL)
699 goto error_dto_alloc;
700 usb_fill_bulk_urb(
701 seg->dto_urb, usb_dev,
702 usb_sndbulkpipe(usb_dev,
703 dto_epd->bEndpointAddress),
704 NULL, 0, wa_seg_dto_cb, seg);
705 if (xfer->is_dma) {
706 seg->dto_urb->transfer_dma =
707 xfer->urb->transfer_dma + buf_itr;
708 seg->dto_urb->transfer_flags |=
709 URB_NO_TRANSFER_DMA_MAP;
710 } else
711 seg->dto_urb->transfer_buffer =
712 xfer->urb->transfer_buffer + buf_itr;
713 seg->dto_urb->transfer_buffer_length = buf_itr_size;
714 }
715 seg->status = WA_SEG_READY;
716 buf_itr += buf_itr_size;
717 buf_size -= buf_itr_size;
718 }
719 return 0;
720
721error_dto_alloc:
722 kfree(xfer->seg[cnt]);
723 cnt--;
724error_seg_kzalloc:
725 /* use the fact that cnt is left at were it failed */
726 for (; cnt > 0; cnt--) {
727 if (xfer->is_inbound == 0)
728 kfree(xfer->seg[cnt]->dto_urb);
729 kfree(xfer->seg[cnt]);
730 }
731error_segs_kzalloc:
732 return result;
733}
734
735/*
736 * Allocates all the stuff needed to submit a transfer
737 *
738 * Breaks the whole data buffer in a list of segments, each one has a
739 * structure allocated to it and linked in xfer->seg[index]
740 *
741 * FIXME: merge setup_segs() and the last part of this function, no
742 * need to do two for loops when we could run everything in a
743 * single one
744 */
745static int __wa_xfer_setup(struct wa_xfer *xfer, struct urb *urb)
746{
747 int result;
748 struct device *dev = &xfer->wa->usb_iface->dev;
749 enum wa_xfer_type xfer_type = 0; /* shut up GCC */
750 size_t xfer_hdr_size, cnt, transfer_size;
751 struct wa_xfer_hdr *xfer_hdr0, *xfer_hdr;
752
753 d_fnstart(3, dev, "(xfer %p [rpipe %p] urb %p)\n",
754 xfer, xfer->ep->hcpriv, urb);
755
756 result = __wa_xfer_setup_sizes(xfer, &xfer_type);
757 if (result < 0)
758 goto error_setup_sizes;
759 xfer_hdr_size = result;
760 result = __wa_xfer_setup_segs(xfer, xfer_hdr_size);
761 if (result < 0) {
762 dev_err(dev, "xfer %p: Failed to allocate %d segments: %d\n",
763 xfer, xfer->segs, result);
764 goto error_setup_segs;
765 }
766 /* Fill the first header */
767 xfer_hdr0 = &xfer->seg[0]->xfer_hdr;
768 wa_xfer_id_init(xfer);
769 __wa_xfer_setup_hdr0(xfer, xfer_hdr0, xfer_type, xfer_hdr_size);
770
771 /* Fill remainig headers */
772 xfer_hdr = xfer_hdr0;
773 transfer_size = urb->transfer_buffer_length;
774 xfer_hdr0->dwTransferLength = transfer_size > xfer->seg_size ?
775 xfer->seg_size : transfer_size;
776 transfer_size -= xfer->seg_size;
777 for (cnt = 1; cnt < xfer->segs; cnt++) {
778 xfer_hdr = &xfer->seg[cnt]->xfer_hdr;
779 memcpy(xfer_hdr, xfer_hdr0, xfer_hdr_size);
780 xfer_hdr->bTransferSegment = cnt;
781 xfer_hdr->dwTransferLength = transfer_size > xfer->seg_size ?
782 cpu_to_le32(xfer->seg_size)
783 : cpu_to_le32(transfer_size);
784 xfer->seg[cnt]->status = WA_SEG_READY;
785 transfer_size -= xfer->seg_size;
786 }
787 xfer_hdr->bTransferSegment |= 0x80; /* this is the last segment */
788 result = 0;
789error_setup_segs:
790error_setup_sizes:
791 d_fnend(3, dev, "(xfer %p [rpipe %p] urb %p) = %d\n",
792 xfer, xfer->ep->hcpriv, urb, result);
793 return result;
794}
795
796/*
797 *
798 *
799 * rpipe->seg_lock is held!
800 */
801static int __wa_seg_submit(struct wa_rpipe *rpipe, struct wa_xfer *xfer,
802 struct wa_seg *seg)
803{
804 int result;
805 result = usb_submit_urb(&seg->urb, GFP_ATOMIC);
806 if (result < 0) {
807 printk(KERN_ERR "xfer %p#%u: REQ submit failed: %d\n",
808 xfer, seg->index, result);
809 goto error_seg_submit;
810 }
811 if (seg->dto_urb) {
812 result = usb_submit_urb(seg->dto_urb, GFP_ATOMIC);
813 if (result < 0) {
814 printk(KERN_ERR "xfer %p#%u: DTO submit failed: %d\n",
815 xfer, seg->index, result);
816 goto error_dto_submit;
817 }
818 }
819 seg->status = WA_SEG_SUBMITTED;
820 rpipe_avail_dec(rpipe);
821 return 0;
822
823error_dto_submit:
824 usb_unlink_urb(&seg->urb);
825error_seg_submit:
826 seg->status = WA_SEG_ERROR;
827 seg->result = result;
828 return result;
829}
830
831/*
832 * Execute more queued request segments until the maximum concurrent allowed
833 *
834 * The ugly unlock/lock sequence on the error path is needed as the
835 * xfer->lock normally nests the seg_lock and not viceversa.
836 *
837 */
838static void wa_xfer_delayed_run(struct wa_rpipe *rpipe)
839{
840 int result;
841 struct device *dev = &rpipe->wa->usb_iface->dev;
842 struct wa_seg *seg;
843 struct wa_xfer *xfer;
844 unsigned long flags;
845
846 d_fnstart(1, dev, "(rpipe #%d) %d segments available\n",
847 le16_to_cpu(rpipe->descr.wRPipeIndex),
848 atomic_read(&rpipe->segs_available));
849 spin_lock_irqsave(&rpipe->seg_lock, flags);
850 while (atomic_read(&rpipe->segs_available) > 0
851 && !list_empty(&rpipe->seg_list)) {
852 seg = list_entry(rpipe->seg_list.next, struct wa_seg,
853 list_node);
854 list_del(&seg->list_node);
855 xfer = seg->xfer;
856 result = __wa_seg_submit(rpipe, xfer, seg);
857 d_printf(1, dev, "xfer %p#%u submitted from delayed "
858 "[%d segments available] %d\n",
859 xfer, seg->index,
860 atomic_read(&rpipe->segs_available), result);
861 if (unlikely(result < 0)) {
862 spin_unlock_irqrestore(&rpipe->seg_lock, flags);
863 spin_lock_irqsave(&xfer->lock, flags);
864 __wa_xfer_abort(xfer);
865 xfer->segs_done++;
866 spin_unlock_irqrestore(&xfer->lock, flags);
867 spin_lock_irqsave(&rpipe->seg_lock, flags);
868 }
869 }
870 spin_unlock_irqrestore(&rpipe->seg_lock, flags);
871 d_fnend(1, dev, "(rpipe #%d) = void, %d segments available\n",
872 le16_to_cpu(rpipe->descr.wRPipeIndex),
873 atomic_read(&rpipe->segs_available));
874
875}
876
877/*
878 *
879 * xfer->lock is taken
880 *
881 * On failure submitting we just stop submitting and return error;
882 * wa_urb_enqueue_b() will execute the completion path
883 */
884static int __wa_xfer_submit(struct wa_xfer *xfer)
885{
886 int result;
887 struct wahc *wa = xfer->wa;
888 struct device *dev = &wa->usb_iface->dev;
889 unsigned cnt;
890 struct wa_seg *seg;
891 unsigned long flags;
892 struct wa_rpipe *rpipe = xfer->ep->hcpriv;
893 size_t maxrequests = le16_to_cpu(rpipe->descr.wRequests);
894 u8 available;
895 u8 empty;
896
897 d_fnstart(3, dev, "(xfer %p [rpipe %p])\n",
898 xfer, xfer->ep->hcpriv);
899
900 spin_lock_irqsave(&wa->xfer_list_lock, flags);
901 list_add_tail(&xfer->list_node, &wa->xfer_list);
902 spin_unlock_irqrestore(&wa->xfer_list_lock, flags);
903
904 BUG_ON(atomic_read(&rpipe->segs_available) > maxrequests);
905 result = 0;
906 spin_lock_irqsave(&rpipe->seg_lock, flags);
907 for (cnt = 0; cnt < xfer->segs; cnt++) {
908 available = atomic_read(&rpipe->segs_available);
909 empty = list_empty(&rpipe->seg_list);
910 seg = xfer->seg[cnt];
911 d_printf(2, dev, "xfer %p#%u: available %u empty %u (%s)\n",
912 xfer, cnt, available, empty,
913 available == 0 || !empty ? "delayed" : "submitted");
914 if (available == 0 || !empty) {
915 d_printf(1, dev, "xfer %p#%u: delayed\n", xfer, cnt);
916 seg->status = WA_SEG_DELAYED;
917 list_add_tail(&seg->list_node, &rpipe->seg_list);
918 } else {
919 result = __wa_seg_submit(rpipe, xfer, seg);
920 if (result < 0)
921 goto error_seg_submit;
922 }
923 xfer->segs_submitted++;
924 }
925 spin_unlock_irqrestore(&rpipe->seg_lock, flags);
926 d_fnend(3, dev, "(xfer %p [rpipe %p]) = void\n", xfer,
927 xfer->ep->hcpriv);
928 return result;
929
930error_seg_submit:
931 __wa_xfer_abort(xfer);
932 spin_unlock_irqrestore(&rpipe->seg_lock, flags);
933 d_fnend(3, dev, "(xfer %p [rpipe %p]) = void\n", xfer,
934 xfer->ep->hcpriv);
935 return result;
936}
937
938/*
939 * Second part of a URB/transfer enqueuement
940 *
941 * Assumes this comes from wa_urb_enqueue() [maybe through
942 * wa_urb_enqueue_run()]. At this point:
943 *
944 * xfer->wa filled and refcounted
945 * xfer->ep filled with rpipe refcounted if
946 * delayed == 0
947 * xfer->urb filled and refcounted (this is the case when called
948 * from wa_urb_enqueue() as we come from usb_submit_urb()
949 * and when called by wa_urb_enqueue_run(), as we took an
950 * extra ref dropped by _run() after we return).
951 * xfer->gfp filled
952 *
953 * If we fail at __wa_xfer_submit(), then we just check if we are done
954 * and if so, we run the completion procedure. However, if we are not
955 * yet done, we do nothing and wait for the completion handlers from
956 * the submitted URBs or from the xfer-result path to kick in. If xfer
957 * result never kicks in, the xfer will timeout from the USB code and
958 * dequeue() will be called.
959 */
960static void wa_urb_enqueue_b(struct wa_xfer *xfer)
961{
962 int result;
963 unsigned long flags;
964 struct urb *urb = xfer->urb;
965 struct wahc *wa = xfer->wa;
966 struct wusbhc *wusbhc = wa->wusb;
967 struct device *dev = &wa->usb_iface->dev;
968 struct wusb_dev *wusb_dev;
969 unsigned done;
970
971 d_fnstart(3, dev, "(wa %p urb %p)\n", wa, urb);
972 result = rpipe_get_by_ep(wa, xfer->ep, urb, xfer->gfp);
973 if (result < 0)
974 goto error_rpipe_get;
975 result = -ENODEV;
976 /* FIXME: segmentation broken -- kills DWA */
977 mutex_lock(&wusbhc->mutex); /* get a WUSB dev */
978 if (urb->dev == NULL)
979 goto error_dev_gone;
980 wusb_dev = __wusb_dev_get_by_usb_dev(wusbhc, urb->dev);
981 if (wusb_dev == NULL) {
982 mutex_unlock(&wusbhc->mutex);
983 goto error_dev_gone;
984 }
985 mutex_unlock(&wusbhc->mutex);
986
987 spin_lock_irqsave(&xfer->lock, flags);
988 xfer->wusb_dev = wusb_dev;
989 result = urb->status;
990 if (urb->status != -EINPROGRESS)
991 goto error_dequeued;
992
993 result = __wa_xfer_setup(xfer, urb);
994 if (result < 0)
995 goto error_xfer_setup;
996 result = __wa_xfer_submit(xfer);
997 if (result < 0)
998 goto error_xfer_submit;
999 spin_unlock_irqrestore(&xfer->lock, flags);
1000 d_fnend(3, dev, "(wa %p urb %p) = void\n", wa, urb);
1001 return;
1002
1003 /* this is basically wa_xfer_completion() broken up wa_xfer_giveback()
1004 * does a wa_xfer_put() that will call wa_xfer_destroy() and clean
1005 * upundo setup().
1006 */
1007error_xfer_setup:
1008error_dequeued:
1009 spin_unlock_irqrestore(&xfer->lock, flags);
1010 /* FIXME: segmentation broken, kills DWA */
1011 if (wusb_dev)
1012 wusb_dev_put(wusb_dev);
1013error_dev_gone:
1014 rpipe_put(xfer->ep->hcpriv);
1015error_rpipe_get:
1016 xfer->result = result;
1017 wa_xfer_giveback(xfer);
1018 d_fnend(3, dev, "(wa %p urb %p) = (void) %d\n", wa, urb, result);
1019 return;
1020
1021error_xfer_submit:
1022 done = __wa_xfer_is_done(xfer);
1023 xfer->result = result;
1024 spin_unlock_irqrestore(&xfer->lock, flags);
1025 if (done)
1026 wa_xfer_completion(xfer);
1027 d_fnend(3, dev, "(wa %p urb %p) = (void) %d\n", wa, urb, result);
1028 return;
1029}
1030
1031/*
1032 * Execute the delayed transfers in the Wire Adapter @wa
1033 *
1034 * We need to be careful here, as dequeue() could be called in the
1035 * middle. That's why we do the whole thing under the
1036 * wa->xfer_list_lock. If dequeue() jumps in, it first locks urb->lock
1037 * and then checks the list -- so as we would be acquiring in inverse
1038 * order, we just drop the lock once we have the xfer and reacquire it
1039 * later.
1040 */
1041void wa_urb_enqueue_run(struct work_struct *ws)
1042{
1043 struct wahc *wa = container_of(ws, struct wahc, xfer_work);
1044 struct device *dev = &wa->usb_iface->dev;
1045 struct wa_xfer *xfer, *next;
1046 struct urb *urb;
1047
1048 d_fnstart(3, dev, "(wa %p)\n", wa);
1049 spin_lock_irq(&wa->xfer_list_lock);
1050 list_for_each_entry_safe(xfer, next, &wa->xfer_delayed_list,
1051 list_node) {
1052 list_del_init(&xfer->list_node);
1053 spin_unlock_irq(&wa->xfer_list_lock);
1054
1055 urb = xfer->urb;
1056 wa_urb_enqueue_b(xfer);
1057 usb_put_urb(urb); /* taken when queuing */
1058
1059 spin_lock_irq(&wa->xfer_list_lock);
1060 }
1061 spin_unlock_irq(&wa->xfer_list_lock);
1062 d_fnend(3, dev, "(wa %p) = void\n", wa);
1063}
1064EXPORT_SYMBOL_GPL(wa_urb_enqueue_run);
1065
1066/*
1067 * Submit a transfer to the Wire Adapter in a delayed way
1068 *
1069 * The process of enqueuing involves possible sleeps() [see
1070 * enqueue_b(), for the rpipe_get() and the mutex_lock()]. If we are
1071 * in an atomic section, we defer the enqueue_b() call--else we call direct.
1072 *
1073 * @urb: We own a reference to it done by the HCI Linux USB stack that
1074 * will be given up by calling usb_hcd_giveback_urb() or by
1075 * returning error from this function -> ergo we don't have to
1076 * refcount it.
1077 */
1078int wa_urb_enqueue(struct wahc *wa, struct usb_host_endpoint *ep,
1079 struct urb *urb, gfp_t gfp)
1080{
1081 int result;
1082 struct device *dev = &wa->usb_iface->dev;
1083 struct wa_xfer *xfer;
1084 unsigned long my_flags;
1085 unsigned cant_sleep = irqs_disabled() | in_atomic();
1086
1087 d_fnstart(3, dev, "(wa %p ep %p urb %p [%d] gfp 0x%x)\n",
1088 wa, ep, urb, urb->transfer_buffer_length, gfp);
1089
1090 if (urb->transfer_buffer == NULL
1091 && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)
1092 && urb->transfer_buffer_length != 0) {
1093 dev_err(dev, "BUG? urb %p: NULL xfer buffer & NODMA\n", urb);
1094 dump_stack();
1095 }
1096
1097 result = -ENOMEM;
1098 xfer = kzalloc(sizeof(*xfer), gfp);
1099 if (xfer == NULL)
1100 goto error_kmalloc;
1101
1102 result = -ENOENT;
1103 if (urb->status != -EINPROGRESS) /* cancelled */
1104 goto error_dequeued; /* before starting? */
1105 wa_xfer_init(xfer);
1106 xfer->wa = wa_get(wa);
1107 xfer->urb = urb;
1108 xfer->gfp = gfp;
1109 xfer->ep = ep;
1110 urb->hcpriv = xfer;
1111 d_printf(2, dev, "xfer %p urb %p pipe 0x%02x [%d bytes] %s %s %s\n",
1112 xfer, urb, urb->pipe, urb->transfer_buffer_length,
1113 urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP ? "dma" : "nodma",
1114 urb->pipe & USB_DIR_IN ? "inbound" : "outbound",
1115 cant_sleep ? "deferred" : "inline");
1116 if (cant_sleep) {
1117 usb_get_urb(urb);
1118 spin_lock_irqsave(&wa->xfer_list_lock, my_flags);
1119 list_add_tail(&xfer->list_node, &wa->xfer_delayed_list);
1120 spin_unlock_irqrestore(&wa->xfer_list_lock, my_flags);
1121 queue_work(wusbd, &wa->xfer_work);
1122 } else {
1123 wa_urb_enqueue_b(xfer);
1124 }
1125 d_fnend(3, dev, "(wa %p ep %p urb %p [%d] gfp 0x%x) = 0\n",
1126 wa, ep, urb, urb->transfer_buffer_length, gfp);
1127 return 0;
1128
1129error_dequeued:
1130 kfree(xfer);
1131error_kmalloc:
1132 d_fnend(3, dev, "(wa %p ep %p urb %p [%d] gfp 0x%x) = %d\n",
1133 wa, ep, urb, urb->transfer_buffer_length, gfp, result);
1134 return result;
1135}
1136EXPORT_SYMBOL_GPL(wa_urb_enqueue);
1137
1138/*
1139 * Dequeue a URB and make sure uwb_hcd_giveback_urb() [completion
1140 * handler] is called.
1141 *
1142 * Until a transfer goes successfully through wa_urb_enqueue() it
1143 * needs to be dequeued with completion calling; when stuck in delayed
1144 * or before wa_xfer_setup() is called, we need to do completion.
1145 *
1146 * not setup If there is no hcpriv yet, that means that that enqueue
1147 * still had no time to set the xfer up. Because
1148 * urb->status should be other than -EINPROGRESS,
1149 * enqueue() will catch that and bail out.
1150 *
1151 * If the transfer has gone through setup, we just need to clean it
1152 * up. If it has gone through submit(), we have to abort it [with an
1153 * asynch request] and then make sure we cancel each segment.
1154 *
1155 */
1156int wa_urb_dequeue(struct wahc *wa, struct urb *urb)
1157{
1158 struct device *dev = &wa->usb_iface->dev;
1159 unsigned long flags, flags2;
1160 struct wa_xfer *xfer;
1161 struct wa_seg *seg;
1162 struct wa_rpipe *rpipe;
1163 unsigned cnt;
1164 unsigned rpipe_ready = 0;
1165
1166 d_fnstart(3, dev, "(wa %p, urb %p)\n", wa, urb);
1167
1168 d_printf(1, dev, "xfer %p urb %p: aborting\n", urb->hcpriv, urb);
1169 xfer = urb->hcpriv;
1170 if (xfer == NULL) {
1171 /* NOthing setup yet enqueue will see urb->status !=
1172 * -EINPROGRESS (by hcd layer) and bail out with
1173 * error, no need to do completion
1174 */
1175 BUG_ON(urb->status == -EINPROGRESS);
1176 goto out;
1177 }
1178 spin_lock_irqsave(&xfer->lock, flags);
1179 rpipe = xfer->ep->hcpriv;
1180 /* Check the delayed list -> if there, release and complete */
1181 spin_lock_irqsave(&wa->xfer_list_lock, flags2);
1182 if (!list_empty(&xfer->list_node) && xfer->seg == NULL)
1183 goto dequeue_delayed;
1184 spin_unlock_irqrestore(&wa->xfer_list_lock, flags2);
1185 if (xfer->seg == NULL) /* still hasn't reached */
1186 goto out_unlock; /* setup(), enqueue_b() completes */
1187 /* Ok, the xfer is in flight already, it's been setup and submitted.*/
1188 __wa_xfer_abort(xfer);
1189 for (cnt = 0; cnt < xfer->segs; cnt++) {
1190 seg = xfer->seg[cnt];
1191 switch (seg->status) {
1192 case WA_SEG_NOTREADY:
1193 case WA_SEG_READY:
1194 printk(KERN_ERR "xfer %p#%u: dequeue bad state %u\n",
1195 xfer, cnt, seg->status);
1196 WARN_ON(1);
1197 break;
1198 case WA_SEG_DELAYED:
1199 seg->status = WA_SEG_ABORTED;
1200 spin_lock_irqsave(&rpipe->seg_lock, flags2);
1201 list_del(&seg->list_node);
1202 xfer->segs_done++;
1203 rpipe_ready = rpipe_avail_inc(rpipe);
1204 spin_unlock_irqrestore(&rpipe->seg_lock, flags2);
1205 break;
1206 case WA_SEG_SUBMITTED:
1207 seg->status = WA_SEG_ABORTED;
1208 usb_unlink_urb(&seg->urb);
1209 if (xfer->is_inbound == 0)
1210 usb_unlink_urb(seg->dto_urb);
1211 xfer->segs_done++;
1212 rpipe_ready = rpipe_avail_inc(rpipe);
1213 break;
1214 case WA_SEG_PENDING:
1215 seg->status = WA_SEG_ABORTED;
1216 xfer->segs_done++;
1217 rpipe_ready = rpipe_avail_inc(rpipe);
1218 break;
1219 case WA_SEG_DTI_PENDING:
1220 usb_unlink_urb(wa->dti_urb);
1221 seg->status = WA_SEG_ABORTED;
1222 xfer->segs_done++;
1223 rpipe_ready = rpipe_avail_inc(rpipe);
1224 break;
1225 case WA_SEG_DONE:
1226 case WA_SEG_ERROR:
1227 case WA_SEG_ABORTED:
1228 break;
1229 }
1230 }
1231 xfer->result = urb->status; /* -ENOENT or -ECONNRESET */
1232 __wa_xfer_is_done(xfer);
1233 spin_unlock_irqrestore(&xfer->lock, flags);
1234 wa_xfer_completion(xfer);
1235 if (rpipe_ready)
1236 wa_xfer_delayed_run(rpipe);
1237 d_fnend(3, dev, "(wa %p, urb %p) = 0\n", wa, urb);
1238 return 0;
1239
1240out_unlock:
1241 spin_unlock_irqrestore(&xfer->lock, flags);
1242out:
1243 d_fnend(3, dev, "(wa %p, urb %p) = 0\n", wa, urb);
1244 return 0;
1245
1246dequeue_delayed:
1247 list_del_init(&xfer->list_node);
1248 spin_unlock_irqrestore(&wa->xfer_list_lock, flags2);
1249 xfer->result = urb->status;
1250 spin_unlock_irqrestore(&xfer->lock, flags);
1251 wa_xfer_giveback(xfer);
1252 usb_put_urb(urb); /* we got a ref in enqueue() */
1253 d_fnend(3, dev, "(wa %p, urb %p) = 0\n", wa, urb);
1254 return 0;
1255}
1256EXPORT_SYMBOL_GPL(wa_urb_dequeue);
1257
1258/*
1259 * Translation from WA status codes (WUSB1.0 Table 8.15) to errno
1260 * codes
1261 *
1262 * Positive errno values are internal inconsistencies and should be
1263 * flagged louder. Negative are to be passed up to the user in the
1264 * normal way.
1265 *
1266 * @status: USB WA status code -- high two bits are stripped.
1267 */
1268static int wa_xfer_status_to_errno(u8 status)
1269{
1270 int errno;
1271 u8 real_status = status;
1272 static int xlat[] = {
1273 [WA_XFER_STATUS_SUCCESS] = 0,
1274 [WA_XFER_STATUS_HALTED] = -EPIPE,
1275 [WA_XFER_STATUS_DATA_BUFFER_ERROR] = -ENOBUFS,
1276 [WA_XFER_STATUS_BABBLE] = -EOVERFLOW,
1277 [WA_XFER_RESERVED] = EINVAL,
1278 [WA_XFER_STATUS_NOT_FOUND] = 0,
1279 [WA_XFER_STATUS_INSUFFICIENT_RESOURCE] = -ENOMEM,
1280 [WA_XFER_STATUS_TRANSACTION_ERROR] = -EILSEQ,
1281 [WA_XFER_STATUS_ABORTED] = -EINTR,
1282 [WA_XFER_STATUS_RPIPE_NOT_READY] = EINVAL,
1283 [WA_XFER_INVALID_FORMAT] = EINVAL,
1284 [WA_XFER_UNEXPECTED_SEGMENT_NUMBER] = EINVAL,
1285 [WA_XFER_STATUS_RPIPE_TYPE_MISMATCH] = EINVAL,
1286 };
1287 status &= 0x3f;
1288
1289 if (status == 0)
1290 return 0;
1291 if (status >= ARRAY_SIZE(xlat)) {
1292 if (printk_ratelimit())
1293 printk(KERN_ERR "%s(): BUG? "
1294 "Unknown WA transfer status 0x%02x\n",
1295 __func__, real_status);
1296 return -EINVAL;
1297 }
1298 errno = xlat[status];
1299 if (unlikely(errno > 0)) {
1300 if (printk_ratelimit())
1301 printk(KERN_ERR "%s(): BUG? "
1302 "Inconsistent WA status: 0x%02x\n",
1303 __func__, real_status);
1304 errno = -errno;
1305 }
1306 return errno;
1307}
1308
1309/*
1310 * Process a xfer result completion message
1311 *
1312 * inbound transfers: need to schedule a DTI read
1313 *
1314 * FIXME: this functio needs to be broken up in parts
1315 */
1316static void wa_xfer_result_chew(struct wahc *wa, struct wa_xfer *xfer)
1317{
1318 int result;
1319 struct device *dev = &wa->usb_iface->dev;
1320 unsigned long flags;
1321 u8 seg_idx;
1322 struct wa_seg *seg;
1323 struct wa_rpipe *rpipe;
1324 struct wa_xfer_result *xfer_result = wa->xfer_result;
1325 u8 done = 0;
1326 u8 usb_status;
1327 unsigned rpipe_ready = 0;
1328
1329 d_fnstart(3, dev, "(wa %p xfer %p)\n", wa, xfer);
1330 spin_lock_irqsave(&xfer->lock, flags);
1331 seg_idx = xfer_result->bTransferSegment & 0x7f;
1332 if (unlikely(seg_idx >= xfer->segs))
1333 goto error_bad_seg;
1334 seg = xfer->seg[seg_idx];
1335 rpipe = xfer->ep->hcpriv;
1336 usb_status = xfer_result->bTransferStatus;
1337 d_printf(2, dev, "xfer %p#%u: bTransferStatus 0x%02x (seg %u)\n",
1338 xfer, seg_idx, usb_status, seg->status);
1339 if (seg->status == WA_SEG_ABORTED
1340 || seg->status == WA_SEG_ERROR) /* already handled */
1341 goto segment_aborted;
1342 if (seg->status == WA_SEG_SUBMITTED) /* ops, got here */
1343 seg->status = WA_SEG_PENDING; /* before wa_seg{_dto}_cb() */
1344 if (seg->status != WA_SEG_PENDING) {
1345 if (printk_ratelimit())
1346 dev_err(dev, "xfer %p#%u: Bad segment state %u\n",
1347 xfer, seg_idx, seg->status);
1348 seg->status = WA_SEG_PENDING; /* workaround/"fix" it */
1349 }
1350 if (usb_status & 0x80) {
1351 seg->result = wa_xfer_status_to_errno(usb_status);
1352 dev_err(dev, "DTI: xfer %p#%u failed (0x%02x)\n",
1353 xfer, seg->index, usb_status);
1354 goto error_complete;
1355 }
1356 /* FIXME: we ignore warnings, tally them for stats */
1357 if (usb_status & 0x40) /* Warning?... */
1358 usb_status = 0; /* ... pass */
1359 if (xfer->is_inbound) { /* IN data phase: read to buffer */
1360 seg->status = WA_SEG_DTI_PENDING;
1361 BUG_ON(wa->buf_in_urb->status == -EINPROGRESS);
1362 if (xfer->is_dma) {
1363 wa->buf_in_urb->transfer_dma =
1364 xfer->urb->transfer_dma
1365 + seg_idx * xfer->seg_size;
1366 wa->buf_in_urb->transfer_flags
1367 |= URB_NO_TRANSFER_DMA_MAP;
1368 } else {
1369 wa->buf_in_urb->transfer_buffer =
1370 xfer->urb->transfer_buffer
1371 + seg_idx * xfer->seg_size;
1372 wa->buf_in_urb->transfer_flags
1373 &= ~URB_NO_TRANSFER_DMA_MAP;
1374 }
1375 wa->buf_in_urb->transfer_buffer_length =
1376 le32_to_cpu(xfer_result->dwTransferLength);
1377 wa->buf_in_urb->context = seg;
1378 result = usb_submit_urb(wa->buf_in_urb, GFP_ATOMIC);
1379 if (result < 0)
1380 goto error_submit_buf_in;
1381 } else {
1382 /* OUT data phase, complete it -- */
1383 seg->status = WA_SEG_DONE;
1384 seg->result = le32_to_cpu(xfer_result->dwTransferLength);
1385 xfer->segs_done++;
1386 rpipe_ready = rpipe_avail_inc(rpipe);
1387 done = __wa_xfer_is_done(xfer);
1388 }
1389 spin_unlock_irqrestore(&xfer->lock, flags);
1390 if (done)
1391 wa_xfer_completion(xfer);
1392 if (rpipe_ready)
1393 wa_xfer_delayed_run(rpipe);
1394 d_fnend(3, dev, "(wa %p xfer %p) = void\n", wa, xfer);
1395 return;
1396
1397
1398error_submit_buf_in:
1399 if (edc_inc(&wa->dti_edc, EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) {
1400 dev_err(dev, "DTI: URB max acceptable errors "
1401 "exceeded, resetting device\n");
1402 wa_reset_all(wa);
1403 }
1404 if (printk_ratelimit())
1405 dev_err(dev, "xfer %p#%u: can't submit DTI data phase: %d\n",
1406 xfer, seg_idx, result);
1407 seg->result = result;
1408error_complete:
1409 seg->status = WA_SEG_ERROR;
1410 xfer->segs_done++;
1411 rpipe_ready = rpipe_avail_inc(rpipe);
1412 __wa_xfer_abort(xfer);
1413 done = __wa_xfer_is_done(xfer);
1414 spin_unlock_irqrestore(&xfer->lock, flags);
1415 if (done)
1416 wa_xfer_completion(xfer);
1417 if (rpipe_ready)
1418 wa_xfer_delayed_run(rpipe);
1419 d_fnend(3, dev, "(wa %p xfer %p) = void [segment/DTI-submit error]\n",
1420 wa, xfer);
1421 return;
1422
1423
1424error_bad_seg:
1425 spin_unlock_irqrestore(&xfer->lock, flags);
1426 wa_urb_dequeue(wa, xfer->urb);
1427 if (printk_ratelimit())
1428 dev_err(dev, "xfer %p#%u: bad segment\n", xfer, seg_idx);
1429 if (edc_inc(&wa->dti_edc, EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) {
1430 dev_err(dev, "DTI: URB max acceptable errors "
1431 "exceeded, resetting device\n");
1432 wa_reset_all(wa);
1433 }
1434 d_fnend(3, dev, "(wa %p xfer %p) = void [bad seg]\n", wa, xfer);
1435 return;
1436
1437
1438segment_aborted:
1439 /* nothing to do, as the aborter did the completion */
1440 spin_unlock_irqrestore(&xfer->lock, flags);
1441 d_fnend(3, dev, "(wa %p xfer %p) = void [segment aborted]\n",
1442 wa, xfer);
1443 return;
1444
1445}
1446
1447/*
1448 * Callback for the IN data phase
1449 *
1450 * If succesful transition state; otherwise, take a note of the
1451 * error, mark this segment done and try completion.
1452 *
1453 * Note we don't access until we are sure that the transfer hasn't
1454 * been cancelled (ECONNRESET, ENOENT), which could mean that
1455 * seg->xfer could be already gone.
1456 */
1457static void wa_buf_in_cb(struct urb *urb)
1458{
1459 struct wa_seg *seg = urb->context;
1460 struct wa_xfer *xfer = seg->xfer;
1461 struct wahc *wa;
1462 struct device *dev;
1463 struct wa_rpipe *rpipe;
1464 unsigned rpipe_ready;
1465 unsigned long flags;
1466 u8 done = 0;
1467
1468 d_fnstart(3, NULL, "(urb %p [%d])\n", urb, urb->status);
1469 switch (urb->status) {
1470 case 0:
1471 spin_lock_irqsave(&xfer->lock, flags);
1472 wa = xfer->wa;
1473 dev = &wa->usb_iface->dev;
1474 rpipe = xfer->ep->hcpriv;
1475 d_printf(2, dev, "xfer %p#%u: data in done (%zu bytes)\n",
1476 xfer, seg->index, (size_t)urb->actual_length);
1477 seg->status = WA_SEG_DONE;
1478 seg->result = urb->actual_length;
1479 xfer->segs_done++;
1480 rpipe_ready = rpipe_avail_inc(rpipe);
1481 done = __wa_xfer_is_done(xfer);
1482 spin_unlock_irqrestore(&xfer->lock, flags);
1483 if (done)
1484 wa_xfer_completion(xfer);
1485 if (rpipe_ready)
1486 wa_xfer_delayed_run(rpipe);
1487 break;
1488 case -ECONNRESET: /* URB unlinked; no need to do anything */
1489 case -ENOENT: /* as it was done by the who unlinked us */
1490 break;
1491 default: /* Other errors ... */
1492 spin_lock_irqsave(&xfer->lock, flags);
1493 wa = xfer->wa;
1494 dev = &wa->usb_iface->dev;
1495 rpipe = xfer->ep->hcpriv;
1496 if (printk_ratelimit())
1497 dev_err(dev, "xfer %p#%u: data in error %d\n",
1498 xfer, seg->index, urb->status);
1499 if (edc_inc(&wa->nep_edc, EDC_MAX_ERRORS,
1500 EDC_ERROR_TIMEFRAME)){
1501 dev_err(dev, "DTO: URB max acceptable errors "
1502 "exceeded, resetting device\n");
1503 wa_reset_all(wa);
1504 }
1505 seg->status = WA_SEG_ERROR;
1506 seg->result = urb->status;
1507 xfer->segs_done++;
1508 rpipe_ready = rpipe_avail_inc(rpipe);
1509 __wa_xfer_abort(xfer);
1510 done = __wa_xfer_is_done(xfer);
1511 spin_unlock_irqrestore(&xfer->lock, flags);
1512 if (done)
1513 wa_xfer_completion(xfer);
1514 if (rpipe_ready)
1515 wa_xfer_delayed_run(rpipe);
1516 }
1517 d_fnend(3, NULL, "(urb %p [%d]) = void\n", urb, urb->status);
1518}
1519
1520/*
1521 * Handle an incoming transfer result buffer
1522 *
1523 * Given a transfer result buffer, it completes the transfer (possibly
1524 * scheduling and buffer in read) and then resubmits the DTI URB for a
1525 * new transfer result read.
1526 *
1527 *
1528 * The xfer_result DTI URB state machine
1529 *
1530 * States: OFF | RXR (Read-Xfer-Result) | RBI (Read-Buffer-In)
1531 *
1532 * We start in OFF mode, the first xfer_result notification [through
1533 * wa_handle_notif_xfer()] moves us to RXR by posting the DTI-URB to
1534 * read.
1535 *
1536 * We receive a buffer -- if it is not a xfer_result, we complain and
1537 * repost the DTI-URB. If it is a xfer_result then do the xfer seg
1538 * request accounting. If it is an IN segment, we move to RBI and post
1539 * a BUF-IN-URB to the right buffer. The BUF-IN-URB callback will
1540 * repost the DTI-URB and move to RXR state. if there was no IN
1541 * segment, it will repost the DTI-URB.
1542 *
1543 * We go back to OFF when we detect a ENOENT or ESHUTDOWN (or too many
1544 * errors) in the URBs.
1545 */
1546static void wa_xfer_result_cb(struct urb *urb)
1547{
1548 int result;
1549 struct wahc *wa = urb->context;
1550 struct device *dev = &wa->usb_iface->dev;
1551 struct wa_xfer_result *xfer_result;
1552 u32 xfer_id;
1553 struct wa_xfer *xfer;
1554 u8 usb_status;
1555
1556 d_fnstart(3, dev, "(%p)\n", wa);
1557 BUG_ON(wa->dti_urb != urb);
1558 switch (wa->dti_urb->status) {
1559 case 0:
1560 /* We have a xfer result buffer; check it */
1561 d_printf(2, dev, "DTI: xfer result %d bytes at %p\n",
1562 urb->actual_length, urb->transfer_buffer);
1563 d_dump(3, dev, urb->transfer_buffer, urb->actual_length);
1564 if (wa->dti_urb->actual_length != sizeof(*xfer_result)) {
1565 dev_err(dev, "DTI Error: xfer result--bad size "
1566 "xfer result (%d bytes vs %zu needed)\n",
1567 urb->actual_length, sizeof(*xfer_result));
1568 break;
1569 }
1570 xfer_result = wa->xfer_result;
1571 if (xfer_result->hdr.bLength != sizeof(*xfer_result)) {
1572 dev_err(dev, "DTI Error: xfer result--"
1573 "bad header length %u\n",
1574 xfer_result->hdr.bLength);
1575 break;
1576 }
1577 if (xfer_result->hdr.bNotifyType != WA_XFER_RESULT) {
1578 dev_err(dev, "DTI Error: xfer result--"
1579 "bad header type 0x%02x\n",
1580 xfer_result->hdr.bNotifyType);
1581 break;
1582 }
1583 usb_status = xfer_result->bTransferStatus & 0x3f;
1584 if (usb_status == WA_XFER_STATUS_ABORTED
1585 || usb_status == WA_XFER_STATUS_NOT_FOUND)
1586 /* taken care of already */
1587 break;
1588 xfer_id = xfer_result->dwTransferID;
1589 xfer = wa_xfer_get_by_id(wa, xfer_id);
1590 if (xfer == NULL) {
1591 /* FIXME: transaction might have been cancelled */
1592 dev_err(dev, "DTI Error: xfer result--"
1593 "unknown xfer 0x%08x (status 0x%02x)\n",
1594 xfer_id, usb_status);
1595 break;
1596 }
1597 wa_xfer_result_chew(wa, xfer);
1598 wa_xfer_put(xfer);
1599 break;
1600 case -ENOENT: /* (we killed the URB)...so, no broadcast */
1601 case -ESHUTDOWN: /* going away! */
1602 dev_dbg(dev, "DTI: going down! %d\n", urb->status);
1603 goto out;
1604 default:
1605 /* Unknown error */
1606 if (edc_inc(&wa->dti_edc, EDC_MAX_ERRORS,
1607 EDC_ERROR_TIMEFRAME)) {
1608 dev_err(dev, "DTI: URB max acceptable errors "
1609 "exceeded, resetting device\n");
1610 wa_reset_all(wa);
1611 goto out;
1612 }
1613 if (printk_ratelimit())
1614 dev_err(dev, "DTI: URB error %d\n", urb->status);
1615 break;
1616 }
1617 /* Resubmit the DTI URB */
1618 result = usb_submit_urb(wa->dti_urb, GFP_ATOMIC);
1619 if (result < 0) {
1620 dev_err(dev, "DTI Error: Could not submit DTI URB (%d), "
1621 "resetting\n", result);
1622 wa_reset_all(wa);
1623 }
1624out:
1625 d_fnend(3, dev, "(%p) = void\n", wa);
1626 return;
1627}
1628
1629/*
1630 * Transfer complete notification
1631 *
1632 * Called from the notif.c code. We get a notification on EP2 saying
1633 * that some endpoint has some transfer result data available. We are
1634 * about to read it.
1635 *
1636 * To speed up things, we always have a URB reading the DTI URB; we
1637 * don't really set it up and start it until the first xfer complete
1638 * notification arrives, which is what we do here.
1639 *
1640 * Follow up in wa_xfer_result_cb(), as that's where the whole state
1641 * machine starts.
1642 *
1643 * So here we just initialize the DTI URB for reading transfer result
1644 * notifications and also the buffer-in URB, for reading buffers. Then
1645 * we just submit the DTI URB.
1646 *
1647 * @wa shall be referenced
1648 */
1649void wa_handle_notif_xfer(struct wahc *wa, struct wa_notif_hdr *notif_hdr)
1650{
1651 int result;
1652 struct device *dev = &wa->usb_iface->dev;
1653 struct wa_notif_xfer *notif_xfer;
1654 const struct usb_endpoint_descriptor *dti_epd = wa->dti_epd;
1655
1656 d_fnstart(4, dev, "(%p, %p)\n", wa, notif_hdr);
1657 notif_xfer = container_of(notif_hdr, struct wa_notif_xfer, hdr);
1658 BUG_ON(notif_hdr->bNotifyType != WA_NOTIF_TRANSFER);
1659
1660 if ((0x80 | notif_xfer->bEndpoint) != dti_epd->bEndpointAddress) {
1661 /* FIXME: hardcoded limitation, adapt */
1662 dev_err(dev, "BUG: DTI ep is %u, not %u (hack me)\n",
1663 notif_xfer->bEndpoint, dti_epd->bEndpointAddress);
1664 goto error;
1665 }
1666 if (wa->dti_urb != NULL) /* DTI URB already started */
1667 goto out;
1668
1669 wa->dti_urb = usb_alloc_urb(0, GFP_KERNEL);
1670 if (wa->dti_urb == NULL) {
1671 dev_err(dev, "Can't allocate DTI URB\n");
1672 goto error_dti_urb_alloc;
1673 }
1674 usb_fill_bulk_urb(
1675 wa->dti_urb, wa->usb_dev,
1676 usb_rcvbulkpipe(wa->usb_dev, 0x80 | notif_xfer->bEndpoint),
1677 wa->xfer_result, wa->xfer_result_size,
1678 wa_xfer_result_cb, wa);
1679
1680 wa->buf_in_urb = usb_alloc_urb(0, GFP_KERNEL);
1681 if (wa->buf_in_urb == NULL) {
1682 dev_err(dev, "Can't allocate BUF-IN URB\n");
1683 goto error_buf_in_urb_alloc;
1684 }
1685 usb_fill_bulk_urb(
1686 wa->buf_in_urb, wa->usb_dev,
1687 usb_rcvbulkpipe(wa->usb_dev, 0x80 | notif_xfer->bEndpoint),
1688 NULL, 0, wa_buf_in_cb, wa);
1689 result = usb_submit_urb(wa->dti_urb, GFP_KERNEL);
1690 if (result < 0) {
1691 dev_err(dev, "DTI Error: Could not submit DTI URB (%d), "
1692 "resetting\n", result);
1693 goto error_dti_urb_submit;
1694 }
1695out:
1696 d_fnend(4, dev, "(%p, %p) = void\n", wa, notif_hdr);
1697 return;
1698
1699error_dti_urb_submit:
1700 usb_put_urb(wa->buf_in_urb);
1701error_buf_in_urb_alloc:
1702 usb_put_urb(wa->dti_urb);
1703 wa->dti_urb = NULL;
1704error_dti_urb_alloc:
1705error:
1706 wa_reset_all(wa);
1707 d_fnend(4, dev, "(%p, %p) = void\n", wa, notif_hdr);
1708 return;
1709}
diff --git a/drivers/usb/wusbcore/wusbhc.c b/drivers/usb/wusbcore/wusbhc.c
new file mode 100644
index 000000000000..07c63a31c799
--- /dev/null
+++ b/drivers/usb/wusbcore/wusbhc.c
@@ -0,0 +1,418 @@
1/*
2 * Wireless USB Host Controller
3 * sysfs glue, wusbcore module support and life cycle management
4 *
5 *
6 * Copyright (C) 2005-2006 Intel Corporation
7 * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License version
11 * 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301, USA.
22 *
23 *
24 * Creation/destruction of wusbhc is split in two parts; that that
25 * doesn't require the HCD to be added (wusbhc_{create,destroy}) and
26 * the one that requires (phase B, wusbhc_b_{create,destroy}).
27 *
28 * This is so because usb_add_hcd() will start the HC, and thus, all
29 * the HC specific stuff has to be already initialiazed (like sysfs
30 * thingies).
31 */
32#include <linux/device.h>
33#include <linux/module.h>
34#include "wusbhc.h"
35
36/**
37 * Extract the wusbhc that corresponds to a USB Host Controller class device
38 *
39 * WARNING! Apply only if @dev is that of a
40 * wusbhc.usb_hcd.self->class_dev; otherwise, you loose.
41 */
42static struct wusbhc *usbhc_dev_to_wusbhc(struct device *dev)
43{
44 struct usb_bus *usb_bus = dev_get_drvdata(dev);
45 struct usb_hcd *usb_hcd = bus_to_hcd(usb_bus);
46 return usb_hcd_to_wusbhc(usb_hcd);
47}
48
49/*
50 * Show & store the current WUSB trust timeout
51 *
52 * We don't do locking--it is an 'atomic' value.
53 *
54 * The units that we store/show are always MILLISECONDS. However, the
55 * value of trust_timeout is jiffies.
56 */
57static ssize_t wusb_trust_timeout_show(struct device *dev,
58 struct device_attribute *attr, char *buf)
59{
60 struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev);
61
62 return scnprintf(buf, PAGE_SIZE, "%u\n", wusbhc->trust_timeout);
63}
64
65static ssize_t wusb_trust_timeout_store(struct device *dev,
66 struct device_attribute *attr,
67 const char *buf, size_t size)
68{
69 struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev);
70 ssize_t result = -ENOSYS;
71 unsigned trust_timeout;
72
73 result = sscanf(buf, "%u", &trust_timeout);
74 if (result != 1) {
75 result = -EINVAL;
76 goto out;
77 }
78 /* FIXME: maybe we should check for range validity? */
79 wusbhc->trust_timeout = trust_timeout;
80 cancel_delayed_work(&wusbhc->keep_alive_timer);
81 flush_workqueue(wusbd);
82 queue_delayed_work(wusbd, &wusbhc->keep_alive_timer,
83 (trust_timeout * CONFIG_HZ)/1000/2);
84out:
85 return result < 0 ? result : size;
86}
87static DEVICE_ATTR(wusb_trust_timeout, 0644, wusb_trust_timeout_show,
88 wusb_trust_timeout_store);
89
90/*
91 * Show & store the current WUSB CHID
92 */
93static ssize_t wusb_chid_show(struct device *dev,
94 struct device_attribute *attr, char *buf)
95{
96 struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev);
97 ssize_t result = 0;
98
99 if (wusbhc->wuie_host_info != NULL)
100 result += ckhdid_printf(buf, PAGE_SIZE,
101 &wusbhc->wuie_host_info->CHID);
102 return result;
103}
104
105/*
106 * Store a new CHID
107 *
108 * This will (FIXME) trigger many changes.
109 *
110 * - Send an all zeros CHID and it will stop the controller
111 * - Send a non-zero CHID and it will start it
112 * (unless it was started, it will just change the CHID,
113 * diconnecting all devices first).
114 *
115 * So first we scan the MMC we are sent and then we act on it. We
116 * read it in the same format as we print it, an ASCII string of 16
117 * hex bytes.
118 *
119 * See wusbhc_chid_set() for more info.
120 */
121static ssize_t wusb_chid_store(struct device *dev,
122 struct device_attribute *attr,
123 const char *buf, size_t size)
124{
125 struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev);
126 struct wusb_ckhdid chid;
127 ssize_t result;
128
129 result = sscanf(buf,
130 "%02hhx %02hhx %02hhx %02hhx "
131 "%02hhx %02hhx %02hhx %02hhx "
132 "%02hhx %02hhx %02hhx %02hhx "
133 "%02hhx %02hhx %02hhx %02hhx\n",
134 &chid.data[0] , &chid.data[1] ,
135 &chid.data[2] , &chid.data[3] ,
136 &chid.data[4] , &chid.data[5] ,
137 &chid.data[6] , &chid.data[7] ,
138 &chid.data[8] , &chid.data[9] ,
139 &chid.data[10], &chid.data[11],
140 &chid.data[12], &chid.data[13],
141 &chid.data[14], &chid.data[15]);
142 if (result != 16) {
143 dev_err(dev, "Unrecognized CHID (need 16 8-bit hex digits): "
144 "%d\n", (int)result);
145 return -EINVAL;
146 }
147 result = wusbhc_chid_set(wusbhc, &chid);
148 return result < 0 ? result : size;
149}
150static DEVICE_ATTR(wusb_chid, 0644, wusb_chid_show, wusb_chid_store);
151
152/* Group all the WUSBHC attributes */
153static struct attribute *wusbhc_attrs[] = {
154 &dev_attr_wusb_trust_timeout.attr,
155 &dev_attr_wusb_chid.attr,
156 NULL,
157};
158
159static struct attribute_group wusbhc_attr_group = {
160 .name = NULL, /* we want them in the same directory */
161 .attrs = wusbhc_attrs,
162};
163
164/*
165 * Create a wusbhc instance
166 *
167 * NOTEs:
168 *
169 * - assumes *wusbhc has been zeroed and wusbhc->usb_hcd has been
170 * initialized but not added.
171 *
172 * - fill out ports_max, mmcies_max and mmcie_{add,rm} before calling.
173 *
174 * - fill out wusbhc->uwb_rc and refcount it before calling
175 * - fill out the wusbhc->sec_modes array
176 */
177int wusbhc_create(struct wusbhc *wusbhc)
178{
179 int result = 0;
180
181 wusbhc->trust_timeout = WUSB_TRUST_TIMEOUT_MS;
182 mutex_init(&wusbhc->mutex);
183 result = wusbhc_mmcie_create(wusbhc);
184 if (result < 0)
185 goto error_mmcie_create;
186 result = wusbhc_devconnect_create(wusbhc);
187 if (result < 0)
188 goto error_devconnect_create;
189 result = wusbhc_rh_create(wusbhc);
190 if (result < 0)
191 goto error_rh_create;
192 result = wusbhc_sec_create(wusbhc);
193 if (result < 0)
194 goto error_sec_create;
195 return 0;
196
197error_sec_create:
198 wusbhc_rh_destroy(wusbhc);
199error_rh_create:
200 wusbhc_devconnect_destroy(wusbhc);
201error_devconnect_create:
202 wusbhc_mmcie_destroy(wusbhc);
203error_mmcie_create:
204 return result;
205}
206EXPORT_SYMBOL_GPL(wusbhc_create);
207
208static inline struct kobject *wusbhc_kobj(struct wusbhc *wusbhc)
209{
210 return &wusbhc->usb_hcd.self.controller->kobj;
211}
212
213/*
214 * Phase B of a wusbhc instance creation
215 *
216 * Creates fields that depend on wusbhc->usb_hcd having been
217 * added. This is where we create the sysfs files in
218 * /sys/class/usb_host/usb_hostX/.
219 *
220 * NOTE: Assumes wusbhc->usb_hcd has been already added by the upper
221 * layer (hwahc or whci)
222 */
223int wusbhc_b_create(struct wusbhc *wusbhc)
224{
225 int result = 0;
226 struct device *dev = wusbhc->usb_hcd.self.controller;
227
228 result = sysfs_create_group(wusbhc_kobj(wusbhc), &wusbhc_attr_group);
229 if (result < 0) {
230 dev_err(dev, "Cannot register WUSBHC attributes: %d\n", result);
231 goto error_create_attr_group;
232 }
233
234 result = wusbhc_pal_register(wusbhc);
235 if (result < 0)
236 goto error_pal_register;
237 return 0;
238
239error_pal_register:
240 sysfs_remove_group(wusbhc_kobj(wusbhc), &wusbhc_attr_group);
241error_create_attr_group:
242 return result;
243}
244EXPORT_SYMBOL_GPL(wusbhc_b_create);
245
246void wusbhc_b_destroy(struct wusbhc *wusbhc)
247{
248 wusbhc_pal_unregister(wusbhc);
249 sysfs_remove_group(wusbhc_kobj(wusbhc), &wusbhc_attr_group);
250}
251EXPORT_SYMBOL_GPL(wusbhc_b_destroy);
252
253void wusbhc_destroy(struct wusbhc *wusbhc)
254{
255 wusbhc_sec_destroy(wusbhc);
256 wusbhc_rh_destroy(wusbhc);
257 wusbhc_devconnect_destroy(wusbhc);
258 wusbhc_mmcie_destroy(wusbhc);
259}
260EXPORT_SYMBOL_GPL(wusbhc_destroy);
261
262struct workqueue_struct *wusbd;
263EXPORT_SYMBOL_GPL(wusbd);
264
265/*
266 * WUSB Cluster ID allocation map
267 *
268 * Each WUSB bus in a channel is identified with a Cluster Id in the
269 * unauth address pace (WUSB1.0[4.3]). We take the range 0xe0 to 0xff
270 * (that's space for 31 WUSB controllers, as 0xff can't be taken). We
271 * start taking from 0xff, 0xfe, 0xfd... (hence the += or -= 0xff).
272 *
273 * For each one we taken, we pin it in the bitap
274 */
275#define CLUSTER_IDS 32
276static DECLARE_BITMAP(wusb_cluster_id_table, CLUSTER_IDS);
277static DEFINE_SPINLOCK(wusb_cluster_ids_lock);
278
279/*
280 * Get a WUSB Cluster ID
281 *
282 * Need to release with wusb_cluster_id_put() when done w/ it.
283 */
284/* FIXME: coordinate with the choose_addres() from the USB stack */
285/* we want to leave the top of the 128 range for cluster addresses and
286 * the bottom for device addresses (as we map them one on one with
287 * ports). */
288u8 wusb_cluster_id_get(void)
289{
290 u8 id;
291 spin_lock(&wusb_cluster_ids_lock);
292 id = find_first_zero_bit(wusb_cluster_id_table, CLUSTER_IDS);
293 if (id > CLUSTER_IDS) {
294 id = 0;
295 goto out;
296 }
297 set_bit(id, wusb_cluster_id_table);
298 id = (u8) 0xff - id;
299out:
300 spin_unlock(&wusb_cluster_ids_lock);
301 return id;
302
303}
304EXPORT_SYMBOL_GPL(wusb_cluster_id_get);
305
306/*
307 * Release a WUSB Cluster ID
308 *
309 * Obtained it with wusb_cluster_id_get()
310 */
311void wusb_cluster_id_put(u8 id)
312{
313 id = 0xff - id;
314 BUG_ON(id >= CLUSTER_IDS);
315 spin_lock(&wusb_cluster_ids_lock);
316 WARN_ON(!test_bit(id, wusb_cluster_id_table));
317 clear_bit(id, wusb_cluster_id_table);
318 spin_unlock(&wusb_cluster_ids_lock);
319}
320EXPORT_SYMBOL_GPL(wusb_cluster_id_put);
321
322/**
323 * wusbhc_giveback_urb - return an URB to the USB core
324 * @wusbhc: the host controller the URB is from.
325 * @urb: the URB.
326 * @status: the URB's status.
327 *
328 * Return an URB to the USB core doing some additional WUSB specific
329 * processing.
330 *
331 * - After a successful transfer, update the trust timeout timestamp
332 * for the WUSB device.
333 *
334 * - [WUSB] sections 4.13 and 7.5.1 specifies the stop retrasmittion
335 * condition for the WCONNECTACK_IE is that the host has observed
336 * the associated device responding to a control transfer.
337 */
338void wusbhc_giveback_urb(struct wusbhc *wusbhc, struct urb *urb, int status)
339{
340 struct wusb_dev *wusb_dev = __wusb_dev_get_by_usb_dev(wusbhc, urb->dev);
341
342 if (status == 0) {
343 wusb_dev->entry_ts = jiffies;
344
345 /* wusbhc_devconnect_acked() can't be called from from
346 atomic context so defer it to a work queue. */
347 if (!list_empty(&wusb_dev->cack_node))
348 queue_work(wusbd, &wusb_dev->devconnect_acked_work);
349 }
350
351 usb_hcd_giveback_urb(&wusbhc->usb_hcd, urb, status);
352}
353EXPORT_SYMBOL_GPL(wusbhc_giveback_urb);
354
355/**
356 * wusbhc_reset_all - reset the HC hardware
357 * @wusbhc: the host controller to reset.
358 *
359 * Request a full hardware reset of the chip. This will also reset
360 * the radio controller and any other PALs.
361 */
362void wusbhc_reset_all(struct wusbhc *wusbhc)
363{
364 uwb_rc_reset_all(wusbhc->uwb_rc);
365}
366EXPORT_SYMBOL_GPL(wusbhc_reset_all);
367
368static struct notifier_block wusb_usb_notifier = {
369 .notifier_call = wusb_usb_ncb,
370 .priority = INT_MAX /* Need to be called first of all */
371};
372
373static int __init wusbcore_init(void)
374{
375 int result;
376 result = wusb_crypto_init();
377 if (result < 0)
378 goto error_crypto_init;
379 /* WQ is singlethread because we need to serialize notifications */
380 wusbd = create_singlethread_workqueue("wusbd");
381 if (wusbd == NULL) {
382 result = -ENOMEM;
383 printk(KERN_ERR "WUSB-core: Cannot create wusbd workqueue\n");
384 goto error_wusbd_create;
385 }
386 usb_register_notify(&wusb_usb_notifier);
387 bitmap_zero(wusb_cluster_id_table, CLUSTER_IDS);
388 set_bit(0, wusb_cluster_id_table); /* reserve Cluster ID 0xff */
389 return 0;
390
391error_wusbd_create:
392 wusb_crypto_exit();
393error_crypto_init:
394 return result;
395
396}
397module_init(wusbcore_init);
398
399static void __exit wusbcore_exit(void)
400{
401 clear_bit(0, wusb_cluster_id_table);
402 if (!bitmap_empty(wusb_cluster_id_table, CLUSTER_IDS)) {
403 char buf[256];
404 bitmap_scnprintf(buf, sizeof(buf), wusb_cluster_id_table,
405 CLUSTER_IDS);
406 printk(KERN_ERR "BUG: WUSB Cluster IDs not released "
407 "on exit: %s\n", buf);
408 WARN_ON(1);
409 }
410 usb_unregister_notify(&wusb_usb_notifier);
411 destroy_workqueue(wusbd);
412 wusb_crypto_exit();
413}
414module_exit(wusbcore_exit);
415
416MODULE_AUTHOR("Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>");
417MODULE_DESCRIPTION("Wireless USB core");
418MODULE_LICENSE("GPL");
diff --git a/drivers/usb/wusbcore/wusbhc.h b/drivers/usb/wusbcore/wusbhc.h
new file mode 100644
index 000000000000..d0c132434f1b
--- /dev/null
+++ b/drivers/usb/wusbcore/wusbhc.h
@@ -0,0 +1,495 @@
1/*
2 * Wireless USB Host Controller
3 * Common infrastructure for WHCI and HWA WUSB-HC drivers
4 *
5 *
6 * Copyright (C) 2005-2006 Intel Corporation
7 * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License version
11 * 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301, USA.
22 *
23 *
24 * This driver implements parts common to all Wireless USB Host
25 * Controllers (struct wusbhc, embedding a struct usb_hcd) and is used
26 * by:
27 *
28 * - hwahc: HWA, USB-dongle that implements a Wireless USB host
29 * controller, (Wireless USB 1.0 Host-Wire-Adapter specification).
30 *
31 * - whci: WHCI, a PCI card with a wireless host controller
32 * (Wireless Host Controller Interface 1.0 specification).
33 *
34 * Check out the Design-overview.txt file in the source documentation
35 * for other details on the implementation.
36 *
37 * Main blocks:
38 *
39 * rh Root Hub emulation (part of the HCD glue)
40 *
41 * devconnect Handle all the issues related to device connection,
42 * authentication, disconnection, timeout, reseting,
43 * keepalives, etc.
44 *
45 * mmc MMC IE broadcasting handling
46 *
47 * A host controller driver just initializes its stuff and as part of
48 * that, creates a 'struct wusbhc' instance that handles all the
49 * common WUSB mechanisms. Links in the function ops that are specific
50 * to it and then registers the host controller. Ready to run.
51 */
52
53#ifndef __WUSBHC_H__
54#define __WUSBHC_H__
55
56#include <linux/usb.h>
57#include <linux/list.h>
58#include <linux/mutex.h>
59#include <linux/kref.h>
60#include <linux/workqueue.h>
61/* FIXME: Yes, I know: BAD--it's not my fault the USB HC iface is not
62 * public */
63#include <linux/../../drivers/usb/core/hcd.h>
64#include <linux/uwb.h>
65#include <linux/usb/wusb.h>
66
67
68/**
69 * Wireless USB device
70 *
71 * Describe a WUSB device connected to the cluster. This struct
72 * belongs to the 'struct wusb_port' it is attached to and it is
73 * responsible for putting and clearing the pointer to it.
74 *
75 * Note this "complements" the 'struct usb_device' that the usb_hcd
76 * keeps for each connected USB device. However, it extends some
77 * information that is not available (there is no hcpriv ptr in it!)
78 * *and* most importantly, it's life cycle is different. It is created
79 * as soon as we get a DN_Connect (connect request notification) from
80 * the device through the WUSB host controller; the USB stack doesn't
81 * create the device until we authenticate it. FIXME: this will
82 * change.
83 *
84 * @bos: This is allocated when the BOS descriptors are read from
85 * the device and freed upon the wusb_dev struct dying.
86 * @wusb_cap_descr: points into @bos, and has been verified to be size
87 * safe.
88 */
89struct wusb_dev {
90 struct kref refcnt;
91 struct wusbhc *wusbhc;
92 struct list_head cack_node; /* Connect-Ack list */
93 u8 port_idx;
94 u8 addr;
95 u8 beacon_type:4;
96 struct usb_encryption_descriptor ccm1_etd;
97 struct wusb_ckhdid cdid;
98 unsigned long entry_ts;
99 struct usb_bos_descriptor *bos;
100 struct usb_wireless_cap_descriptor *wusb_cap_descr;
101 struct uwb_mas_bm availability;
102 struct work_struct devconnect_acked_work;
103 struct urb *set_gtk_urb;
104 struct usb_ctrlrequest *set_gtk_req;
105 struct usb_device *usb_dev;
106};
107
108#define WUSB_DEV_ADDR_UNAUTH 0x80
109
110static inline void wusb_dev_init(struct wusb_dev *wusb_dev)
111{
112 kref_init(&wusb_dev->refcnt);
113 /* no need to init the cack_node */
114}
115
116extern void wusb_dev_destroy(struct kref *_wusb_dev);
117
118static inline struct wusb_dev *wusb_dev_get(struct wusb_dev *wusb_dev)
119{
120 kref_get(&wusb_dev->refcnt);
121 return wusb_dev;
122}
123
124static inline void wusb_dev_put(struct wusb_dev *wusb_dev)
125{
126 kref_put(&wusb_dev->refcnt, wusb_dev_destroy);
127}
128
129/**
130 * Wireless USB Host Controlller root hub "fake" ports
131 * (state and device information)
132 *
133 * Wireless USB is wireless, so there are no ports; but we
134 * fake'em. Each RC can connect a max of devices at the same time
135 * (given in the Wireless Adapter descriptor, bNumPorts or WHCI's
136 * caps), referred to in wusbhc->ports_max.
137 *
138 * See rh.c for more information.
139 *
140 * The @status and @change use the same bits as in USB2.0[11.24.2.7],
141 * so we don't have to do much when getting the port's status.
142 *
143 * WUSB1.0[7.1], USB2.0[11.24.2.7.1,fig 11-10],
144 * include/linux/usb_ch9.h (#define USB_PORT_STAT_*)
145 */
146struct wusb_port {
147 u16 status;
148 u16 change;
149 struct wusb_dev *wusb_dev; /* connected device's info */
150 unsigned reset_count;
151 u32 ptk_tkid;
152};
153
154/**
155 * WUSB Host Controller specifics
156 *
157 * All fields that are common to all Wireless USB controller types
158 * (HWA and WHCI) are grouped here. Host Controller
159 * functions/operations that only deal with general Wireless USB HC
160 * issues use this data type to refer to the host.
161 *
162 * @usb_hcd Instantiation of a USB host controller
163 * (initialized by upper layer [HWA=HC or WHCI].
164 *
165 * @dev Device that implements this; initialized by the
166 * upper layer (HWA-HC, WHCI...); this device should
167 * have a refcount.
168 *
169 * @trust_timeout After this time without hearing for device
170 * activity, we consider the device gone and we have to
171 * re-authenticate.
172 *
173 * Can be accessed w/o locking--however, read to a
174 * local variable then use.
175 *
176 * @chid WUSB Cluster Host ID: this is supposed to be a
177 * unique value that doesn't change across reboots (so
178 * that your devices do not require re-association).
179 *
180 * Read/Write protected by @mutex
181 *
182 * @dev_info This array has ports_max elements. It is used to
183 * give the HC information about the WUSB devices (see
184 * 'struct wusb_dev_info').
185 *
186 * For HWA we need to allocate it in heap; for WHCI it
187 * needs to be permanently mapped, so we keep it for
188 * both and make it easy. Call wusbhc->dev_info_set()
189 * to update an entry.
190 *
191 * @ports_max Number of simultaneous device connections (fake
192 * ports) this HC will take. Read-only.
193 *
194 * @port Array of port status for each fake root port. Guaranteed to
195 * always be the same lenght during device existence
196 * [this allows for some unlocked but referenced reading].
197 *
198 * @mmcies_max Max number of Information Elements this HC can send
199 * in its MMC. Read-only.
200 *
201 * @mmcie_add HC specific operation (WHCI or HWA) for adding an
202 * MMCIE.
203 *
204 * @mmcie_rm HC specific operation (WHCI or HWA) for removing an
205 * MMCIE.
206 *
207 * @enc_types Array which describes the encryptions methods
208 * supported by the host as described in WUSB1.0 --
209 * one entry per supported method. As of WUSB1.0 there
210 * is only four methods, we make space for eight just in
211 * case they decide to add some more (and pray they do
212 * it in sequential order). if 'enc_types[enc_method]
213 * != 0', then it is supported by the host. enc_method
214 * is USB_ENC_TYPE*.
215 *
216 * @set_ptk: Set the PTK and enable encryption for a device. Or, if
217 * the supplied key is NULL, disable encryption for that
218 * device.
219 *
220 * @set_gtk: Set the GTK to be used for all future broadcast packets
221 * (i.e., MMCs). With some hardware, setting the GTK may start
222 * MMC transmission.
223 *
224 * NOTE:
225 *
226 * - If wusb_dev->usb_dev is not NULL, then usb_dev is valid
227 * (wusb_dev has a refcount on it). Likewise, if usb_dev->wusb_dev
228 * is not NULL, usb_dev->wusb_dev is valid (usb_dev keeps a
229 * refcount on it).
230 *
231 * Most of the times when you need to use it, it will be non-NULL,
232 * so there is no real need to check for it (wusb_dev will
233 * dissapear before usb_dev).
234 *
235 * - The following fields need to be filled out before calling
236 * wusbhc_create(): ports_max, mmcies_max, mmcie_{add,rm}.
237 *
238 * - there is no wusbhc_init() method, we do everything in
239 * wusbhc_create().
240 *
241 * - Creation is done in two phases, wusbhc_create() and
242 * wusbhc_create_b(); b are the parts that need to be called after
243 * calling usb_hcd_add(&wusbhc->usb_hcd).
244 */
245struct wusbhc {
246 struct usb_hcd usb_hcd; /* HAS TO BE 1st */
247 struct device *dev;
248 struct uwb_rc *uwb_rc;
249 struct uwb_pal pal;
250
251 unsigned trust_timeout; /* in jiffies */
252 struct wuie_host_info *wuie_host_info; /* Includes CHID */
253
254 struct mutex mutex; /* locks everything else */
255 u16 cluster_id; /* Wireless USB Cluster ID */
256 struct wusb_port *port; /* Fake port status handling */
257 struct wusb_dev_info *dev_info; /* for Set Device Info mgmt */
258 u8 ports_max;
259 unsigned active:1; /* currently xmit'ing MMCs */
260 struct wuie_keep_alive keep_alive_ie; /* protected by mutex */
261 struct delayed_work keep_alive_timer;
262 struct list_head cack_list; /* Connect acknowledging */
263 size_t cack_count; /* protected by 'mutex' */
264 struct wuie_connect_ack cack_ie;
265 struct uwb_rsv *rsv; /* cluster bandwidth reservation */
266
267 struct mutex mmcie_mutex; /* MMC WUIE handling */
268 struct wuie_hdr **mmcie; /* WUIE array */
269 u8 mmcies_max;
270 /* FIXME: make wusbhc_ops? */
271 int (*start)(struct wusbhc *wusbhc);
272 void (*stop)(struct wusbhc *wusbhc);
273 int (*mmcie_add)(struct wusbhc *wusbhc, u8 interval, u8 repeat_cnt,
274 u8 handle, struct wuie_hdr *wuie);
275 int (*mmcie_rm)(struct wusbhc *wusbhc, u8 handle);
276 int (*dev_info_set)(struct wusbhc *, struct wusb_dev *wusb_dev);
277 int (*bwa_set)(struct wusbhc *wusbhc, s8 stream_index,
278 const struct uwb_mas_bm *);
279 int (*set_ptk)(struct wusbhc *wusbhc, u8 port_idx,
280 u32 tkid, const void *key, size_t key_size);
281 int (*set_gtk)(struct wusbhc *wusbhc,
282 u32 tkid, const void *key, size_t key_size);
283 int (*set_num_dnts)(struct wusbhc *wusbhc, u8 interval, u8 slots);
284
285 struct {
286 struct usb_key_descriptor descr;
287 u8 data[16]; /* GTK key data */
288 } __attribute__((packed)) gtk;
289 u8 gtk_index;
290 u32 gtk_tkid;
291 struct work_struct gtk_rekey_done_work;
292 int pending_set_gtks;
293
294 struct usb_encryption_descriptor *ccm1_etd;
295};
296
297#define usb_hcd_to_wusbhc(u) container_of((u), struct wusbhc, usb_hcd)
298
299
300extern int wusbhc_create(struct wusbhc *);
301extern int wusbhc_b_create(struct wusbhc *);
302extern void wusbhc_b_destroy(struct wusbhc *);
303extern void wusbhc_destroy(struct wusbhc *);
304extern int wusb_dev_sysfs_add(struct wusbhc *, struct usb_device *,
305 struct wusb_dev *);
306extern void wusb_dev_sysfs_rm(struct wusb_dev *);
307extern int wusbhc_sec_create(struct wusbhc *);
308extern int wusbhc_sec_start(struct wusbhc *);
309extern void wusbhc_sec_stop(struct wusbhc *);
310extern void wusbhc_sec_destroy(struct wusbhc *);
311extern void wusbhc_giveback_urb(struct wusbhc *wusbhc, struct urb *urb,
312 int status);
313void wusbhc_reset_all(struct wusbhc *wusbhc);
314
315int wusbhc_pal_register(struct wusbhc *wusbhc);
316void wusbhc_pal_unregister(struct wusbhc *wusbhc);
317
318/*
319 * Return @usb_dev's @usb_hcd (properly referenced) or NULL if gone
320 *
321 * @usb_dev: USB device, UNLOCKED and referenced (or otherwise, safe ptr)
322 *
323 * This is a safe assumption as @usb_dev->bus is referenced all the
324 * time during the @usb_dev life cycle.
325 */
326static inline struct usb_hcd *usb_hcd_get_by_usb_dev(struct usb_device *usb_dev)
327{
328 struct usb_hcd *usb_hcd;
329 usb_hcd = container_of(usb_dev->bus, struct usb_hcd, self);
330 return usb_get_hcd(usb_hcd);
331}
332
333/*
334 * Increment the reference count on a wusbhc.
335 *
336 * @wusbhc's life cycle is identical to that of the underlying usb_hcd.
337 */
338static inline struct wusbhc *wusbhc_get(struct wusbhc *wusbhc)
339{
340 return usb_get_hcd(&wusbhc->usb_hcd) ? wusbhc : NULL;
341}
342
343/*
344 * Return the wusbhc associated to a @usb_dev
345 *
346 * @usb_dev: USB device, UNLOCKED and referenced (or otherwise, safe ptr)
347 *
348 * @returns: wusbhc for @usb_dev; NULL if the @usb_dev is being torn down.
349 * WARNING: referenced at the usb_hcd level, unlocked
350 *
351 * FIXME: move offline
352 */
353static inline struct wusbhc *wusbhc_get_by_usb_dev(struct usb_device *usb_dev)
354{
355 struct wusbhc *wusbhc = NULL;
356 struct usb_hcd *usb_hcd;
357 if (usb_dev->devnum > 1 && !usb_dev->wusb) {
358 /* but root hubs */
359 dev_err(&usb_dev->dev, "devnum %d wusb %d\n", usb_dev->devnum,
360 usb_dev->wusb);
361 BUG_ON(usb_dev->devnum > 1 && !usb_dev->wusb);
362 }
363 usb_hcd = usb_hcd_get_by_usb_dev(usb_dev);
364 if (usb_hcd == NULL)
365 return NULL;
366 BUG_ON(usb_hcd->wireless == 0);
367 return wusbhc = usb_hcd_to_wusbhc(usb_hcd);
368}
369
370
371static inline void wusbhc_put(struct wusbhc *wusbhc)
372{
373 usb_put_hcd(&wusbhc->usb_hcd);
374}
375
376int wusbhc_start(struct wusbhc *wusbhc, const struct wusb_ckhdid *chid);
377void wusbhc_stop(struct wusbhc *wusbhc);
378extern int wusbhc_chid_set(struct wusbhc *, const struct wusb_ckhdid *);
379
380/* Device connect handling */
381extern int wusbhc_devconnect_create(struct wusbhc *);
382extern void wusbhc_devconnect_destroy(struct wusbhc *);
383extern int wusbhc_devconnect_start(struct wusbhc *wusbhc,
384 const struct wusb_ckhdid *chid);
385extern void wusbhc_devconnect_stop(struct wusbhc *wusbhc);
386extern int wusbhc_devconnect_auth(struct wusbhc *, u8);
387extern void wusbhc_handle_dn(struct wusbhc *, u8 srcaddr,
388 struct wusb_dn_hdr *dn_hdr, size_t size);
389extern int wusbhc_dev_reset(struct wusbhc *wusbhc, u8 port);
390extern void __wusbhc_dev_disable(struct wusbhc *wusbhc, u8 port);
391extern int wusb_usb_ncb(struct notifier_block *nb, unsigned long val,
392 void *priv);
393extern int wusb_set_dev_addr(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev,
394 u8 addr);
395
396/* Wireless USB fake Root Hub methods */
397extern int wusbhc_rh_create(struct wusbhc *);
398extern void wusbhc_rh_destroy(struct wusbhc *);
399
400extern int wusbhc_rh_status_data(struct usb_hcd *, char *);
401extern int wusbhc_rh_control(struct usb_hcd *, u16, u16, u16, char *, u16);
402extern int wusbhc_rh_suspend(struct usb_hcd *);
403extern int wusbhc_rh_resume(struct usb_hcd *);
404extern int wusbhc_rh_start_port_reset(struct usb_hcd *, unsigned);
405
406/* MMC handling */
407extern int wusbhc_mmcie_create(struct wusbhc *);
408extern void wusbhc_mmcie_destroy(struct wusbhc *);
409extern int wusbhc_mmcie_set(struct wusbhc *, u8 interval, u8 repeat_cnt,
410 struct wuie_hdr *);
411extern void wusbhc_mmcie_rm(struct wusbhc *, struct wuie_hdr *);
412
413/* Bandwidth reservation */
414int wusbhc_rsv_establish(struct wusbhc *wusbhc);
415void wusbhc_rsv_terminate(struct wusbhc *wusbhc);
416
417/*
418 * I've always said
419 * I wanted a wedding in a church...
420 *
421 * but lately I've been thinking about
422 * the Botanical Gardens.
423 *
424 * We could do it by the tulips.
425 * It'll be beautiful
426 *
427 * --Security!
428 */
429extern int wusb_dev_sec_add(struct wusbhc *, struct usb_device *,
430 struct wusb_dev *);
431extern void wusb_dev_sec_rm(struct wusb_dev *) ;
432extern int wusb_dev_4way_handshake(struct wusbhc *, struct wusb_dev *,
433 struct wusb_ckhdid *ck);
434void wusbhc_gtk_rekey(struct wusbhc *wusbhc);
435
436
437/* WUSB Cluster ID handling */
438extern u8 wusb_cluster_id_get(void);
439extern void wusb_cluster_id_put(u8);
440
441/*
442 * wusb_port_by_idx - return the port associated to a zero-based port index
443 *
444 * NOTE: valid without locking as long as wusbhc is referenced (as the
445 * number of ports doesn't change). The data pointed to has to
446 * be verified though :)
447 */
448static inline struct wusb_port *wusb_port_by_idx(struct wusbhc *wusbhc,
449 u8 port_idx)
450{
451 return &wusbhc->port[port_idx];
452}
453
454/*
455 * wusb_port_no_to_idx - Convert port number (per usb_dev->portnum) to
456 * a port_idx.
457 *
458 * USB stack USB ports are 1 based!!
459 *
460 * NOTE: only valid for WUSB devices!!!
461 */
462static inline u8 wusb_port_no_to_idx(u8 port_no)
463{
464 return port_no - 1;
465}
466
467extern struct wusb_dev *__wusb_dev_get_by_usb_dev(struct wusbhc *,
468 struct usb_device *);
469
470/*
471 * Return a referenced wusb_dev given a @usb_dev
472 *
473 * Returns NULL if the usb_dev is being torn down.
474 *
475 * FIXME: move offline
476 */
477static inline
478struct wusb_dev *wusb_dev_get_by_usb_dev(struct usb_device *usb_dev)
479{
480 struct wusbhc *wusbhc;
481 struct wusb_dev *wusb_dev;
482 wusbhc = wusbhc_get_by_usb_dev(usb_dev);
483 if (wusbhc == NULL)
484 return NULL;
485 mutex_lock(&wusbhc->mutex);
486 wusb_dev = __wusb_dev_get_by_usb_dev(wusbhc, usb_dev);
487 mutex_unlock(&wusbhc->mutex);
488 wusbhc_put(wusbhc);
489 return wusb_dev;
490}
491
492/* Misc */
493
494extern struct workqueue_struct *wusbd;
495#endif /* #ifndef __WUSBHC_H__ */