• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/drivers/usb/wusbcore/
1
2
3#include <linux/jiffies.h>
4#include <linux/ctype.h>
5#include <linux/slab.h>
6#include <linux/workqueue.h>
7#include "wusbhc.h"
8
9static void wusbhc_devconnect_acked_work(struct work_struct *work);
10
11static void wusb_dev_free(struct wusb_dev *wusb_dev)
12{
13	if (wusb_dev) {
14		kfree(wusb_dev->set_gtk_req);
15		usb_free_urb(wusb_dev->set_gtk_urb);
16		kfree(wusb_dev);
17	}
18}
19
20static struct wusb_dev *wusb_dev_alloc(struct wusbhc *wusbhc)
21{
22	struct wusb_dev *wusb_dev;
23	struct urb *urb;
24	struct usb_ctrlrequest *req;
25
26	wusb_dev = kzalloc(sizeof(*wusb_dev), GFP_KERNEL);
27	if (wusb_dev == NULL)
28		goto err;
29
30	wusb_dev->wusbhc = wusbhc;
31
32	INIT_WORK(&wusb_dev->devconnect_acked_work, wusbhc_devconnect_acked_work);
33
34	urb = usb_alloc_urb(0, GFP_KERNEL);
35	if (urb == NULL)
36		goto err;
37	wusb_dev->set_gtk_urb = urb;
38
39	req = kmalloc(sizeof(*req), GFP_KERNEL);
40	if (req == NULL)
41		goto err;
42	wusb_dev->set_gtk_req = req;
43
44	req->bRequestType = USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE;
45	req->bRequest = USB_REQ_SET_DESCRIPTOR;
46	req->wValue = cpu_to_le16(USB_DT_KEY << 8 | wusbhc->gtk_index);
47	req->wIndex = 0;
48	req->wLength = cpu_to_le16(wusbhc->gtk.descr.bLength);
49
50	return wusb_dev;
51err:
52	wusb_dev_free(wusb_dev);
53	return NULL;
54}
55
56
57/*
58 * Using the Connect-Ack list, fill out the @wusbhc Connect-Ack WUSB IE
59 * properly so that it can be added to the MMC.
60 *
61 * We just get the @wusbhc->ca_list and fill out the first four ones or
62 * less (per-spec WUSB1.0[7.5, before T7-38). If the ConnectAck WUSB
63 * IE is not allocated, we alloc it.
64 *
65 * @wusbhc->mutex must be taken
66 */
67static void wusbhc_fill_cack_ie(struct wusbhc *wusbhc)
68{
69	unsigned cnt;
70	struct wusb_dev *dev_itr;
71	struct wuie_connect_ack *cack_ie;
72
73	cack_ie = &wusbhc->cack_ie;
74	cnt = 0;
75	list_for_each_entry(dev_itr, &wusbhc->cack_list, cack_node) {
76		cack_ie->blk[cnt].CDID = dev_itr->cdid;
77		cack_ie->blk[cnt].bDeviceAddress = dev_itr->addr;
78		if (++cnt >= WUIE_ELT_MAX)
79			break;
80	}
81	cack_ie->hdr.bLength = sizeof(cack_ie->hdr)
82		+ cnt * sizeof(cack_ie->blk[0]);
83}
84
85/*
86 * Register a new device that wants to connect
87 *
88 * A new device wants to connect, so we add it to the Connect-Ack
89 * list. We give it an address in the unauthorized range (bit 8 set);
90 * user space will have to drive authorization further on.
91 *
92 * @dev_addr: address to use for the device (which is also the port
93 *            number).
94 *
95 * @wusbhc->mutex must be taken
96 */
97static struct wusb_dev *wusbhc_cack_add(struct wusbhc *wusbhc,
98					struct wusb_dn_connect *dnc,
99					const char *pr_cdid, u8 port_idx)
100{
101	struct device *dev = wusbhc->dev;
102	struct wusb_dev *wusb_dev;
103	int new_connection = wusb_dn_connect_new_connection(dnc);
104	u8 dev_addr;
105	int result;
106
107	/* Is it registered already? */
108	list_for_each_entry(wusb_dev, &wusbhc->cack_list, cack_node)
109		if (!memcmp(&wusb_dev->cdid, &dnc->CDID,
110			    sizeof(wusb_dev->cdid)))
111			return wusb_dev;
112	/* We don't have it, create an entry, register it */
113	wusb_dev = wusb_dev_alloc(wusbhc);
114	if (wusb_dev == NULL)
115		return NULL;
116	wusb_dev_init(wusb_dev);
117	wusb_dev->cdid = dnc->CDID;
118	wusb_dev->port_idx = port_idx;
119
120	/*
121	 * Devices are always available within the cluster reservation
122	 * and since the hardware will take the intersection of the
123	 * per-device availability and the cluster reservation, the
124	 * per-device availability can simply be set to always
125	 * available.
126	 */
127	bitmap_fill(wusb_dev->availability.bm, UWB_NUM_MAS);
128
129	if (1 && new_connection == 0)
130		new_connection = 1;
131	if (new_connection) {
132		dev_addr = (port_idx + 2) | WUSB_DEV_ADDR_UNAUTH;
133
134		dev_info(dev, "Connecting new WUSB device to address %u, "
135			"port %u\n", dev_addr, port_idx);
136
137		result = wusb_set_dev_addr(wusbhc, wusb_dev, dev_addr);
138		if (result < 0)
139			return NULL;
140	}
141	wusb_dev->entry_ts = jiffies;
142	list_add_tail(&wusb_dev->cack_node, &wusbhc->cack_list);
143	wusbhc->cack_count++;
144	wusbhc_fill_cack_ie(wusbhc);
145
146	return wusb_dev;
147}
148
149/*
150 * Remove a Connect-Ack context entry from the HCs view
151 *
152 * @wusbhc->mutex must be taken
153 */
154static void wusbhc_cack_rm(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
155{
156	list_del_init(&wusb_dev->cack_node);
157	wusbhc->cack_count--;
158	wusbhc_fill_cack_ie(wusbhc);
159}
160
161/*
162 * @wusbhc->mutex must be taken */
163static
164void wusbhc_devconnect_acked(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
165{
166	wusbhc_cack_rm(wusbhc, wusb_dev);
167	if (wusbhc->cack_count)
168		wusbhc_mmcie_set(wusbhc, 0, 0, &wusbhc->cack_ie.hdr);
169	else
170		wusbhc_mmcie_rm(wusbhc, &wusbhc->cack_ie.hdr);
171}
172
173static void wusbhc_devconnect_acked_work(struct work_struct *work)
174{
175	struct wusb_dev *wusb_dev = container_of(work, struct wusb_dev,
176						 devconnect_acked_work);
177	struct wusbhc *wusbhc = wusb_dev->wusbhc;
178
179	mutex_lock(&wusbhc->mutex);
180	wusbhc_devconnect_acked(wusbhc, wusb_dev);
181	mutex_unlock(&wusbhc->mutex);
182
183	wusb_dev_put(wusb_dev);
184}
185
186static
187void wusbhc_devconnect_ack(struct wusbhc *wusbhc, struct wusb_dn_connect *dnc,
188			   const char *pr_cdid)
189{
190	int result;
191	struct device *dev = wusbhc->dev;
192	struct wusb_dev *wusb_dev;
193	struct wusb_port *port;
194	unsigned idx, devnum;
195
196	mutex_lock(&wusbhc->mutex);
197
198	/* Check we are not handling it already */
199	for (idx = 0; idx < wusbhc->ports_max; idx++) {
200		port = wusb_port_by_idx(wusbhc, idx);
201		if (port->wusb_dev
202		    && memcmp(&dnc->CDID, &port->wusb_dev->cdid, sizeof(dnc->CDID)) == 0)
203			goto error_unlock;
204	}
205	/* Look up those fake ports we have for a free one */
206	for (idx = 0; idx < wusbhc->ports_max; idx++) {
207		port = wusb_port_by_idx(wusbhc, idx);
208		if ((port->status & USB_PORT_STAT_POWER)
209		    && !(port->status & USB_PORT_STAT_CONNECTION))
210			break;
211	}
212	if (idx >= wusbhc->ports_max) {
213		dev_err(dev, "Host controller can't connect more devices "
214			"(%u already connected); device %s rejected\n",
215			wusbhc->ports_max, pr_cdid);
216		/* NOTE: we could send a WUIE_Disconnect here, but we haven't
217		 *       event acked, so the device will eventually timeout the
218		 *       connection, right? */
219		goto error_unlock;
220	}
221
222	devnum = idx + 2;
223
224	/* Make sure we are using no crypto on that "virtual port" */
225	wusbhc->set_ptk(wusbhc, idx, 0, NULL, 0);
226
227	/* Grab a filled in Connect-Ack context, fill out the
228	 * Connect-Ack Wireless USB IE, set the MMC */
229	wusb_dev = wusbhc_cack_add(wusbhc, dnc, pr_cdid, idx);
230	if (wusb_dev == NULL)
231		goto error_unlock;
232	result = wusbhc_mmcie_set(wusbhc, 0, 0, &wusbhc->cack_ie.hdr);
233	if (result < 0)
234		goto error_unlock;
235	/* Give the device at least 2ms (WUSB1.0[7.5.1p3]), let's do
236	 * three for a good measure */
237	msleep(3);
238	port->wusb_dev = wusb_dev;
239	port->status |= USB_PORT_STAT_CONNECTION;
240	port->change |= USB_PORT_STAT_C_CONNECTION;
241	/* Now the port status changed to connected; khubd will
242	 * pick the change up and try to reset the port to bring it to
243	 * the enabled state--so this process returns up to the stack
244	 * and it calls back into wusbhc_rh_port_reset().
245	 */
246error_unlock:
247	mutex_unlock(&wusbhc->mutex);
248	return;
249
250}
251
252/*
253 * Disconnect a Wireless USB device from its fake port
254 *
255 * Marks the port as disconnected so that khubd can pick up the change
256 * and drops our knowledge about the device.
257 *
258 * Assumes there is a device connected
259 *
260 * @port_index: zero based port number
261 *
262 * NOTE: @wusbhc->mutex is locked
263 *
264 * WARNING: From here it is not very safe to access anything hanging off
265 *	    wusb_dev
266 */
267static void __wusbhc_dev_disconnect(struct wusbhc *wusbhc,
268				    struct wusb_port *port)
269{
270	struct wusb_dev *wusb_dev = port->wusb_dev;
271
272	port->status &= ~(USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE
273			  | USB_PORT_STAT_SUSPEND | USB_PORT_STAT_RESET
274			  | USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED);
275	port->change |= USB_PORT_STAT_C_CONNECTION | USB_PORT_STAT_C_ENABLE;
276	if (wusb_dev) {
277		dev_dbg(wusbhc->dev, "disconnecting device from port %d\n", wusb_dev->port_idx);
278		if (!list_empty(&wusb_dev->cack_node))
279			list_del_init(&wusb_dev->cack_node);
280		/* For the one in cack_add() */
281		wusb_dev_put(wusb_dev);
282	}
283	port->wusb_dev = NULL;
284
285	/* After a device disconnects, change the GTK (see [WUSB]
286	 * section 6.2.11.2). */
287	if (wusbhc->active)
288		wusbhc_gtk_rekey(wusbhc);
289
290	/* The Wireless USB part has forgotten about the device already; now
291	 * khubd's timer will pick up the disconnection and remove the USB
292	 * device from the system
293	 */
294}
295
296static void __wusbhc_keep_alive(struct wusbhc *wusbhc)
297{
298	struct device *dev = wusbhc->dev;
299	unsigned cnt;
300	struct wusb_dev *wusb_dev;
301	struct wusb_port *wusb_port;
302	struct wuie_keep_alive *ie = &wusbhc->keep_alive_ie;
303	unsigned keep_alives, old_keep_alives;
304
305	old_keep_alives = ie->hdr.bLength - sizeof(ie->hdr);
306	keep_alives = 0;
307	for (cnt = 0;
308	     keep_alives < WUIE_ELT_MAX && cnt < wusbhc->ports_max;
309	     cnt++) {
310		unsigned tt = msecs_to_jiffies(wusbhc->trust_timeout);
311
312		wusb_port = wusb_port_by_idx(wusbhc, cnt);
313		wusb_dev = wusb_port->wusb_dev;
314
315		if (wusb_dev == NULL)
316			continue;
317		if (wusb_dev->usb_dev == NULL || !wusb_dev->usb_dev->authenticated)
318			continue;
319
320		if (time_after(jiffies, wusb_dev->entry_ts + tt)) {
321			dev_err(dev, "KEEPALIVE: device %u timed out\n",
322				wusb_dev->addr);
323			__wusbhc_dev_disconnect(wusbhc, wusb_port);
324		} else if (time_after(jiffies, wusb_dev->entry_ts + tt/2)) {
325			/* Approaching timeout cut out, need to refresh */
326			ie->bDeviceAddress[keep_alives++] = wusb_dev->addr;
327		}
328	}
329	if (keep_alives & 0x1)	/* pad to even number ([WUSB] section 7.5.9) */
330		ie->bDeviceAddress[keep_alives++] = 0x7f;
331	ie->hdr.bLength = sizeof(ie->hdr) +
332		keep_alives*sizeof(ie->bDeviceAddress[0]);
333	if (keep_alives > 0)
334		wusbhc_mmcie_set(wusbhc, 10, 5, &ie->hdr);
335	else if (old_keep_alives != 0)
336		wusbhc_mmcie_rm(wusbhc, &ie->hdr);
337}
338
339/*
340 * Do a run through all devices checking for timeouts
341 */
342static void wusbhc_keep_alive_run(struct work_struct *ws)
343{
344	struct delayed_work *dw = to_delayed_work(ws);
345	struct wusbhc *wusbhc =	container_of(dw, struct wusbhc, keep_alive_timer);
346
347	mutex_lock(&wusbhc->mutex);
348	__wusbhc_keep_alive(wusbhc);
349	mutex_unlock(&wusbhc->mutex);
350
351	queue_delayed_work(wusbd, &wusbhc->keep_alive_timer,
352			   msecs_to_jiffies(wusbhc->trust_timeout / 2));
353}
354
355/*
356 * Find the wusb_dev from its device address.
357 *
358 * The device can be found directly from the address (see
359 * wusb_cack_add() for where the device address is set to port_idx
360 * +2), except when the address is zero.
361 */
362static struct wusb_dev *wusbhc_find_dev_by_addr(struct wusbhc *wusbhc, u8 addr)
363{
364	int p;
365
366	if (addr == 0xff) /* unconnected */
367		return NULL;
368
369	if (addr > 0) {
370		int port = (addr & ~0x80) - 2;
371		if (port < 0 || port >= wusbhc->ports_max)
372			return NULL;
373		return wusb_port_by_idx(wusbhc, port)->wusb_dev;
374	}
375
376	/* Look for the device with address 0. */
377	for (p = 0; p < wusbhc->ports_max; p++) {
378		struct wusb_dev *wusb_dev = wusb_port_by_idx(wusbhc, p)->wusb_dev;
379		if (wusb_dev && wusb_dev->addr == addr)
380			return wusb_dev;
381	}
382	return NULL;
383}
384
385/*
386 * Handle a DN_Alive notification (WUSB1.0[7.6.1])
387 *
388 * This just updates the device activity timestamp and then refreshes
389 * the keep alive IE.
390 *
391 * @wusbhc shall be referenced and unlocked
392 */
393static void wusbhc_handle_dn_alive(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
394{
395	mutex_lock(&wusbhc->mutex);
396	wusb_dev->entry_ts = jiffies;
397	__wusbhc_keep_alive(wusbhc);
398	mutex_unlock(&wusbhc->mutex);
399}
400
401/*
402 * Handle a DN_Connect notification (WUSB1.0[7.6.1])
403 *
404 * @wusbhc
405 * @pkt_hdr
406 * @size:    Size of the buffer where the notification resides; if the
407 *           notification data suggests there should be more data than
408 *           available, an error will be signaled and the whole buffer
409 *           consumed.
410 *
411 * @wusbhc->mutex shall be held
412 */
413static void wusbhc_handle_dn_connect(struct wusbhc *wusbhc,
414				     struct wusb_dn_hdr *dn_hdr,
415				     size_t size)
416{
417	struct device *dev = wusbhc->dev;
418	struct wusb_dn_connect *dnc;
419	char pr_cdid[WUSB_CKHDID_STRSIZE];
420	static const char *beacon_behaviour[] = {
421		"reserved",
422		"self-beacon",
423		"directed-beacon",
424		"no-beacon"
425	};
426
427	if (size < sizeof(*dnc)) {
428		dev_err(dev, "DN CONNECT: short notification (%zu < %zu)\n",
429			size, sizeof(*dnc));
430		return;
431	}
432
433	dnc = container_of(dn_hdr, struct wusb_dn_connect, hdr);
434	ckhdid_printf(pr_cdid, sizeof(pr_cdid), &dnc->CDID);
435	dev_info(dev, "DN CONNECT: device %s @ %x (%s) wants to %s\n",
436		 pr_cdid,
437		 wusb_dn_connect_prev_dev_addr(dnc),
438		 beacon_behaviour[wusb_dn_connect_beacon_behavior(dnc)],
439		 wusb_dn_connect_new_connection(dnc) ? "connect" : "reconnect");
440	/* ACK the connect */
441	wusbhc_devconnect_ack(wusbhc, dnc, pr_cdid);
442}
443
444/*
445 * Handle a DN_Disconnect notification (WUSB1.0[7.6.1])
446 *
447 * Device is going down -- do the disconnect.
448 *
449 * @wusbhc shall be referenced and unlocked
450 */
451static void wusbhc_handle_dn_disconnect(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
452{
453	struct device *dev = wusbhc->dev;
454
455	dev_info(dev, "DN DISCONNECT: device 0x%02x going down\n", wusb_dev->addr);
456
457	mutex_lock(&wusbhc->mutex);
458	__wusbhc_dev_disconnect(wusbhc, wusb_port_by_idx(wusbhc, wusb_dev->port_idx));
459	mutex_unlock(&wusbhc->mutex);
460}
461
462/*
463 * Handle a Device Notification coming a host
464 *
465 * The Device Notification comes from a host (HWA, DWA or WHCI)
466 * wrapped in a set of headers. Somebody else has peeled off those
467 * headers for us and we just get one Device Notifications.
468 *
469 * Invalid DNs (e.g., too short) are discarded.
470 *
471 * @wusbhc shall be referenced
472 *
473 * FIXMES:
474 *  - implement priorities as in WUSB1.0[Table 7-55]?
475 */
476void wusbhc_handle_dn(struct wusbhc *wusbhc, u8 srcaddr,
477		      struct wusb_dn_hdr *dn_hdr, size_t size)
478{
479	struct device *dev = wusbhc->dev;
480	struct wusb_dev *wusb_dev;
481
482	if (size < sizeof(struct wusb_dn_hdr)) {
483		dev_err(dev, "DN data shorter than DN header (%d < %d)\n",
484			(int)size, (int)sizeof(struct wusb_dn_hdr));
485		return;
486	}
487
488	wusb_dev = wusbhc_find_dev_by_addr(wusbhc, srcaddr);
489	if (wusb_dev == NULL && dn_hdr->bType != WUSB_DN_CONNECT) {
490		dev_dbg(dev, "ignoring DN %d from unconnected device %02x\n",
491			dn_hdr->bType, srcaddr);
492		return;
493	}
494
495	switch (dn_hdr->bType) {
496	case WUSB_DN_CONNECT:
497		wusbhc_handle_dn_connect(wusbhc, dn_hdr, size);
498		break;
499	case WUSB_DN_ALIVE:
500		wusbhc_handle_dn_alive(wusbhc, wusb_dev);
501		break;
502	case WUSB_DN_DISCONNECT:
503		wusbhc_handle_dn_disconnect(wusbhc, wusb_dev);
504		break;
505	case WUSB_DN_MASAVAILCHANGED:
506	case WUSB_DN_RWAKE:
507	case WUSB_DN_SLEEP:
508		break;
509	case WUSB_DN_EPRDY:
510		/* The hardware handles these. */
511		break;
512	default:
513		dev_warn(dev, "unknown DN %u (%d octets) from %u\n",
514			 dn_hdr->bType, (int)size, srcaddr);
515	}
516}
517EXPORT_SYMBOL_GPL(wusbhc_handle_dn);
518
519/*
520 * Disconnect a WUSB device from a the cluster
521 *
522 * @wusbhc
523 * @port     Fake port where the device is (wusbhc index, not USB port number).
524 *
525 * In Wireless USB, a disconnect is basically telling the device he is
526 * being disconnected and forgetting about him.
527 *
528 * We send the device a Device Disconnect IE (WUSB1.0[7.5.11]) for 100
529 * ms and then keep going.
530 *
531 * We don't do much in case of error; we always pretend we disabled
532 * the port and disconnected the device. If physically the request
533 * didn't get there (many things can fail in the way there), the stack
534 * will reject the device's communication attempts.
535 *
536 * @wusbhc should be refcounted and locked
537 */
538void __wusbhc_dev_disable(struct wusbhc *wusbhc, u8 port_idx)
539{
540	int result;
541	struct device *dev = wusbhc->dev;
542	struct wusb_dev *wusb_dev;
543	struct wuie_disconnect *ie;
544
545	wusb_dev = wusb_port_by_idx(wusbhc, port_idx)->wusb_dev;
546	if (wusb_dev == NULL) {
547		/* reset no device? ignore */
548		dev_dbg(dev, "DISCONNECT: no device at port %u, ignoring\n",
549			port_idx);
550		return;
551	}
552	__wusbhc_dev_disconnect(wusbhc, wusb_port_by_idx(wusbhc, port_idx));
553
554	ie = kzalloc(sizeof(*ie), GFP_KERNEL);
555	if (ie == NULL)
556		return;
557	ie->hdr.bLength = sizeof(*ie);
558	ie->hdr.bIEIdentifier = WUIE_ID_DEVICE_DISCONNECT;
559	ie->bDeviceAddress = wusb_dev->addr;
560	result = wusbhc_mmcie_set(wusbhc, 0, 0, &ie->hdr);
561	if (result < 0)
562		dev_err(dev, "DISCONNECT: can't set MMC: %d\n", result);
563	else {
564		/* At least 6 MMCs, assuming at least 1 MMC per zone. */
565		msleep(7*4);
566		wusbhc_mmcie_rm(wusbhc, &ie->hdr);
567	}
568	kfree(ie);
569}
570
571/*
572 * Walk over the BOS descriptor, verify and grok it
573 *
574 * @usb_dev: referenced
575 * @wusb_dev: referenced and unlocked
576 *
577 * The BOS descriptor is defined at WUSB1.0[7.4.1], and it defines a
578 * "flexible" way to wrap all kinds of descriptors inside an standard
579 * descriptor (wonder why they didn't use normal descriptors,
580 * btw). Not like they lack code.
581 *
582 * At the end we go to look for the WUSB Device Capabilities
583 * (WUSB1.0[7.4.1.1]) that is wrapped in a device capability descriptor
584 * that is part of the BOS descriptor set. That tells us what does the
585 * device support (dual role, beacon type, UWB PHY rates).
586 */
587static int wusb_dev_bos_grok(struct usb_device *usb_dev,
588			     struct wusb_dev *wusb_dev,
589			     struct usb_bos_descriptor *bos, size_t desc_size)
590{
591	ssize_t result;
592	struct device *dev = &usb_dev->dev;
593	void *itr, *top;
594
595	/* Walk over BOS capabilities, verify them */
596	itr = (void *)bos + sizeof(*bos);
597	top = itr + desc_size - sizeof(*bos);
598	while (itr < top) {
599		struct usb_dev_cap_header *cap_hdr = itr;
600		size_t cap_size;
601		u8 cap_type;
602		if (top - itr < sizeof(*cap_hdr)) {
603			dev_err(dev, "Device BUG? premature end of BOS header "
604				"data [offset 0x%02x]: only %zu bytes left\n",
605				(int)(itr - (void *)bos), top - itr);
606			result = -ENOSPC;
607			goto error_bad_cap;
608		}
609		cap_size = cap_hdr->bLength;
610		cap_type = cap_hdr->bDevCapabilityType;
611		if (cap_size == 0)
612			break;
613		if (cap_size > top - itr) {
614			dev_err(dev, "Device BUG? premature end of BOS data "
615				"[offset 0x%02x cap %02x %zu bytes]: "
616				"only %zu bytes left\n",
617				(int)(itr - (void *)bos),
618				cap_type, cap_size, top - itr);
619			result = -EBADF;
620			goto error_bad_cap;
621		}
622		switch (cap_type) {
623		case USB_CAP_TYPE_WIRELESS_USB:
624			if (cap_size != sizeof(*wusb_dev->wusb_cap_descr))
625				dev_err(dev, "Device BUG? WUSB Capability "
626					"descriptor is %zu bytes vs %zu "
627					"needed\n", cap_size,
628					sizeof(*wusb_dev->wusb_cap_descr));
629			else
630				wusb_dev->wusb_cap_descr = itr;
631			break;
632		default:
633			dev_err(dev, "BUG? Unknown BOS capability 0x%02x "
634				"(%zu bytes) at offset 0x%02x\n", cap_type,
635				cap_size, (int)(itr - (void *)bos));
636		}
637		itr += cap_size;
638	}
639	result = 0;
640error_bad_cap:
641	return result;
642}
643
644/*
645 * Add information from the BOS descriptors to the device
646 *
647 * @usb_dev: referenced
648 * @wusb_dev: referenced and unlocked
649 *
650 * So what we do is we alloc a space for the BOS descriptor of 64
651 * bytes; read the first four bytes which include the wTotalLength
652 * field (WUSB1.0[T7-26]) and if it fits in those 64 bytes, read the
653 * whole thing. If not we realloc to that size.
654 *
655 * Then we call the groking function, that will fill up
656 * wusb_dev->wusb_cap_descr, which is what we'll need later on.
657 */
658static int wusb_dev_bos_add(struct usb_device *usb_dev,
659			    struct wusb_dev *wusb_dev)
660{
661	ssize_t result;
662	struct device *dev = &usb_dev->dev;
663	struct usb_bos_descriptor *bos;
664	size_t alloc_size = 32, desc_size = 4;
665
666	bos = kmalloc(alloc_size, GFP_KERNEL);
667	if (bos == NULL)
668		return -ENOMEM;
669	result = usb_get_descriptor(usb_dev, USB_DT_BOS, 0, bos, desc_size);
670	if (result < 4) {
671		dev_err(dev, "Can't get BOS descriptor or too short: %zd\n",
672			result);
673		goto error_get_descriptor;
674	}
675	desc_size = le16_to_cpu(bos->wTotalLength);
676	if (desc_size >= alloc_size) {
677		kfree(bos);
678		alloc_size = desc_size;
679		bos = kmalloc(alloc_size, GFP_KERNEL);
680		if (bos == NULL)
681			return -ENOMEM;
682	}
683	result = usb_get_descriptor(usb_dev, USB_DT_BOS, 0, bos, desc_size);
684	if (result < 0 || result != desc_size) {
685		dev_err(dev, "Can't get  BOS descriptor or too short (need "
686			"%zu bytes): %zd\n", desc_size, result);
687		goto error_get_descriptor;
688	}
689	if (result < sizeof(*bos)
690	    || le16_to_cpu(bos->wTotalLength) != desc_size) {
691		dev_err(dev, "Can't get  BOS descriptor or too short (need "
692			"%zu bytes): %zd\n", desc_size, result);
693		goto error_get_descriptor;
694	}
695
696	result = wusb_dev_bos_grok(usb_dev, wusb_dev, bos, result);
697	if (result < 0)
698		goto error_bad_bos;
699	wusb_dev->bos = bos;
700	return 0;
701
702error_bad_bos:
703error_get_descriptor:
704	kfree(bos);
705	wusb_dev->wusb_cap_descr = NULL;
706	return result;
707}
708
709static void wusb_dev_bos_rm(struct wusb_dev *wusb_dev)
710{
711	kfree(wusb_dev->bos);
712	wusb_dev->wusb_cap_descr = NULL;
713};
714
715static struct usb_wireless_cap_descriptor wusb_cap_descr_default = {
716	.bLength = sizeof(wusb_cap_descr_default),
717	.bDescriptorType = USB_DT_DEVICE_CAPABILITY,
718	.bDevCapabilityType = USB_CAP_TYPE_WIRELESS_USB,
719
720	.bmAttributes = USB_WIRELESS_BEACON_NONE,
721	.wPHYRates = cpu_to_le16(USB_WIRELESS_PHY_53),
722	.bmTFITXPowerInfo = 0,
723	.bmFFITXPowerInfo = 0,
724	.bmBandGroup = cpu_to_le16(0x0001),	/* WUSB1.0[7.4.1] bottom */
725	.bReserved = 0
726};
727
728static void wusb_dev_add_ncb(struct usb_device *usb_dev)
729{
730	int result = 0;
731	struct wusb_dev *wusb_dev;
732	struct wusbhc *wusbhc;
733	struct device *dev = &usb_dev->dev;
734	u8 port_idx;
735
736	if (usb_dev->wusb == 0 || usb_dev->devnum == 1)
737		return;		/* skip non wusb and wusb RHs */
738
739	usb_set_device_state(usb_dev, USB_STATE_UNAUTHENTICATED);
740
741	wusbhc = wusbhc_get_by_usb_dev(usb_dev);
742	if (wusbhc == NULL)
743		goto error_nodev;
744	mutex_lock(&wusbhc->mutex);
745	wusb_dev = __wusb_dev_get_by_usb_dev(wusbhc, usb_dev);
746	port_idx = wusb_port_no_to_idx(usb_dev->portnum);
747	mutex_unlock(&wusbhc->mutex);
748	if (wusb_dev == NULL)
749		goto error_nodev;
750	wusb_dev->usb_dev = usb_get_dev(usb_dev);
751	usb_dev->wusb_dev = wusb_dev_get(wusb_dev);
752	result = wusb_dev_sec_add(wusbhc, usb_dev, wusb_dev);
753	if (result < 0) {
754		dev_err(dev, "Cannot enable security: %d\n", result);
755		goto error_sec_add;
756	}
757	/* Now query the device for it's BOS and attach it to wusb_dev */
758	result = wusb_dev_bos_add(usb_dev, wusb_dev);
759	if (result < 0) {
760		dev_err(dev, "Cannot get BOS descriptors: %d\n", result);
761		goto error_bos_add;
762	}
763	result = wusb_dev_sysfs_add(wusbhc, usb_dev, wusb_dev);
764	if (result < 0)
765		goto error_add_sysfs;
766out:
767	wusb_dev_put(wusb_dev);
768	wusbhc_put(wusbhc);
769error_nodev:
770	return;
771
772	wusb_dev_sysfs_rm(wusb_dev);
773error_add_sysfs:
774	wusb_dev_bos_rm(wusb_dev);
775error_bos_add:
776	wusb_dev_sec_rm(wusb_dev);
777error_sec_add:
778	mutex_lock(&wusbhc->mutex);
779	__wusbhc_dev_disconnect(wusbhc, wusb_port_by_idx(wusbhc, port_idx));
780	mutex_unlock(&wusbhc->mutex);
781	goto out;
782}
783
784/*
785 * Undo all the steps done at connection by the notifier callback
786 *
787 * NOTE: @usb_dev locked
788 */
789static void wusb_dev_rm_ncb(struct usb_device *usb_dev)
790{
791	struct wusb_dev *wusb_dev = usb_dev->wusb_dev;
792
793	if (usb_dev->wusb == 0 || usb_dev->devnum == 1)
794		return;		/* skip non wusb and wusb RHs */
795
796	wusb_dev_sysfs_rm(wusb_dev);
797	wusb_dev_bos_rm(wusb_dev);
798	wusb_dev_sec_rm(wusb_dev);
799	wusb_dev->usb_dev = NULL;
800	usb_dev->wusb_dev = NULL;
801	wusb_dev_put(wusb_dev);
802	usb_put_dev(usb_dev);
803}
804
805/*
806 * Handle notifications from the USB stack (notifier call back)
807 *
808 * This is called when the USB stack does a
809 * usb_{bus,device}_{add,remove}() so we can do WUSB specific
810 * handling. It is called with [for the case of
811 * USB_DEVICE_{ADD,REMOVE} with the usb_dev locked.
812 */
813int wusb_usb_ncb(struct notifier_block *nb, unsigned long val,
814		 void *priv)
815{
816	int result = NOTIFY_OK;
817
818	switch (val) {
819	case USB_DEVICE_ADD:
820		wusb_dev_add_ncb(priv);
821		break;
822	case USB_DEVICE_REMOVE:
823		wusb_dev_rm_ncb(priv);
824		break;
825	case USB_BUS_ADD:
826		/* ignore (for now) */
827	case USB_BUS_REMOVE:
828		break;
829	default:
830		WARN_ON(1);
831		result = NOTIFY_BAD;
832	};
833	return result;
834}
835
836/*
837 * Return a referenced wusb_dev given a @wusbhc and @usb_dev
838 */
839struct wusb_dev *__wusb_dev_get_by_usb_dev(struct wusbhc *wusbhc,
840					   struct usb_device *usb_dev)
841{
842	struct wusb_dev *wusb_dev;
843	u8 port_idx;
844
845	port_idx = wusb_port_no_to_idx(usb_dev->portnum);
846	BUG_ON(port_idx > wusbhc->ports_max);
847	wusb_dev = wusb_port_by_idx(wusbhc, port_idx)->wusb_dev;
848	if (wusb_dev != NULL)		/* ops, device is gone */
849		wusb_dev_get(wusb_dev);
850	return wusb_dev;
851}
852EXPORT_SYMBOL_GPL(__wusb_dev_get_by_usb_dev);
853
854void wusb_dev_destroy(struct kref *_wusb_dev)
855{
856	struct wusb_dev *wusb_dev = container_of(_wusb_dev, struct wusb_dev, refcnt);
857
858	list_del_init(&wusb_dev->cack_node);
859	wusb_dev_free(wusb_dev);
860}
861EXPORT_SYMBOL_GPL(wusb_dev_destroy);
862
863/*
864 * Create all the device connect handling infrastructure
865 *
866 * This is basically the device info array, Connect Acknowledgement
867 * (cack) lists, keep-alive timers (and delayed work thread).
868 */
869int wusbhc_devconnect_create(struct wusbhc *wusbhc)
870{
871	wusbhc->keep_alive_ie.hdr.bIEIdentifier = WUIE_ID_KEEP_ALIVE;
872	wusbhc->keep_alive_ie.hdr.bLength = sizeof(wusbhc->keep_alive_ie.hdr);
873	INIT_DELAYED_WORK(&wusbhc->keep_alive_timer, wusbhc_keep_alive_run);
874
875	wusbhc->cack_ie.hdr.bIEIdentifier = WUIE_ID_CONNECTACK;
876	wusbhc->cack_ie.hdr.bLength = sizeof(wusbhc->cack_ie.hdr);
877	INIT_LIST_HEAD(&wusbhc->cack_list);
878
879	return 0;
880}
881
882/*
883 * Release all resources taken by the devconnect stuff
884 */
885void wusbhc_devconnect_destroy(struct wusbhc *wusbhc)
886{
887	/* no op */
888}
889
890int wusbhc_devconnect_start(struct wusbhc *wusbhc)
891{
892	struct device *dev = wusbhc->dev;
893	struct wuie_host_info *hi;
894	int result;
895
896	hi = kzalloc(sizeof(*hi), GFP_KERNEL);
897	if (hi == NULL)
898		return -ENOMEM;
899
900	hi->hdr.bLength       = sizeof(*hi);
901	hi->hdr.bIEIdentifier = WUIE_ID_HOST_INFO;
902	hi->attributes        = cpu_to_le16((wusbhc->rsv->stream << 3) | WUIE_HI_CAP_ALL);
903	hi->CHID              = wusbhc->chid;
904	result = wusbhc_mmcie_set(wusbhc, 0, 0, &hi->hdr);
905	if (result < 0) {
906		dev_err(dev, "Cannot add Host Info MMCIE: %d\n", result);
907		goto error_mmcie_set;
908	}
909	wusbhc->wuie_host_info = hi;
910
911	queue_delayed_work(wusbd, &wusbhc->keep_alive_timer,
912			   (wusbhc->trust_timeout*CONFIG_HZ)/1000/2);
913
914	return 0;
915
916error_mmcie_set:
917	kfree(hi);
918	return result;
919}
920
921/*
922 * wusbhc_devconnect_stop - stop managing connected devices
923 * @wusbhc: the WUSB HC
924 *
925 * Disconnects any devices still connected, stops the keep alives and
926 * removes the Host Info IE.
927 */
928void wusbhc_devconnect_stop(struct wusbhc *wusbhc)
929{
930	int i;
931
932	mutex_lock(&wusbhc->mutex);
933	for (i = 0; i < wusbhc->ports_max; i++) {
934		if (wusbhc->port[i].wusb_dev)
935			__wusbhc_dev_disconnect(wusbhc, &wusbhc->port[i]);
936	}
937	mutex_unlock(&wusbhc->mutex);
938
939	cancel_delayed_work_sync(&wusbhc->keep_alive_timer);
940	wusbhc_mmcie_rm(wusbhc, &wusbhc->wuie_host_info->hdr);
941	kfree(wusbhc->wuie_host_info);
942	wusbhc->wuie_host_info = NULL;
943}
944
945/*
946 * wusb_set_dev_addr - set the WUSB device address used by the host
947 * @wusbhc: the WUSB HC the device is connect to
948 * @wusb_dev: the WUSB device
949 * @addr: new device address
950 */
951int wusb_set_dev_addr(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev, u8 addr)
952{
953	int result;
954
955	wusb_dev->addr = addr;
956	result = wusbhc->dev_info_set(wusbhc, wusb_dev);
957	if (result < 0)
958		dev_err(wusbhc->dev, "device %d: failed to set device "
959			"address\n", wusb_dev->port_idx);
960	else
961		dev_info(wusbhc->dev, "device %d: %s addr %u\n",
962			 wusb_dev->port_idx,
963			 (addr & WUSB_DEV_ADDR_UNAUTH) ? "unauth" : "auth",
964			 wusb_dev->addr);
965
966	return result;
967}
968