usb: Add ability to attach and detach devices for real
This commit is contained in:
@@ -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);
|
||||||
|
50
src/usb.c
50
src/usb.c
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user