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. */
extern const device_t usb_device;
extern usb_t* usb_device_inst;
/* Functions. */
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
};
usb_t* usb_device_inst = NULL;
static void
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)
dev->ohci_mmio[addr >> 2].b[addr & 3] &= ~0x04;
if (val & 0x04)
dev->ohci_mmio[addr >> 2].b[addr & 3] |= 0x04;
if (val & 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 (old & 0x01)
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++) {
if (!dev->ohci_devices[i]) {
uint32_t old = dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * i)].l;
dev->ohci_devices[i] = device;
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) {
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;
}
}
@@ -968,23 +977,24 @@ usb_detach_device(usb_t *dev, uint8_t port, uint8_t bus_type)
switch (bus_type) {
case USB_BUS_OHCI:
{
for (int i = 0; i < 2; i++) {
if (dev->ohci_devices[i]) {
uint32_t old = dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * i)].l;
dev->ohci_devices[i] = NULL;
if (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_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 (port > 2)
return;
if (dev->ohci_devices[port]) {
uint32_t old = dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * port)].l;
dev->ohci_devices[port] = NULL;
if (dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * port)].b[0] & 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 * 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;
}
@@ -1046,6 +1056,8 @@ usb_init_ext(const device_t *info, void *params)
usb_reset(dev);
usb_device_inst = dev;
return dev;
}