Przeglądaj źródła

[usb] Add functions for manual device address assignment

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 9 lat temu
rodzic
commit
838ab97ce3
2 zmienionych plików z 70 dodań i 0 usunięć
  1. 44
    0
      src/drivers/bus/usb.c
  2. 26
    0
      src/include/ipxe/usb.h

+ 44
- 0
src/drivers/bus/usb.c Wyświetl plik

26
 #include <stdlib.h>
26
 #include <stdlib.h>
27
 #include <stdio.h>
27
 #include <stdio.h>
28
 #include <string.h>
28
 #include <string.h>
29
+#include <strings.h>
29
 #include <unistd.h>
30
 #include <unistd.h>
30
 #include <errno.h>
31
 #include <errno.h>
31
 #include <assert.h>
32
 #include <assert.h>
1849
 	free ( bus );
1850
 	free ( bus );
1850
 }
1851
 }
1851
 
1852
 
1853
+/******************************************************************************
1854
+ *
1855
+ * USB address assignment
1856
+ *
1857
+ ******************************************************************************
1858
+ */
1859
+
1860
+/**
1861
+ * Allocate device address
1862
+ *
1863
+ * @v bus		USB bus
1864
+ * @ret address		Device address, or negative error
1865
+ */
1866
+int usb_alloc_address ( struct usb_bus *bus ) {
1867
+	unsigned int address;
1868
+
1869
+	/* Find first free device address */
1870
+	address = ffsll ( ~bus->addresses );
1871
+	if ( ! address )
1872
+		return -ENOENT;
1873
+
1874
+	/* Mark address as used */
1875
+	bus->addresses |= ( 1ULL << ( address - 1 ) );
1876
+
1877
+	return address;
1878
+}
1879
+
1880
+/**
1881
+ * Free device address
1882
+ *
1883
+ * @v bus		USB bus
1884
+ * @v address		Device address
1885
+ */
1886
+void usb_free_address ( struct usb_bus *bus, unsigned int address ) {
1887
+
1888
+	/* Sanity check */
1889
+	assert ( address > 0 );
1890
+	assert ( bus->addresses & ( 1ULL << ( address - 1 ) ) );
1891
+
1892
+	/* Mark address as free */
1893
+	bus->addresses &= ~( 1ULL << ( address - 1 ) );
1894
+}
1895
+
1852
 /******************************************************************************
1896
 /******************************************************************************
1853
  *
1897
  *
1854
  * USB bus topology
1898
  * USB bus topology

+ 26
- 0
src/include/ipxe/usb.h Wyświetl plik

867
 
867
 
868
 	/** Largest transfer allowed on the bus */
868
 	/** Largest transfer allowed on the bus */
869
 	size_t mtu;
869
 	size_t mtu;
870
+	/** Address in-use mask
871
+	 *
872
+	 * This is used only by buses which perform manual address
873
+	 * assignment.  USB allows for addresses in the range [1,127].
874
+	 * We use a simple bitmask which restricts us to the range
875
+	 * [1,64]; this is unlikely to be a problem in practice.  For
876
+	 * comparison: controllers which perform autonomous address
877
+	 * assignment (such as xHCI) typically allow for only 32
878
+	 * devices per bus anyway.
879
+	 */
880
+	unsigned long long addresses;
870
 
881
 
871
 	/** Root hub */
882
 	/** Root hub */
872
 	struct usb_hub *hub;
883
 	struct usb_hub *hub;
1021
 			     feature, index, NULL, 0 );
1032
 			     feature, index, NULL, 0 );
1022
 }
1033
 }
1023
 
1034
 
1035
+/**
1036
+ * Set address
1037
+ *
1038
+ * @v usb		USB device
1039
+ * @v address		Device address
1040
+ * @ret rc		Return status code
1041
+ */
1042
+static inline __attribute__ (( always_inline )) int
1043
+usb_set_address ( struct usb_device *usb, unsigned int address ) {
1044
+
1045
+	return usb_control ( usb, USB_SET_ADDRESS, address, 0, NULL, 0 );
1046
+}
1047
+
1024
 /**
1048
 /**
1025
  * Get USB descriptor
1049
  * Get USB descriptor
1026
  *
1050
  *
1148
 extern void unregister_usb_bus ( struct usb_bus *bus );
1172
 extern void unregister_usb_bus ( struct usb_bus *bus );
1149
 extern void free_usb_bus ( struct usb_bus *bus );
1173
 extern void free_usb_bus ( struct usb_bus *bus );
1150
 
1174
 
1175
+extern int usb_alloc_address ( struct usb_bus *bus );
1176
+extern void usb_free_address ( struct usb_bus *bus, unsigned int address );
1151
 extern unsigned int usb_route_string ( struct usb_device *usb );
1177
 extern unsigned int usb_route_string ( struct usb_device *usb );
1152
 extern unsigned int usb_depth ( struct usb_device *usb );
1178
 extern unsigned int usb_depth ( struct usb_device *usb );
1153
 extern struct usb_port * usb_root_hub_port ( struct usb_device *usb );
1179
 extern struct usb_port * usb_root_hub_port ( struct usb_device *usb );

Ładowanie…
Anuluj
Zapisz