usb-host: move legacy cmd line bits

The code handling the "-usbdevice host:..." legacy command line
syntax is moved to the new hw/usb/host-legacy.c file.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
Gerd Hoffmann 2013-01-23 14:15:38 +01:00
parent 9db7c41419
commit 4075975d83
5 changed files with 191 additions and 102 deletions

2
configure vendored
View File

@ -3723,7 +3723,7 @@ fi
# USB host support
case "$usb" in
linux)
echo "HOST_USB=linux" >> $config_host_mak
echo "HOST_USB=linux legacy" >> $config_host_mak
;;
bsd)
echo "HOST_USB=bsd" >> $config_host_mak

View File

@ -27,4 +27,4 @@ common-obj-$(CONFIG_USB_SMARTCARD) += dev-smartcard-reader.o
common-obj-$(CONFIG_USB_REDIR) += redirect.o quirks.o
# usb pass-through
common-obj-y += host-$(HOST_USB).o
common-obj-y += $(patsubst %,host-%.o,$(HOST_USB))

144
hw/usb/host-legacy.c Normal file
View File

@ -0,0 +1,144 @@
/*
* Linux host USB redirector
*
* Copyright (c) 2005 Fabrice Bellard
*
* Copyright (c) 2008 Max Krasnyansky
* Support for host device auto connect & disconnect
* Major rewrite to support fully async operation
*
* Copyright 2008 TJ <linux@tjworld.net>
* Added flexible support for /dev/bus/usb /sys/bus/usb/devices in addition
* to the legacy /proc/bus/usb USB device discovery and handling
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "qemu-common.h"
#include "hw/usb.h"
#include "hw/usb/host.h"
/*
* Autoconnect filter
* Format:
* auto:bus:dev[:vid:pid]
* auto:bus.dev[:vid:pid]
*
* bus - bus number (dec, * means any)
* dev - device number (dec, * means any)
* vid - vendor id (hex, * means any)
* pid - product id (hex, * means any)
*
* See 'lsusb' output.
*/
static int parse_filter(const char *spec, struct USBAutoFilter *f)
{
enum { BUS, DEV, VID, PID, DONE };
const char *p = spec;
int i;
f->bus_num = 0;
f->addr = 0;
f->vendor_id = 0;
f->product_id = 0;
for (i = BUS; i < DONE; i++) {
p = strpbrk(p, ":.");
if (!p) {
break;
}
p++;
if (*p == '*') {
continue;
}
switch (i) {
case BUS:
f->bus_num = strtol(p, NULL, 10);
break;
case DEV:
f->addr = strtol(p, NULL, 10);
break;
case VID:
f->vendor_id = strtol(p, NULL, 16);
break;
case PID:
f->product_id = strtol(p, NULL, 16);
break;
}
}
if (i < DEV) {
fprintf(stderr, "husb: invalid auto filter spec %s\n", spec);
return -1;
}
return 0;
}
USBDevice *usb_host_device_open(USBBus *bus, const char *devname)
{
struct USBAutoFilter filter;
USBDevice *dev;
char *p;
dev = usb_create(bus, "usb-host");
if (strstr(devname, "auto:")) {
if (parse_filter(devname, &filter) < 0) {
goto fail;
}
} else {
p = strchr(devname, '.');
if (p) {
filter.bus_num = strtoul(devname, NULL, 0);
filter.addr = strtoul(p + 1, NULL, 0);
filter.vendor_id = 0;
filter.product_id = 0;
} else {
p = strchr(devname, ':');
if (p) {
filter.bus_num = 0;
filter.addr = 0;
filter.vendor_id = strtoul(devname, NULL, 16);
filter.product_id = strtoul(p + 1, NULL, 16);
} else {
goto fail;
}
}
}
qdev_prop_set_uint32(&dev->qdev, "hostbus", filter.bus_num);
qdev_prop_set_uint32(&dev->qdev, "hostaddr", filter.addr);
qdev_prop_set_uint32(&dev->qdev, "vendorid", filter.vendor_id);
qdev_prop_set_uint32(&dev->qdev, "productid", filter.product_id);
qdev_init_nofail(&dev->qdev);
return dev;
fail:
qdev_free(&dev->qdev);
return NULL;
}
static void usb_host_register_types(void)
{
usb_legacy_register("usb-host", "host", usb_host_device_open);
}
type_init(usb_host_register_types)

View File

@ -43,6 +43,7 @@
#include <linux/version.h>
#include "hw/usb.h"
#include "hw/usb/desc.h"
#include "hw/usb/host.h"
/* We redefine it to avoid version problems */
struct usb_ctrltransfer {
@ -87,14 +88,6 @@ struct endp_data {
int inflight;
};
struct USBAutoFilter {
uint32_t bus_num;
uint32_t addr;
char *port;
uint32_t vendor_id;
uint32_t product_id;
};
enum USBHostDeviceOptions {
USB_HOST_OPT_PIPELINE,
};
@ -131,7 +124,6 @@ typedef struct USBHostDevice {
static QTAILQ_HEAD(, USBHostDevice) hostdevs = QTAILQ_HEAD_INITIALIZER(hostdevs);
static int usb_host_close(USBHostDevice *dev);
static int parse_filter(const char *spec, struct USBAutoFilter *f);
static void usb_host_auto_check(void *unused);
static int usb_host_read_file(char *line, size_t line_size,
const char *device_file, const char *device_name);
@ -1544,51 +1536,10 @@ static const TypeInfo usb_host_dev_info = {
static void usb_host_register_types(void)
{
type_register_static(&usb_host_dev_info);
usb_legacy_register("usb-host", "host", usb_host_device_open);
}
type_init(usb_host_register_types)
USBDevice *usb_host_device_open(USBBus *bus, const char *devname)
{
struct USBAutoFilter filter;
USBDevice *dev;
char *p;
dev = usb_create(bus, "usb-host");
if (strstr(devname, "auto:")) {
if (parse_filter(devname, &filter) < 0) {
goto fail;
}
} else {
if ((p = strchr(devname, '.'))) {
filter.bus_num = strtoul(devname, NULL, 0);
filter.addr = strtoul(p + 1, NULL, 0);
filter.vendor_id = 0;
filter.product_id = 0;
} else if ((p = strchr(devname, ':'))) {
filter.bus_num = 0;
filter.addr = 0;
filter.vendor_id = strtoul(devname, NULL, 16);
filter.product_id = strtoul(p + 1, NULL, 16);
} else {
goto fail;
}
}
qdev_prop_set_uint32(&dev->qdev, "hostbus", filter.bus_num);
qdev_prop_set_uint32(&dev->qdev, "hostaddr", filter.addr);
qdev_prop_set_uint32(&dev->qdev, "vendorid", filter.vendor_id);
qdev_prop_set_uint32(&dev->qdev, "productid", filter.product_id);
qdev_init_nofail(&dev->qdev);
return dev;
fail:
qdev_free(&dev->qdev);
return NULL;
}
int usb_host_device_close(const char *devname)
{
#if 0
@ -1840,56 +1791,6 @@ static void usb_host_auto_check(void *unused)
qemu_mod_timer(usb_auto_timer, qemu_get_clock_ms(rt_clock) + 2000);
}
/*
* Autoconnect filter
* Format:
* auto:bus:dev[:vid:pid]
* auto:bus.dev[:vid:pid]
*
* bus - bus number (dec, * means any)
* dev - device number (dec, * means any)
* vid - vendor id (hex, * means any)
* pid - product id (hex, * means any)
*
* See 'lsusb' output.
*/
static int parse_filter(const char *spec, struct USBAutoFilter *f)
{
enum { BUS, DEV, VID, PID, DONE };
const char *p = spec;
int i;
f->bus_num = 0;
f->addr = 0;
f->vendor_id = 0;
f->product_id = 0;
for (i = BUS; i < DONE; i++) {
p = strpbrk(p, ":.");
if (!p) {
break;
}
p++;
if (*p == '*') {
continue;
}
switch(i) {
case BUS: f->bus_num = strtol(p, NULL, 10); break;
case DEV: f->addr = strtol(p, NULL, 10); break;
case VID: f->vendor_id = strtol(p, NULL, 16); break;
case PID: f->product_id = strtol(p, NULL, 16); break;
}
}
if (i < DEV) {
fprintf(stderr, "husb: invalid auto filter spec %s\n", spec);
return -1;
}
return 0;
}
/**********************/
/* USB host device info */

44
hw/usb/host.h Normal file
View File

@ -0,0 +1,44 @@
/*
* Linux host USB redirector
*
* Copyright (c) 2005 Fabrice Bellard
*
* Copyright (c) 2008 Max Krasnyansky
* Support for host device auto connect & disconnect
* Major rewrite to support fully async operation
*
* Copyright 2008 TJ <linux@tjworld.net>
* Added flexible support for /dev/bus/usb /sys/bus/usb/devices in addition
* to the legacy /proc/bus/usb USB device discovery and handling
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef QEMU_USB_HOST_H
#define QEMU_USB_HOST_H
struct USBAutoFilter {
uint32_t bus_num;
uint32_t addr;
char *port;
uint32_t vendor_id;
uint32_t product_id;
};
#endif /* QEMU_USB_HOST_H */