Changes in uspace/lib/usbdev/src/devpoll.c [9dbfd288:b77931d] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbdev/src/devpoll.c
r9dbfd288 rb77931d 46 46 /** Data needed for polling. */ 47 47 typedef struct { 48 usb_device_auto_polling_t auto_polling; 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 *); 49 55 50 56 usb_device_t *dev; … … 63 69 static int polling_fibril(void *arg) 64 70 { 65 assert(arg); 66 const polling_data_t *data = arg; 67 /* Helper to reduce typing. */ 68 const usb_device_auto_polling_t *params = &data->auto_polling; 71 polling_data_t *polling_data = (polling_data_t *) arg; 72 assert(polling_data); 69 73 70 74 usb_pipe_t *pipe 71 = & data->dev->pipes[data->pipe_index].pipe;72 73 if (p arams->debug > 0) {74 constusb_endpoint_mapping_t *mapping75 = & data->dev->pipes[data->pipe_index];75 = &polling_data->dev->pipes[polling_data->pipe_index].pipe; 76 77 if (polling_data->debug > 0) { 78 usb_endpoint_mapping_t *mapping 79 = &polling_data->dev->pipes[polling_data->pipe_index]; 76 80 usb_log_debug("Poll%p: started polling of `%s' - " \ 77 81 "interface %d (%s,%d,%d), %zuB/%zu.\n", 78 data, data->dev->ddf_dev->name, 82 polling_data, 83 polling_data->dev->ddf_dev->name, 79 84 (int) mapping->interface->interface_number, 80 85 usb_str_class(mapping->interface->interface_class), 81 86 (int) mapping->interface->interface_subclass, 82 87 (int) mapping->interface->interface_protocol, 83 data->request_size, pipe->max_packet_size); 84 } 85 86 usb_pipe_start_long_transfer(pipe); 88 polling_data->request_size, pipe->max_packet_size); 89 } 90 87 91 size_t failed_attempts = 0; 88 while (failed_attempts <= params->max_failures) { 92 while (failed_attempts <= polling_data->max_failures) { 93 int rc; 94 89 95 size_t actual_size; 90 const int rc = usb_pipe_read(pipe,data->buffer,91 data->request_size, &actual_size);92 93 if (p arams->debug > 1) {96 rc = usb_pipe_read(pipe, polling_data->buffer, 97 polling_data->request_size, &actual_size); 98 99 if (polling_data->debug > 1) { 94 100 if (rc == EOK) { 95 101 usb_log_debug( 96 102 "Poll%p: received: '%s' (%zuB).\n", 97 data,98 usb_debug_str_buffer( data->buffer,103 polling_data, 104 usb_debug_str_buffer(polling_data->buffer, 99 105 actual_size, 16), 100 106 actual_size); … … 102 108 usb_log_debug( 103 109 "Poll%p: polling failed: %s.\n", 104 data, str_error(rc));110 polling_data, str_error(rc)); 105 111 } 106 112 } 107 113 108 114 /* If the pipe stalled, we can try to reset the stall. */ 109 if ((rc == ESTALL) && (p arams->auto_clear_halt)) {115 if ((rc == ESTALL) && (polling_data->auto_clear_halt)) { 110 116 /* 111 117 * We ignore error here as this is usually a futile … … 113 119 */ 114 120 usb_request_clear_endpoint_halt( 115 &data->dev->ctrl_pipe, pipe->endpoint_no); 121 &polling_data->dev->ctrl_pipe, 122 pipe->endpoint_no); 116 123 } 117 124 118 125 if (rc != EOK) { 119 ++failed_attempts; 120 const bool cont = (params->on_error == NULL) ? true : 121 params->on_error(data->dev, rc, data->custom_arg); 122 if (!cont) { 123 failed_attempts = params->max_failures; 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_attempts 132 = polling_data->max_failures; 133 } 124 134 } 135 failed_attempts++; 125 136 continue; 126 137 } 127 138 128 139 /* We have the data, execute the callback now. */ 129 assert(params->on_data);130 const bool carry_on = params->on_data(131 data->dev, data->buffer, actual_size,data->custom_arg);140 bool carry_on = polling_data->on_data(polling_data->dev, 141 polling_data->buffer, actual_size, 142 polling_data->custom_arg); 132 143 133 144 if (!carry_on) { 134 /* This is user requested abort, erases failures. */135 145 failed_attempts = 0; 136 146 break; … … 141 151 142 152 /* Take a rest before next request. */ 143 async_usleep(params->delay); 144 } 145 146 usb_pipe_end_long_transfer(pipe); 147 148 const bool failed = failed_attempts > 0; 149 150 if (params->on_polling_end != NULL) { 151 params->on_polling_end(data->dev, failed, data->custom_arg); 152 } 153 154 if (params->debug > 0) { 155 if (failed) { 156 usb_log_error("Polling of device `%s' terminated: " 157 "recurring failures.\n", data->dev->ddf_dev->name); 153 async_usleep(polling_data->delay); 154 } 155 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); 159 } 160 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"); 158 167 } else { 159 usb_log_debug("Polling of device `%s' terminated: " 160 "driver request.\n", data->dev->ddf_dev->name); 168 usb_log_debug( 169 "Polling of device `%s' terminated by user.\n", 170 polling_data->dev->ddf_dev->name 171 ); 161 172 } 162 173 } 163 174 164 175 /* Free the allocated memory. */ 165 free( data->buffer);166 free( data);176 free(polling_data->buffer); 177 free(polling_data); 167 178 168 179 return EOK; … … 191 202 usb_polling_terminted_callback_t terminated_callback, void *arg) 192 203 { 204 if ((dev == NULL) || (callback == NULL)) { 205 return EBADMEM; 206 } 207 if (request_size == 0) { 208 return EINVAL; 209 } 210 if ((dev->pipes[pipe_index].pipe.transfer_type != USB_TRANSFER_INTERRUPT) 211 || (dev->pipes[pipe_index].pipe.direction != USB_DIRECTION_IN)) { 212 return EINVAL; 213 } 214 193 215 const usb_device_auto_polling_t auto_polling = { 194 216 .debug = 1, … … 226 248 size_t request_size, void *arg) 227 249 { 228 if ( (dev == NULL) || (polling == NULL) || (polling->on_data == NULL)) {250 if (dev == NULL) { 229 251 return EBADMEM; 230 252 } 231 232 if (pipe_index >= dev->pipes_count || request_size == 0) { 253 if (pipe_index >= dev->pipes_count) { 233 254 return EINVAL; 234 255 } … … 236 257 || (dev->pipes[pipe_index].pipe.direction != USB_DIRECTION_IN)) { 237 258 return EINVAL; 259 } 260 if ((polling == NULL) || (polling->on_data == NULL)) { 261 return EBADMEM; 238 262 } 239 263 … … 254 278 polling_data->custom_arg = arg; 255 279 256 /* Copy provided settings. */ 257 polling_data->auto_polling = *polling; 258 259 /* Negative value means use descriptor provided value. */ 260 if (polling->delay < 0) { 261 polling_data->auto_polling.delay = 262 (int) dev->pipes[pipe_index].descriptor->poll_interval; 263 } 280 polling_data->debug = polling->debug; 281 polling_data->max_failures = polling->max_failures; 282 if (polling->delay >= 0) { 283 polling_data->delay = (useconds_t) polling->delay; 284 } else { 285 polling_data->delay = (useconds_t) dev->pipes[pipe_index] 286 .descriptor->poll_interval; 287 } 288 polling_data->auto_clear_halt = polling->auto_clear_halt; 289 290 polling_data->on_data = polling->on_data; 291 polling_data->on_polling_end = polling->on_polling_end; 292 polling_data->on_error = polling->on_error; 264 293 265 294 fid_t fibril = fibril_create(polling_fibril, polling_data);
Note:
See TracChangeset
for help on using the changeset viewer.