From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:35239) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QzQUh-0000qE-CN for qemu-devel@nongnu.org; Fri, 02 Sep 2011 05:57:06 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QzQUf-0002CO-Pc for qemu-devel@nongnu.org; Fri, 02 Sep 2011 05:57:03 -0400 Received: from mx1.redhat.com ([209.132.183.28]:31627) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QzQUf-0002Bo-EN for qemu-devel@nongnu.org; Fri, 02 Sep 2011 05:57:01 -0400 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p829v0R0031316 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 2 Sep 2011 05:57:00 -0400 From: Gerd Hoffmann Date: Fri, 2 Sep 2011 11:56:35 +0200 Message-Id: <1314957407-29508-7-git-send-email-kraxel@redhat.com> In-Reply-To: <1314957407-29508-1-git-send-email-kraxel@redhat.com> References: <1314957407-29508-1-git-send-email-kraxel@redhat.com> Subject: [Qemu-devel] [PATCH 06/18] usb-host: claim port List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Gerd Hoffmann When configured to pass through a specific host port (using hostbus and hostport properties), try to claim the port if supported by the kernel. That will avoid any kernel drivers binding to devices plugged into that port. It will not stop any userspace apps (such as usb_modeswitch) access the device via usbfs though. Signed-off-by: Gerd Hoffmann --- trace-events | 1 + usb-linux.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 0 deletions(-) diff --git a/trace-events b/trace-events index f48cb85..5535e56 100644 --- a/trace-events +++ b/trace-events @@ -266,6 +266,7 @@ disable usb_host_ep_stop_iso(int bus, int addr, int ep) "dev %d:%d, ep %d" disable usb_host_reset(int bus, int addr) "dev %d:%d" disable usb_host_auto_scan_enabled(void) disable usb_host_auto_scan_disabled(void) +disable usb_host_claim_port(int bus, int hub, int port) "bus %d, hub addr %d, port %d" # hw/scsi-bus.c disable scsi_req_alloc(int target, int lun, int tag) "target %d lun %d tag %d" diff --git a/usb-linux.c b/usb-linux.c index a903023..ce0eadd 100644 --- a/usb-linux.c +++ b/usb-linux.c @@ -115,6 +115,7 @@ struct USBAutoFilter { typedef struct USBHostDevice { USBDevice dev; int fd; + int hub_fd; uint8_t descr[8192]; int descr_len; @@ -525,6 +526,9 @@ static void usb_host_handle_destroy(USBDevice *dev) USBHostDevice *s = (USBHostDevice *)dev; usb_host_close(s); + if (s->hub_fd != -1) { + close(s->hub_fd); + } QTAILQ_REMOVE(&hostdevs, s, next); qemu_remove_exit_notifier(&s->exit); } @@ -1266,10 +1270,63 @@ static int usb_host_initfn(USBDevice *dev) dev->auto_attach = 0; s->fd = -1; + s->hub_fd = -1; + QTAILQ_INSERT_TAIL(&hostdevs, s, next); s->exit.notify = usb_host_exit_notifier; qemu_add_exit_notifier(&s->exit); usb_host_auto_check(NULL); + +#ifdef USBDEVFS_CLAIM_PORT + if (s->match.bus_num != 0 && s->match.port != NULL) { + char *h, hub_name[64], line[1024]; + int hub_addr, portnr, ret; + + snprintf(hub_name, sizeof(hub_name), "%d-%s", + s->match.bus_num, s->match.port); + + /* try strip off last ".$portnr" to get hub */ + h = strrchr(hub_name, '.'); + if (h != NULL) { + portnr = atoi(h+1); + *h = '\0'; + } else { + /* no dot in there -> it is the root hub */ + snprintf(hub_name, sizeof(hub_name), "usb%d", + s->match.bus_num); + portnr = atoi(s->match.port); + } + + if (!usb_host_read_file(line, sizeof(line), "devnum", + hub_name)) { + goto out; + } + if (sscanf(line, "%d", &hub_addr) != 1) { + goto out; + } + + if (!usb_host_device_path) { + goto out; + } + snprintf(line, sizeof(line), "%s/%03d/%03d", + usb_host_device_path, s->match.bus_num, hub_addr); + s->hub_fd = open(line, O_RDWR | O_NONBLOCK); + if (s->hub_fd < 0) { + goto out; + } + + ret = ioctl(s->hub_fd, USBDEVFS_CLAIM_PORT, &portnr); + if (ret < 0) { + close(s->hub_fd); + s->hub_fd = -1; + goto out; + } + + trace_usb_host_claim_port(s->match.bus_num, hub_addr, portnr); + } +out: +#endif + return 0; } -- 1.7.1