summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brown2020-10-12 16:28:26 +0200
committerMichael Brown2020-10-12 16:28:26 +0200
commite30c26d01c7493a7e02e77fc80c490fc85612d5a (patch)
tree1a6f62f48209d3eb16c8da00345df8431bc81a34
parent[usb] Allow device halt to be cleared independently of host controller (diff)
downloadipxe-e30c26d01c7493a7e02e77fc80c490fc85612d5a.tar.gz
ipxe-e30c26d01c7493a7e02e77fc80c490fc85612d5a.tar.xz
ipxe-e30c26d01c7493a7e02e77fc80c490fc85612d5a.zip
[usb] Allow endpoints to be refilled to a specified upper limit
For USB mass storage devices, we do not want to submit more bulk IN packets than are required for the inbound data, since this will waste memory. Allow an upper limit to be specified on each refill attempt. The endpoint will be refilled to the lower of this limit or the limit specified by usb_refill_init(). Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r--src/drivers/bus/usb.c19
-rw-r--r--src/include/ipxe/usb.h1
2 files changed, 17 insertions, 3 deletions
diff --git a/src/drivers/bus/usb.c b/src/drivers/bus/usb.c
index 88df9c64a..70a86c913 100644
--- a/src/drivers/bus/usb.c
+++ b/src/drivers/bus/usb.c
@@ -651,12 +651,13 @@ int usb_prefill ( struct usb_endpoint *ep ) {
}
/**
- * Refill endpoint
+ * Refill endpoint up to specified limit
*
* @v ep USB endpoint
+ * @v max Fill limit
* @ret rc Return status code
*/
-int usb_refill ( struct usb_endpoint *ep ) {
+int usb_refill_limit ( struct usb_endpoint *ep, unsigned int max ) {
struct io_buffer *iobuf;
size_t reserve = ep->reserve;
size_t len = ( ep->len ? ep->len : ep->mtu );
@@ -667,7 +668,9 @@ int usb_refill ( struct usb_endpoint *ep ) {
assert ( ep->max > 0 );
/* Refill endpoint */
- while ( ep->fill < ep->max ) {
+ if ( max > ep->max )
+ max = ep->max;
+ while ( ep->fill < max ) {
/* Get or allocate buffer */
if ( list_empty ( &ep->recycled ) ) {
@@ -699,6 +702,16 @@ int usb_refill ( struct usb_endpoint *ep ) {
}
/**
+ * Refill endpoint
+ *
+ * @v ep USB endpoint
+ * @ret rc Return status code
+ */
+int usb_refill ( struct usb_endpoint *ep ) {
+ return usb_refill_limit ( ep, ep->max );
+}
+
+/**
* Discard endpoint recycled buffer list
*
* @v ep USB endpoint
diff --git a/src/include/ipxe/usb.h b/src/include/ipxe/usb.h
index a05ac613c..70d6daf33 100644
--- a/src/include/ipxe/usb.h
+++ b/src/include/ipxe/usb.h
@@ -621,6 +621,7 @@ usb_recycle ( struct usb_endpoint *ep, struct io_buffer *iobuf ) {
}
extern int usb_prefill ( struct usb_endpoint *ep );
+extern int usb_refill_limit ( struct usb_endpoint *ep, unsigned int max );
extern int usb_refill ( struct usb_endpoint *ep );
extern void usb_flush ( struct usb_endpoint *ep );