Changes in uspace/lib/usb/src/hcdhubd.c [4317827:71ed4849] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usb/src/hcdhubd.c
r4317827 r71ed4849 36 36 #include <usb/devreq.h> 37 37 #include <usbhc_iface.h> 38 #include <usb_iface.h> 38 39 #include <usb/descriptor.h> 39 40 #include <driver.h> … … 45 46 #include "hcdhubd_private.h" 46 47 48 49 static int usb_iface_get_hc_handle(device_t *dev, devman_handle_t *handle) 50 { 51 assert(dev); 52 assert(dev->parent != NULL); 53 54 device_t *parent = dev->parent; 55 56 if (parent->ops && parent->ops->interfaces[USB_DEV_IFACE]) { 57 usb_iface_t *usb_iface 58 = (usb_iface_t *) parent->ops->interfaces[USB_DEV_IFACE]; 59 assert(usb_iface != NULL); 60 if (usb_iface->get_hc_handle) { 61 int rc = usb_iface->get_hc_handle(parent, handle); 62 return rc; 63 } 64 } 65 66 return ENOTSUP; 67 } 68 69 static usb_iface_t usb_iface = { 70 .get_hc_handle = usb_iface_get_hc_handle 71 }; 72 73 static device_ops_t child_ops = { 74 .interfaces[USB_DEV_IFACE] = &usb_iface 75 }; 76 47 77 /** Callback when new device is detected and must be handled by this driver. 48 78 * … … 114 144 115 145 /** Adds a child device fibril worker. */ 116 static int fibril_add_child_device(void *arg) 117 { 146 static int fibril_add_child_device(void *arg) { 118 147 struct child_device_info *child_info 119 148 = (struct child_device_info *) arg; 120 149 int rc; 121 150 … … 130 159 } 131 160 child->name = child_info->name; 161 child->parent = child_info->parent; 162 child->ops = &child_ops; 132 163 133 164 match_id = create_match_id(); … … 141 172 142 173 printf("%s: adding child device `%s' with match \"%s\"\n", 143 174 hc_driver->name, child->name, match_id->id); 144 175 rc = child_device_register(child, child_info->parent); 145 176 printf("%s: child device `%s' registration: %s\n", 146 177 hc_driver->name, child->name, str_error(rc)); 147 178 148 179 if (rc != EOK) { … … 182 213 */ 183 214 int usb_hc_add_child_device(device_t *parent, const char *name, 184 const char *match_id, bool create_fibril) 185 { 215 const char *match_id, bool create_fibril) { 186 216 printf("%s: about to add child device `%s' (%s)\n", hc_driver->name, 187 217 name, match_id); 188 218 189 219 /* … … 194 224 195 225 struct child_device_info *child_info 196 = malloc(sizeof(struct child_device_info));226 = malloc(sizeof (struct child_device_info)); 197 227 198 228 child_info->parent = parent; … … 218 248 * @return USB device address or error code. 219 249 */ 220 usb_address_t usb_get_address_by_handle(devman_handle_t handle) 221 { 250 usb_address_t usb_get_address_by_handle(devman_handle_t handle) { 222 251 /* TODO: search list of attached devices. */ 223 252 return ENOENT; 224 253 } 225 254 255 usb_address_t usb_use_free_address(usb_hc_device_t * this_hcd) { 256 //is there free address? 257 link_t * addresses = &this_hcd->addresses; 258 if (list_empty(addresses)) return -1; 259 link_t * link_addr = addresses; 260 bool found = false; 261 usb_address_list_t * range = NULL; 262 while (!found) { 263 link_addr = link_addr->next; 264 if (link_addr == addresses) return -2; 265 range = list_get_instance(link_addr, 266 usb_address_list_t, link); 267 if (range->upper_bound - range->lower_bound > 0) { 268 found = true; 269 } 270 } 271 //now we have interval 272 int result = range->lower_bound; 273 ++(range->lower_bound); 274 if (range->upper_bound - range->lower_bound == 0) { 275 list_remove(&range->link); 276 free(range); 277 } 278 return result; 279 } 280 281 void usb_free_used_address(usb_hc_device_t * this_hcd, usb_address_t addr) { 282 //check range 283 if (addr < usb_lowest_address || addr > usb_highest_address) 284 return; 285 link_t * addresses = &this_hcd->addresses; 286 link_t * link_addr = addresses; 287 //find 'good' interval 288 usb_address_list_t * found_range = NULL; 289 bool found = false; 290 while (!found) { 291 link_addr = link_addr->next; 292 if (link_addr == addresses) { 293 found = true; 294 } else { 295 usb_address_list_t * range = list_get_instance(link_addr, 296 usb_address_list_t, link); 297 if ( (range->lower_bound - 1 == addr) || 298 (range->upper_bound == addr)) { 299 found = true; 300 found_range = range; 301 } 302 if (range->lower_bound - 1 > addr) { 303 found = true; 304 } 305 306 } 307 } 308 if (found_range == NULL) { 309 //no suitable range found 310 usb_address_list_t * result_range = 311 (usb_address_list_t*) malloc(sizeof (usb_address_list_t)); 312 result_range->lower_bound = addr; 313 result_range->upper_bound = addr + 1; 314 list_insert_before(&result_range->link, link_addr); 315 } else { 316 //we have good range 317 if (found_range->lower_bound - 1 == addr) { 318 --found_range->lower_bound; 319 } else { 320 //only one possible case 321 ++found_range->upper_bound; 322 if (found_range->link.next != addresses) { 323 usb_address_list_t * next_range = 324 list_get_instance( &found_range->link.next, 325 usb_address_list_t, link); 326 //check neighbour range 327 if (next_range->lower_bound == addr + 1) { 328 //join ranges 329 found_range->upper_bound = next_range->upper_bound; 330 list_remove(&next_range->link); 331 free(next_range); 332 } 333 } 334 } 335 } 336 337 } 338 226 339 /** 227 340 * @}
Note:
See TracChangeset
for help on using the changeset viewer.