1*816ac92eSJuergen Gross /* 2*816ac92eSJuergen Gross * xen paravirt usb device backend 3*816ac92eSJuergen Gross * 4*816ac92eSJuergen Gross * (c) Juergen Gross <jgross@suse.com> 5*816ac92eSJuergen Gross * 6*816ac92eSJuergen Gross * This program is free software; you can redistribute it and/or modify 7*816ac92eSJuergen Gross * it under the terms of the GNU General Public License as published by 8*816ac92eSJuergen Gross * the Free Software Foundation; under version 2 of the License. 9*816ac92eSJuergen Gross * 10*816ac92eSJuergen Gross * This program is distributed in the hope that it will be useful, 11*816ac92eSJuergen Gross * but WITHOUT ANY WARRANTY; without even the implied warranty of 12*816ac92eSJuergen Gross * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13*816ac92eSJuergen Gross * GNU General Public License for more details. 14*816ac92eSJuergen Gross * 15*816ac92eSJuergen Gross * You should have received a copy of the GNU General Public License along 16*816ac92eSJuergen Gross * with this program; if not, see <http://www.gnu.org/licenses/>. 17*816ac92eSJuergen Gross * 18*816ac92eSJuergen Gross * Contributions after 2012-01-13 are licensed under the terms of the 19*816ac92eSJuergen Gross * GNU GPL, version 2 or (at your option) any later version. 20*816ac92eSJuergen Gross */ 21*816ac92eSJuergen Gross 22*816ac92eSJuergen Gross #include <libusb.h> 23*816ac92eSJuergen Gross #include <stdio.h> 24*816ac92eSJuergen Gross #include <sys/types.h> 25*816ac92eSJuergen Gross #include <sys/mman.h> 26*816ac92eSJuergen Gross #include <sys/time.h> 27*816ac92eSJuergen Gross 28*816ac92eSJuergen Gross #include "qemu/osdep.h" 29*816ac92eSJuergen Gross #include "qemu-common.h" 30*816ac92eSJuergen Gross #include "qemu/config-file.h" 31*816ac92eSJuergen Gross #include "hw/sysbus.h" 32*816ac92eSJuergen Gross #include "hw/usb.h" 33*816ac92eSJuergen Gross #include "hw/xen/xen_backend.h" 34*816ac92eSJuergen Gross #include "monitor/qdev.h" 35*816ac92eSJuergen Gross #include "qapi/qmp/qbool.h" 36*816ac92eSJuergen Gross #include "qapi/qmp/qint.h" 37*816ac92eSJuergen Gross #include "qapi/qmp/qstring.h" 38*816ac92eSJuergen Gross #include "sys/user.h" 39*816ac92eSJuergen Gross 40*816ac92eSJuergen Gross #include <xen/io/ring.h> 41*816ac92eSJuergen Gross #include <xen/io/usbif.h> 42*816ac92eSJuergen Gross 43*816ac92eSJuergen Gross /* 44*816ac92eSJuergen Gross * Check for required support of usbif.h: USBIF_SHORT_NOT_OK was the last 45*816ac92eSJuergen Gross * macro added we rely on. 46*816ac92eSJuergen Gross */ 47*816ac92eSJuergen Gross #ifdef USBIF_SHORT_NOT_OK 48*816ac92eSJuergen Gross 49*816ac92eSJuergen Gross #define TR(xendev, lvl, fmt, args...) \ 50*816ac92eSJuergen Gross { \ 51*816ac92eSJuergen Gross struct timeval tv; \ 52*816ac92eSJuergen Gross \ 53*816ac92eSJuergen Gross gettimeofday(&tv, NULL); \ 54*816ac92eSJuergen Gross xen_be_printf(xendev, lvl, "%8ld.%06ld xen-usb(%s):" fmt, \ 55*816ac92eSJuergen Gross tv.tv_sec, tv.tv_usec, __func__, ##args); \ 56*816ac92eSJuergen Gross } 57*816ac92eSJuergen Gross #define TR_BUS(xendev, fmt, args...) TR(xendev, 2, fmt, ##args) 58*816ac92eSJuergen Gross #define TR_REQ(xendev, fmt, args...) TR(xendev, 3, fmt, ##args) 59*816ac92eSJuergen Gross 60*816ac92eSJuergen Gross #define USBBACK_MAXPORTS USBIF_PIPE_PORT_MASK 61*816ac92eSJuergen Gross #define USB_DEV_ADDR_SIZE (USBIF_PIPE_DEV_MASK + 1) 62*816ac92eSJuergen Gross 63*816ac92eSJuergen Gross /* USB wire protocol: structure describing control request parameter. */ 64*816ac92eSJuergen Gross struct usbif_ctrlrequest { 65*816ac92eSJuergen Gross uint8_t bRequestType; 66*816ac92eSJuergen Gross uint8_t bRequest; 67*816ac92eSJuergen Gross uint16_t wValue; 68*816ac92eSJuergen Gross uint16_t wIndex; 69*816ac92eSJuergen Gross uint16_t wLength; 70*816ac92eSJuergen Gross }; 71*816ac92eSJuergen Gross 72*816ac92eSJuergen Gross struct usbback_info; 73*816ac92eSJuergen Gross struct usbback_req; 74*816ac92eSJuergen Gross 75*816ac92eSJuergen Gross struct usbback_stub { 76*816ac92eSJuergen Gross USBDevice *dev; 77*816ac92eSJuergen Gross USBPort port; 78*816ac92eSJuergen Gross unsigned int speed; 79*816ac92eSJuergen Gross bool attached; 80*816ac92eSJuergen Gross QTAILQ_HEAD(submit_q_head, usbback_req) submit_q; 81*816ac92eSJuergen Gross }; 82*816ac92eSJuergen Gross 83*816ac92eSJuergen Gross struct usbback_req { 84*816ac92eSJuergen Gross struct usbback_info *usbif; 85*816ac92eSJuergen Gross struct usbback_stub *stub; 86*816ac92eSJuergen Gross struct usbif_urb_request req; 87*816ac92eSJuergen Gross USBPacket packet; 88*816ac92eSJuergen Gross 89*816ac92eSJuergen Gross unsigned int nr_buffer_segs; /* # of transfer_buffer segments */ 90*816ac92eSJuergen Gross unsigned int nr_extra_segs; /* # of iso_frame_desc segments */ 91*816ac92eSJuergen Gross 92*816ac92eSJuergen Gross QTAILQ_ENTRY(usbback_req) q; 93*816ac92eSJuergen Gross 94*816ac92eSJuergen Gross void *buffer; 95*816ac92eSJuergen Gross void *isoc_buffer; 96*816ac92eSJuergen Gross struct libusb_transfer *xfer; 97*816ac92eSJuergen Gross }; 98*816ac92eSJuergen Gross 99*816ac92eSJuergen Gross struct usbback_hotplug { 100*816ac92eSJuergen Gross QSIMPLEQ_ENTRY(usbback_hotplug) q; 101*816ac92eSJuergen Gross unsigned port; 102*816ac92eSJuergen Gross }; 103*816ac92eSJuergen Gross 104*816ac92eSJuergen Gross struct usbback_info { 105*816ac92eSJuergen Gross struct XenDevice xendev; /* must be first */ 106*816ac92eSJuergen Gross USBBus bus; 107*816ac92eSJuergen Gross void *urb_sring; 108*816ac92eSJuergen Gross void *conn_sring; 109*816ac92eSJuergen Gross struct usbif_urb_back_ring urb_ring; 110*816ac92eSJuergen Gross struct usbif_conn_back_ring conn_ring; 111*816ac92eSJuergen Gross int num_ports; 112*816ac92eSJuergen Gross int usb_ver; 113*816ac92eSJuergen Gross bool ring_error; 114*816ac92eSJuergen Gross QTAILQ_HEAD(req_free_q_head, usbback_req) req_free_q; 115*816ac92eSJuergen Gross QSIMPLEQ_HEAD(hotplug_q_head, usbback_hotplug) hotplug_q; 116*816ac92eSJuergen Gross struct usbback_stub ports[USBBACK_MAXPORTS]; 117*816ac92eSJuergen Gross struct usbback_stub *addr_table[USB_DEV_ADDR_SIZE]; 118*816ac92eSJuergen Gross QEMUBH *bh; 119*816ac92eSJuergen Gross }; 120*816ac92eSJuergen Gross 121*816ac92eSJuergen Gross static struct usbback_req *usbback_get_req(struct usbback_info *usbif) 122*816ac92eSJuergen Gross { 123*816ac92eSJuergen Gross struct usbback_req *usbback_req; 124*816ac92eSJuergen Gross 125*816ac92eSJuergen Gross if (QTAILQ_EMPTY(&usbif->req_free_q)) { 126*816ac92eSJuergen Gross usbback_req = g_new0(struct usbback_req, 1); 127*816ac92eSJuergen Gross } else { 128*816ac92eSJuergen Gross usbback_req = QTAILQ_FIRST(&usbif->req_free_q); 129*816ac92eSJuergen Gross QTAILQ_REMOVE(&usbif->req_free_q, usbback_req, q); 130*816ac92eSJuergen Gross } 131*816ac92eSJuergen Gross return usbback_req; 132*816ac92eSJuergen Gross } 133*816ac92eSJuergen Gross 134*816ac92eSJuergen Gross static void usbback_put_req(struct usbback_req *usbback_req) 135*816ac92eSJuergen Gross { 136*816ac92eSJuergen Gross struct usbback_info *usbif; 137*816ac92eSJuergen Gross 138*816ac92eSJuergen Gross usbif = usbback_req->usbif; 139*816ac92eSJuergen Gross memset(usbback_req, 0, sizeof(*usbback_req)); 140*816ac92eSJuergen Gross QTAILQ_INSERT_HEAD(&usbif->req_free_q, usbback_req, q); 141*816ac92eSJuergen Gross } 142*816ac92eSJuergen Gross 143*816ac92eSJuergen Gross static int usbback_gnttab_map(struct usbback_req *usbback_req) 144*816ac92eSJuergen Gross { 145*816ac92eSJuergen Gross unsigned int nr_segs, i, prot; 146*816ac92eSJuergen Gross uint32_t ref[USBIF_MAX_SEGMENTS_PER_REQUEST]; 147*816ac92eSJuergen Gross struct usbback_info *usbif = usbback_req->usbif; 148*816ac92eSJuergen Gross struct XenDevice *xendev = &usbif->xendev; 149*816ac92eSJuergen Gross struct usbif_request_segment *seg; 150*816ac92eSJuergen Gross void *addr; 151*816ac92eSJuergen Gross 152*816ac92eSJuergen Gross nr_segs = usbback_req->nr_buffer_segs + usbback_req->nr_extra_segs; 153*816ac92eSJuergen Gross if (!nr_segs) { 154*816ac92eSJuergen Gross return 0; 155*816ac92eSJuergen Gross } 156*816ac92eSJuergen Gross 157*816ac92eSJuergen Gross if (nr_segs > USBIF_MAX_SEGMENTS_PER_REQUEST) { 158*816ac92eSJuergen Gross xen_be_printf(xendev, 0, "bad number of segments in request (%d)\n", 159*816ac92eSJuergen Gross nr_segs); 160*816ac92eSJuergen Gross return -EINVAL; 161*816ac92eSJuergen Gross } 162*816ac92eSJuergen Gross 163*816ac92eSJuergen Gross for (i = 0; i < nr_segs; i++) { 164*816ac92eSJuergen Gross if ((unsigned)usbback_req->req.seg[i].offset + 165*816ac92eSJuergen Gross (unsigned)usbback_req->req.seg[i].length > PAGE_SIZE) { 166*816ac92eSJuergen Gross xen_be_printf(xendev, 0, "segment crosses page boundary\n"); 167*816ac92eSJuergen Gross return -EINVAL; 168*816ac92eSJuergen Gross } 169*816ac92eSJuergen Gross } 170*816ac92eSJuergen Gross 171*816ac92eSJuergen Gross if (usbback_req->nr_buffer_segs) { 172*816ac92eSJuergen Gross prot = PROT_READ; 173*816ac92eSJuergen Gross if (usbif_pipein(usbback_req->req.pipe)) { 174*816ac92eSJuergen Gross prot |= PROT_WRITE; 175*816ac92eSJuergen Gross } 176*816ac92eSJuergen Gross for (i = 0; i < usbback_req->nr_buffer_segs; i++) { 177*816ac92eSJuergen Gross ref[i] = usbback_req->req.seg[i].gref; 178*816ac92eSJuergen Gross } 179*816ac92eSJuergen Gross usbback_req->buffer = xengnttab_map_domain_grant_refs(xendev->gnttabdev, 180*816ac92eSJuergen Gross usbback_req->nr_buffer_segs, xendev->dom, ref, prot); 181*816ac92eSJuergen Gross 182*816ac92eSJuergen Gross if (!usbback_req->buffer) { 183*816ac92eSJuergen Gross return -ENOMEM; 184*816ac92eSJuergen Gross } 185*816ac92eSJuergen Gross 186*816ac92eSJuergen Gross for (i = 0; i < usbback_req->nr_buffer_segs; i++) { 187*816ac92eSJuergen Gross seg = usbback_req->req.seg + i; 188*816ac92eSJuergen Gross addr = usbback_req->buffer + i * PAGE_SIZE + seg->offset; 189*816ac92eSJuergen Gross qemu_iovec_add(&usbback_req->packet.iov, addr, seg->length); 190*816ac92eSJuergen Gross } 191*816ac92eSJuergen Gross } 192*816ac92eSJuergen Gross 193*816ac92eSJuergen Gross if (!usbif_pipeisoc(usbback_req->req.pipe)) { 194*816ac92eSJuergen Gross return 0; 195*816ac92eSJuergen Gross } 196*816ac92eSJuergen Gross 197*816ac92eSJuergen Gross /* 198*816ac92eSJuergen Gross * Right now isoc requests are not supported. 199*816ac92eSJuergen Gross * Prepare supporting those by doing the work needed on the guest 200*816ac92eSJuergen Gross * interface side. 201*816ac92eSJuergen Gross */ 202*816ac92eSJuergen Gross 203*816ac92eSJuergen Gross if (!usbback_req->nr_extra_segs) { 204*816ac92eSJuergen Gross xen_be_printf(xendev, 0, "iso request without descriptor segments\n"); 205*816ac92eSJuergen Gross return -EINVAL; 206*816ac92eSJuergen Gross } 207*816ac92eSJuergen Gross 208*816ac92eSJuergen Gross prot = PROT_READ | PROT_WRITE; 209*816ac92eSJuergen Gross for (i = 0; i < usbback_req->nr_extra_segs; i++) { 210*816ac92eSJuergen Gross ref[i] = usbback_req->req.seg[i + usbback_req->req.nr_buffer_segs].gref; 211*816ac92eSJuergen Gross } 212*816ac92eSJuergen Gross usbback_req->isoc_buffer = xengnttab_map_domain_grant_refs( 213*816ac92eSJuergen Gross xendev->gnttabdev, usbback_req->nr_extra_segs, xendev->dom, ref, prot); 214*816ac92eSJuergen Gross 215*816ac92eSJuergen Gross if (!usbback_req->isoc_buffer) { 216*816ac92eSJuergen Gross return -ENOMEM; 217*816ac92eSJuergen Gross } 218*816ac92eSJuergen Gross 219*816ac92eSJuergen Gross return 0; 220*816ac92eSJuergen Gross } 221*816ac92eSJuergen Gross 222*816ac92eSJuergen Gross static int usbback_init_packet(struct usbback_req *usbback_req) 223*816ac92eSJuergen Gross { 224*816ac92eSJuergen Gross struct XenDevice *xendev = &usbback_req->usbif->xendev; 225*816ac92eSJuergen Gross USBPacket *packet = &usbback_req->packet; 226*816ac92eSJuergen Gross USBDevice *dev = usbback_req->stub->dev; 227*816ac92eSJuergen Gross USBEndpoint *ep; 228*816ac92eSJuergen Gross unsigned int pid, ep_nr; 229*816ac92eSJuergen Gross bool sok; 230*816ac92eSJuergen Gross int ret = 0; 231*816ac92eSJuergen Gross 232*816ac92eSJuergen Gross qemu_iovec_init(&packet->iov, USBIF_MAX_SEGMENTS_PER_REQUEST); 233*816ac92eSJuergen Gross pid = usbif_pipein(usbback_req->req.pipe) ? USB_TOKEN_IN : USB_TOKEN_OUT; 234*816ac92eSJuergen Gross ep_nr = usbif_pipeendpoint(usbback_req->req.pipe); 235*816ac92eSJuergen Gross sok = !!(usbback_req->req.transfer_flags & USBIF_SHORT_NOT_OK); 236*816ac92eSJuergen Gross if (usbif_pipectrl(usbback_req->req.pipe)) { 237*816ac92eSJuergen Gross ep_nr = 0; 238*816ac92eSJuergen Gross sok = false; 239*816ac92eSJuergen Gross } 240*816ac92eSJuergen Gross ep = usb_ep_get(dev, pid, ep_nr); 241*816ac92eSJuergen Gross usb_packet_setup(packet, pid, ep, 0, 1, sok, true); 242*816ac92eSJuergen Gross 243*816ac92eSJuergen Gross switch (usbif_pipetype(usbback_req->req.pipe)) { 244*816ac92eSJuergen Gross case USBIF_PIPE_TYPE_ISOC: 245*816ac92eSJuergen Gross TR_REQ(xendev, "iso transfer %s: buflen: %x, %d frames\n", 246*816ac92eSJuergen Gross (pid == USB_TOKEN_IN) ? "in" : "out", 247*816ac92eSJuergen Gross usbback_req->req.buffer_length, 248*816ac92eSJuergen Gross usbback_req->req.u.isoc.nr_frame_desc_segs); 249*816ac92eSJuergen Gross ret = -EINVAL; /* isoc not implemented yet */ 250*816ac92eSJuergen Gross break; 251*816ac92eSJuergen Gross 252*816ac92eSJuergen Gross case USBIF_PIPE_TYPE_INT: 253*816ac92eSJuergen Gross TR_REQ(xendev, "int transfer %s: buflen: %x\n", 254*816ac92eSJuergen Gross (pid == USB_TOKEN_IN) ? "in" : "out", 255*816ac92eSJuergen Gross usbback_req->req.buffer_length); 256*816ac92eSJuergen Gross break; 257*816ac92eSJuergen Gross 258*816ac92eSJuergen Gross case USBIF_PIPE_TYPE_CTRL: 259*816ac92eSJuergen Gross packet->parameter = *(uint64_t *)usbback_req->req.u.ctrl; 260*816ac92eSJuergen Gross TR_REQ(xendev, "ctrl parameter: %lx, buflen: %x\n", packet->parameter, 261*816ac92eSJuergen Gross usbback_req->req.buffer_length); 262*816ac92eSJuergen Gross break; 263*816ac92eSJuergen Gross 264*816ac92eSJuergen Gross case USBIF_PIPE_TYPE_BULK: 265*816ac92eSJuergen Gross TR_REQ(xendev, "bulk transfer %s: buflen: %x\n", 266*816ac92eSJuergen Gross (pid == USB_TOKEN_IN) ? "in" : "out", 267*816ac92eSJuergen Gross usbback_req->req.buffer_length); 268*816ac92eSJuergen Gross break; 269*816ac92eSJuergen Gross default: 270*816ac92eSJuergen Gross ret = -EINVAL; 271*816ac92eSJuergen Gross break; 272*816ac92eSJuergen Gross } 273*816ac92eSJuergen Gross 274*816ac92eSJuergen Gross return ret; 275*816ac92eSJuergen Gross } 276*816ac92eSJuergen Gross 277*816ac92eSJuergen Gross static void usbback_do_response(struct usbback_req *usbback_req, int32_t status, 278*816ac92eSJuergen Gross int32_t actual_length, int32_t error_count) 279*816ac92eSJuergen Gross { 280*816ac92eSJuergen Gross struct usbback_info *usbif; 281*816ac92eSJuergen Gross struct usbif_urb_response *res; 282*816ac92eSJuergen Gross struct XenDevice *xendev; 283*816ac92eSJuergen Gross unsigned int notify; 284*816ac92eSJuergen Gross 285*816ac92eSJuergen Gross usbif = usbback_req->usbif; 286*816ac92eSJuergen Gross xendev = &usbif->xendev; 287*816ac92eSJuergen Gross 288*816ac92eSJuergen Gross TR_REQ(xendev, "id %d, status %d, length %d, errcnt %d\n", 289*816ac92eSJuergen Gross usbback_req->req.id, status, actual_length, error_count); 290*816ac92eSJuergen Gross 291*816ac92eSJuergen Gross if (usbback_req->packet.iov.iov) { 292*816ac92eSJuergen Gross qemu_iovec_destroy(&usbback_req->packet.iov); 293*816ac92eSJuergen Gross } 294*816ac92eSJuergen Gross 295*816ac92eSJuergen Gross if (usbback_req->buffer) { 296*816ac92eSJuergen Gross xengnttab_unmap(xendev->gnttabdev, usbback_req->buffer, 297*816ac92eSJuergen Gross usbback_req->nr_buffer_segs); 298*816ac92eSJuergen Gross usbback_req->buffer = NULL; 299*816ac92eSJuergen Gross } 300*816ac92eSJuergen Gross 301*816ac92eSJuergen Gross if (usbback_req->isoc_buffer) { 302*816ac92eSJuergen Gross xengnttab_unmap(xendev->gnttabdev, usbback_req->isoc_buffer, 303*816ac92eSJuergen Gross usbback_req->nr_extra_segs); 304*816ac92eSJuergen Gross usbback_req->isoc_buffer = NULL; 305*816ac92eSJuergen Gross } 306*816ac92eSJuergen Gross 307*816ac92eSJuergen Gross res = RING_GET_RESPONSE(&usbif->urb_ring, usbif->urb_ring.rsp_prod_pvt); 308*816ac92eSJuergen Gross res->id = usbback_req->req.id; 309*816ac92eSJuergen Gross res->status = status; 310*816ac92eSJuergen Gross res->actual_length = actual_length; 311*816ac92eSJuergen Gross res->error_count = error_count; 312*816ac92eSJuergen Gross res->start_frame = 0; 313*816ac92eSJuergen Gross usbif->urb_ring.rsp_prod_pvt++; 314*816ac92eSJuergen Gross RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&usbif->urb_ring, notify); 315*816ac92eSJuergen Gross 316*816ac92eSJuergen Gross if (notify) { 317*816ac92eSJuergen Gross xen_be_send_notify(xendev); 318*816ac92eSJuergen Gross } 319*816ac92eSJuergen Gross 320*816ac92eSJuergen Gross usbback_put_req(usbback_req); 321*816ac92eSJuergen Gross } 322*816ac92eSJuergen Gross 323*816ac92eSJuergen Gross static void usbback_do_response_ret(struct usbback_req *usbback_req, 324*816ac92eSJuergen Gross int32_t status) 325*816ac92eSJuergen Gross { 326*816ac92eSJuergen Gross usbback_do_response(usbback_req, status, 0, 0); 327*816ac92eSJuergen Gross } 328*816ac92eSJuergen Gross 329*816ac92eSJuergen Gross static int32_t usbback_xlat_status(int status) 330*816ac92eSJuergen Gross { 331*816ac92eSJuergen Gross switch (status) { 332*816ac92eSJuergen Gross case USB_RET_SUCCESS: 333*816ac92eSJuergen Gross return 0; 334*816ac92eSJuergen Gross case USB_RET_NODEV: 335*816ac92eSJuergen Gross return -ENODEV; 336*816ac92eSJuergen Gross case USB_RET_STALL: 337*816ac92eSJuergen Gross return -EPIPE; 338*816ac92eSJuergen Gross case USB_RET_BABBLE: 339*816ac92eSJuergen Gross return -EOVERFLOW; 340*816ac92eSJuergen Gross case USB_RET_IOERROR: 341*816ac92eSJuergen Gross return -EPROTO; 342*816ac92eSJuergen Gross } 343*816ac92eSJuergen Gross 344*816ac92eSJuergen Gross return -ESHUTDOWN; 345*816ac92eSJuergen Gross } 346*816ac92eSJuergen Gross 347*816ac92eSJuergen Gross static void usbback_packet_complete(USBPacket *packet) 348*816ac92eSJuergen Gross { 349*816ac92eSJuergen Gross struct usbback_req *usbback_req; 350*816ac92eSJuergen Gross int32_t status; 351*816ac92eSJuergen Gross 352*816ac92eSJuergen Gross usbback_req = container_of(packet, struct usbback_req, packet); 353*816ac92eSJuergen Gross 354*816ac92eSJuergen Gross QTAILQ_REMOVE(&usbback_req->stub->submit_q, usbback_req, q); 355*816ac92eSJuergen Gross 356*816ac92eSJuergen Gross status = usbback_xlat_status(packet->status); 357*816ac92eSJuergen Gross usbback_do_response(usbback_req, status, packet->actual_length, 0); 358*816ac92eSJuergen Gross } 359*816ac92eSJuergen Gross 360*816ac92eSJuergen Gross static void usbback_set_address(struct usbback_info *usbif, 361*816ac92eSJuergen Gross struct usbback_stub *stub, 362*816ac92eSJuergen Gross unsigned int cur_addr, unsigned int new_addr) 363*816ac92eSJuergen Gross { 364*816ac92eSJuergen Gross if (cur_addr) { 365*816ac92eSJuergen Gross usbif->addr_table[cur_addr] = NULL; 366*816ac92eSJuergen Gross } 367*816ac92eSJuergen Gross if (new_addr) { 368*816ac92eSJuergen Gross usbif->addr_table[new_addr] = stub; 369*816ac92eSJuergen Gross } 370*816ac92eSJuergen Gross } 371*816ac92eSJuergen Gross 372*816ac92eSJuergen Gross static bool usbback_cancel_req(struct usbback_req *usbback_req) 373*816ac92eSJuergen Gross { 374*816ac92eSJuergen Gross bool ret = false; 375*816ac92eSJuergen Gross 376*816ac92eSJuergen Gross if (usb_packet_is_inflight(&usbback_req->packet)) { 377*816ac92eSJuergen Gross usb_cancel_packet(&usbback_req->packet); 378*816ac92eSJuergen Gross ret = true; 379*816ac92eSJuergen Gross } 380*816ac92eSJuergen Gross return ret; 381*816ac92eSJuergen Gross } 382*816ac92eSJuergen Gross 383*816ac92eSJuergen Gross static void usbback_process_unlink_req(struct usbback_req *usbback_req) 384*816ac92eSJuergen Gross { 385*816ac92eSJuergen Gross struct usbback_info *usbif; 386*816ac92eSJuergen Gross struct usbback_req *unlink_req; 387*816ac92eSJuergen Gross unsigned int id, devnum; 388*816ac92eSJuergen Gross int ret; 389*816ac92eSJuergen Gross 390*816ac92eSJuergen Gross usbif = usbback_req->usbif; 391*816ac92eSJuergen Gross ret = 0; 392*816ac92eSJuergen Gross id = usbback_req->req.u.unlink.unlink_id; 393*816ac92eSJuergen Gross TR_REQ(&usbif->xendev, "unlink id %d\n", id); 394*816ac92eSJuergen Gross devnum = usbif_pipedevice(usbback_req->req.pipe); 395*816ac92eSJuergen Gross if (unlikely(devnum == 0)) { 396*816ac92eSJuergen Gross usbback_req->stub = usbif->ports + 397*816ac92eSJuergen Gross usbif_pipeportnum(usbback_req->req.pipe); 398*816ac92eSJuergen Gross if (unlikely(!usbback_req->stub)) { 399*816ac92eSJuergen Gross ret = -ENODEV; 400*816ac92eSJuergen Gross goto fail_response; 401*816ac92eSJuergen Gross } 402*816ac92eSJuergen Gross } else { 403*816ac92eSJuergen Gross if (unlikely(!usbif->addr_table[devnum])) { 404*816ac92eSJuergen Gross ret = -ENODEV; 405*816ac92eSJuergen Gross goto fail_response; 406*816ac92eSJuergen Gross } 407*816ac92eSJuergen Gross usbback_req->stub = usbif->addr_table[devnum]; 408*816ac92eSJuergen Gross } 409*816ac92eSJuergen Gross 410*816ac92eSJuergen Gross QTAILQ_FOREACH(unlink_req, &usbback_req->stub->submit_q, q) { 411*816ac92eSJuergen Gross if (unlink_req->req.id == id) { 412*816ac92eSJuergen Gross if (usbback_cancel_req(unlink_req)) { 413*816ac92eSJuergen Gross usbback_do_response_ret(unlink_req, -EPROTO); 414*816ac92eSJuergen Gross } 415*816ac92eSJuergen Gross break; 416*816ac92eSJuergen Gross } 417*816ac92eSJuergen Gross } 418*816ac92eSJuergen Gross 419*816ac92eSJuergen Gross fail_response: 420*816ac92eSJuergen Gross usbback_do_response_ret(usbback_req, ret); 421*816ac92eSJuergen Gross } 422*816ac92eSJuergen Gross 423*816ac92eSJuergen Gross /* 424*816ac92eSJuergen Gross * Checks whether a request can be handled at once or should be forwarded 425*816ac92eSJuergen Gross * to the usb framework. 426*816ac92eSJuergen Gross * Return value is: 427*816ac92eSJuergen Gross * 0 in case of usb framework is needed 428*816ac92eSJuergen Gross * 1 in case of local handling (no error) 429*816ac92eSJuergen Gross * The request response has been queued already if return value not 0. 430*816ac92eSJuergen Gross */ 431*816ac92eSJuergen Gross static int usbback_check_and_submit(struct usbback_req *usbback_req) 432*816ac92eSJuergen Gross { 433*816ac92eSJuergen Gross struct usbback_info *usbif; 434*816ac92eSJuergen Gross unsigned int devnum; 435*816ac92eSJuergen Gross struct usbback_stub *stub; 436*816ac92eSJuergen Gross struct usbif_ctrlrequest *ctrl; 437*816ac92eSJuergen Gross int ret; 438*816ac92eSJuergen Gross uint16_t wValue; 439*816ac92eSJuergen Gross 440*816ac92eSJuergen Gross usbif = usbback_req->usbif; 441*816ac92eSJuergen Gross stub = NULL; 442*816ac92eSJuergen Gross devnum = usbif_pipedevice(usbback_req->req.pipe); 443*816ac92eSJuergen Gross ctrl = (struct usbif_ctrlrequest *)usbback_req->req.u.ctrl; 444*816ac92eSJuergen Gross wValue = le16_to_cpu(ctrl->wValue); 445*816ac92eSJuergen Gross 446*816ac92eSJuergen Gross /* 447*816ac92eSJuergen Gross * When the device is first connected or resetted, USB device has no 448*816ac92eSJuergen Gross * address. In this initial state, following requests are sent to device 449*816ac92eSJuergen Gross * address (#0), 450*816ac92eSJuergen Gross * 451*816ac92eSJuergen Gross * 1. GET_DESCRIPTOR (with Descriptor Type is "DEVICE") is sent, 452*816ac92eSJuergen Gross * and OS knows what device is connected to. 453*816ac92eSJuergen Gross * 454*816ac92eSJuergen Gross * 2. SET_ADDRESS is sent, and then device has its address. 455*816ac92eSJuergen Gross * 456*816ac92eSJuergen Gross * In the next step, SET_CONFIGURATION is sent to addressed device, and 457*816ac92eSJuergen Gross * then the device is finally ready to use. 458*816ac92eSJuergen Gross */ 459*816ac92eSJuergen Gross if (unlikely(devnum == 0)) { 460*816ac92eSJuergen Gross stub = usbif->ports + usbif_pipeportnum(usbback_req->req.pipe) - 1; 461*816ac92eSJuergen Gross if (!stub->dev || !stub->attached) { 462*816ac92eSJuergen Gross ret = -ENODEV; 463*816ac92eSJuergen Gross goto do_response; 464*816ac92eSJuergen Gross } 465*816ac92eSJuergen Gross 466*816ac92eSJuergen Gross switch (ctrl->bRequest) { 467*816ac92eSJuergen Gross case USB_REQ_GET_DESCRIPTOR: 468*816ac92eSJuergen Gross /* 469*816ac92eSJuergen Gross * GET_DESCRIPTOR request to device #0. 470*816ac92eSJuergen Gross * through normal transfer. 471*816ac92eSJuergen Gross */ 472*816ac92eSJuergen Gross TR_REQ(&usbif->xendev, "devnum 0 GET_DESCRIPTOR\n"); 473*816ac92eSJuergen Gross usbback_req->stub = stub; 474*816ac92eSJuergen Gross return 0; 475*816ac92eSJuergen Gross case USB_REQ_SET_ADDRESS: 476*816ac92eSJuergen Gross /* 477*816ac92eSJuergen Gross * SET_ADDRESS request to device #0. 478*816ac92eSJuergen Gross * add attached device to addr_table. 479*816ac92eSJuergen Gross */ 480*816ac92eSJuergen Gross TR_REQ(&usbif->xendev, "devnum 0 SET_ADDRESS\n"); 481*816ac92eSJuergen Gross usbback_set_address(usbif, stub, 0, wValue); 482*816ac92eSJuergen Gross ret = 0; 483*816ac92eSJuergen Gross break; 484*816ac92eSJuergen Gross default: 485*816ac92eSJuergen Gross ret = -EINVAL; 486*816ac92eSJuergen Gross break; 487*816ac92eSJuergen Gross } 488*816ac92eSJuergen Gross goto do_response; 489*816ac92eSJuergen Gross } 490*816ac92eSJuergen Gross 491*816ac92eSJuergen Gross if (unlikely(!usbif->addr_table[devnum])) { 492*816ac92eSJuergen Gross ret = -ENODEV; 493*816ac92eSJuergen Gross goto do_response; 494*816ac92eSJuergen Gross } 495*816ac92eSJuergen Gross usbback_req->stub = usbif->addr_table[devnum]; 496*816ac92eSJuergen Gross 497*816ac92eSJuergen Gross /* 498*816ac92eSJuergen Gross * Check special request 499*816ac92eSJuergen Gross */ 500*816ac92eSJuergen Gross if (ctrl->bRequest != USB_REQ_SET_ADDRESS) { 501*816ac92eSJuergen Gross return 0; 502*816ac92eSJuergen Gross } 503*816ac92eSJuergen Gross 504*816ac92eSJuergen Gross /* 505*816ac92eSJuergen Gross * SET_ADDRESS request to addressed device. 506*816ac92eSJuergen Gross * change addr or remove from addr_table. 507*816ac92eSJuergen Gross */ 508*816ac92eSJuergen Gross usbback_set_address(usbif, usbback_req->stub, devnum, wValue); 509*816ac92eSJuergen Gross ret = 0; 510*816ac92eSJuergen Gross 511*816ac92eSJuergen Gross do_response: 512*816ac92eSJuergen Gross usbback_do_response_ret(usbback_req, ret); 513*816ac92eSJuergen Gross return 1; 514*816ac92eSJuergen Gross } 515*816ac92eSJuergen Gross 516*816ac92eSJuergen Gross static void usbback_dispatch(struct usbback_req *usbback_req) 517*816ac92eSJuergen Gross { 518*816ac92eSJuergen Gross int ret; 519*816ac92eSJuergen Gross unsigned int devnum; 520*816ac92eSJuergen Gross struct usbback_info *usbif; 521*816ac92eSJuergen Gross 522*816ac92eSJuergen Gross usbif = usbback_req->usbif; 523*816ac92eSJuergen Gross 524*816ac92eSJuergen Gross TR_REQ(&usbif->xendev, "start req_id %d pipe %08x\n", usbback_req->req.id, 525*816ac92eSJuergen Gross usbback_req->req.pipe); 526*816ac92eSJuergen Gross 527*816ac92eSJuergen Gross /* unlink request */ 528*816ac92eSJuergen Gross if (unlikely(usbif_pipeunlink(usbback_req->req.pipe))) { 529*816ac92eSJuergen Gross usbback_process_unlink_req(usbback_req); 530*816ac92eSJuergen Gross return; 531*816ac92eSJuergen Gross } 532*816ac92eSJuergen Gross 533*816ac92eSJuergen Gross if (usbif_pipectrl(usbback_req->req.pipe)) { 534*816ac92eSJuergen Gross if (usbback_check_and_submit(usbback_req)) { 535*816ac92eSJuergen Gross return; 536*816ac92eSJuergen Gross } 537*816ac92eSJuergen Gross } else { 538*816ac92eSJuergen Gross devnum = usbif_pipedevice(usbback_req->req.pipe); 539*816ac92eSJuergen Gross usbback_req->stub = usbif->addr_table[devnum]; 540*816ac92eSJuergen Gross 541*816ac92eSJuergen Gross if (!usbback_req->stub || !usbback_req->stub->attached) { 542*816ac92eSJuergen Gross ret = -ENODEV; 543*816ac92eSJuergen Gross goto fail_response; 544*816ac92eSJuergen Gross } 545*816ac92eSJuergen Gross } 546*816ac92eSJuergen Gross 547*816ac92eSJuergen Gross QTAILQ_INSERT_TAIL(&usbback_req->stub->submit_q, usbback_req, q); 548*816ac92eSJuergen Gross 549*816ac92eSJuergen Gross usbback_req->nr_buffer_segs = usbback_req->req.nr_buffer_segs; 550*816ac92eSJuergen Gross usbback_req->nr_extra_segs = usbif_pipeisoc(usbback_req->req.pipe) ? 551*816ac92eSJuergen Gross usbback_req->req.u.isoc.nr_frame_desc_segs : 0; 552*816ac92eSJuergen Gross 553*816ac92eSJuergen Gross ret = usbback_init_packet(usbback_req); 554*816ac92eSJuergen Gross if (ret) { 555*816ac92eSJuergen Gross xen_be_printf(&usbif->xendev, 0, "invalid request\n"); 556*816ac92eSJuergen Gross ret = -ESHUTDOWN; 557*816ac92eSJuergen Gross goto fail_free_urb; 558*816ac92eSJuergen Gross } 559*816ac92eSJuergen Gross 560*816ac92eSJuergen Gross ret = usbback_gnttab_map(usbback_req); 561*816ac92eSJuergen Gross if (ret) { 562*816ac92eSJuergen Gross xen_be_printf(&usbif->xendev, 0, "invalid buffer, ret=%d\n", ret); 563*816ac92eSJuergen Gross ret = -ESHUTDOWN; 564*816ac92eSJuergen Gross goto fail_free_urb; 565*816ac92eSJuergen Gross } 566*816ac92eSJuergen Gross 567*816ac92eSJuergen Gross usb_handle_packet(usbback_req->stub->dev, &usbback_req->packet); 568*816ac92eSJuergen Gross if (usbback_req->packet.status != USB_RET_ASYNC) { 569*816ac92eSJuergen Gross usbback_packet_complete(&usbback_req->packet); 570*816ac92eSJuergen Gross } 571*816ac92eSJuergen Gross return; 572*816ac92eSJuergen Gross 573*816ac92eSJuergen Gross fail_free_urb: 574*816ac92eSJuergen Gross QTAILQ_REMOVE(&usbback_req->stub->submit_q, usbback_req, q); 575*816ac92eSJuergen Gross 576*816ac92eSJuergen Gross fail_response: 577*816ac92eSJuergen Gross usbback_do_response_ret(usbback_req, ret); 578*816ac92eSJuergen Gross } 579*816ac92eSJuergen Gross 580*816ac92eSJuergen Gross static void usbback_hotplug_notify(struct usbback_info *usbif) 581*816ac92eSJuergen Gross { 582*816ac92eSJuergen Gross struct usbif_conn_back_ring *ring = &usbif->conn_ring; 583*816ac92eSJuergen Gross struct usbif_conn_request req; 584*816ac92eSJuergen Gross struct usbif_conn_response *res; 585*816ac92eSJuergen Gross struct usbback_hotplug *usb_hp; 586*816ac92eSJuergen Gross unsigned int notify; 587*816ac92eSJuergen Gross 588*816ac92eSJuergen Gross if (!usbif->conn_sring) { 589*816ac92eSJuergen Gross return; 590*816ac92eSJuergen Gross } 591*816ac92eSJuergen Gross 592*816ac92eSJuergen Gross /* Check for full ring. */ 593*816ac92eSJuergen Gross if ((RING_SIZE(ring) - ring->rsp_prod_pvt - ring->req_cons) == 0) { 594*816ac92eSJuergen Gross xen_be_send_notify(&usbif->xendev); 595*816ac92eSJuergen Gross return; 596*816ac92eSJuergen Gross } 597*816ac92eSJuergen Gross 598*816ac92eSJuergen Gross usb_hp = QSIMPLEQ_FIRST(&usbif->hotplug_q); 599*816ac92eSJuergen Gross QSIMPLEQ_REMOVE_HEAD(&usbif->hotplug_q, q); 600*816ac92eSJuergen Gross 601*816ac92eSJuergen Gross RING_COPY_REQUEST(ring, ring->req_cons, &req); 602*816ac92eSJuergen Gross ring->req_cons++; 603*816ac92eSJuergen Gross ring->sring->req_event = ring->req_cons + 1; 604*816ac92eSJuergen Gross 605*816ac92eSJuergen Gross res = RING_GET_RESPONSE(ring, ring->rsp_prod_pvt); 606*816ac92eSJuergen Gross res->id = req.id; 607*816ac92eSJuergen Gross res->portnum = usb_hp->port; 608*816ac92eSJuergen Gross res->speed = usbif->ports[usb_hp->port - 1].speed; 609*816ac92eSJuergen Gross ring->rsp_prod_pvt++; 610*816ac92eSJuergen Gross RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(ring, notify); 611*816ac92eSJuergen Gross 612*816ac92eSJuergen Gross if (notify) { 613*816ac92eSJuergen Gross xen_be_send_notify(&usbif->xendev); 614*816ac92eSJuergen Gross } 615*816ac92eSJuergen Gross 616*816ac92eSJuergen Gross TR_BUS(&usbif->xendev, "hotplug port %d speed %d\n", usb_hp->port, 617*816ac92eSJuergen Gross res->speed); 618*816ac92eSJuergen Gross 619*816ac92eSJuergen Gross g_free(usb_hp); 620*816ac92eSJuergen Gross 621*816ac92eSJuergen Gross if (!QSIMPLEQ_EMPTY(&usbif->hotplug_q)) { 622*816ac92eSJuergen Gross qemu_bh_schedule(usbif->bh); 623*816ac92eSJuergen Gross } 624*816ac92eSJuergen Gross } 625*816ac92eSJuergen Gross 626*816ac92eSJuergen Gross static void usbback_bh(void *opaque) 627*816ac92eSJuergen Gross { 628*816ac92eSJuergen Gross struct usbback_info *usbif; 629*816ac92eSJuergen Gross struct usbif_urb_back_ring *urb_ring; 630*816ac92eSJuergen Gross struct usbback_req *usbback_req; 631*816ac92eSJuergen Gross RING_IDX rc, rp; 632*816ac92eSJuergen Gross unsigned int more_to_do; 633*816ac92eSJuergen Gross 634*816ac92eSJuergen Gross usbif = opaque; 635*816ac92eSJuergen Gross if (usbif->ring_error) { 636*816ac92eSJuergen Gross return; 637*816ac92eSJuergen Gross } 638*816ac92eSJuergen Gross 639*816ac92eSJuergen Gross if (!QSIMPLEQ_EMPTY(&usbif->hotplug_q)) { 640*816ac92eSJuergen Gross usbback_hotplug_notify(usbif); 641*816ac92eSJuergen Gross } 642*816ac92eSJuergen Gross 643*816ac92eSJuergen Gross urb_ring = &usbif->urb_ring; 644*816ac92eSJuergen Gross rc = urb_ring->req_cons; 645*816ac92eSJuergen Gross rp = urb_ring->sring->req_prod; 646*816ac92eSJuergen Gross xen_rmb(); /* Ensure we see queued requests up to 'rp'. */ 647*816ac92eSJuergen Gross 648*816ac92eSJuergen Gross if (RING_REQUEST_PROD_OVERFLOW(urb_ring, rp)) { 649*816ac92eSJuergen Gross rc = urb_ring->rsp_prod_pvt; 650*816ac92eSJuergen Gross xen_be_printf(&usbif->xendev, 0, "domU provided bogus ring requests " 651*816ac92eSJuergen Gross "(%#x - %#x = %u). Halting ring processing.\n", 652*816ac92eSJuergen Gross rp, rc, rp - rc); 653*816ac92eSJuergen Gross usbif->ring_error = true; 654*816ac92eSJuergen Gross return; 655*816ac92eSJuergen Gross } 656*816ac92eSJuergen Gross 657*816ac92eSJuergen Gross while (rc != rp) { 658*816ac92eSJuergen Gross if (RING_REQUEST_CONS_OVERFLOW(urb_ring, rc)) { 659*816ac92eSJuergen Gross break; 660*816ac92eSJuergen Gross } 661*816ac92eSJuergen Gross usbback_req = usbback_get_req(usbif); 662*816ac92eSJuergen Gross 663*816ac92eSJuergen Gross RING_COPY_REQUEST(urb_ring, rc, &usbback_req->req); 664*816ac92eSJuergen Gross usbback_req->usbif = usbif; 665*816ac92eSJuergen Gross 666*816ac92eSJuergen Gross usbback_dispatch(usbback_req); 667*816ac92eSJuergen Gross 668*816ac92eSJuergen Gross urb_ring->req_cons = ++rc; 669*816ac92eSJuergen Gross } 670*816ac92eSJuergen Gross 671*816ac92eSJuergen Gross RING_FINAL_CHECK_FOR_REQUESTS(urb_ring, more_to_do); 672*816ac92eSJuergen Gross if (more_to_do) { 673*816ac92eSJuergen Gross qemu_bh_schedule(usbif->bh); 674*816ac92eSJuergen Gross } 675*816ac92eSJuergen Gross } 676*816ac92eSJuergen Gross 677*816ac92eSJuergen Gross static void usbback_hotplug_enq(struct usbback_info *usbif, unsigned port) 678*816ac92eSJuergen Gross { 679*816ac92eSJuergen Gross struct usbback_hotplug *usb_hp; 680*816ac92eSJuergen Gross 681*816ac92eSJuergen Gross usb_hp = g_new0(struct usbback_hotplug, 1); 682*816ac92eSJuergen Gross usb_hp->port = port; 683*816ac92eSJuergen Gross QSIMPLEQ_INSERT_TAIL(&usbif->hotplug_q, usb_hp, q); 684*816ac92eSJuergen Gross usbback_hotplug_notify(usbif); 685*816ac92eSJuergen Gross } 686*816ac92eSJuergen Gross 687*816ac92eSJuergen Gross static void usbback_portid_remove(struct usbback_info *usbif, unsigned port) 688*816ac92eSJuergen Gross { 689*816ac92eSJuergen Gross USBPort *p; 690*816ac92eSJuergen Gross 691*816ac92eSJuergen Gross if (!usbif->ports[port - 1].dev) { 692*816ac92eSJuergen Gross return; 693*816ac92eSJuergen Gross } 694*816ac92eSJuergen Gross 695*816ac92eSJuergen Gross p = &(usbif->ports[port - 1].port); 696*816ac92eSJuergen Gross snprintf(p->path, sizeof(p->path), "%d", 99); 697*816ac92eSJuergen Gross 698*816ac92eSJuergen Gross object_unparent(OBJECT(usbif->ports[port - 1].dev)); 699*816ac92eSJuergen Gross usbif->ports[port - 1].dev = NULL; 700*816ac92eSJuergen Gross usbif->ports[port - 1].speed = USBIF_SPEED_NONE; 701*816ac92eSJuergen Gross usbif->ports[port - 1].attached = false; 702*816ac92eSJuergen Gross usbback_hotplug_enq(usbif, port); 703*816ac92eSJuergen Gross 704*816ac92eSJuergen Gross TR_BUS(&usbif->xendev, "port %d removed\n", port); 705*816ac92eSJuergen Gross } 706*816ac92eSJuergen Gross 707*816ac92eSJuergen Gross static void usbback_portid_add(struct usbback_info *usbif, unsigned port, 708*816ac92eSJuergen Gross char *busid) 709*816ac92eSJuergen Gross { 710*816ac92eSJuergen Gross unsigned speed; 711*816ac92eSJuergen Gross char *portname; 712*816ac92eSJuergen Gross USBPort *p; 713*816ac92eSJuergen Gross Error *local_err = NULL; 714*816ac92eSJuergen Gross QDict *qdict; 715*816ac92eSJuergen Gross QemuOpts *opts; 716*816ac92eSJuergen Gross 717*816ac92eSJuergen Gross if (usbif->ports[port - 1].dev) { 718*816ac92eSJuergen Gross return; 719*816ac92eSJuergen Gross } 720*816ac92eSJuergen Gross 721*816ac92eSJuergen Gross portname = strchr(busid, '-'); 722*816ac92eSJuergen Gross if (!portname) { 723*816ac92eSJuergen Gross xen_be_printf(&usbif->xendev, 0, "device %s illegal specification\n", 724*816ac92eSJuergen Gross busid); 725*816ac92eSJuergen Gross return; 726*816ac92eSJuergen Gross } 727*816ac92eSJuergen Gross portname++; 728*816ac92eSJuergen Gross p = &(usbif->ports[port - 1].port); 729*816ac92eSJuergen Gross snprintf(p->path, sizeof(p->path), "%s", portname); 730*816ac92eSJuergen Gross 731*816ac92eSJuergen Gross qdict = qdict_new(); 732*816ac92eSJuergen Gross qdict_put(qdict, "driver", qstring_from_str("usb-host")); 733*816ac92eSJuergen Gross qdict_put(qdict, "hostbus", qint_from_int(atoi(busid))); 734*816ac92eSJuergen Gross qdict_put(qdict, "hostport", qstring_from_str(portname)); 735*816ac92eSJuergen Gross opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict, &local_err); 736*816ac92eSJuergen Gross if (local_err) { 737*816ac92eSJuergen Gross goto err; 738*816ac92eSJuergen Gross } 739*816ac92eSJuergen Gross usbif->ports[port - 1].dev = USB_DEVICE(qdev_device_add(opts, &local_err)); 740*816ac92eSJuergen Gross if (!usbif->ports[port - 1].dev) { 741*816ac92eSJuergen Gross goto err; 742*816ac92eSJuergen Gross } 743*816ac92eSJuergen Gross QDECREF(qdict); 744*816ac92eSJuergen Gross snprintf(p->path, sizeof(p->path), "%d", port); 745*816ac92eSJuergen Gross speed = usbif->ports[port - 1].dev->speed; 746*816ac92eSJuergen Gross switch (speed) { 747*816ac92eSJuergen Gross case USB_SPEED_LOW: 748*816ac92eSJuergen Gross speed = USBIF_SPEED_LOW; 749*816ac92eSJuergen Gross break; 750*816ac92eSJuergen Gross case USB_SPEED_FULL: 751*816ac92eSJuergen Gross speed = USBIF_SPEED_FULL; 752*816ac92eSJuergen Gross break; 753*816ac92eSJuergen Gross case USB_SPEED_HIGH: 754*816ac92eSJuergen Gross speed = (usbif->usb_ver < USB_VER_USB20) ? 755*816ac92eSJuergen Gross USBIF_SPEED_NONE : USBIF_SPEED_HIGH; 756*816ac92eSJuergen Gross break; 757*816ac92eSJuergen Gross default: 758*816ac92eSJuergen Gross speed = USBIF_SPEED_NONE; 759*816ac92eSJuergen Gross break; 760*816ac92eSJuergen Gross } 761*816ac92eSJuergen Gross if (speed == USBIF_SPEED_NONE) { 762*816ac92eSJuergen Gross xen_be_printf(&usbif->xendev, 0, "device %s wrong speed\n", busid); 763*816ac92eSJuergen Gross object_unparent(OBJECT(usbif->ports[port - 1].dev)); 764*816ac92eSJuergen Gross usbif->ports[port - 1].dev = NULL; 765*816ac92eSJuergen Gross return; 766*816ac92eSJuergen Gross } 767*816ac92eSJuergen Gross usb_device_reset(usbif->ports[port - 1].dev); 768*816ac92eSJuergen Gross usbif->ports[port - 1].speed = speed; 769*816ac92eSJuergen Gross usbif->ports[port - 1].attached = true; 770*816ac92eSJuergen Gross QTAILQ_INIT(&usbif->ports[port - 1].submit_q); 771*816ac92eSJuergen Gross usbback_hotplug_enq(usbif, port); 772*816ac92eSJuergen Gross 773*816ac92eSJuergen Gross TR_BUS(&usbif->xendev, "port %d attached\n", port); 774*816ac92eSJuergen Gross return; 775*816ac92eSJuergen Gross 776*816ac92eSJuergen Gross err: 777*816ac92eSJuergen Gross QDECREF(qdict); 778*816ac92eSJuergen Gross snprintf(p->path, sizeof(p->path), "%d", 99); 779*816ac92eSJuergen Gross xen_be_printf(&usbif->xendev, 0, "device %s could not be opened\n", busid); 780*816ac92eSJuergen Gross } 781*816ac92eSJuergen Gross 782*816ac92eSJuergen Gross static void usbback_process_port(struct usbback_info *usbif, unsigned port) 783*816ac92eSJuergen Gross { 784*816ac92eSJuergen Gross char node[8]; 785*816ac92eSJuergen Gross char *busid; 786*816ac92eSJuergen Gross 787*816ac92eSJuergen Gross snprintf(node, sizeof(node), "port/%d", port); 788*816ac92eSJuergen Gross busid = xenstore_read_be_str(&usbif->xendev, node); 789*816ac92eSJuergen Gross if (busid == NULL) { 790*816ac92eSJuergen Gross xen_be_printf(&usbif->xendev, 0, "xenstore_read %s failed\n", node); 791*816ac92eSJuergen Gross return; 792*816ac92eSJuergen Gross } 793*816ac92eSJuergen Gross 794*816ac92eSJuergen Gross /* Remove portid, if the port is not connected. */ 795*816ac92eSJuergen Gross if (strlen(busid) == 0) { 796*816ac92eSJuergen Gross usbback_portid_remove(usbif, port); 797*816ac92eSJuergen Gross } else { 798*816ac92eSJuergen Gross usbback_portid_add(usbif, port, busid); 799*816ac92eSJuergen Gross } 800*816ac92eSJuergen Gross 801*816ac92eSJuergen Gross g_free(busid); 802*816ac92eSJuergen Gross } 803*816ac92eSJuergen Gross 804*816ac92eSJuergen Gross static void usbback_disconnect(struct XenDevice *xendev) 805*816ac92eSJuergen Gross { 806*816ac92eSJuergen Gross struct usbback_info *usbif; 807*816ac92eSJuergen Gross struct usbback_req *req, *tmp; 808*816ac92eSJuergen Gross unsigned int i; 809*816ac92eSJuergen Gross 810*816ac92eSJuergen Gross TR_BUS(xendev, "start\n"); 811*816ac92eSJuergen Gross 812*816ac92eSJuergen Gross usbif = container_of(xendev, struct usbback_info, xendev); 813*816ac92eSJuergen Gross 814*816ac92eSJuergen Gross xen_be_unbind_evtchn(xendev); 815*816ac92eSJuergen Gross 816*816ac92eSJuergen Gross if (usbif->urb_sring) { 817*816ac92eSJuergen Gross xengnttab_unmap(xendev->gnttabdev, usbif->urb_sring, 1); 818*816ac92eSJuergen Gross usbif->urb_sring = NULL; 819*816ac92eSJuergen Gross } 820*816ac92eSJuergen Gross if (usbif->conn_sring) { 821*816ac92eSJuergen Gross xengnttab_unmap(xendev->gnttabdev, usbif->conn_sring, 1); 822*816ac92eSJuergen Gross usbif->conn_sring = NULL; 823*816ac92eSJuergen Gross } 824*816ac92eSJuergen Gross 825*816ac92eSJuergen Gross for (i = 0; i < usbif->num_ports; i++) { 826*816ac92eSJuergen Gross if (!usbif->ports[i].dev) { 827*816ac92eSJuergen Gross continue; 828*816ac92eSJuergen Gross } 829*816ac92eSJuergen Gross QTAILQ_FOREACH_SAFE(req, &usbif->ports[i].submit_q, q, tmp) { 830*816ac92eSJuergen Gross usbback_cancel_req(req); 831*816ac92eSJuergen Gross } 832*816ac92eSJuergen Gross } 833*816ac92eSJuergen Gross 834*816ac92eSJuergen Gross TR_BUS(xendev, "finished\n"); 835*816ac92eSJuergen Gross } 836*816ac92eSJuergen Gross 837*816ac92eSJuergen Gross static int usbback_connect(struct XenDevice *xendev) 838*816ac92eSJuergen Gross { 839*816ac92eSJuergen Gross struct usbback_info *usbif; 840*816ac92eSJuergen Gross struct usbif_urb_sring *urb_sring; 841*816ac92eSJuergen Gross struct usbif_conn_sring *conn_sring; 842*816ac92eSJuergen Gross int urb_ring_ref; 843*816ac92eSJuergen Gross int conn_ring_ref; 844*816ac92eSJuergen Gross unsigned int i; 845*816ac92eSJuergen Gross 846*816ac92eSJuergen Gross TR_BUS(xendev, "start\n"); 847*816ac92eSJuergen Gross 848*816ac92eSJuergen Gross usbif = container_of(xendev, struct usbback_info, xendev); 849*816ac92eSJuergen Gross 850*816ac92eSJuergen Gross if (xenstore_read_fe_int(xendev, "urb-ring-ref", &urb_ring_ref)) { 851*816ac92eSJuergen Gross xen_be_printf(xendev, 0, "error reading urb-ring-ref\n"); 852*816ac92eSJuergen Gross return -1; 853*816ac92eSJuergen Gross } 854*816ac92eSJuergen Gross if (xenstore_read_fe_int(xendev, "conn-ring-ref", &conn_ring_ref)) { 855*816ac92eSJuergen Gross xen_be_printf(xendev, 0, "error reading conn-ring-ref\n"); 856*816ac92eSJuergen Gross return -1; 857*816ac92eSJuergen Gross } 858*816ac92eSJuergen Gross if (xenstore_read_fe_int(xendev, "event-channel", &xendev->remote_port)) { 859*816ac92eSJuergen Gross xen_be_printf(xendev, 0, "error reading event-channel\n"); 860*816ac92eSJuergen Gross return -1; 861*816ac92eSJuergen Gross } 862*816ac92eSJuergen Gross 863*816ac92eSJuergen Gross usbif->urb_sring = xengnttab_map_grant_ref(xendev->gnttabdev, xendev->dom, 864*816ac92eSJuergen Gross urb_ring_ref, 865*816ac92eSJuergen Gross PROT_READ | PROT_WRITE); 866*816ac92eSJuergen Gross usbif->conn_sring = xengnttab_map_grant_ref(xendev->gnttabdev, xendev->dom, 867*816ac92eSJuergen Gross conn_ring_ref, 868*816ac92eSJuergen Gross PROT_READ | PROT_WRITE); 869*816ac92eSJuergen Gross if (!usbif->urb_sring || !usbif->conn_sring) { 870*816ac92eSJuergen Gross xen_be_printf(xendev, 0, "error mapping rings\n"); 871*816ac92eSJuergen Gross usbback_disconnect(xendev); 872*816ac92eSJuergen Gross return -1; 873*816ac92eSJuergen Gross } 874*816ac92eSJuergen Gross 875*816ac92eSJuergen Gross urb_sring = usbif->urb_sring; 876*816ac92eSJuergen Gross conn_sring = usbif->conn_sring; 877*816ac92eSJuergen Gross BACK_RING_INIT(&usbif->urb_ring, urb_sring, XC_PAGE_SIZE); 878*816ac92eSJuergen Gross BACK_RING_INIT(&usbif->conn_ring, conn_sring, XC_PAGE_SIZE); 879*816ac92eSJuergen Gross 880*816ac92eSJuergen Gross xen_be_bind_evtchn(xendev); 881*816ac92eSJuergen Gross 882*816ac92eSJuergen Gross xen_be_printf(xendev, 1, "urb-ring-ref %d, conn-ring-ref %d, " 883*816ac92eSJuergen Gross "remote port %d, local port %d\n", urb_ring_ref, 884*816ac92eSJuergen Gross conn_ring_ref, xendev->remote_port, xendev->local_port); 885*816ac92eSJuergen Gross 886*816ac92eSJuergen Gross for (i = 1; i <= usbif->num_ports; i++) { 887*816ac92eSJuergen Gross if (usbif->ports[i - 1].dev) { 888*816ac92eSJuergen Gross usbback_hotplug_enq(usbif, i); 889*816ac92eSJuergen Gross } 890*816ac92eSJuergen Gross } 891*816ac92eSJuergen Gross 892*816ac92eSJuergen Gross return 0; 893*816ac92eSJuergen Gross } 894*816ac92eSJuergen Gross 895*816ac92eSJuergen Gross static void usbback_backend_changed(struct XenDevice *xendev, const char *node) 896*816ac92eSJuergen Gross { 897*816ac92eSJuergen Gross struct usbback_info *usbif; 898*816ac92eSJuergen Gross unsigned int i; 899*816ac92eSJuergen Gross 900*816ac92eSJuergen Gross TR_BUS(xendev, "path %s\n", node); 901*816ac92eSJuergen Gross 902*816ac92eSJuergen Gross usbif = container_of(xendev, struct usbback_info, xendev); 903*816ac92eSJuergen Gross for (i = 1; i <= usbif->num_ports; i++) { 904*816ac92eSJuergen Gross usbback_process_port(usbif, i); 905*816ac92eSJuergen Gross } 906*816ac92eSJuergen Gross } 907*816ac92eSJuergen Gross 908*816ac92eSJuergen Gross static int usbback_init(struct XenDevice *xendev) 909*816ac92eSJuergen Gross { 910*816ac92eSJuergen Gross struct usbback_info *usbif; 911*816ac92eSJuergen Gross 912*816ac92eSJuergen Gross TR_BUS(xendev, "start\n"); 913*816ac92eSJuergen Gross 914*816ac92eSJuergen Gross usbif = container_of(xendev, struct usbback_info, xendev); 915*816ac92eSJuergen Gross 916*816ac92eSJuergen Gross if (xenstore_read_be_int(xendev, "num-ports", &usbif->num_ports) || 917*816ac92eSJuergen Gross usbif->num_ports < 1 || usbif->num_ports > USBBACK_MAXPORTS) { 918*816ac92eSJuergen Gross xen_be_printf(xendev, 0, "num-ports not readable or out of bounds\n"); 919*816ac92eSJuergen Gross return -1; 920*816ac92eSJuergen Gross } 921*816ac92eSJuergen Gross if (xenstore_read_be_int(xendev, "usb-ver", &usbif->usb_ver) || 922*816ac92eSJuergen Gross (usbif->usb_ver != USB_VER_USB11 && usbif->usb_ver != USB_VER_USB20)) { 923*816ac92eSJuergen Gross xen_be_printf(xendev, 0, "usb-ver not readable or out of bounds\n"); 924*816ac92eSJuergen Gross return -1; 925*816ac92eSJuergen Gross } 926*816ac92eSJuergen Gross 927*816ac92eSJuergen Gross usbback_backend_changed(xendev, "port"); 928*816ac92eSJuergen Gross 929*816ac92eSJuergen Gross TR_BUS(xendev, "finished\n"); 930*816ac92eSJuergen Gross 931*816ac92eSJuergen Gross return 0; 932*816ac92eSJuergen Gross } 933*816ac92eSJuergen Gross 934*816ac92eSJuergen Gross static void xen_bus_attach(USBPort *port) 935*816ac92eSJuergen Gross { 936*816ac92eSJuergen Gross struct usbback_info *usbif; 937*816ac92eSJuergen Gross 938*816ac92eSJuergen Gross usbif = port->opaque; 939*816ac92eSJuergen Gross TR_BUS(&usbif->xendev, "\n"); 940*816ac92eSJuergen Gross usbif->ports[port->index].attached = true; 941*816ac92eSJuergen Gross usbback_hotplug_enq(usbif, port->index + 1); 942*816ac92eSJuergen Gross } 943*816ac92eSJuergen Gross 944*816ac92eSJuergen Gross static void xen_bus_detach(USBPort *port) 945*816ac92eSJuergen Gross { 946*816ac92eSJuergen Gross struct usbback_info *usbif; 947*816ac92eSJuergen Gross 948*816ac92eSJuergen Gross usbif = port->opaque; 949*816ac92eSJuergen Gross TR_BUS(&usbif->xendev, "\n"); 950*816ac92eSJuergen Gross usbif->ports[port->index].attached = false; 951*816ac92eSJuergen Gross usbback_hotplug_enq(usbif, port->index + 1); 952*816ac92eSJuergen Gross } 953*816ac92eSJuergen Gross 954*816ac92eSJuergen Gross static void xen_bus_child_detach(USBPort *port, USBDevice *child) 955*816ac92eSJuergen Gross { 956*816ac92eSJuergen Gross struct usbback_info *usbif; 957*816ac92eSJuergen Gross 958*816ac92eSJuergen Gross usbif = port->opaque; 959*816ac92eSJuergen Gross TR_BUS(&usbif->xendev, "\n"); 960*816ac92eSJuergen Gross } 961*816ac92eSJuergen Gross 962*816ac92eSJuergen Gross static void xen_bus_complete(USBPort *port, USBPacket *packet) 963*816ac92eSJuergen Gross { 964*816ac92eSJuergen Gross struct usbback_info *usbif; 965*816ac92eSJuergen Gross 966*816ac92eSJuergen Gross usbif = port->opaque; 967*816ac92eSJuergen Gross TR_REQ(&usbif->xendev, "\n"); 968*816ac92eSJuergen Gross usbback_packet_complete(packet); 969*816ac92eSJuergen Gross } 970*816ac92eSJuergen Gross 971*816ac92eSJuergen Gross static USBPortOps xen_usb_port_ops = { 972*816ac92eSJuergen Gross .attach = xen_bus_attach, 973*816ac92eSJuergen Gross .detach = xen_bus_detach, 974*816ac92eSJuergen Gross .child_detach = xen_bus_child_detach, 975*816ac92eSJuergen Gross .complete = xen_bus_complete, 976*816ac92eSJuergen Gross }; 977*816ac92eSJuergen Gross 978*816ac92eSJuergen Gross static USBBusOps xen_usb_bus_ops = { 979*816ac92eSJuergen Gross }; 980*816ac92eSJuergen Gross 981*816ac92eSJuergen Gross static void usbback_alloc(struct XenDevice *xendev) 982*816ac92eSJuergen Gross { 983*816ac92eSJuergen Gross struct usbback_info *usbif; 984*816ac92eSJuergen Gross USBPort *p; 985*816ac92eSJuergen Gross unsigned int i, max_grants; 986*816ac92eSJuergen Gross 987*816ac92eSJuergen Gross usbif = container_of(xendev, struct usbback_info, xendev); 988*816ac92eSJuergen Gross 989*816ac92eSJuergen Gross usb_bus_new(&usbif->bus, sizeof(usbif->bus), &xen_usb_bus_ops, xen_sysdev); 990*816ac92eSJuergen Gross for (i = 0; i < USBBACK_MAXPORTS; i++) { 991*816ac92eSJuergen Gross p = &(usbif->ports[i].port); 992*816ac92eSJuergen Gross usb_register_port(&usbif->bus, p, usbif, i, &xen_usb_port_ops, 993*816ac92eSJuergen Gross USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL | 994*816ac92eSJuergen Gross USB_SPEED_MASK_HIGH); 995*816ac92eSJuergen Gross snprintf(p->path, sizeof(p->path), "%d", 99); 996*816ac92eSJuergen Gross } 997*816ac92eSJuergen Gross 998*816ac92eSJuergen Gross QTAILQ_INIT(&usbif->req_free_q); 999*816ac92eSJuergen Gross QSIMPLEQ_INIT(&usbif->hotplug_q); 1000*816ac92eSJuergen Gross usbif->bh = qemu_bh_new(usbback_bh, usbif); 1001*816ac92eSJuergen Gross 1002*816ac92eSJuergen Gross /* max_grants: for each request and for the rings (request and connect). */ 1003*816ac92eSJuergen Gross max_grants = USBIF_MAX_SEGMENTS_PER_REQUEST * USB_URB_RING_SIZE + 2; 1004*816ac92eSJuergen Gross if (xengnttab_set_max_grants(xendev->gnttabdev, max_grants) < 0) { 1005*816ac92eSJuergen Gross xen_be_printf(xendev, 0, "xengnttab_set_max_grants failed: %s\n", 1006*816ac92eSJuergen Gross strerror(errno)); 1007*816ac92eSJuergen Gross } 1008*816ac92eSJuergen Gross } 1009*816ac92eSJuergen Gross 1010*816ac92eSJuergen Gross static int usbback_free(struct XenDevice *xendev) 1011*816ac92eSJuergen Gross { 1012*816ac92eSJuergen Gross struct usbback_info *usbif; 1013*816ac92eSJuergen Gross struct usbback_req *usbback_req; 1014*816ac92eSJuergen Gross struct usbback_hotplug *usb_hp; 1015*816ac92eSJuergen Gross unsigned int i; 1016*816ac92eSJuergen Gross 1017*816ac92eSJuergen Gross TR_BUS(xendev, "start\n"); 1018*816ac92eSJuergen Gross 1019*816ac92eSJuergen Gross usbback_disconnect(xendev); 1020*816ac92eSJuergen Gross usbif = container_of(xendev, struct usbback_info, xendev); 1021*816ac92eSJuergen Gross for (i = 1; i <= usbif->num_ports; i++) { 1022*816ac92eSJuergen Gross usbback_portid_remove(usbif, i); 1023*816ac92eSJuergen Gross } 1024*816ac92eSJuergen Gross 1025*816ac92eSJuergen Gross while (!QTAILQ_EMPTY(&usbif->req_free_q)) { 1026*816ac92eSJuergen Gross usbback_req = QTAILQ_FIRST(&usbif->req_free_q); 1027*816ac92eSJuergen Gross QTAILQ_REMOVE(&usbif->req_free_q, usbback_req, q); 1028*816ac92eSJuergen Gross g_free(usbback_req); 1029*816ac92eSJuergen Gross } 1030*816ac92eSJuergen Gross while (!QSIMPLEQ_EMPTY(&usbif->hotplug_q)) { 1031*816ac92eSJuergen Gross usb_hp = QSIMPLEQ_FIRST(&usbif->hotplug_q); 1032*816ac92eSJuergen Gross QSIMPLEQ_REMOVE_HEAD(&usbif->hotplug_q, q); 1033*816ac92eSJuergen Gross g_free(usb_hp); 1034*816ac92eSJuergen Gross } 1035*816ac92eSJuergen Gross 1036*816ac92eSJuergen Gross qemu_bh_delete(usbif->bh); 1037*816ac92eSJuergen Gross 1038*816ac92eSJuergen Gross for (i = 0; i < USBBACK_MAXPORTS; i++) { 1039*816ac92eSJuergen Gross usb_unregister_port(&usbif->bus, &(usbif->ports[i].port)); 1040*816ac92eSJuergen Gross } 1041*816ac92eSJuergen Gross 1042*816ac92eSJuergen Gross usb_bus_release(&usbif->bus); 1043*816ac92eSJuergen Gross 1044*816ac92eSJuergen Gross TR_BUS(xendev, "finished\n"); 1045*816ac92eSJuergen Gross 1046*816ac92eSJuergen Gross return 0; 1047*816ac92eSJuergen Gross } 1048*816ac92eSJuergen Gross 1049*816ac92eSJuergen Gross static void usbback_event(struct XenDevice *xendev) 1050*816ac92eSJuergen Gross { 1051*816ac92eSJuergen Gross struct usbback_info *usbif; 1052*816ac92eSJuergen Gross 1053*816ac92eSJuergen Gross usbif = container_of(xendev, struct usbback_info, xendev); 1054*816ac92eSJuergen Gross qemu_bh_schedule(usbif->bh); 1055*816ac92eSJuergen Gross } 1056*816ac92eSJuergen Gross 1057*816ac92eSJuergen Gross struct XenDevOps xen_usb_ops = { 1058*816ac92eSJuergen Gross .size = sizeof(struct usbback_info), 1059*816ac92eSJuergen Gross .flags = DEVOPS_FLAG_NEED_GNTDEV, 1060*816ac92eSJuergen Gross .init = usbback_init, 1061*816ac92eSJuergen Gross .alloc = usbback_alloc, 1062*816ac92eSJuergen Gross .free = usbback_free, 1063*816ac92eSJuergen Gross .backend_changed = usbback_backend_changed, 1064*816ac92eSJuergen Gross .initialise = usbback_connect, 1065*816ac92eSJuergen Gross .disconnect = usbback_disconnect, 1066*816ac92eSJuergen Gross .event = usbback_event, 1067*816ac92eSJuergen Gross }; 1068*816ac92eSJuergen Gross 1069*816ac92eSJuergen Gross #else /* USBIF_SHORT_NOT_OK */ 1070*816ac92eSJuergen Gross 1071*816ac92eSJuergen Gross static int usbback_not_supported(void) 1072*816ac92eSJuergen Gross { 1073*816ac92eSJuergen Gross return -EINVAL; 1074*816ac92eSJuergen Gross } 1075*816ac92eSJuergen Gross 1076*816ac92eSJuergen Gross struct XenDevOps xen_usb_ops = { 1077*816ac92eSJuergen Gross .backend_register = usbback_not_supported, 1078*816ac92eSJuergen Gross }; 1079*816ac92eSJuergen Gross 1080*816ac92eSJuergen Gross #endif 1081