2
* WUSB Wire Adapter: Control/Data Streaming Interface (WUSB[8])
3
* Device Connect handling
5
* Copyright (C) 2006 Intel Corporation
6
* Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
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.
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.
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
24
* FIXME: this file needs to be broken up, it's grown too big
27
* WUSB1.0[7.1, 7.5.1, ]
29
* WUSB device connection is kind of messy. Some background:
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] .
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).
44
* So now the device now has a WUSB address. From now on, we use
45
* that to talk to it in the RPipes.
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.
54
* This file contains the logic for doing that--entry points:
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.
60
* wusb_devconnect_acked() Ack done, release resources.
62
* wusb_handle_dn_alive() Called by notif.c:wusb_handle_dn()
63
* for processing a DN_Alive pong from a device.
65
* wusb_handle_dn_disconnect()Called by notif.c:wusb_handle_dn() to
66
* process a disconenct request from a
69
* __wusb_dev_disable() Called by rh.c:wusbhc_rh_clear_port_feat() when
72
* wusb_devconnect_create() Called when creating the host by
73
* lc.c:wusbhc_create().
75
* wusb_devconnect_destroy() Cleanup called removing the host. Called
76
* by lc.c:wusbhc_destroy().
78
* Each Wireless USB host maintains a list of DN_Connect requests
79
* (actually we maintain a list of pending Connect Acks, the
82
* LIFE CYCLE OF port->wusb_dev
84
* Before the @wusbhc structure put()s the reference it owns for
85
* port->wusb_dev [and clean the wusb_dev pointer], it needs to
86
* lock @wusbhc->mutex.
89
#include <linux/jiffies.h>
90
#include <linux/ctype.h>
91
#include <linux/slab.h>
92
#include <linux/workqueue.h>
93
#include <linux/export.h>
96
static void wusbhc_devconnect_acked_work(struct work_struct *work);
98
static void wusb_dev_free(struct wusb_dev *wusb_dev)
101
kfree(wusb_dev->set_gtk_req);
102
usb_free_urb(wusb_dev->set_gtk_urb);
107
static struct wusb_dev *wusb_dev_alloc(struct wusbhc *wusbhc)
109
struct wusb_dev *wusb_dev;
111
struct usb_ctrlrequest *req;
113
wusb_dev = kzalloc(sizeof(*wusb_dev), GFP_KERNEL);
114
if (wusb_dev == NULL)
117
wusb_dev->wusbhc = wusbhc;
119
INIT_WORK(&wusb_dev->devconnect_acked_work, wusbhc_devconnect_acked_work);
121
urb = usb_alloc_urb(0, GFP_KERNEL);
124
wusb_dev->set_gtk_urb = urb;
126
req = kmalloc(sizeof(*req), GFP_KERNEL);
129
wusb_dev->set_gtk_req = req;
131
req->bRequestType = USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE;
132
req->bRequest = USB_REQ_SET_DESCRIPTOR;
133
req->wValue = cpu_to_le16(USB_DT_KEY << 8 | wusbhc->gtk_index);
135
req->wLength = cpu_to_le16(wusbhc->gtk.descr.bLength);
139
wusb_dev_free(wusb_dev);
145
* Using the Connect-Ack list, fill out the @wusbhc Connect-Ack WUSB IE
146
* properly so that it can be added to the MMC.
148
* We just get the @wusbhc->ca_list and fill out the first four ones or
149
* less (per-spec WUSB1.0[7.5, before T7-38). If the ConnectAck WUSB
150
* IE is not allocated, we alloc it.
152
* @wusbhc->mutex must be taken
154
static void wusbhc_fill_cack_ie(struct wusbhc *wusbhc)
157
struct wusb_dev *dev_itr;
158
struct wuie_connect_ack *cack_ie;
160
cack_ie = &wusbhc->cack_ie;
162
list_for_each_entry(dev_itr, &wusbhc->cack_list, cack_node) {
163
cack_ie->blk[cnt].CDID = dev_itr->cdid;
164
cack_ie->blk[cnt].bDeviceAddress = dev_itr->addr;
165
if (++cnt >= WUIE_ELT_MAX)
168
cack_ie->hdr.bLength = sizeof(cack_ie->hdr)
169
+ cnt * sizeof(cack_ie->blk[0]);
173
* Register a new device that wants to connect
175
* A new device wants to connect, so we add it to the Connect-Ack
176
* list. We give it an address in the unauthorized range (bit 8 set);
177
* user space will have to drive authorization further on.
179
* @dev_addr: address to use for the device (which is also the port
182
* @wusbhc->mutex must be taken
184
static struct wusb_dev *wusbhc_cack_add(struct wusbhc *wusbhc,
185
struct wusb_dn_connect *dnc,
186
const char *pr_cdid, u8 port_idx)
188
struct device *dev = wusbhc->dev;
189
struct wusb_dev *wusb_dev;
190
int new_connection = wusb_dn_connect_new_connection(dnc);
194
/* Is it registered already? */
195
list_for_each_entry(wusb_dev, &wusbhc->cack_list, cack_node)
196
if (!memcmp(&wusb_dev->cdid, &dnc->CDID,
197
sizeof(wusb_dev->cdid)))
199
/* We don't have it, create an entry, register it */
200
wusb_dev = wusb_dev_alloc(wusbhc);
201
if (wusb_dev == NULL)
203
wusb_dev_init(wusb_dev);
204
wusb_dev->cdid = dnc->CDID;
205
wusb_dev->port_idx = port_idx;
208
* Devices are always available within the cluster reservation
209
* and since the hardware will take the intersection of the
210
* per-device availability and the cluster reservation, the
211
* per-device availability can simply be set to always
214
bitmap_fill(wusb_dev->availability.bm, UWB_NUM_MAS);
216
/* FIXME: handle reconnects instead of assuming connects are
218
if (1 && new_connection == 0)
220
if (new_connection) {
221
dev_addr = (port_idx + 2) | WUSB_DEV_ADDR_UNAUTH;
223
dev_info(dev, "Connecting new WUSB device to address %u, "
224
"port %u\n", dev_addr, port_idx);
226
result = wusb_set_dev_addr(wusbhc, wusb_dev, dev_addr);
230
wusb_dev->entry_ts = jiffies;
231
list_add_tail(&wusb_dev->cack_node, &wusbhc->cack_list);
232
wusbhc->cack_count++;
233
wusbhc_fill_cack_ie(wusbhc);
239
* Remove a Connect-Ack context entry from the HCs view
241
* @wusbhc->mutex must be taken
243
static void wusbhc_cack_rm(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
245
list_del_init(&wusb_dev->cack_node);
246
wusbhc->cack_count--;
247
wusbhc_fill_cack_ie(wusbhc);
251
* @wusbhc->mutex must be taken */
253
void wusbhc_devconnect_acked(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
255
wusbhc_cack_rm(wusbhc, wusb_dev);
256
if (wusbhc->cack_count)
257
wusbhc_mmcie_set(wusbhc, 0, 0, &wusbhc->cack_ie.hdr);
259
wusbhc_mmcie_rm(wusbhc, &wusbhc->cack_ie.hdr);
262
static void wusbhc_devconnect_acked_work(struct work_struct *work)
264
struct wusb_dev *wusb_dev = container_of(work, struct wusb_dev,
265
devconnect_acked_work);
266
struct wusbhc *wusbhc = wusb_dev->wusbhc;
268
mutex_lock(&wusbhc->mutex);
269
wusbhc_devconnect_acked(wusbhc, wusb_dev);
270
mutex_unlock(&wusbhc->mutex);
272
wusb_dev_put(wusb_dev);
276
* Ack a device for connection
280
* @pr_cdid: Printable CDID...hex Use @dnc->cdid for the real deal.
282
* So we get the connect ack IE (may have been allocated already),
283
* find an empty connect block, an empty virtual port, create an
284
* address with it (see below), make it an unauth addr [bit 7 set] and
287
* Addresses: because WUSB hosts have no downstream hubs, we can do a
288
* 1:1 mapping between 'port number' and device
289
* address. This simplifies many things, as during this
290
* initial connect phase the USB stack has no knoledge of
291
* the device and hasn't assigned an address yet--we know
292
* USB's choose_address() will use the same euristics we
293
* use here, so we can assume which address will be assigned.
295
* USB stack always assigns address 1 to the root hub, so
296
* to the port number we add 2 (thus virtual port #0 is
299
* @wusbhc shall be referenced
302
void wusbhc_devconnect_ack(struct wusbhc *wusbhc, struct wusb_dn_connect *dnc,
306
struct device *dev = wusbhc->dev;
307
struct wusb_dev *wusb_dev;
308
struct wusb_port *port;
309
unsigned idx, devnum;
311
mutex_lock(&wusbhc->mutex);
313
/* Check we are not handling it already */
314
for (idx = 0; idx < wusbhc->ports_max; idx++) {
315
port = wusb_port_by_idx(wusbhc, idx);
317
&& memcmp(&dnc->CDID, &port->wusb_dev->cdid, sizeof(dnc->CDID)) == 0)
320
/* Look up those fake ports we have for a free one */
321
for (idx = 0; idx < wusbhc->ports_max; idx++) {
322
port = wusb_port_by_idx(wusbhc, idx);
323
if ((port->status & USB_PORT_STAT_POWER)
324
&& !(port->status & USB_PORT_STAT_CONNECTION))
327
if (idx >= wusbhc->ports_max) {
328
dev_err(dev, "Host controller can't connect more devices "
329
"(%u already connected); device %s rejected\n",
330
wusbhc->ports_max, pr_cdid);
331
/* NOTE: we could send a WUIE_Disconnect here, but we haven't
332
* event acked, so the device will eventually timeout the
333
* connection, right? */
339
/* Make sure we are using no crypto on that "virtual port" */
340
wusbhc->set_ptk(wusbhc, idx, 0, NULL, 0);
342
/* Grab a filled in Connect-Ack context, fill out the
343
* Connect-Ack Wireless USB IE, set the MMC */
344
wusb_dev = wusbhc_cack_add(wusbhc, dnc, pr_cdid, idx);
345
if (wusb_dev == NULL)
347
result = wusbhc_mmcie_set(wusbhc, 0, 0, &wusbhc->cack_ie.hdr);
350
/* Give the device at least 2ms (WUSB1.0[7.5.1p3]), let's do
351
* three for a good measure */
353
port->wusb_dev = wusb_dev;
354
port->status |= USB_PORT_STAT_CONNECTION;
355
port->change |= USB_PORT_STAT_C_CONNECTION;
356
/* Now the port status changed to connected; khubd will
357
* pick the change up and try to reset the port to bring it to
358
* the enabled state--so this process returns up to the stack
359
* and it calls back into wusbhc_rh_port_reset().
362
mutex_unlock(&wusbhc->mutex);
368
* Disconnect a Wireless USB device from its fake port
370
* Marks the port as disconnected so that khubd can pick up the change
371
* and drops our knowledge about the device.
373
* Assumes there is a device connected
375
* @port_index: zero based port number
377
* NOTE: @wusbhc->mutex is locked
379
* WARNING: From here it is not very safe to access anything hanging off
382
static void __wusbhc_dev_disconnect(struct wusbhc *wusbhc,
383
struct wusb_port *port)
385
struct wusb_dev *wusb_dev = port->wusb_dev;
387
port->status &= ~(USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE
388
| USB_PORT_STAT_SUSPEND | USB_PORT_STAT_RESET
389
| USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED);
390
port->change |= USB_PORT_STAT_C_CONNECTION | USB_PORT_STAT_C_ENABLE;
392
dev_dbg(wusbhc->dev, "disconnecting device from port %d\n", wusb_dev->port_idx);
393
if (!list_empty(&wusb_dev->cack_node))
394
list_del_init(&wusb_dev->cack_node);
395
/* For the one in cack_add() */
396
wusb_dev_put(wusb_dev);
398
port->wusb_dev = NULL;
400
/* After a device disconnects, change the GTK (see [WUSB]
401
* section 6.2.11.2). */
403
wusbhc_gtk_rekey(wusbhc);
405
/* The Wireless USB part has forgotten about the device already; now
406
* khubd's timer will pick up the disconnection and remove the USB
407
* device from the system
412
* Refresh the list of keep alives to emit in the MMC
414
* Some devices don't respond to keep alives unless they've been
415
* authenticated, so skip unauthenticated devices.
417
* We only publish the first four devices that have a coming timeout
418
* condition. Then when we are done processing those, we go for the
419
* next ones. We ignore the ones that have timed out already (they'll
422
* This might cause the first devices to timeout the last devices in
423
* the port array...FIXME: come up with a better algorithm?
425
* Note we can't do much about MMC's ops errors; we hope next refresh
426
* will kind of handle it.
428
* NOTE: @wusbhc->mutex is locked
430
static void __wusbhc_keep_alive(struct wusbhc *wusbhc)
432
struct device *dev = wusbhc->dev;
434
struct wusb_dev *wusb_dev;
435
struct wusb_port *wusb_port;
436
struct wuie_keep_alive *ie = &wusbhc->keep_alive_ie;
437
unsigned keep_alives, old_keep_alives;
439
old_keep_alives = ie->hdr.bLength - sizeof(ie->hdr);
442
keep_alives < WUIE_ELT_MAX && cnt < wusbhc->ports_max;
444
unsigned tt = msecs_to_jiffies(wusbhc->trust_timeout);
446
wusb_port = wusb_port_by_idx(wusbhc, cnt);
447
wusb_dev = wusb_port->wusb_dev;
449
if (wusb_dev == NULL)
451
if (wusb_dev->usb_dev == NULL || !wusb_dev->usb_dev->authenticated)
454
if (time_after(jiffies, wusb_dev->entry_ts + tt)) {
455
dev_err(dev, "KEEPALIVE: device %u timed out\n",
457
__wusbhc_dev_disconnect(wusbhc, wusb_port);
458
} else if (time_after(jiffies, wusb_dev->entry_ts + tt/2)) {
459
/* Approaching timeout cut out, need to refresh */
460
ie->bDeviceAddress[keep_alives++] = wusb_dev->addr;
463
if (keep_alives & 0x1) /* pad to even number ([WUSB] section 7.5.9) */
464
ie->bDeviceAddress[keep_alives++] = 0x7f;
465
ie->hdr.bLength = sizeof(ie->hdr) +
466
keep_alives*sizeof(ie->bDeviceAddress[0]);
468
wusbhc_mmcie_set(wusbhc, 10, 5, &ie->hdr);
469
else if (old_keep_alives != 0)
470
wusbhc_mmcie_rm(wusbhc, &ie->hdr);
474
* Do a run through all devices checking for timeouts
476
static void wusbhc_keep_alive_run(struct work_struct *ws)
478
struct delayed_work *dw = to_delayed_work(ws);
479
struct wusbhc *wusbhc = container_of(dw, struct wusbhc, keep_alive_timer);
481
mutex_lock(&wusbhc->mutex);
482
__wusbhc_keep_alive(wusbhc);
483
mutex_unlock(&wusbhc->mutex);
485
queue_delayed_work(wusbd, &wusbhc->keep_alive_timer,
486
msecs_to_jiffies(wusbhc->trust_timeout / 2));
490
* Find the wusb_dev from its device address.
492
* The device can be found directly from the address (see
493
* wusb_cack_add() for where the device address is set to port_idx
494
* +2), except when the address is zero.
496
static struct wusb_dev *wusbhc_find_dev_by_addr(struct wusbhc *wusbhc, u8 addr)
500
if (addr == 0xff) /* unconnected */
504
int port = (addr & ~0x80) - 2;
505
if (port < 0 || port >= wusbhc->ports_max)
507
return wusb_port_by_idx(wusbhc, port)->wusb_dev;
510
/* Look for the device with address 0. */
511
for (p = 0; p < wusbhc->ports_max; p++) {
512
struct wusb_dev *wusb_dev = wusb_port_by_idx(wusbhc, p)->wusb_dev;
513
if (wusb_dev && wusb_dev->addr == addr)
520
* Handle a DN_Alive notification (WUSB1.0[7.6.1])
522
* This just updates the device activity timestamp and then refreshes
525
* @wusbhc shall be referenced and unlocked
527
static void wusbhc_handle_dn_alive(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
529
mutex_lock(&wusbhc->mutex);
530
wusb_dev->entry_ts = jiffies;
531
__wusbhc_keep_alive(wusbhc);
532
mutex_unlock(&wusbhc->mutex);
536
* Handle a DN_Connect notification (WUSB1.0[7.6.1])
540
* @size: Size of the buffer where the notification resides; if the
541
* notification data suggests there should be more data than
542
* available, an error will be signaled and the whole buffer
545
* @wusbhc->mutex shall be held
547
static void wusbhc_handle_dn_connect(struct wusbhc *wusbhc,
548
struct wusb_dn_hdr *dn_hdr,
551
struct device *dev = wusbhc->dev;
552
struct wusb_dn_connect *dnc;
553
char pr_cdid[WUSB_CKHDID_STRSIZE];
554
static const char *beacon_behaviour[] = {
561
if (size < sizeof(*dnc)) {
562
dev_err(dev, "DN CONNECT: short notification (%zu < %zu)\n",
567
dnc = container_of(dn_hdr, struct wusb_dn_connect, hdr);
568
ckhdid_printf(pr_cdid, sizeof(pr_cdid), &dnc->CDID);
569
dev_info(dev, "DN CONNECT: device %s @ %x (%s) wants to %s\n",
571
wusb_dn_connect_prev_dev_addr(dnc),
572
beacon_behaviour[wusb_dn_connect_beacon_behavior(dnc)],
573
wusb_dn_connect_new_connection(dnc) ? "connect" : "reconnect");
574
/* ACK the connect */
575
wusbhc_devconnect_ack(wusbhc, dnc, pr_cdid);
579
* Handle a DN_Disconnect notification (WUSB1.0[7.6.1])
581
* Device is going down -- do the disconnect.
583
* @wusbhc shall be referenced and unlocked
585
static void wusbhc_handle_dn_disconnect(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
587
struct device *dev = wusbhc->dev;
589
dev_info(dev, "DN DISCONNECT: device 0x%02x going down\n", wusb_dev->addr);
591
mutex_lock(&wusbhc->mutex);
592
__wusbhc_dev_disconnect(wusbhc, wusb_port_by_idx(wusbhc, wusb_dev->port_idx));
593
mutex_unlock(&wusbhc->mutex);
597
* Handle a Device Notification coming a host
599
* The Device Notification comes from a host (HWA, DWA or WHCI)
600
* wrapped in a set of headers. Somebody else has peeled off those
601
* headers for us and we just get one Device Notifications.
603
* Invalid DNs (e.g., too short) are discarded.
605
* @wusbhc shall be referenced
608
* - implement priorities as in WUSB1.0[Table 7-55]?
610
void wusbhc_handle_dn(struct wusbhc *wusbhc, u8 srcaddr,
611
struct wusb_dn_hdr *dn_hdr, size_t size)
613
struct device *dev = wusbhc->dev;
614
struct wusb_dev *wusb_dev;
616
if (size < sizeof(struct wusb_dn_hdr)) {
617
dev_err(dev, "DN data shorter than DN header (%d < %d)\n",
618
(int)size, (int)sizeof(struct wusb_dn_hdr));
622
wusb_dev = wusbhc_find_dev_by_addr(wusbhc, srcaddr);
623
if (wusb_dev == NULL && dn_hdr->bType != WUSB_DN_CONNECT) {
624
dev_dbg(dev, "ignoring DN %d from unconnected device %02x\n",
625
dn_hdr->bType, srcaddr);
629
switch (dn_hdr->bType) {
630
case WUSB_DN_CONNECT:
631
wusbhc_handle_dn_connect(wusbhc, dn_hdr, size);
634
wusbhc_handle_dn_alive(wusbhc, wusb_dev);
636
case WUSB_DN_DISCONNECT:
637
wusbhc_handle_dn_disconnect(wusbhc, wusb_dev);
639
case WUSB_DN_MASAVAILCHANGED:
642
/* FIXME: handle these DNs. */
645
/* The hardware handles these. */
648
dev_warn(dev, "unknown DN %u (%d octets) from %u\n",
649
dn_hdr->bType, (int)size, srcaddr);
652
EXPORT_SYMBOL_GPL(wusbhc_handle_dn);
655
* Disconnect a WUSB device from a the cluster
658
* @port Fake port where the device is (wusbhc index, not USB port number).
660
* In Wireless USB, a disconnect is basically telling the device he is
661
* being disconnected and forgetting about him.
663
* We send the device a Device Disconnect IE (WUSB1.0[7.5.11]) for 100
664
* ms and then keep going.
666
* We don't do much in case of error; we always pretend we disabled
667
* the port and disconnected the device. If physically the request
668
* didn't get there (many things can fail in the way there), the stack
669
* will reject the device's communication attempts.
671
* @wusbhc should be refcounted and locked
673
void __wusbhc_dev_disable(struct wusbhc *wusbhc, u8 port_idx)
676
struct device *dev = wusbhc->dev;
677
struct wusb_dev *wusb_dev;
678
struct wuie_disconnect *ie;
680
wusb_dev = wusb_port_by_idx(wusbhc, port_idx)->wusb_dev;
681
if (wusb_dev == NULL) {
682
/* reset no device? ignore */
683
dev_dbg(dev, "DISCONNECT: no device at port %u, ignoring\n",
687
__wusbhc_dev_disconnect(wusbhc, wusb_port_by_idx(wusbhc, port_idx));
689
ie = kzalloc(sizeof(*ie), GFP_KERNEL);
692
ie->hdr.bLength = sizeof(*ie);
693
ie->hdr.bIEIdentifier = WUIE_ID_DEVICE_DISCONNECT;
694
ie->bDeviceAddress = wusb_dev->addr;
695
result = wusbhc_mmcie_set(wusbhc, 0, 0, &ie->hdr);
697
dev_err(dev, "DISCONNECT: can't set MMC: %d\n", result);
699
/* At least 6 MMCs, assuming at least 1 MMC per zone. */
701
wusbhc_mmcie_rm(wusbhc, &ie->hdr);
707
* Walk over the BOS descriptor, verify and grok it
709
* @usb_dev: referenced
710
* @wusb_dev: referenced and unlocked
712
* The BOS descriptor is defined at WUSB1.0[7.4.1], and it defines a
713
* "flexible" way to wrap all kinds of descriptors inside an standard
714
* descriptor (wonder why they didn't use normal descriptors,
715
* btw). Not like they lack code.
717
* At the end we go to look for the WUSB Device Capabilities
718
* (WUSB1.0[7.4.1.1]) that is wrapped in a device capability descriptor
719
* that is part of the BOS descriptor set. That tells us what does the
720
* device support (dual role, beacon type, UWB PHY rates).
722
static int wusb_dev_bos_grok(struct usb_device *usb_dev,
723
struct wusb_dev *wusb_dev,
724
struct usb_bos_descriptor *bos, size_t desc_size)
727
struct device *dev = &usb_dev->dev;
730
/* Walk over BOS capabilities, verify them */
731
itr = (void *)bos + sizeof(*bos);
732
top = itr + desc_size - sizeof(*bos);
734
struct usb_dev_cap_header *cap_hdr = itr;
737
if (top - itr < sizeof(*cap_hdr)) {
738
dev_err(dev, "Device BUG? premature end of BOS header "
739
"data [offset 0x%02x]: only %zu bytes left\n",
740
(int)(itr - (void *)bos), top - itr);
744
cap_size = cap_hdr->bLength;
745
cap_type = cap_hdr->bDevCapabilityType;
748
if (cap_size > top - itr) {
749
dev_err(dev, "Device BUG? premature end of BOS data "
750
"[offset 0x%02x cap %02x %zu bytes]: "
751
"only %zu bytes left\n",
752
(int)(itr - (void *)bos),
753
cap_type, cap_size, top - itr);
758
case USB_CAP_TYPE_WIRELESS_USB:
759
if (cap_size != sizeof(*wusb_dev->wusb_cap_descr))
760
dev_err(dev, "Device BUG? WUSB Capability "
761
"descriptor is %zu bytes vs %zu "
762
"needed\n", cap_size,
763
sizeof(*wusb_dev->wusb_cap_descr));
765
wusb_dev->wusb_cap_descr = itr;
768
dev_err(dev, "BUG? Unknown BOS capability 0x%02x "
769
"(%zu bytes) at offset 0x%02x\n", cap_type,
770
cap_size, (int)(itr - (void *)bos));
780
* Add information from the BOS descriptors to the device
782
* @usb_dev: referenced
783
* @wusb_dev: referenced and unlocked
785
* So what we do is we alloc a space for the BOS descriptor of 64
786
* bytes; read the first four bytes which include the wTotalLength
787
* field (WUSB1.0[T7-26]) and if it fits in those 64 bytes, read the
788
* whole thing. If not we realloc to that size.
790
* Then we call the groking function, that will fill up
791
* wusb_dev->wusb_cap_descr, which is what we'll need later on.
793
static int wusb_dev_bos_add(struct usb_device *usb_dev,
794
struct wusb_dev *wusb_dev)
797
struct device *dev = &usb_dev->dev;
798
struct usb_bos_descriptor *bos;
799
size_t alloc_size = 32, desc_size = 4;
801
bos = kmalloc(alloc_size, GFP_KERNEL);
804
result = usb_get_descriptor(usb_dev, USB_DT_BOS, 0, bos, desc_size);
806
dev_err(dev, "Can't get BOS descriptor or too short: %zd\n",
808
goto error_get_descriptor;
810
desc_size = le16_to_cpu(bos->wTotalLength);
811
if (desc_size >= alloc_size) {
813
alloc_size = desc_size;
814
bos = kmalloc(alloc_size, GFP_KERNEL);
818
result = usb_get_descriptor(usb_dev, USB_DT_BOS, 0, bos, desc_size);
819
if (result < 0 || result != desc_size) {
820
dev_err(dev, "Can't get BOS descriptor or too short (need "
821
"%zu bytes): %zd\n", desc_size, result);
822
goto error_get_descriptor;
824
if (result < sizeof(*bos)
825
|| le16_to_cpu(bos->wTotalLength) != desc_size) {
826
dev_err(dev, "Can't get BOS descriptor or too short (need "
827
"%zu bytes): %zd\n", desc_size, result);
828
goto error_get_descriptor;
831
result = wusb_dev_bos_grok(usb_dev, wusb_dev, bos, result);
838
error_get_descriptor:
840
wusb_dev->wusb_cap_descr = NULL;
844
static void wusb_dev_bos_rm(struct wusb_dev *wusb_dev)
846
kfree(wusb_dev->bos);
847
wusb_dev->wusb_cap_descr = NULL;
850
static struct usb_wireless_cap_descriptor wusb_cap_descr_default = {
851
.bLength = sizeof(wusb_cap_descr_default),
852
.bDescriptorType = USB_DT_DEVICE_CAPABILITY,
853
.bDevCapabilityType = USB_CAP_TYPE_WIRELESS_USB,
855
.bmAttributes = USB_WIRELESS_BEACON_NONE,
856
.wPHYRates = cpu_to_le16(USB_WIRELESS_PHY_53),
857
.bmTFITXPowerInfo = 0,
858
.bmFFITXPowerInfo = 0,
859
.bmBandGroup = cpu_to_le16(0x0001), /* WUSB1.0[7.4.1] bottom */
864
* USB stack's device addition Notifier Callback
866
* Called from drivers/usb/core/hub.c when a new device is added; we
867
* use this hook to perform certain WUSB specific setup work on the
868
* new device. As well, it is the first time we can connect the
869
* wusb_dev and the usb_dev. So we note it down in wusb_dev and take a
870
* reference that we'll drop.
872
* First we need to determine if the device is a WUSB device (else we
873
* ignore it). For that we use the speed setting (USB_SPEED_WIRELESS)
874
* [FIXME: maybe we'd need something more definitive]. If so, we track
875
* it's usb_busd and from there, the WUSB HC.
877
* Because all WUSB HCs are contained in a 'struct wusbhc', voila, we
878
* get the wusbhc for the device.
880
* We have a reference on @usb_dev (as we are called at the end of its
883
* NOTE: @usb_dev locked
885
static void wusb_dev_add_ncb(struct usb_device *usb_dev)
888
struct wusb_dev *wusb_dev;
889
struct wusbhc *wusbhc;
890
struct device *dev = &usb_dev->dev;
893
if (usb_dev->wusb == 0 || usb_dev->devnum == 1)
894
return; /* skip non wusb and wusb RHs */
896
usb_set_device_state(usb_dev, USB_STATE_UNAUTHENTICATED);
898
wusbhc = wusbhc_get_by_usb_dev(usb_dev);
901
mutex_lock(&wusbhc->mutex);
902
wusb_dev = __wusb_dev_get_by_usb_dev(wusbhc, usb_dev);
903
port_idx = wusb_port_no_to_idx(usb_dev->portnum);
904
mutex_unlock(&wusbhc->mutex);
905
if (wusb_dev == NULL)
907
wusb_dev->usb_dev = usb_get_dev(usb_dev);
908
usb_dev->wusb_dev = wusb_dev_get(wusb_dev);
909
result = wusb_dev_sec_add(wusbhc, usb_dev, wusb_dev);
911
dev_err(dev, "Cannot enable security: %d\n", result);
914
/* Now query the device for it's BOS and attach it to wusb_dev */
915
result = wusb_dev_bos_add(usb_dev, wusb_dev);
917
dev_err(dev, "Cannot get BOS descriptors: %d\n", result);
920
result = wusb_dev_sysfs_add(wusbhc, usb_dev, wusb_dev);
922
goto error_add_sysfs;
924
wusb_dev_put(wusb_dev);
929
wusb_dev_sysfs_rm(wusb_dev);
931
wusb_dev_bos_rm(wusb_dev);
933
wusb_dev_sec_rm(wusb_dev);
935
mutex_lock(&wusbhc->mutex);
936
__wusbhc_dev_disconnect(wusbhc, wusb_port_by_idx(wusbhc, port_idx));
937
mutex_unlock(&wusbhc->mutex);
942
* Undo all the steps done at connection by the notifier callback
944
* NOTE: @usb_dev locked
946
static void wusb_dev_rm_ncb(struct usb_device *usb_dev)
948
struct wusb_dev *wusb_dev = usb_dev->wusb_dev;
950
if (usb_dev->wusb == 0 || usb_dev->devnum == 1)
951
return; /* skip non wusb and wusb RHs */
953
wusb_dev_sysfs_rm(wusb_dev);
954
wusb_dev_bos_rm(wusb_dev);
955
wusb_dev_sec_rm(wusb_dev);
956
wusb_dev->usb_dev = NULL;
957
usb_dev->wusb_dev = NULL;
958
wusb_dev_put(wusb_dev);
959
usb_put_dev(usb_dev);
963
* Handle notifications from the USB stack (notifier call back)
965
* This is called when the USB stack does a
966
* usb_{bus,device}_{add,remove}() so we can do WUSB specific
967
* handling. It is called with [for the case of
968
* USB_DEVICE_{ADD,REMOVE} with the usb_dev locked.
970
int wusb_usb_ncb(struct notifier_block *nb, unsigned long val,
973
int result = NOTIFY_OK;
977
wusb_dev_add_ncb(priv);
979
case USB_DEVICE_REMOVE:
980
wusb_dev_rm_ncb(priv);
983
/* ignore (for now) */
994
* Return a referenced wusb_dev given a @wusbhc and @usb_dev
996
struct wusb_dev *__wusb_dev_get_by_usb_dev(struct wusbhc *wusbhc,
997
struct usb_device *usb_dev)
999
struct wusb_dev *wusb_dev;
1002
port_idx = wusb_port_no_to_idx(usb_dev->portnum);
1003
BUG_ON(port_idx > wusbhc->ports_max);
1004
wusb_dev = wusb_port_by_idx(wusbhc, port_idx)->wusb_dev;
1005
if (wusb_dev != NULL) /* ops, device is gone */
1006
wusb_dev_get(wusb_dev);
1009
EXPORT_SYMBOL_GPL(__wusb_dev_get_by_usb_dev);
1011
void wusb_dev_destroy(struct kref *_wusb_dev)
1013
struct wusb_dev *wusb_dev = container_of(_wusb_dev, struct wusb_dev, refcnt);
1015
list_del_init(&wusb_dev->cack_node);
1016
wusb_dev_free(wusb_dev);
1018
EXPORT_SYMBOL_GPL(wusb_dev_destroy);
1021
* Create all the device connect handling infrastructure
1023
* This is basically the device info array, Connect Acknowledgement
1024
* (cack) lists, keep-alive timers (and delayed work thread).
1026
int wusbhc_devconnect_create(struct wusbhc *wusbhc)
1028
wusbhc->keep_alive_ie.hdr.bIEIdentifier = WUIE_ID_KEEP_ALIVE;
1029
wusbhc->keep_alive_ie.hdr.bLength = sizeof(wusbhc->keep_alive_ie.hdr);
1030
INIT_DELAYED_WORK(&wusbhc->keep_alive_timer, wusbhc_keep_alive_run);
1032
wusbhc->cack_ie.hdr.bIEIdentifier = WUIE_ID_CONNECTACK;
1033
wusbhc->cack_ie.hdr.bLength = sizeof(wusbhc->cack_ie.hdr);
1034
INIT_LIST_HEAD(&wusbhc->cack_list);
1040
* Release all resources taken by the devconnect stuff
1042
void wusbhc_devconnect_destroy(struct wusbhc *wusbhc)
1048
* wusbhc_devconnect_start - start accepting device connections
1049
* @wusbhc: the WUSB HC
1051
* Sets the Host Info IE to accept all new connections.
1053
* FIXME: This also enables the keep alives but this is not necessary
1054
* until there are connected and authenticated devices.
1056
int wusbhc_devconnect_start(struct wusbhc *wusbhc)
1058
struct device *dev = wusbhc->dev;
1059
struct wuie_host_info *hi;
1062
hi = kzalloc(sizeof(*hi), GFP_KERNEL);
1066
hi->hdr.bLength = sizeof(*hi);
1067
hi->hdr.bIEIdentifier = WUIE_ID_HOST_INFO;
1068
hi->attributes = cpu_to_le16((wusbhc->rsv->stream << 3) | WUIE_HI_CAP_ALL);
1069
hi->CHID = wusbhc->chid;
1070
result = wusbhc_mmcie_set(wusbhc, 0, 0, &hi->hdr);
1072
dev_err(dev, "Cannot add Host Info MMCIE: %d\n", result);
1073
goto error_mmcie_set;
1075
wusbhc->wuie_host_info = hi;
1077
queue_delayed_work(wusbd, &wusbhc->keep_alive_timer,
1078
(wusbhc->trust_timeout*CONFIG_HZ)/1000/2);
1088
* wusbhc_devconnect_stop - stop managing connected devices
1089
* @wusbhc: the WUSB HC
1091
* Disconnects any devices still connected, stops the keep alives and
1092
* removes the Host Info IE.
1094
void wusbhc_devconnect_stop(struct wusbhc *wusbhc)
1098
mutex_lock(&wusbhc->mutex);
1099
for (i = 0; i < wusbhc->ports_max; i++) {
1100
if (wusbhc->port[i].wusb_dev)
1101
__wusbhc_dev_disconnect(wusbhc, &wusbhc->port[i]);
1103
mutex_unlock(&wusbhc->mutex);
1105
cancel_delayed_work_sync(&wusbhc->keep_alive_timer);
1106
wusbhc_mmcie_rm(wusbhc, &wusbhc->wuie_host_info->hdr);
1107
kfree(wusbhc->wuie_host_info);
1108
wusbhc->wuie_host_info = NULL;
1112
* wusb_set_dev_addr - set the WUSB device address used by the host
1113
* @wusbhc: the WUSB HC the device is connect to
1114
* @wusb_dev: the WUSB device
1115
* @addr: new device address
1117
int wusb_set_dev_addr(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev, u8 addr)
1121
wusb_dev->addr = addr;
1122
result = wusbhc->dev_info_set(wusbhc, wusb_dev);
1124
dev_err(wusbhc->dev, "device %d: failed to set device "
1125
"address\n", wusb_dev->port_idx);
1127
dev_info(wusbhc->dev, "device %d: %s addr %u\n",
1129
(addr & WUSB_DEV_ADDR_UNAUTH) ? "unauth" : "auth",