2 * xen paravirt usb device backend
4 * (c) Juergen Gross <jgross@suse.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; under version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, see <http://www.gnu.org/licenses/>.
18 * Contributions after 2012-01-13 are licensed under the terms of the
19 * GNU GPL, version 2 or (at your option) any later version.
22 #include "qemu/osdep.h"
26 #include "qemu/config-file.h"
27 #include "qemu/main-loop.h"
28 #include "qemu/option.h"
30 #include "hw/xen/xen-legacy-backend.h"
31 #include "monitor/qdev.h"
32 #include "qapi/error.h"
33 #include "qapi/qmp/qdict.h"
34 #include "qapi/qmp/qstring.h"
36 #include "hw/xen/interface/io/usbif.h"
39 * Check for required support of usbif.h: USBIF_SHORT_NOT_OK was the last
40 * macro added we rely on.
42 #ifdef USBIF_SHORT_NOT_OK
44 #define TR(xendev, lvl, fmt, args...) \
48 gettimeofday(&tv, NULL); \
49 xen_pv_printf(xendev, lvl, "%8ld.%06ld xen-usb(%s):" fmt, \
50 tv.tv_sec, tv.tv_usec, __func__, ##args); \
52 #define TR_BUS(xendev, fmt, args...) TR(xendev, 2, fmt, ##args)
53 #define TR_REQ(xendev, fmt, args...) TR(xendev, 3, fmt, ##args)
55 #define USBBACK_MAXPORTS USBIF_PIPE_PORT_MASK
56 #define USB_DEV_ADDR_SIZE (USBIF_PIPE_DEV_MASK + 1)
58 /* USB wire protocol: structure describing control request parameter. */
59 struct usbif_ctrlrequest
{
75 QTAILQ_HEAD(, usbback_req
) submit_q
;
79 struct usbback_info
*usbif
;
80 struct usbback_stub
*stub
;
81 struct usbif_urb_request req
;
84 unsigned int nr_buffer_segs
; /* # of transfer_buffer segments */
85 unsigned int nr_extra_segs
; /* # of iso_frame_desc segments */
87 QTAILQ_ENTRY(usbback_req
) q
;
91 struct libusb_transfer
*xfer
;
96 struct usbback_hotplug
{
97 QSIMPLEQ_ENTRY(usbback_hotplug
) q
;
101 struct usbback_info
{
102 struct XenLegacyDevice xendev
; /* must be first */
104 uint32_t urb_ring_ref
;
105 uint32_t conn_ring_ref
;
108 struct usbif_urb_back_ring urb_ring
;
109 struct usbif_conn_back_ring conn_ring
;
113 QTAILQ_HEAD(, usbback_req
) req_free_q
;
114 QSIMPLEQ_HEAD(, usbback_hotplug
) hotplug_q
;
115 struct usbback_stub ports
[USBBACK_MAXPORTS
];
116 struct usbback_stub
*addr_table
[USB_DEV_ADDR_SIZE
];
120 static struct usbback_req
*usbback_get_req(struct usbback_info
*usbif
)
122 struct usbback_req
*usbback_req
;
124 if (QTAILQ_EMPTY(&usbif
->req_free_q
)) {
125 usbback_req
= g_new0(struct usbback_req
, 1);
127 usbback_req
= QTAILQ_FIRST(&usbif
->req_free_q
);
128 QTAILQ_REMOVE(&usbif
->req_free_q
, usbback_req
, q
);
133 static void usbback_put_req(struct usbback_req
*usbback_req
)
135 struct usbback_info
*usbif
;
137 usbif
= usbback_req
->usbif
;
138 memset(usbback_req
, 0, sizeof(*usbback_req
));
139 QTAILQ_INSERT_HEAD(&usbif
->req_free_q
, usbback_req
, q
);
142 static int usbback_gnttab_map(struct usbback_req
*usbback_req
)
144 unsigned int nr_segs
, i
, prot
;
145 uint32_t ref
[USBIF_MAX_SEGMENTS_PER_REQUEST
];
146 struct usbback_info
*usbif
= usbback_req
->usbif
;
147 struct XenLegacyDevice
*xendev
= &usbif
->xendev
;
148 struct usbif_request_segment
*seg
;
151 nr_segs
= usbback_req
->nr_buffer_segs
+ usbback_req
->nr_extra_segs
;
156 if (nr_segs
> USBIF_MAX_SEGMENTS_PER_REQUEST
) {
157 xen_pv_printf(xendev
, 0, "bad number of segments in request (%d)\n",
162 for (i
= 0; i
< nr_segs
; i
++) {
163 if ((unsigned)usbback_req
->req
.seg
[i
].offset
+
164 (unsigned)usbback_req
->req
.seg
[i
].length
> XEN_PAGE_SIZE
) {
165 xen_pv_printf(xendev
, 0, "segment crosses page boundary\n");
170 if (usbback_req
->nr_buffer_segs
) {
172 if (usbif_pipein(usbback_req
->req
.pipe
)) {
175 for (i
= 0; i
< usbback_req
->nr_buffer_segs
; i
++) {
176 ref
[i
] = usbback_req
->req
.seg
[i
].gref
;
178 usbback_req
->buffer
=
179 xen_be_map_grant_refs(xendev
, ref
, usbback_req
->nr_buffer_segs
,
182 if (!usbback_req
->buffer
) {
186 for (i
= 0; i
< usbback_req
->nr_buffer_segs
; i
++) {
187 seg
= usbback_req
->req
.seg
+ i
;
188 addr
= usbback_req
->buffer
+ i
* XEN_PAGE_SIZE
+ seg
->offset
;
189 qemu_iovec_add(&usbback_req
->packet
.iov
, addr
, seg
->length
);
193 if (!usbif_pipeisoc(usbback_req
->req
.pipe
)) {
198 * Right now isoc requests are not supported.
199 * Prepare supporting those by doing the work needed on the guest
203 if (!usbback_req
->nr_extra_segs
) {
204 xen_pv_printf(xendev
, 0, "iso request without descriptor segments\n");
208 prot
= PROT_READ
| PROT_WRITE
;
209 for (i
= 0; i
< usbback_req
->nr_extra_segs
; i
++) {
210 ref
[i
] = usbback_req
->req
.seg
[i
+ usbback_req
->req
.nr_buffer_segs
].gref
;
212 usbback_req
->isoc_buffer
=
213 xen_be_map_grant_refs(xendev
, ref
, usbback_req
->nr_extra_segs
,
216 if (!usbback_req
->isoc_buffer
) {
223 static int usbback_init_packet(struct usbback_req
*usbback_req
)
225 struct XenLegacyDevice
*xendev
= &usbback_req
->usbif
->xendev
;
226 USBPacket
*packet
= &usbback_req
->packet
;
227 USBDevice
*dev
= usbback_req
->stub
->dev
;
229 unsigned int pid
, ep_nr
;
233 qemu_iovec_init(&packet
->iov
, USBIF_MAX_SEGMENTS_PER_REQUEST
);
234 pid
= usbif_pipein(usbback_req
->req
.pipe
) ? USB_TOKEN_IN
: USB_TOKEN_OUT
;
235 ep_nr
= usbif_pipeendpoint(usbback_req
->req
.pipe
);
236 sok
= !!(usbback_req
->req
.transfer_flags
& USBIF_SHORT_NOT_OK
);
237 if (usbif_pipectrl(usbback_req
->req
.pipe
)) {
241 ep
= usb_ep_get(dev
, pid
, ep_nr
);
242 usb_packet_setup(packet
, pid
, ep
, 0, 1, sok
, true);
244 switch (usbif_pipetype(usbback_req
->req
.pipe
)) {
245 case USBIF_PIPE_TYPE_ISOC
:
246 TR_REQ(xendev
, "iso transfer %s: buflen: %x, %d frames\n",
247 (pid
== USB_TOKEN_IN
) ? "in" : "out",
248 usbback_req
->req
.buffer_length
,
249 usbback_req
->req
.u
.isoc
.nr_frame_desc_segs
);
250 ret
= -EINVAL
; /* isoc not implemented yet */
253 case USBIF_PIPE_TYPE_INT
:
254 TR_REQ(xendev
, "int transfer %s: buflen: %x\n",
255 (pid
== USB_TOKEN_IN
) ? "in" : "out",
256 usbback_req
->req
.buffer_length
);
259 case USBIF_PIPE_TYPE_CTRL
:
260 packet
->parameter
= *(uint64_t *)usbback_req
->req
.u
.ctrl
;
261 TR_REQ(xendev
, "ctrl parameter: %"PRIx64
", buflen: %x\n",
263 usbback_req
->req
.buffer_length
);
266 case USBIF_PIPE_TYPE_BULK
:
267 TR_REQ(xendev
, "bulk transfer %s: buflen: %x\n",
268 (pid
== USB_TOKEN_IN
) ? "in" : "out",
269 usbback_req
->req
.buffer_length
);
279 static void usbback_do_response(struct usbback_req
*usbback_req
, int32_t status
,
280 int32_t actual_length
, int32_t error_count
)
282 uint32_t ref
[USBIF_MAX_SEGMENTS_PER_REQUEST
];
283 struct usbback_info
*usbif
;
284 struct usbif_urb_response
*res
;
285 struct XenLegacyDevice
*xendev
;
286 unsigned int notify
, i
;
288 usbif
= usbback_req
->usbif
;
289 xendev
= &usbif
->xendev
;
291 TR_REQ(xendev
, "id %d, status %d, length %d, errcnt %d\n",
292 usbback_req
->req
.id
, status
, actual_length
, error_count
);
294 if (usbback_req
->packet
.iov
.iov
) {
295 qemu_iovec_destroy(&usbback_req
->packet
.iov
);
298 if (usbback_req
->buffer
) {
299 for (i
= 0; i
< usbback_req
->nr_buffer_segs
; i
++) {
300 ref
[i
] = usbback_req
->req
.seg
[i
].gref
;
302 xen_be_unmap_grant_refs(xendev
, usbback_req
->buffer
, ref
,
303 usbback_req
->nr_buffer_segs
);
304 usbback_req
->buffer
= NULL
;
307 if (usbback_req
->isoc_buffer
) {
308 for (i
= 0; i
< usbback_req
->nr_extra_segs
; i
++) {
309 ref
[i
] = usbback_req
->req
.seg
[i
+ usbback_req
->req
.nr_buffer_segs
].gref
;
311 xen_be_unmap_grant_refs(xendev
, usbback_req
->isoc_buffer
, ref
,
312 usbback_req
->nr_extra_segs
);
313 usbback_req
->isoc_buffer
= NULL
;
316 if (usbif
->urb_sring
) {
317 res
= RING_GET_RESPONSE(&usbif
->urb_ring
, usbif
->urb_ring
.rsp_prod_pvt
);
318 res
->id
= usbback_req
->req
.id
;
319 res
->status
= status
;
320 res
->actual_length
= actual_length
;
321 res
->error_count
= error_count
;
322 res
->start_frame
= 0;
323 usbif
->urb_ring
.rsp_prod_pvt
++;
324 RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&usbif
->urb_ring
, notify
);
327 xen_pv_send_notify(xendev
);
331 if (!usbback_req
->cancelled
)
332 usbback_put_req(usbback_req
);
335 static void usbback_do_response_ret(struct usbback_req
*usbback_req
,
338 usbback_do_response(usbback_req
, status
, 0, 0);
341 static int32_t usbback_xlat_status(int status
)
344 case USB_RET_SUCCESS
:
352 case USB_RET_IOERROR
:
359 static void usbback_packet_complete(struct usbback_req
*usbback_req
)
361 USBPacket
*packet
= &usbback_req
->packet
;
364 QTAILQ_REMOVE(&usbback_req
->stub
->submit_q
, usbback_req
, q
);
366 status
= usbback_xlat_status(packet
->status
);
367 usbback_do_response(usbback_req
, status
, packet
->actual_length
, 0);
370 static void usbback_set_address(struct usbback_info
*usbif
,
371 struct usbback_stub
*stub
,
372 unsigned int cur_addr
, unsigned int new_addr
)
375 usbif
->addr_table
[cur_addr
] = NULL
;
378 usbif
->addr_table
[new_addr
] = stub
;
382 static void usbback_cancel_req(struct usbback_req
*usbback_req
)
384 if (usb_packet_is_inflight(&usbback_req
->packet
)) {
385 usb_cancel_packet(&usbback_req
->packet
);
386 QTAILQ_REMOVE(&usbback_req
->stub
->submit_q
, usbback_req
, q
);
387 usbback_req
->cancelled
= true;
388 usbback_do_response_ret(usbback_req
, -EPROTO
);
392 static void usbback_process_unlink_req(struct usbback_req
*usbback_req
)
394 struct usbback_info
*usbif
;
395 struct usbback_req
*unlink_req
;
396 unsigned int id
, devnum
;
399 usbif
= usbback_req
->usbif
;
401 id
= usbback_req
->req
.u
.unlink
.unlink_id
;
402 TR_REQ(&usbif
->xendev
, "unlink id %d\n", id
);
403 devnum
= usbif_pipedevice(usbback_req
->req
.pipe
);
404 if (unlikely(devnum
== 0)) {
405 usbback_req
->stub
= usbif
->ports
+
406 usbif_pipeportnum(usbback_req
->req
.pipe
) - 1;
407 if (unlikely(!usbback_req
->stub
)) {
412 if (unlikely(!usbif
->addr_table
[devnum
])) {
416 usbback_req
->stub
= usbif
->addr_table
[devnum
];
419 QTAILQ_FOREACH(unlink_req
, &usbback_req
->stub
->submit_q
, q
) {
420 if (unlink_req
->req
.id
== id
) {
421 usbback_cancel_req(unlink_req
);
427 usbback_do_response_ret(usbback_req
, ret
);
431 * Checks whether a request can be handled at once or should be forwarded
432 * to the usb framework.
434 * 0 in case of usb framework is needed
435 * 1 in case of local handling (no error)
436 * The request response has been queued already if return value not 0.
438 static int usbback_check_and_submit(struct usbback_req
*usbback_req
)
440 struct usbback_info
*usbif
;
442 struct usbback_stub
*stub
;
443 struct usbif_ctrlrequest
*ctrl
;
447 usbif
= usbback_req
->usbif
;
449 devnum
= usbif_pipedevice(usbback_req
->req
.pipe
);
450 ctrl
= (struct usbif_ctrlrequest
*)usbback_req
->req
.u
.ctrl
;
451 wValue
= le16_to_cpu(ctrl
->wValue
);
454 * When the device is first connected or reset, USB device has no
455 * address. In this initial state, following requests are sent to device
458 * 1. GET_DESCRIPTOR (with Descriptor Type is "DEVICE") is sent,
459 * and OS knows what device is connected to.
461 * 2. SET_ADDRESS is sent, and then device has its address.
463 * In the next step, SET_CONFIGURATION is sent to addressed device, and
464 * then the device is finally ready to use.
466 if (unlikely(devnum
== 0)) {
467 stub
= usbif
->ports
+ usbif_pipeportnum(usbback_req
->req
.pipe
) - 1;
468 if (!stub
->dev
|| !stub
->attached
) {
473 switch (ctrl
->bRequest
) {
474 case USB_REQ_GET_DESCRIPTOR
:
476 * GET_DESCRIPTOR request to device #0.
477 * through normal transfer.
479 TR_REQ(&usbif
->xendev
, "devnum 0 GET_DESCRIPTOR\n");
480 usbback_req
->stub
= stub
;
482 case USB_REQ_SET_ADDRESS
:
484 * SET_ADDRESS request to device #0.
485 * add attached device to addr_table.
487 TR_REQ(&usbif
->xendev
, "devnum 0 SET_ADDRESS\n");
488 usbback_set_address(usbif
, stub
, 0, wValue
);
498 if (unlikely(!usbif
->addr_table
[devnum
])) {
502 usbback_req
->stub
= usbif
->addr_table
[devnum
];
505 * Check special request
507 if (ctrl
->bRequest
!= USB_REQ_SET_ADDRESS
) {
512 * SET_ADDRESS request to addressed device.
513 * change addr or remove from addr_table.
515 usbback_set_address(usbif
, usbback_req
->stub
, devnum
, wValue
);
519 usbback_do_response_ret(usbback_req
, ret
);
523 static void usbback_dispatch(struct usbback_req
*usbback_req
)
527 struct usbback_info
*usbif
;
529 usbif
= usbback_req
->usbif
;
531 TR_REQ(&usbif
->xendev
, "start req_id %d pipe %08x\n", usbback_req
->req
.id
,
532 usbback_req
->req
.pipe
);
535 if (unlikely(usbif_pipeunlink(usbback_req
->req
.pipe
))) {
536 usbback_process_unlink_req(usbback_req
);
540 if (usbif_pipectrl(usbback_req
->req
.pipe
)) {
541 if (usbback_check_and_submit(usbback_req
)) {
545 devnum
= usbif_pipedevice(usbback_req
->req
.pipe
);
546 usbback_req
->stub
= usbif
->addr_table
[devnum
];
548 if (!usbback_req
->stub
|| !usbback_req
->stub
->attached
) {
554 QTAILQ_INSERT_TAIL(&usbback_req
->stub
->submit_q
, usbback_req
, q
);
556 usbback_req
->nr_buffer_segs
= usbback_req
->req
.nr_buffer_segs
;
557 usbback_req
->nr_extra_segs
= usbif_pipeisoc(usbback_req
->req
.pipe
) ?
558 usbback_req
->req
.u
.isoc
.nr_frame_desc_segs
: 0;
560 ret
= usbback_init_packet(usbback_req
);
562 xen_pv_printf(&usbif
->xendev
, 0, "invalid request\n");
567 ret
= usbback_gnttab_map(usbback_req
);
569 xen_pv_printf(&usbif
->xendev
, 0, "invalid buffer, ret=%d\n", ret
);
574 usb_handle_packet(usbback_req
->stub
->dev
, &usbback_req
->packet
);
575 if (usbback_req
->packet
.status
!= USB_RET_ASYNC
) {
576 usbback_packet_complete(usbback_req
);
581 QTAILQ_REMOVE(&usbback_req
->stub
->submit_q
, usbback_req
, q
);
584 usbback_do_response_ret(usbback_req
, ret
);
587 static void usbback_hotplug_notify(struct usbback_info
*usbif
)
589 struct usbif_conn_back_ring
*ring
= &usbif
->conn_ring
;
590 struct usbif_conn_request req
;
591 struct usbif_conn_response
*res
;
592 struct usbback_hotplug
*usb_hp
;
595 if (!usbif
->conn_sring
) {
599 /* Check for full ring. */
600 if ((RING_SIZE(ring
) - ring
->rsp_prod_pvt
- ring
->req_cons
) == 0) {
601 xen_pv_send_notify(&usbif
->xendev
);
605 usb_hp
= QSIMPLEQ_FIRST(&usbif
->hotplug_q
);
606 QSIMPLEQ_REMOVE_HEAD(&usbif
->hotplug_q
, q
);
608 RING_COPY_REQUEST(ring
, ring
->req_cons
, &req
);
610 ring
->sring
->req_event
= ring
->req_cons
+ 1;
612 res
= RING_GET_RESPONSE(ring
, ring
->rsp_prod_pvt
);
614 res
->portnum
= usb_hp
->port
;
615 res
->speed
= usbif
->ports
[usb_hp
->port
- 1].speed
;
616 ring
->rsp_prod_pvt
++;
617 RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(ring
, notify
);
620 xen_pv_send_notify(&usbif
->xendev
);
623 TR_BUS(&usbif
->xendev
, "hotplug port %d speed %d\n", usb_hp
->port
,
628 if (!QSIMPLEQ_EMPTY(&usbif
->hotplug_q
)) {
629 qemu_bh_schedule(usbif
->bh
);
633 static void usbback_bh(void *opaque
)
635 struct usbback_info
*usbif
;
636 struct usbif_urb_back_ring
*urb_ring
;
637 struct usbback_req
*usbback_req
;
639 unsigned int more_to_do
;
642 if (usbif
->ring_error
) {
646 if (!QSIMPLEQ_EMPTY(&usbif
->hotplug_q
)) {
647 usbback_hotplug_notify(usbif
);
650 urb_ring
= &usbif
->urb_ring
;
651 rc
= urb_ring
->req_cons
;
652 rp
= urb_ring
->sring
->req_prod
;
653 xen_rmb(); /* Ensure we see queued requests up to 'rp'. */
655 if (RING_REQUEST_PROD_OVERFLOW(urb_ring
, rp
)) {
656 rc
= urb_ring
->rsp_prod_pvt
;
657 xen_pv_printf(&usbif
->xendev
, 0, "domU provided bogus ring requests "
658 "(%#x - %#x = %u). Halting ring processing.\n",
660 usbif
->ring_error
= true;
665 if (RING_REQUEST_CONS_OVERFLOW(urb_ring
, rc
)) {
668 usbback_req
= usbback_get_req(usbif
);
670 RING_COPY_REQUEST(urb_ring
, rc
, &usbback_req
->req
);
671 usbback_req
->usbif
= usbif
;
673 usbback_dispatch(usbback_req
);
675 urb_ring
->req_cons
= ++rc
;
678 RING_FINAL_CHECK_FOR_REQUESTS(urb_ring
, more_to_do
);
680 qemu_bh_schedule(usbif
->bh
);
684 static void usbback_hotplug_enq(struct usbback_info
*usbif
, unsigned port
)
686 struct usbback_hotplug
*usb_hp
;
688 usb_hp
= g_new0(struct usbback_hotplug
, 1);
690 QSIMPLEQ_INSERT_TAIL(&usbif
->hotplug_q
, usb_hp
, q
);
691 usbback_hotplug_notify(usbif
);
694 static void usbback_portid_drain(struct usbback_info
*usbif
, unsigned port
)
696 struct usbback_req
*req
, *tmp
;
699 QTAILQ_FOREACH_SAFE(req
, &usbif
->ports
[port
- 1].submit_q
, q
, tmp
) {
700 usbback_cancel_req(req
);
705 qemu_bh_schedule(usbif
->bh
);
709 static void usbback_portid_detach(struct usbback_info
*usbif
, unsigned port
)
711 if (!usbif
->ports
[port
- 1].attached
) {
715 usbif
->ports
[port
- 1].speed
= USBIF_SPEED_NONE
;
716 usbif
->ports
[port
- 1].attached
= false;
717 usbback_portid_drain(usbif
, port
);
718 usbback_hotplug_enq(usbif
, port
);
721 static void usbback_portid_remove(struct usbback_info
*usbif
, unsigned port
)
723 if (!usbif
->ports
[port
- 1].dev
) {
727 object_unparent(OBJECT(usbif
->ports
[port
- 1].dev
));
728 usbif
->ports
[port
- 1].dev
= NULL
;
729 usbback_portid_detach(usbif
, port
);
731 TR_BUS(&usbif
->xendev
, "port %d removed\n", port
);
734 static void usbback_portid_add(struct usbback_info
*usbif
, unsigned port
,
739 Error
*local_err
= NULL
;
744 if (usbif
->ports
[port
- 1].dev
) {
748 portname
= strchr(busid
, '-');
750 xen_pv_printf(&usbif
->xendev
, 0, "device %s illegal specification\n",
757 qdict_put_str(qdict
, "driver", "usb-host");
758 tmp
= g_strdup_printf("%s.0", usbif
->xendev
.qdev
.id
);
759 qdict_put_str(qdict
, "bus", tmp
);
761 tmp
= g_strdup_printf("%s-%u", usbif
->xendev
.qdev
.id
, port
);
762 qdict_put_str(qdict
, "id", tmp
);
764 qdict_put_int(qdict
, "port", port
);
765 qdict_put_int(qdict
, "hostbus", atoi(busid
));
766 qdict_put_str(qdict
, "hostport", portname
);
767 opts
= qemu_opts_from_qdict(qemu_find_opts("device"), qdict
,
769 usbif
->ports
[port
- 1].dev
= USB_DEVICE(qdev_device_add(opts
, &local_err
));
770 if (!usbif
->ports
[port
- 1].dev
) {
771 qobject_unref(qdict
);
772 xen_pv_printf(&usbif
->xendev
, 0,
773 "device %s could not be opened: %s\n",
774 busid
, error_get_pretty(local_err
));
775 error_free(local_err
);
778 qobject_unref(qdict
);
779 speed
= usbif
->ports
[port
- 1].dev
->speed
;
782 speed
= USBIF_SPEED_LOW
;
785 speed
= USBIF_SPEED_FULL
;
788 speed
= (usbif
->usb_ver
< USB_VER_USB20
) ?
789 USBIF_SPEED_NONE
: USBIF_SPEED_HIGH
;
792 speed
= USBIF_SPEED_NONE
;
795 if (speed
== USBIF_SPEED_NONE
) {
796 xen_pv_printf(&usbif
->xendev
, 0, "device %s wrong speed\n", busid
);
797 object_unparent(OBJECT(usbif
->ports
[port
- 1].dev
));
798 usbif
->ports
[port
- 1].dev
= NULL
;
801 usb_device_reset(usbif
->ports
[port
- 1].dev
);
802 usbif
->ports
[port
- 1].speed
= speed
;
803 usbif
->ports
[port
- 1].attached
= true;
804 QTAILQ_INIT(&usbif
->ports
[port
- 1].submit_q
);
805 usbback_hotplug_enq(usbif
, port
);
807 TR_BUS(&usbif
->xendev
, "port %d attached\n", port
);
810 static void usbback_process_port(struct usbback_info
*usbif
, unsigned port
)
815 snprintf(node
, sizeof(node
), "port/%d", port
);
816 busid
= xenstore_read_be_str(&usbif
->xendev
, node
);
818 xen_pv_printf(&usbif
->xendev
, 0, "xenstore_read %s failed\n", node
);
822 /* Remove portid, if the port is not connected. */
823 if (strlen(busid
) == 0) {
824 usbback_portid_remove(usbif
, port
);
826 usbback_portid_add(usbif
, port
, busid
);
832 static void usbback_disconnect(struct XenLegacyDevice
*xendev
)
834 struct usbback_info
*usbif
;
837 TR_BUS(xendev
, "start\n");
839 usbif
= container_of(xendev
, struct usbback_info
, xendev
);
841 xen_pv_unbind_evtchn(xendev
);
843 if (usbif
->urb_sring
) {
844 xen_be_unmap_grant_ref(xendev
, usbif
->urb_sring
, usbif
->urb_ring_ref
);
845 usbif
->urb_sring
= NULL
;
847 if (usbif
->conn_sring
) {
848 xen_be_unmap_grant_ref(xendev
, usbif
->conn_sring
, usbif
->conn_ring_ref
);
849 usbif
->conn_sring
= NULL
;
852 for (i
= 0; i
< usbif
->num_ports
; i
++) {
853 if (usbif
->ports
[i
].dev
) {
854 usbback_portid_drain(usbif
, i
+ 1);
858 TR_BUS(xendev
, "finished\n");
861 static int usbback_connect(struct XenLegacyDevice
*xendev
)
863 struct usbback_info
*usbif
;
864 struct usbif_urb_sring
*urb_sring
;
865 struct usbif_conn_sring
*conn_sring
;
868 unsigned int i
, max_grants
;
870 TR_BUS(xendev
, "start\n");
872 /* max_grants: for each request and for the rings (request and connect). */
873 max_grants
= USBIF_MAX_SEGMENTS_PER_REQUEST
* USB_URB_RING_SIZE
+ 2;
874 xen_be_set_max_grant_refs(xendev
, max_grants
);
876 usbif
= container_of(xendev
, struct usbback_info
, xendev
);
878 if (xenstore_read_fe_int(xendev
, "urb-ring-ref", &urb_ring_ref
)) {
879 xen_pv_printf(xendev
, 0, "error reading urb-ring-ref\n");
882 if (xenstore_read_fe_int(xendev
, "conn-ring-ref", &conn_ring_ref
)) {
883 xen_pv_printf(xendev
, 0, "error reading conn-ring-ref\n");
886 if (xenstore_read_fe_int(xendev
, "event-channel", &xendev
->remote_port
)) {
887 xen_pv_printf(xendev
, 0, "error reading event-channel\n");
891 usbif
->urb_sring
= xen_be_map_grant_ref(xendev
, urb_ring_ref
,
892 PROT_READ
| PROT_WRITE
);
893 usbif
->conn_sring
= xen_be_map_grant_ref(xendev
, conn_ring_ref
,
894 PROT_READ
| PROT_WRITE
);
895 if (!usbif
->urb_sring
|| !usbif
->conn_sring
) {
896 xen_pv_printf(xendev
, 0, "error mapping rings\n");
897 usbback_disconnect(xendev
);
901 usbif
->urb_ring_ref
= urb_ring_ref
;
902 usbif
->conn_ring_ref
= conn_ring_ref
;
903 urb_sring
= usbif
->urb_sring
;
904 conn_sring
= usbif
->conn_sring
;
905 BACK_RING_INIT(&usbif
->urb_ring
, urb_sring
, XEN_PAGE_SIZE
);
906 BACK_RING_INIT(&usbif
->conn_ring
, conn_sring
, XEN_PAGE_SIZE
);
908 xen_be_bind_evtchn(xendev
);
910 xen_pv_printf(xendev
, 1, "urb-ring-ref %d, conn-ring-ref %d, "
911 "remote port %d, local port %d\n", urb_ring_ref
,
912 conn_ring_ref
, xendev
->remote_port
, xendev
->local_port
);
914 for (i
= 1; i
<= usbif
->num_ports
; i
++) {
915 if (usbif
->ports
[i
- 1].dev
) {
916 usbback_hotplug_enq(usbif
, i
);
923 static void usbback_backend_changed(struct XenLegacyDevice
*xendev
,
926 struct usbback_info
*usbif
;
929 TR_BUS(xendev
, "path %s\n", node
);
931 usbif
= container_of(xendev
, struct usbback_info
, xendev
);
932 for (i
= 1; i
<= usbif
->num_ports
; i
++) {
933 usbback_process_port(usbif
, i
);
937 static int usbback_init(struct XenLegacyDevice
*xendev
)
939 struct usbback_info
*usbif
;
941 TR_BUS(xendev
, "start\n");
943 usbif
= container_of(xendev
, struct usbback_info
, xendev
);
945 if (xenstore_read_be_int(xendev
, "num-ports", &usbif
->num_ports
) ||
946 usbif
->num_ports
< 1 || usbif
->num_ports
> USBBACK_MAXPORTS
) {
947 xen_pv_printf(xendev
, 0, "num-ports not readable or out of bounds\n");
950 if (xenstore_read_be_int(xendev
, "usb-ver", &usbif
->usb_ver
) ||
951 (usbif
->usb_ver
!= USB_VER_USB11
&& usbif
->usb_ver
!= USB_VER_USB20
)) {
952 xen_pv_printf(xendev
, 0, "usb-ver not readable or out of bounds\n");
956 usbback_backend_changed(xendev
, "port");
958 TR_BUS(xendev
, "finished\n");
963 static void xen_bus_attach(USBPort
*port
)
965 struct usbback_info
*usbif
;
967 usbif
= port
->opaque
;
968 TR_BUS(&usbif
->xendev
, "\n");
969 usbif
->ports
[port
->index
].attached
= true;
970 usbback_hotplug_enq(usbif
, port
->index
+ 1);
973 static void xen_bus_detach(USBPort
*port
)
975 struct usbback_info
*usbif
;
977 usbif
= port
->opaque
;
978 TR_BUS(&usbif
->xendev
, "\n");
979 usbback_portid_detach(usbif
, port
->index
+ 1);
982 static void xen_bus_child_detach(USBPort
*port
, USBDevice
*child
)
984 struct usbback_info
*usbif
;
986 usbif
= port
->opaque
;
987 TR_BUS(&usbif
->xendev
, "\n");
990 static void xen_bus_complete(USBPort
*port
, USBPacket
*packet
)
992 struct usbback_req
*usbback_req
;
993 struct usbback_info
*usbif
;
995 usbback_req
= container_of(packet
, struct usbback_req
, packet
);
996 if (usbback_req
->cancelled
) {
1001 usbif
= usbback_req
->usbif
;
1002 TR_REQ(&usbif
->xendev
, "\n");
1003 usbback_packet_complete(usbback_req
);
1006 static USBPortOps xen_usb_port_ops
= {
1007 .attach
= xen_bus_attach
,
1008 .detach
= xen_bus_detach
,
1009 .child_detach
= xen_bus_child_detach
,
1010 .complete
= xen_bus_complete
,
1013 static USBBusOps xen_usb_bus_ops
= {
1016 static void usbback_alloc(struct XenLegacyDevice
*xendev
)
1018 struct usbback_info
*usbif
;
1022 usbif
= container_of(xendev
, struct usbback_info
, xendev
);
1024 usb_bus_new(&usbif
->bus
, sizeof(usbif
->bus
), &xen_usb_bus_ops
,
1025 DEVICE(&xendev
->qdev
));
1026 for (i
= 0; i
< USBBACK_MAXPORTS
; i
++) {
1027 p
= &(usbif
->ports
[i
].port
);
1028 usb_register_port(&usbif
->bus
, p
, usbif
, i
, &xen_usb_port_ops
,
1029 USB_SPEED_MASK_LOW
| USB_SPEED_MASK_FULL
|
1030 USB_SPEED_MASK_HIGH
);
1033 QTAILQ_INIT(&usbif
->req_free_q
);
1034 QSIMPLEQ_INIT(&usbif
->hotplug_q
);
1035 usbif
->bh
= qemu_bh_new_guarded(usbback_bh
, usbif
,
1036 &DEVICE(xendev
)->mem_reentrancy_guard
);
1039 static int usbback_free(struct XenLegacyDevice
*xendev
)
1041 struct usbback_info
*usbif
;
1042 struct usbback_req
*usbback_req
;
1043 struct usbback_hotplug
*usb_hp
;
1046 TR_BUS(xendev
, "start\n");
1048 usbback_disconnect(xendev
);
1049 usbif
= container_of(xendev
, struct usbback_info
, xendev
);
1050 for (i
= 1; i
<= usbif
->num_ports
; i
++) {
1051 usbback_portid_remove(usbif
, i
);
1054 while (!QTAILQ_EMPTY(&usbif
->req_free_q
)) {
1055 usbback_req
= QTAILQ_FIRST(&usbif
->req_free_q
);
1056 QTAILQ_REMOVE(&usbif
->req_free_q
, usbback_req
, q
);
1057 g_free(usbback_req
);
1059 while (!QSIMPLEQ_EMPTY(&usbif
->hotplug_q
)) {
1060 usb_hp
= QSIMPLEQ_FIRST(&usbif
->hotplug_q
);
1061 QSIMPLEQ_REMOVE_HEAD(&usbif
->hotplug_q
, q
);
1065 qemu_bh_delete(usbif
->bh
);
1067 for (i
= 0; i
< USBBACK_MAXPORTS
; i
++) {
1068 usb_unregister_port(&usbif
->bus
, &(usbif
->ports
[i
].port
));
1071 usb_bus_release(&usbif
->bus
);
1073 TR_BUS(xendev
, "finished\n");
1078 static void usbback_event(struct XenLegacyDevice
*xendev
)
1080 struct usbback_info
*usbif
;
1082 usbif
= container_of(xendev
, struct usbback_info
, xendev
);
1083 qemu_bh_schedule(usbif
->bh
);
1086 struct XenDevOps xen_usb_ops
= {
1087 .size
= sizeof(struct usbback_info
),
1088 .flags
= DEVOPS_FLAG_NEED_GNTDEV
,
1089 .init
= usbback_init
,
1090 .alloc
= usbback_alloc
,
1091 .free
= usbback_free
,
1092 .backend_changed
= usbback_backend_changed
,
1093 .initialise
= usbback_connect
,
1094 .disconnect
= usbback_disconnect
,
1095 .event
= usbback_event
,
1098 #else /* USBIF_SHORT_NOT_OK */
1100 static int usbback_not_supported(void)
1105 struct XenDevOps xen_usb_ops
= {
1106 .backend_register
= usbback_not_supported
,