90 #include <linux/ctype.h>
91 #include <linux/slab.h>
93 #include <linux/export.h>
107 static struct wusb_dev *wusb_dev_alloc(
struct wusbhc *
wusbhc)
109 struct wusb_dev *wusb_dev;
113 wusb_dev = kzalloc(
sizeof(*wusb_dev),
GFP_KERNEL);
114 if (wusb_dev ==
NULL)
117 wusb_dev->
wusbhc = wusbhc;
139 wusb_dev_free(wusb_dev);
154 static void wusbhc_fill_cack_ie(
struct wusbhc *wusbhc)
157 struct wusb_dev *dev_itr;
164 cack_ie->
blk[
cnt].bDeviceAddress = dev_itr->
addr;
168 cack_ie->
hdr.bLength =
sizeof(cack_ie->
hdr)
169 + cnt *
sizeof(cack_ie->
blk[0]);
184 static struct wusb_dev *wusbhc_cack_add(
struct wusbhc *wusbhc,
189 struct wusb_dev *wusb_dev;
190 int new_connection = wusb_dn_connect_new_connection(dnc);
200 wusb_dev = wusb_dev_alloc(wusbhc);
203 wusb_dev_init(wusb_dev);
204 wusb_dev->cdid = dnc->CDID;
205 wusb_dev->port_idx = port_idx;
218 if (1 && new_connection == 0)
220 if (new_connection) {
223 dev_info(dev,
"Connecting new WUSB device to address %u, "
224 "port %u\n", dev_addr, port_idx);
232 wusbhc->cack_count++;
233 wusbhc_fill_cack_ie(wusbhc);
243 static void wusbhc_cack_rm(
struct wusbhc *wusbhc,
struct wusb_dev *wusb_dev)
247 wusbhc_fill_cack_ie(wusbhc);
253 void wusbhc_devconnect_acked(
struct wusbhc *wusbhc,
struct wusb_dev *wusb_dev)
255 wusbhc_cack_rm(wusbhc, wusb_dev);
264 struct wusb_dev *wusb_dev =
container_of(work,
struct wusb_dev,
266 struct wusbhc *wusbhc = wusb_dev->
wusbhc;
269 wusbhc_devconnect_acked(wusbhc, wusb_dev);
272 wusb_dev_put(wusb_dev);
302 void wusbhc_devconnect_ack(
struct wusbhc *wusbhc,
struct wusb_dn_connect *dnc,
307 struct wusb_dev *wusb_dev;
314 for (idx = 0; idx < wusbhc->
ports_max; idx++) {
315 port = wusb_port_by_idx(wusbhc, idx);
321 for (idx = 0; idx < wusbhc->
ports_max; idx++) {
322 port = wusb_port_by_idx(wusbhc, idx);
328 dev_err(dev,
"Host controller can't connect more devices "
329 "(%u already connected); device %s rejected\n",
344 wusb_dev = wusbhc_cack_add(wusbhc, dnc, pr_cdid, idx);
345 if (wusb_dev ==
NULL)
382 static void __wusbhc_dev_disconnect(
struct wusbhc *wusbhc,
385 struct wusb_dev *wusb_dev = port->
wusb_dev;
396 wusb_dev_put(wusb_dev);
430 static void __wusbhc_keep_alive(
struct wusbhc *wusbhc)
434 struct wusb_dev *wusb_dev;
437 unsigned keep_alives, old_keep_alives;
439 old_keep_alives = ie->
hdr.bLength -
sizeof(ie->
hdr);
446 wusb_port = wusb_port_by_idx(wusbhc, cnt);
449 if (wusb_dev ==
NULL)
455 dev_err(dev,
"KEEPALIVE: device %u timed out\n",
457 __wusbhc_dev_disconnect(wusbhc, wusb_port);
463 if (keep_alives & 0x1)
465 ie->
hdr.bLength =
sizeof(ie->
hdr) +
469 else if (old_keep_alives != 0)
482 __wusbhc_keep_alive(wusbhc);
496 static struct wusb_dev *wusbhc_find_dev_by_addr(
struct wusbhc *wusbhc,
u8 addr)
504 int port = (addr & ~0x80) - 2;
507 return wusb_port_by_idx(wusbhc, port)->wusb_dev;
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)
527 static void wusbhc_handle_dn_alive(
struct wusbhc *wusbhc,
struct wusb_dev *wusb_dev)
531 __wusbhc_keep_alive(wusbhc);
547 static void wusbhc_handle_dn_connect(
struct wusbhc *wusbhc,
554 static const char *beacon_behaviour[] = {
561 if (size <
sizeof(*dnc)) {
562 dev_err(dev,
"DN CONNECT: short notification (%zu < %zu)\n",
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");
575 wusbhc_devconnect_ack(wusbhc, dnc, pr_cdid);
585 static void wusbhc_handle_dn_disconnect(
struct wusbhc *wusbhc,
struct wusb_dev *wusb_dev)
589 dev_info(dev,
"DN DISCONNECT: device 0x%02x going down\n", wusb_dev->
addr);
592 __wusbhc_dev_disconnect(wusbhc, wusb_port_by_idx(wusbhc, wusb_dev->
port_idx));
614 struct wusb_dev *wusb_dev;
617 dev_err(dev,
"DN data shorter than DN header (%d < %d)\n",
622 wusb_dev = wusbhc_find_dev_by_addr(wusbhc, srcaddr);
624 dev_dbg(dev,
"ignoring DN %d from unconnected device %02x\n",
625 dn_hdr->
bType, srcaddr);
629 switch (dn_hdr->
bType) {
631 wusbhc_handle_dn_connect(wusbhc, dn_hdr, size);
634 wusbhc_handle_dn_alive(wusbhc, wusb_dev);
637 wusbhc_handle_dn_disconnect(wusbhc, wusb_dev);
648 dev_warn(dev,
"unknown DN %u (%d octets) from %u\n",
649 dn_hdr->
bType, (
int)size, srcaddr);
677 struct wusb_dev *wusb_dev;
680 wusb_dev = wusb_port_by_idx(wusbhc, port_idx)->wusb_dev;
681 if (wusb_dev ==
NULL) {
683 dev_dbg(dev,
"DISCONNECT: no device at port %u, ignoring\n",
687 __wusbhc_dev_disconnect(wusbhc, wusb_port_by_idx(wusbhc, port_idx));
692 ie->
hdr.bLength =
sizeof(*ie);
697 dev_err(dev,
"DISCONNECT: can't set MMC: %d\n", result);
722 static int wusb_dev_bos_grok(
struct usb_device *usb_dev,
723 struct wusb_dev *wusb_dev,
727 struct device *dev = &usb_dev->dev;
731 itr = (
void *)bos +
sizeof(*bos);
732 top = itr + desc_size -
sizeof(*bos);
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);
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);
760 dev_err(dev,
"Device BUG? WUSB Capability "
761 "descriptor is %zu bytes vs %zu "
762 "needed\n", cap_size,
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));
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;
799 size_t alloc_size = 32, desc_size = 4;
806 dev_err(dev,
"Can't get BOS descriptor or too short: %zd\n",
808 goto error_get_descriptor;
811 if (desc_size >= alloc_size) {
813 alloc_size = 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)
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:
844 static void wusb_dev_bos_rm(
struct wusb_dev *wusb_dev)
851 .bLength =
sizeof(wusb_cap_descr_default),
857 .bmTFITXPowerInfo = 0,
858 .bmFFITXPowerInfo = 0,
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)
898 wusbhc = wusbhc_get_by_usb_dev(usb_dev);
903 port_idx = wusb_port_no_to_idx(usb_dev->portnum);
905 if (wusb_dev ==
NULL)
908 usb_dev->wusb_dev = wusb_dev_get(wusb_dev);
911 dev_err(dev,
"Cannot enable security: %d\n", result);
915 result = wusb_dev_bos_add(usb_dev, wusb_dev);
917 dev_err(dev,
"Cannot get BOS descriptors: %d\n", result);
922 goto error_add_sysfs;
924 wusb_dev_put(wusb_dev);
931 wusb_dev_bos_rm(wusb_dev);
936 __wusbhc_dev_disconnect(wusbhc, wusb_port_by_idx(wusbhc, port_idx));
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)
954 wusb_dev_bos_rm(wusb_dev);
957 usb_dev->wusb_dev =
NULL;
958 wusb_dev_put(wusb_dev);
973 int result = NOTIFY_OK;
977 wusb_dev_add_ncb(priv);
979 case USB_DEVICE_REMOVE:
980 wusb_dev_rm_ncb(priv);
997 struct usb_device *usb_dev)
999 struct wusb_dev *wusb_dev;
1002 port_idx = wusb_port_no_to_idx(usb_dev->portnum);
1004 wusb_dev = wusb_port_by_idx(wusbhc, port_idx)->wusb_dev;
1005 if (wusb_dev !=
NULL)
1006 wusb_dev_get(wusb_dev);
1016 wusb_dev_free(wusb_dev);
1066 hi->
hdr.bLength =
sizeof(*hi);
1072 dev_err(dev,
"Cannot add Host Info MMCIE: %d\n", result);
1073 goto error_mmcie_set;
1099 for (i = 0; i < wusbhc->
ports_max; i++) {
1100 if (wusbhc->
port[i].wusb_dev)
1101 __wusbhc_dev_disconnect(wusbhc, &wusbhc->
port[i]);
1124 dev_err(wusbhc->
dev,
"device %d: failed to set device "