Changes in / [e05d6c3:a39cfb8] in mainline
- Location:
- uspace
- Files:
-
- 1 deleted
- 22 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/ohci/batch.c
re05d6c3 ra39cfb8 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;168 163 break; 169 164 } … … 174 169 assert(hcd_ep); 175 170 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));181 171 182 172 return true; -
uspace/drv/ohci/hcd_endpoint.c
re05d6c3 ra39cfb8 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 53 37 hcd_endpoint_t * hcd_endpoint_assign(endpoint_t *ep) 54 38 { … … 73 57 ed_init(hcd_ep->ed, ep); 74 58 ed_set_td(hcd_ep->ed, hcd_ep->td); 75 endpoint_set_hc_data(ep, hcd_ep, hcd_ep_toggle_get, hcd_ep_toggle_set);59 endpoint_set_hc_data(ep, hcd_ep, NULL, NULL); 76 60 77 61 return hcd_ep; -
uspace/drv/ohci/hw_struct/endpoint_descriptor.h
re05d6c3 ra39cfb8 73 73 #define ED_TDHEAD_ZERO_SHIFT (2) 74 74 #define ED_TDHEAD_TOGGLE_CARRY (0x2) 75 #define ED_TDHEAD_HALTED_FLAG (0x1)76 75 77 76 volatile uint32_t next; … … 107 106 instance->next = pa; 108 107 } 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 }128 108 #endif 129 109 /** -
uspace/drv/ohci/ohci_regs.h
re05d6c3 ra39cfb8 55 55 #define C_HCFS_MASK (0x3) /* Host controller functional state */ 56 56 #define C_HCFS_RESET (0x0) 57 #define C_HCFS_ RESUME(0x1)58 #define C_HCFS_ OPERATIONAL(0x2)57 #define C_HCFS_OPERATIONAL (0x1) 58 #define C_HCFS_RESUME (0x2) 59 59 #define C_HCFS_SUSPEND (0x3) 60 60 #define C_HCFS_SHIFT (6) -
uspace/drv/ohci/root_hub.h
re05d6c3 ra39cfb8 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;58 56 } rh_t; 59 57 -
uspace/drv/uhci-hcd/hc.c
re05d6c3 ra39cfb8 247 247 { 248 248 assert(instance); 249 #define SETUP_TRANSFER_LIST(type, name) \ 250 do { \ 251 int ret = transfer_list_init(&instance->transfers_##type, name); \ 249 #define CHECK_RET_CLEAR_RETURN(ret, message...) \ 252 250 if (ret != EOK) { \ 253 usb_log_error("Failed(%d) to setup %s transfer list: %s.\n", \ 254 ret, name, str_error(ret)); \ 251 usb_log_error(message); \ 255 252 transfer_list_fini(&instance->transfers_bulk_full); \ 256 253 transfer_list_fini(&instance->transfers_control_full); \ … … 258 255 transfer_list_fini(&instance->transfers_interrupt); \ 259 256 return ret; \ 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 */ 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 269 275 transfer_list_set_next(&instance->transfers_control_full, 270 276 &instance->transfers_bulk_full); … … 331 337 assert(instance); 332 338 // status |= 1; //Uncomment to work around qemu hang 339 /* TODO: Resume interrupts are not supported */ 333 340 /* Lower 2 bits are transaction error and transaction complete */ 334 if (status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) {341 if (status & 0x3) { 335 342 LIST_INITIALIZE(done); 336 343 transfer_list_remove_finished( … … 351 358 } 352 359 } 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)) { 360 /* bits 4 and 5 indicate hc error */ 361 if (status & 0x18) { 357 362 usb_log_error("UHCI hardware failure!.\n"); 358 363 ++instance->hw_failures; … … 384 389 385 390 while (1) { 386 /* Readd and clear status register*/391 /* read and ack interrupts */ 387 392 uint16_t status = pio_read_16(&instance->registers->usbsts); 388 pio_write_16(&instance->registers->usbsts, status);393 pio_write_16(&instance->registers->usbsts, 0x1f); 389 394 if (status != 0) 390 395 usb_log_debug2("UHCI status: %x.\n", status); 391 396 hc_interrupt(instance, status); 392 async_usleep(UHCI_ INT_EMULATOR_TIMEOUT);397 async_usleep(UHCI_CLEANER_TIMEOUT); 393 398 } 394 399 return EOK; -
uspace/drv/uhci-hcd/hc.h
re05d6c3 ra39cfb8 88 88 89 89 #define UHCI_FRAME_LIST_COUNT 1024 90 #define UHCI_ INT_EMULATOR_TIMEOUT 1000090 #define UHCI_CLEANER_TIMEOUT 10000 91 91 #define UHCI_DEBUGER_TIMEOUT 5000000 92 92 #define UHCI_ALLOWED_HW_FAIL 5 -
uspace/drv/uhci-hcd/main.c
re05d6c3 ra39cfb8 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
re05d6c3 ra39cfb8 68 68 * @return Error code. (Always EOK) 69 69 */ 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); 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); 74 75 } 75 76 /*----------------------------------------------------------------------------*/ … … 100 101 port->rh = rh; 101 102 102 int r et =103 usb_hc_connection_initialize_from_device(&port->hc_connection, rh);104 if (r et!= EOK) {103 int rc = usb_hc_connection_initialize_from_device( 104 &port->hc_connection, rh); 105 if (rc != EOK) { 105 106 usb_log_error("Failed to initialize connection to HC."); 106 return r et;107 return rc; 107 108 } 108 109 … … 237 238 /* Enable the port. */ 238 239 uhci_port_set_enabled(port, true); 240 239 241 return EOK; 240 242 } … … 269 271 usb_log_info("New device at port %u, address %d (handle %llu).\n", 270 272 port->number, dev_addr, port->attached_device); 273 271 274 return EOK; 272 275 } … … 310 313 /* Write new value. */ 311 314 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));319 315 320 316 usb_log_debug("%s: %sabled port.\n", -
uspace/drv/uhci-rhd/port.h
re05d6c3 ra39cfb8 54 54 #define STATUS_SUSPEND (1 << 12) 55 55 56 /** UHCI port structure */57 56 typedef struct uhci_port 58 57 { -
uspace/drv/uhci-rhd/root_hub.c
re05d6c3 ra39cfb8 33 33 */ 34 34 #include <errno.h> 35 #include <str_error.h>36 35 #include <ddi.h> 37 36 #include <usb/debug.h> … … 44 43 * @param[in] addr Address of I/O registers. 45 44 * @param[in] size Size of available I/O space. 46 * @param[in] rh Pointer to DDFinstance of the root hub driver.45 * @param[in] rh Pointer to ddf instance of the root hub driver. 47 46 * @return Error code. 48 47 */ … … 59 58 if (ret < 0) { 60 59 usb_log_error( 61 "Failed(%d) to gain access to port registers at %p : %s.\n",62 ret, regs , str_error(ret));60 "Failed(%d) to gain access to port registers at %p\n", 61 ret, regs); 63 62 return ret; 64 63 } … … 67 66 unsigned i = 0; 68 67 for (; i < UHCI_ROOT_HUB_PORT_COUNT; ++i) { 68 /* NOTE: mind pointer arithmetics here */ 69 69 ret = uhci_port_init( 70 &instance->ports[i], ®s[i], i, ROOT_HUB_WAIT_USEC, rh);70 &instance->ports[i], regs + i, i, ROOT_HUB_WAIT_USEC, rh); 71 71 if (ret != EOK) { 72 72 unsigned j = 0; -
uspace/drv/uhci-rhd/root_hub.h
re05d6c3 ra39cfb8 42 42 #define ROOT_HUB_WAIT_USEC 250000 /* 250 miliseconds */ 43 43 44 /** UHCI root hub drvier structure */45 44 typedef struct root_hub { 46 /** Ports provided by the hub */47 45 uhci_port_t ports[UHCI_ROOT_HUB_PORT_COUNT]; 46 devman_handle_t hc_handle; 48 47 } uhci_root_hub_t; 49 48 50 49 int uhci_root_hub_init( 51 50 uhci_root_hub_t *instance, void *addr, size_t size, ddf_dev_t *rh); 52 51 53 52 void uhci_root_hub_fini(uhci_root_hub_t *instance); -
uspace/drv/usbhid/main.c
re05d6c3 ra39cfb8 42 42 43 43 #include <usb/devdrv.h> 44 #include <usb/devpoll.h>45 44 46 45 #include "usbhid.h" -
uspace/drv/usbhub/usbhub.c
re05d6c3 ra39cfb8 45 45 #include <usb/request.h> 46 46 #include <usb/classes/hub.h> 47 #include <usb/devpoll.h>48 47 #include <stdio.h> 49 48 -
uspace/drv/usbkbd/main.c
re05d6c3 ra39cfb8 42 42 43 43 #include <usb/devdrv.h> 44 #include <usb/devpoll.h>45 44 46 45 #include "kbddev.h" -
uspace/drv/usbmouse/main.c
re05d6c3 ra39cfb8 36 36 #include "mouse.h" 37 37 #include <usb/debug.h> 38 #include <usb/devpoll.h>39 38 #include <errno.h> 40 39 #include <str_error.h> -
uspace/lib/usb/include/usb/devdrv.h
re05d6c3 ra39cfb8 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 164 171 int usb_device_retrieve_descriptors(usb_pipe_t *, usb_device_descriptors_t *); 165 172 int usb_device_create_pipes(ddf_dev_t *, usb_device_connection_t *, -
uspace/lib/usb/include/usb/pipes.h
re05d6c3 ra39cfb8 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;106 101 } usb_pipe_t; 107 102 -
uspace/lib/usb/src/devpoll.c
re05d6c3 ra39cfb8 33 33 * USB device driver framework - automatic interrupt polling. 34 34 */ 35 #include <usb/dev poll.h>35 #include <usb/devdrv.h> 36 36 #include <usb/request.h> 37 37 #include <usb/debug.h> 38 #include <usb/classes/classes.h>39 38 #include <errno.h> 40 39 #include <str_error.h> … … 46 45 /** Data needed for polling. */ 47 46 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 56 47 usb_device_t *dev; 57 48 size_t pipe_index; 49 usb_polling_callback_t callback; 50 usb_polling_terminted_callback_t terminated_callback; 58 51 size_t request_size; 59 52 uint8_t *buffer; 60 53 void *custom_arg; 61 54 } polling_data_t; 62 63 55 64 56 /** Polling fibril. … … 75 67 = polling_data->dev->pipes[polling_data->pipe_index].pipe; 76 68 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 } 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); 90 74 91 75 size_t failed_attempts = 0; 92 while (failed_attempts < = polling_data->max_failures) {76 while (failed_attempts < MAX_FAILED_ATTEMPTS) { 93 77 int rc; 94 78 … … 97 81 polling_data->request_size, &actual_size); 98 82 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 } 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 // } 124 90 125 91 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_attempts132 = polling_data->max_failures;133 }134 }135 92 failed_attempts++; 136 93 continue; … … 138 95 139 96 /* We have the data, execute the callback now. */ 140 bool carry_on = polling_data-> on_data(polling_data->dev,97 bool carry_on = polling_data->callback(polling_data->dev, 141 98 polling_data->buffer, actual_size, 142 99 polling_data->custom_arg); … … 149 106 /* Reset as something might be only a temporary problem. */ 150 107 failed_attempts = 0; 151 152 /* Take a rest before next request. */153 async_usleep(polling_data->delay);154 108 } 155 109 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); 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); 159 114 } 160 115 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 } 116 if (polling_data->terminated_callback != NULL) { 117 polling_data->terminated_callback(polling_data->dev, 118 failed_attempts > 0, polling_data->custom_arg); 173 119 } 174 120 … … 213 159 } 214 160 215 usb_device_auto_polling_t *auto_polling216 = 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 structure240 * after this function returns.241 *242 * @warning There is no guarantee when the request to the device243 * will be sent for the first time (it is possible that this244 * 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 272 161 polling_data_t *polling_data = malloc(sizeof(polling_data_t)); 273 162 if (polling_data == NULL) { … … 275 164 } 276 165 277 /* Fill-in the data. */278 polling_data->buffer = malloc( sizeof(request_size));166 /* Allocate now to prevent immediate failure in the polling fibril. */ 167 polling_data->buffer = malloc(request_size); 279 168 if (polling_data->buffer == NULL) { 280 169 free(polling_data); 281 170 return ENOMEM; 282 171 } 283 polling_data->request_size = request_size;284 172 polling_data->dev = dev; 285 173 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; 286 177 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;301 178 302 179 fid_t fibril = fibril_create(polling_fibril, polling_data); … … 304 181 free(polling_data->buffer); 305 182 free(polling_data); 183 /* FIXME: better error code. */ 306 184 return ENOMEM; 307 185 } 308 186 fibril_add_ready(fibril); 309 187 310 /* Fibril launched. That fibril will free the allocated data. */188 /* The allocated buffer etc. will be freed by the fibril. */ 311 189 312 190 return EOK; -
uspace/lib/usb/src/host/endpoint.c
re05d6c3 ra39cfb8 123 123 if (instance->address == target.address && 124 124 (instance->endpoint == target.endpoint || target.endpoint == 0)) 125 endpoint_toggle_set(instance, 0);125 instance->toggle = 0; 126 126 } 127 127 /** -
uspace/lib/usb/src/pipesinit.c
re05d6c3 ra39cfb8 365 365 pipe->direction = direction; 366 366 pipe->refcount = 0; 367 pipe->auto_reset_halt = false;368 367 369 368 return EOK; … … 386 385 0, USB_TRANSFER_CONTROL, CTRL_PIPE_MIN_PACKET_SIZE, 387 386 USB_DIRECTION_BOTH); 388 389 pipe->auto_reset_halt = true;390 387 391 388 return rc; -
uspace/lib/usb/src/pipesio.c
re05d6c3 ra39cfb8 49 49 #include <assert.h> 50 50 #include <usbhc_iface.h> 51 #include <usb/request.h>52 51 #include "pipepriv.h" 53 52 … … 308 307 } 309 308 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 329 309 330 310 /** Request a control read transfer, no checking of input parameters. … … 457 437 data_buffer, data_buffer_size, &act_size); 458 438 459 if (rc == ESTALL) {460 clear_self_endpoint_halt(pipe);461 }462 463 439 pipe_drop_ref(pipe); 464 440 … … 587 563 setup_buffer, setup_buffer_size, data_buffer, data_buffer_size); 588 564 589 if (rc == ESTALL) {590 clear_self_endpoint_halt(pipe);591 }592 593 565 pipe_drop_ref(pipe); 594 566
Note:
See TracChangeset
for help on using the changeset viewer.