Changeset 84439d7 in mainline for uspace/lib/usb
- Timestamp:
- 2010-12-05T09:34:46Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 75732da
- Parents:
- 56b962d (diff), 35537a7 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - Location:
- uspace/lib/usb
- Files:
-
- 3 added
- 7 edited
-
Makefile (modified) (1 diff)
-
include/usb/classes/hub.h (modified) (2 diffs)
-
include/usb/hcdhubd.h (modified) (6 diffs)
-
include/usb/usbdrv.h (modified) (2 diffs)
-
src/hcdhubd.c (modified) (5 diffs)
-
src/hcdhubd_private.h (added)
-
src/hcdrv.c (added)
-
src/localdrv.c (modified) (1 diff)
-
src/remotedrv.c (added)
-
src/usbdrv.c (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usb/Makefile
r56b962d r84439d7 34 34 SOURCES = \ 35 35 src/hcdhubd.c \ 36 src/hcdrv.c \ 36 37 src/localdrv.c \ 38 src/remotedrv.c \ 37 39 src/usb.c \ 38 40 src/usbdrv.c -
uspace/lib/usb/include/usb/classes/hub.h
r56b962d r84439d7 36 36 #define LIBUSB_HUB_H_ 37 37 38 /** Hub class request. */ 39 typedef enum { 40 USB_HUB_REQUEST_GET_STATUS = 0, 41 USB_HUB_REQUEST_CLEAR_FEATURE = 1, 42 USB_HUB_REQUEST_GET_STATE = 2, 43 USB_HUB_REQUEST_SET_FEATURE = 3, 44 USB_HUB_REQUEST_GET_DESCRIPTOR = 6, 45 USB_HUB_REQUEST_SET_DESCRIPTOR = 7, 46 /* USB_HUB_REQUEST_ = , */ 47 } usb_hub_class_request_t; 38 #include <sys/types.h> 39 #include <usb/hcdhubd.h> 40 48 41 49 42 /** Hub class feature selector. … … 69 62 } usb_hub_class_feature_t; 70 63 64 65 /** 66 * @brief usb hub descriptor 67 * 68 * For more information see Universal Serial Bus Specification Revision 1.1 chapter 11.16.2 69 */ 70 typedef struct hub_descriptor_type{ 71 /** Number of bytes in this descriptor, including this byte */ 72 //uint8_t bDescLength; 73 74 /** Descriptor Type, value: 29H for hub descriptor */ 75 //uint8_t bDescriptorType; 76 77 /** Number of downstream ports that this hub supports */ 78 uint8_t ports_count; 79 80 /** 81 D1...D0: Logical Power Switching Mode 82 00: Ganged power switching (all ports’ power at 83 once) 84 01: Individual port power switching 85 1X: Reserved. Used only on 1.0 compliant hubs 86 that implement no power switching. 87 D2: Identifies a Compound Device 88 0: Hub is not part of a compound device 89 1: Hub is part of a compound device 90 D4...D3: Over-current Protection Mode 91 00: Global Over-current Protection. The hub 92 reports over-current as a summation of all 93 ports’ current draw, without a breakdown of 94 individual port over-current status. 95 01: Individual Port Over-current Protection. The 96 hub reports over-current on a per-port basis. 97 Each port has an over-current indicator. 98 1X: No Over-current Protection. This option is 99 allowed only for bus-powered hubs that do not 100 implement over-current protection. 101 D15...D5: 102 Reserved 103 */ 104 uint16_t hub_characteristics; 105 106 /** 107 Time (in 2ms intervals) from the time the power-on 108 sequence begins on a port until power is good on that 109 port. The USB System Software uses this value to 110 determine how long to wait before accessing a 111 powered-on port. 112 */ 113 uint8_t pwr_on_2_good_time; 114 115 /** 116 Maximum current requirements of the Hub Controller 117 electronics in mA. 118 */ 119 uint8_t current_requirement; 120 121 /** 122 Indicates if a port has a removable device attached. 123 This field is reported on byte-granularity. Within a 124 byte, if no port exists for a given location, the field 125 representing the port characteristics returns 0. 126 Bit value definition: 127 0B - Device is removable 128 1B - Device is non-removable 129 This is a bitmap corresponding to the individual ports 130 on the hub: 131 Bit 0: Reserved for future use 132 Bit 1: Port 1 133 Bit 2: Port 2 134 .... 135 Bit n: Port n (implementation-dependent, up to a 136 maximum of 255 ports). 137 */ 138 uint8_t * devices_removable; 139 140 /** 141 This field exists for reasons of compatibility with 142 software written for 1.0 compliant devices. All bits in 143 this field should be set to 1B. This field has one bit for 144 each port on the hub with additional pad bits, if 145 necessary, to make the number of bits in the field an 146 integer multiple of 8. 147 */ 148 //uint8_t * port_pwr_ctrl_mask; 149 } usb_hub_descriptor_t; 150 151 152 153 /** @brief usb hub specific request types. 154 * 155 * For more information see Universal Serial Bus Specification Revision 1.1 chapter 11.16.2 156 */ 157 typedef enum { 158 /** This request resets a value reported in the hub status. */ 159 USB_HUB_REQ_TYPE_CLEAR_HUB_FEATURE = 0x20, 160 /** This request resets a value reported in the port status. */ 161 USB_HUB_REQ_TYPE_CLEAR_PORT_FEATURE = 0x23, 162 /** This is an optional per-port diagnostic request that returns the bus state value, as sampled at the last EOF2 point. */ 163 USB_HUB_REQ_TYPE_GET_STATE = 0xA3, 164 /** This request returns the hub descriptor. */ 165 USB_HUB_REQ_TYPE_GET_DESCRIPTOR = 0xA0, 166 /** This request returns the current hub status and the states that have changed since the previous acknowledgment. */ 167 USB_HUB_REQ_TYPE_GET_HUB_STATUS = 0xA0, 168 /** This request returns the current port status and the current value of the port status change bits. */ 169 USB_HUB_REQ_TYPE_GET_PORT_STATUS = 0xA3, 170 /** This request overwrites the hub descriptor. */ 171 USB_HUB_REQ_TYPE_SET_DESCRIPTOR = 0x20, 172 /** This request sets a value reported in the hub status. */ 173 USB_HUB_REQ_TYPE_SET_HUB_FEATURE = 0x20, 174 /** This request sets a value reported in the port status. */ 175 USB_HUB_REQ_TYPE_SET_PORT_FEATURE = 0x23 176 } usb_hub_bm_request_type_t; 177 178 /** @brief hub class request codes*/ 179 typedef enum { 180 /** */ 181 USB_HUB_REQUEST_GET_STATUS = 0, 182 /** */ 183 USB_HUB_REQUEST_CLEAR_FEATURE = 1, 184 /** */ 185 USB_HUB_REQUEST_GET_STATE = 2, 186 /** */ 187 USB_HUB_REQUEST_SET_FEATURE = 3, 188 /** */ 189 USB_HUB_REQUEST_GET_DESCRIPTOR = 6, 190 /** */ 191 USB_HUB_REQUEST_SET_DESCRIPTOR = 7 192 } usb_hub_request_t; 193 194 /** 195 * Maximum size of usb hub descriptor in bytes 196 */ 197 extern size_t USB_HUB_MAX_DESCRIPTOR_SIZE; 198 199 /** 200 * @brief create uint8_t array with serialized descriptor 201 * 202 * @param descriptor 203 */ 204 void * usb_serialize_hub_descriptor(usb_hub_descriptor_t * descriptor); 205 206 /** 207 * @brief create deserialized desriptor structure out of serialized descriptor 208 * 209 * The serialized descriptor must be proper usb hub descriptor, otherwise an eerror might occur. 210 * 211 * @param sdescriptor serialized descriptor 212 */ 213 usb_hub_descriptor_t * usb_deserialize_hub_desriptor(void * sdescriptor); 214 215 /** 216 * @brief create hub structure instance 217 * 218 * @param device 219 * @return 220 */ 221 usb_hcd_hub_info_t * usb_create_hub_info(device_t * device); 222 223 224 225 226 71 227 #endif 72 228 /** -
uspace/lib/usb/include/usb/hcdhubd.h
r56b962d r84439d7 37 37 38 38 #include <adt/list.h> 39 #include <bool.h> 39 40 #include <driver.h> 40 41 #include <usb/usb.h> … … 115 116 } usb_hcd_transfer_ops_t; 116 117 118 /** 119 * @brief structure holding information about free and used addresses 120 * 121 * This structure should not be used outside usb hcd driver. 122 * You better consider it to be 'private'. 123 */ 124 typedef struct { 125 /** lower bound included in the interval */ 126 usb_address_t lower_bound; 127 128 /** upper bound, excluded from the interval */ 129 usb_address_t upper_bound; 130 131 /** */ 132 link_t link; 133 }usb_address_list_t; 134 117 135 struct usb_hc_device { 118 136 /** Transfer operations. */ … … 130 148 /** List of hubs operating from this HC. */ 131 149 link_t hubs; 150 151 /** Structure with free and used addresses */ 152 link_t addresses; 132 153 133 154 /** Link to other driven HCs. */ … … 145 166 146 167 int usb_hcd_main(usb_hc_driver_t *); 147 int usb_hcd_add_root_hub(usb_hc_device_t *dev); 168 int usb_hcd_add_root_hub(device_t *dev); 169 170 /** 171 * find first not yet used address on this host controller and use it 172 * @param this_hcd 173 * @return number in the range of allowed usb addresses or 174 * a negative number if not succesful 175 */ 176 usb_address_t usb_use_free_address(usb_hc_device_t * this_hcd); 177 178 /** 179 * @brief free the address in the address space of this hcd. 180 * 181 * if address is not used, nothing happens 182 * @param this_hcd 183 * @param addr 184 */ 185 void usb_free_used_address(usb_hc_device_t * this_hcd, usb_address_t addr ); 148 186 149 187 … … 153 191 */ 154 192 193 device_t *usb_hc_connect(device_t *); 155 194 156 195 int usb_hc_async_interrupt_out(usb_hc_device_t *, usb_target_t, … … 175 214 int usb_hc_async_wait_for(usb_handle_t); 176 215 216 int usb_hc_add_child_device(device_t *, const char *, const char *, bool); 177 217 178 218 #endif -
uspace/lib/usb/include/usb/usbdrv.h
r56b962d r84439d7 41 41 int usb_drv_hc_connect(device_t *, unsigned int); 42 42 43 int usb_drv_reserve_default_address(int); 44 int usb_drv_release_default_address(int); 45 usb_address_t usb_drv_request_address(int); 46 int usb_drv_bind_address(int, usb_address_t, devman_handle_t); 47 int usb_drv_release_address(int, usb_address_t); 48 43 49 usb_address_t usb_drv_get_my_address(int, device_t *); 44 50 … … 48 54 void *, size_t, size_t *, usb_handle_t *); 49 55 56 int usb_drv_async_control_write_setup(int, usb_target_t, 57 void *, size_t, usb_handle_t *); 58 int usb_drv_async_control_write_data(int, usb_target_t, 59 void *, size_t, usb_handle_t *); 60 int usb_drv_async_control_write_status(int, usb_target_t, 61 usb_handle_t *); 62 63 int usb_drv_async_control_read_setup(int, usb_target_t, 64 void *, size_t, usb_handle_t *); 65 int usb_drv_async_control_read_data(int, usb_target_t, 66 void *, size_t, size_t *, usb_handle_t *); 67 int usb_drv_async_control_read_status(int, usb_target_t, 68 usb_handle_t *); 69 50 70 int usb_drv_async_wait_for(usb_handle_t); 51 71 -
uspace/lib/usb/src/hcdhubd.c
r56b962d r84439d7 31 31 */ 32 32 /** @file 33 * @brief HC driver and hub driver (implementation).33 * @brief Common stuff for both HC driver and hub driver. 34 34 */ 35 35 #include <usb/hcdhubd.h> 36 36 #include <usb/devreq.h> 37 37 #include <usbhc_iface.h> 38 #include <usb/descriptor.h> 38 39 #include <driver.h> 39 40 #include <bool.h> 40 41 #include <errno.h> 41 42 #define USB_HUB_DEVICE_NAME "usbhub" 43 44 /** List of handled host controllers. */ 45 static LIST_INITIALIZE(hc_list); 46 47 /** Our HC driver. */ 48 static usb_hc_driver_t *hc_driver = NULL; 49 50 static usbhc_iface_t usb_interface = { 51 .interrupt_out = NULL, 52 .interrupt_in = NULL 53 }; 54 55 static device_ops_t usb_device_ops = { 56 .interfaces[USBHC_DEV_IFACE] = &usb_interface 57 }; 58 59 static void set_hub_address(usb_hc_device_t *hc, usb_address_t address); 42 #include <str_error.h> 43 #include <usb/classes/hub.h> 44 45 #include "hcdhubd_private.h" 60 46 61 47 /** Callback when new device is detected and must be handled by this driver. … … 64 50 * @return Error code. 65 51 */ 66 static int add_device(device_t *dev) 67 { 68 /* 69 * FIXME: use some magic to determine whether hub or another HC 70 * was connected. 71 */ 72 bool is_hc = str_cmp(dev->name, USB_HUB_DEVICE_NAME) != 0; 73 printf("%s: add_device(name=\"%s\")\n", hc_driver->name, dev->name); 74 75 if (is_hc) { 76 /* 77 * We are the HC itself. 78 */ 79 usb_hc_device_t *hc_dev = malloc(sizeof(usb_hc_device_t)); 80 list_initialize(&hc_dev->link); 81 hc_dev->transfer_ops = NULL; 82 83 hc_dev->generic = dev; 84 dev->ops = &usb_device_ops; 85 hc_dev->generic->driver_data = hc_dev; 86 87 int rc = hc_driver->add_hc(hc_dev); 88 if (rc != EOK) { 89 free(hc_dev); 90 return rc; 91 } 92 93 /* 94 * FIXME: The following line causes devman to hang. 95 * Will investigate later why. 96 */ 97 // add_device_to_class(dev, "usbhc"); 98 99 list_append(&hc_dev->link, &hc_list); 100 101 return EOK; 102 } else { 103 usb_hc_device_t *hc = list_get_instance(hc_list.next, usb_hc_device_t, link); 104 set_hub_address(hc, 5); 105 106 /* 107 * We are some (probably deeply nested) hub. 108 * Thus, assign our own operations and explore already 109 * connected devices. 110 */ 111 112 return ENOTSUP; 113 } 114 } 115 116 /** Sample usage of usb_hc_async functions. 117 * This function sets hub address using standard SET_ADDRESS request. 118 * 119 * @warning This function shall be removed once you are familiar with 120 * the usb_hc_ API. 121 * 122 * @param hc Host controller the hub belongs to. 123 * @param address New hub address. 124 */ 125 static void set_hub_address(usb_hc_device_t *hc, usb_address_t address) 126 { 127 printf("%s: setting hub address to %d\n", hc->generic->name, address); 128 usb_target_t target = {0, 0}; 129 usb_handle_t handle; 130 int rc; 131 132 usb_device_request_setup_packet_t setup_packet = { 133 .request_type = 0, 134 .request = USB_DEVREQ_SET_ADDRESS, 135 .index = 0, 136 .length = 0, 137 }; 138 setup_packet.value = address; 139 140 rc = usb_hc_async_control_write_setup(hc, target, 141 &setup_packet, sizeof(setup_packet), &handle); 142 if (rc != EOK) { 143 return; 144 } 145 146 rc = usb_hc_async_wait_for(handle); 147 if (rc != EOK) { 148 return; 149 } 150 151 rc = usb_hc_async_control_write_status(hc, target, &handle); 152 if (rc != EOK) { 153 return; 154 } 155 156 rc = usb_hc_async_wait_for(handle); 157 if (rc != EOK) { 158 return; 159 } 160 161 printf("%s: hub address changed\n", hc->generic->name); 162 } 163 164 /** Check changes on all known hubs. 165 */ 166 static void check_hub_changes(void) 167 { 168 /* 169 * Iterate through all HCs. 170 */ 171 link_t *link_hc; 172 for (link_hc = hc_list.next; 173 link_hc != &hc_list; 174 link_hc = link_hc->next) { 175 usb_hc_device_t *hc = list_get_instance(link_hc, 176 usb_hc_device_t, link); 177 /* 178 * Iterate through all their hubs. 179 */ 180 link_t *link_hub; 181 for (link_hub = hc->hubs.next; 182 link_hub != &hc->hubs; 183 link_hub = link_hub->next) { 184 usb_hcd_hub_info_t *hub = list_get_instance(link_hub, 185 usb_hcd_hub_info_t, link); 186 187 /* 188 * Check status change pipe of this hub. 189 */ 190 usb_target_t target = { 191 .address = hub->device->address, 192 .endpoint = 1 193 }; 194 195 // FIXME: count properly 196 size_t byte_length = (hub->port_count / 8) + 1; 197 198 void *change_bitmap = malloc(byte_length); 199 size_t actual_size; 200 usb_handle_t handle; 201 202 /* 203 * Send the request. 204 * FIXME: check returned value for possible errors 205 */ 206 usb_hc_async_interrupt_in(hc, target, 207 change_bitmap, byte_length, &actual_size, 208 &handle); 209 210 usb_hc_async_wait_for(handle); 211 212 /* 213 * TODO: handle the changes. 214 */ 215 } 216 } 52 static int add_device(device_t *dev) { 53 return ENOTSUP; 217 54 } 218 55 … … 234 71 * @return Error code. 235 72 */ 236 int usb_hcd_main(usb_hc_driver_t *hc) 237 { 73 int usb_hcd_main(usb_hc_driver_t *hc) { 238 74 hc_driver = hc; 239 75 hc_driver_generic.name = hc->name; 240 241 /*242 * Launch here fibril that will periodically check all243 * attached hubs for status change.244 * WARN: This call will effectively do nothing.245 */246 check_hub_changes();247 76 248 77 /* … … 261 90 * @return Error code. 262 91 */ 263 int usb_hcd_add_root_hub( usb_hc_device_t *dev)92 int usb_hcd_add_root_hub(device_t *dev) 264 93 { 94 char *id; 95 int rc = asprintf(&id, "usb&hub"); 96 if (rc <= 0) { 97 return rc; 98 } 99 100 rc = usb_hc_add_child_device(dev, USB_HUB_DEVICE_NAME, id, true); 101 if (rc != EOK) { 102 free(id); 103 } 104 105 return rc; 106 } 107 108 /** Info about child device. */ 109 struct child_device_info { 110 device_t *parent; 111 const char *name; 112 const char *match_id; 113 }; 114 115 /** Adds a child device fibril worker. */ 116 static int fibril_add_child_device(void *arg) { 117 struct child_device_info *child_info 118 = (struct child_device_info *) arg; 265 119 int rc; 266 120 267 /* 268 * Announce presence of child device. 269 */ 270 device_t *hub = NULL; 121 async_usleep(1000); 122 123 device_t *child = create_device(); 271 124 match_id_t *match_id = NULL; 272 125 273 hub = create_device(); 274 if (hub == NULL) { 126 if (child == NULL) { 275 127 rc = ENOMEM; 276 128 goto failure; 277 129 } 278 hub->name = USB_HUB_DEVICE_NAME;130 child->name = child_info->name; 279 131 280 132 match_id = create_match_id(); … … 283 135 goto failure; 284 136 } 285 286 char *id; 287 rc = asprintf(&id, "usb&hc=%s&hub", dev->generic->name); 288 if (rc <= 0) { 289 rc = ENOMEM; 290 goto failure; 291 } 292 293 match_id->id = id; 294 match_id->score = 30; 295 296 add_match_id(&hub->match_ids, match_id); 297 298 rc = child_device_register(hub, dev->generic); 137 match_id->id = child_info->match_id; 138 match_id->score = 10; 139 add_match_id(&child->match_ids, match_id); 140 141 printf("%s: adding child device `%s' with match \"%s\"\n", 142 hc_driver->name, child->name, match_id->id); 143 rc = child_device_register(child, child_info->parent); 144 printf("%s: child device `%s' registration: %s\n", 145 hc_driver->name, child->name, str_error(rc)); 146 299 147 if (rc != EOK) { 300 148 goto failure; 301 149 } 302 150 303 printf("%s: registered root hub\n", dev->generic->name); 151 goto leave; 152 153 failure: 154 if (child != NULL) { 155 child->name = NULL; 156 delete_device(child); 157 } 158 159 if (match_id != NULL) { 160 match_id->id = NULL; 161 delete_match_id(match_id); 162 } 163 164 leave: 165 free(arg); 304 166 return EOK; 305 306 failure: 307 if (hub != NULL) { 308 hub->name = NULL; 309 delete_device(hub); 310 } 311 delete_match_id(match_id); 312 313 return rc; 167 } 168 169 /** Adds a child. 170 * Due to deadlock in devman when parent registers child that oughts to be 171 * driven by the same task, the child adding is done in separate fibril. 172 * Not optimal, but it works. 173 * Update: not under all circumstances the new fibril is successful either. 174 * Thus the last parameter to let the caller choose. 175 * 176 * @param parent Parent device. 177 * @param name Device name. 178 * @param match_id Match id. 179 * @param create_fibril Whether to run the addition in new fibril. 180 * @return Error code. 181 */ 182 int usb_hc_add_child_device(device_t *parent, const char *name, 183 const char *match_id, bool create_fibril) { 184 printf("%s: about to add child device `%s' (%s)\n", hc_driver->name, 185 name, match_id); 186 187 /* 188 * Seems that creating fibril which postpones the action 189 * is the best solution. 190 */ 191 create_fibril = true; 192 193 struct child_device_info *child_info 194 = malloc(sizeof (struct child_device_info)); 195 196 child_info->parent = parent; 197 child_info->name = name; 198 child_info->match_id = match_id; 199 200 if (create_fibril) { 201 fid_t fibril = fibril_create(fibril_add_child_device, child_info); 202 if (!fibril) { 203 return ENOMEM; 204 } 205 fibril_add_ready(fibril); 206 } else { 207 fibril_add_child_device(child_info); 208 } 209 210 return EOK; 211 } 212 213 /** Tell USB address of given device. 214 * 215 * @param handle Devman handle of the device. 216 * @return USB device address or error code. 217 */ 218 usb_address_t usb_get_address_by_handle(devman_handle_t handle) { 219 /* TODO: search list of attached devices. */ 220 return ENOENT; 221 } 222 223 usb_address_t usb_use_free_address(usb_hc_device_t * this_hcd) { 224 //is there free address? 225 link_t * addresses = &this_hcd->addresses; 226 if (list_empty(addresses)) return -1; 227 link_t * link_addr = addresses; 228 bool found = false; 229 usb_address_list_t * range = NULL; 230 while (!found) { 231 link_addr = link_addr->next; 232 if (link_addr == addresses) return -2; 233 range = list_get_instance(link_addr, 234 usb_address_list_t, link); 235 if (range->upper_bound - range->lower_bound > 0) { 236 found = true; 237 } 238 } 239 //now we have interval 240 int result = range->lower_bound; 241 ++(range->lower_bound); 242 if (range->upper_bound - range->lower_bound == 0) { 243 list_remove(&range->link); 244 free(range); 245 } 246 return result; 247 } 248 249 void usb_free_used_address(usb_hc_device_t * this_hcd, usb_address_t addr) { 250 //check range 251 if (addr < usb_lowest_address || addr > usb_highest_address) 252 return; 253 link_t * addresses = &this_hcd->addresses; 254 link_t * link_addr = addresses; 255 //find 'good' interval 256 usb_address_list_t * found_range = NULL; 257 bool found = false; 258 while (!found) { 259 link_addr = link_addr->next; 260 if (link_addr == addresses) { 261 found = true; 262 } else { 263 usb_address_list_t * range = list_get_instance(link_addr, 264 usb_address_list_t, link); 265 if ( (range->lower_bound - 1 == addr) || 266 (range->upper_bound == addr)) { 267 found = true; 268 found_range = range; 269 } 270 if (range->lower_bound - 1 > addr) { 271 found = true; 272 } 273 274 } 275 } 276 if (found_range == NULL) { 277 //no suitable range found 278 usb_address_list_t * result_range = 279 (usb_address_list_t*) malloc(sizeof (usb_address_list_t)); 280 result_range->lower_bound = addr; 281 result_range->upper_bound = addr + 1; 282 list_insert_before(&result_range->link, link_addr); 283 } else { 284 //we have good range 285 if (found_range->lower_bound - 1 == addr) { 286 --found_range->lower_bound; 287 } else { 288 //only one possible case 289 ++found_range->upper_bound; 290 if (found_range->link.next != addresses) { 291 usb_address_list_t * next_range = 292 list_get_instance( &found_range->link.next, 293 usb_address_list_t, link); 294 //check neighbour range 295 if (next_range->lower_bound == addr + 1) { 296 //join ranges 297 found_range->upper_bound = next_range->upper_bound; 298 list_remove(&next_range->link); 299 free(next_range); 300 } 301 } 302 } 303 } 304 314 305 } 315 306 -
uspace/lib/usb/src/localdrv.c
r56b962d r84439d7 39 39 #include <errno.h> 40 40 41 /** Find host controller when handled by current task. 42 * 43 * @param dev Device asking for connection. 44 * @return Device structure corresponding to parent host controller. 45 * @retval NULL Corresponding host controller not found. 46 */ 47 device_t *usb_hc_connect(device_t *dev) 48 { 49 /* 50 * FIXME: this will not work when some hub on the path is 51 * not driven by the same task. 52 */ 53 device_t *parent = dev; 54 while (parent->parent != NULL) { 55 parent = parent->parent; 56 } 57 58 if (dev == parent) { 59 printf("FIXME in %s:%d encountered!\n", __FILE__, __LINE__); 60 parent = NULL; 61 } 62 63 return parent; 64 } 65 41 66 /** Information about pending transaction on HC. */ 42 67 typedef struct { -
uspace/lib/usb/src/usbdrv.c
r56b962d r84439d7 55 55 /** Connect to host controller the device is physically attached to. 56 56 * 57 * @param handle Device handle.57 * @param dev Device asking for connection. 58 58 * @param flags Connection flags (blocking connection). 59 59 * @return Phone to corresponding HC or error code. … … 64 64 * Call parent hub to obtain device handle of respective HC. 65 65 */ 66 return ENOTSUP; 66 67 /* 68 * FIXME: currently we connect always to virtual host controller. 69 */ 70 int rc; 71 devman_handle_t handle; 72 73 rc = devman_device_get_handle("/vhc", &handle, 0); 74 if (rc != EOK) { 75 return rc; 76 } 77 78 int phone = devman_device_connect(handle, 0); 79 80 return phone; 67 81 } 68 82 … … 75 89 usb_address_t usb_drv_get_my_address(int phone, device_t *dev) 76 90 { 77 return ENOTSUP; 91 ipcarg_t address; 92 int rc = async_req_1_1(phone, IPC_M_USBHC_GET_ADDRESS, 93 dev->handle, &address); 94 95 if (rc != EOK) { 96 return rc; 97 } 98 99 return (usb_address_t) address; 100 } 101 102 /** Tell HC to reserve default address. 103 * 104 * @param phone Open phone to host controller driver. 105 * @return Error code. 106 */ 107 int usb_drv_reserve_default_address(int phone) 108 { 109 return async_req_0_0(phone, IPC_M_USBHC_RESERVE_DEFAULT_ADDRESS); 110 } 111 112 /** Tell HC to release default address. 113 * 114 * @param phone Open phone to host controller driver. 115 * @return Error code. 116 */ 117 int usb_drv_release_default_address(int phone) 118 { 119 return async_req_0_0(phone, IPC_M_USBHC_RELEASE_DEFAULT_ADDRESS); 120 } 121 122 /** Ask HC for free address assignment. 123 * 124 * @param phone Open phone to host controller driver. 125 * @return Assigned USB address or negative error code. 126 */ 127 usb_address_t usb_drv_request_address(int phone) 128 { 129 ipcarg_t address; 130 int rc = async_req_0_1(phone, IPC_M_USBHC_REQUEST_ADDRESS, &address); 131 if (rc != EOK) { 132 return rc; 133 } else { 134 return (usb_address_t) address; 135 } 136 } 137 138 /** Inform HC about binding address with devman handle. 139 * 140 * @param phone Open phone to host controller driver. 141 * @param address Address to be binded. 142 * @param handle Devman handle of the device. 143 * @return Error code. 144 */ 145 int usb_drv_bind_address(int phone, usb_address_t address, 146 devman_handle_t handle) 147 { 148 int rc = async_req_2_0(phone, IPC_M_USBHC_BIND_ADDRESS, 149 address, handle); 150 151 return rc; 152 } 153 154 /** Inform HC about address release. 155 * 156 * @param phone Open phone to host controller driver. 157 * @param address Address to be released. 158 * @return Error code. 159 */ 160 int usb_drv_release_address(int phone, usb_address_t address) 161 { 162 return async_req_1_0(phone, IPC_M_USBHC_RELEASE_ADDRESS, address); 78 163 } 79 164 … … 323 408 } 324 409 410 /** Start control write transfer. */ 411 int usb_drv_async_control_write_setup(int phone, usb_target_t target, 412 void *buffer, size_t size, 413 usb_handle_t *handle) 414 { 415 return async_send_buffer(phone, 416 IPC_M_USBHC_CONTROL_WRITE_SETUP, 417 target, 418 buffer, size, 419 handle); 420 } 421 422 /** Send data during control write transfer. */ 423 int usb_drv_async_control_write_data(int phone, usb_target_t target, 424 void *buffer, size_t size, 425 usb_handle_t *handle) 426 { 427 return async_send_buffer(phone, 428 IPC_M_USBHC_CONTROL_WRITE_DATA, 429 target, 430 buffer, size, 431 handle); 432 } 433 434 /** Finalize control write transfer. */ 435 int usb_drv_async_control_write_status(int phone, usb_target_t target, 436 usb_handle_t *handle) 437 { 438 return async_recv_buffer(phone, 439 IPC_M_USBHC_CONTROL_WRITE_STATUS, 440 target, 441 NULL, 0, NULL, 442 handle); 443 } 444 445 /** Start control read transfer. */ 446 int usb_drv_async_control_read_setup(int phone, usb_target_t target, 447 void *buffer, size_t size, 448 usb_handle_t *handle) 449 { 450 return async_send_buffer(phone, 451 IPC_M_USBHC_CONTROL_READ_SETUP, 452 target, 453 buffer, size, 454 handle); 455 } 456 457 /** Read data during control read transfer. */ 458 int usb_drv_async_control_read_data(int phone, usb_target_t target, 459 void *buffer, size_t size, size_t *actual_size, 460 usb_handle_t *handle) 461 { 462 return async_recv_buffer(phone, 463 IPC_M_USBHC_CONTROL_READ_DATA, 464 target, 465 buffer, size, actual_size, 466 handle); 467 } 468 469 /** Finalize control read transfer. */ 470 int usb_drv_async_control_read_status(int phone, usb_target_t target, 471 usb_handle_t *handle) 472 { 473 return async_send_buffer(phone, 474 IPC_M_USBHC_CONTROL_READ_STATUS, 475 target, 476 NULL, 0, 477 handle); 478 } 479 325 480 /** 326 481 * @}
Note:
See TracChangeset
for help on using the changeset viewer.
