Clean up bandwidth usage info when deleting a pipe

This commit is contained in:
PaulStoffregen 2017-12-19 15:31:08 -08:00
parent 713bfb1513
commit 133d082760
3 changed files with 69 additions and 4 deletions

View File

@ -211,13 +211,16 @@ struct Pipe_struct {
void (*callback_function)(const Transfer_t *);
uint16_t periodic_interval;
uint16_t periodic_offset;
uint16_t bandwidth_interval;
uint16_t bandwidth_offset;
uint16_t bandwidth_shift;
uint8_t bandwidth_stime;
uint8_t bandwidth_ctime;
uint32_t unused1;
uint32_t unused2;
uint32_t unused3;
uint32_t unused4;
uint32_t unused5;
uint32_t unused6;
uint32_t unused7;
};
// Transfer_t represents a single transaction on the USB bus.
@ -259,6 +262,7 @@ class USBHost {
public:
static void begin();
static void Task();
static void countFree(uint32_t &devices, uint32_t &pipes, uint32_t &trans, uint32_t &strs);
protected:
static Pipe_t * new_Pipe(Device_t *dev, uint32_t type, uint32_t endpoint,
uint32_t direction, uint32_t maxlen, uint32_t interval=0);

View File

@ -1045,6 +1045,10 @@ bool USBHost::allocate_interrupt_pipe_bandwidth(Pipe_t *pipe, uint32_t maxlen, u
// a 125 us micro frame can fit 7500 bytes, or 234 of our 32-byte units
// fail if the best found needs more than 80% (234 * 0.8) in any uframe
if (best_bandwidth > 187) return false;
// save essential bandwidth specs, for cleanup in delete_Pipe
pipe->bandwidth_interval = interval;
pipe->bandwidth_offset = best_offset;
pipe->bandwidth_stime = stime;
for (uint32_t i=best_offset; i < PERIODIC_LIST_SIZE*8; i += interval) {
uframe_bandwidth[i] += stime;
}
@ -1113,6 +1117,12 @@ bool USBHost::allocate_interrupt_pipe_bandwidth(Pipe_t *pipe, uint32_t maxlen, u
// a 125 us micro frame can fit 7500 bytes, or 234 of our 32-byte units
// fail if the best found needs more than 80% (234 * 0.8) in any uframe
if (best_bandwidth > 187) return false;
// save essential bandwidth specs, for cleanup in delete_Pipe
pipe->bandwidth_interval = interval;
pipe->bandwidth_offset = best_offset;
pipe->bandwidth_shift = best_shift;
pipe->bandwidth_stime = stime;
pipe->bandwidth_ctime = ctime;
for (uint32_t i=best_offset; i < PERIODIC_LIST_SIZE; i += interval) {
uint32_t n = (i << 3) + best_shift;
uframe_bandwidth[n+0] += stime;
@ -1299,7 +1309,28 @@ void USBHost::delete_Pipe(Pipe_t *pipe)
prev = node;
}
}
// TODO: subtract bandwidth from uframe_bandwidth array
// subtract bandwidth from uframe_bandwidth array
if (pipe->device->speed == 2) {
uint32_t interval = pipe->bandwidth_interval;
uint32_t offset = pipe->bandwidth_offset;
uint32_t stime = pipe->bandwidth_stime;
for (uint32_t i=offset; i < PERIODIC_LIST_SIZE*8; i += interval) {
uframe_bandwidth[i] -= stime;
}
} else {
uint32_t interval = pipe->bandwidth_interval;
uint32_t offset = pipe->bandwidth_offset;
uint32_t shift = pipe->bandwidth_shift;
uint32_t stime = pipe->bandwidth_stime;
uint32_t ctime = pipe->bandwidth_ctime;
for (uint32_t i=offset; i < PERIODIC_LIST_SIZE; i += interval) {
uint32_t n = (i << 3) + shift;
uframe_bandwidth[n+0] -= stime;
uframe_bandwidth[n+2] -= ctime;
uframe_bandwidth[n+3] -= ctime;
uframe_bandwidth[n+4] -= ctime;
}
}
// find & free all the transfers which completed
println(" Free transfers");

View File

@ -159,4 +159,34 @@ void USBHost::contribute_String_Buffers(strbuf_t *strbufs, uint32_t num)
}
}
// for debugging, hopefully never needed...
void USBHost::countFree(uint32_t &devices, uint32_t &pipes, uint32_t &transfers, uint32_t &strs)
{
uint32_t ndev=0, npipe=0, ntransfer=0, nstr=0;
__disable_irq();
Device_t *dev = free_Device_list;
while (dev) {
ndev++;
dev = *(Device_t **)dev;
}
Pipe_t *pipe = free_Pipe_list;
while (pipe) {
npipe++;
pipe = *(Pipe_t **)pipe;
}
Transfer_t *transfer = free_Transfer_list;
while (transfer) {
ntransfer++;
transfer = *(Transfer_t **)transfer;
}
strbuf_t *str = free_strbuf_list;
while (str) {
nstr++;
str = *(strbuf_t **)str;
}
__enable_irq();
devices = ndev;
pipes = npipe;
transfers = ntransfer;
strs = nstr;
}