Changeset ef75332 in mainline for uspace/lib/usb/src/hcdhubd.c
- Timestamp:
- 2010-11-27T08:07:18Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 36bcf84f
- Parents:
- 8e423a2d (diff), dac43be (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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usb/src/hcdhubd.c
r8e423a2d ref75332 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> … … 42 42 #include <usb/classes/hub.h> 43 43 44 #define USB_HUB_DEVICE_NAME "usbhub" 45 46 #define USB_KBD_DEVICE_NAME "hid" 47 48 49 50 51 /** List of handled host controllers. */ 52 static LIST_INITIALIZE(hc_list); 53 54 /** Our HC driver. */ 55 static usb_hc_driver_t *hc_driver = NULL; 56 57 static usbhc_iface_t usb_interface = { 58 .interrupt_out = NULL, 59 .interrupt_in = NULL 60 }; 61 62 static device_ops_t usb_device_ops = { 63 .interfaces[USBHC_DEV_IFACE] = &usb_interface 64 }; 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 131 static void set_hub_address(usb_hc_device_t *hc, usb_address_t address); 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 } 44 #include "hcdhubd_private.h" 151 45 152 46 /** Callback when new device is detected and must be handled by this driver. 153 47 * 154 48 * @param dev New device. 155 * @return Error code. hub added, hurrah!\n"49 * @return Error code. 156 50 */ 157 51 static int add_device(device_t *dev) { 158 /*159 * FIXME: use some magic to determine whether hub or another HC160 * was connected.161 */162 52 bool is_hc = str_cmp(dev->name, USB_HUB_DEVICE_NAME) != 0; 163 53 printf("%s: add_device(name=\"%s\")\n", hc_driver->name, dev->name); … … 167 57 * We are the HC itself. 168 58 */ 169 usb_hc_device_t *hc_dev = malloc(sizeof (usb_hc_device_t)); 170 list_initialize(&hc_dev->link); 171 hc_dev->transfer_ops = NULL; 172 173 hc_dev->generic = dev; 174 dev->ops = &usb_device_ops; 175 hc_dev->generic->driver_data = hc_dev; 176 177 int rc = hc_driver->add_hc(hc_dev); 178 if (rc != EOK) { 179 free(hc_dev); 180 return rc; 181 } 182 59 return usb_add_hc_device(dev); 60 } else { 183 61 /* 184 * FIXME: The following line causes devman to hang. 185 * Will investigate later why. 186 */ 187 // add_device_to_class(dev, "usbhc"); 188 189 list_append(&hc_dev->link, &hc_list); 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); 230 return EOK; 231 232 233 234 } else { 235 usb_hc_device_t *hc = list_get_instance(hc_list.next, usb_hc_device_t, link); 236 set_hub_address(hc, 5); 237 238 /* 239 * We are some (probably deeply nested) hub. 62 * We are some (maybe deeply nested) hub. 240 63 * Thus, assign our own operations and explore already 241 64 * connected devices. 242 65 */ 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; 269 } 270 } 271 272 /** Sample usage of usb_hc_async functions. 273 * This function sets hub address using standard SET_ADDRESS request. 274 * 275 * @warning This function shall be removed once you are familiar with 276 * the usb_hc_ API. 277 * 278 * @param hc Host controller the hub belongs to. 279 * @param address New hub address. 280 */ 281 static void set_hub_address(usb_hc_device_t *hc, usb_address_t address) { 282 printf("%s: setting hub address to %d\n", hc->generic->name, address); 283 usb_target_t target = {0, 0}; 284 usb_handle_t handle; 285 int rc; 286 287 usb_device_request_setup_packet_t setup_packet = { 288 .request_type = 0, 289 .request = USB_DEVREQ_SET_ADDRESS, 290 .index = 0, 291 .length = 0, 292 }; 293 setup_packet.value = address; 294 295 rc = usb_hc_async_control_write_setup(hc, target, 296 &setup_packet, sizeof (setup_packet), &handle); 297 if (rc != EOK) { 298 return; 299 } 300 301 rc = usb_hc_async_wait_for(handle); 302 if (rc != EOK) { 303 return; 304 } 305 306 rc = usb_hc_async_control_write_status(hc, target, &handle); 307 if (rc != EOK) { 308 return; 309 } 310 311 rc = usb_hc_async_wait_for(handle); 312 if (rc != EOK) { 313 return; 314 } 315 316 printf("%s: hub address changed\n", hc->generic->name); 317 } 318 319 /** Check changes on all known hubs. 320 */ 321 static void check_hub_changes(void) { 322 /* 323 * Iterate through all HCs. 324 */ 325 link_t *link_hc; 326 for (link_hc = hc_list.next; 327 link_hc != &hc_list; 328 link_hc = link_hc->next) { 329 usb_hc_device_t *hc = list_get_instance(link_hc, 330 usb_hc_device_t, link); 331 /* 332 * Iterate through all their hubs. 333 */ 334 link_t *link_hub; 335 for (link_hub = hc->hubs.next; 336 link_hub != &hc->hubs; 337 link_hub = link_hub->next) { 338 usb_hcd_hub_info_t *hub = list_get_instance(link_hub, 339 usb_hcd_hub_info_t, link); 340 341 /* 342 * Check status change pipe of this hub. 343 */ 344 usb_target_t target = { 345 .address = hub->device->address, 346 .endpoint = 1 347 }; 348 349 // FIXME: count properly 350 size_t byte_length = (hub->port_count / 8) + 1; 351 352 void *change_bitmap = malloc(byte_length); 353 size_t actual_size; 354 usb_handle_t handle; 355 356 /* 357 * Send the request. 358 * FIXME: check returned value for possible errors 359 */ 360 usb_hc_async_interrupt_in(hc, target, 361 change_bitmap, byte_length, &actual_size, 362 &handle); 363 364 usb_hc_async_wait_for(handle); 365 366 /* 367 * TODO: handle the changes. 368 */ 369 } 66 return usb_add_hub_device(dev); 370 67 } 371 68 } … … 391 88 hc_driver = hc; 392 89 hc_driver_generic.name = hc->name; 393 394 /*395 * Launch here fibril that will periodically check all396 * attached hubs for status change.397 * WARN: This call will effectively do nothing.398 */399 check_hub_changes();400 90 401 91 /*
Note:
See TracChangeset
for help on using the changeset viewer.