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