Changes in uspace/lib/usbdev/src/devpoll.c [ff0258f:56fd7cf] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbdev/src/devpoll.c
rff0258f r56fd7cf 33 33 * USB device driver framework - automatic interrupt polling. 34 34 */ 35 #include <usb/dev/device.h>36 #include <usb/dev/pipes.h>37 35 #include <usb/dev/poll.h> 38 36 #include <usb/dev/request.h> 37 #include <usb/debug.h> 39 38 #include <usb/classes/classes.h> 40 #include <usb/debug.h> 41 #include <usb/descriptor.h> 42 #include <usb/usb.h> 43 39 #include <errno.h> 40 #include <str_error.h> 44 41 #include <assert.h> 45 #include <async.h>46 #include <errno.h>47 #include <fibril.h>48 #include <stdbool.h>49 #include <stdlib.h>50 #include <str_error.h>51 #include <sys/types.h>52 42 53 43 /** Maximum number of failed consecutive requests before announcing failure. */ … … 61 51 /** USB device to poll. */ 62 52 usb_device_t *dev; 63 /** Device enpoint mappingto use for polling. */64 usb_endpoint_mapping_t *polling_mapping;53 /** Device pipe to use for polling. */ 54 size_t pipe_index; 65 55 /** Size of the recieved data. */ 66 56 size_t request_size; … … 82 72 const usb_device_auto_polling_t *params = &data->auto_polling; 83 73 84 usb_pipe_t *pipe = &data->polling_mapping->pipe; 74 usb_pipe_t *pipe 75 = &data->dev->pipes[data->pipe_index].pipe; 85 76 86 77 if (params->debug > 0) { 87 78 const usb_endpoint_mapping_t *mapping 88 = data->polling_mapping;89 usb_log_debug("Poll (%p): started polling of `%s' - " \79 = &data->dev->pipes[data->pipe_index]; 80 usb_log_debug("Poll%p: started polling of `%s' - " \ 90 81 "interface %d (%s,%d,%d), %zuB/%zu.\n", 91 data, usb_device_get_name(data->dev),82 data, ddf_dev_get_name(data->dev->ddf_dev), 92 83 (int) mapping->interface->interface_number, 93 84 usb_str_class(mapping->interface->interface_class), … … 97 88 } 98 89 90 usb_pipe_start_long_transfer(pipe); 99 91 size_t failed_attempts = 0; 100 92 while (failed_attempts <= params->max_failures) { … … 103 95 data->request_size, &actual_size); 104 96 105 if ( rc == EOK) {106 if ( params->debug > 1) {97 if (params->debug > 1) { 98 if (rc == EOK) { 107 99 usb_log_debug( 108 100 "Poll%p: received: '%s' (%zuB).\n", … … 111 103 actual_size, 16), 112 104 actual_size); 113 } 114 } else { 105 } else { 115 106 usb_log_debug( 116 107 "Poll%p: polling failed: %s.\n", 117 108 data, str_error(rc)); 109 } 118 110 } 119 111 … … 125 117 */ 126 118 usb_request_clear_endpoint_halt( 127 usb_device_get_default_pipe(data->dev), 128 pipe->endpoint_no); 119 &data->dev->ctrl_pipe, pipe->endpoint_no); 129 120 } 130 121 … … 154 145 155 146 /* Take a rest before next request. */ 156 //TODO: This is broken, the time is in ms not us.157 // but first we need to fix drivers to actually stop using this,158 // since polling dealy should be implemented in HC schedule159 147 async_usleep(params->delay); 160 148 } 149 150 usb_pipe_end_long_transfer(pipe); 161 151 162 152 const bool failed = failed_attempts > 0; … … 169 159 if (failed) { 170 160 usb_log_error("Polling of device `%s' terminated: " 171 "recurring failures.\n", 172 usb_device_get_name(data->dev));161 "recurring failures.\n", ddf_dev_get_name( 162 data->dev->ddf_dev)); 173 163 } else { 174 164 usb_log_debug("Polling of device `%s' terminated: " 175 "driver request.\n", 176 usb_device_get_name(data->dev));165 "driver request.\n", ddf_dev_get_name( 166 data->dev->ddf_dev)); 177 167 } 178 168 } … … 185 175 } 186 176 187 188 177 /** Start automatic device polling over interrupt in pipe. 189 178 * 190 * The polling settings is copied thus it is okay to destroy the structure191 * after this function returns.179 * @warning It is up to the callback to produce delays between individual 180 * requests. 192 181 * 193 182 * @warning There is no guarantee when the request to the device … … 196 185 * 197 186 * @param dev Device to be periodically polled. 198 * @param epm Endpoint mapping to use.199 * @param polling Polling settings.200 * @param request_size How many bytes to ask for in each request.201 * @param arg Custom argument (passed as is to the callbacks).202 * @return Error code.203 * @retval EOK New fibril polling the device was already started.204 */205 static int usb_device_auto_polling_internal(usb_device_t *dev,206 usb_endpoint_mapping_t *epm, const usb_device_auto_polling_t *polling,207 size_t request_size)208 {209 if ((dev == NULL) || (polling == NULL) || (polling->on_data == NULL)) {210 return EBADMEM;211 }212 213 if (request_size == 0)214 return EINVAL;215 216 if (!epm || (epm->pipe.transfer_type != USB_TRANSFER_INTERRUPT) ||217 (epm->pipe.direction != USB_DIRECTION_IN))218 return EINVAL;219 220 221 polling_data_t *polling_data = malloc(sizeof(polling_data_t));222 if (polling_data == NULL) {223 return ENOMEM;224 }225 226 /* Fill-in the data. */227 polling_data->buffer = malloc(sizeof(request_size));228 if (polling_data->buffer == NULL) {229 free(polling_data);230 return ENOMEM;231 }232 polling_data->request_size = request_size;233 polling_data->dev = dev;234 polling_data->polling_mapping = epm;235 236 /* Copy provided settings. */237 polling_data->auto_polling = *polling;238 239 /* Negative value means use descriptor provided value. */240 if (polling->delay < 0) {241 polling_data->auto_polling.delay =242 epm->descriptor->poll_interval;243 }244 245 fid_t fibril = fibril_create(polling_fibril, polling_data);246 if (fibril == 0) {247 free(polling_data->buffer);248 free(polling_data);249 return ENOMEM;250 }251 fibril_add_ready(fibril);252 253 /* Fibril launched. That fibril will free the allocated data. */254 255 return EOK;256 }257 /** Start automatic device polling over interrupt in pipe.258 *259 * The polling settings is copied thus it is okay to destroy the structure260 * after this function returns.261 *262 * @warning There is no guarantee when the request to the device263 * will be sent for the first time (it is possible that this264 * first request would be executed prior to return from this function).265 *266 * @param dev Device to be periodically polled.267 187 * @param pipe_index Index of the endpoint pipe used for polling. 268 * @param polling Polling settings.269 * @param req_size How many bytes to ask for in each request.270 * @param arg Custom argument (passed as is to the callbacks).271 * @return Error code.272 * @retval EOK New fibril polling the device was already started.273 */274 int usb_device_auto_polling(usb_device_t *usb_dev, usb_endpoint_t ep,275 const usb_device_auto_polling_t *polling, size_t req_size)276 {277 usb_endpoint_mapping_t *epm = usb_device_get_mapped_ep(usb_dev, ep);278 return usb_device_auto_polling_internal(usb_dev, epm, polling, req_size);279 }280 281 /** Start automatic device polling over interrupt in pipe.282 *283 * @warning It is up to the callback to produce delays between individual284 * requests.285 *286 * @warning There is no guarantee when the request to the device287 * will be sent for the first time (it is possible that this288 * first request would be executed prior to return from this function).289 *290 * @param dev Device to be periodically polled.291 * @param ep Endpoint used for polling.292 188 * @param callback Callback when data are available. 293 189 * @param request_size How many bytes to ask for in each request. 294 * @param delay NUmber of ms to wait between queries, -1 to use descriptor val.295 190 * @param terminated_callback Callback when polling is terminated. 296 191 * @param arg Custom argument (passed as is to the callbacks). … … 298 193 * @retval EOK New fibril polling the device was already started. 299 194 */ 300 int usb_device_auto_poll(usb_device_t *dev, usb_endpoint_t ep,301 usb_polling_callback_t callback, size_t request_size, int delay,195 int usb_device_auto_poll(usb_device_t *dev, size_t pipe_index, 196 usb_polling_callback_t callback, size_t request_size, 302 197 usb_polling_terminted_callback_t terminated_callback, void *arg) 303 198 { … … 305 200 .debug = 1, 306 201 .auto_clear_halt = true, 307 .delay = delay,202 .delay = 0, 308 203 .max_failures = MAX_FAILED_ATTEMPTS, 309 204 .on_data = callback, … … 313 208 }; 314 209 315 usb_endpoint_mapping_t *epm = usb_device_get_mapped_ep(dev, ep); 316 return usb_device_auto_polling_internal( 317 dev, epm, &auto_polling, request_size); 210 return usb_device_auto_polling(dev, pipe_index, &auto_polling, 211 request_size); 318 212 } 319 213 320 int usb_device_auto_polling_desc(usb_device_t *usb_dev, 321 const usb_endpoint_description_t *desc, 322 const usb_device_auto_polling_t *polling, size_t req_size) 214 /** Start automatic device polling over interrupt in pipe. 215 * 216 * The polling settings is copied thus it is okay to destroy the structure 217 * after this function returns. 218 * 219 * @warning There is no guarantee when the request to the device 220 * will be sent for the first time (it is possible that this 221 * first request would be executed prior to return from this function). 222 * 223 * @param dev Device to be periodically polled. 224 * @param pipe_index Index of the endpoint pipe used for polling. 225 * @param polling Polling settings. 226 * @param request_size How many bytes to ask for in each request. 227 * @param arg Custom argument (passed as is to the callbacks). 228 * @return Error code. 229 * @retval EOK New fibril polling the device was already started. 230 */ 231 int usb_device_auto_polling(usb_device_t *dev, size_t pipe_index, 232 const usb_device_auto_polling_t *polling, 233 size_t request_size) 323 234 { 324 usb_endpoint_mapping_t *epm = 325 usb_device_get_mapped_ep_desc(usb_dev, desc); 326 return usb_device_auto_polling_internal(usb_dev, epm, polling, req_size); 327 } 328 329 int usb_device_auto_poll_desc(usb_device_t * usb_dev, 330 const usb_endpoint_description_t *desc, usb_polling_callback_t callback, 331 size_t req_size, int delay, 332 usb_polling_terminted_callback_t terminated_callback, void *arg) 333 { 334 const usb_device_auto_polling_t auto_polling = { 335 .debug = 1, 336 .auto_clear_halt = true, 337 .delay = delay, 338 .max_failures = MAX_FAILED_ATTEMPTS, 339 .on_data = callback, 340 .on_polling_end = terminated_callback, 341 .on_error = NULL, 342 .arg = arg, 343 }; 344 345 usb_endpoint_mapping_t *epm = 346 usb_device_get_mapped_ep_desc(usb_dev, desc); 347 return usb_device_auto_polling_internal( 348 usb_dev, epm, &auto_polling, req_size); 235 if ((dev == NULL) || (polling == NULL) || (polling->on_data == NULL)) { 236 return EBADMEM; 237 } 238 239 if (pipe_index >= dev->pipes_count || request_size == 0) { 240 return EINVAL; 241 } 242 if ((dev->pipes[pipe_index].pipe.transfer_type != USB_TRANSFER_INTERRUPT) 243 || (dev->pipes[pipe_index].pipe.direction != USB_DIRECTION_IN)) { 244 return EINVAL; 245 } 246 247 polling_data_t *polling_data = malloc(sizeof(polling_data_t)); 248 if (polling_data == NULL) { 249 return ENOMEM; 250 } 251 252 /* Fill-in the data. */ 253 polling_data->buffer = malloc(sizeof(request_size)); 254 if (polling_data->buffer == NULL) { 255 free(polling_data); 256 return ENOMEM; 257 } 258 polling_data->request_size = request_size; 259 polling_data->dev = dev; 260 polling_data->pipe_index = pipe_index; 261 262 /* Copy provided settings. */ 263 polling_data->auto_polling = *polling; 264 265 /* Negative value means use descriptor provided value. */ 266 if (polling->delay < 0) { 267 polling_data->auto_polling.delay = 268 (int) dev->pipes[pipe_index].descriptor->poll_interval; 269 } 270 271 fid_t fibril = fibril_create(polling_fibril, polling_data); 272 if (fibril == 0) { 273 free(polling_data->buffer); 274 free(polling_data); 275 return ENOMEM; 276 } 277 fibril_add_ready(fibril); 278 279 /* Fibril launched. That fibril will free the allocated data. */ 280 281 return EOK; 349 282 } 350 283
Note:
See TracChangeset
for help on using the changeset viewer.