summaryrefslogtreecommitdiffstats
path: root/src/drivers/bus
diff options
context:
space:
mode:
authorMichael Brown2015-03-16 16:37:39 +0100
committerMichael Brown2015-03-16 16:42:29 +0100
commit838ab97ce3bda9db0b6d5beb98f8c5bc16582be9 (patch)
tree0ce8b7eb9f24f1b6fb66fc74dbd7facdce028eba /src/drivers/bus
parent[ncm] Respect maximum transfer size of the bus (diff)
downloadipxe-838ab97ce3bda9db0b6d5beb98f8c5bc16582be9.tar.gz
ipxe-838ab97ce3bda9db0b6d5beb98f8c5bc16582be9.tar.xz
ipxe-838ab97ce3bda9db0b6d5beb98f8c5bc16582be9.zip
[usb] Add functions for manual device address assignment
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/drivers/bus')
-rw-r--r--src/drivers/bus/usb.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/src/drivers/bus/usb.c b/src/drivers/bus/usb.c
index 57a25332..548aa7b0 100644
--- a/src/drivers/bus/usb.c
+++ b/src/drivers/bus/usb.c
@@ -26,6 +26,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <strings.h>
#include <unistd.h>
#include <errno.h>
#include <assert.h>
@@ -1851,6 +1852,49 @@ void free_usb_bus ( struct usb_bus *bus ) {
/******************************************************************************
*
+ * USB address assignment
+ *
+ ******************************************************************************
+ */
+
+/**
+ * Allocate device address
+ *
+ * @v bus USB bus
+ * @ret address Device address, or negative error
+ */
+int usb_alloc_address ( struct usb_bus *bus ) {
+ unsigned int address;
+
+ /* Find first free device address */
+ address = ffsll ( ~bus->addresses );
+ if ( ! address )
+ return -ENOENT;
+
+ /* Mark address as used */
+ bus->addresses |= ( 1ULL << ( address - 1 ) );
+
+ return address;
+}
+
+/**
+ * Free device address
+ *
+ * @v bus USB bus
+ * @v address Device address
+ */
+void usb_free_address ( struct usb_bus *bus, unsigned int address ) {
+
+ /* Sanity check */
+ assert ( address > 0 );
+ assert ( bus->addresses & ( 1ULL << ( address - 1 ) ) );
+
+ /* Mark address as free */
+ bus->addresses &= ~( 1ULL << ( address - 1 ) );
+}
+
+/******************************************************************************
+ *
* USB bus topology
*
******************************************************************************