Revision 0d92ed30 vl.c
b/vl.c | ||
---|---|---|
106 | 106 |
/* in ms */ |
107 | 107 |
#define GUI_REFRESH_INTERVAL 30 |
108 | 108 |
|
109 |
/* Max number of USB devices that can be specified on the commandline. */ |
|
110 |
#define MAX_USB_CMDLINE 8 |
|
111 |
|
|
109 | 112 |
/* XXX: use a two level table to limit memory usage */ |
110 | 113 |
#define MAX_IOPORTS 65536 |
111 | 114 |
|
... | ... | |
145 | 148 |
int win2k_install_hack = 0; |
146 | 149 |
#endif |
147 | 150 |
int usb_enabled = 0; |
148 |
USBPort *vm_usb_ports[MAX_VM_USB_PORTS]; |
|
149 |
USBDevice *vm_usb_hub; |
|
150 | 151 |
static VLANState *first_vlan; |
151 | 152 |
int smp_cpus = 1; |
152 | 153 |
int vnc_display = -1; |
... | ... | |
3249 | 3250 |
/***********************************************************/ |
3250 | 3251 |
/* USB devices */ |
3251 | 3252 |
|
3253 |
static USBPort *used_usb_ports; |
|
3254 |
static USBPort *free_usb_ports; |
|
3255 |
|
|
3256 |
/* ??? Maybe change this to register a hub to keep track of the topology. */ |
|
3257 |
void qemu_register_usb_port(USBPort *port, void *opaque, int index, |
|
3258 |
usb_attachfn attach) |
|
3259 |
{ |
|
3260 |
port->opaque = opaque; |
|
3261 |
port->index = index; |
|
3262 |
port->attach = attach; |
|
3263 |
port->next = free_usb_ports; |
|
3264 |
free_usb_ports = port; |
|
3265 |
} |
|
3266 |
|
|
3252 | 3267 |
static int usb_device_add(const char *devname) |
3253 | 3268 |
{ |
3254 | 3269 |
const char *p; |
3255 | 3270 |
USBDevice *dev; |
3256 |
int i;
|
|
3271 |
USBPort *port;
|
|
3257 | 3272 |
|
3258 |
if (!vm_usb_hub) |
|
3259 |
return -1; |
|
3260 |
for(i = 0;i < MAX_VM_USB_PORTS; i++) { |
|
3261 |
if (!vm_usb_ports[i]->dev) |
|
3262 |
break; |
|
3263 |
} |
|
3264 |
if (i == MAX_VM_USB_PORTS) |
|
3273 |
if (!free_usb_ports) |
|
3265 | 3274 |
return -1; |
3266 | 3275 |
|
3267 | 3276 |
if (strstart(devname, "host:", &p)) { |
3268 | 3277 |
dev = usb_host_device_open(p); |
3269 |
if (!dev) |
|
3270 |
return -1; |
|
3271 | 3278 |
} else if (!strcmp(devname, "mouse")) { |
3272 | 3279 |
dev = usb_mouse_init(); |
3273 |
if (!dev) |
|
3274 |
return -1; |
|
3275 | 3280 |
} else if (!strcmp(devname, "tablet")) { |
3276 | 3281 |
dev = usb_tablet_init(); |
3277 |
if (!dev) |
|
3278 |
return -1; |
|
3279 | 3282 |
} else { |
3280 | 3283 |
return -1; |
3281 | 3284 |
} |
3282 |
usb_attach(vm_usb_ports[i], dev); |
|
3285 |
if (!dev) |
|
3286 |
return -1; |
|
3287 |
|
|
3288 |
/* Find a USB port to add the device to. */ |
|
3289 |
port = free_usb_ports; |
|
3290 |
if (!port->next) { |
|
3291 |
USBDevice *hub; |
|
3292 |
|
|
3293 |
/* Create a new hub and chain it on. */ |
|
3294 |
free_usb_ports = NULL; |
|
3295 |
port->next = used_usb_ports; |
|
3296 |
used_usb_ports = port; |
|
3297 |
|
|
3298 |
hub = usb_hub_init(VM_USB_HUB_SIZE); |
|
3299 |
usb_attach(port, hub); |
|
3300 |
port = free_usb_ports; |
|
3301 |
} |
|
3302 |
|
|
3303 |
free_usb_ports = port->next; |
|
3304 |
port->next = used_usb_ports; |
|
3305 |
used_usb_ports = port; |
|
3306 |
usb_attach(port, dev); |
|
3283 | 3307 |
return 0; |
3284 | 3308 |
} |
3285 | 3309 |
|
3286 | 3310 |
static int usb_device_del(const char *devname) |
3287 | 3311 |
{ |
3288 |
USBDevice *dev; |
|
3289 |
int bus_num, addr, i; |
|
3312 |
USBPort *port; |
|
3313 |
USBPort **lastp; |
|
3314 |
int bus_num, addr; |
|
3290 | 3315 |
const char *p; |
3291 | 3316 |
|
3292 |
if (!vm_usb_hub)
|
|
3317 |
if (!used_usb_ports)
|
|
3293 | 3318 |
return -1; |
3294 | 3319 |
|
3295 | 3320 |
p = strchr(devname, '.'); |
... | ... | |
3299 | 3324 |
addr = strtoul(p + 1, NULL, 0); |
3300 | 3325 |
if (bus_num != 0) |
3301 | 3326 |
return -1; |
3302 |
for(i = 0;i < MAX_VM_USB_PORTS; i++) { |
|
3303 |
dev = vm_usb_ports[i]->dev; |
|
3304 |
if (dev && dev->addr == addr) |
|
3305 |
break; |
|
3327 |
|
|
3328 |
lastp = &used_usb_ports; |
|
3329 |
port = used_usb_ports; |
|
3330 |
while (port && port->dev->addr != addr) { |
|
3331 |
lastp = &port->next; |
|
3332 |
port = port->next; |
|
3306 | 3333 |
} |
3307 |
if (i == MAX_VM_USB_PORTS) |
|
3334 |
|
|
3335 |
if (!port) |
|
3308 | 3336 |
return -1; |
3309 |
usb_attach(vm_usb_ports[i], NULL); |
|
3337 |
|
|
3338 |
*lastp = port->next; |
|
3339 |
usb_attach(port, NULL); |
|
3340 |
port->next = free_usb_ports; |
|
3341 |
free_usb_ports = port; |
|
3310 | 3342 |
return 0; |
3311 | 3343 |
} |
3312 | 3344 |
|
... | ... | |
3329 | 3361 |
void usb_info(void) |
3330 | 3362 |
{ |
3331 | 3363 |
USBDevice *dev; |
3332 |
int i;
|
|
3364 |
USBPort *port;
|
|
3333 | 3365 |
const char *speed_str; |
3334 | 3366 |
|
3335 |
if (!vm_usb_hub) {
|
|
3367 |
if (!usb_enabled) {
|
|
3336 | 3368 |
term_printf("USB support not enabled\n"); |
3337 | 3369 |
return; |
3338 | 3370 |
} |
3339 | 3371 |
|
3340 |
for(i = 0; i < MAX_VM_USB_PORTS; i++) { |
|
3341 |
dev = vm_usb_ports[i]->dev; |
|
3342 |
if (dev) { |
|
3343 |
term_printf("Hub port %d:\n", i); |
|
3344 |
switch(dev->speed) { |
|
3345 |
case USB_SPEED_LOW: |
|
3346 |
speed_str = "1.5"; |
|
3347 |
break; |
|
3348 |
case USB_SPEED_FULL: |
|
3349 |
speed_str = "12"; |
|
3350 |
break; |
|
3351 |
case USB_SPEED_HIGH: |
|
3352 |
speed_str = "480"; |
|
3353 |
break; |
|
3354 |
default: |
|
3355 |
speed_str = "?"; |
|
3356 |
break; |
|
3357 |
} |
|
3358 |
term_printf(" Device %d.%d, speed %s Mb/s\n", |
|
3359 |
0, dev->addr, speed_str); |
|
3372 |
for (port = used_usb_ports; port; port = port->next) { |
|
3373 |
dev = port->dev; |
|
3374 |
if (!dev) |
|
3375 |
continue; |
|
3376 |
switch(dev->speed) { |
|
3377 |
case USB_SPEED_LOW: |
|
3378 |
speed_str = "1.5"; |
|
3379 |
break; |
|
3380 |
case USB_SPEED_FULL: |
|
3381 |
speed_str = "12"; |
|
3382 |
break; |
|
3383 |
case USB_SPEED_HIGH: |
|
3384 |
speed_str = "480"; |
|
3385 |
break; |
|
3386 |
default: |
|
3387 |
speed_str = "?"; |
|
3388 |
break; |
|
3360 | 3389 |
} |
3390 |
term_printf(" Device %d.%d, speed %s Mb/s\n", |
|
3391 |
0, dev->addr, speed_str); |
|
3361 | 3392 |
} |
3362 | 3393 |
} |
3363 | 3394 |
|
... | ... | |
5066 | 5097 |
int parallel_device_index; |
5067 | 5098 |
const char *loadvm = NULL; |
5068 | 5099 |
QEMUMachine *machine; |
5069 |
char usb_devices[MAX_VM_USB_PORTS][128];
|
|
5100 |
char usb_devices[MAX_USB_CMDLINE][128];
|
|
5070 | 5101 |
int usb_devices_index; |
5071 | 5102 |
|
5072 | 5103 |
LIST_INIT (&vm_change_state_head); |
... | ... | |
5425 | 5456 |
break; |
5426 | 5457 |
case QEMU_OPTION_usbdevice: |
5427 | 5458 |
usb_enabled = 1; |
5428 |
if (usb_devices_index >= MAX_VM_USB_PORTS) {
|
|
5459 |
if (usb_devices_index >= MAX_USB_CMDLINE) {
|
|
5429 | 5460 |
fprintf(stderr, "Too many USB devices\n"); |
5430 | 5461 |
exit(1); |
5431 | 5462 |
} |
... | ... | |
5596 | 5627 |
} |
5597 | 5628 |
} |
5598 | 5629 |
|
5599 |
/* init USB devices */ |
|
5600 |
if (usb_enabled) { |
|
5601 |
vm_usb_hub = usb_hub_init(vm_usb_ports, MAX_VM_USB_PORTS); |
|
5602 |
for(i = 0; i < usb_devices_index; i++) { |
|
5603 |
if (usb_device_add(usb_devices[i]) < 0) { |
|
5604 |
fprintf(stderr, "Warning: could not add USB device %s\n", |
|
5605 |
usb_devices[i]); |
|
5606 |
} |
|
5607 |
} |
|
5608 |
} |
|
5609 |
|
|
5610 | 5630 |
register_savevm("timer", 0, 1, timer_save, timer_load, NULL); |
5611 | 5631 |
register_savevm("ram", 0, 1, ram_save, ram_load, NULL); |
5612 | 5632 |
|
... | ... | |
5710 | 5730 |
ds, fd_filename, snapshot, |
5711 | 5731 |
kernel_filename, kernel_cmdline, initrd_filename); |
5712 | 5732 |
|
5733 |
/* init USB devices */ |
|
5734 |
if (usb_enabled) { |
|
5735 |
for(i = 0; i < usb_devices_index; i++) { |
|
5736 |
if (usb_device_add(usb_devices[i]) < 0) { |
|
5737 |
fprintf(stderr, "Warning: could not add USB device %s\n", |
|
5738 |
usb_devices[i]); |
|
5739 |
} |
|
5740 |
} |
|
5741 |
} |
|
5742 |
|
|
5713 | 5743 |
gui_timer = qemu_new_timer(rt_clock, gui_update, NULL); |
5714 | 5744 |
qemu_mod_timer(gui_timer, qemu_get_clock(rt_clock)); |
5715 | 5745 |
|
Also available in: Unified diff