Changes in uspace/lib/usbhost/src/iface.c [77ad86c:8b54fe6] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbhost/src/iface.c
r77ad86c r8b54fe6 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 29 28 /** @addtogroup libusbhost 30 29 * @{ … … 33 32 * @brief HCD DDF interface implementation 34 33 */ 35 36 34 #include <ddf/driver.h> 37 35 #include <errno.h> … … 41 39 #include <usb/host/hcd.h> 42 40 43 /** Prepare generic usb_transfer_batch and schedule it.44 * @param fun DDF fun45 * @param target address and endpoint number.46 * @param setup_data Data to use in setup stage (Control communication type)47 * @param in Callback for device to host communication.48 * @param out Callback for host to device communication.49 * @param arg Callback parameter.50 * @param name Communication identifier (for nicer output).51 * @return Error code.52 */53 41 static inline int send_batch( 54 42 ddf_fun_t *fun, usb_target_t target, usb_direction_t direction, … … 61 49 assert(hcd); 62 50 63 endpoint_t *ep = usb_endpoint_manager_find_ep(&hcd->ep_manager, 64 target.address, target.endpoint, direction); 51 int ret; 52 53 size_t res_bw; 54 endpoint_t *ep = usb_endpoint_manager_get_ep(&hcd->ep_manager, 55 target.address, target.endpoint, direction, &res_bw); 65 56 if (ep == NULL) { 66 57 usb_log_error("Endpoint(%d:%d) not registered for %s.\n", … … 74 65 const size_t bw = bandwidth_count_usb11( 75 66 ep->speed, ep->transfer_type, size, ep->max_packet_size); 76 /* Check if we have enough bandwidth reserved */ 77 if (ep->bandwidth < bw) { 67 if (res_bw < bw) { 78 68 usb_log_error("Endpoint(%d:%d) %s needs %zu bw " 79 69 "but only %zu is reserved.\n", 80 ep->address, ep->endpoint, name, bw, ep->bandwidth);70 target.address, target.endpoint, name, bw, res_bw); 81 71 return ENOSPC; 82 72 } … … 88 78 /* No private data and no private data dtor */ 89 79 usb_transfer_batch_t *batch = 90 usb_transfer_batch_ create(ep, data, size, setup_data,80 usb_transfer_batch_get(ep, data, size, setup_data, 91 81 in, out, arg, fun, NULL, NULL); 92 82 if (!batch) { … … 94 84 } 95 85 96 const intret = hcd->schedule(hcd, batch);86 ret = hcd->schedule(hcd, batch); 97 87 if (ret != EOK) 98 usb_transfer_batch_d estroy(batch);88 usb_transfer_batch_dispose(batch); 99 89 100 90 return ret; 101 91 } 102 103 /** Calls ep_add_hook upon endpoint registration. 104 * @param ep Endpoint to be registered. 105 * @param arg hcd_t in disguise. 106 * @return Error code. 107 */ 108 static int register_helper(endpoint_t *ep, void *arg) 109 { 110 hcd_t *hcd = arg; 111 assert(ep); 112 assert(hcd); 113 if (hcd->ep_add_hook) 114 return hcd->ep_add_hook(hcd, ep); 92 /*----------------------------------------------------------------------------*/ 93 /** Request address interface function 94 * 95 * @param[in] fun DDF function that was called. 96 * @param[in] speed Speed to associate with the new default address. 97 * @param[out] address Place to write a new address. 98 * @return Error code. 99 */ 100 static int request_address( 101 ddf_fun_t *fun, usb_speed_t speed, usb_address_t *address) 102 { 103 assert(fun); 104 hcd_t *hcd = fun_to_hcd(fun); 105 assert(hcd); 106 assert(address); 107 108 usb_log_debug("Address request speed: %s.\n", usb_str_speed(speed)); 109 *address = 110 usb_device_manager_get_free_address(&hcd->dev_manager, speed); 111 usb_log_debug("Address request with result: %d.\n", *address); 112 if (*address <= 0) 113 return *address; 115 114 return EOK; 116 115 } 117 118 /** Calls ep_remove_hook upon endpoint removal. 119 * @param ep Endpoint to be unregistered. 120 * @param arg hcd_t in disguise. 121 */ 122 static void unregister_helper(endpoint_t *ep, void *arg) 123 { 124 hcd_t *hcd = arg; 125 assert(ep); 126 assert(hcd); 127 if (hcd->ep_remove_hook) 128 hcd->ep_remove_hook(hcd, ep); 129 } 130 131 /** Calls ep_remove_hook upon endpoint removal. Prints warning. 132 * @param ep Endpoint to be unregistered. 133 * @param arg hcd_t in disguise. 134 */ 135 static void unregister_helper_warn(endpoint_t *ep, void *arg) 136 { 137 hcd_t *hcd = arg; 138 assert(ep); 139 assert(hcd); 140 usb_log_warning("Endpoint %d:%d %s was left behind, removing.\n", 141 ep->address, ep->endpoint, usb_str_direction(ep->direction)); 142 if (hcd->ep_remove_hook) 143 hcd->ep_remove_hook(hcd, ep); 144 } 145 146 /** Request address interface function. 147 * 148 * @param[in] fun DDF function that was called. 149 * @param[in] address Pointer to preferred USB address. 150 * @param[out] address Place to write a new address. 151 * @param[in] strict Fail if the preferred address is not available. 152 * @param[in] speed Speed to associate with the new default address. 153 * @return Error code. 154 */ 155 static int request_address( 156 ddf_fun_t *fun, usb_address_t *address, bool strict, usb_speed_t speed) 157 { 158 assert(fun); 159 hcd_t *hcd = fun_to_hcd(fun); 160 assert(hcd); 161 assert(address); 162 163 usb_log_debug("Address request: speed: %s, address: %d, strict: %s.\n", 164 usb_str_speed(speed), *address, strict ? "YES" : "NO"); 165 return usb_device_manager_request_address( 166 &hcd->dev_manager, address, strict, speed); 167 } 168 169 /** Bind address interface function. 116 /*----------------------------------------------------------------------------*/ 117 /** Bind address interface function 170 118 * 171 119 * @param[in] fun DDF function that was called. … … 175 123 */ 176 124 static int bind_address( 177 125 ddf_fun_t *fun, usb_address_t address, devman_handle_t handle) 178 126 { 179 127 assert(fun); … … 182 130 183 131 usb_log_debug("Address bind %d-%" PRIun ".\n", address, handle); 184 return usb_device_manager_bind_address(185 &hcd->dev_manager, address, handle);186 } 187 132 usb_device_manager_bind(&hcd->dev_manager, address, handle); 133 return EOK; 134 } 135 /*----------------------------------------------------------------------------*/ 188 136 /** Find device handle by address interface function. 189 137 * … … 199 147 hcd_t *hcd = fun_to_hcd(fun); 200 148 assert(hcd); 201 return usb_device_manager_get_info_by_address( 202 &hcd->dev_manager, address, handle, NULL); 203 } 204 205 /** Release address interface function. 149 const bool found = 150 usb_device_manager_find_by_address(&hcd->dev_manager, address, handle); 151 return found ? EOK : ENOENT; 152 } 153 /*----------------------------------------------------------------------------*/ 154 /** Release address interface function 206 155 * 207 156 * @param[in] fun DDF function that was called. … … 215 164 assert(hcd); 216 165 usb_log_debug("Address release %d.\n", address); 217 usb_device_manager_release_address(&hcd->dev_manager, address); 218 usb_endpoint_manager_remove_address(&hcd->ep_manager, address, 219 unregister_helper_warn, hcd); 166 usb_device_manager_release(&hcd->dev_manager, address); 220 167 return EOK; 221 168 } 222 223 /** Register endpoint interface function. 224 * @param fun DDF function. 225 * @param address USB address of the device. 226 * @param endpoint USB endpoint number to be registered. 227 * @param transfer_type Endpoint's transfer type. 228 * @param direction USB communication direction the endpoint is capable of. 229 * @param max_packet_size Maximu size of packets the endpoint accepts. 230 * @param interval Preferred timeout between communication. 231 * @return Error code. 232 */ 169 /*----------------------------------------------------------------------------*/ 233 170 static int register_endpoint( 234 ddf_fun_t *fun, usb_address_t address, usb_endpoint_t endpoint, 171 ddf_fun_t *fun, usb_address_t address, usb_speed_t ep_speed, 172 usb_endpoint_t endpoint, 235 173 usb_transfer_type_t transfer_type, usb_direction_t direction, 236 size_t max_packet_size, unsigned int erval)174 size_t max_packet_size, unsigned int interval) 237 175 { 238 176 assert(fun); … … 240 178 assert(hcd); 241 179 const size_t size = max_packet_size; 242 usb_speed_t speed = USB_SPEED_MAX; 243 const int ret = usb_device_manager_get_info_by_address( 244 &hcd->dev_manager, address, NULL, &speed); 245 if (ret != EOK) { 246 return ret; 247 } 180 /* Default address is not bound or registered, 181 * thus it does not provide speed info. */ 182 const usb_speed_t speed = (address == 0) ? ep_speed : 183 usb_device_manager_get_speed(&hcd->dev_manager, address); 248 184 249 185 usb_log_debug("Register endpoint %d:%d %s-%s %s %zuB %ums.\n", … … 252 188 max_packet_size, interval); 253 189 254 return usb_endpoint_manager_add_ep(&hcd->ep_manager, address, endpoint, 255 direction, transfer_type, speed, max_packet_size, size, 256 register_helper, hcd); 257 } 258 259 /** Unregister endpoint interface function. 260 * @param fun DDF function. 261 * @param address USB address of the endpoint. 262 * @param endpoint USB endpoint number. 263 * @param direction Communication direction of the enpdoint to unregister. 264 * @return Error code. 265 */ 190 endpoint_t *ep = endpoint_get( 191 address, endpoint, direction, transfer_type, speed, max_packet_size); 192 if (!ep) 193 return ENOMEM; 194 int ret = EOK; 195 196 if (hcd->ep_add_hook) { 197 ret = hcd->ep_add_hook(hcd, ep); 198 } 199 if (ret != EOK) { 200 endpoint_destroy(ep); 201 return ret; 202 } 203 204 ret = usb_endpoint_manager_register_ep(&hcd->ep_manager, ep, size); 205 if (ret != EOK) { 206 endpoint_destroy(ep); 207 } 208 return ret; 209 } 210 /*----------------------------------------------------------------------------*/ 266 211 static int unregister_endpoint( 267 212 ddf_fun_t *fun, usb_address_t address, … … 273 218 usb_log_debug("Unregister endpoint %d:%d %s.\n", 274 219 address, endpoint, usb_str_direction(direction)); 275 return usb_endpoint_manager_remove_ep(&hcd->ep_manager, address, 276 endpoint, direction, unregister_helper, hcd); 277 } 278 279 /** Inbound communication interface function. 280 * @param fun DDF function. 281 * @param target Communication target. 282 * @param setup_data Data to use in setup stage (control transfers). 283 * @param data Pointer to data buffer. 284 * @param size Size of the data buffer. 285 * @param callback Function to call on communication end. 286 * @param arg Argument passed to the callback function. 287 * @return Error code. 288 */ 220 return usb_endpoint_manager_unregister_ep(&hcd->ep_manager, address, 221 endpoint, direction); 222 } 223 /*----------------------------------------------------------------------------*/ 289 224 static int usb_read(ddf_fun_t *fun, usb_target_t target, uint64_t setup_data, 290 225 uint8_t *data, size_t size, usbhc_iface_transfer_in_callback_t callback, … … 294 229 setup_data, callback, NULL, arg, "READ"); 295 230 } 296 297 /** Outbound communication interface function. 298 * @param fun DDF function. 299 * @param target Communication target. 300 * @param setup_data Data to use in setup stage (control transfers). 301 * @param data Pointer to data buffer. 302 * @param size Size of the data buffer. 303 * @param callback Function to call on communication end. 304 * @param arg Argument passed to the callback function. 305 * @return Error code. 306 */ 231 /*----------------------------------------------------------------------------*/ 307 232 static int usb_write(ddf_fun_t *fun, usb_target_t target, uint64_t setup_data, 308 233 const uint8_t *data, size_t size, … … 312 237 setup_data, NULL, callback, arg, "WRITE"); 313 238 } 314 315 /** usbhc Interface implementation using hcd_t from libusbhost library. */ 239 /*----------------------------------------------------------------------------*/ 316 240 usbhc_iface_t hcd_iface = { 317 241 .request_address = request_address, 318 242 .bind_address = bind_address, 319 . get_handle= find_by_address,243 .find_by_address = find_by_address, 320 244 .release_address = release_address, 321 245 … … 326 250 .write = usb_write, 327 251 }; 328 329 252 /** 330 253 * @}
Note:
See TracChangeset
for help on using the changeset viewer.