Changeset 8989f48f in mainline
- Timestamp:
- 2011-04-14T10:03:20Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 5e168be1
- Parents:
- 5e07e2b5
- Location:
- uspace/lib/usb
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usb/include/usb/devpoll.h
r5e07e2b5 r8989f48f 37 37 38 38 #include <usb/devdrv.h> 39 #include <time.h> 40 41 typedef struct { 42 /** Maximum number of consecutive errors before polling termination. */ 43 size_t max_failures; 44 /** Delay between poll requests in milliseconds. 45 * Set to negative value to use value from endpoint descriptor. 46 */ 47 int delay; 48 /** Whether to automatically try to clear the HALT feature after 49 * the endpoint stalls. 50 */ 51 bool auto_clear_halt; 52 /** Callback when data arrives. 53 * 54 * @param dev Device that was polled. 55 * @param data Data buffer (in USB endianness). 56 * @param data_size Size of the @p data buffer in bytes. 57 * @param arg Custom argument. 58 * @return Whether to continue in polling. 59 */ 60 bool (*on_data)(usb_device_t *dev, uint8_t *data, size_t data_size, 61 void *arg); 62 /** Callback when polling is terminated. 63 * 64 * @param dev Device where the polling was terminated. 65 * @param due_to_errors Whether polling stopped due to several failures. 66 * @param arg Custom argument. 67 */ 68 void (*on_polling_end)(usb_device_t *dev, bool due_to_errors, 69 void *arg); 70 /** Callback when error occurs. 71 * 72 * @param dev Device where error occurred. 73 * @param err_code Error code (as returned from usb_pipe_read). 74 * @param arg Custom argument. 75 * @return Whether to continue in polling. 76 */ 77 bool (*on_error)(usb_device_t *dev, int err_code, void *arg); 78 } usb_device_auto_polling_t; 79 80 int usb_device_auto_polling(usb_device_t *, size_t, usb_device_auto_polling_t *, 81 size_t, void *); 39 82 40 83 typedef bool (*usb_polling_callback_t)(usb_device_t *, -
uspace/lib/usb/src/devpoll.c
r5e07e2b5 r8989f48f 45 45 /** Data needed for polling. */ 46 46 typedef struct { 47 size_t max_failures; 48 useconds_t delay; 49 bool auto_clear_halt; 50 bool (*on_data)(usb_device_t *, uint8_t *, size_t, void *); 51 void (*on_polling_end)(usb_device_t *, bool, void *); 52 bool (*on_error)(usb_device_t *, int, void *); 53 47 54 usb_device_t *dev; 48 55 size_t pipe_index; 49 usb_polling_callback_t callback;50 usb_polling_terminted_callback_t terminated_callback;51 56 size_t request_size; 52 57 uint8_t *buffer; 53 58 void *custom_arg; 54 59 } polling_data_t; 60 55 61 56 62 /** Polling fibril. … … 74 80 75 81 size_t failed_attempts = 0; 76 while (failed_attempts < MAX_FAILED_ATTEMPTS) {82 while (failed_attempts <= polling_data->max_failures) { 77 83 int rc; 78 84 … … 81 87 polling_data->request_size, &actual_size); 82 88 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 // } 89 /* If the pipe stalled, we can try to reset the stall. */ 90 if ((rc == ESTALL) && (polling_data->auto_clear_halt)) { 91 /* 92 * We ignore error here as this is usually a futile 93 * attempt anyway. 94 */ 95 usb_request_clear_endpoint_halt( 96 &polling_data->dev->ctrl_pipe, 97 pipe->endpoint_no); 98 } 90 99 91 100 if (rc != EOK) { 101 if (polling_data->on_error != NULL) { 102 bool cont = polling_data->on_error( 103 polling_data->dev, rc, 104 polling_data->custom_arg); 105 if (!cont) { 106 failed_attempts 107 = polling_data->max_failures; 108 } 109 } 92 110 failed_attempts++; 93 111 continue; … … 95 113 96 114 /* We have the data, execute the callback now. */ 97 bool carry_on = polling_data-> callback(polling_data->dev,115 bool carry_on = polling_data->on_data(polling_data->dev, 98 116 polling_data->buffer, actual_size, 99 117 polling_data->custom_arg); … … 106 124 /* Reset as something might be only a temporary problem. */ 107 125 failed_attempts = 0; 126 127 /* Take a rest before next request. */ 128 async_usleep(polling_data->delay); 108 129 } 109 130 … … 114 135 } 115 136 116 if (polling_data-> terminated_callback!= NULL) {117 polling_data-> terminated_callback(polling_data->dev,137 if (polling_data->on_polling_end != NULL) { 138 polling_data->on_polling_end(polling_data->dev, 118 139 failed_attempts > 0, polling_data->custom_arg); 119 140 } … … 159 180 } 160 181 182 usb_device_auto_polling_t *auto_polling 183 = malloc(sizeof(usb_device_auto_polling_t)); 184 if (auto_polling == NULL) { 185 return ENOMEM; 186 } 187 188 auto_polling->auto_clear_halt = true; 189 auto_polling->delay = 0; 190 auto_polling->max_failures = MAX_FAILED_ATTEMPTS; 191 auto_polling->on_data = callback; 192 auto_polling->on_polling_end = terminated_callback; 193 auto_polling->on_error = NULL; 194 195 int rc = usb_device_auto_polling(dev, pipe_index, auto_polling, 196 request_size, arg); 197 198 free(auto_polling); 199 200 return rc; 201 } 202 203 /** Start automatic device polling over interrupt in pipe. 204 * 205 * The polling settings is copied thus it is okay to destroy the structure 206 * after this function returns. 207 * 208 * @warning There is no guarantee when the request to the device 209 * will be sent for the first time (it is possible that this 210 * first request would be executed prior to return from this function). 211 * 212 * @param dev Device to be periodically polled. 213 * @param pipe_index Index of the endpoint pipe used for polling. 214 * @param polling Polling settings. 215 * @param request_size How many bytes to ask for in each request. 216 * @param arg Custom argument (passed as is to the callbacks). 217 * @return Error code. 218 * @retval EOK New fibril polling the device was already started. 219 */ 220 int usb_device_auto_polling(usb_device_t *dev, size_t pipe_index, 221 usb_device_auto_polling_t *polling, 222 size_t request_size, void *arg) 223 { 224 if (dev == NULL) { 225 return EBADMEM; 226 } 227 if (pipe_index >= dev->pipes_count) { 228 return EINVAL; 229 } 230 if ((dev->pipes[pipe_index].pipe->transfer_type != USB_TRANSFER_INTERRUPT) 231 || (dev->pipes[pipe_index].pipe->direction != USB_DIRECTION_IN)) { 232 return EINVAL; 233 } 234 if ((polling == NULL) || (polling->on_data == NULL)) { 235 return EBADMEM; 236 } 237 161 238 polling_data_t *polling_data = malloc(sizeof(polling_data_t)); 162 239 if (polling_data == NULL) { … … 164 241 } 165 242 166 /* Allocate now to prevent immediate failure in the polling fibril. */167 polling_data->buffer = malloc( request_size);243 /* Fill-in the data. */ 244 polling_data->buffer = malloc(sizeof(request_size)); 168 245 if (polling_data->buffer == NULL) { 169 246 free(polling_data); 170 247 return ENOMEM; 171 248 } 249 polling_data->request_size = request_size; 172 250 polling_data->dev = dev; 173 251 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;177 252 polling_data->custom_arg = arg; 253 254 polling_data->max_failures = polling->max_failures; 255 if (polling->delay >= 0) { 256 polling_data->delay = (useconds_t) polling->delay; 257 } else { 258 polling_data->delay = (useconds_t) dev->pipes[pipe_index] 259 .descriptor->poll_interval; 260 } 261 polling_data->auto_clear_halt = polling->auto_clear_halt; 262 263 polling_data->on_data = polling->on_data; 264 polling_data->on_polling_end = polling->on_polling_end; 265 polling_data->on_error = polling->on_error; 178 266 179 267 fid_t fibril = fibril_create(polling_fibril, polling_data); … … 181 269 free(polling_data->buffer); 182 270 free(polling_data); 183 /* FIXME: better error code. */184 271 return ENOMEM; 185 272 } 186 273 fibril_add_ready(fibril); 187 274 188 /* The allocated buffer etc. will be freed by the fibril. */275 /* Fibril launched. That fibril will free the allocated data. */ 189 276 190 277 return EOK;
Note:
See TracChangeset
for help on using the changeset viewer.