Changes in uspace/drv/ohci/iface.c [6bec59b:1998bcd] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/ohci/iface.c
r6bec59b r1998bcd 1 1 /* 2 * Copyright (c) 2011 Vojtech Horky , Jan Vesely2 * Copyright (c) 2011 Vojtech Horky 3 3 * All rights reserved. 4 4 * … … 30 30 */ 31 31 /** @file 32 * @brief OHCI driver hc interface implementation32 * USB-HC interface implementation. 33 33 */ 34 34 #include <ddf/driver.h> … … 36 36 37 37 #include <usb/debug.h> 38 #include <usb/host/endpoint.h>39 38 40 39 #include "iface.h" 41 40 #include "hc.h" 42 41 43 static inline int setup_batch( 44 ddf_fun_t *fun, usb_target_t target, usb_direction_t direction, 45 void *data, size_t size, void * setup_data, size_t setup_size, 46 usbhc_iface_transfer_in_callback_t in, 47 usbhc_iface_transfer_out_callback_t out, void *arg, const char* name, 48 hc_t **hc, usb_transfer_batch_t **batch) 49 { 50 assert(hc); 51 assert(batch); 52 assert(fun); 53 *hc = fun_to_hc(fun); 54 assert(*hc); 55 56 size_t res_bw; 57 endpoint_t *ep = usb_endpoint_manager_get_ep(&(*hc)->ep_manager, 58 target.address, target.endpoint, direction, &res_bw); 59 if (ep == NULL) { 60 usb_log_error("Endpoint(%d:%d) not registered for %s.\n", 61 target.address, target.endpoint, name); 62 return ENOENT; 63 } 64 65 const size_t bw = bandwidth_count_usb11( 66 ep->speed, ep->transfer_type, size, ep->max_packet_size); 67 if (res_bw < bw) { 68 usb_log_error("Endpoint(%d:%d) %s needs %zu bw " 69 "but only %zu is reserved.\n", 70 name, target.address, target.endpoint, bw, res_bw); 71 return ENOSPC; 72 } 73 usb_log_debug("%s %d:%d %zu(%zu).\n", 74 name, target.address, target.endpoint, size, ep->max_packet_size); 75 76 assert(ep->speed == 77 usb_device_keeper_get_speed(&(*hc)->manager, target.address)); 78 // assert(ep->max_packet_size == max_packet_size); 79 // assert(ep->transfer_type == USB_TRANSFER_CONTROL); 80 81 *batch = 82 batch_get(fun, ep, data, size, setup_data, setup_size, 83 in, out, arg); 84 if (!batch) 85 return ENOMEM; 86 return EOK; 87 } 88 89 90 /** Reserve default address interface function 91 * 92 * @param[in] fun DDF function that was called. 93 * @param[in] speed Speed to associate with the new default address. 42 #define UNSUPPORTED(methodname) \ 43 usb_log_warning("Unsupported interface method `%s()' in %s:%d.\n", \ 44 methodname, __FILE__, __LINE__) 45 46 /** Reserve default address. 47 * 48 * This function may block the caller. 49 * 50 * @param[in] fun Device function the action was invoked on. 51 * @param[in] speed Speed of the device for which the default address is 52 * reserved. 94 53 * @return Error code. 95 54 */ … … 102 61 usb_device_keeper_reserve_default_address(&hc->manager, speed); 103 62 return EOK; 104 #if 0 105 endpoint_t *ep = malloc(sizeof(endpoint_t)); 106 if (ep == NULL) 107 return ENOMEM; 108 const size_t max_packet_size = speed == USB_SPEED_LOW ? 8 : 64; 109 endpoint_init(ep, USB_TRANSFER_CONTROL, speed, max_packet_size); 110 int ret; 111 try_retgister: 112 ret = usb_endpoint_manager_register_ep(&hc->ep_manager, 113 USB_ADDRESS_DEFAULT, 0, USB_DIRECTION_BOTH, ep, endpoint_destroy, 0); 114 if (ret == EEXISTS) { 115 async_usleep(1000); 116 goto try_retgister; 117 } 118 if (ret != EOK) { 119 endpoint_destroy(ep); 120 } 121 return ret; 122 #endif 123 } 124 /*----------------------------------------------------------------------------*/ 125 /** Release default address interface function 126 * 127 * @param[in] fun DDF function that was called. 63 } 64 /*----------------------------------------------------------------------------*/ 65 /** Release default address. 66 * 67 * @param[in] fun Device function the action was invoked on. 128 68 * @return Error code. 129 69 */ … … 134 74 assert(hc); 135 75 usb_log_debug("Default address release.\n"); 136 // return usb_endpoint_manager_unregister_ep(&hc->ep_manager,137 // USB_ADDRESS_DEFAULT, 0, USB_DIRECTION_BOTH);138 76 usb_device_keeper_release_default_address(&hc->manager); 139 77 return EOK; 140 78 } 141 79 /*----------------------------------------------------------------------------*/ 142 /** Request address interface function143 * 144 * @param[in] fun D DF function that was called.145 * @param[in] speed Speed to associate with the new defaultaddress.146 * @param[out] address Place to write a newaddress.80 /** Found free USB address. 81 * 82 * @param[in] fun Device function the action was invoked on. 83 * @param[in] speed Speed of the device that will get this address. 84 * @param[out] address Non-null pointer where to store the free address. 147 85 * @return Error code. 148 86 */ … … 163 101 } 164 102 /*----------------------------------------------------------------------------*/ 165 /** Bind address interface function166 * 167 * @param[in] fun D DF function that was called.168 * @param[in] address Address of the device169 * @param[in] handle Devman handle of the device driver.103 /** Bind USB address with device devman handle. 104 * 105 * @param[in] fun Device function the action was invoked on. 106 * @param[in] address USB address of the device. 107 * @param[in] handle Devman handle of the device. 170 108 * @return Error code. 171 109 */ 172 110 static int bind_address( 173 ddf_fun_t *fun, usb_address_t address, devman_handle_t handle)111 ddf_fun_t *fun, usb_address_t address, devman_handle_t handle) 174 112 { 175 113 assert(fun); … … 181 119 } 182 120 /*----------------------------------------------------------------------------*/ 183 /** Release address interface function184 * 185 * @param[in] fun D DF function that was called.121 /** Release previously requested address. 122 * 123 * @param[in] fun Device function the action was invoked on. 186 124 * @param[in] address USB address to be released. 187 125 * @return Error code. … … 197 135 } 198 136 /*----------------------------------------------------------------------------*/ 199 static int register_endpoint( 200 ddf_fun_t *fun, usb_address_t address, usb_endpoint_t endpoint, 137 /** Register endpoint for bandwidth reservation. 138 * 139 * @param[in] fun Device function the action was invoked on. 140 * @param[in] address USB address of the device. 141 * @param[in] ep_speed Endpoint speed (invalid means to use device one). 142 * @param[in] endpoint Endpoint number. 143 * @param[in] transfer_type USB transfer type. 144 * @param[in] direction Endpoint data direction. 145 * @param[in] max_packet_size Max packet size of the endpoint. 146 * @param[in] interval Polling interval. 147 * @return Error code. 148 */ 149 static int register_endpoint(ddf_fun_t *fun, 150 usb_address_t address, usb_speed_t ep_speed, usb_endpoint_t endpoint, 201 151 usb_transfer_type_t transfer_type, usb_direction_t direction, 202 152 size_t max_packet_size, unsigned int interval) 203 153 { 204 hc_t *hc = fun_to_hc(fun); 205 assert(hc); 206 const usb_speed_t speed = 207 usb_device_keeper_get_speed(&hc->manager, address); 208 const size_t size = 209 (transfer_type == USB_TRANSFER_INTERRUPT 210 || transfer_type == USB_TRANSFER_ISOCHRONOUS) ? 211 max_packet_size : 0; 212 int ret; 213 214 endpoint_t *ep = malloc(sizeof(endpoint_t)); 215 if (ep == NULL) 216 return ENOMEM; 217 ret = endpoint_init(ep, address, endpoint, direction, 218 transfer_type, speed, max_packet_size); 219 if (ret != EOK) { 220 free(ep); 221 return ret; 222 } 223 154 assert(fun); 155 hc_t *hc = fun_to_hc(fun); 156 assert(hc); 157 if (address == hc->rh.address) 158 return EOK; 159 usb_speed_t speed = usb_device_keeper_get_speed(&hc->manager, address); 160 if (speed >= USB_SPEED_MAX) { 161 speed = ep_speed; 162 } 163 const size_t size = max_packet_size; 224 164 usb_log_debug("Register endpoint %d:%d %s %s(%d) %zu(%zu) %u.\n", 225 165 address, endpoint, usb_str_transfer_type(transfer_type), 226 166 usb_str_speed(speed), direction, size, max_packet_size, interval); 227 228 ret = usb_endpoint_manager_register_ep(&hc->ep_manager, ep, size); 229 if (ret != EOK) { 230 endpoint_destroy(ep); 231 } else { 232 usb_device_keeper_add_ep(&hc->manager, address, ep); 233 } 234 return ret; 235 } 236 /*----------------------------------------------------------------------------*/ 167 // TODO use real endpoint here! 168 return usb_endpoint_manager_register_ep(&hc->ep_manager,NULL, 0); 169 } 170 /*----------------------------------------------------------------------------*/ 171 /** Unregister endpoint (free some bandwidth reservation). 172 * 173 * @param[in] fun Device function the action was invoked on. 174 * @param[in] address USB address of the device. 175 * @param[in] endpoint Endpoint number. 176 * @param[in] direction Endpoint data direction. 177 * @return Error code. 178 */ 237 179 static int unregister_endpoint( 238 180 ddf_fun_t *fun, usb_address_t address, 239 181 usb_endpoint_t endpoint, usb_direction_t direction) 240 182 { 183 assert(fun); 241 184 hc_t *hc = fun_to_hc(fun); 242 185 assert(hc); 243 186 usb_log_debug("Unregister endpoint %d:%d %d.\n", 244 187 address, endpoint, direction); 188 endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager, 189 address, endpoint, direction, NULL); 190 if (ep != NULL) { 191 usb_device_keeper_del_ep(&hc->manager, address, ep); 192 } 245 193 return usb_endpoint_manager_unregister_ep(&hc->ep_manager, address, 246 194 endpoint, direction); 247 195 } 248 196 /*----------------------------------------------------------------------------*/ 249 /** Interrupt out transaction interface function 250 * 251 * @param[in] fun DDF function that was called. 252 * @param[in] target USB device to write to. 253 * @param[in] max_packet_size maximum size of data packet the device accepts 254 * @param[in] data Source of data. 255 * @param[in] size Size of data source. 256 * @param[in] callback Function to call on transaction completion 257 * @param[in] arg Additional for callback function. 197 /** Schedule interrupt out transfer. 198 * 199 * The callback is supposed to be called once the transfer (on the wire) is 200 * complete regardless of the outcome. 201 * However, the callback could be called only when this function returns 202 * with success status (i.e. returns EOK). 203 * 204 * @param[in] fun Device function the action was invoked on. 205 * @param[in] target Target pipe (address and endpoint number) specification. 206 * @param[in] data Data to be sent (in USB endianess, allocated and deallocated 207 * by the caller). 208 * @param[in] size Size of the @p data buffer in bytes. 209 * @param[in] callback Callback to be issued once the transfer is complete. 210 * @param[in] arg Pass-through argument to the callback. 258 211 * @return Error code. 259 212 */ 260 213 static int interrupt_out( 261 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,void *data,214 ddf_fun_t *fun, usb_target_t target, void *data, 262 215 size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg) 263 216 { 264 usb_transfer_batch_t *batch = NULL; 265 hc_t *hc = NULL; 266 int ret = setup_batch(fun, target, USB_DIRECTION_OUT, data, size, 267 NULL, 0, NULL, callback, arg, "Interrupt OUT", &hc, &batch); 268 if (ret != EOK) 269 return ret; 217 assert(fun); 218 219 // FIXME: get from endpoint manager 220 size_t max_packet_size = 8; 221 222 hc_t *hc = fun_to_hc(fun); 223 assert(hc); 224 usb_speed_t speed = 225 usb_device_keeper_get_speed(&hc->manager, target.address); 226 227 usb_log_debug("Interrupt OUT %d:%d %zu(%zu).\n", 228 target.address, target.endpoint, size, max_packet_size); 229 230 usb_transfer_batch_t *batch = 231 batch_get(fun, target, USB_TRANSFER_INTERRUPT, max_packet_size, 232 speed, data, size, NULL, 0, NULL, callback, arg, &hc->manager); 233 if (!batch) 234 return ENOMEM; 270 235 batch_interrupt_out(batch); 271 ret = hc_schedule(hc, batch);236 const int ret = hc_schedule(hc, batch); 272 237 if (ret != EOK) { 273 238 batch_dispose(batch); … … 276 241 } 277 242 /*----------------------------------------------------------------------------*/ 278 /** Interrupt in transaction interface function 279 * 280 * @param[in] fun DDF function that was called. 281 * @param[in] target USB device to write to. 282 * @param[in] max_packet_size maximum size of data packet the device accepts 283 * @param[out] data Data destination. 284 * @param[in] size Size of data source. 285 * @param[in] callback Function to call on transaction completion 286 * @param[in] arg Additional for callback function. 243 /** Schedule interrupt in transfer. 244 * 245 * The callback is supposed to be called once the transfer (on the wire) is 246 * complete regardless of the outcome. 247 * However, the callback could be called only when this function returns 248 * with success status (i.e. returns EOK). 249 * 250 * @param[in] fun Device function the action was invoked on. 251 * @param[in] target Target pipe (address and endpoint number) specification. 252 * @param[in] data Buffer where to store the data (in USB endianess, 253 * allocated and deallocated by the caller). 254 * @param[in] size Size of the @p data buffer in bytes. 255 * @param[in] callback Callback to be issued once the transfer is complete. 256 * @param[in] arg Pass-through argument to the callback. 287 257 * @return Error code. 288 258 */ 289 259 static int interrupt_in( 290 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,void *data,260 ddf_fun_t *fun, usb_target_t target, void *data, 291 261 size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg) 292 262 { 293 usb_transfer_batch_t *batch = NULL; 294 hc_t *hc = NULL; 295 int ret = setup_batch(fun, target, USB_DIRECTION_IN, data, size, 296 NULL, 0, callback, NULL, arg, "Interrupt IN", &hc, &batch); 297 if (ret != EOK) 298 return ret; 263 assert(fun); 264 265 // FIXME: get from endpoint manager 266 size_t max_packet_size = 8; 267 268 hc_t *hc = fun_to_hc(fun); 269 assert(hc); 270 usb_speed_t speed = 271 usb_device_keeper_get_speed(&hc->manager, target.address); 272 usb_log_debug("Interrupt IN %d:%d %zu(%zu).\n", 273 target.address, target.endpoint, size, max_packet_size); 274 275 usb_transfer_batch_t *batch = 276 batch_get(fun, target, USB_TRANSFER_INTERRUPT, max_packet_size, 277 speed, data, size, NULL, 0, callback, NULL, arg, &hc->manager); 278 if (!batch) 279 return ENOMEM; 299 280 batch_interrupt_in(batch); 300 ret = hc_schedule(hc, batch);281 const int ret = hc_schedule(hc, batch); 301 282 if (ret != EOK) { 302 283 batch_dispose(batch); … … 305 286 } 306 287 /*----------------------------------------------------------------------------*/ 307 /** Bulk out transaction interface function 308 * 309 * @param[in] fun DDF function that was called. 310 * @param[in] target USB device to write to. 311 * @param[in] max_packet_size maximum size of data packet the device accepts 312 * @param[in] data Source of data. 313 * @param[in] size Size of data source. 314 * @param[in] callback Function to call on transaction completion 315 * @param[in] arg Additional for callback function. 288 /** Schedule bulk out transfer. 289 * 290 * The callback is supposed to be called once the transfer (on the wire) is 291 * complete regardless of the outcome. 292 * However, the callback could be called only when this function returns 293 * with success status (i.e. returns EOK). 294 * 295 * @param[in] fun Device function the action was invoked on. 296 * @param[in] target Target pipe (address and endpoint number) specification. 297 * @param[in] data Data to be sent (in USB endianess, allocated and deallocated 298 * by the caller). 299 * @param[in] size Size of the @p data buffer in bytes. 300 * @param[in] callback Callback to be issued once the transfer is complete. 301 * @param[in] arg Pass-through argument to the callback. 316 302 * @return Error code. 317 303 */ 318 304 static int bulk_out( 319 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,void *data,305 ddf_fun_t *fun, usb_target_t target, void *data, 320 306 size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg) 321 307 { 322 usb_transfer_batch_t *batch = NULL; 323 hc_t *hc = NULL; 324 int ret = setup_batch(fun, target, USB_DIRECTION_OUT, data, size, 325 NULL, 0, NULL, callback, arg, "Bulk OUT", &hc, &batch); 326 if (ret != EOK) 327 return ret; 308 assert(fun); 309 310 // FIXME: get from endpoint manager 311 size_t max_packet_size = 8; 312 313 hc_t *hc = fun_to_hc(fun); 314 assert(hc); 315 usb_speed_t speed = 316 usb_device_keeper_get_speed(&hc->manager, target.address); 317 318 usb_log_debug("Bulk OUT %d:%d %zu(%zu).\n", 319 target.address, target.endpoint, size, max_packet_size); 320 321 usb_transfer_batch_t *batch = 322 batch_get(fun, target, USB_TRANSFER_BULK, max_packet_size, speed, 323 data, size, NULL, 0, NULL, callback, arg, &hc->manager); 324 if (!batch) 325 return ENOMEM; 328 326 batch_bulk_out(batch); 329 ret = hc_schedule(hc, batch);327 const int ret = hc_schedule(hc, batch); 330 328 if (ret != EOK) { 331 329 batch_dispose(batch); … … 334 332 } 335 333 /*----------------------------------------------------------------------------*/ 336 /** Bulk in transaction interface function 337 * 338 * @param[in] fun DDF function that was called. 339 * @param[in] target USB device to write to. 340 * @param[in] max_packet_size maximum size of data packet the device accepts 341 * @param[out] data Data destination. 342 * @param[in] size Size of data source. 343 * @param[in] callback Function to call on transaction completion 344 * @param[in] arg Additional for callback function. 334 /** Schedule bulk in transfer. 335 * 336 * The callback is supposed to be called once the transfer (on the wire) is 337 * complete regardless of the outcome. 338 * However, the callback could be called only when this function returns 339 * with success status (i.e. returns EOK). 340 * 341 * @param[in] fun Device function the action was invoked on. 342 * @param[in] target Target pipe (address and endpoint number) specification. 343 * @param[in] data Buffer where to store the data (in USB endianess, 344 * allocated and deallocated by the caller). 345 * @param[in] size Size of the @p data buffer in bytes. 346 * @param[in] callback Callback to be issued once the transfer is complete. 347 * @param[in] arg Pass-through argument to the callback. 345 348 * @return Error code. 346 349 */ 347 350 static int bulk_in( 348 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,void *data,351 ddf_fun_t *fun, usb_target_t target, void *data, 349 352 size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg) 350 353 { 351 usb_transfer_batch_t *batch = NULL; 352 hc_t *hc = NULL; 353 int ret = setup_batch(fun, target, USB_DIRECTION_IN, data, size, 354 NULL, 0, callback, NULL, arg, "Bulk IN", &hc, &batch); 355 if (ret != EOK) 356 return ret; 354 assert(fun); 355 356 // FIXME: get from endpoint manager 357 size_t max_packet_size = 8; 358 359 hc_t *hc = fun_to_hc(fun); 360 assert(hc); 361 usb_speed_t speed = 362 usb_device_keeper_get_speed(&hc->manager, target.address); 363 usb_log_debug("Bulk IN %d:%d %zu(%zu).\n", 364 target.address, target.endpoint, size, max_packet_size); 365 366 usb_transfer_batch_t *batch = 367 batch_get(fun, target, USB_TRANSFER_BULK, max_packet_size, speed, 368 data, size, NULL, 0, callback, NULL, arg, &hc->manager); 369 if (!batch) 370 return ENOMEM; 357 371 batch_bulk_in(batch); 358 ret = hc_schedule(hc, batch);372 const int ret = hc_schedule(hc, batch); 359 373 if (ret != EOK) { 360 374 batch_dispose(batch); … … 363 377 } 364 378 /*----------------------------------------------------------------------------*/ 365 /** Control write transaction interface function 366 * 367 * @param[in] fun DDF function that was called. 368 * @param[in] target USB device to write to. 369 * @param[in] max_packet_size maximum size of data packet the device accepts. 370 * @param[in] setup_data Data to send with SETUP transfer. 371 * @param[in] setup_size Size of data to send with SETUP transfer (always 8B). 372 * @param[in] data Source of data. 373 * @param[in] size Size of data source. 374 * @param[in] callback Function to call on transaction completion. 375 * @param[in] arg Additional for callback function. 379 /** Schedule control write transfer. 380 * 381 * The callback is supposed to be called once the transfer (on the wire) is 382 * complete regardless of the outcome. 383 * However, the callback could be called only when this function returns 384 * with success status (i.e. returns EOK). 385 * 386 * @param[in] fun Device function the action was invoked on. 387 * @param[in] target Target pipe (address and endpoint number) specification. 388 * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated 389 * and deallocated by the caller). 390 * @param[in] setup_packet_size Size of @p setup_packet buffer in bytes. 391 * @param[in] data_buffer Data buffer (in USB endianess, allocated and 392 * deallocated by the caller). 393 * @param[in] data_buffer_size Size of @p data_buffer buffer in bytes. 394 * @param[in] callback Callback to be issued once the transfer is complete. 395 * @param[in] arg Pass-through argument to the callback. 376 396 * @return Error code. 377 397 */ 378 398 static int control_write( 379 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,399 ddf_fun_t *fun, usb_target_t target, 380 400 void *setup_data, size_t setup_size, void *data, size_t size, 381 401 usbhc_iface_transfer_out_callback_t callback, void *arg) 382 402 { 383 usb_transfer_batch_t *batch = NULL; 384 hc_t *hc = NULL; 385 int ret = setup_batch(fun, target, USB_DIRECTION_BOTH, data, size, 386 setup_data, setup_size, NULL, callback, arg, "Control WRITE", 387 &hc, &batch); 388 if (ret != EOK) 389 return ret; 403 assert(fun); 404 405 // FIXME: get from endpoint manager 406 size_t max_packet_size = 8; 407 408 hc_t *hc = fun_to_hc(fun); 409 assert(hc); 410 usb_speed_t speed = 411 usb_device_keeper_get_speed(&hc->manager, target.address); 412 usb_log_debug("Control WRITE (%d) %d:%d %zu(%zu).\n", 413 speed, target.address, target.endpoint, size, max_packet_size); 414 415 if (setup_size != 8) 416 return EINVAL; 417 418 usb_transfer_batch_t *batch = 419 batch_get(fun, target, USB_TRANSFER_CONTROL, max_packet_size, 420 speed, data, size, setup_data, setup_size, NULL, callback, arg, 421 &hc->manager); 422 if (!batch) 423 return ENOMEM; 390 424 usb_device_keeper_reset_if_need(&hc->manager, target, setup_data); 391 425 batch_control_write(batch); 392 ret = hc_schedule(hc, batch);426 const int ret = hc_schedule(hc, batch); 393 427 if (ret != EOK) { 394 428 batch_dispose(batch); … … 397 431 } 398 432 /*----------------------------------------------------------------------------*/ 399 /** Control read transaction interface function 400 * 401 * @param[in] fun DDF function that was called. 402 * @param[in] target USB device to write to. 403 * @param[in] max_packet_size maximum size of data packet the device accepts. 404 * @param[in] setup_data Data to send with SETUP packet. 405 * @param[in] setup_size Size of data to send with SETUP packet (should be 8B). 406 * @param[out] data Source of data. 407 * @param[in] size Size of data source. 408 * @param[in] callback Function to call on transaction completion. 409 * @param[in] arg Additional for callback function. 433 /** Schedule control read transfer. 434 * 435 * The callback is supposed to be called once the transfer (on the wire) is 436 * complete regardless of the outcome. 437 * However, the callback could be called only when this function returns 438 * with success status (i.e. returns EOK). 439 * 440 * @param[in] fun Device function the action was invoked on. 441 * @param[in] target Target pipe (address and endpoint number) specification. 442 * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated 443 * and deallocated by the caller). 444 * @param[in] setup_packet_size Size of @p setup_packet buffer in bytes. 445 * @param[in] data_buffer Buffer where to store the data (in USB endianess, 446 * allocated and deallocated by the caller). 447 * @param[in] data_buffer_size Size of @p data_buffer buffer in bytes. 448 * @param[in] callback Callback to be issued once the transfer is complete. 449 * @param[in] arg Pass-through argument to the callback. 410 450 * @return Error code. 411 451 */ 412 452 static int control_read( 413 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,453 ddf_fun_t *fun, usb_target_t target, 414 454 void *setup_data, size_t setup_size, void *data, size_t size, 415 455 usbhc_iface_transfer_in_callback_t callback, void *arg) 416 456 { 417 usb_transfer_batch_t *batch = NULL; 418 hc_t *hc = NULL; 419 int ret = setup_batch(fun, target, USB_DIRECTION_BOTH, data, size, 420 setup_data, setup_size, callback, NULL, arg, "Control READ", 421 &hc, &batch); 422 if (ret != EOK) 423 return ret; 457 assert(fun); 458 459 // FIXME: get from endpoint manager 460 size_t max_packet_size = 8; 461 462 hc_t *hc = fun_to_hc(fun); 463 assert(hc); 464 usb_speed_t speed = 465 usb_device_keeper_get_speed(&hc->manager, target.address); 466 467 usb_log_debug("Control READ(%d) %d:%d %zu(%zu).\n", 468 speed, target.address, target.endpoint, size, max_packet_size); 469 usb_transfer_batch_t *batch = 470 batch_get(fun, target, USB_TRANSFER_CONTROL, max_packet_size, 471 speed, data, size, setup_data, setup_size, callback, NULL, arg, 472 &hc->manager); 473 if (!batch) 474 return ENOMEM; 424 475 batch_control_read(batch); 425 ret = hc_schedule(hc, batch);476 const int ret = hc_schedule(hc, batch); 426 477 if (ret != EOK) { 427 478 batch_dispose(batch); … … 430 481 } 431 482 /*----------------------------------------------------------------------------*/ 483 /** Host controller interface implementation for OHCI. */ 432 484 usbhc_iface_t hc_iface = { 433 485 .reserve_default_address = reserve_default_address, … … 449 501 .control_read = control_read, 450 502 }; 503 451 504 /** 452 505 * @}
Note:
See TracChangeset
for help on using the changeset viewer.