Changes in uspace/lib/usb/src/devpoll.c [4125b7d:4ede178] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usb/src/devpoll.c
r4125b7d r4ede178 33 33 * USB device driver framework - automatic interrupt polling. 34 34 */ 35 #include <usb/dev poll.h>35 #include <usb/devdrv.h> 36 36 #include <usb/request.h> 37 37 #include <usb/debug.h> 38 #include <usb/classes/classes.h>39 38 #include <errno.h> 40 39 #include <str_error.h> … … 46 45 /** Data needed for polling. */ 47 46 typedef struct { 48 int debug;49 size_t max_failures;50 useconds_t delay;51 bool auto_clear_halt;52 bool (*on_data)(usb_device_t *, uint8_t *, size_t, void *);53 void (*on_polling_end)(usb_device_t *, bool, void *);54 bool (*on_error)(usb_device_t *, int, void *);55 56 47 usb_device_t *dev; 57 48 size_t pipe_index; 49 usb_polling_callback_t callback; 50 usb_polling_terminted_callback_t terminated_callback; 58 51 size_t request_size; 59 52 uint8_t *buffer; 60 53 void *custom_arg; 61 54 } polling_data_t; 62 63 55 64 56 /** Polling fibril. … … 75 67 = polling_data->dev->pipes[polling_data->pipe_index].pipe; 76 68 77 if (polling_data->debug > 0) { 78 usb_endpoint_mapping_t *mapping 79 = &polling_data->dev->pipes[polling_data->pipe_index]; 80 usb_log_debug("Poll%p: started polling of `%s' - " \ 81 "interface %d (%s,%d,%d), %zuB/%zu.\n", 82 polling_data, 83 polling_data->dev->ddf_dev->name, 84 (int) mapping->interface->interface_number, 85 usb_str_class(mapping->interface->interface_class), 86 (int) mapping->interface->interface_subclass, 87 (int) mapping->interface->interface_protocol, 88 polling_data->request_size, pipe->max_packet_size); 89 } 69 usb_log_debug("Pipe interface number: %d, protocol: %d, subclass: %d, max packet size: %d\n", 70 polling_data->dev->pipes[polling_data->pipe_index].interface_no, 71 polling_data->dev->pipes[polling_data->pipe_index].description->interface_protocol, 72 polling_data->dev->pipes[polling_data->pipe_index].description->interface_subclass, 73 pipe->max_packet_size); 90 74 91 75 size_t failed_attempts = 0; 92 while (failed_attempts < = polling_data->max_failures) {76 while (failed_attempts < MAX_FAILED_ATTEMPTS) { 93 77 int rc; 94 78 … … 97 81 polling_data->request_size, &actual_size); 98 82 99 if (polling_data->debug > 1) { 100 if (rc == EOK) { 101 usb_log_debug( 102 "Poll%p: received: '%s' (%zuB).\n", 103 polling_data, 104 usb_debug_str_buffer(polling_data->buffer, 105 actual_size, 16), 106 actual_size); 107 } else { 108 usb_log_debug( 109 "Poll%p: polling failed: %s.\n", 110 polling_data, str_error(rc)); 111 } 112 } 113 114 /* If the pipe stalled, we can try to reset the stall. */ 115 if ((rc == ESTALL) && (polling_data->auto_clear_halt)) { 116 /* 117 * We ignore error here as this is usually a futile 118 * attempt anyway. 119 */ 120 usb_request_clear_endpoint_halt( 121 &polling_data->dev->ctrl_pipe, 122 pipe->endpoint_no); 123 } 83 84 // if (rc == ESTALL) { 85 // usb_log_debug("Seding clear feature...\n"); 86 // usb_request_clear_feature(pipe, USB_REQUEST_TYPE_STANDARD, 87 // USB_REQUEST_RECIPIENT_ENDPOINT, 0, pipe->endpoint_no); 88 // continue; 89 // } 124 90 125 91 if (rc != EOK) { 126 if (polling_data->on_error != NULL) {127 bool cont = polling_data->on_error(128 polling_data->dev, rc,129 polling_data->custom_arg);130 if (!cont) {131 failed_attempts132 = polling_data->max_failures;133 }134 }135 92 failed_attempts++; 136 93 continue; … … 138 95 139 96 /* We have the data, execute the callback now. */ 140 bool carry_on = polling_data-> on_data(polling_data->dev,97 bool carry_on = polling_data->callback(polling_data->dev, 141 98 polling_data->buffer, actual_size, 142 99 polling_data->custom_arg); … … 149 106 /* Reset as something might be only a temporary problem. */ 150 107 failed_attempts = 0; 151 152 /* Take a rest before next request. */153 async_usleep(polling_data->delay);154 108 } 155 109 156 if (polling_data->on_polling_end != NULL) { 157 polling_data->on_polling_end(polling_data->dev, 158 failed_attempts > 0, polling_data->custom_arg); 110 if (failed_attempts > 0) { 111 usb_log_error( 112 "Polling of device `%s' terminated: recurring failures.\n", 113 polling_data->dev->ddf_dev->name); 159 114 } 160 115 161 if (polling_data->debug > 0) { 162 if (failed_attempts > 0) { 163 usb_log_error( 164 "Polling of device `%s' terminated: %s.\n", 165 polling_data->dev->ddf_dev->name, 166 "recurring failures"); 167 } else { 168 usb_log_debug( 169 "Polling of device `%s' terminated by user.\n", 170 polling_data->dev->ddf_dev->name 171 ); 172 } 116 if (polling_data->terminated_callback != NULL) { 117 polling_data->terminated_callback(polling_data->dev, 118 failed_attempts > 0, polling_data->custom_arg); 173 119 } 174 120 … … 213 159 } 214 160 215 usb_device_auto_polling_t *auto_polling216 = malloc(sizeof(usb_device_auto_polling_t));217 if (auto_polling == NULL) {218 return ENOMEM;219 }220 221 auto_polling->debug = 1;222 auto_polling->auto_clear_halt = true;223 auto_polling->delay = 0;224 auto_polling->max_failures = MAX_FAILED_ATTEMPTS;225 auto_polling->on_data = callback;226 auto_polling->on_polling_end = terminated_callback;227 auto_polling->on_error = NULL;228 229 int rc = usb_device_auto_polling(dev, pipe_index, auto_polling,230 request_size, arg);231 232 free(auto_polling);233 234 return rc;235 }236 237 /** Start automatic device polling over interrupt in pipe.238 *239 * The polling settings is copied thus it is okay to destroy the structure240 * after this function returns.241 *242 * @warning There is no guarantee when the request to the device243 * will be sent for the first time (it is possible that this244 * first request would be executed prior to return from this function).245 *246 * @param dev Device to be periodically polled.247 * @param pipe_index Index of the endpoint pipe used for polling.248 * @param polling Polling settings.249 * @param request_size How many bytes to ask for in each request.250 * @param arg Custom argument (passed as is to the callbacks).251 * @return Error code.252 * @retval EOK New fibril polling the device was already started.253 */254 int usb_device_auto_polling(usb_device_t *dev, size_t pipe_index,255 usb_device_auto_polling_t *polling,256 size_t request_size, void *arg)257 {258 if (dev == NULL) {259 return EBADMEM;260 }261 if (pipe_index >= dev->pipes_count) {262 return EINVAL;263 }264 if ((dev->pipes[pipe_index].pipe->transfer_type != USB_TRANSFER_INTERRUPT)265 || (dev->pipes[pipe_index].pipe->direction != USB_DIRECTION_IN)) {266 return EINVAL;267 }268 if ((polling == NULL) || (polling->on_data == NULL)) {269 return EBADMEM;270 }271 272 161 polling_data_t *polling_data = malloc(sizeof(polling_data_t)); 273 162 if (polling_data == NULL) { … … 275 164 } 276 165 277 /* Fill-in the data. */278 polling_data->buffer = malloc( sizeof(request_size));166 /* Allocate now to prevent immediate failure in the polling fibril. */ 167 polling_data->buffer = malloc(request_size); 279 168 if (polling_data->buffer == NULL) { 280 169 free(polling_data); 281 170 return ENOMEM; 282 171 } 283 polling_data->request_size = request_size;284 172 polling_data->dev = dev; 285 173 polling_data->pipe_index = pipe_index; 174 polling_data->callback = callback; 175 polling_data->terminated_callback = terminated_callback; 176 polling_data->request_size = request_size; 286 177 polling_data->custom_arg = arg; 287 288 polling_data->debug = polling->debug;289 polling_data->max_failures = polling->max_failures;290 if (polling->delay >= 0) {291 polling_data->delay = (useconds_t) polling->delay;292 } else {293 polling_data->delay = (useconds_t) dev->pipes[pipe_index]294 .descriptor->poll_interval;295 }296 polling_data->auto_clear_halt = polling->auto_clear_halt;297 298 polling_data->on_data = polling->on_data;299 polling_data->on_polling_end = polling->on_polling_end;300 polling_data->on_error = polling->on_error;301 178 302 179 fid_t fibril = fibril_create(polling_fibril, polling_data); … … 304 181 free(polling_data->buffer); 305 182 free(polling_data); 183 /* FIXME: better error code. */ 306 184 return ENOMEM; 307 185 } 308 186 fibril_add_ready(fibril); 309 187 310 /* Fibril launched. That fibril will free the allocated data. */188 /* The allocated buffer etc. will be freed by the fibril. */ 311 189 312 190 return EOK;
Note:
See TracChangeset
for help on using the changeset viewer.