Feature: USB - Hotplug, mass storage, disconnect callbacks, dynamic device lists
- Add disconnect callback (fnDisconnect) to TUSBDevice for safe unplug handling - Add HotplugArmed/PortChangePending flags to TUSBHCDriver for deferred hotplug processing from ISR context (OHCI RHSC, EHCI PCD, xHCI PSC) - Implement usb_rescan_port() and usb_check_hotplug() in usbcore - Add usb_bulk_transfer_wait() with timer-based timeout (bios_data_area) - Add timer-based timeout to usb_control_msg polling loop - Replace static device arrays with dynamic linked lists in class drivers: usb_keyboard (KeyboardList), usb_mouse (MouseList), usb_storage (StorageList) - Add 3-strike fail-count self-deactivation in keyboard/mouse poll loops - Add unload() disconnect handlers for keyboard, mouse, and storage drivers - Implement USB Mass Storage BOT driver (usb_storage.pas): CBW/CSW transport, SCSI INQUIRY/READ_CAPACITY/READ10/WRITE10, storagemanagement integration with read/write callbacks - xHCI: acknowledge port status change W1C bits in event handler - Integrate usb_check_hotplug + poll_keyboards/poll_mice into kernel main loop
This commit is contained in:
@@ -1355,6 +1355,10 @@ begin
|
||||
|
||||
{ Process completions (walks QH lists) }
|
||||
ehci_poll(hc);
|
||||
|
||||
{ Hotplug: if Port Change Detect, flag for deferred processing }
|
||||
if ((usbsts AND EHCI_STS_PCD) <> 0) and hc^.HotplugArmed then
|
||||
hc^.PortChangePending := true;
|
||||
end;
|
||||
usbcore.fire_completion_hooks;
|
||||
end;
|
||||
|
||||
@@ -1058,6 +1058,10 @@ begin
|
||||
|
||||
{ Process completions (walks ED lists) }
|
||||
ohci_poll(hc);
|
||||
|
||||
{ Hotplug: if RootHubStatusChange, flag for deferred processing }
|
||||
if ((intSts AND OHCI_INT_RHSC) <> 0) and hc^.HotplugArmed then
|
||||
hc^.PortChangePending := true;
|
||||
end;
|
||||
usbcore.fire_completion_hooks;
|
||||
end;
|
||||
|
||||
@@ -35,6 +35,7 @@ uses
|
||||
usbhub,
|
||||
usb_keyboard,
|
||||
usb_mouse,
|
||||
usb_storage,
|
||||
OHCI, UHCI, EHCI, XHCI;
|
||||
|
||||
procedure init;
|
||||
@@ -89,6 +90,9 @@ begin
|
||||
{ Initialize HID class drivers }
|
||||
usb_keyboard.init;
|
||||
usb_mouse.init;
|
||||
|
||||
{ Initialize storage class driver }
|
||||
usb_storage.init;
|
||||
|
||||
UHCI_ID.Bus:= biPCI;
|
||||
UHCI_ID.id0:= idANY;
|
||||
|
||||
@@ -1870,6 +1870,8 @@ var
|
||||
pend : PXHCI_PendingTransfer;
|
||||
transfer : PUSBTransfer;
|
||||
processed : boolean;
|
||||
hpPortId : uint8;
|
||||
hpPortSC : uint32;
|
||||
begin
|
||||
if (hc = nil) or (hc^.PrivData = nil) then exit;
|
||||
priv := PXHCI_PrivData(hc^.PrivData);
|
||||
@@ -1924,9 +1926,19 @@ begin
|
||||
end;
|
||||
|
||||
XHCI_TRB_PORT_STATUS_CHG: begin
|
||||
{ Port ID in bits 31:24 of Param0 }
|
||||
{ Port ID in bits 31:24 of Param0 (1-based) }
|
||||
hpPortId := uint8((evt.Param0 SHR 24) AND $FF);
|
||||
syslog.log('XHCI', 'Port Status Change: port ');
|
||||
syslog.writeintln((evt.Param0 SHR 24) AND $FF);
|
||||
syslog.writeintln(hpPortId);
|
||||
if hpPortId > 0 then begin
|
||||
{ Acknowledge port status change by writing W1C bits }
|
||||
hpPortSC := xhci_readl(priv^.OpBase, XHCI_OP_PORTSC_BASE + ((hpPortId - 1) * $10));
|
||||
xhci_writel(priv^.OpBase, XHCI_OP_PORTSC_BASE + ((hpPortId - 1) * $10),
|
||||
(hpPortSC AND $0E00C3E0) OR $00FE0000);
|
||||
{ Flag for deferred hotplug processing }
|
||||
if hc^.HotplugArmed then
|
||||
hc^.PortChangePending := true;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -217,6 +217,9 @@ type
|
||||
PUSBHCDriver = ^TUSBHCDriver;
|
||||
PUSBTransfer = ^TUSBTransfer;
|
||||
|
||||
{ ---- Disconnect Callback ---- }
|
||||
TUSBDisconnectCallback = procedure(dev : PUSBDevice);
|
||||
|
||||
{ ---- Transfer Request ---- }
|
||||
|
||||
TUSBTransfer = record
|
||||
@@ -246,6 +249,7 @@ type
|
||||
Endpoints : array[0..USB_MAX_ENDPOINTS-1] of TUSBEndpoint;
|
||||
NumEndpoints : uint8;
|
||||
Configured : boolean;
|
||||
fnDisconnect : TUSBDisconnectCallback; { Called before device is freed on unplug }
|
||||
end;
|
||||
|
||||
{ ---- HC Driver Abstraction (Function Pointer Types) ---- }
|
||||
@@ -269,6 +273,8 @@ type
|
||||
PrivData : Pointer; { HC-specific state }
|
||||
Devices : PLinkedListBase; { List of PUSBDevice attached }
|
||||
NextAddress : uint8; { Next available USB address (1-127) }
|
||||
PortChangePending : boolean; { Set by ISR when port status changes; processed in deferred context }
|
||||
HotplugArmed : boolean; { False during boot; set true after initial scan_ports to ignore spurious RHSC }
|
||||
{ Operations }
|
||||
fnReset : TUSBHCReset;
|
||||
fnStart : TUSBHCStart;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user