Changes in uspace/lib/usb/src/hcdhubd.c [da55d5b:e4dbfda] in mainline
- File:
-
- 1 edited
-
uspace/lib/usb/src/hcdhubd.c (modified) (14 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usb/src/hcdhubd.c
rda55d5b re4dbfda 36 36 #include <usb/devreq.h> 37 37 #include <usbhc_iface.h> 38 #include <usb/descriptor.h>39 38 #include <driver.h> 40 39 #include <bool.h> 41 40 #include <errno.h> 42 #include <usb/classes/hub.h>43 41 44 42 #define USB_HUB_DEVICE_NAME "usbhub" 45 46 #define USB_KBD_DEVICE_NAME "hid"47 48 49 50 43 51 44 /** List of handled host controllers. */ … … 64 57 }; 65 58 66 size_t USB_HUB_MAX_DESCRIPTOR_SIZE = 71;67 68 uint8_t USB_HUB_DESCRIPTOR_TYPE = 0x29;69 70 //*********************************************71 //72 // various utils73 //74 //*********************************************75 76 void * usb_serialize_hub_descriptor(usb_hub_descriptor_t * descriptor) {77 //base size78 size_t size = 7;79 //variable size according to port count80 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 //size84 result[0] = size;85 //descriptor type86 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 code128 //129 //*********************************************130 131 59 static void set_hub_address(usb_hc_device_t *hc, usb_address_t address); 132 60 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 device136 /// @TODO this code is not correct137 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 hc143 //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 info147 148 149 return result;150 }151 152 61 /** Callback when new device is detected and must be handled by this driver. 153 62 * 154 63 * @param dev New device. 155 * @return Error code.hub added, hurrah!\n" 156 */ 157 static int add_device(device_t *dev) { 64 * @return Error code. 65 */ 66 static int add_device(device_t *dev) 67 { 158 68 /* 159 69 * FIXME: use some magic to determine whether hub or another HC … … 167 77 * We are the HC itself. 168 78 */ 169 usb_hc_device_t *hc_dev = malloc(sizeof (usb_hc_device_t));79 usb_hc_device_t *hc_dev = malloc(sizeof(usb_hc_device_t)); 170 80 list_initialize(&hc_dev->link); 171 81 hc_dev->transfer_ops = NULL; … … 189 99 list_append(&hc_dev->link, &hc_list); 190 100 191 //add keyboard192 /// @TODO this is not correct code193 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);230 101 return EOK; 231 232 233 234 102 } else { 235 103 usb_hc_device_t *hc = list_get_instance(hc_list.next, usb_hc_device_t, link); … … 241 109 * connected devices. 242 110 */ 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; 111 112 return ENOTSUP; 269 113 } 270 114 } … … 279 123 * @param address New hub address. 280 124 */ 281 static void set_hub_address(usb_hc_device_t *hc, usb_address_t address) { 125 static void set_hub_address(usb_hc_device_t *hc, usb_address_t address) 126 { 282 127 printf("%s: setting hub address to %d\n", hc->generic->name, address); 283 128 usb_target_t target = {0, 0}; … … 294 139 295 140 rc = usb_hc_async_control_write_setup(hc, target, 296 &setup_packet, sizeof(setup_packet), &handle);141 &setup_packet, sizeof(setup_packet), &handle); 297 142 if (rc != EOK) { 298 143 return; … … 319 164 /** Check changes on all known hubs. 320 165 */ 321 static void check_hub_changes(void) { 166 static void check_hub_changes(void) 167 { 322 168 /* 323 169 * Iterate through all HCs. … … 325 171 link_t *link_hc; 326 172 for (link_hc = hc_list.next; 327 link_hc != &hc_list;328 link_hc = link_hc->next) {173 link_hc != &hc_list; 174 link_hc = link_hc->next) { 329 175 usb_hc_device_t *hc = list_get_instance(link_hc, 330 usb_hc_device_t, link);176 usb_hc_device_t, link); 331 177 /* 332 178 * Iterate through all their hubs. … … 334 180 link_t *link_hub; 335 181 for (link_hub = hc->hubs.next; 336 link_hub != &hc->hubs;337 link_hub = link_hub->next) {182 link_hub != &hc->hubs; 183 link_hub = link_hub->next) { 338 184 usb_hcd_hub_info_t *hub = list_get_instance(link_hub, 339 usb_hcd_hub_info_t, link);185 usb_hcd_hub_info_t, link); 340 186 341 187 /* … … 359 205 */ 360 206 usb_hc_async_interrupt_in(hc, target, 361 change_bitmap, byte_length, &actual_size,362 &handle);207 change_bitmap, byte_length, &actual_size, 208 &handle); 363 209 364 210 usb_hc_async_wait_for(handle); … … 388 234 * @return Error code. 389 235 */ 390 int usb_hcd_main(usb_hc_driver_t *hc) { 236 int usb_hcd_main(usb_hc_driver_t *hc) 237 { 391 238 hc_driver = hc; 392 239 hc_driver_generic.name = hc->name; … … 414 261 * @return Error code. 415 262 */ 416 int usb_hcd_add_root_hub(usb_hc_device_t *dev) { 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; 417 291 int rc; 418 292 419 /* 420 * Announce presence of child device. 421 */ 422 device_t *hub = NULL; 293 device_t *child = create_device(); 423 294 match_id_t *match_id = NULL; 424 295 425 hub = create_device(); 426 if (hub == NULL) { 296 if (child == NULL) { 427 297 rc = ENOMEM; 428 298 goto failure; 429 299 } 430 hub->name = USB_HUB_DEVICE_NAME;300 child->name = child_info->name; 431 301 432 302 match_id = create_match_id(); … … 435 305 goto failure; 436 306 } 437 438 char *id; 439 rc = asprintf(&id, "usb&hc=%s&hub", dev->generic->name); 440 if (rc <= 0) { 441 rc = ENOMEM; 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); 313 if (rc != EOK) { 442 314 goto failure; 443 315 } 444 316 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); 451 if (rc != EOK) { 452 goto failure; 453 } 454 455 printf("%s: registered root hub\n", dev->generic->name); 317 goto leave; 318 319 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); 332 return rc; 333 } 334 335 /** Adds a child. 336 * Due to deadlock in devman when parent registers child that oughts to be 337 * 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_info 349 = 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 456 361 return EOK; 457 458 failure:459 if (hub != NULL) {460 hub->name = NULL;461 delete_device(hub);462 }463 delete_match_id(match_id);464 465 return rc;466 362 } 467 363
Note:
See TracChangeset
for help on using the changeset viewer.
