]> git.sur5r.net Git - u-boot/blob - drivers/usb/host/usb-sandbox.c
SPDX: Convert all of our single license tags to Linux Kernel style
[u-boot] / drivers / usb / host / usb-sandbox.c
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 };