Changeset 237df2f in mainline for uspace/lib/usbhost/src/ddf_helpers.c
- Timestamp:
- 2013-01-04T16:49:53Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 0e97b4b5
- Parents:
- daf199f
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbhost/src/ddf_helpers.c
rdaf199f r237df2f 35 35 36 36 #include <usb_iface.h> 37 #include <usb/classes/classes.h> 37 38 #include <usb/debug.h> 39 #include <usb/descriptor.h> 40 #include <usb/request.h> 38 41 #include <errno.h> 39 42 #include <str_error.h> 40 43 41 44 #include "ddf_helpers.h" 45 46 #define CTRL_PIPE_MIN_PACKET_SIZE 8 42 47 43 48 extern usbhc_iface_t hcd_iface; … … 119 124 }; 120 125 126 #define GET_DEVICE_DESC(size) \ 127 { \ 128 .request_type = SETUP_REQUEST_TYPE_DEVICE_TO_HOST \ 129 | (USB_REQUEST_TYPE_STANDARD << 5) \ 130 | USB_REQUEST_RECIPIENT_DEVICE, \ 131 .request = USB_DEVREQ_GET_DESCRIPTOR, \ 132 .value = uint16_host2usb(USB_DESCTYPE_DEVICE << 8), \ 133 .index = uint16_host2usb(0), \ 134 .length = uint16_host2usb(size), \ 135 }; 136 137 #define SET_ADDRESS(address) \ 138 { \ 139 .request_type = SETUP_REQUEST_TYPE_HOST_TO_DEVICE \ 140 | (USB_REQUEST_TYPE_STANDARD << 5) \ 141 | USB_REQUEST_RECIPIENT_DEVICE, \ 142 .request = USB_DEVREQ_SET_ADDRESS, \ 143 .value = uint16_host2usb(address), \ 144 .index = uint16_host2usb(0), \ 145 .length = uint16_host2usb(0), \ 146 }; 147 148 static const usb_device_request_setup_packet_t set_address = { 149 .request_type = SETUP_REQUEST_TYPE_DEVICE_TO_HOST 150 | (USB_REQUEST_TYPE_STANDARD << 5) 151 | USB_REQUEST_RECIPIENT_DEVICE, 152 .request = USB_DEVREQ_GET_DESCRIPTOR, 153 .value = uint16_host2usb(USB_DESCTYPE_DEVICE << 8), 154 .index = uint16_host2usb(0), 155 .length = uint16_host2usb(CTRL_PIPE_MIN_PACKET_SIZE), 156 }; 157 121 158 int hcd_ddf_add_usb_device(ddf_dev_t *parent, 122 159 usb_address_t address, usb_speed_t speed, const char *name, … … 127 164 devman_handle_t hc_handle = ddf_fun_get_handle(hc_dev->hc_fun); 128 165 129 char default_name[ 8]; /* usbxyzs */166 char default_name[10] = { 0 }; /* usbxyz-ss */ 130 167 if (!name) { 131 168 snprintf(default_name, sizeof(default_name) - 1, 132 "usb%u %c", address, usb_str_speed(speed)[0]);169 "usb%u-%cs", address, usb_str_speed(speed)[0]); 133 170 name = default_name; 134 171 } … … 169 206 list_append(&info->link, &hc_dev->devices); 170 207 return EOK; 208 } 209 210 211 #define ADD_MATCHID_OR_RETURN(list, sc, str, ...) \ 212 do { \ 213 match_id_t *mid = malloc(sizeof(match_id_t)); \ 214 if (!mid) { \ 215 clean_match_ids(list); \ 216 return ENOMEM; \ 217 } \ 218 char *id = NULL; \ 219 int ret = asprintf(&id, str, ##__VA_ARGS__); \ 220 if (ret < 0) { \ 221 clean_match_ids(list); \ 222 free(mid); \ 223 return ENOMEM; \ 224 } \ 225 mid->score = sc; \ 226 mid->id = id; \ 227 add_match_id(list, mid); \ 228 } while (0) 229 230 231 /* This is a copy of lib/usbdev/src/recognise.c */ 232 static int create_match_ids(match_id_list_t *l, 233 usb_standard_device_descriptor_t *d) 234 { 235 assert(l); 236 assert(d); 237 238 if (d->vendor_id != 0) { 239 /* First, with release number. */ 240 ADD_MATCHID_OR_RETURN(l, 100, 241 "usb&vendor=%#04x&product=%#04x&release=%x.%x", 242 d->vendor_id, d->product_id, (d->device_version >> 8), 243 (d->device_version & 0xff)); 244 245 /* Next, without release number. */ 246 ADD_MATCHID_OR_RETURN(l, 90, "usb&vendor=%#04x&product=%#04x", 247 d->vendor_id, d->product_id); 248 } 249 250 /* Class match id */ 251 ADD_MATCHID_OR_RETURN(l, 50, "usb&class=%s", 252 usb_str_class(d->device_class)); 253 254 /* As a last resort, try fallback driver. */ 255 ADD_MATCHID_OR_RETURN(l, 10, "usb&fallback"); 256 257 return EOK; 258 259 } 260 261 int hcd_ddf_new_device(ddf_dev_t *device) 262 { 263 assert(device); 264 265 hcd_t *hcd = dev_to_hcd(device); 266 assert(hcd); 267 268 usb_speed_t speed = USB_SPEED_MAX; 269 270 /* This checks whether the default address is reserved and gets speed */ 271 int ret = usb_device_manager_get_info_by_address(&hcd->dev_manager, 272 USB_ADDRESS_DEFAULT, NULL, &speed); 273 if (ret != EOK) { 274 return ret; 275 } 276 277 static const usb_target_t default_target = {{ 278 .address = USB_ADDRESS_DEFAULT, 279 .endpoint = 0, 280 }}; 281 282 const usb_address_t address = hcd_request_address(hcd, speed); 283 if (address < 0) 284 return address; 285 286 const usb_target_t target = {{ 287 .address = address, 288 .endpoint = 0, 289 }}; 290 291 /* Add default pipe on default address */ 292 ret = hcd_add_ep(hcd, 293 default_target, USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL, 294 CTRL_PIPE_MIN_PACKET_SIZE, CTRL_PIPE_MIN_PACKET_SIZE); 295 296 if (ret != EOK) { 297 hcd_release_address(hcd, address); 298 return ret; 299 } 300 301 /* Get max packet size for default pipe */ 302 usb_standard_device_descriptor_t desc = { 0 }; 303 static const usb_device_request_setup_packet_t get_device_desc_8 = 304 GET_DEVICE_DESC(CTRL_PIPE_MIN_PACKET_SIZE); 305 306 // TODO CALLBACKS 307 ssize_t got = hcd_send_batch_sync(hcd, default_target, USB_DIRECTION_IN, 308 &desc, CTRL_PIPE_MIN_PACKET_SIZE, *(uint64_t *)&get_device_desc_8, 309 "read first 8 bytes of dev descriptor"); 310 311 if (got != CTRL_PIPE_MIN_PACKET_SIZE) { 312 hcd_remove_ep(hcd, default_target, USB_DIRECTION_BOTH); 313 hcd_release_address(hcd, address); 314 return got < 0 ? got : EOVERFLOW; 315 } 316 317 /* Register EP on the new address */ 318 ret = hcd_add_ep(hcd, target, USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL, 319 desc.max_packet_size, desc.max_packet_size); 320 if (ret != EOK) { 321 hcd_remove_ep(hcd, default_target, USB_DIRECTION_BOTH); 322 hcd_remove_ep(hcd, target, USB_DIRECTION_BOTH); 323 hcd_release_address(hcd, address); 324 return ret; 325 } 326 327 /* Set new address */ 328 const usb_device_request_setup_packet_t set_address = 329 SET_ADDRESS(target.address); 330 331 // TODO CALLBACKS 332 got = hcd_send_batch_sync(hcd, default_target, USB_DIRECTION_OUT, 333 NULL, 0, *(uint64_t *)&set_address, "set address"); 334 335 hcd_remove_ep(hcd, default_target, USB_DIRECTION_BOTH); 336 337 if (got != 0) { 338 hcd_remove_ep(hcd, target, USB_DIRECTION_BOTH); 339 hcd_release_address(hcd, address); 340 return got; 341 } 342 343 /* Get std device descriptor */ 344 static const usb_device_request_setup_packet_t get_device_desc = 345 GET_DEVICE_DESC(sizeof(desc)); 346 347 // TODO CALLBACKS 348 got = hcd_send_batch_sync(hcd, target, USB_DIRECTION_IN, 349 &desc, sizeof(desc), *(uint64_t *)&get_device_desc, 350 "read device descriptor"); 351 if (ret != EOK) { 352 hcd_remove_ep(hcd, target, USB_DIRECTION_BOTH); 353 hcd_release_address(hcd, target.address); 354 return got < 0 ? got : EOVERFLOW; 355 } 356 357 /* Create match ids from the device descriptor */ 358 match_id_list_t mids; 359 init_match_ids(&mids); 360 361 ret = create_match_ids(&mids, &desc); 362 if (ret != EOK) { 363 hcd_remove_ep(hcd, target, USB_DIRECTION_BOTH); 364 hcd_release_address(hcd, target.address); 365 return ret; 366 } 367 368 369 370 /* Register device */ 371 ret = hcd_ddf_add_usb_device(device, address, speed, NULL, &mids); 372 clean_match_ids(&mids); 373 if (ret != EOK) { 374 hcd_remove_ep(hcd, target, USB_DIRECTION_BOTH); 375 hcd_release_address(hcd, target.address); 376 return ret; 377 } 378 379 return ret; 380 } 381 382 /** Announce root hub to the DDF 383 * 384 * @param[in] device Host controller ddf device 385 * @param[in] speed roothub communication speed 386 * @return Error code 387 */ 388 int hcd_ddf_setup_root_hub(ddf_dev_t *device, usb_speed_t speed) 389 { 390 assert(device); 391 hcd_t *hcd = dev_to_hcd(device); 392 assert(hcd); 393 394 hcd_reserve_default_address(hcd, speed); 395 int ret = hcd_ddf_new_device(device); 396 hcd_release_default_address(hcd); 397 return ret; 171 398 } 172 399
Note:
See TracChangeset
for help on using the changeset viewer.