Bug Summary

File:hw/usb/bus.c
Location:line 592, column 13
Description:Value stored to 'pos' is never read

Annotated Source Code

1#include "hw/hw.h"
2#include "hw/usb.h"
3#include "hw/qdev.h"
4#include "sysemu/sysemu.h"
5#include "monitor/monitor.h"
6#include "trace.h"
7
8static void usb_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent);
9
10static char *usb_get_dev_path(DeviceState *dev);
11static char *usb_get_fw_dev_path(DeviceState *qdev);
12static int usb_qdev_exit(DeviceState *qdev);
13
14static Property usb_props[] = {
15 DEFINE_PROP_STRING("port", USBDevice, port_path){ .name = ("port"), .info = &(qdev_prop_string), .offset =
__builtin_offsetof(USBDevice, port_path) + ((char**)0 - (typeof
(((USBDevice *)0)->port_path)*)0), }
,
16 DEFINE_PROP_STRING("serial", USBDevice, serial){ .name = ("serial"), .info = &(qdev_prop_string), .offset
= __builtin_offsetof(USBDevice, serial) + ((char**)0 - (typeof
(((USBDevice *)0)->serial)*)0), }
,
17 DEFINE_PROP_BIT("full-path", USBDevice, flags,{ .name = ("full-path"), .info = &(qdev_prop_bit), .bitnr
= (USB_DEV_FLAG_FULL_PATH), .offset = __builtin_offsetof(USBDevice
, flags) + ((uint32_t*)0 - (typeof(((USBDevice *)0)->flags
)*)0), .qtype = QTYPE_QBOOL, .defval = (_Bool)1, }
18 USB_DEV_FLAG_FULL_PATH, true){ .name = ("full-path"), .info = &(qdev_prop_bit), .bitnr
= (USB_DEV_FLAG_FULL_PATH), .offset = __builtin_offsetof(USBDevice
, flags) + ((uint32_t*)0 - (typeof(((USBDevice *)0)->flags
)*)0), .qtype = QTYPE_QBOOL, .defval = (_Bool)1, }
,
19 DEFINE_PROP_END_OF_LIST(){}
20};
21
22static void usb_bus_class_init(ObjectClass *klass, void *data)
23{
24 BusClass *k = BUS_CLASS(klass)((BusClass *)object_class_dynamic_cast_assert(((ObjectClass *
)((klass))), ("bus"), "/home/stefan/src/qemu/qemu.org/qemu/hw/usb/bus.c"
, 24, __func__))
;
25
26 k->print_dev = usb_bus_dev_print;
27 k->get_dev_path = usb_get_dev_path;
28 k->get_fw_dev_path = usb_get_fw_dev_path;
29}
30
31static const TypeInfo usb_bus_info = {
32 .name = TYPE_USB_BUS"usb-bus",
33 .parent = TYPE_BUS"bus",
34 .instance_size = sizeof(USBBus),
35 .class_init = usb_bus_class_init,
36};
37
38static int next_usb_bus = 0;
39static QTAILQ_HEAD(, USBBus)struct { struct USBBus *tqh_first; struct USBBus * *tqh_last;
}
busses = QTAILQ_HEAD_INITIALIZER(busses){ ((void*)0), &(busses).tqh_first };
40
41static int usb_device_post_load(void *opaque, int version_id)
42{
43 USBDevice *dev = opaque;
44
45 if (dev->state == USB_STATE_NOTATTACHED0) {
46 dev->attached = 0;
47 } else {
48 dev->attached = 1;
49 }
50 if (dev->setup_index >= sizeof(dev->data_buf) ||
51 dev->setup_len >= sizeof(dev->data_buf)) {
52 return -EINVAL22;
53 }
54 return 0;
55}
56
57const VMStateDescription vmstate_usb_device = {
58 .name = "USBDevice",
59 .version_id = 1,
60 .minimum_version_id = 1,
61 .post_load = usb_device_post_load,
62 .fields = (VMStateField []) {
63 VMSTATE_UINT8(addr, USBDevice){ .name = ("addr"), .version_id = (0), .field_exists = (((void
*)0)), .size = sizeof(uint8_t), .info = &(vmstate_info_uint8
), .flags = VMS_SINGLE, .offset = (__builtin_offsetof(USBDevice
, addr) + ((uint8_t*)0 - (typeof(((USBDevice *)0)->addr)*)
0)), }
,
64 VMSTATE_INT32(state, USBDevice){ .name = ("state"), .version_id = (0), .field_exists = (((void
*)0)), .size = sizeof(int32_t), .info = &(vmstate_info_int32
), .flags = VMS_SINGLE, .offset = (__builtin_offsetof(USBDevice
, state) + ((int32_t*)0 - (typeof(((USBDevice *)0)->state)
*)0)), }
,
65 VMSTATE_INT32(remote_wakeup, USBDevice){ .name = ("remote_wakeup"), .version_id = (0), .field_exists
= (((void*)0)), .size = sizeof(int32_t), .info = &(vmstate_info_int32
), .flags = VMS_SINGLE, .offset = (__builtin_offsetof(USBDevice
, remote_wakeup) + ((int32_t*)0 - (typeof(((USBDevice *)0)->
remote_wakeup)*)0)), }
,
66 VMSTATE_INT32(setup_state, USBDevice){ .name = ("setup_state"), .version_id = (0), .field_exists =
(((void*)0)), .size = sizeof(int32_t), .info = &(vmstate_info_int32
), .flags = VMS_SINGLE, .offset = (__builtin_offsetof(USBDevice
, setup_state) + ((int32_t*)0 - (typeof(((USBDevice *)0)->
setup_state)*)0)), }
,
67 VMSTATE_INT32(setup_len, USBDevice){ .name = ("setup_len"), .version_id = (0), .field_exists = (
((void*)0)), .size = sizeof(int32_t), .info = &(vmstate_info_int32
), .flags = VMS_SINGLE, .offset = (__builtin_offsetof(USBDevice
, setup_len) + ((int32_t*)0 - (typeof(((USBDevice *)0)->setup_len
)*)0)), }
,
68 VMSTATE_INT32(setup_index, USBDevice){ .name = ("setup_index"), .version_id = (0), .field_exists =
(((void*)0)), .size = sizeof(int32_t), .info = &(vmstate_info_int32
), .flags = VMS_SINGLE, .offset = (__builtin_offsetof(USBDevice
, setup_index) + ((int32_t*)0 - (typeof(((USBDevice *)0)->
setup_index)*)0)), }
,
69 VMSTATE_UINT8_ARRAY(setup_buf, USBDevice, 8){ .name = ("setup_buf"), .version_id = (0), .num = (8), .info
= &(vmstate_info_uint8), .size = sizeof(uint8_t), .flags
= VMS_ARRAY, .offset = (__builtin_offsetof(USBDevice, setup_buf
) + ((uint8_t(*)[8])0 - (typeof(((USBDevice *)0)->setup_buf
)*)0)), }
,
70 VMSTATE_END_OF_LIST(){},
71 }
72};
73
74void usb_bus_new(USBBus *bus, size_t bus_size,
75 USBBusOps *ops, DeviceState *host)
76{
77 qbus_create_inplace(bus, bus_size, TYPE_USB_BUS"usb-bus", host, NULL((void*)0));
78 bus->ops = ops;
79 bus->busnr = next_usb_bus++;
80 bus->qbus.allow_hotplug = 1; /* Yes, we can */
81 QTAILQ_INIT(&bus->free)do { (&bus->free)->tqh_first = ((void*)0); (&bus
->free)->tqh_last = &(&bus->free)->tqh_first
; } while ( 0)
;
82 QTAILQ_INIT(&bus->used)do { (&bus->used)->tqh_first = ((void*)0); (&bus
->used)->tqh_last = &(&bus->used)->tqh_first
; } while ( 0)
;
83 QTAILQ_INSERT_TAIL(&busses, bus, next)do { (bus)->next.tqe_next = ((void*)0); (bus)->next.tqe_prev
= (&busses)->tqh_last; *(&busses)->tqh_last = (
bus); (&busses)->tqh_last = &(bus)->next.tqe_next
; } while ( 0)
;
84}
85
86USBBus *usb_bus_find(int busnr)
87{
88 USBBus *bus;
89
90 if (-1 == busnr)
91 return QTAILQ_FIRST(&busses)((&busses)->tqh_first);
92 QTAILQ_FOREACH(bus, &busses, next)for ((bus) = ((&busses)->tqh_first); (bus); (bus) = ((
bus)->next.tqe_next))
{
93 if (bus->busnr == busnr)
94 return bus;
95 }
96 return NULL((void*)0);
97}
98
99static int usb_device_init(USBDevice *dev)
100{
101 USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev)((USBDeviceClass *)object_class_dynamic_cast_assert(((ObjectClass
*)(object_get_class(((Object *)((dev)))))), ("usb-device"), "/home/stefan/src/qemu/qemu.org/qemu/hw/usb/bus.c"
, 101, __func__))
;
102 if (klass->init) {
103 return klass->init(dev);
104 }
105 return 0;
106}
107
108USBDevice *usb_device_find_device(USBDevice *dev, uint8_t addr)
109{
110 USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev)((USBDeviceClass *)object_class_dynamic_cast_assert(((ObjectClass
*)(object_get_class(((Object *)((dev)))))), ("usb-device"), "/home/stefan/src/qemu/qemu.org/qemu/hw/usb/bus.c"
, 110, __func__))
;
111 if (klass->find_device) {
112 return klass->find_device(dev, addr);
113 }
114 return NULL((void*)0);
115}
116
117static void usb_device_handle_destroy(USBDevice *dev)
118{
119 USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev)((USBDeviceClass *)object_class_dynamic_cast_assert(((ObjectClass
*)(object_get_class(((Object *)((dev)))))), ("usb-device"), "/home/stefan/src/qemu/qemu.org/qemu/hw/usb/bus.c"
, 119, __func__))
;
120 if (klass->handle_destroy) {
121 klass->handle_destroy(dev);
122 }
123}
124
125void usb_device_cancel_packet(USBDevice *dev, USBPacket *p)
126{
127 USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev)((USBDeviceClass *)object_class_dynamic_cast_assert(((ObjectClass
*)(object_get_class(((Object *)((dev)))))), ("usb-device"), "/home/stefan/src/qemu/qemu.org/qemu/hw/usb/bus.c"
, 127, __func__))
;
128 if (klass->cancel_packet) {
129 klass->cancel_packet(dev, p);
130 }
131}
132
133void usb_device_handle_attach(USBDevice *dev)
134{
135 USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev)((USBDeviceClass *)object_class_dynamic_cast_assert(((ObjectClass
*)(object_get_class(((Object *)((dev)))))), ("usb-device"), "/home/stefan/src/qemu/qemu.org/qemu/hw/usb/bus.c"
, 135, __func__))
;
136 if (klass->handle_attach) {
137 klass->handle_attach(dev);
138 }
139}
140
141void usb_device_handle_reset(USBDevice *dev)
142{
143 USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev)((USBDeviceClass *)object_class_dynamic_cast_assert(((ObjectClass
*)(object_get_class(((Object *)((dev)))))), ("usb-device"), "/home/stefan/src/qemu/qemu.org/qemu/hw/usb/bus.c"
, 143, __func__))
;
144 if (klass->handle_reset) {
145 klass->handle_reset(dev);
146 }
147}
148
149void usb_device_handle_control(USBDevice *dev, USBPacket *p, int request,
150 int value, int index, int length, uint8_t *data)
151{
152 USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev)((USBDeviceClass *)object_class_dynamic_cast_assert(((ObjectClass
*)(object_get_class(((Object *)((dev)))))), ("usb-device"), "/home/stefan/src/qemu/qemu.org/qemu/hw/usb/bus.c"
, 152, __func__))
;
153 if (klass->handle_control) {
154 klass->handle_control(dev, p, request, value, index, length, data);
155 }
156}
157
158void usb_device_handle_data(USBDevice *dev, USBPacket *p)
159{
160 USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev)((USBDeviceClass *)object_class_dynamic_cast_assert(((ObjectClass
*)(object_get_class(((Object *)((dev)))))), ("usb-device"), "/home/stefan/src/qemu/qemu.org/qemu/hw/usb/bus.c"
, 160, __func__))
;
161 if (klass->handle_data) {
162 klass->handle_data(dev, p);
163 }
164}
165
166const char *usb_device_get_product_desc(USBDevice *dev)
167{
168 USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev)((USBDeviceClass *)object_class_dynamic_cast_assert(((ObjectClass
*)(object_get_class(((Object *)((dev)))))), ("usb-device"), "/home/stefan/src/qemu/qemu.org/qemu/hw/usb/bus.c"
, 168, __func__))
;
169 return klass->product_desc;
170}
171
172const USBDesc *usb_device_get_usb_desc(USBDevice *dev)
173{
174 USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev)((USBDeviceClass *)object_class_dynamic_cast_assert(((ObjectClass
*)(object_get_class(((Object *)((dev)))))), ("usb-device"), "/home/stefan/src/qemu/qemu.org/qemu/hw/usb/bus.c"
, 174, __func__))
;
175 if (dev->usb_desc) {
176 return dev->usb_desc;
177 }
178 return klass->usb_desc;
179}
180
181void usb_device_set_interface(USBDevice *dev, int interface,
182 int alt_old, int alt_new)
183{
184 USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev)((USBDeviceClass *)object_class_dynamic_cast_assert(((ObjectClass
*)(object_get_class(((Object *)((dev)))))), ("usb-device"), "/home/stefan/src/qemu/qemu.org/qemu/hw/usb/bus.c"
, 184, __func__))
;
185 if (klass->set_interface) {
186 klass->set_interface(dev, interface, alt_old, alt_new);
187 }
188}
189
190void usb_device_flush_ep_queue(USBDevice *dev, USBEndpoint *ep)
191{
192 USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev)((USBDeviceClass *)object_class_dynamic_cast_assert(((ObjectClass
*)(object_get_class(((Object *)((dev)))))), ("usb-device"), "/home/stefan/src/qemu/qemu.org/qemu/hw/usb/bus.c"
, 192, __func__))
;
193 if (klass->flush_ep_queue) {
194 klass->flush_ep_queue(dev, ep);
195 }
196}
197
198void usb_device_ep_stopped(USBDevice *dev, USBEndpoint *ep)
199{
200 USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev)((USBDeviceClass *)object_class_dynamic_cast_assert(((ObjectClass
*)(object_get_class(((Object *)((dev)))))), ("usb-device"), "/home/stefan/src/qemu/qemu.org/qemu/hw/usb/bus.c"
, 200, __func__))
;
201 if (klass->ep_stopped) {
202 klass->ep_stopped(dev, ep);
203 }
204}
205
206int usb_device_alloc_streams(USBDevice *dev, USBEndpoint **eps, int nr_eps,
207 int streams)
208{
209 USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev)((USBDeviceClass *)object_class_dynamic_cast_assert(((ObjectClass
*)(object_get_class(((Object *)((dev)))))), ("usb-device"), "/home/stefan/src/qemu/qemu.org/qemu/hw/usb/bus.c"
, 209, __func__))
;
210 if (klass->alloc_streams) {
211 return klass->alloc_streams(dev, eps, nr_eps, streams);
212 }
213 return 0;
214}
215
216void usb_device_free_streams(USBDevice *dev, USBEndpoint **eps, int nr_eps)
217{
218 USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev)((USBDeviceClass *)object_class_dynamic_cast_assert(((ObjectClass
*)(object_get_class(((Object *)((dev)))))), ("usb-device"), "/home/stefan/src/qemu/qemu.org/qemu/hw/usb/bus.c"
, 218, __func__))
;
219 if (klass->free_streams) {
220 klass->free_streams(dev, eps, nr_eps);
221 }
222}
223
224static int usb_qdev_init(DeviceState *qdev)
225{
226 USBDevice *dev = USB_DEVICE(qdev)((USBDevice *)object_dynamic_cast_assert(((Object *)((qdev)))
, ("usb-device"), "/home/stefan/src/qemu/qemu.org/qemu/hw/usb/bus.c"
, 226, __func__))
;
227 int rc;
228
229 pstrcpy(dev->product_desc, sizeof(dev->product_desc),
230 usb_device_get_product_desc(dev));
231 dev->auto_attach = 1;
232 QLIST_INIT(&dev->strings)do { (&dev->strings)->lh_first = ((void*)0); } while
( 0)
;
233 usb_ep_init(dev);
234 rc = usb_claim_port(dev);
235 if (rc != 0) {
236 return rc;
237 }
238 rc = usb_device_init(dev);
239 if (rc != 0) {
240 usb_release_port(dev);
241 return rc;
242 }
243 if (dev->auto_attach) {
244 rc = usb_device_attach(dev);
245 if (rc != 0) {
246 usb_qdev_exit(qdev);
247 return rc;
248 }
249 }
250 return 0;
251}
252
253static int usb_qdev_exit(DeviceState *qdev)
254{
255 USBDevice *dev = USB_DEVICE(qdev)((USBDevice *)object_dynamic_cast_assert(((Object *)((qdev)))
, ("usb-device"), "/home/stefan/src/qemu/qemu.org/qemu/hw/usb/bus.c"
, 255, __func__))
;
256
257 if (dev->attached) {
258 usb_device_detach(dev);
259 }
260 usb_device_handle_destroy(dev);
261 if (dev->port) {
262 usb_release_port(dev);
263 }
264 return 0;
265}
266
267typedef struct LegacyUSBFactory
268{
269 const char *name;
270 const char *usbdevice_name;
271 USBDevice *(*usbdevice_init)(USBBus *bus, const char *params);
272} LegacyUSBFactory;
273
274static GSList *legacy_usb_factory;
275
276void usb_legacy_register(const char *typename, const char *usbdevice_name,
277 USBDevice *(*usbdevice_init)(USBBus *bus,
278 const char *params))
279{
280 if (usbdevice_name) {
281 LegacyUSBFactory *f = g_malloc0(sizeof(*f));
282 f->name = typename;
283 f->usbdevice_name = usbdevice_name;
284 f->usbdevice_init = usbdevice_init;
285 legacy_usb_factory = g_slist_append(legacy_usb_factory, f);
286 }
287}
288
289USBDevice *usb_create(USBBus *bus, const char *name)
290{
291 DeviceState *dev;
292
293 dev = qdev_create(&bus->qbus, name);
294 return USB_DEVICE(dev)((USBDevice *)object_dynamic_cast_assert(((Object *)((dev))),
("usb-device"), "/home/stefan/src/qemu/qemu.org/qemu/hw/usb/bus.c"
, 294, __func__))
;
295}
296
297USBDevice *usb_create_simple(USBBus *bus, const char *name)
298{
299 USBDevice *dev = usb_create(bus, name);
300 int rc;
301
302 if (!dev) {
303 error_report("Failed to create USB device '%s'", name);
304 return NULL((void*)0);
305 }
306 rc = qdev_init(&dev->qdev);
307 if (rc < 0) {
308 error_report("Failed to initialize USB device '%s'", name);
309 return NULL((void*)0);
310 }
311 return dev;
312}
313
314static void usb_fill_port(USBPort *port, void *opaque, int index,
315 USBPortOps *ops, int speedmask)
316{
317 port->opaque = opaque;
318 port->index = index;
319 port->ops = ops;
320 port->speedmask = speedmask;
321 usb_port_location(port, NULL((void*)0), index + 1);
322}
323
324void usb_register_port(USBBus *bus, USBPort *port, void *opaque, int index,
325 USBPortOps *ops, int speedmask)
326{
327 usb_fill_port(port, opaque, index, ops, speedmask);
328 QTAILQ_INSERT_TAIL(&bus->free, port, next)do { (port)->next.tqe_next = ((void*)0); (port)->next.tqe_prev
= (&bus->free)->tqh_last; *(&bus->free)->
tqh_last = (port); (&bus->free)->tqh_last = &(port
)->next.tqe_next; } while ( 0)
;
329 bus->nfree++;
330}
331
332int usb_register_companion(const char *masterbus, USBPort *ports[],
333 uint32_t portcount, uint32_t firstport,
334 void *opaque, USBPortOps *ops, int speedmask)
335{
336 USBBus *bus;
337 int i;
338
339 QTAILQ_FOREACH(bus, &busses, next)for ((bus) = ((&busses)->tqh_first); (bus); (bus) = ((
bus)->next.tqe_next))
{
340 if (strcmp(bus->qbus.name, masterbus) == 0) {
341 break;
342 }
343 }
344
345 if (!bus || !bus->ops->register_companion) {
346 qerror_report(QERR_INVALID_PARAMETER_VALUEERROR_CLASS_GENERIC_ERROR, "Parameter '%s' expects %s", "masterbus",
347 "an USB masterbus");
348 if (bus) {
349 error_printf_unless_qmp(
350 "USB bus '%s' does not allow companion controllers\n",
351 masterbus);
352 }
353 return -1;
354 }
355
356 for (i = 0; i < portcount; i++) {
357 usb_fill_port(ports[i], opaque, i, ops, speedmask);
358 }
359
360 return bus->ops->register_companion(bus, ports, portcount, firstport);
361}
362
363void usb_port_location(USBPort *downstream, USBPort *upstream, int portnr)
364{
365 if (upstream) {
366 snprintf(downstream->path, sizeof(downstream->path), "%s.%d",
367 upstream->path, portnr);
368 downstream->hubcount = upstream->hubcount + 1;
369 } else {
370 snprintf(downstream->path, sizeof(downstream->path), "%d", portnr);
371 downstream->hubcount = 0;
372 }
373}
374
375void usb_unregister_port(USBBus *bus, USBPort *port)
376{
377 if (port->dev) {
378 object_unparent(OBJECT(port->dev)((Object *)(port->dev)));
379 }
380 QTAILQ_REMOVE(&bus->free, port, next)do { if (((port)->next.tqe_next) != ((void*)0)) (port)->
next.tqe_next->next.tqe_prev = (port)->next.tqe_prev; else
(&bus->free)->tqh_last = (port)->next.tqe_prev;
*(port)->next.tqe_prev = (port)->next.tqe_next; } while
( 0)
;
381 bus->nfree--;
382}
383
384int usb_claim_port(USBDevice *dev)
385{
386 USBBus *bus = usb_bus_from_device(dev);
387 USBPort *port;
388
389 assert(dev->port == NULL)((dev->port == ((void*)0)) ? (void) (0) : __assert_fail ("dev->port == ((void*)0)"
, "/home/stefan/src/qemu/qemu.org/qemu/hw/usb/bus.c", 389, __PRETTY_FUNCTION__
))
;
390
391 if (dev->port_path) {
392 QTAILQ_FOREACH(port, &bus->free, next)for ((port) = ((&bus->free)->tqh_first); (port); (port
) = ((port)->next.tqe_next))
{
393 if (strcmp(port->path, dev->port_path) == 0) {
394 break;
395 }
396 }
397 if (port == NULL((void*)0)) {
398 error_report("Error: usb port %s (bus %s) not found (in use?)",
399 dev->port_path, bus->qbus.name);
400 return -1;
401 }
402 } else {
403 if (bus->nfree == 1 && strcmp(object_get_typename(OBJECT(dev)((Object *)(dev))), "usb-hub") != 0) {
404 /* Create a new hub and chain it on */
405 usb_create_simple(bus, "usb-hub");
406 }
407 if (bus->nfree == 0) {
408 error_report("Error: tried to attach usb device %s to a bus "
409 "with no free ports", dev->product_desc);
410 return -1;
411 }
412 port = QTAILQ_FIRST(&bus->free)((&bus->free)->tqh_first);
413 }
414 trace_usb_port_claim(bus->busnr, port->path);
415
416 QTAILQ_REMOVE(&bus->free, port, next)do { if (((port)->next.tqe_next) != ((void*)0)) (port)->
next.tqe_next->next.tqe_prev = (port)->next.tqe_prev; else
(&bus->free)->tqh_last = (port)->next.tqe_prev;
*(port)->next.tqe_prev = (port)->next.tqe_next; } while
( 0)
;
417 bus->nfree--;
418
419 dev->port = port;
420 port->dev = dev;
421
422 QTAILQ_INSERT_TAIL(&bus->used, port, next)do { (port)->next.tqe_next = ((void*)0); (port)->next.tqe_prev
= (&bus->used)->tqh_last; *(&bus->used)->
tqh_last = (port); (&bus->used)->tqh_last = &(port
)->next.tqe_next; } while ( 0)
;
423 bus->nused++;
424 return 0;
425}
426
427void usb_release_port(USBDevice *dev)
428{
429 USBBus *bus = usb_bus_from_device(dev);
430 USBPort *port = dev->port;
431
432 assert(port != NULL)((port != ((void*)0)) ? (void) (0) : __assert_fail ("port != ((void*)0)"
, "/home/stefan/src/qemu/qemu.org/qemu/hw/usb/bus.c", 432, __PRETTY_FUNCTION__
))
;
433 trace_usb_port_release(bus->busnr, port->path);
434
435 QTAILQ_REMOVE(&bus->used, port, next)do { if (((port)->next.tqe_next) != ((void*)0)) (port)->
next.tqe_next->next.tqe_prev = (port)->next.tqe_prev; else
(&bus->used)->tqh_last = (port)->next.tqe_prev;
*(port)->next.tqe_prev = (port)->next.tqe_next; } while
( 0)
;
436 bus->nused--;
437
438 dev->port = NULL((void*)0);
439 port->dev = NULL((void*)0);
440
441 QTAILQ_INSERT_TAIL(&bus->free, port, next)do { (port)->next.tqe_next = ((void*)0); (port)->next.tqe_prev
= (&bus->free)->tqh_last; *(&bus->free)->
tqh_last = (port); (&bus->free)->tqh_last = &(port
)->next.tqe_next; } while ( 0)
;
442 bus->nfree++;
443}
444
445static void usb_mask_to_str(char *dest, size_t size,
446 unsigned int speedmask)
447{
448 static const struct {
449 unsigned int mask;
450 const char *name;
451 } speeds[] = {
452 { .mask = USB_SPEED_MASK_FULL(1 << 1), .name = "full" },
453 { .mask = USB_SPEED_MASK_HIGH(1 << 2), .name = "high" },
454 { .mask = USB_SPEED_MASK_SUPER(1 << 3), .name = "super" },
455 };
456 int i, pos = 0;
457
458 for (i = 0; i < ARRAY_SIZE(speeds)(sizeof(speeds) / sizeof((speeds)[0])); i++) {
459 if (speeds[i].mask & speedmask) {
460 pos += snprintf(dest + pos, size - pos, "%s%s",
461 pos ? "+" : "",
462 speeds[i].name);
463 }
464 }
465}
466
467int usb_device_attach(USBDevice *dev)
468{
469 USBBus *bus = usb_bus_from_device(dev);
470 USBPort *port = dev->port;
471 char devspeed[32], portspeed[32];
472
473 assert(port != NULL)((port != ((void*)0)) ? (void) (0) : __assert_fail ("port != ((void*)0)"
, "/home/stefan/src/qemu/qemu.org/qemu/hw/usb/bus.c", 473, __PRETTY_FUNCTION__
))
;
474 assert(!dev->attached)((!dev->attached) ? (void) (0) : __assert_fail ("!dev->attached"
, "/home/stefan/src/qemu/qemu.org/qemu/hw/usb/bus.c", 474, __PRETTY_FUNCTION__
))
;
475 usb_mask_to_str(devspeed, sizeof(devspeed), dev->speedmask);
476 usb_mask_to_str(portspeed, sizeof(portspeed), port->speedmask);
477 trace_usb_port_attach(bus->busnr, port->path,
478 devspeed, portspeed);
479
480 if (!(port->speedmask & dev->speedmask)) {
481 error_report("Warning: speed mismatch trying to attach"
482 " usb device \"%s\" (%s speed)"
483 " to bus \"%s\", port \"%s\" (%s speed)",
484 dev->product_desc, devspeed,
485 bus->qbus.name, port->path, portspeed);
486 return -1;
487 }
488
489 dev->attached++;
490 usb_attach(port);
491
492 return 0;
493}
494
495int usb_device_detach(USBDevice *dev)
496{
497 USBBus *bus = usb_bus_from_device(dev);
498 USBPort *port = dev->port;
499
500 assert(port != NULL)((port != ((void*)0)) ? (void) (0) : __assert_fail ("port != ((void*)0)"
, "/home/stefan/src/qemu/qemu.org/qemu/hw/usb/bus.c", 500, __PRETTY_FUNCTION__
))
;
501 assert(dev->attached)((dev->attached) ? (void) (0) : __assert_fail ("dev->attached"
, "/home/stefan/src/qemu/qemu.org/qemu/hw/usb/bus.c", 501, __PRETTY_FUNCTION__
))
;
502 trace_usb_port_detach(bus->busnr, port->path);
503
504 usb_detach(port);
505 dev->attached--;
506 return 0;
507}
508
509int usb_device_delete_addr(int busnr, int addr)
510{
511 USBBus *bus;
512 USBPort *port;
513 USBDevice *dev;
514
515 bus = usb_bus_find(busnr);
516 if (!bus)
517 return -1;
518
519 QTAILQ_FOREACH(port, &bus->used, next)for ((port) = ((&bus->used)->tqh_first); (port); (port
) = ((port)->next.tqe_next))
{
520 if (port->dev->addr == addr)
521 break;
522 }
523 if (!port)
524 return -1;
525 dev = port->dev;
526
527 object_unparent(OBJECT(dev)((Object *)(dev)));
528 return 0;
529}
530
531static const char *usb_speed(unsigned int speed)
532{
533 static const char *txt[] = {
534 [ USB_SPEED_LOW0 ] = "1.5",
535 [ USB_SPEED_FULL1 ] = "12",
536 [ USB_SPEED_HIGH2 ] = "480",
537 [ USB_SPEED_SUPER3 ] = "5000",
538 };
539 if (speed >= ARRAY_SIZE(txt)(sizeof(txt) / sizeof((txt)[0])))
540 return "?";
541 return txt[speed];
542}
543
544static void usb_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent)
545{
546 USBDevice *dev = USB_DEVICE(qdev)((USBDevice *)object_dynamic_cast_assert(((Object *)((qdev)))
, ("usb-device"), "/home/stefan/src/qemu/qemu.org/qemu/hw/usb/bus.c"
, 546, __func__))
;
547 USBBus *bus = usb_bus_from_device(dev);
548
549 monitor_printf(mon, "%*saddr %d.%d, port %s, speed %s, name %s%s\n",
550 indent, "", bus->busnr, dev->addr,
551 dev->port ? dev->port->path : "-",
552 usb_speed(dev->speed), dev->product_desc,
553 dev->attached ? ", attached" : "");
554}
555
556static char *usb_get_dev_path(DeviceState *qdev)
557{
558 USBDevice *dev = USB_DEVICE(qdev)((USBDevice *)object_dynamic_cast_assert(((Object *)((qdev)))
, ("usb-device"), "/home/stefan/src/qemu/qemu.org/qemu/hw/usb/bus.c"
, 558, __func__))
;
559 DeviceState *hcd = qdev->parent_bus->parent;
560 char *id = NULL((void*)0);
561
562 if (dev->flags & (1 << USB_DEV_FLAG_FULL_PATH)) {
563 id = qdev_get_dev_path(hcd);
564 }
565 if (id) {
566 char *ret = g_strdup_printf("%s/%s", id, dev->port->path);
567 g_free(id);
568 return ret;
569 } else {
570 return g_strdup(dev->port->path);
571 }
572}
573
574static char *usb_get_fw_dev_path(DeviceState *qdev)
575{
576 USBDevice *dev = USB_DEVICE(qdev)((USBDevice *)object_dynamic_cast_assert(((Object *)((qdev)))
, ("usb-device"), "/home/stefan/src/qemu/qemu.org/qemu/hw/usb/bus.c"
, 576, __func__))
;
577 char *fw_path, *in;
578 ssize_t pos = 0, fw_len;
579 long nr;
580
581 fw_len = 32 + strlen(dev->port->path) * 6;
582 fw_path = g_malloc(fw_len);
583 in = dev->port->path;
584 while (fw_len - pos > 0) {
585 nr = strtol(in, &in, 10);
586 if (in[0] == '.') {
587 /* some hub between root port and device */
588 pos += snprintf(fw_path + pos, fw_len - pos, "hub@%ld/", nr);
589 in++;
590 } else {
591 /* the device itself */
592 pos += snprintf(fw_path + pos, fw_len - pos, "%s@%ld",
Value stored to 'pos' is never read
593 qdev_fw_name(qdev), nr);
594 break;
595 }
596 }
597 return fw_path;
598}
599
600void usb_info(Monitor *mon, const QDict *qdict)
601{
602 USBBus *bus;
603 USBDevice *dev;
604 USBPort *port;
605
606 if (QTAILQ_EMPTY(&busses)((&busses)->tqh_first == ((void*)0))) {
607 monitor_printf(mon, "USB support not enabled\n");
608 return;
609 }
610
611 QTAILQ_FOREACH(bus, &busses, next)for ((bus) = ((&busses)->tqh_first); (bus); (bus) = ((
bus)->next.tqe_next))
{
612 QTAILQ_FOREACH(port, &bus->used, next)for ((port) = ((&bus->used)->tqh_first); (port); (port
) = ((port)->next.tqe_next))
{
613 dev = port->dev;
614 if (!dev)
615 continue;
616 monitor_printf(mon, " Device %d.%d, Port %s, Speed %s Mb/s, Product %s\n",
617 bus->busnr, dev->addr, port->path, usb_speed(dev->speed),
618 dev->product_desc);
619 }
620 }
621}
622
623/* handle legacy -usbdevice cmd line option */
624USBDevice *usbdevice_create(const char *cmdline)
625{
626 USBBus *bus = usb_bus_find(-1 /* any */);
627 LegacyUSBFactory *f = NULL((void*)0);
628 GSList *i;
629 char driver[32];
630 const char *params;
631 int len;
632
633 params = strchr(cmdline,':');
634 if (params) {
635 params++;
636 len = params - cmdline;
637 if (len > sizeof(driver))
638 len = sizeof(driver);
639 pstrcpy(driver, len, cmdline);
640 } else {
641 params = "";
642 pstrcpy(driver, sizeof(driver), cmdline);
643 }
644
645 for (i = legacy_usb_factory; i; i = i->next) {
646 f = i->data;
647 if (strcmp(f->usbdevice_name, driver) == 0) {
648 break;
649 }
650 }
651 if (i == NULL((void*)0)) {
652#if 0
653 /* no error because some drivers are not converted (yet) */
654 error_report("usbdevice %s not found", driver);
655#endif
656 return NULL((void*)0);
657 }
658
659 if (!bus) {
660 error_report("Error: no usb bus to attach usbdevice %s, "
661 "please try -machine usb=on and check that "
662 "the machine model supports USB", driver);
663 return NULL((void*)0);
664 }
665
666 if (!f->usbdevice_init) {
667 if (*params) {
668 error_report("usbdevice %s accepts no params", driver);
669 return NULL((void*)0);
670 }
671 return usb_create_simple(bus, f->name);
672 }
673 return f->usbdevice_init(bus, params);
674}
675
676static void usb_device_class_init(ObjectClass *klass, void *data)
677{
678 DeviceClass *k = DEVICE_CLASS(klass)((DeviceClass *)object_class_dynamic_cast_assert(((ObjectClass
*)((klass))), ("device"), "/home/stefan/src/qemu/qemu.org/qemu/hw/usb/bus.c"
, 678, __func__))
;
679 k->bus_type = TYPE_USB_BUS"usb-bus";
680 k->init = usb_qdev_init;
681 k->unplug = qdev_simple_unplug_cb;
682 k->exit = usb_qdev_exit;
683 k->props = usb_props;
684}
685
686static const TypeInfo usb_device_type_info = {
687 .name = TYPE_USB_DEVICE"usb-device",
688 .parent = TYPE_DEVICE"device",
689 .instance_size = sizeof(USBDevice),
690 .abstract = true1,
691 .class_size = sizeof(USBDeviceClass),
692 .class_init = usb_device_class_init,
693};
694
695static void usb_register_types(void)
696{
697 type_register_static(&usb_bus_info);
698 type_register_static(&usb_device_type_info);
699}
700
701type_init(usb_register_types)static void __attribute__((constructor)) do_qemu_init_usb_register_types
(void) { register_module_init(usb_register_types, MODULE_INIT_QOM
); }