1*dfd84001SSimon Glass /* 2*dfd84001SSimon Glass * (C) Copyright 2015 Google, Inc 3*dfd84001SSimon Glass * Written by Simon Glass <sjg@chromium.org> 4*dfd84001SSimon Glass * 5*dfd84001SSimon Glass * SPDX-License-Identifier: GPL-2.0+ 6*dfd84001SSimon Glass */ 7*dfd84001SSimon Glass 8*dfd84001SSimon Glass #include <common.h> 9*dfd84001SSimon Glass #include <dm.h> 10*dfd84001SSimon Glass #include <usb.h> 11*dfd84001SSimon Glass #include <dm/root.h> 12*dfd84001SSimon Glass 13*dfd84001SSimon Glass DECLARE_GLOBAL_DATA_PTR; 14*dfd84001SSimon Glass 15*dfd84001SSimon Glass static void usbmon_trace(struct udevice *bus, ulong pipe, 16*dfd84001SSimon Glass struct devrequest *setup, struct udevice *emul) 17*dfd84001SSimon Glass { 18*dfd84001SSimon Glass static const char types[] = "ZICB"; 19*dfd84001SSimon Glass int type; 20*dfd84001SSimon Glass 21*dfd84001SSimon Glass type = (pipe & USB_PIPE_TYPE_MASK) >> USB_PIPE_TYPE_SHIFT; 22*dfd84001SSimon Glass debug("0 0 S %c%c:%d:%03ld:%ld", types[type], 23*dfd84001SSimon Glass pipe & USB_DIR_IN ? 'i' : 'o', 24*dfd84001SSimon Glass bus->seq, 25*dfd84001SSimon Glass (pipe & USB_PIPE_DEV_MASK) >> USB_PIPE_DEV_SHIFT, 26*dfd84001SSimon Glass (pipe & USB_PIPE_EP_MASK) >> USB_PIPE_EP_SHIFT); 27*dfd84001SSimon Glass if (setup) { 28*dfd84001SSimon Glass debug(" s %02x %02x %04x %04x %04x", setup->requesttype, 29*dfd84001SSimon Glass setup->request, setup->value, setup->index, 30*dfd84001SSimon Glass setup->length); 31*dfd84001SSimon Glass } 32*dfd84001SSimon Glass debug(" %s", emul ? emul->name : "(no emul found)"); 33*dfd84001SSimon Glass 34*dfd84001SSimon Glass debug("\n"); 35*dfd84001SSimon Glass } 36*dfd84001SSimon Glass 37*dfd84001SSimon Glass static int sandbox_submit_control(struct udevice *bus, 38*dfd84001SSimon Glass struct usb_device *udev, 39*dfd84001SSimon Glass unsigned long pipe, 40*dfd84001SSimon Glass void *buffer, int length, 41*dfd84001SSimon Glass struct devrequest *setup) 42*dfd84001SSimon Glass { 43*dfd84001SSimon Glass struct udevice *emul; 44*dfd84001SSimon Glass int ret; 45*dfd84001SSimon Glass 46*dfd84001SSimon Glass /* Just use child of dev as emulator? */ 47*dfd84001SSimon Glass debug("%s: bus=%s\n", __func__, bus->name); 48*dfd84001SSimon Glass ret = usb_emul_find(bus, pipe, &emul); 49*dfd84001SSimon Glass usbmon_trace(bus, pipe, setup, emul); 50*dfd84001SSimon Glass if (ret) 51*dfd84001SSimon Glass return ret; 52*dfd84001SSimon Glass ret = usb_emul_control(emul, udev, pipe, buffer, length, setup); 53*dfd84001SSimon Glass if (ret < 0) { 54*dfd84001SSimon Glass debug("ret=%d\n", ret); 55*dfd84001SSimon Glass udev->status = ret; 56*dfd84001SSimon Glass udev->act_len = 0; 57*dfd84001SSimon Glass } else { 58*dfd84001SSimon Glass udev->status = 0; 59*dfd84001SSimon Glass udev->act_len = ret; 60*dfd84001SSimon Glass } 61*dfd84001SSimon Glass 62*dfd84001SSimon Glass return ret; 63*dfd84001SSimon Glass } 64*dfd84001SSimon Glass 65*dfd84001SSimon Glass static int sandbox_submit_bulk(struct udevice *bus, struct usb_device *udev, 66*dfd84001SSimon Glass unsigned long pipe, void *buffer, int length) 67*dfd84001SSimon Glass { 68*dfd84001SSimon Glass struct udevice *emul; 69*dfd84001SSimon Glass int ret; 70*dfd84001SSimon Glass 71*dfd84001SSimon Glass /* Just use child of dev as emulator? */ 72*dfd84001SSimon Glass debug("%s: bus=%s\n", __func__, bus->name); 73*dfd84001SSimon Glass ret = usb_emul_find(bus, pipe, &emul); 74*dfd84001SSimon Glass usbmon_trace(bus, pipe, NULL, emul); 75*dfd84001SSimon Glass if (ret) 76*dfd84001SSimon Glass return ret; 77*dfd84001SSimon Glass ret = usb_emul_bulk(emul, udev, pipe, buffer, length); 78*dfd84001SSimon Glass if (ret < 0) { 79*dfd84001SSimon Glass debug("ret=%d\n", ret); 80*dfd84001SSimon Glass udev->status = ret; 81*dfd84001SSimon Glass udev->act_len = 0; 82*dfd84001SSimon Glass } else { 83*dfd84001SSimon Glass udev->status = 0; 84*dfd84001SSimon Glass udev->act_len = ret; 85*dfd84001SSimon Glass } 86*dfd84001SSimon Glass 87*dfd84001SSimon Glass return ret; 88*dfd84001SSimon Glass } 89*dfd84001SSimon Glass 90*dfd84001SSimon Glass static int sandbox_alloc_device(struct udevice *dev, struct usb_device *udev) 91*dfd84001SSimon Glass { 92*dfd84001SSimon Glass return 0; 93*dfd84001SSimon Glass } 94*dfd84001SSimon Glass 95*dfd84001SSimon Glass static int sandbox_usb_probe(struct udevice *dev) 96*dfd84001SSimon Glass { 97*dfd84001SSimon Glass return 0; 98*dfd84001SSimon Glass } 99*dfd84001SSimon Glass 100*dfd84001SSimon Glass static const struct dm_usb_ops sandbox_usb_ops = { 101*dfd84001SSimon Glass .control = sandbox_submit_control, 102*dfd84001SSimon Glass .bulk = sandbox_submit_bulk, 103*dfd84001SSimon Glass .alloc_device = sandbox_alloc_device, 104*dfd84001SSimon Glass }; 105*dfd84001SSimon Glass 106*dfd84001SSimon Glass static const struct udevice_id sandbox_usb_ids[] = { 107*dfd84001SSimon Glass { .compatible = "sandbox,usb" }, 108*dfd84001SSimon Glass { } 109*dfd84001SSimon Glass }; 110*dfd84001SSimon Glass 111*dfd84001SSimon Glass U_BOOT_DRIVER(usb_sandbox) = { 112*dfd84001SSimon Glass .name = "usb_sandbox", 113*dfd84001SSimon Glass .id = UCLASS_USB, 114*dfd84001SSimon Glass .of_match = sandbox_usb_ids, 115*dfd84001SSimon Glass .probe = sandbox_usb_probe, 116*dfd84001SSimon Glass .ops = &sandbox_usb_ops, 117*dfd84001SSimon Glass }; 118