diff --git a/bochs/iodev/usb/uhci_core.cc b/bochs/iodev/usb/uhci_core.cc index 4e8d4264ac..7358e35ba6 100644 --- a/bochs/iodev/usb/uhci_core.cc +++ b/bochs/iodev/usb/uhci_core.cc @@ -871,6 +871,10 @@ int bx_uhci_core_c::event_handler(int event, void *ptr, int port) break; // host controller events start here + case USB_EVENT_DEFAULT_SPEED: + // return default speed for specified port number + return USB_SPEED_FULL; + case USB_EVENT_CHECK_SPEED: if (ptr != NULL) { usb_device_c *usb_device = (usb_device_c *) ptr; diff --git a/bochs/iodev/usb/usb_common.cc b/bochs/iodev/usb/usb_common.cc index 58a7ee8714..7207adb7ba 100644 --- a/bochs/iodev/usb/usb_common.cc +++ b/bochs/iodev/usb/usb_common.cc @@ -157,7 +157,12 @@ static const char *usb_speed[4] = { void bx_usbdev_ctl_c::parse_port_options(usb_device_c *device, bx_list_c *portconf) { - int speed = device->get_default_speed(USB_SPEED_FULL); // try to default to FULL speed if parameter not given. + // if the speed option parameter is not given: + // first try to default to speed of controller + // then adjust to default max speed of device + // if the speed option parameter is given, this will be overwritten anyway + int speed = device->hc_event(USB_EVENT_DEFAULT_SPEED, device); + speed = device->get_default_speed(speed); char *opts[16]; memset(opts, 0, sizeof(opts)); diff --git a/bochs/iodev/usb/usb_common.h b/bochs/iodev/usb/usb_common.h index 8454edcdec..89c733de64 100644 --- a/bochs/iodev/usb/usb_common.h +++ b/bochs/iodev/usb/usb_common.h @@ -142,7 +142,8 @@ typedef struct USBPacket USBPacket; #define USB_EVENT_WAKEUP 0 #define USB_EVENT_ASYNC 1 // controller events -#define USB_EVENT_CHECK_SPEED 10 +#define USB_EVENT_DEFAULT_SPEED 10 +#define USB_EVENT_CHECK_SPEED 11 // set this to 1 to monitor the TD's toggle bit // setting to 0 will speed up the emualtion slightly @@ -240,7 +241,7 @@ class BOCHSAPI usb_device_c : public logfunctions { int get_default_speed(int speed) { if ((speed >= d.minspeed) && (speed <= d.maxspeed)) return speed; - return d.minspeed; // will be no more than full-speed + return BX_MIN(speed, d.maxspeed); } // return information for the specified ep of the current device diff --git a/bochs/iodev/usb/usb_ehci.cc b/bochs/iodev/usb/usb_ehci.cc index acfe3de9a2..c4265d0770 100644 --- a/bochs/iodev/usb/usb_ehci.cc +++ b/bochs/iodev/usb/usb_ehci.cc @@ -1324,6 +1324,10 @@ int bx_usb_ehci_c::event_handler(int event, void *ptr, int port) break; // host controller events start here + case USB_EVENT_DEFAULT_SPEED: + // return default speed for specified port number + return USB_SPEED_HIGH; + case USB_EVENT_CHECK_SPEED: if (ptr != NULL) { usb_device_c *usb_device = (usb_device_c *) ptr; diff --git a/bochs/iodev/usb/usb_ohci.cc b/bochs/iodev/usb/usb_ohci.cc index 3efe93bb98..5fd2b8e709 100644 --- a/bochs/iodev/usb/usb_ohci.cc +++ b/bochs/iodev/usb/usb_ohci.cc @@ -1233,6 +1233,10 @@ int bx_usb_ohci_c::event_handler(int event, void *ptr, int port) break; // host controller events start here + case USB_EVENT_DEFAULT_SPEED: + // return default speed for specified port number + return USB_SPEED_FULL; + case USB_EVENT_CHECK_SPEED: if (ptr != NULL) { usb_device_c *usb_device = (usb_device_c *) ptr; diff --git a/bochs/iodev/usb/usb_xhci.cc b/bochs/iodev/usb/usb_xhci.cc index ee2080bb52..c5fa770f60 100644 --- a/bochs/iodev/usb/usb_xhci.cc +++ b/bochs/iodev/usb/usb_xhci.cc @@ -2149,6 +2149,15 @@ int bx_usb_xhci_c::event_handler(int event, void *ptr, int port) break; // host controller events start here + case USB_EVENT_DEFAULT_SPEED: + // return default speed for specified port number + if (BX_XHCI_THIS hub.usb_port[port].is_usb3 == 1) { + // return super-speed + return USB_SPEED_SUPER; + } + // else return high-speed + return USB_SPEED_HIGH; + case USB_EVENT_CHECK_SPEED: // all super-speed device must be on the first half port register sets, // while all non-super-speed device must be on the second half.