Browse Source

Disconnect drivers and free device when cable unplugged

main
PaulStoffregen 7 years ago
parent
commit
08ed25eb49
4 changed files with 76 additions and 6 deletions
  1. +2
    -0
      USBHost.h
  2. +2
    -2
      ehci.cpp
  3. +51
    -4
      enumeration.cpp
  4. +21
    -0
      print.cpp

+ 2
- 0
USBHost.h View File

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:
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); }

+ 2
- 2
ehci.cpp View File

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) {
return true; return true;
} }




+ 51
- 4
enumeration.cpp View File

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);
// 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;
} }


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)
//{
// return pipe->qh.capabilities[0] & 0xFFFFFF80;
//}

void USBHost::disconnect_Device(Device_t *dev)
{
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
- 0
print.cpp View File

//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…
Cancel
Save