1019808f9SSimon Glass /* 2019808f9SSimon Glass * (C) Copyright 2015 Google, Inc 3019808f9SSimon Glass * Written by Simon Glass <sjg@chromium.org> 4019808f9SSimon Glass * 5019808f9SSimon Glass * SPDX-License-Identifier: GPL-2.0+ 6019808f9SSimon Glass */ 7019808f9SSimon Glass 8019808f9SSimon Glass #include <common.h> 9019808f9SSimon Glass #include <dm.h> 10019808f9SSimon Glass #include <usb.h> 11019808f9SSimon Glass #include <dm/device-internal.h> 12019808f9SSimon Glass 13019808f9SSimon Glass DECLARE_GLOBAL_DATA_PTR; 14019808f9SSimon Glass 15019808f9SSimon Glass static int copy_to_unicode(char *buff, int length, const char *str) 16019808f9SSimon Glass { 17019808f9SSimon Glass int ptr; 18019808f9SSimon Glass int i; 19019808f9SSimon Glass 20019808f9SSimon Glass if (length < 2) 21019808f9SSimon Glass return 0; 22019808f9SSimon Glass buff[1] = USB_DT_STRING; 23019808f9SSimon Glass for (ptr = 2, i = 0; ptr + 1 < length && *str; i++, ptr += 2) { 24019808f9SSimon Glass buff[ptr] = str[i]; 25019808f9SSimon Glass buff[ptr + 1] = 0; 26019808f9SSimon Glass } 27019808f9SSimon Glass buff[0] = ptr; 28019808f9SSimon Glass 29019808f9SSimon Glass return ptr; 30019808f9SSimon Glass } 31019808f9SSimon Glass 32019808f9SSimon Glass static int usb_emul_get_string(struct usb_string *strings, int index, 33019808f9SSimon Glass char *buff, int length) 34019808f9SSimon Glass { 35019808f9SSimon Glass if (index == 0) { 36019808f9SSimon Glass char *desc = buff; 37019808f9SSimon Glass 38019808f9SSimon Glass desc[0] = 4; 39019808f9SSimon Glass desc[1] = USB_DT_STRING; 40019808f9SSimon Glass desc[2] = 0x09; 41019808f9SSimon Glass desc[3] = 0x14; 42019808f9SSimon Glass return 4; 43019808f9SSimon Glass } else if (strings) { 44019808f9SSimon Glass struct usb_string *ptr; 45019808f9SSimon Glass 46019808f9SSimon Glass for (ptr = strings; ptr->s; ptr++) { 47019808f9SSimon Glass if (ptr->id == index) 48019808f9SSimon Glass return copy_to_unicode(buff, length, ptr->s); 49019808f9SSimon Glass } 50019808f9SSimon Glass } 51019808f9SSimon Glass 52019808f9SSimon Glass return -EINVAL; 53019808f9SSimon Glass } 54019808f9SSimon Glass 558e288127SBin Meng struct usb_generic_descriptor **usb_emul_find_descriptor( 56019808f9SSimon Glass struct usb_generic_descriptor **ptr, int type, int index) 57019808f9SSimon Glass { 58019808f9SSimon Glass debug("%s: type=%x, index=%d\n", __func__, type, index); 59019808f9SSimon Glass for (; *ptr; ptr++) { 60019808f9SSimon Glass if ((*ptr)->bDescriptorType != type) 61019808f9SSimon Glass continue; 62019808f9SSimon Glass switch (type) { 63019808f9SSimon Glass case USB_DT_CONFIG: { 64019808f9SSimon Glass struct usb_config_descriptor *cdesc; 65019808f9SSimon Glass 66019808f9SSimon Glass cdesc = (struct usb_config_descriptor *)*ptr; 67019808f9SSimon Glass if (cdesc && cdesc->bConfigurationValue == index) 68019808f9SSimon Glass return ptr; 69019808f9SSimon Glass break; 70019808f9SSimon Glass } 71019808f9SSimon Glass default: 72019808f9SSimon Glass return ptr; 73019808f9SSimon Glass } 74019808f9SSimon Glass } 75019808f9SSimon Glass debug("%s: config ptr=%p\n", __func__, *ptr); 76019808f9SSimon Glass 77019808f9SSimon Glass return ptr; 78019808f9SSimon Glass } 79019808f9SSimon Glass 80019808f9SSimon Glass static int usb_emul_get_descriptor(struct usb_dev_platdata *plat, int value, 81019808f9SSimon Glass void *buffer, int length) 82019808f9SSimon Glass { 83019808f9SSimon Glass struct usb_generic_descriptor **ptr; 84019808f9SSimon Glass int type = value >> 8; 85019808f9SSimon Glass int index = value & 0xff; 86019808f9SSimon Glass int upto, todo; 87019808f9SSimon Glass 88019808f9SSimon Glass debug("%s: type=%d, index=%d, plat=%p\n", __func__, type, index, plat); 89019808f9SSimon Glass if (type == USB_DT_STRING) { 90019808f9SSimon Glass return usb_emul_get_string(plat->strings, index, buffer, 91019808f9SSimon Glass length); 92019808f9SSimon Glass } 93019808f9SSimon Glass 948e288127SBin Meng ptr = usb_emul_find_descriptor(plat->desc_list, type, index); 95019808f9SSimon Glass if (!ptr) { 96019808f9SSimon Glass debug("%s: Could not find descriptor type %d, index %d\n", 97019808f9SSimon Glass __func__, type, index); 98019808f9SSimon Glass return -ENOENT; 99019808f9SSimon Glass } 100019808f9SSimon Glass for (upto = 0; *ptr && upto < length; ptr++, upto += todo) { 101019808f9SSimon Glass todo = min(length - upto, (int)(*ptr)->bLength); 102019808f9SSimon Glass 103019808f9SSimon Glass memcpy(buffer + upto, *ptr, todo); 104019808f9SSimon Glass } 105019808f9SSimon Glass 106019808f9SSimon Glass return upto ? upto : length ? -EIO : 0; 107019808f9SSimon Glass } 108019808f9SSimon Glass 109*7832d01eSBin Meng static int usb_emul_find_devnum(int devnum, int port1, struct udevice **emulp) 110019808f9SSimon Glass { 111019808f9SSimon Glass struct udevice *dev; 112019808f9SSimon Glass struct uclass *uc; 113019808f9SSimon Glass int ret; 114019808f9SSimon Glass 115019808f9SSimon Glass *emulp = NULL; 116019808f9SSimon Glass ret = uclass_get(UCLASS_USB_EMUL, &uc); 117019808f9SSimon Glass if (ret) 118019808f9SSimon Glass return ret; 119019808f9SSimon Glass uclass_foreach_dev(dev, uc) { 120019808f9SSimon Glass struct usb_dev_platdata *udev = dev_get_parent_platdata(dev); 121019808f9SSimon Glass 122*7832d01eSBin Meng /* 123*7832d01eSBin Meng * devnum is initialzied to zero at the beginning of the 124*7832d01eSBin Meng * enumeration process in usb_setup_device(). At this 125*7832d01eSBin Meng * point, udev->devnum has not been assigned to any valid 126*7832d01eSBin Meng * USB address either, so we can't rely on the comparison 127*7832d01eSBin Meng * result between udev->devnum and devnum to select an 128*7832d01eSBin Meng * emulator device. 129*7832d01eSBin Meng */ 130*7832d01eSBin Meng if (!devnum) { 131*7832d01eSBin Meng struct usb_emul_platdata *plat; 132*7832d01eSBin Meng 133*7832d01eSBin Meng /* 134*7832d01eSBin Meng * If the parent is sandbox USB controller, we are 135*7832d01eSBin Meng * the root hub. And there is only one root hub 136*7832d01eSBin Meng * in the system. 137*7832d01eSBin Meng */ 138*7832d01eSBin Meng if (device_get_uclass_id(dev->parent) == UCLASS_USB) { 139*7832d01eSBin Meng debug("%s: Found emulator '%s'\n", 140*7832d01eSBin Meng __func__, dev->name); 141*7832d01eSBin Meng *emulp = dev; 142*7832d01eSBin Meng return 0; 143*7832d01eSBin Meng } 144*7832d01eSBin Meng 145*7832d01eSBin Meng plat = dev_get_uclass_platdata(dev); 146*7832d01eSBin Meng if (plat->port1 == port1) { 147*7832d01eSBin Meng debug("%s: Found emulator '%s', port %d\n", 148*7832d01eSBin Meng __func__, dev->name, port1); 149*7832d01eSBin Meng *emulp = dev; 150*7832d01eSBin Meng return 0; 151*7832d01eSBin Meng } 152*7832d01eSBin Meng } else if (udev->devnum == devnum) { 153019808f9SSimon Glass debug("%s: Found emulator '%s', addr %d\n", __func__, 154019808f9SSimon Glass dev->name, udev->devnum); 155019808f9SSimon Glass *emulp = dev; 156019808f9SSimon Glass return 0; 157019808f9SSimon Glass } 158019808f9SSimon Glass } 159019808f9SSimon Glass 160019808f9SSimon Glass debug("%s: No emulator found, addr %d\n", __func__, devnum); 161019808f9SSimon Glass return -ENOENT; 162019808f9SSimon Glass } 163019808f9SSimon Glass 164*7832d01eSBin Meng int usb_emul_find(struct udevice *bus, ulong pipe, int port1, 165*7832d01eSBin Meng struct udevice **emulp) 166af9c7c11SSimon Glass { 167af9c7c11SSimon Glass int devnum = usb_pipedevice(pipe); 168af9c7c11SSimon Glass 169*7832d01eSBin Meng return usb_emul_find_devnum(devnum, port1, emulp); 170af9c7c11SSimon Glass } 171af9c7c11SSimon Glass 172af9c7c11SSimon Glass int usb_emul_find_for_dev(struct udevice *dev, struct udevice **emulp) 173af9c7c11SSimon Glass { 174af9c7c11SSimon Glass struct usb_dev_platdata *udev = dev_get_parent_platdata(dev); 175af9c7c11SSimon Glass 176*7832d01eSBin Meng return usb_emul_find_devnum(udev->devnum, 0, emulp); 177af9c7c11SSimon Glass } 178af9c7c11SSimon Glass 179019808f9SSimon Glass int usb_emul_control(struct udevice *emul, struct usb_device *udev, 180019808f9SSimon Glass unsigned long pipe, void *buffer, int length, 181019808f9SSimon Glass struct devrequest *setup) 182019808f9SSimon Glass { 183019808f9SSimon Glass struct dm_usb_ops *ops = usb_get_emul_ops(emul); 184019808f9SSimon Glass struct usb_dev_platdata *plat; 185019808f9SSimon Glass int ret; 186019808f9SSimon Glass 187019808f9SSimon Glass /* We permit getting the descriptor before we are probed */ 188019808f9SSimon Glass plat = dev_get_parent_platdata(emul); 189019808f9SSimon Glass if (!ops->control) 190019808f9SSimon Glass return -ENOSYS; 191019808f9SSimon Glass debug("%s: dev=%s\n", __func__, emul->name); 192019808f9SSimon Glass if (pipe == usb_rcvctrlpipe(udev, 0)) { 193019808f9SSimon Glass switch (setup->request) { 194019808f9SSimon Glass case USB_REQ_GET_DESCRIPTOR: { 195019808f9SSimon Glass return usb_emul_get_descriptor(plat, setup->value, 196019808f9SSimon Glass buffer, length); 197019808f9SSimon Glass } 198019808f9SSimon Glass default: 199019808f9SSimon Glass ret = device_probe(emul); 200019808f9SSimon Glass if (ret) 201019808f9SSimon Glass return ret; 202019808f9SSimon Glass return ops->control(emul, udev, pipe, buffer, length, 203019808f9SSimon Glass setup); 204019808f9SSimon Glass } 205019808f9SSimon Glass } else if (pipe == usb_snddefctrl(udev)) { 206019808f9SSimon Glass switch (setup->request) { 207019808f9SSimon Glass case USB_REQ_SET_ADDRESS: 208019808f9SSimon Glass debug(" ** set address %s %d\n", emul->name, 209019808f9SSimon Glass setup->value); 210019808f9SSimon Glass plat->devnum = setup->value; 211019808f9SSimon Glass return 0; 212019808f9SSimon Glass default: 213019808f9SSimon Glass debug("requestsend =%x\n", setup->request); 214019808f9SSimon Glass break; 215019808f9SSimon Glass } 216019808f9SSimon Glass } else if (pipe == usb_sndctrlpipe(udev, 0)) { 217019808f9SSimon Glass switch (setup->request) { 218019808f9SSimon Glass case USB_REQ_SET_CONFIGURATION: 219019808f9SSimon Glass plat->configno = setup->value; 220019808f9SSimon Glass return 0; 221019808f9SSimon Glass default: 222019808f9SSimon Glass ret = device_probe(emul); 223019808f9SSimon Glass if (ret) 224019808f9SSimon Glass return ret; 225019808f9SSimon Glass return ops->control(emul, udev, pipe, buffer, length, 226019808f9SSimon Glass setup); 227019808f9SSimon Glass } 228019808f9SSimon Glass } 229019808f9SSimon Glass debug("pipe=%lx\n", pipe); 230019808f9SSimon Glass 231019808f9SSimon Glass return -EIO; 232019808f9SSimon Glass } 233019808f9SSimon Glass 234019808f9SSimon Glass int usb_emul_bulk(struct udevice *emul, struct usb_device *udev, 235019808f9SSimon Glass unsigned long pipe, void *buffer, int length) 236019808f9SSimon Glass { 237019808f9SSimon Glass struct dm_usb_ops *ops = usb_get_emul_ops(emul); 238019808f9SSimon Glass int ret; 239019808f9SSimon Glass 240019808f9SSimon Glass /* We permit getting the descriptor before we are probed */ 241019808f9SSimon Glass if (!ops->bulk) 242019808f9SSimon Glass return -ENOSYS; 243019808f9SSimon Glass debug("%s: dev=%s\n", __func__, emul->name); 244019808f9SSimon Glass ret = device_probe(emul); 245019808f9SSimon Glass if (ret) 246019808f9SSimon Glass return ret; 247019808f9SSimon Glass return ops->bulk(emul, udev, pipe, buffer, length); 248019808f9SSimon Glass } 249019808f9SSimon Glass 250b70a3feaSSimon Glass int usb_emul_int(struct udevice *emul, struct usb_device *udev, 251b70a3feaSSimon Glass unsigned long pipe, void *buffer, int length, int interval) 252b70a3feaSSimon Glass { 253b70a3feaSSimon Glass struct dm_usb_ops *ops = usb_get_emul_ops(emul); 254b70a3feaSSimon Glass 255b70a3feaSSimon Glass if (!ops->interrupt) 256b70a3feaSSimon Glass return -ENOSYS; 257b70a3feaSSimon Glass debug("%s: dev=%s\n", __func__, emul->name); 258b70a3feaSSimon Glass 259b70a3feaSSimon Glass return ops->interrupt(emul, udev, pipe, buffer, length, interval); 260b70a3feaSSimon Glass } 261b70a3feaSSimon Glass 262879f76fcSBin Meng int usb_emul_setup_device(struct udevice *dev, struct usb_string *strings, 263879f76fcSBin Meng void **desc_list) 264019808f9SSimon Glass { 265019808f9SSimon Glass struct usb_dev_platdata *plat = dev_get_parent_platdata(dev); 266019808f9SSimon Glass struct usb_generic_descriptor **ptr; 267019808f9SSimon Glass struct usb_config_descriptor *cdesc; 268019808f9SSimon Glass int upto; 269019808f9SSimon Glass 270019808f9SSimon Glass plat->strings = strings; 271019808f9SSimon Glass plat->desc_list = (struct usb_generic_descriptor **)desc_list; 272019808f9SSimon Glass 273019808f9SSimon Glass /* Fill in wTotalLength for each configuration descriptor */ 274019808f9SSimon Glass ptr = plat->desc_list; 275019808f9SSimon Glass for (cdesc = NULL, upto = 0; *ptr; upto += (*ptr)->bLength, ptr++) { 276019808f9SSimon Glass debug(" - upto=%d, type=%d\n", upto, (*ptr)->bDescriptorType); 277019808f9SSimon Glass if ((*ptr)->bDescriptorType == USB_DT_CONFIG) { 278019808f9SSimon Glass if (cdesc) { 279019808f9SSimon Glass cdesc->wTotalLength = upto; 280019808f9SSimon Glass debug("%s: config %d length %d\n", __func__, 281019808f9SSimon Glass cdesc->bConfigurationValue, 282019808f9SSimon Glass cdesc->bLength); 283019808f9SSimon Glass } 284019808f9SSimon Glass cdesc = (struct usb_config_descriptor *)*ptr; 285019808f9SSimon Glass upto = 0; 286019808f9SSimon Glass } 287019808f9SSimon Glass } 288019808f9SSimon Glass if (cdesc) { 289019808f9SSimon Glass cdesc->wTotalLength = upto; 290019808f9SSimon Glass debug("%s: config %d length %d\n", __func__, 291019808f9SSimon Glass cdesc->bConfigurationValue, cdesc->wTotalLength); 292019808f9SSimon Glass } 293019808f9SSimon Glass 294019808f9SSimon Glass return 0; 295019808f9SSimon Glass } 296019808f9SSimon Glass 297019808f9SSimon Glass UCLASS_DRIVER(usb_emul) = { 298019808f9SSimon Glass .id = UCLASS_USB_EMUL, 299019808f9SSimon Glass .name = "usb_emul", 30091195485SSimon Glass .post_bind = dm_scan_fdt_dev, 301*7832d01eSBin Meng .per_device_platdata_auto_alloc_size = sizeof(struct usb_emul_platdata), 302019808f9SSimon Glass .per_child_auto_alloc_size = sizeof(struct usb_device), 303019808f9SSimon Glass .per_child_platdata_auto_alloc_size = sizeof(struct usb_dev_platdata), 304019808f9SSimon Glass }; 305