mirror of
https://github.com/gdsports/USBHost_t36
synced 2024-11-22 00:52:19 -05:00
Disconnect drivers and free device when cable unplugged
This commit is contained in:
parent
af4e4599f4
commit
08ed25eb49
@ -145,6 +145,7 @@ protected:
|
|||||||
static bool queue_Data_Transfer(Pipe_t *pipe, void *buffer,
|
static bool queue_Data_Transfer(Pipe_t *pipe, void *buffer,
|
||||||
uint32_t len, USBDriver *driver);
|
uint32_t len, USBDriver *driver);
|
||||||
static Device_t * new_Device(uint32_t speed, uint32_t hub_addr, uint32_t hub_port);
|
static Device_t * new_Device(uint32_t speed, uint32_t hub_addr, uint32_t hub_port);
|
||||||
|
static void disconnect_Device(Device_t *dev);
|
||||||
static void enumeration(const Transfer_t *transfer);
|
static void enumeration(const Transfer_t *transfer);
|
||||||
static void driver_ready_for_device(USBDriver *driver);
|
static void driver_ready_for_device(USBDriver *driver);
|
||||||
private:
|
private:
|
||||||
@ -166,6 +167,7 @@ protected:
|
|||||||
static void print(const Transfer_t *first, const Transfer_t *last);
|
static void print(const Transfer_t *first, const Transfer_t *last);
|
||||||
static void print_token(uint32_t token);
|
static void print_token(uint32_t token);
|
||||||
static void print(const Pipe_t *pipe);
|
static void print(const Pipe_t *pipe);
|
||||||
|
static void print_driverlist(const char *name, const USBDriver *driver);
|
||||||
static void print_hexbytes(const void *ptr, uint32_t len);
|
static void print_hexbytes(const void *ptr, uint32_t len);
|
||||||
static void print(const char *s) { Serial.print(s); }
|
static void print(const char *s) { Serial.print(s); }
|
||||||
static void print(int n) { Serial.print(n); }
|
static void print(int n) { Serial.print(n); }
|
||||||
|
4
ehci.cpp
4
ehci.cpp
@ -275,7 +275,8 @@ void USBHost::isr()
|
|||||||
println(" disconnect");
|
println(" disconnect");
|
||||||
port_state = PORT_STATE_DISCONNECTED;
|
port_state = PORT_STATE_DISCONNECTED;
|
||||||
USBPHY_CTRL_CLR = USBPHY_CTRL_ENHOSTDISCONDETECT;
|
USBPHY_CTRL_CLR = USBPHY_CTRL_ENHOSTDISCONDETECT;
|
||||||
// TODO: delete & clean up device state...
|
disconnect_Device(rootdev);
|
||||||
|
rootdev = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (portstat & USBHS_PORTSC_PEC) {
|
if (portstat & USBHS_PORTSC_PEC) {
|
||||||
@ -824,4 +825,3 @@ bool USBHost::allocate_interrupt_pipe_bandwidth(uint32_t speed, uint32_t maxlen,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ static USBDriver *available_drivers = NULL;
|
|||||||
static uint8_t enumbuf[256] __attribute__ ((aligned(16)));
|
static uint8_t enumbuf[256] __attribute__ ((aligned(16)));
|
||||||
static setup_t enumsetup __attribute__ ((aligned(16)));
|
static setup_t enumsetup __attribute__ ((aligned(16)));
|
||||||
static uint16_t enumlen;
|
static uint16_t enumlen;
|
||||||
|
static Device_t *devlist=NULL;
|
||||||
|
|
||||||
|
|
||||||
static uint32_t assign_addr(void);
|
static uint32_t assign_addr(void);
|
||||||
@ -84,6 +85,13 @@ Device_t * USBHost::new_Device(uint32_t speed, uint32_t hub_addr, uint32_t hub_p
|
|||||||
// go onto a waiting list
|
// go onto a waiting list
|
||||||
mk_setup(enumsetup, 0x80, 6, 0x0100, 0, 8); // 6=GET_DESCRIPTOR
|
mk_setup(enumsetup, 0x80, 6, 0x0100, 0, 8); // 6=GET_DESCRIPTOR
|
||||||
queue_Control_Transfer(dev, &enumsetup, enumbuf, NULL);
|
queue_Control_Transfer(dev, &enumsetup, enumbuf, NULL);
|
||||||
|
if (devlist == NULL) {
|
||||||
|
devlist = dev;
|
||||||
|
} else {
|
||||||
|
Device_t *p;
|
||||||
|
for (p = devlist; p->next; p = p->next) ; // walk devlist
|
||||||
|
p->next = dev;
|
||||||
|
}
|
||||||
return dev;
|
return dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,9 +325,48 @@ static void pipe_set_addr(Pipe_t *pipe, uint32_t addr)
|
|||||||
pipe->qh.capabilities[0] = (pipe->qh.capabilities[0] & 0xFFFFFF80) | addr;
|
pipe->qh.capabilities[0] = (pipe->qh.capabilities[0] & 0xFFFFFF80) | addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
//static uint32_t pipe_get_addr(Pipe_t *pipe)
|
|
||||||
//{
|
void USBHost::disconnect_Device(Device_t *dev)
|
||||||
// return pipe->qh.capabilities[0] & 0xFFFFFF80;
|
{
|
||||||
//}
|
if (!dev) return;
|
||||||
|
println("disconnect_Device:");
|
||||||
|
|
||||||
|
// Disconnect all drivers using this device. If this device is
|
||||||
|
// a hub, the hub driver is responsible for recursively calling
|
||||||
|
// this function to disconnect its downstream devices.
|
||||||
|
print_driverlist("available_drivers", available_drivers);
|
||||||
|
print_driverlist("dev->drivers", dev->drivers);
|
||||||
|
for (USBDriver *p = dev->drivers; p; ) {
|
||||||
|
println("disconnect driver ", (uint32_t)p, HEX);
|
||||||
|
p->disconnect();
|
||||||
|
USBDriver *next = p->next;
|
||||||
|
p->next = available_drivers;
|
||||||
|
available_drivers = p;
|
||||||
|
p = next;
|
||||||
|
}
|
||||||
|
print_driverlist("available_drivers", available_drivers);
|
||||||
|
|
||||||
|
// TODO: halt all pipes, free their Transfer_t
|
||||||
|
|
||||||
|
// TODO: remove periodic scheduled pipes, free their Pipe_t
|
||||||
|
|
||||||
|
// TODO: remove async scheduled pipes, free their Pipe_t
|
||||||
|
|
||||||
|
// remove device from devlist and free its Device_t
|
||||||
|
Device_t *prev_dev = NULL;
|
||||||
|
for (Device_t *p = devlist; p; p = p->next) {
|
||||||
|
if (p == dev) {
|
||||||
|
if (prev_dev == NULL) {
|
||||||
|
devlist = p->next;
|
||||||
|
} else {
|
||||||
|
prev_dev->next = p->next;
|
||||||
|
}
|
||||||
|
println("removed Device_t from devlist");
|
||||||
|
free_Device(p);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
prev_dev = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
21
print.cpp
21
print.cpp
@ -125,6 +125,27 @@ void USBHost::print(const Pipe_t *pipe)
|
|||||||
//Serial.print();
|
//Serial.print();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void USBHost::print_driverlist(const char *name, const USBDriver *driver)
|
||||||
|
{
|
||||||
|
Serial.print("USBDriver (");
|
||||||
|
Serial.print(name);
|
||||||
|
Serial.print(") list: ");
|
||||||
|
if (driver == NULL) {
|
||||||
|
Serial.println("(empty");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uint32_t count=0;
|
||||||
|
for (const USBDriver *p = driver; p; p = p->next) {
|
||||||
|
Serial.print((uint32_t)p, HEX);
|
||||||
|
if (p->next) Serial.print(" -> ");
|
||||||
|
if (++count > 30) {
|
||||||
|
Serial.println("abort:list too long");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void USBHost::print_hexbytes(const void *ptr, uint32_t len)
|
void USBHost::print_hexbytes(const void *ptr, uint32_t len)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user