usb: Add ability to attach and detach devices for real

This commit is contained in:
Cacodemon345
2023-05-08 22:30:28 +06:00
parent 2fac3e5dc5
commit 50b0fe4990
2 changed files with 32 additions and 19 deletions

View File

@@ -123,6 +123,7 @@ typedef struct
/* Global variables. */ /* Global variables. */
extern const device_t usb_device; extern const device_t usb_device;
extern usb_t* usb_device_inst;
/* Functions. */ /* Functions. */
extern void uhci_update_io_mapping(usb_t *dev, uint8_t base_l, uint8_t base_h, int enable); extern void uhci_update_io_mapping(usb_t *dev, uint8_t base_l, uint8_t base_h, int enable);

View File

@@ -129,6 +129,8 @@ enum
OHCI_HcControl_BulkListEnable = 1 << 4 OHCI_HcControl_BulkListEnable = 1 << 4
}; };
usb_t* usb_device_inst = NULL;
static void static void
usb_interrupt_ohci(usb_t *dev, uint32_t level) usb_interrupt_ohci(usb_t *dev, uint32_t level)
{ {
@@ -851,8 +853,12 @@ ohci_mmio_write(uint32_t addr, uint8_t val, void *p)
} }
if (val & 0x08) if (val & 0x08)
dev->ohci_mmio[addr >> 2].b[addr & 3] &= ~0x04; dev->ohci_mmio[addr >> 2].b[addr & 3] &= ~0x04;
if (val & 0x04) if (val & 0x04) {
dev->ohci_mmio[addr >> 2].b[addr & 3] |= 0x04; if (old & 0x01)
dev->ohci_mmio[addr >> 2].b[addr & 3] |= 0x04;
else
dev->ohci_mmio[(addr + 2) >> 2].b[(addr + 2) & 3] |= 0x01;
}
if (val & 0x02) { if (val & 0x02) {
if (old & 0x01) if (old & 0x01)
dev->ohci_mmio[addr >> 2].b[addr & 3] |= 0x02; dev->ohci_mmio[addr >> 2].b[addr & 3] |= 0x02;
@@ -946,13 +952,16 @@ usb_attach_device(usb_t *dev, usb_device_t* device, uint8_t bus_type)
{ {
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
if (!dev->ohci_devices[i]) { if (!dev->ohci_devices[i]) {
uint32_t old = dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * i)].l;
dev->ohci_devices[i] = device; dev->ohci_devices[i] = device;
dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * i)].b[0] |= 0x1; dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * i)].b[0] |= 0x1;
dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * i)].b[2] |= 0x1;
if ((dev->ohci_mmio[OHCI_HcControl].b[0] & 0xc0) == 0xc0) { if ((dev->ohci_mmio[OHCI_HcControl].b[0] & 0xc0) == 0xc0) {
ohci_set_interrupt(dev, OHCI_HcInterruptEnable_RD); ohci_set_interrupt(dev, OHCI_HcInterruptEnable_RD);
} }
ohci_set_interrupt(dev, OHCI_HcInterruptEnable_RHSC); if (old != dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * i)].l) {
dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * i)].b[2] |= 0x1;
ohci_set_interrupt(dev, OHCI_HcInterruptEnable_RHSC);
}
return i; return i;
} }
} }
@@ -968,23 +977,24 @@ usb_detach_device(usb_t *dev, uint8_t port, uint8_t bus_type)
switch (bus_type) { switch (bus_type) {
case USB_BUS_OHCI: case USB_BUS_OHCI:
{ {
for (int i = 0; i < 2; i++) { if (port > 2)
if (dev->ohci_devices[i]) { return;
uint32_t old = dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * i)].l; if (dev->ohci_devices[port]) {
dev->ohci_devices[i] = NULL; uint32_t old = dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * port)].l;
if (dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * i)].b[0] & 0x1) { dev->ohci_devices[port] = NULL;
dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * i)].b[0] &= ~0x1; if (dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * port)].b[0] & 0x1) {
dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * i)].b[2] |= 0x1; dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * port)].b[0] &= ~0x1;
} dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * port)].b[2] |= 0x1;
if (dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * i)].b[0] & 0x2) {
dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * i)].b[0] &= ~0x2;
dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * i)].b[2] |= 0x2;
}
if (old != dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * i)].l)
ohci_set_interrupt(dev, OHCI_HcInterruptEnable_RHSC);
return;
} }
if (dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * port)].b[0] & 0x2) {
dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * port)].b[0] &= ~0x2;
dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * port)].b[2] |= 0x2;
}
if (old != dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * port)].l)
ohci_set_interrupt(dev, OHCI_HcInterruptEnable_RHSC);
return;
} }
} }
break; break;
} }
@@ -1046,6 +1056,8 @@ usb_init_ext(const device_t *info, void *params)
usb_reset(dev); usb_reset(dev);
usb_device_inst = dev;
return dev; return dev;
} }