usb: -usbdevice cleanups, storage fix, QOMify ccid.
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABAgAGBQJaauEhAAoJEEy22O7T6HE44xcP/0adAFXpNaFmdlI4urSOpBWv 4w3rwbmtfLRoevD8fRH2QK37T8qwc+bAPSN5NVzFAKY4GnFeC7noeRGHNdb1/KgU KY7B4lBWHaNh1m/F9ebyS/8SnagrwKWgyaia49DncYeSlvZ/CBUBzx7IjdVMWUYi dDj48yK70GzfhDMQUtbiVR3qKH+7ESN1l40cKnbleJrGEQA7V+/JpVaI/z9fxgU0 rQTMf9OiLJqB8ymwaILWnWyWmw8MMcautaU9NURjGfBVitAX4mL4rWI7rVEcdozi jZZwcuN2NtQ6lHDgdIPAA3JOfzw/rp8ApT/VWWIY2YaQir1HydWZscPExfutEv0f ys8LsoS5L8SEUXWYJVUfuT1rD+fRUACmjwDzCH9kakL89uD4AnDF1X0SDvuQI4aH g+D8E5sRe/3yqosK4XHQNZlmBJ0x1KKNEWrIHjanzh5EcBiEpMJRA7NkmLFV6gsd DZf0vwiJNZ6sGwp/7ZpWtOYsyVBGM0Qapc2ooO40qUI88Fl/uzJk6EKYHypm+yud APNpdGKyj3JiyOVxSqvDdy7GCZh1QpdfvcFGofjQ44DcjXcG3Drnfg5k85nb/jQg pM15+Cvdq4OSg4sRun2PHZK9W8Mt/Tmk5elyC2DopLNnSH8JEOO+GTeLPHjOPOs1 dH04KChG7zOxOHk6Wt5o =siZC -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/kraxel/tags/usb-20180126-v3-pull-request' into staging usb: -usbdevice cleanups, storage fix, QOMify ccid. # gpg: Signature made Fri 26 Jan 2018 08:04:49 GMT # gpg: using RSA key 0x4CB6D8EED3E87138 # gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" # gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" # gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" # Primary key fingerprint: A032 8CFF B93A 17A7 9901 FE7D 4CB6 D8EE D3E8 7138 * remotes/kraxel/tags/usb-20180126-v3-pull-request: usb-ccid: convert CCIDCardClass::exitfn() -> unrealize() usb-ccid: inline ccid_card_initfn() in ccid_card_realize() hw/usb/ccid: Make ccid_card_init() take an error parameter usb-storage: Fix share-rw option parsing usb: Remove legacy -usbdevice options (host, serial, disk and net) Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
d45091e449
@ -224,6 +224,7 @@ static void scsi_qdev_unrealize(DeviceState *qdev, Error **errp)
|
||||
/* handle legacy '-drive if=scsi,...' cmd line args */
|
||||
SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockBackend *blk,
|
||||
int unit, bool removable, int bootindex,
|
||||
bool share_rw,
|
||||
const char *serial, Error **errp)
|
||||
{
|
||||
const char *driver;
|
||||
@ -254,6 +255,12 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockBackend *blk,
|
||||
object_unparent(OBJECT(dev));
|
||||
return NULL;
|
||||
}
|
||||
object_property_set_bool(OBJECT(dev), share_rw, "share-rw", &err);
|
||||
if (err != NULL) {
|
||||
error_propagate(errp, err);
|
||||
object_unparent(OBJECT(dev));
|
||||
return NULL;
|
||||
}
|
||||
object_property_set_bool(OBJECT(dev), true, "realized", &err);
|
||||
if (err != NULL) {
|
||||
error_propagate(errp, err);
|
||||
@ -288,7 +295,7 @@ void scsi_bus_legacy_handle_cmdline(SCSIBus *bus, bool deprecated)
|
||||
}
|
||||
}
|
||||
scsi_bus_legacy_add_drive(bus, blk_by_legacy_dinfo(dinfo),
|
||||
unit, false, -1, NULL, &error_fatal);
|
||||
unit, false, -1, false, NULL, &error_fatal);
|
||||
}
|
||||
loc_pop(&loc);
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ redirect.o-libs = $(USB_REDIR_LIBS)
|
||||
|
||||
# usb pass-through
|
||||
ifeq ($(CONFIG_USB_LIBUSB)$(CONFIG_USB),yy)
|
||||
common-obj-y += host-libusb.o host-legacy.o
|
||||
common-obj-y += host-libusb.o
|
||||
else
|
||||
common-obj-y += host-stub.o
|
||||
endif
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "qemu/thread.h"
|
||||
#include "qemu/main-loop.h"
|
||||
#include "ccid.h"
|
||||
#include "qapi/error.h"
|
||||
|
||||
#define DPRINTF(card, lvl, fmt, ...) \
|
||||
do {\
|
||||
@ -401,10 +402,10 @@ static void card_event_handler(EventNotifier *notifier)
|
||||
qemu_mutex_unlock(&card->event_list_mutex);
|
||||
}
|
||||
|
||||
static int init_event_notifier(EmulatedState *card)
|
||||
static int init_event_notifier(EmulatedState *card, Error **errp)
|
||||
{
|
||||
if (event_notifier_init(&card->notifier, false) < 0) {
|
||||
DPRINTF(card, 2, "event notifier creation failed\n");
|
||||
error_setg(errp, "ccid-card-emul: event notifier creation failed");
|
||||
return -1;
|
||||
}
|
||||
event_notifier_set_handler(&card->notifier, card_event_handler);
|
||||
@ -480,7 +481,7 @@ static uint32_t parse_enumeration(char *str,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int emulated_initfn(CCIDCardState *base)
|
||||
static void emulated_realize(CCIDCardState *base, Error **errp)
|
||||
{
|
||||
EmulatedState *card = EMULATED_CCID_CARD(base);
|
||||
VCardEmulError ret;
|
||||
@ -494,8 +495,8 @@ static int emulated_initfn(CCIDCardState *base)
|
||||
qemu_cond_init(&card->handle_apdu_cond);
|
||||
card->reader = NULL;
|
||||
card->quit_apdu_thread = 0;
|
||||
if (init_event_notifier(card) < 0) {
|
||||
return -1;
|
||||
if (init_event_notifier(card, errp) < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
card->backend = 0;
|
||||
@ -505,11 +506,11 @@ static int emulated_initfn(CCIDCardState *base)
|
||||
}
|
||||
|
||||
if (card->backend == 0) {
|
||||
printf("backend must be one of:\n");
|
||||
error_setg(errp, "backend must be one of:");
|
||||
for (ptable = backend_enum_table; ptable->name != NULL; ++ptable) {
|
||||
printf("%s\n", ptable->name);
|
||||
error_append_hint(errp, "%s\n", ptable->name);
|
||||
}
|
||||
return -1;
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO: a passthru backened that works on local machine. third card type?*/
|
||||
@ -517,37 +518,36 @@ static int emulated_initfn(CCIDCardState *base)
|
||||
if (card->cert1 != NULL && card->cert2 != NULL && card->cert3 != NULL) {
|
||||
ret = emulated_initialize_vcard_from_certificates(card);
|
||||
} else {
|
||||
printf("%s: you must provide all three certs for"
|
||||
" certificates backend\n", TYPE_EMULATED_CCID);
|
||||
return -1;
|
||||
error_setg(errp, "%s: you must provide all three certs for"
|
||||
" certificates backend", TYPE_EMULATED_CCID);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (card->backend != BACKEND_NSS_EMULATED) {
|
||||
printf("%s: bad backend specified. The options are:\n%s (default),"
|
||||
" %s.\n", TYPE_EMULATED_CCID, BACKEND_NSS_EMULATED_NAME,
|
||||
BACKEND_CERTIFICATES_NAME);
|
||||
return -1;
|
||||
error_setg(errp, "%s: bad backend specified. The options are:%s"
|
||||
" (default), %s.", TYPE_EMULATED_CCID,
|
||||
BACKEND_NSS_EMULATED_NAME, BACKEND_CERTIFICATES_NAME);
|
||||
return;
|
||||
}
|
||||
if (card->cert1 != NULL || card->cert2 != NULL || card->cert3 != NULL) {
|
||||
printf("%s: unexpected cert parameters to nss emulated backend\n",
|
||||
TYPE_EMULATED_CCID);
|
||||
return -1;
|
||||
error_setg(errp, "%s: unexpected cert parameters to nss emulated "
|
||||
"backend", TYPE_EMULATED_CCID);
|
||||
return;
|
||||
}
|
||||
/* default to mirroring the local hardware readers */
|
||||
ret = wrap_vcard_emul_init(NULL);
|
||||
}
|
||||
if (ret != VCARD_EMUL_OK) {
|
||||
printf("%s: failed to initialize vcard\n", TYPE_EMULATED_CCID);
|
||||
return -1;
|
||||
error_setg(errp, "%s: failed to initialize vcard", TYPE_EMULATED_CCID);
|
||||
return;
|
||||
}
|
||||
qemu_thread_create(&card->event_thread_id, "ccid/event", event_thread,
|
||||
card, QEMU_THREAD_JOINABLE);
|
||||
qemu_thread_create(&card->apdu_thread_id, "ccid/apdu", handle_apdu_thread,
|
||||
card, QEMU_THREAD_JOINABLE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void emulated_exitfn(CCIDCardState *base)
|
||||
static void emulated_unrealize(CCIDCardState *base, Error **errp)
|
||||
{
|
||||
EmulatedState *card = EMULATED_CCID_CARD(base);
|
||||
VEvent *vevent = vevent_new(VEVENT_LAST, NULL, NULL);
|
||||
@ -581,8 +581,8 @@ static void emulated_class_initfn(ObjectClass *klass, void *data)
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
CCIDCardClass *cc = CCID_CARD_CLASS(klass);
|
||||
|
||||
cc->initfn = emulated_initfn;
|
||||
cc->exitfn = emulated_exitfn;
|
||||
cc->realize = emulated_realize;
|
||||
cc->unrealize = emulated_unrealize;
|
||||
cc->get_atr = emulated_get_atr;
|
||||
cc->apdu_from_guest = emulated_apdu_from_guest;
|
||||
set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
|
||||
|
@ -9,11 +9,13 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qapi/error.h"
|
||||
#include <cacard/vscard_common.h>
|
||||
#include "chardev/char-fe.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "qemu/sockets.h"
|
||||
#include "ccid.h"
|
||||
#include "qapi/error.h"
|
||||
|
||||
#define DPRINTF(card, lvl, fmt, ...) \
|
||||
do { \
|
||||
@ -337,29 +339,28 @@ static const uint8_t *passthru_get_atr(CCIDCardState *base, uint32_t *len)
|
||||
return card->atr;
|
||||
}
|
||||
|
||||
static int passthru_initfn(CCIDCardState *base)
|
||||
static void passthru_realize(CCIDCardState *base, Error **errp)
|
||||
{
|
||||
PassthruState *card = PASSTHRU_CCID_CARD(base);
|
||||
|
||||
card->vscard_in_pos = 0;
|
||||
card->vscard_in_hdr = 0;
|
||||
if (qemu_chr_fe_backend_connected(&card->cs)) {
|
||||
DPRINTF(card, D_INFO, "initing chardev\n");
|
||||
error_setg(errp, "ccid-card-passthru: initing chardev");
|
||||
qemu_chr_fe_set_handlers(&card->cs,
|
||||
ccid_card_vscard_can_read,
|
||||
ccid_card_vscard_read,
|
||||
ccid_card_vscard_event, NULL, card, NULL, true);
|
||||
ccid_card_vscard_send_init(card);
|
||||
} else {
|
||||
error_report("missing chardev");
|
||||
return -1;
|
||||
error_setg(errp, "missing chardev");
|
||||
return;
|
||||
}
|
||||
card->debug = parse_debug_env("QEMU_CCID_PASSTHRU_DEBUG", D_VERBOSE,
|
||||
card->debug);
|
||||
assert(sizeof(DEFAULT_ATR) <= MAX_ATR_SIZE);
|
||||
memcpy(card->atr, DEFAULT_ATR, sizeof(DEFAULT_ATR));
|
||||
card->atr_length = sizeof(DEFAULT_ATR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static VMStateDescription passthru_vmstate = {
|
||||
@ -387,7 +388,7 @@ static void passthru_class_initfn(ObjectClass *klass, void *data)
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
CCIDCardClass *cc = CCID_CARD_CLASS(klass);
|
||||
|
||||
cc->initfn = passthru_initfn;
|
||||
cc->realize = passthru_realize;
|
||||
cc->get_atr = passthru_get_atr;
|
||||
cc->apdu_from_guest = passthru_apdu_from_guest;
|
||||
set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
|
||||
|
@ -28,13 +28,15 @@ typedef struct CCIDCardInfo CCIDCardInfo;
|
||||
* into the smartcard device (hw/ccid-card-*.c)
|
||||
*/
|
||||
typedef struct CCIDCardClass {
|
||||
/*< private >*/
|
||||
DeviceClass parent_class;
|
||||
/*< public >*/
|
||||
const uint8_t *(*get_atr)(CCIDCardState *card, uint32_t *len);
|
||||
void (*apdu_from_guest)(CCIDCardState *card,
|
||||
const uint8_t *apdu,
|
||||
uint32_t len);
|
||||
void (*exitfn)(CCIDCardState *card);
|
||||
int (*initfn)(CCIDCardState *card);
|
||||
void (*realize)(CCIDCardState *card, Error **errp);
|
||||
void (*unrealize)(CCIDCardState *card, Error **errp);
|
||||
} CCIDCardClass;
|
||||
|
||||
/*
|
||||
|
@ -1382,31 +1382,6 @@ static void usb_net_instance_init(Object *obj)
|
||||
&dev->qdev, NULL);
|
||||
}
|
||||
|
||||
static USBDevice *usb_net_init(USBBus *bus, const char *cmdline)
|
||||
{
|
||||
Error *local_err = NULL;
|
||||
USBDevice *dev;
|
||||
QemuOpts *opts;
|
||||
int idx;
|
||||
|
||||
opts = qemu_opts_parse_noisily(qemu_find_opts("net"), cmdline, false);
|
||||
if (!opts) {
|
||||
return NULL;
|
||||
}
|
||||
qemu_opt_set(opts, "type", "nic", &error_abort);
|
||||
qemu_opt_set(opts, "model", "usb", &error_abort);
|
||||
|
||||
idx = net_client_init(opts, false, &local_err);
|
||||
if (local_err) {
|
||||
error_report_err(local_err);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dev = usb_create(bus, "usb-net");
|
||||
qdev_set_nic_properties(&dev->qdev, &nd_table[idx]);
|
||||
return dev;
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_usb_net = {
|
||||
.name = "usb-net",
|
||||
.unmigratable = 1,
|
||||
@ -1446,7 +1421,6 @@ static const TypeInfo net_info = {
|
||||
static void usb_net_register_types(void)
|
||||
{
|
||||
type_register_static(&net_info);
|
||||
usb_legacy_register(TYPE_USB_NET, "net", usb_net_init);
|
||||
}
|
||||
|
||||
type_init(usb_net_register_types)
|
||||
|
@ -509,35 +509,6 @@ static void usb_serial_realize(USBDevice *dev, Error **errp)
|
||||
}
|
||||
}
|
||||
|
||||
static USBDevice *usb_serial_init(USBBus *bus, const char *filename)
|
||||
{
|
||||
USBDevice *dev;
|
||||
Chardev *cdrv;
|
||||
char label[32];
|
||||
static int index;
|
||||
|
||||
if (*filename == ':') {
|
||||
filename++;
|
||||
} else if (*filename) {
|
||||
error_report("unrecognized serial USB option %s", filename);
|
||||
return NULL;
|
||||
}
|
||||
if (!*filename) {
|
||||
error_report("character device specification needed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
snprintf(label, sizeof(label), "usbserial%d", index++);
|
||||
cdrv = qemu_chr_new(label, filename);
|
||||
if (!cdrv)
|
||||
return NULL;
|
||||
|
||||
dev = usb_create(bus, "usb-serial");
|
||||
qdev_prop_set_chr(&dev->qdev, "chardev", cdrv);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
static USBDevice *usb_braille_init(USBBus *bus, const char *unused)
|
||||
{
|
||||
USBDevice *dev;
|
||||
@ -624,7 +595,6 @@ static void usb_serial_register_types(void)
|
||||
{
|
||||
type_register_static(&usb_serial_dev_type_info);
|
||||
type_register_static(&serial_info);
|
||||
usb_legacy_register("usb-serial", "serial", usb_serial_init);
|
||||
type_register_static(&braille_info);
|
||||
usb_legacy_register("usb-braille", "braille", usb_braille_init);
|
||||
}
|
||||
|
@ -500,26 +500,6 @@ static void ccid_card_apdu_from_guest(CCIDCardState *card,
|
||||
}
|
||||
}
|
||||
|
||||
static void ccid_card_exitfn(CCIDCardState *card)
|
||||
{
|
||||
CCIDCardClass *cc = CCID_CARD_GET_CLASS(card);
|
||||
|
||||
if (cc->exitfn) {
|
||||
cc->exitfn(card);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static int ccid_card_initfn(CCIDCardState *card)
|
||||
{
|
||||
CCIDCardClass *cc = CCID_CARD_GET_CLASS(card);
|
||||
|
||||
if (cc->initfn) {
|
||||
return cc->initfn(card);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool ccid_has_pending_answers(USBCCIDState *s)
|
||||
{
|
||||
return s->pending_answers_num > 0;
|
||||
@ -1281,41 +1261,52 @@ void ccid_card_card_inserted(CCIDCardState *card)
|
||||
ccid_on_slot_change(s, true);
|
||||
}
|
||||
|
||||
static int ccid_card_exit(DeviceState *qdev)
|
||||
static void ccid_card_unrealize(DeviceState *qdev, Error **errp)
|
||||
{
|
||||
CCIDCardState *card = CCID_CARD(qdev);
|
||||
CCIDCardClass *cc = CCID_CARD_GET_CLASS(card);
|
||||
USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent);
|
||||
USBCCIDState *s = USB_CCID_DEV(dev);
|
||||
Error *local_err = NULL;
|
||||
|
||||
if (ccid_card_inserted(s)) {
|
||||
ccid_card_card_removed(card);
|
||||
}
|
||||
ccid_card_exitfn(card);
|
||||
if (cc->unrealize) {
|
||||
cc->unrealize(card, &local_err);
|
||||
if (local_err != NULL) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
s->card = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ccid_card_init(DeviceState *qdev)
|
||||
static void ccid_card_realize(DeviceState *qdev, Error **errp)
|
||||
{
|
||||
CCIDCardState *card = CCID_CARD(qdev);
|
||||
CCIDCardClass *cc = CCID_CARD_GET_CLASS(card);
|
||||
USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent);
|
||||
USBCCIDState *s = USB_CCID_DEV(dev);
|
||||
int ret = 0;
|
||||
Error *local_err = NULL;
|
||||
|
||||
if (card->slot != 0) {
|
||||
warn_report("usb-ccid supports one slot, can't add %d",
|
||||
card->slot);
|
||||
return -1;
|
||||
error_setg(errp, "usb-ccid supports one slot, can't add %d",
|
||||
card->slot);
|
||||
return;
|
||||
}
|
||||
if (s->card != NULL) {
|
||||
warn_report("usb-ccid card already full, not adding");
|
||||
return -1;
|
||||
error_setg(errp, "usb-ccid card already full, not adding");
|
||||
return;
|
||||
}
|
||||
ret = ccid_card_initfn(card);
|
||||
if (ret == 0) {
|
||||
s->card = card;
|
||||
if (cc->realize) {
|
||||
cc->realize(card, &local_err);
|
||||
if (local_err != NULL) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
s->card = card;
|
||||
}
|
||||
|
||||
static void ccid_realize(USBDevice *dev, Error **errp)
|
||||
@ -1477,8 +1468,8 @@ static void ccid_card_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *k = DEVICE_CLASS(klass);
|
||||
k->bus_type = TYPE_CCID_BUS;
|
||||
k->init = ccid_card_init;
|
||||
k->exit = ccid_card_exit;
|
||||
k->realize = ccid_card_realize;
|
||||
k->unrealize = ccid_card_unrealize;
|
||||
k->props = ccid_props;
|
||||
}
|
||||
|
||||
|
@ -633,7 +633,8 @@ static void usb_msd_storage_realize(USBDevice *dev, Error **errp)
|
||||
scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev),
|
||||
&usb_msd_scsi_info_storage, NULL);
|
||||
scsi_dev = scsi_bus_legacy_add_drive(&s->bus, blk, 0, !!s->removable,
|
||||
s->conf.bootindex, dev->serial,
|
||||
s->conf.bootindex, s->conf.share_rw,
|
||||
dev->serial,
|
||||
errp);
|
||||
blk_unref(blk);
|
||||
if (!scsi_dev) {
|
||||
@ -666,63 +667,6 @@ static void usb_msd_bot_realize(USBDevice *dev, Error **errp)
|
||||
usb_msd_handle_reset(dev);
|
||||
}
|
||||
|
||||
static USBDevice *usb_msd_init(USBBus *bus, const char *filename)
|
||||
{
|
||||
static int nr=0;
|
||||
Error *err = NULL;
|
||||
char id[8];
|
||||
QemuOpts *opts;
|
||||
DriveInfo *dinfo;
|
||||
USBDevice *dev;
|
||||
const char *p1;
|
||||
char fmt[32];
|
||||
|
||||
/* parse -usbdevice disk: syntax into drive opts */
|
||||
do {
|
||||
snprintf(id, sizeof(id), "usb%d", nr++);
|
||||
opts = qemu_opts_create(qemu_find_opts("drive"), id, 1, NULL);
|
||||
} while (!opts);
|
||||
|
||||
p1 = strchr(filename, ':');
|
||||
if (p1++) {
|
||||
const char *p2;
|
||||
|
||||
if (strstart(filename, "format=", &p2)) {
|
||||
int len = MIN(p1 - p2, sizeof(fmt));
|
||||
pstrcpy(fmt, len, p2);
|
||||
qemu_opt_set(opts, "format", fmt, &error_abort);
|
||||
} else if (*filename != ':') {
|
||||
error_report("unrecognized USB mass-storage option %s", filename);
|
||||
return NULL;
|
||||
}
|
||||
filename = p1;
|
||||
}
|
||||
if (!*filename) {
|
||||
error_report("block device specification needed");
|
||||
return NULL;
|
||||
}
|
||||
qemu_opt_set(opts, "file", filename, &error_abort);
|
||||
qemu_opt_set(opts, "if", "none", &error_abort);
|
||||
|
||||
/* create host drive */
|
||||
dinfo = drive_new(opts, 0);
|
||||
if (!dinfo) {
|
||||
qemu_opts_del(opts);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* create guest device */
|
||||
dev = usb_create(bus, "usb-storage");
|
||||
qdev_prop_set_drive(&dev->qdev, "drive", blk_by_legacy_dinfo(dinfo),
|
||||
&err);
|
||||
if (err) {
|
||||
error_report_err(err);
|
||||
object_unparent(OBJECT(dev));
|
||||
return NULL;
|
||||
}
|
||||
return dev;
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_usb_msd = {
|
||||
.name = "usb-storage",
|
||||
.version_id = 1,
|
||||
@ -855,7 +799,6 @@ static void usb_msd_register_types(void)
|
||||
type_register_static(&usb_storage_dev_type_info);
|
||||
type_register_static(&msd_info);
|
||||
type_register_static(&bot_info);
|
||||
usb_legacy_register("usb-storage", "disk", usb_msd_init);
|
||||
}
|
||||
|
||||
type_init(usb_msd_register_types)
|
||||
|
@ -1,144 +0,0 @@
|
||||
/*
|
||||
* 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/osdep.h"
|
||||
#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);
|
||||
return dev;
|
||||
|
||||
fail:
|
||||
object_unparent(OBJECT(dev));
|
||||
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)
|
@ -41,12 +41,6 @@ void hmp_info_usbhost(Monitor *mon, const QDict *qdict)
|
||||
monitor_printf(mon, "USB host devices not supported\n");
|
||||
}
|
||||
|
||||
/* XXX: modify configure to compile the right host driver */
|
||||
USBDevice *usb_host_device_open(USBBus *bus, const char *devname)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool usb_host_dev_is_scsi_storage(USBDevice *ud)
|
||||
{
|
||||
return false;
|
||||
|
@ -151,6 +151,7 @@ static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d)
|
||||
|
||||
SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockBackend *blk,
|
||||
int unit, bool removable, int bootindex,
|
||||
bool share_rw,
|
||||
const char *serial, Error **errp);
|
||||
void scsi_bus_legacy_handle_cmdline(SCSIBus *bus, bool deprecated);
|
||||
void scsi_legacy_handle_cmdline(void);
|
||||
|
@ -466,7 +466,6 @@ void usb_wakeup(USBEndpoint *ep, unsigned int stream);
|
||||
void usb_generic_async_ctrl_complete(USBDevice *s, USBPacket *p);
|
||||
|
||||
/* usb-linux.c */
|
||||
USBDevice *usb_host_device_open(USBBus *bus, const char *devname);
|
||||
void hmp_info_usbhost(Monitor *mon, const QDict *qdict);
|
||||
bool usb_host_dev_is_scsi_storage(USBDevice *usbdev);
|
||||
|
||||
|
@ -1221,29 +1221,10 @@ Pointer device that uses absolute coordinates (like a touchscreen). This
|
||||
means QEMU is able to report the mouse position without having to grab the
|
||||
mouse. Also overrides the PS/2 mouse emulation when activated.
|
||||
|
||||
@item disk:[format=@var{format}]:@var{file}
|
||||
Mass storage device based on file. The optional @var{format} argument
|
||||
will be used rather than detecting the format. Can be used to specify
|
||||
@code{format=raw} to avoid interpreting an untrusted format header.
|
||||
|
||||
@item host:@var{bus}.@var{addr}
|
||||
Pass through the host device identified by @var{bus}.@var{addr} (Linux only).
|
||||
|
||||
@item host:@var{vendor_id}:@var{product_id}
|
||||
Pass through the host device identified by @var{vendor_id}:@var{product_id}
|
||||
(Linux only).
|
||||
|
||||
@item serial:[vendorid=@var{vendor_id}][,productid=@var{product_id}]:@var{dev}
|
||||
Serial converter to host character device @var{dev}, see @code{-serial} for the
|
||||
available devices.
|
||||
|
||||
@item braille
|
||||
Braille device. This will use BrlAPI to display the braille output on a real
|
||||
or fake device.
|
||||
|
||||
@item net:@var{options}
|
||||
Network adapter that supports CDC ethernet and RNDIS protocols.
|
||||
|
||||
@end table
|
||||
ETEXI
|
||||
|
||||
|
15
vl.c
15
vl.c
@ -1451,30 +1451,15 @@ static void igd_gfx_passthru(void)
|
||||
static int usb_device_add(const char *devname)
|
||||
{
|
||||
USBDevice *dev = NULL;
|
||||
#ifndef CONFIG_LINUX
|
||||
const char *p;
|
||||
#endif
|
||||
|
||||
if (!machine_usb(current_machine)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* drivers with .usbdevice_name entry in USBDeviceInfo */
|
||||
dev = usbdevice_create(devname);
|
||||
if (dev)
|
||||
goto done;
|
||||
|
||||
/* the other ones */
|
||||
#ifndef CONFIG_LINUX
|
||||
/* only the linux version is qdev-ified, usb-bsd still needs this */
|
||||
if (strstart(devname, "host:", &p)) {
|
||||
dev = usb_host_device_open(usb_bus_find(-1), p);
|
||||
}
|
||||
#endif
|
||||
if (!dev)
|
||||
return -1;
|
||||
|
||||
done:
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user