1
0
mirror of https://github.com/gdsports/USBHost_t36 synced 2024-11-21 08:35:03 -05:00

Keep list of pipes to be deleted when device disconnects

This commit is contained in:
PaulStoffregen 2017-02-25 14:43:49 -08:00
parent 7f44715014
commit b4905f40ef
3 changed files with 40 additions and 7 deletions

View File

@ -61,6 +61,7 @@ typedef union {
// Device_t holds all the information about a USB device
struct Device_struct {
Pipe_t *control_pipe;
Pipe_t *data_pipes;
Device_t *next;
USBDriver *drivers;
uint8_t speed; // 0=12, 1=1.5, 2=480 Mbit/sec
@ -95,7 +96,7 @@ struct Pipe_struct {
uint8_t type; // 0=control, 1=isochronous, 2=bulk, 3=interrupt
uint8_t direction; // 0=out, 1=in (changes for control, others fixed)
uint8_t unusedbyte[2];
USBDriver *callback_object;
Pipe_t *next;
void (*callback_function)(const Transfer_t *);
};
@ -155,6 +156,7 @@ private:
static bool queue_Transfer(Pipe_t *pipe, Transfer_t *transfer);
static void init_Device_Pipe_Transfer_memory(void);
static Device_t * allocate_Device(void);
static void delete_Pipe(Pipe_t *pipe);
static void free_Device(Device_t *q);
static Pipe_t * allocate_Pipe(void);
static void free_Pipe(Pipe_t *q);
@ -236,7 +238,11 @@ protected:
virtual void control(const Transfer_t *transfer) { }
// When a device disconnects from the USB, this function is called.
// The driver must free all resources it has allocated.
// The driver must free all resources it allocated and update any
// internal state necessary to deal with the possibility of user
// code continuing to call its API. However, pipes and transfers
// are the handled by lower layers, so device drivers do not free
// pipes they created or cancel transfers they had in progress.
virtual void disconnect();
// Drivers are managed by this single-linked list. All inactive

View File

@ -372,6 +372,16 @@ Pipe_t * USBHost::new_Pipe(Device_t *dev, uint32_t type, uint32_t endpoint,
}
}
memset(pipe, 0, sizeof(Pipe_t));
if (endpoint > 0) {
// if non-control pipe, update dev->data_pipes list
Pipe_t *p = dev->data_pipes;
if (p == NULL) {
dev->data_pipes = pipe;
} else {
while (p->next) p = p->next;
p->next = pipe;
}
}
memset(halt, 0, sizeof(Transfer_t));
halt->qtd.next = 1;
halt->qtd.token = 0x40;
@ -825,3 +835,18 @@ bool USBHost::allocate_interrupt_pipe_bandwidth(uint32_t speed, uint32_t maxlen,
return true;
}
void USBHost::delete_Pipe(Pipe_t *pipe)
{
// TODO: a *LOT* of work here.....
println("delete_Pipe ", (uint32_t)pipe, HEX);
// halt pipe, find and free all Transfer_t
// remove periodic scheduled pipes
// remove async scheduled pipes
// can't free the pipe until the ECHI and all qTD referencing are done
// free_Pipe(pipe);
}

View File

@ -361,11 +361,13 @@ void USBHost::disconnect_Device(Device_t *dev)
}
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
// delete all the pipes
for (Pipe_t *p = dev->data_pipes; p; ) {
Pipe_t *next = p->next;
delete_Pipe(p);
p = next;
}
delete_Pipe(dev->control_pipe);
// remove device from devlist and free its Device_t
Device_t *prev_dev = NULL;