Changes in / [a39cfb8:e05d6c3] in mainline
- Location:
- uspace
- Files:
-
- 1 added
- 22 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/ohci/batch.c
ra39cfb8 re05d6c3 161 161 usb_log_debug("Batch(%p) found error TD(%d):%x.\n", 162 162 instance, i, data->tds[i]->status); 163 /* Make sure TD queue is empty (one TD), 164 * ED should be marked as halted */ 165 data->ed->td_tail = 166 (data->ed->td_head & ED_TDTAIL_PTR_MASK); 167 ++i; 163 168 break; 164 169 } … … 169 174 assert(hcd_ep); 170 175 hcd_ep->td = data->tds[i]; 176 /* Clear possible ED HALT */ 177 data->ed->td_head &= ~ED_TDHEAD_HALTED_FLAG; 178 uint32_t pa = addr_to_phys(hcd_ep->td); 179 assert(pa == (data->ed->td_head & ED_TDHEAD_PTR_MASK)); 180 assert(pa == (data->ed->td_tail & ED_TDTAIL_PTR_MASK)); 171 181 172 182 return true; -
uspace/drv/ohci/hcd_endpoint.c
ra39cfb8 re05d6c3 35 35 #include "hcd_endpoint.h" 36 36 37 static void hcd_ep_toggle_set(void *hcd_ep, int toggle) 38 { 39 hcd_endpoint_t *instance = hcd_ep; 40 assert(instance); 41 assert(instance->ed); 42 ed_toggle_set(instance->ed, toggle); 43 } 44 static int hcd_ep_toggle_get(void *hcd_ep) 45 { 46 hcd_endpoint_t *instance = hcd_ep; 47 assert(instance); 48 assert(instance->ed); 49 return ed_toggle_get(instance->ed); 50 } 51 52 37 53 hcd_endpoint_t * hcd_endpoint_assign(endpoint_t *ep) 38 54 { … … 57 73 ed_init(hcd_ep->ed, ep); 58 74 ed_set_td(hcd_ep->ed, hcd_ep->td); 59 endpoint_set_hc_data(ep, hcd_ep, NULL, NULL);75 endpoint_set_hc_data(ep, hcd_ep, hcd_ep_toggle_get, hcd_ep_toggle_set); 60 76 61 77 return hcd_ep; -
uspace/drv/ohci/hw_struct/endpoint_descriptor.h
ra39cfb8 re05d6c3 73 73 #define ED_TDHEAD_ZERO_SHIFT (2) 74 74 #define ED_TDHEAD_TOGGLE_CARRY (0x2) 75 #define ED_TDHEAD_HALTED_FLAG (0x1) 75 76 76 77 volatile uint32_t next; … … 106 107 instance->next = pa; 107 108 } 109 110 static inline int ed_toggle_get(ed_t *instance) 111 { 112 assert(instance); 113 return (instance->td_head & ED_TDHEAD_TOGGLE_CARRY) ? 1 : 0; 114 } 115 116 static inline void ed_toggle_set(ed_t *instance, int toggle) 117 { 118 assert(instance); 119 assert(toggle == 0 || toggle == 1); 120 if (toggle == 1) { 121 instance->td_head |= ED_TDHEAD_TOGGLE_CARRY; 122 } else { 123 /* clear halted flag when reseting toggle */ 124 instance->td_head &= ~ED_TDHEAD_TOGGLE_CARRY; 125 instance->td_head &= ~ED_TDHEAD_HALTED_FLAG; 126 } 127 } 108 128 #endif 109 129 /** -
uspace/drv/ohci/ohci_regs.h
ra39cfb8 re05d6c3 55 55 #define C_HCFS_MASK (0x3) /* Host controller functional state */ 56 56 #define C_HCFS_RESET (0x0) 57 #define C_HCFS_ OPERATIONAL(0x1)58 #define C_HCFS_ RESUME(0x2)57 #define C_HCFS_RESUME (0x1) 58 #define C_HCFS_OPERATIONAL (0x2) 59 59 #define C_HCFS_SUSPEND (0x3) 60 60 #define C_HCFS_SHIFT (6) -
uspace/drv/ohci/root_hub.h
ra39cfb8 re05d6c3 54 54 /** hubs descriptors */ 55 55 usb_device_descriptors_t descriptors; 56 /** interrupt transfer waiting for an actual interrupt to occur */ 57 usb_transfer_batch_t * unfinished_interrupt_transfer; 56 58 } rh_t; 57 59 -
uspace/drv/uhci-hcd/hc.c
ra39cfb8 re05d6c3 247 247 { 248 248 assert(instance); 249 #define CHECK_RET_CLEAR_RETURN(ret, message...) \ 249 #define SETUP_TRANSFER_LIST(type, name) \ 250 do { \ 251 int ret = transfer_list_init(&instance->transfers_##type, name); \ 250 252 if (ret != EOK) { \ 251 usb_log_error(message); \ 253 usb_log_error("Failed(%d) to setup %s transfer list: %s.\n", \ 254 ret, name, str_error(ret)); \ 252 255 transfer_list_fini(&instance->transfers_bulk_full); \ 253 256 transfer_list_fini(&instance->transfers_control_full); \ … … 255 258 transfer_list_fini(&instance->transfers_interrupt); \ 256 259 return ret; \ 257 } else (void) 0 258 259 /* initialize TODO: check errors */ 260 int ret; 261 ret = transfer_list_init(&instance->transfers_bulk_full, "BULK_FULL"); 262 CHECK_RET_CLEAR_RETURN(ret, "Failed to init BULK list."); 263 264 ret = transfer_list_init( 265 &instance->transfers_control_full, "CONTROL_FULL"); 266 CHECK_RET_CLEAR_RETURN(ret, "Failed to init CONTROL FULL list."); 267 268 ret = transfer_list_init( 269 &instance->transfers_control_slow, "CONTROL_SLOW"); 270 CHECK_RET_CLEAR_RETURN(ret, "Failed to init CONTROL SLOW list."); 271 272 ret = transfer_list_init(&instance->transfers_interrupt, "INTERRUPT"); 273 CHECK_RET_CLEAR_RETURN(ret, "Failed to init INTERRUPT list."); 274 260 } \ 261 } while (0) 262 263 SETUP_TRANSFER_LIST(bulk_full, "BULK FULL"); 264 SETUP_TRANSFER_LIST(control_full, "CONTROL FULL"); 265 SETUP_TRANSFER_LIST(control_slow, "CONTROL LOW"); 266 SETUP_TRANSFER_LIST(interrupt, "INTERRUPT"); 267 #undef SETUP_TRANSFER_LIST 268 /* Connect lists into one schedule */ 275 269 transfer_list_set_next(&instance->transfers_control_full, 276 270 &instance->transfers_bulk_full); … … 337 331 assert(instance); 338 332 // status |= 1; //Uncomment to work around qemu hang 339 /* TODO: Resume interrupts are not supported */340 333 /* Lower 2 bits are transaction error and transaction complete */ 341 if (status & 0x3) {334 if (status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) { 342 335 LIST_INITIALIZE(done); 343 336 transfer_list_remove_finished( … … 358 351 } 359 352 } 360 /* bits 4 and 5 indicate hc error */ 361 if (status & 0x18) { 353 /* Resume interrupts are not supported */ 354 355 /* Bits 4 and 5 indicate hc error */ 356 if (status & (UHCI_STATUS_PROCESS_ERROR | UHCI_STATUS_SYSTEM_ERROR)) { 362 357 usb_log_error("UHCI hardware failure!.\n"); 363 358 ++instance->hw_failures; … … 389 384 390 385 while (1) { 391 /* read and ack interrupts*/386 /* Readd and clear status register */ 392 387 uint16_t status = pio_read_16(&instance->registers->usbsts); 393 pio_write_16(&instance->registers->usbsts, 0x1f);388 pio_write_16(&instance->registers->usbsts, status); 394 389 if (status != 0) 395 390 usb_log_debug2("UHCI status: %x.\n", status); 396 391 hc_interrupt(instance, status); 397 async_usleep(UHCI_ CLEANER_TIMEOUT);392 async_usleep(UHCI_INT_EMULATOR_TIMEOUT); 398 393 } 399 394 return EOK; -
uspace/drv/uhci-hcd/hc.h
ra39cfb8 re05d6c3 88 88 89 89 #define UHCI_FRAME_LIST_COUNT 1024 90 #define UHCI_ CLEANER_TIMEOUT 1000090 #define UHCI_INT_EMULATOR_TIMEOUT 10000 91 91 #define UHCI_DEBUGER_TIMEOUT 5000000 92 92 #define UHCI_ALLOWED_HW_FAIL 5 -
uspace/drv/uhci-hcd/main.c
ra39cfb8 re05d6c3 78 78 device->driver_data = uhci; 79 79 80 usb_log_info("Controlling new UHCI device `%s'.\n", device->name);80 usb_log_info("Controlling new UHCI device '%s'.\n", device->name); 81 81 82 82 return EOK; -
uspace/drv/uhci-rhd/port.c
ra39cfb8 re05d6c3 68 68 * @return Error code. (Always EOK) 69 69 */ 70 static inline void uhci_port_write_status( 71 uhci_port_t *port, port_status_t value) 72 { 73 assert(port); 74 pio_write_16(port->address, value); 70 static inline void uhci_port_write_status(uhci_port_t *port, port_status_t val) 71 { 72 assert(port); 73 pio_write_16(port->address, val); 75 74 } 76 75 /*----------------------------------------------------------------------------*/ … … 101 100 port->rh = rh; 102 101 103 int r c = usb_hc_connection_initialize_from_device(104 &port->hc_connection, rh);105 if (r c!= EOK) {102 int ret = 103 usb_hc_connection_initialize_from_device(&port->hc_connection, rh); 104 if (ret != EOK) { 106 105 usb_log_error("Failed to initialize connection to HC."); 107 return r c;106 return ret; 108 107 } 109 108 … … 238 237 /* Enable the port. */ 239 238 uhci_port_set_enabled(port, true); 240 241 239 return EOK; 242 240 } … … 271 269 usb_log_info("New device at port %u, address %d (handle %llu).\n", 272 270 port->number, dev_addr, port->attached_device); 273 274 271 return EOK; 275 272 } … … 313 310 /* Write new value. */ 314 311 uhci_port_write_status(port, port_status); 312 313 /* Wait for port to become enabled */ 314 do { 315 async_usleep(1000); 316 port_status = uhci_port_read_status(port); 317 } while ((port_status & STATUS_CONNECTED) && 318 !(port_status & STATUS_ENABLED)); 315 319 316 320 usb_log_debug("%s: %sabled port.\n", -
uspace/drv/uhci-rhd/port.h
ra39cfb8 re05d6c3 54 54 #define STATUS_SUSPEND (1 << 12) 55 55 56 /** UHCI port structure */ 56 57 typedef struct uhci_port 57 58 { -
uspace/drv/uhci-rhd/root_hub.c
ra39cfb8 re05d6c3 33 33 */ 34 34 #include <errno.h> 35 #include <str_error.h> 35 36 #include <ddi.h> 36 37 #include <usb/debug.h> … … 43 44 * @param[in] addr Address of I/O registers. 44 45 * @param[in] size Size of available I/O space. 45 * @param[in] rh Pointer to ddfinstance of the root hub driver.46 * @param[in] rh Pointer to DDF instance of the root hub driver. 46 47 * @return Error code. 47 48 */ … … 58 59 if (ret < 0) { 59 60 usb_log_error( 60 "Failed(%d) to gain access to port registers at %p \n",61 ret, regs );61 "Failed(%d) to gain access to port registers at %p: %s.\n", 62 ret, regs, str_error(ret)); 62 63 return ret; 63 64 } … … 66 67 unsigned i = 0; 67 68 for (; i < UHCI_ROOT_HUB_PORT_COUNT; ++i) { 68 /* NOTE: mind pointer arithmetics here */69 69 ret = uhci_port_init( 70 &instance->ports[i], regs + i, i, ROOT_HUB_WAIT_USEC, rh);70 &instance->ports[i], ®s[i], i, ROOT_HUB_WAIT_USEC, rh); 71 71 if (ret != EOK) { 72 72 unsigned j = 0; -
uspace/drv/uhci-rhd/root_hub.h
ra39cfb8 re05d6c3 42 42 #define ROOT_HUB_WAIT_USEC 250000 /* 250 miliseconds */ 43 43 44 /** UHCI root hub drvier structure */ 44 45 typedef struct root_hub { 46 /** Ports provided by the hub */ 45 47 uhci_port_t ports[UHCI_ROOT_HUB_PORT_COUNT]; 46 devman_handle_t hc_handle;47 48 } uhci_root_hub_t; 48 49 49 50 int uhci_root_hub_init( 50 uhci_root_hub_t *instance, void *addr, size_t size, ddf_dev_t *rh);51 uhci_root_hub_t *instance, void *addr, size_t size, ddf_dev_t *rh); 51 52 52 53 void uhci_root_hub_fini(uhci_root_hub_t *instance); -
uspace/drv/usbhid/main.c
ra39cfb8 re05d6c3 42 42 43 43 #include <usb/devdrv.h> 44 #include <usb/devpoll.h> 44 45 45 46 #include "usbhid.h" -
uspace/drv/usbhub/usbhub.c
ra39cfb8 re05d6c3 45 45 #include <usb/request.h> 46 46 #include <usb/classes/hub.h> 47 #include <usb/devpoll.h> 47 48 #include <stdio.h> 48 49 -
uspace/drv/usbkbd/main.c
ra39cfb8 re05d6c3 42 42 43 43 #include <usb/devdrv.h> 44 #include <usb/devpoll.h> 44 45 45 46 #include "kbddev.h" -
uspace/drv/usbmouse/main.c
ra39cfb8 re05d6c3 36 36 #include "mouse.h" 37 37 #include <usb/debug.h> 38 #include <usb/devpoll.h> 38 39 #include <errno.h> 39 40 #include <str_error.h> -
uspace/lib/usb/include/usb/devdrv.h
ra39cfb8 re05d6c3 162 162 usb_endpoint_description_t **); 163 163 164 typedef bool (*usb_polling_callback_t)(usb_device_t *,165 uint8_t *, size_t, void *);166 typedef void (*usb_polling_terminted_callback_t)(usb_device_t *, bool, void *);167 168 int usb_device_auto_poll(usb_device_t *, size_t,169 usb_polling_callback_t, size_t, usb_polling_terminted_callback_t, void *);170 171 164 int usb_device_retrieve_descriptors(usb_pipe_t *, usb_device_descriptors_t *); 172 165 int usb_device_create_pipes(ddf_dev_t *, usb_device_connection_t *, -
uspace/lib/usb/include/usb/pipes.h
ra39cfb8 re05d6c3 99 99 /** Number of active transfers over the pipe. */ 100 100 int refcount; 101 102 /** Whether to automatically reset halt on the endpoint. 103 * Valid only for control endpoint zero. 104 */ 105 bool auto_reset_halt; 101 106 } usb_pipe_t; 102 107 -
uspace/lib/usb/src/devpoll.c
ra39cfb8 re05d6c3 33 33 * USB device driver framework - automatic interrupt polling. 34 34 */ 35 #include <usb/dev drv.h>35 #include <usb/devpoll.h> 36 36 #include <usb/request.h> 37 37 #include <usb/debug.h> 38 #include <usb/classes/classes.h> 38 39 #include <errno.h> 39 40 #include <str_error.h> … … 45 46 /** Data needed for polling. */ 46 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 *); 55 47 56 usb_device_t *dev; 48 57 size_t pipe_index; 49 usb_polling_callback_t callback;50 usb_polling_terminted_callback_t terminated_callback;51 58 size_t request_size; 52 59 uint8_t *buffer; … … 54 61 } polling_data_t; 55 62 63 56 64 /** Polling fibril. 57 65 * … … 67 75 = polling_data->dev->pipes[polling_data->pipe_index].pipe; 68 76 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); 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("Poll0x%x: 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 } 74 90 75 91 size_t failed_attempts = 0; 76 while (failed_attempts < MAX_FAILED_ATTEMPTS) {92 while (failed_attempts <= polling_data->max_failures) { 77 93 int rc; 78 94 … … 81 97 polling_data->request_size, &actual_size); 82 98 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 // } 99 if (polling_data->debug > 1) { 100 if (rc == EOK) { 101 usb_log_debug( 102 "Poll0x%x: 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 "Poll0x%x: 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 } 90 124 91 125 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 } 134 } 92 135 failed_attempts++; 93 136 continue; … … 95 138 96 139 /* We have the data, execute the callback now. */ 97 bool carry_on = polling_data-> callback(polling_data->dev,140 bool carry_on = polling_data->on_data(polling_data->dev, 98 141 polling_data->buffer, actual_size, 99 142 polling_data->custom_arg); … … 106 149 /* Reset as something might be only a temporary problem. */ 107 150 failed_attempts = 0; 108 } 109 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); 114 } 115 116 if (polling_data->terminated_callback != NULL) { 117 polling_data->terminated_callback(polling_data->dev, 151 152 /* 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, 118 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"); 167 } else { 168 usb_log_debug( 169 "Polling of device `%s' terminated by user.\n", 170 polling_data->dev->ddf_dev->name 171 ); 172 } 119 173 } 120 174 … … 159 213 } 160 214 215 usb_device_auto_polling_t *auto_polling 216 = 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 structure 240 * after this function returns. 241 * 242 * @warning There is no guarantee when the request to the device 243 * will be sent for the first time (it is possible that this 244 * 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 161 272 polling_data_t *polling_data = malloc(sizeof(polling_data_t)); 162 273 if (polling_data == NULL) { … … 164 275 } 165 276 166 /* Allocate now to prevent immediate failure in the polling fibril. */167 polling_data->buffer = malloc( request_size);277 /* Fill-in the data. */ 278 polling_data->buffer = malloc(sizeof(request_size)); 168 279 if (polling_data->buffer == NULL) { 169 280 free(polling_data); 170 281 return ENOMEM; 171 282 } 283 polling_data->request_size = request_size; 172 284 polling_data->dev = dev; 173 285 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 286 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; 178 301 179 302 fid_t fibril = fibril_create(polling_fibril, polling_data); … … 181 304 free(polling_data->buffer); 182 305 free(polling_data); 183 /* FIXME: better error code. */184 306 return ENOMEM; 185 307 } 186 308 fibril_add_ready(fibril); 187 309 188 /* The allocated buffer etc. will be freed by the fibril. */310 /* Fibril launched. That fibril will free the allocated data. */ 189 311 190 312 return EOK; -
uspace/lib/usb/src/host/endpoint.c
ra39cfb8 re05d6c3 123 123 if (instance->address == target.address && 124 124 (instance->endpoint == target.endpoint || target.endpoint == 0)) 125 instance->toggle = 0;125 endpoint_toggle_set(instance, 0); 126 126 } 127 127 /** -
uspace/lib/usb/src/pipesinit.c
ra39cfb8 re05d6c3 365 365 pipe->direction = direction; 366 366 pipe->refcount = 0; 367 pipe->auto_reset_halt = false; 367 368 368 369 return EOK; … … 385 386 0, USB_TRANSFER_CONTROL, CTRL_PIPE_MIN_PACKET_SIZE, 386 387 USB_DIRECTION_BOTH); 388 389 pipe->auto_reset_halt = true; 387 390 388 391 return rc; -
uspace/lib/usb/src/pipesio.c
ra39cfb8 re05d6c3 49 49 #include <assert.h> 50 50 #include <usbhc_iface.h> 51 #include <usb/request.h> 51 52 #include "pipepriv.h" 52 53 … … 307 308 } 308 309 310 /** Try to clear endpoint halt of default control pipe. 311 * 312 * @param pipe Pipe for control endpoint zero. 313 */ 314 static void clear_self_endpoint_halt(usb_pipe_t *pipe) 315 { 316 assert(pipe != NULL); 317 318 if (!pipe->auto_reset_halt || (pipe->endpoint_no != 0)) { 319 return; 320 } 321 322 323 /* Prevent indefinite recursion. */ 324 pipe->auto_reset_halt = false; 325 usb_request_clear_endpoint_halt(pipe, 0); 326 pipe->auto_reset_halt = true; 327 } 328 309 329 310 330 /** Request a control read transfer, no checking of input parameters. … … 436 456 setup_buffer, setup_buffer_size, 437 457 data_buffer, data_buffer_size, &act_size); 458 459 if (rc == ESTALL) { 460 clear_self_endpoint_halt(pipe); 461 } 438 462 439 463 pipe_drop_ref(pipe); … … 563 587 setup_buffer, setup_buffer_size, data_buffer, data_buffer_size); 564 588 589 if (rc == ESTALL) { 590 clear_self_endpoint_halt(pipe); 591 } 592 565 593 pipe_drop_ref(pipe); 566 594
Note:
See TracChangeset
for help on using the changeset viewer.