Changeset 237df2f in mainline
- 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
- Location:
- uspace/lib
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usb/include/usb/request.h
rdaf199f r237df2f 79 79 uint8_t request_type; 80 80 #define SETUP_REQUEST_TYPE_DEVICE_TO_HOST (1 << 7) 81 #define SETUP_REQUEST_TYPE_HOST_TO_DEVICE (0 << 7) 81 82 #define SETUP_REQUEST_TYPE_GET_TYPE(rt) ((rt >> 5) & 0x3) 82 83 #define SETUP_REQUEST_TYPE_GET_RECIPIENT(rec) (rec & 0x1f) -
uspace/lib/usbhost/include/usb/host/ddf_helpers.h
rdaf199f r237df2f 45 45 int hcd_ddf_setup_device(ddf_dev_t *device, ddf_fun_t **hc_fun, 46 46 usb_speed_t max_speed, size_t bw, bw_count_func_t bw_count); 47 int hcd_ddf_setup_root_hub(ddf_dev_t *dev, usb_speed_t speed); 47 48 int hcd_ddf_setup_hub(ddf_dev_t *dev, usb_address_t *address); 49 int hcd_ddf_new_device(ddf_dev_t *device); 48 50 49 51 hcd_t *dev_to_hcd(ddf_dev_t *dev); -
uspace/lib/usbhost/include/usb/host/hcd.h
rdaf199f r237df2f 88 88 int hcd_reserve_default_address(hcd_t *hcd, usb_speed_t speed); 89 89 90 static inline int hcd_release_default_address(hcd_t *hcd , usb_address_t address)90 static inline int hcd_release_default_address(hcd_t *hcd) 91 91 { 92 92 return hcd_release_address(hcd, USB_ADDRESS_DEFAULT); … … 103 103 usbhc_iface_transfer_out_callback_t out, void *arg, const char* name); 104 104 105 ssize_t hcd_send_batch_sync(hcd_t *hcd, usb_target_t target, 106 usb_direction_t dir, void *data, size_t size, uint64_t setup_data, 107 const char* name); 108 105 109 #endif 106 110 /** -
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 -
uspace/lib/usbhost/src/hcd.c
rdaf199f r237df2f 253 253 } 254 254 255 typedef struct { 256 volatile unsigned done; 257 int ret; 258 size_t size; 259 } sync_data_t; 260 261 static void transfer_in_cb(int ret, size_t size, void* data) 262 { 263 sync_data_t *d = data; 264 assert(d); 265 d->ret = ret; 266 d->done = 1; 267 d->size = size; 268 } 269 270 static void transfer_out_cb(int ret, void* data) 271 { 272 sync_data_t *d = data; 273 assert(data); 274 d->ret = ret; 275 d->done = 1; 276 } 277 278 /** this is really ugly version of sync usb communication */ 279 ssize_t hcd_send_batch_sync( 280 hcd_t *hcd, usb_target_t target, usb_direction_t dir, 281 void *data, size_t size, uint64_t setup_data, const char* name) 282 { 283 assert(hcd); 284 sync_data_t sd = { .done = 0, .ret = EINPROGRESS, .size = size }; 285 286 int ret = hcd_send_batch(hcd, target, dir, data, size, setup_data, 287 dir == USB_DIRECTION_IN ? transfer_in_cb : NULL, 288 dir == USB_DIRECTION_OUT ? transfer_out_cb : NULL, &sd, name); 289 if (ret != EOK) 290 return ret; 291 do { 292 async_usleep(1000); 293 } while (!sd.done); 294 if (sd.ret == EOK) 295 return sd.size; 296 return sd.ret; 297 } 298 299 255 300 /** 256 301 * @}
Note:
See TracChangeset
for help on using the changeset viewer.