Fix USB device speed reporting across host controllers #75
No files matched your search
@@ -247,8 +247,7 @@ begin
|
|||||||
if (status AND $01) <> 0 then begin
|
if (status AND $01) <> 0 then begin
|
||||||
io.syslog.log('driver.bus.usb Core', 'Device detected on port ');
|
io.syslog.log('driver.bus.usb Core', 'Device detected on port ');
|
||||||
io.syslog.writeintln(port);
|
io.syslog.writeintln(port);
|
||||||
{ Determine speed from status bits - HC specific,
|
{ Root-port speed is resolved by enumerate_device after reset. }
|
||||||
default to full-speed for now }
|
|
||||||
speed := USB_SPEED_FULL;
|
speed := USB_SPEED_FULL;
|
||||||
enumerate_device(hc, port, speed, nil, port);
|
enumerate_device(hc, port, speed, nil, port);
|
||||||
end;
|
end;
|
||||||
@@ -656,6 +655,10 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ Speed is valid after reset. Hub children retain the hub-reported speed. }
|
||||||
|
if (parentHub = nil) and (hc^.fnPortSpeed <> nil) then
|
||||||
|
speed := hc^.fnPortSpeed(hc, port);
|
||||||
|
|
||||||
{ Step 2: Create device at address 0 }
|
{ Step 2: Create device at address 0 }
|
||||||
dev := PUSBDevice(kalloc(sizeof(TUSBDevice)));
|
dev := PUSBDevice(kalloc(sizeof(TUSBDevice)));
|
||||||
dev^.Address := 0;
|
dev^.Address := 0;
|
||||||
|
|||||||
@@ -783,6 +783,13 @@ end;
|
|||||||
|
|
||||||
{ ========================= Port Reset ========================= }
|
{ ========================= Port Reset ========================= }
|
||||||
|
|
||||||
|
function ehci_port_speed(hc : PUSBHCDriver; port : uint8) : uint8;
|
||||||
|
begin
|
||||||
|
{ Successful EHCI root resets retain only high-speed devices;
|
||||||
|
full/low-speed devices are handed to a companion controller. }
|
||||||
|
ehci_port_speed := USB_SPEED_HIGH;
|
||||||
|
end;
|
||||||
|
|
||||||
function ehci_port_reset(hc : PUSBHCDriver; port : uint8) : boolean;
|
function ehci_port_reset(hc : PUSBHCDriver; port : uint8) : boolean;
|
||||||
var
|
var
|
||||||
priv : PEHCI_PrivData;
|
priv : PEHCI_PrivData;
|
||||||
@@ -1558,6 +1565,7 @@ begin
|
|||||||
hc.fnPoll := TUSBHCPoll(@ehci_poll);
|
hc.fnPoll := TUSBHCPoll(@ehci_poll);
|
||||||
hc.fnPortReset := TUSBHCPortReset(@ehci_port_reset);
|
hc.fnPortReset := TUSBHCPortReset(@ehci_port_reset);
|
||||||
hc.fnPortStatus := TUSBHCPortStatus(@ehci_port_status);
|
hc.fnPortStatus := TUSBHCPortStatus(@ehci_port_status);
|
||||||
|
hc.fnPortSpeed := TUSBHCPortSpeed(@ehci_port_speed);
|
||||||
|
|
||||||
{ Reset the controller }
|
{ Reset the controller }
|
||||||
if not ehci_reset(@hc) then begin
|
if not ehci_reset(@hc) then begin
|
||||||
|
|||||||
@@ -602,6 +602,14 @@ end;
|
|||||||
|
|
||||||
{ ========================= Port Reset ========================= }
|
{ ========================= Port Reset ========================= }
|
||||||
|
|
||||||
|
function ohci_port_speed(hc : PUSBHCDriver; port : uint8) : uint8;
|
||||||
|
begin
|
||||||
|
if (ohci_port_status(hc, port) AND OHCI_PORT_LSDA) <> 0 then
|
||||||
|
ohci_port_speed := USB_SPEED_LOW
|
||||||
|
else
|
||||||
|
ohci_port_speed := USB_SPEED_FULL;
|
||||||
|
end;
|
||||||
|
|
||||||
function ohci_port_reset(hc : PUSBHCDriver; port : uint8) : boolean;
|
function ohci_port_reset(hc : PUSBHCDriver; port : uint8) : boolean;
|
||||||
var
|
var
|
||||||
priv : POHCI_PrivData;
|
priv : POHCI_PrivData;
|
||||||
@@ -1257,6 +1265,7 @@ begin
|
|||||||
hc.fnPoll := TUSBHCPoll(@ohci_poll);
|
hc.fnPoll := TUSBHCPoll(@ohci_poll);
|
||||||
hc.fnPortReset := TUSBHCPortReset(@ohci_port_reset);
|
hc.fnPortReset := TUSBHCPortReset(@ohci_port_reset);
|
||||||
hc.fnPortStatus := TUSBHCPortStatus(@ohci_port_status);
|
hc.fnPortStatus := TUSBHCPortStatus(@ohci_port_status);
|
||||||
|
hc.fnPortSpeed := TUSBHCPortSpeed(@ohci_port_speed);
|
||||||
|
|
||||||
{ Reset the controller }
|
{ Reset the controller }
|
||||||
if not ohci_reset(@hc) then begin
|
if not ohci_reset(@hc) then begin
|
||||||
|
|||||||
@@ -261,6 +261,8 @@ type
|
|||||||
TUSBHCPoll = procedure(hc : PUSBHCDriver);
|
TUSBHCPoll = procedure(hc : PUSBHCDriver);
|
||||||
TUSBHCPortReset = function(hc : PUSBHCDriver; port : uint8) : boolean;
|
TUSBHCPortReset = function(hc : PUSBHCDriver; port : uint8) : boolean;
|
||||||
TUSBHCPortStatus = function(hc : PUSBHCDriver; port : uint8) : uint32;
|
TUSBHCPortStatus = function(hc : PUSBHCDriver; port : uint8) : uint32;
|
||||||
|
{ Return USB_SPEED_* after root-port reset has completed. }
|
||||||
|
TUSBHCPortSpeed = function(hc : PUSBHCDriver; port : uint8) : uint8;
|
||||||
|
|
||||||
{ ---- HC Driver Record ---- }
|
{ ---- HC Driver Record ---- }
|
||||||
|
|
||||||
@@ -283,6 +285,7 @@ type
|
|||||||
fnPoll : TUSBHCPoll;
|
fnPoll : TUSBHCPoll;
|
||||||
fnPortReset : TUSBHCPortReset;
|
fnPortReset : TUSBHCPortReset;
|
||||||
fnPortStatus : TUSBHCPortStatus;
|
fnPortStatus : TUSBHCPortStatus;
|
||||||
|
fnPortSpeed : TUSBHCPortSpeed;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ ========================= Utility Functions ========================= }
|
{ ========================= Utility Functions ========================= }
|
||||||
@@ -429,6 +432,7 @@ begin
|
|||||||
hc^.fnPoll := nil;
|
hc^.fnPoll := nil;
|
||||||
hc^.fnPortReset := nil;
|
hc^.fnPortReset := nil;
|
||||||
hc^.fnPortStatus := nil;
|
hc^.fnPortStatus := nil;
|
||||||
|
hc^.fnPortSpeed := nil;
|
||||||
end;
|
end;
|
||||||
pop_trace;
|
pop_trace;
|
||||||
end;
|
end;
|
||||||
|
|||||||
@@ -453,6 +453,14 @@ end;
|
|||||||
|
|
||||||
{ ========================= Port Reset ========================= }
|
{ ========================= Port Reset ========================= }
|
||||||
|
|
||||||
|
function uhci_port_speed(hc : PUSBHCDriver; port : uint8) : uint8;
|
||||||
|
begin
|
||||||
|
if (uhci_port_status(hc, port) AND UHCI_PORT_LSDA) <> 0 then
|
||||||
|
uhci_port_speed := USB_SPEED_LOW
|
||||||
|
else
|
||||||
|
uhci_port_speed := USB_SPEED_FULL;
|
||||||
|
end;
|
||||||
|
|
||||||
function uhci_port_reset(hc : PUSBHCDriver; port : uint8) : boolean;
|
function uhci_port_reset(hc : PUSBHCDriver; port : uint8) : boolean;
|
||||||
var
|
var
|
||||||
priv : PUHCI_PrivData;
|
priv : PUHCI_PrivData;
|
||||||
@@ -976,6 +984,7 @@ begin
|
|||||||
hc.fnPoll := TUSBHCPoll(@uhci_poll);
|
hc.fnPoll := TUSBHCPoll(@uhci_poll);
|
||||||
hc.fnPortReset := TUSBHCPortReset(@uhci_port_reset);
|
hc.fnPortReset := TUSBHCPortReset(@uhci_port_reset);
|
||||||
hc.fnPortStatus := TUSBHCPortStatus(@uhci_port_status);
|
hc.fnPortStatus := TUSBHCPortStatus(@uhci_port_status);
|
||||||
|
hc.fnPortSpeed := TUSBHCPortSpeed(@uhci_port_speed);
|
||||||
|
|
||||||
{ Reset the controller }
|
{ Reset the controller }
|
||||||
if not uhci_reset(@hc) then begin
|
if not uhci_reset(@hc) then begin
|
||||||
|
|||||||
@@ -1142,6 +1142,12 @@ begin
|
|||||||
pop_trace;
|
pop_trace;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function xhci_port_speed(hc : PUSBHCDriver; port : uint8) : uint8;
|
||||||
|
begin
|
||||||
|
xhci_port_speed := xhci_map_speed(
|
||||||
|
(xhci_port_status(hc, port) AND XHCI_PORTSC_SPEED_MASK) SHR XHCI_PORTSC_SPEED_SHIFT);
|
||||||
|
end;
|
||||||
|
|
||||||
function xhci_port_reset(hc : PUSBHCDriver; port : uint8) : boolean;
|
function xhci_port_reset(hc : PUSBHCDriver; port : uint8) : boolean;
|
||||||
var
|
var
|
||||||
priv : PXHCI_PrivData;
|
priv : PXHCI_PrivData;
|
||||||
@@ -2095,6 +2101,7 @@ begin
|
|||||||
hc.fnPoll := TUSBHCPoll(@xhci_poll);
|
hc.fnPoll := TUSBHCPoll(@xhci_poll);
|
||||||
hc.fnPortReset := TUSBHCPortReset(@xhci_port_reset);
|
hc.fnPortReset := TUSBHCPortReset(@xhci_port_reset);
|
||||||
hc.fnPortStatus := TUSBHCPortStatus(@xhci_port_status);
|
hc.fnPortStatus := TUSBHCPortStatus(@xhci_port_status);
|
||||||
|
hc.fnPortSpeed := TUSBHCPortSpeed(@xhci_port_speed);
|
||||||
|
|
||||||
{ Reset the controller }
|
{ Reset the controller }
|
||||||
if not xhci_reset(@hc) then begin
|
if not xhci_reset(@hc) then begin
|
||||||
|
|||||||
Reference in new issue
Block a user