Changes in uspace/lib/usb/src/hcdhubd.c [4317827:4144630] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usb/src/hcdhubd.c
r4317827 r4144630 51 51 */ 52 52 static int add_device(device_t *dev) { 53 return ENOTSUP; 53 bool is_hc = str_cmp(dev->name, USB_HUB_DEVICE_NAME) != 0; 54 printf("%s: add_device(name=\"%s\")\n", hc_driver->name, dev->name); 55 56 if (is_hc) { 57 /* 58 * We are the HC itself. 59 */ 60 return usb_add_hc_device(dev); 61 } else { 62 /* 63 * We are some (maybe deeply nested) hub. 64 * Thus, assign our own operations and explore already 65 * connected devices. 66 */ 67 return usb_add_hub_device(dev); 68 } 54 69 } 55 70 … … 90 105 * @return Error code. 91 106 */ 92 int usb_hcd_add_root_hub(device_t *dev) 93 { 107 int usb_hcd_add_root_hub(usb_hc_device_t *dev) { 94 108 char *id; 95 int rc = asprintf(&id, "usb&h ub");109 int rc = asprintf(&id, "usb&hc=%s&hub", dev->generic->name); 96 110 if (rc <= 0) { 97 111 return rc; 98 112 } 99 113 100 rc = usb_hc_add_child_device(dev , USB_HUB_DEVICE_NAME, id, true);114 rc = usb_hc_add_child_device(dev->generic, USB_HUB_DEVICE_NAME, id, true); 101 115 if (rc != EOK) { 102 116 free(id); … … 114 128 115 129 /** Adds a child device fibril worker. */ 116 static int fibril_add_child_device(void *arg) 117 { 130 static int fibril_add_child_device(void *arg) { 118 131 struct child_device_info *child_info 119 132 = (struct child_device_info *) arg; 120 133 int rc; 121 122 async_usleep(1000);123 134 124 135 device_t *child = create_device(); … … 141 152 142 153 printf("%s: adding child device `%s' with match \"%s\"\n", 143 154 hc_driver->name, child->name, match_id->id); 144 155 rc = child_device_register(child, child_info->parent); 145 156 printf("%s: child device `%s' registration: %s\n", 146 157 hc_driver->name, child->name, str_error(rc)); 147 158 148 159 if (rc != EOK) { … … 182 193 */ 183 194 int usb_hc_add_child_device(device_t *parent, const char *name, 184 const char *match_id, bool create_fibril) 185 { 195 const char *match_id, bool create_fibril) { 186 196 printf("%s: about to add child device `%s' (%s)\n", hc_driver->name, 187 name, match_id); 188 189 /* 190 * Seems that creating fibril which postpones the action 191 * is the best solution. 192 */ 193 create_fibril = true; 197 name, match_id); 194 198 195 199 struct child_device_info *child_info 196 = malloc(sizeof(struct child_device_info));200 = malloc(sizeof (struct child_device_info)); 197 201 198 202 child_info->parent = parent; … … 218 222 * @return USB device address or error code. 219 223 */ 220 usb_address_t usb_get_address_by_handle(devman_handle_t handle) 221 { 224 usb_address_t usb_get_address_by_handle(devman_handle_t handle) { 222 225 /* TODO: search list of attached devices. */ 223 226 return ENOENT; 224 227 } 225 228 229 usb_address_t usb_use_free_address(usb_hc_device_t * this_hcd) { 230 //is there free address? 231 link_t * addresses = &this_hcd->addresses; 232 if (list_empty(addresses)) return -1; 233 link_t * link_addr = addresses; 234 bool found = false; 235 usb_address_list_t * range = NULL; 236 while (!found) { 237 link_addr = link_addr->next; 238 if (link_addr == addresses) return -2; 239 range = list_get_instance(link_addr, 240 usb_address_list_t, link); 241 if (range->upper_bound - range->lower_bound > 0) { 242 found = true; 243 } 244 } 245 //now we have interval 246 int result = range->lower_bound; 247 ++(range->lower_bound); 248 if (range->upper_bound - range->lower_bound == 0) { 249 list_remove(&range->link); 250 free(range); 251 } 252 return result; 253 } 254 255 void usb_free_used_address(usb_hc_device_t * this_hcd, usb_address_t addr) { 256 //check range 257 if (addr < usb_lowest_address || addr > usb_highest_address) 258 return; 259 link_t * addresses = &this_hcd->addresses; 260 link_t * link_addr = addresses; 261 //find 'good' interval 262 usb_address_list_t * found_range = NULL; 263 bool found = false; 264 while (!found) { 265 link_addr = link_addr->next; 266 if (link_addr == addresses) { 267 found = true; 268 } else { 269 usb_address_list_t * range = list_get_instance(link_addr, 270 usb_address_list_t, link); 271 if ( (range->lower_bound - 1 == addr) || 272 (range->upper_bound == addr)) { 273 found = true; 274 found_range = range; 275 } 276 if (range->lower_bound - 1 > addr) { 277 found = true; 278 } 279 280 } 281 } 282 if (found_range == NULL) { 283 //no suitable range found 284 usb_address_list_t * result_range = 285 (usb_address_list_t*) malloc(sizeof (usb_address_list_t)); 286 result_range->lower_bound = addr; 287 result_range->upper_bound = addr + 1; 288 list_insert_before(&result_range->link, link_addr); 289 } else { 290 //we have good range 291 if (found_range->lower_bound - 1 == addr) { 292 --found_range->lower_bound; 293 } else { 294 //only one possible case 295 ++found_range->upper_bound; 296 if (found_range->link.next != addresses) { 297 usb_address_list_t * next_range = 298 list_get_instance( &found_range->link.next, 299 usb_address_list_t, link); 300 //check neighbour range 301 if (next_range->lower_bound == addr + 1) { 302 //join ranges 303 found_range->upper_bound = next_range->upper_bound; 304 list_remove(&next_range->link); 305 free(next_range); 306 } 307 } 308 } 309 } 310 311 } 312 226 313 /** 227 314 * @}
Note:
See TracChangeset
for help on using the changeset viewer.