1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2015 Google, Inc 4 * Written by Simon Glass <sjg@chromium.org> 5 */ 6 7 #include <common.h> 8 #include <dm.h> 9 #include <usb.h> 10 #include <dm/root.h> 11 12 struct sandbox_usb_ctrl { 13 int rootdev; 14 }; 15 16 static void usbmon_trace(struct udevice *bus, ulong pipe, 17 struct devrequest *setup, struct udevice *emul) 18 { 19 static const char types[] = "ZICB"; 20 int type; 21 22 type = (pipe & USB_PIPE_TYPE_MASK) >> USB_PIPE_TYPE_SHIFT; 23 debug("0 0 S %c%c:%d:%03ld:%ld", types[type], 24 pipe & USB_DIR_IN ? 'i' : 'o', 25 bus->seq, 26 (pipe & USB_PIPE_DEV_MASK) >> USB_PIPE_DEV_SHIFT, 27 (pipe & USB_PIPE_EP_MASK) >> USB_PIPE_EP_SHIFT); 28 if (setup) { 29 debug(" s %02x %02x %04x %04x %04x", setup->requesttype, 30 setup->request, setup->value, setup->index, 31 setup->length); 32 } 33 debug(" %s", emul ? emul->name : "(no emul found)"); 34 35 debug("\n"); 36 } 37 38 static int sandbox_submit_control(struct udevice *bus, 39 struct usb_device *udev, 40 unsigned long pipe, 41 void *buffer, int length, 42 struct devrequest *setup) 43 { 44 struct sandbox_usb_ctrl *ctrl = dev_get_priv(bus); 45 struct udevice *emul; 46 int ret; 47 48 /* Just use child of dev as emulator? */ 49 debug("%s: bus=%s\n", __func__, bus->name); 50 ret = usb_emul_find(bus, pipe, udev->portnr, &emul); 51 usbmon_trace(bus, pipe, setup, emul); 52 if (ret) 53 return ret; 54 55 if (usb_pipedevice(pipe) == ctrl->rootdev) { 56 if (setup->request == USB_REQ_SET_ADDRESS) { 57 debug("%s: Set root hub's USB address\n", __func__); 58 ctrl->rootdev = le16_to_cpu(setup->value); 59 } 60 } 61 62 ret = usb_emul_control(emul, udev, pipe, buffer, length, setup); 63 if (ret < 0) { 64 debug("ret=%d\n", ret); 65 udev->status = ret; 66 udev->act_len = 0; 67 } else { 68 udev->status = 0; 69 udev->act_len = ret; 70 } 71 72 return ret; 73 } 74 75 static int sandbox_submit_bulk(struct udevice *bus, struct usb_device *udev, 76 unsigned long pipe, void *buffer, int length) 77 { 78 struct udevice *emul; 79 int ret; 80 81 /* Just use child of dev as emulator? */ 82 debug("%s: bus=%s\n", __func__, bus->name); 83 ret = usb_emul_find(bus, pipe, udev->portnr, &emul); 84 usbmon_trace(bus, pipe, NULL, emul); 85 if (ret) 86 return ret; 87 ret = usb_emul_bulk(emul, udev, pipe, buffer, length); 88 if (ret < 0) { 89 debug("ret=%d\n", ret); 90 udev->status = ret; 91 udev->act_len = 0; 92 } else { 93 udev->status = 0; 94 udev->act_len = ret; 95 } 96 97 return ret; 98 } 99 100 static int sandbox_submit_int(struct udevice *bus, struct usb_device *udev, 101 unsigned long pipe, void *buffer, int length, 102 int interval) 103 { 104 struct udevice *emul; 105 int ret; 106 107 /* Just use child of dev as emulator? */ 108 debug("%s: bus=%s\n", __func__, bus->name); 109 ret = usb_emul_find(bus, pipe, udev->portnr, &emul); 110 usbmon_trace(bus, pipe, NULL, emul); 111 if (ret) 112 return ret; 113 ret = usb_emul_int(emul, udev, pipe, buffer, length, interval); 114 115 return ret; 116 } 117 118 static int sandbox_alloc_device(struct udevice *dev, struct usb_device *udev) 119 { 120 struct sandbox_usb_ctrl *ctrl = dev_get_priv(dev); 121 122 /* 123 * Root hub will be the first device to be initailized. 124 * If this device is a root hub, initialize its device speed 125 * to high speed as we are a USB 2.0 controller. 126 */ 127 if (ctrl->rootdev == 0) 128 udev->speed = USB_SPEED_HIGH; 129 130 return 0; 131 } 132 133 static int sandbox_usb_probe(struct udevice *dev) 134 { 135 return 0; 136 } 137 138 static const struct dm_usb_ops sandbox_usb_ops = { 139 .control = sandbox_submit_control, 140 .bulk = sandbox_submit_bulk, 141 .interrupt = sandbox_submit_int, 142 .alloc_device = sandbox_alloc_device, 143 }; 144 145 static const struct udevice_id sandbox_usb_ids[] = { 146 { .compatible = "sandbox,usb" }, 147 { } 148 }; 149 150 U_BOOT_DRIVER(usb_sandbox) = { 151 .name = "usb_sandbox", 152 .id = UCLASS_USB, 153 .of_match = sandbox_usb_ids, 154 .probe = sandbox_usb_probe, 155 .ops = &sandbox_usb_ops, 156 .priv_auto_alloc_size = sizeof(struct sandbox_usb_ctrl), 157 }; 158