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