Changes in uspace/lib/usb/src/usbdrvreq.c [82783b0:863d45e] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usb/src/usbdrvreq.c
r82783b0 r863d45e 36 36 #include <errno.h> 37 37 38 /** Prepare USB target for control endpoint. 39 * 40 * @param name Variable name with the USB target. 41 * @param target_address Target USB address. 42 */ 43 #define PREPARE_TARGET(name, target_address) \ 44 usb_target_t name = { \ 45 .address = target_address, \ 46 .endpoint = 0 \ 47 } 48 49 /** Prepare setup packet. 50 * 51 * @param name Variable name with the setup packet. 52 * @param p_direction Data transfer direction. 53 * @param p_type Request type (standard/class/vendor) 54 * @param p_recipient Recipient of the request. 55 * @param p_request Request. 56 * @param p_value wValue field of setup packet. 57 * @param p_index wIndex field of setup packet. 58 * @param p_length Length of extra data. 59 */ 60 #define PREPARE_SETUP_PACKET(name, p_direction, p_type, p_recipient, \ 61 p_request, p_value, p_index, p_length) \ 62 usb_device_request_setup_packet_t setup_packet = { \ 63 .request_type = \ 64 ((p_direction) == USB_DIRECTION_IN ? 128 : 0) \ 65 | ((p_type) << 5) \ 66 | (p_recipient), \ 67 .request = (p_request), \ 68 { .value = (p_value) }, \ 69 .index = (p_index), \ 70 .length = (p_length) \ 71 } 72 73 /** Prepare setup packet. 74 * 75 * @param name Variable name with the setup packet. 76 * @param p_direction Data transfer direction. 77 * @param p_type Request type (standard/class/vendor) 78 * @param p_recipient Recipient of the request. 79 * @param p_request Request. 80 * @param p_value_low wValue field of setup packet (low byte). 81 * @param p_value_high wValue field of setup packet (high byte). 82 * @param p_index wIndex field of setup packet. 83 * @param p_length Length of extra data. 84 */ 85 #define PREPARE_SETUP_PACKET_LOHI(name, p_direction, p_type, p_recipient, \ 86 p_request, p_value_low, p_value_high, p_index, p_length) \ 87 PREPARE_SETUP_PACKET(name, p_direction, p_type, p_recipient, \ 88 p_request, (p_value_low) | ((p_value_high) << 8), \ 89 p_index, p_length) 90 91 /** Retrieve status of a USB device. 92 * 93 * @param[in] hc_phone Open phone to HC driver. 94 * @param[in] address Device address. 95 * @param[in] recipient Recipient of the request. 96 * @param[in] recipient_index Index of @p recipient. 97 * @param[out] status Status (see figure 9-4 in USB 1.1 specification). 98 * @return Error code. 99 */ 100 int usb_drv_req_get_status(int hc_phone, usb_address_t address, 101 usb_request_recipient_t recipient, uint16_t recipient_index, 102 uint16_t *status) 103 { 104 if (status == NULL) { 105 return EBADMEM; 106 } 107 108 PREPARE_TARGET(target, address); 109 110 PREPARE_SETUP_PACKET(setup_packet, 111 USB_DIRECTION_IN, USB_REQUEST_TYPE_STANDARD, 112 recipient, USB_DEVREQ_GET_STATUS, 0, recipient_index, 2); 113 114 size_t transfered; 115 uint16_t tmp_status; 116 int rc = usb_drv_psync_control_read(hc_phone, target, 117 &setup_packet, sizeof(setup_packet), &tmp_status, 2, &transfered); 118 if (rc != EOK) { 119 return rc; 120 } 121 if (transfered != 2) { 122 return ERANGE; 123 } 124 125 *status = tmp_status; 126 127 return EOK; 128 } 129 130 /** Clear or disable USB device feature. 131 * 132 * @param[in] hc_phone Open phone to HC driver. 133 * @param[in] address Device address. 134 * @param[in] recipient Recipient of the request. 135 * @param[in] selector Feature selector. 136 * @param[in] index Index of @p recipient. 137 * @return Error code. 138 */ 139 int usb_drv_req_clear_feature(int hc_phone, usb_address_t address, 140 usb_request_recipient_t recipient, 141 uint16_t selector, uint16_t index) 142 { 143 PREPARE_TARGET(target, address); 144 145 PREPARE_SETUP_PACKET(setup_packet, 146 USB_DIRECTION_OUT, USB_REQUEST_TYPE_STANDARD, 147 recipient, USB_DEVREQ_CLEAR_FEATURE, selector, index, 0); 148 149 int rc = usb_drv_psync_control_write(hc_phone, target, 150 &setup_packet, sizeof(setup_packet), NULL, 0); 151 152 return rc; 153 } 154 155 /** Set or enable USB device feature. 156 * 157 * @param[in] hc_phone Open phone to HC driver. 158 * @param[in] address Device address. 159 * @param[in] recipient Recipient of the request. 160 * @param[in] selector Feature selector. 161 * @param[in] index Index of @p recipient. 162 * @return Error code. 163 */ 164 int usb_drv_req_set_feature(int hc_phone, usb_address_t address, 165 usb_request_recipient_t recipient, 166 uint16_t selector, uint16_t index) 167 { 168 PREPARE_TARGET(target, address); 169 170 PREPARE_SETUP_PACKET(setup_packet, 171 USB_DIRECTION_OUT, USB_REQUEST_TYPE_STANDARD, 172 recipient, USB_DEVREQ_SET_FEATURE, selector, index, 0); 173 174 int rc = usb_drv_psync_control_write(hc_phone, target, 175 &setup_packet, sizeof(setup_packet), NULL, 0); 176 177 return rc; 178 } 179 38 180 /** Change address of connected device. 39 181 * … … 44 186 * @see usb_drv_bind_address 45 187 * 46 * @param phone Open phone to HC driver.47 * @param old_address Current address.48 * @param address Address to be set.188 * @param[in] phone Open phone to HC driver. 189 * @param[in] old_address Current address. 190 * @param[in] address Address to be set. 49 191 * @return Error code. 50 192 */ … … 52 194 usb_address_t new_address) 53 195 { 54 /* Prepare the target. */ 55 usb_target_t target = { 56 .address = old_address, 57 .endpoint = 0 58 }; 59 60 /* Prepare the setup packet. */ 61 usb_device_request_setup_packet_t setup_packet = { 62 .request_type = 0, 63 .request = USB_DEVREQ_SET_ADDRESS, 64 .index = 0, 65 .length = 0, 66 }; 67 setup_packet.value = new_address; 196 PREPARE_TARGET(target, old_address); 197 198 PREPARE_SETUP_PACKET(setup_packet, USB_DIRECTION_OUT, 199 USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE, 200 USB_DEVREQ_SET_ADDRESS, new_address, 0, 0); 68 201 69 202 int rc = usb_drv_psync_control_write(phone, target, … … 73 206 } 74 207 208 /** Retrieve USB descriptor of connected USB device. 209 * 210 * @param[in] hc_phone Open phone to HC driver. 211 * @param[in] address Device address. 212 * @param[in] request_type Request type (standard/class/vendor). 213 * @param[in] descriptor_type Descriptor type (device/configuration/HID/...). 214 * @param[in] descriptor_index Descriptor index. 215 * @param[in] language Language index. 216 * @param[out] buffer Buffer where to store the retrieved descriptor. 217 * @param[in] size Size of the @p buffer. 218 * @param[out] actual_size Number of bytes actually transferred. 219 * @return Error code. 220 */ 221 int usb_drv_req_get_descriptor(int hc_phone, usb_address_t address, 222 usb_request_type_t request_type, 223 uint8_t descriptor_type, uint8_t descriptor_index, 224 uint16_t language, 225 void *buffer, size_t size, size_t *actual_size) 226 { 227 if (buffer == NULL) { 228 return EBADMEM; 229 } 230 if (size == 0) { 231 return EINVAL; 232 } 233 234 // FIXME: check that size is not too big 235 236 PREPARE_TARGET(target, address); 237 238 PREPARE_SETUP_PACKET_LOHI(setup_packet, USB_DIRECTION_IN, 239 request_type, USB_REQUEST_RECIPIENT_DEVICE, 240 USB_DEVREQ_GET_DESCRIPTOR, descriptor_index, descriptor_type, 241 language, size); 242 243 int rc = usb_drv_psync_control_read(hc_phone, target, 244 &setup_packet, sizeof(setup_packet), 245 buffer, size, actual_size); 246 247 return rc; 248 } 249 75 250 /** Retrieve device descriptor of connected USB device. 76 251 * 77 252 * @param[in] phone Open phone to HC driver. 78 * @param[in] address Device USBaddress.253 * @param[in] address Device address. 79 254 * @param[out] descriptor Storage for the device descriptor. 80 255 * @return Error code. … … 87 262 return EBADMEM; 88 263 } 89 90 /* Prepare the target. */ 91 usb_target_t target = { 92 .address = address, 93 .endpoint = 0 94 }; 95 96 /* Prepare the setup packet. */ 97 usb_device_request_setup_packet_t setup_packet = { 98 .request_type = 128, 99 .request = USB_DEVREQ_GET_DESCRIPTOR, 100 .index = 0, 101 .length = sizeof(usb_standard_device_descriptor_t) 102 }; 103 setup_packet.value_high = USB_DESCTYPE_DEVICE; 104 setup_packet.value_low = 0; 105 106 /* Prepare local descriptor. */ 264 107 265 size_t actually_transferred = 0; 108 266 usb_standard_device_descriptor_t descriptor_tmp; 109 110 /* Perform the control read transaction. */ 111 int rc = usb_drv_psync_control_read(phone, target, 112 &setup_packet, sizeof(setup_packet), 113 &descriptor_tmp, sizeof(descriptor_tmp), &actually_transferred); 267 int rc = usb_drv_req_get_descriptor(phone, address, 268 USB_REQUEST_TYPE_STANDARD, 269 USB_DESCTYPE_DEVICE, 0, 270 0, 271 &descriptor_tmp, sizeof(descriptor_tmp), 272 &actually_transferred); 114 273 115 274 if (rc != EOK) { … … 137 296 * 138 297 * @param[in] phone Open phone to HC driver. 139 * @param[in] address Device USBaddress.298 * @param[in] address Device address. 140 299 * @param[in] index Configuration descriptor index. 141 300 * @param[out] descriptor Storage for the configuration descriptor. … … 150 309 return EBADMEM; 151 310 } 152 153 /* Prepare the target. */ 154 usb_target_t target = { 155 .address = address, 156 .endpoint = 0 157 }; 158 159 /* Prepare the setup packet. */ 160 usb_device_request_setup_packet_t setup_packet = { 161 .request_type = 128, 162 .request = USB_DEVREQ_GET_DESCRIPTOR, 163 .index = 0, 164 .length = sizeof(usb_standard_configuration_descriptor_t) 165 }; 166 setup_packet.value_high = USB_DESCTYPE_CONFIGURATION; 167 setup_packet.value_low = index; 168 169 /* Prepare local descriptor. */ 311 170 312 size_t actually_transferred = 0; 171 313 usb_standard_configuration_descriptor_t descriptor_tmp; 172 173 /* Perform the control read transaction. */ 174 int rc = usb_drv_psync_control_read(phone, target, 175 &setup_packet, sizeof(setup_packet), 176 &descriptor_tmp, sizeof(descriptor_tmp), &actually_transferred); 314 int rc = usb_drv_req_get_descriptor(phone, address, 315 USB_REQUEST_TYPE_STANDARD, 316 USB_DESCTYPE_CONFIGURATION, 0, 317 0, 318 &descriptor_tmp, sizeof(descriptor_tmp), 319 &actually_transferred); 177 320 178 321 if (rc != EOK) { … … 195 338 * 196 339 * @warning The @p buffer might be touched (i.e. its contents changed) 197 * even when error occur res.340 * even when error occurs. 198 341 * 199 342 * @param[in] phone Open phone to HC driver. 200 * @param[in] address Device USBaddress.343 * @param[in] address Device address. 201 344 * @param[in] index Configuration descriptor index. 202 345 * @param[out] buffer Buffer for the whole configuration descriptor. … … 210 353 void *buffer, size_t buffer_size, size_t *actual_buffer_size) 211 354 { 212 if (buffer == NULL) { 355 int rc = usb_drv_req_get_descriptor(phone, address, 356 USB_REQUEST_TYPE_STANDARD, 357 USB_DESCTYPE_CONFIGURATION, 0, 358 0, 359 buffer, buffer_size, 360 actual_buffer_size); 361 362 return rc; 363 } 364 365 /** Update existing descriptor of a USB device. 366 * 367 * @param[in] hc_phone Open phone to HC driver. 368 * @param[in] address Device address. 369 * @param[in] descriptor_type Descriptor type (device/configuration/...). 370 * @param[in] descriptor_index Descriptor index. 371 * @param[in] language Language index. 372 * @param[in] descriptor Actual descriptor data. 373 * @param[in] descriptor_size Descriptor size. 374 * @return Error code. 375 */ 376 int usb_drv_req_set_descriptor(int hc_phone, usb_address_t address, 377 uint8_t descriptor_type, uint8_t descriptor_index, 378 uint16_t language, 379 void *descriptor, size_t descriptor_size) 380 { 381 // FIXME: check that descriptor is not too big 382 383 PREPARE_TARGET(target, address); 384 385 PREPARE_SETUP_PACKET_LOHI(setup_packet, USB_DIRECTION_OUT, 386 USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE, 387 USB_DEVREQ_SET_DESCRIPTOR, descriptor_index, descriptor_type, 388 language, descriptor_size); 389 390 int rc = usb_drv_psync_control_write(hc_phone, target, 391 &setup_packet, sizeof(setup_packet), 392 descriptor, descriptor_size); 393 394 return rc; 395 } 396 397 /** Determine current configuration value of USB device. 398 * 399 * @param[in] hc_phone Open phone to HC driver. 400 * @param[in] address Device address. 401 * @param[out] configuration_value Current configuration value. 402 * @return Error code. 403 */ 404 int usb_drv_req_get_configuration(int hc_phone, usb_address_t address, 405 uint8_t *configuration_value) 406 { 407 if (configuration_value == NULL) { 213 408 return EBADMEM; 214 409 } 215 410 216 /* Prepare the target. */ 217 usb_target_t target = { 218 .address = address, 219 .endpoint = 0 220 }; 221 222 /* Prepare the setup packet. */ 223 usb_device_request_setup_packet_t setup_packet = { 224 .request_type = 128, 225 .request = USB_DEVREQ_GET_DESCRIPTOR, 226 .index = 0, 227 .length = buffer_size 228 }; 229 setup_packet.value_high = USB_DESCTYPE_CONFIGURATION; 230 setup_packet.value_low = index; 231 232 /* Perform the control read transaction. */ 233 int rc = usb_drv_psync_control_read(phone, target, 234 &setup_packet, sizeof(setup_packet), 235 buffer, buffer_size, actual_buffer_size); 236 237 return rc; 238 } 239 411 PREPARE_TARGET(target, address); 412 413 PREPARE_SETUP_PACKET(setup_packet, USB_DIRECTION_IN, 414 USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE, 415 USB_DEVREQ_GET_CONFIGURATION, 0, 0, 1); 416 417 uint8_t value; 418 size_t transfered; 419 int rc = usb_drv_psync_control_read(hc_phone, target, 420 &setup_packet, sizeof(setup_packet), &value, 1, &transfered); 421 422 if (rc != EOK) { 423 return rc; 424 } 425 426 if (transfered != 1) { 427 return ERANGE; 428 } 429 430 *configuration_value = value; 431 432 return EOK; 433 } 434 435 /** Set configuration of USB device. 436 * 437 * @param[in] hc_phone Open phone to HC driver. 438 * @param[in] address Device address. 439 * @param[in] configuration_value New configuration value. 440 * @return Error code. 441 */ 442 int usb_drv_req_set_configuration(int hc_phone, usb_address_t address, 443 uint8_t configuration_value) 444 { 445 PREPARE_TARGET(target, address); 446 447 PREPARE_SETUP_PACKET_LOHI(setup_packet, USB_DIRECTION_OUT, 448 USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE, 449 USB_DEVREQ_SET_CONFIGURATION, configuration_value, 0, 450 0, 0); 451 452 int rc = usb_drv_psync_control_write(hc_phone, target, 453 &setup_packet, sizeof(setup_packet), NULL, 0); 454 455 return rc; 456 } 457 458 /** Determine alternate setting of USB device interface. 459 * 460 * @param[in] hc_phone Open phone to HC driver. 461 * @param[in] address Device address. 462 * @param[in] interface_index Interface index. 463 * @param[out] alternate_setting Value of alternate setting. 464 * @return Error code. 465 */ 466 int usb_drv_req_get_interface(int hc_phone, usb_address_t address, 467 uint16_t interface_index, uint8_t *alternate_setting) 468 { 469 if (alternate_setting == NULL) { 470 return EBADMEM; 471 } 472 473 PREPARE_TARGET(target, address); 474 475 PREPARE_SETUP_PACKET(setup_packet, USB_DIRECTION_IN, 476 USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_INTERFACE, 477 USB_DEVREQ_GET_INTERFACE, 0, interface_index, 1); 478 479 uint8_t alternate; 480 size_t transfered; 481 int rc = usb_drv_psync_control_read(hc_phone, target, 482 &setup_packet, sizeof(setup_packet), &alternate, 1, &transfered); 483 484 if (rc != EOK) { 485 return rc; 486 } 487 488 if (transfered != 1) { 489 return ERANGE; 490 } 491 492 *alternate_setting = alternate; 493 494 return EOK; 495 } 496 497 /** Select an alternate setting of USB device interface. 498 * 499 * @param[in] hc_phone Open phone to HC driver. 500 * @param[in] address Device address. 501 * @param[in] interface_index Interface index. 502 * @param[in] alternate_setting Value of alternate setting. 503 * @return Error code. 504 */ 505 int usb_drv_req_set_interface(int hc_phone, usb_address_t address, 506 uint16_t interface_index, uint8_t alternate_setting) 507 { 508 PREPARE_TARGET(target, address); 509 510 PREPARE_SETUP_PACKET_LOHI(setup_packet, USB_DIRECTION_OUT, 511 USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_INTERFACE, 512 USB_DEVREQ_SET_INTERFACE, alternate_setting, 0, 513 0, 0); 514 515 int rc = usb_drv_psync_control_write(hc_phone, target, 516 &setup_packet, sizeof(setup_packet), NULL, 0); 517 518 return rc; 519 } 240 520 241 521 /**
Note:
See TracChangeset
for help on using the changeset viewer.