Changes in uspace/lib/usb/src/hcdhubd.c [e4dbfda:da55d5b] in mainline
- File:
-
- 1 edited
-
uspace/lib/usb/src/hcdhubd.c (modified) (14 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usb/src/hcdhubd.c
re4dbfda rda55d5b 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> 42 #include <usb/classes/hub.h> 41 43 42 44 #define USB_HUB_DEVICE_NAME "usbhub" 45 46 #define USB_KBD_DEVICE_NAME "hid" 47 48 49 43 50 44 51 /** List of handled host controllers. */ … … 57 64 }; 58 65 66 size_t USB_HUB_MAX_DESCRIPTOR_SIZE = 71; 67 68 uint8_t USB_HUB_DESCRIPTOR_TYPE = 0x29; 69 70 //********************************************* 71 // 72 // various utils 73 // 74 //********************************************* 75 76 void * usb_serialize_hub_descriptor(usb_hub_descriptor_t * descriptor) { 77 //base size 78 size_t size = 7; 79 //variable size according to port count 80 size_t var_size = descriptor->ports_count / 8 + ((descriptor->ports_count % 8 > 0) ? 1 : 0); 81 size += 2 * var_size; 82 uint8_t * result = (uint8_t*) malloc(size); 83 //size 84 result[0] = size; 85 //descriptor type 86 result[1] = USB_DESCTYPE_HUB; 87 result[2] = descriptor->ports_count; 88 /// @fixme handling of endianness?? 89 result[3] = descriptor->hub_characteristics / 256; 90 result[4] = descriptor->hub_characteristics % 256; 91 result[5] = descriptor->pwr_on_2_good_time; 92 result[6] = descriptor->current_requirement; 93 94 size_t i; 95 for (i = 0; i < var_size; ++i) { 96 result[7 + i] = descriptor->devices_removable[i]; 97 } 98 for (i = 0; i < var_size; ++i) { 99 result[7 + var_size + i] = 255; 100 } 101 return result; 102 } 103 104 usb_hub_descriptor_t * usb_deserialize_hub_desriptor(void * serialized_descriptor) { 105 uint8_t * sdescriptor = (uint8_t*) serialized_descriptor; 106 if (sdescriptor[1] != USB_DESCTYPE_HUB) return NULL; 107 usb_hub_descriptor_t * result = (usb_hub_descriptor_t*) malloc(sizeof (usb_hub_descriptor_t)); 108 //uint8_t size = sdescriptor[0]; 109 result->ports_count = sdescriptor[2]; 110 /// @fixme handling of endianness?? 111 result->hub_characteristics = sdescriptor[4] + 256 * sdescriptor[3]; 112 result->pwr_on_2_good_time = sdescriptor[5]; 113 result->current_requirement = sdescriptor[6]; 114 size_t var_size = result->ports_count / 8 + ((result->ports_count % 8 > 0) ? 1 : 0); 115 result->devices_removable = (uint8_t*) malloc(var_size); 116 117 size_t i; 118 for (i = 0; i < var_size; ++i) { 119 result->devices_removable[i] = sdescriptor[7 + i]; 120 } 121 return result; 122 } 123 124 125 //********************************************* 126 // 127 // hub driver code 128 // 129 //********************************************* 130 59 131 static void set_hub_address(usb_hc_device_t *hc, usb_address_t address); 60 132 133 usb_hcd_hub_info_t * usb_create_hub_info(device_t * device) { 134 usb_hcd_hub_info_t* result = (usb_hcd_hub_info_t*) malloc(sizeof (usb_hcd_hub_info_t)); 135 //get parent device 136 /// @TODO this code is not correct 137 device_t * my_hcd = device; 138 while (my_hcd->parent) 139 my_hcd = my_hcd->parent; 140 //dev-> 141 printf("%s: owner hcd found: %s\n", hc_driver->name, my_hcd->name); 142 //we add the hub into the first hc 143 //link_t *link_hc = hc_list.next; 144 //usb_hc_device_t *hc = list_get_instance(link_hc, 145 // usb_hc_device_t, link); 146 //must get generic device info 147 148 149 return result; 150 } 151 61 152 /** Callback when new device is detected and must be handled by this driver. 62 153 * 63 154 * @param dev New device. 64 * @return Error code. 65 */ 66 static int add_device(device_t *dev) 67 { 155 * @return Error code.hub added, hurrah!\n" 156 */ 157 static int add_device(device_t *dev) { 68 158 /* 69 159 * FIXME: use some magic to determine whether hub or another HC … … 77 167 * We are the HC itself. 78 168 */ 79 usb_hc_device_t *hc_dev = malloc(sizeof (usb_hc_device_t));169 usb_hc_device_t *hc_dev = malloc(sizeof (usb_hc_device_t)); 80 170 list_initialize(&hc_dev->link); 81 171 hc_dev->transfer_ops = NULL; … … 99 189 list_append(&hc_dev->link, &hc_list); 100 190 191 //add keyboard 192 /// @TODO this is not correct code 193 194 /* 195 * Announce presence of child device. 196 */ 197 device_t *kbd = NULL; 198 match_id_t *match_id = NULL; 199 200 kbd = create_device(); 201 if (kbd == NULL) { 202 printf("ERROR: enomem\n"); 203 } 204 kbd->name = USB_KBD_DEVICE_NAME; 205 206 match_id = create_match_id(); 207 if (match_id == NULL) { 208 printf("ERROR: enomem\n"); 209 } 210 211 char *id; 212 rc = asprintf(&id, USB_KBD_DEVICE_NAME); 213 if (rc <= 0) { 214 printf("ERROR: enomem\n"); 215 return rc; 216 } 217 218 match_id->id = id; 219 match_id->score = 30; 220 221 add_match_id(&kbd->match_ids, match_id); 222 223 rc = child_device_register(kbd, dev); 224 if (rc != EOK) { 225 printf("ERROR: cannot register kbd\n"); 226 return rc; 227 } 228 229 printf("%s: registered root hub\n", dev->name); 101 230 return EOK; 231 232 233 102 234 } else { 103 235 usb_hc_device_t *hc = list_get_instance(hc_list.next, usb_hc_device_t, link); … … 109 241 * connected devices. 110 242 */ 111 112 return ENOTSUP; 243 //insert hub into list 244 //find owner hcd 245 device_t * my_hcd = dev; 246 while (my_hcd->parent) 247 my_hcd = my_hcd->parent; 248 //dev-> 249 printf("%s: owner hcd found: %s\n", hc_driver->name, my_hcd->name); 250 my_hcd = dev; 251 while (my_hcd->parent) 252 my_hcd = my_hcd->parent; 253 //dev-> 254 255 printf("%s: owner hcd found: %s\n", hc_driver->name, my_hcd->name); 256 257 //create the hub structure 258 usb_hcd_hub_info_t * hub_info = usb_create_hub_info(dev); 259 260 261 //append into the list 262 //we add the hub into the first hc 263 list_append(&hub_info->link, &hc->hubs); 264 265 266 267 return EOK; 268 //return ENOTSUP; 113 269 } 114 270 } … … 123 279 * @param address New hub address. 124 280 */ 125 static void set_hub_address(usb_hc_device_t *hc, usb_address_t address) 126 { 281 static void set_hub_address(usb_hc_device_t *hc, usb_address_t address) { 127 282 printf("%s: setting hub address to %d\n", hc->generic->name, address); 128 283 usb_target_t target = {0, 0}; … … 139 294 140 295 rc = usb_hc_async_control_write_setup(hc, target, 141 &setup_packet, sizeof(setup_packet), &handle);296 &setup_packet, sizeof (setup_packet), &handle); 142 297 if (rc != EOK) { 143 298 return; … … 164 319 /** Check changes on all known hubs. 165 320 */ 166 static void check_hub_changes(void) 167 { 321 static void check_hub_changes(void) { 168 322 /* 169 323 * Iterate through all HCs. … … 171 325 link_t *link_hc; 172 326 for (link_hc = hc_list.next; 173 link_hc != &hc_list;174 link_hc = link_hc->next) {327 link_hc != &hc_list; 328 link_hc = link_hc->next) { 175 329 usb_hc_device_t *hc = list_get_instance(link_hc, 176 usb_hc_device_t, link);330 usb_hc_device_t, link); 177 331 /* 178 332 * Iterate through all their hubs. … … 180 334 link_t *link_hub; 181 335 for (link_hub = hc->hubs.next; 182 link_hub != &hc->hubs;183 link_hub = link_hub->next) {336 link_hub != &hc->hubs; 337 link_hub = link_hub->next) { 184 338 usb_hcd_hub_info_t *hub = list_get_instance(link_hub, 185 usb_hcd_hub_info_t, link);339 usb_hcd_hub_info_t, link); 186 340 187 341 /* … … 205 359 */ 206 360 usb_hc_async_interrupt_in(hc, target, 207 change_bitmap, byte_length, &actual_size,208 &handle);361 change_bitmap, byte_length, &actual_size, 362 &handle); 209 363 210 364 usb_hc_async_wait_for(handle); … … 234 388 * @return Error code. 235 389 */ 236 int usb_hcd_main(usb_hc_driver_t *hc) 237 { 390 int usb_hcd_main(usb_hc_driver_t *hc) { 238 391 hc_driver = hc; 239 392 hc_driver_generic.name = hc->name; … … 261 414 * @return Error code. 262 415 */ 263 int usb_hcd_add_root_hub(usb_hc_device_t *dev) 264 { 265 char *id; 266 int rc = asprintf(&id, "usb&hc=%s&hub", dev->generic->name); 267 if (rc <= 0) { 268 return rc; 269 } 270 271 rc = usb_hc_add_child_device(dev->generic, USB_HUB_DEVICE_NAME, id); 272 if (rc != EOK) { 273 free(id); 274 } 275 276 return rc; 277 } 278 279 /** Info about child device. */ 280 struct child_device_info { 281 device_t *parent; 282 const char *name; 283 const char *match_id; 284 }; 285 286 /** Adds a child device fibril worker. */ 287 static int fibril_add_child_device(void *arg) 288 { 289 struct child_device_info *child_info 290 = (struct child_device_info *) arg; 416 int usb_hcd_add_root_hub(usb_hc_device_t *dev) { 291 417 int rc; 292 418 293 device_t *child = create_device(); 419 /* 420 * Announce presence of child device. 421 */ 422 device_t *hub = NULL; 294 423 match_id_t *match_id = NULL; 295 424 296 if (child == NULL) { 425 hub = create_device(); 426 if (hub == NULL) { 297 427 rc = ENOMEM; 298 428 goto failure; 299 429 } 300 child->name = child_info->name;430 hub->name = USB_HUB_DEVICE_NAME; 301 431 302 432 match_id = create_match_id(); … … 305 435 goto failure; 306 436 } 307 match_id->id = child_info->match_id; 308 match_id->score = 10; 309 printf("adding child device with match \"%s\"\n", match_id->id); 310 add_match_id(&child->match_ids, match_id); 311 312 rc = child_device_register(child, child_info->parent); 437 438 char *id; 439 rc = asprintf(&id, "usb&hc=%s&hub", dev->generic->name); 440 if (rc <= 0) { 441 rc = ENOMEM; 442 goto failure; 443 } 444 445 match_id->id = id; 446 match_id->score = 30; 447 448 add_match_id(&hub->match_ids, match_id); 449 450 rc = child_device_register(hub, dev->generic); 313 451 if (rc != EOK) { 314 452 goto failure; 315 453 } 316 454 317 goto leave; 455 printf("%s: registered root hub\n", dev->generic->name); 456 return EOK; 318 457 319 458 failure: 320 if (child != NULL) { 321 child->name = NULL; 322 delete_device(child); 323 } 324 325 if (match_id != NULL) { 326 match_id->id = NULL; 327 delete_match_id(match_id); 328 } 329 330 leave: 331 free(arg); 459 if (hub != NULL) { 460 hub->name = NULL; 461 delete_device(hub); 462 } 463 delete_match_id(match_id); 464 332 465 return rc; 333 }334 335 /** Adds a child.336 * Due to deadlock in devman when parent registers child that oughts to be337 * driven by the same task, the child adding is done in separate fibril.338 * Not optimal, but it works.339 *340 * @param parent Parent device.341 * @param name Device name.342 * @param match_id Match id.343 * @return Error code.344 */345 int usb_hc_add_child_device(device_t *parent, const char *name,346 const char *match_id)347 {348 struct child_device_info *child_info349 = malloc(sizeof(struct child_device_info));350 351 child_info->parent = parent;352 child_info->name = name;353 child_info->match_id = match_id;354 355 fid_t fibril = fibril_create(fibril_add_child_device, child_info);356 if (!fibril) {357 return ENOMEM;358 }359 fibril_add_ready(fibril);360 361 return EOK;362 466 } 363 467
Note:
See TracChangeset
for help on using the changeset viewer.
