From 50b0fe499086fa36b85ecc214fa5332a7c109945 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 8 May 2023 22:30:28 +0600 Subject: [PATCH] usb: Add ability to attach and detach devices for real --- src/include/86box/usb.h | 1 + src/usb.c | 50 +++++++++++++++++++++++++---------------- 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/src/include/86box/usb.h b/src/include/86box/usb.h index b9497b92e..4dbec55c3 100644 --- a/src/include/86box/usb.h +++ b/src/include/86box/usb.h @@ -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); diff --git a/src/usb.c b/src/usb.c index 1dd6aa02c..2ef5bb895 100644 --- a/src/usb.c +++ b/src/usb.c @@ -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; }