Changeset f58154c5 in mainline
- Timestamp:
- 2011-05-18T10:59:50Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 17fc40c
- Parents:
- b2995c3 (diff), aeca5a3 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Files:
-
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
.bzrignore
rb2995c3 rf58154c5 53 53 ./uspace/app/klog/klog 54 54 ./uspace/app/lsusb/lsusb 55 ./uspace/app/mkbd/mkbd 55 56 ./uspace/app/mkfat/mkfat 56 57 ./uspace/app/netstart/netstart -
uspace/drv/ohci/batch.c
rb2995c3 rf58154c5 44 44 #include "hw_struct/transfer_descriptor.h" 45 45 46 /** OHCI specific data required for USB transfer */ 46 47 typedef struct ohci_transfer_batch { 48 /** Endpoint descriptor of the target endpoint. */ 47 49 ed_t *ed; 50 /** List of TDs needed for the transfer */ 48 51 td_t **tds; 52 /** Number of TDs used by the transfer */ 49 53 size_t td_count; 54 /** Dummy TD to be left at the ED and used by the next transfer */ 50 55 size_t leave_td; 51 char *device_buffer; 56 /** Data buffer, must be accessible byb the OHCI hw. */ 57 void *device_buffer; 52 58 } ohci_transfer_batch_t; 53 59 /*----------------------------------------------------------------------------*/ 60 static void batch_control(usb_transfer_batch_t *instance, 61 usb_direction_t data_dir, usb_direction_t status_dir); 62 static void batch_data(usb_transfer_batch_t *instance); 63 /*----------------------------------------------------------------------------*/ 64 /** Safely destructs ohci_transfer_batch_t structure 65 * 66 * @param[in] ohci_batch Instance to destroy. 67 */ 54 68 static void ohci_transfer_batch_dispose(void *ohci_batch) 55 69 { … … 69 83 } 70 84 /*----------------------------------------------------------------------------*/ 71 static void batch_control(usb_transfer_batch_t *instance, 72 usb_direction_t data_dir, usb_direction_t status_dir); 73 static void batch_data(usb_transfer_batch_t *instance); 74 /*----------------------------------------------------------------------------*/ 85 /** Allocate memory initialize internal structures 86 * 87 * @param[in] fun DDF function to pass to callback. 88 * @param[in] ep Communication target 89 * @param[in] buffer Data source/destination. 90 * @param[in] buffer_size Size of the buffer. 91 * @param[in] setup_buffer Setup data source (if not NULL) 92 * @param[in] setup_size Size of setup_buffer (should be always 8) 93 * @param[in] func_in function to call on inbound transfer completion 94 * @param[in] func_out function to call on outbound transfer completion 95 * @param[in] arg additional parameter to func_in or func_out 96 * @return Valid pointer if all structures were successfully created, 97 * NULL otherwise. 98 * 99 * Allocates and initializes structures needed by the OHCI hw for the transfer. 100 */ 75 101 usb_transfer_batch_t * batch_get(ddf_fun_t *fun, endpoint_t *ep, 76 102 char *buffer, size_t buffer_size, char* setup_buffer, size_t setup_size, … … 107 133 } 108 134 109 /* we need one extra place for tdthat is currently assigned to hcd_ep*/135 /* We need an extra place for TD that is currently assigned to hcd_ep*/ 110 136 data->tds = calloc(sizeof(td_t*), data->td_count + 1); 111 137 CHECK_NULL_DISPOSE_RETURN(data->tds, 112 138 "Failed to allocate transfer descriptors.\n"); 113 139 140 /* Add TD left over by the previous transfer */ 114 141 data->tds[0] = hcd_ep->td; 115 142 data->leave_td = 0; … … 123 150 data->ed = hcd_ep->ed; 124 151 152 /* NOTE: OHCI is capable of handling buffer that crosses page boundaries 153 * it is, however, not capable of handling buffer that occupies more 154 * than two pages (the first page is computed using start pointer, the 155 * other using the end pointer) */ 125 156 if (setup_size + buffer_size > 0) { 126 157 data->device_buffer = malloc32(setup_size + buffer_size); … … 135 166 } 136 167 /*----------------------------------------------------------------------------*/ 168 /** Check batch TDs' status. 169 * 170 * @param[in] instance Batch structure to use. 171 * @return False, if there is an active TD, true otherwise. 172 * 173 * Walk all TDs (usually there is just one). Stop with false if there is an 174 * active TD. Stop with true if an error is found. Return true if the walk 175 * completes with the last TD. 176 */ 137 177 bool batch_is_complete(usb_transfer_batch_t *instance) 138 178 { … … 140 180 ohci_transfer_batch_t *data = instance->private_data; 141 181 assert(data); 142 size_t tds = data->td_count;143 182 usb_log_debug("Batch(%p) checking %zu td(s) for completion.\n", 144 instance, tds);183 instance, data->td_count); 145 184 usb_log_debug("ED: %x:%x:%x:%x.\n", 146 185 data->ed->status, data->ed->td_head, data->ed->td_tail, … … 148 187 size_t i = 0; 149 188 instance->transfered_size = instance->buffer_size; 150 for (; i < tds; ++i) {189 for (; i < data->td_count; ++i) { 151 190 assert(data->tds[i] != NULL); 152 191 usb_log_debug("TD %zu: %x:%x:%x:%x.\n", i, … … 173 212 assert(hcd_ep); 174 213 hcd_ep->td = data->tds[i]; 175 if (i > 0) 176 instance->transfered_size -= td_remain_size(data->tds[i - 1]); 214 assert(i > 0); 215 for (--i;i < data->td_count; ++i) 216 instance->transfered_size -= td_remain_size(data->tds[i]); 177 217 178 218 /* Clear possible ED HALT */ 179 219 data->ed->td_head &= ~ED_TDHEAD_HALTED_FLAG; 180 uint32_t pa = addr_to_phys(hcd_ep->td);220 const uint32_t pa = addr_to_phys(hcd_ep->td); 181 221 assert(pa == (data->ed->td_head & ED_TDHEAD_PTR_MASK)); 182 222 assert(pa == (data->ed->td_tail & ED_TDTAIL_PTR_MASK)); … … 185 225 } 186 226 /*----------------------------------------------------------------------------*/ 227 /** Starts execution of the TD list 228 * 229 * @param[in] instance Batch structure to use 230 */ 187 231 void batch_commit(usb_transfer_batch_t *instance) 188 232 { … … 193 237 } 194 238 /*----------------------------------------------------------------------------*/ 239 /** Prepares control write transfer. 240 * 241 * @param[in] instance Batch structure to use. 242 * 243 * Uses generic control transfer using direction OUT(data stage) and 244 * IN(status stage). 245 */ 195 246 void batch_control_write(usb_transfer_batch_t *instance) 196 247 { … … 203 254 } 204 255 /*----------------------------------------------------------------------------*/ 256 /** Prepares control read transfer. 257 * 258 * @param[in] instance Batch structure to use. 259 * 260 * Uses generic control transfer using direction IN(data stage) and 261 * OUT(status stage). 262 */ 205 263 void batch_control_read(usb_transfer_batch_t *instance) 206 264 { … … 211 269 } 212 270 /*----------------------------------------------------------------------------*/ 271 /** Prepare interrupt in transfer. 272 * 273 * @param[in] instance Batch structure to use. 274 * 275 * Data transfer. 276 */ 213 277 void batch_interrupt_in(usb_transfer_batch_t *instance) 214 278 { … … 219 283 } 220 284 /*----------------------------------------------------------------------------*/ 285 /** Prepare interrupt out transfer. 286 * 287 * @param[in] instance Batch structure to use. 288 * 289 * Data transfer. 290 */ 221 291 void batch_interrupt_out(usb_transfer_batch_t *instance) 222 292 { … … 229 299 } 230 300 /*----------------------------------------------------------------------------*/ 301 /** Prepare bulk in transfer. 302 * 303 * @param[in] instance Batch structure to use. 304 * 305 * Data transfer. 306 */ 231 307 void batch_bulk_in(usb_transfer_batch_t *instance) 232 308 { … … 237 313 } 238 314 /*----------------------------------------------------------------------------*/ 315 /** Prepare bulk out transfer. 316 * 317 * @param[in] instance Batch structure to use. 318 * 319 * Data transfer. 320 */ 239 321 void batch_bulk_out(usb_transfer_batch_t *instance) 240 322 { … … 247 329 } 248 330 /*----------------------------------------------------------------------------*/ 249 ed_t * batch_ed(usb_transfer_batch_t *instance) 250 { 251 assert(instance); 252 ohci_transfer_batch_t *data = instance->private_data; 253 assert(data); 254 return data->ed; 255 } 256 /*----------------------------------------------------------------------------*/ 331 /** Prepare generic control transfer 332 * 333 * @param[in] instance Batch structure to use. 334 * @param[in] data_dir Direction to use for data stage. 335 * @param[in] status_dir Direction to use for status stage. 336 * 337 * Setup stage with toggle 0 and direction BOTH(SETUP_PID) 338 * Data stage with alternating toggle and direction supplied by parameter. 339 * Status stage with toggle 1 and direction supplied by parameter. 340 */ 257 341 void batch_control(usb_transfer_batch_t *instance, 258 342 usb_direction_t data_dir, usb_direction_t status_dir) … … 303 387 } 304 388 /*----------------------------------------------------------------------------*/ 389 /** Prepare generic data transfer 390 * 391 * @param[in] instance Batch structure to use. 392 * 393 * Direction is supplied by the associated ep and toggle is maintained by the 394 * OHCI hw in ED. 395 */ 305 396 void batch_data(usb_transfer_batch_t *instance) 306 397 { -
uspace/drv/ohci/batch.h
rb2995c3 rf58154c5 41 41 #include <usb/host/batch.h> 42 42 43 #include "hw_struct/endpoint_descriptor.h"44 45 43 usb_transfer_batch_t * batch_get( 46 44 ddf_fun_t *fun, endpoint_t *ep, char *buffer, size_t size, … … 65 63 66 64 void batch_bulk_out(usb_transfer_batch_t *instance); 67 68 ed_t * batch_ed(usb_transfer_batch_t *instance);69 65 #endif 70 66 /** -
uspace/drv/ohci/endpoint_list.c
rb2995c3 rf58154c5 34 34 #include <errno.h> 35 35 #include <usb/debug.h> 36 #include <arch/barrier.h> 36 37 37 38 #include "endpoint_list.h" … … 43 44 * @return Error code 44 45 * 45 * Allocates memory for internal qh_t structure.46 * Allocates memory for internal ed_t structure. 46 47 */ 47 48 int endpoint_list_init(endpoint_list_t *instance, const char *name) … … 68 69 * @param[in] instance List to lead. 69 70 * @param[in] next List to append. 70 * @return Error code71 71 * 72 * Does not check whether this replaces an existing list 72 * Does not check whether this replaces an existing list. 73 73 */ 74 74 void endpoint_list_set_next(endpoint_list_t *instance, endpoint_list_t *next) … … 79 79 } 80 80 /*----------------------------------------------------------------------------*/ 81 /** Submit transferendpoint to the list and queue.81 /** Add endpoint to the list and queue. 82 82 * 83 83 * @param[in] instance List to use. 84 * @param[in] endpoint Transfer endpoint to submit. 85 * @return Error code 84 * @param[in] endpoint Endpoint to add. 86 85 * 87 86 * The endpoint is added to the end of the list and queue. … … 99 98 /* Add to the hardware queue. */ 100 99 if (list_empty(&instance->endpoint_list)) { 101 /* There is nothing scheduled*/100 /* There are no active EDs */ 102 101 last_ed = instance->list_head; 103 102 } else { 104 /* There is something scheduled*/103 /* There are active EDs, get the last one */ 105 104 hcd_endpoint_t *last = list_get_instance( 106 105 instance->endpoint_list.prev, hcd_endpoint_t, link); 106 assert(last); 107 107 last_ed = last->ed; 108 108 } 109 /* keep link */109 /* Keep link */ 110 110 hcd_ep->ed->next = last_ed->next; 111 /* Make sure ED is written to the memory */ 112 write_barrier(); 113 114 /* Add ed to the hw queue */ 111 115 ed_append_ed(last_ed, hcd_ep->ed); 116 /* Make sure ED is updated */ 117 write_barrier(); 112 118 113 asm volatile ("": : :"memory"); 114 115 /* Add to the driver list */ 119 /* Add to the sw list */ 116 120 list_append(&hcd_ep->link, &instance->endpoint_list); 117 121 … … 129 133 } 130 134 /*----------------------------------------------------------------------------*/ 131 #if 0 132 /** Create list for finished endpoints. 135 /** Remove endpoint from the list and queue. 133 136 * 134 137 * @param[in] instance List to use. 135 * @param[in] done list to fill 136 */ 137 void endpoint_list_remove_finished(endpoint_list_t *instance, link_t *done) 138 { 139 assert(instance); 140 assert(done); 141 142 fibril_mutex_lock(&instance->guard); 143 usb_log_debug2("Checking list %s for completed endpointes(%d).\n", 144 instance->name, list_count(&instance->endpoint_list)); 145 link_t *current = instance->endpoint_list.next; 146 while (current != &instance->endpoint_list) { 147 link_t *next = current->next; 148 hcd_endpoint_t *endpoint = 149 list_get_instance(current, hcd_endpoint_t, link); 150 151 if (endpoint_is_complete(endpoint)) { 152 /* Save for post-processing */ 153 endpoint_list_remove_endpoint(instance, endpoint); 154 list_append(current, done); 155 } 156 current = next; 157 } 158 fibril_mutex_unlock(&instance->guard); 159 } 160 /*----------------------------------------------------------------------------*/ 161 /** Walk the list and abort all endpointes. 162 * 163 * @param[in] instance List to use. 164 */ 165 void endpoint_list_abort_all(endpoint_list_t *instance) 166 { 167 fibril_mutex_lock(&instance->guard); 168 while (!list_empty(&instance->endpoint_list)) { 169 link_t *current = instance->endpoint_list.next; 170 hcd_endpoint_t *endpoint = 171 list_get_instance(current, hcd_endpoint_t, link); 172 endpoint_list_remove_endpoint(instance, endpoint); 173 hcd_endpoint_finish_error(endpoint, EIO); 174 } 175 fibril_mutex_unlock(&instance->guard); 176 } 177 #endif 178 /*----------------------------------------------------------------------------*/ 179 /** Remove a transfer endpoint from the list and queue. 180 * 181 * @param[in] instance List to use. 182 * @param[in] endpoint Transfer endpoint to remove. 183 * @return Error code 184 * 185 * Does not lock the transfer list, caller is responsible for that. 138 * @param[in] endpoint Endpoint to remove. 186 139 */ 187 140 void endpoint_list_remove_ep(endpoint_list_t *instance, hcd_endpoint_t *hcd_ep) … … 212 165 assert((prev_ed->next & ED_NEXT_PTR_MASK) == addr_to_phys(hcd_ep->ed)); 213 166 prev_ed->next = hcd_ep->ed->next; 167 /* Make sure ED is updated */ 168 write_barrier(); 214 169 215 asm volatile ("": : :"memory");216 170 usb_log_debug("HCD EP(%p) removed (%s) from %s, next %x.\n", 217 171 hcd_ep, qpos, instance->name, hcd_ep->ed->next); -
uspace/drv/ohci/endpoint_list.h
rb2995c3 rf58154c5 41 41 #include "utils/malloc32.h" 42 42 43 typedef struct endpoint_list { 43 /** Structure maintains both OHCI queue and software list of active endpoints.*/ 44 typedef struct endpoint_list 45 { 46 /** Guard against add/remove races */ 44 47 fibril_mutex_t guard; 48 /** OHCI hw structure at the beginning of the queue */ 45 49 ed_t *list_head; 50 /** Physical address of the first(dummy) ED */ 46 51 uint32_t list_head_pa; 52 /** Assigned name, provides nicer debug output */ 47 53 const char *name; 54 /** Sw list of all active EDs */ 48 55 link_t endpoint_list; 49 56 } endpoint_list_t; … … 53 60 * @param[in] instance Memory place to use. 54 61 * 55 * Frees memory for internal qh_t structure.62 * Frees memory of the internal ed_t structure. 56 63 */ 57 64 static inline void endpoint_list_fini(endpoint_list_t *instance) … … 68 75 69 76 void endpoint_list_remove_ep(endpoint_list_t *instance, hcd_endpoint_t *hcd_ep); 70 #if 071 void endpoint_list_remove_finished(endpoint_list_t *instance, link_t *done);72 73 void endpoint_list_abort_all(endpoint_list_t *instance);74 #endif75 77 #endif 76 78 /** -
uspace/drv/ohci/hc.c
rb2995c3 rf58154c5 293 293 rh_interrupt(&instance->rh); 294 294 295 296 295 if (status & I_WDH) { 297 296 fibril_mutex_lock(&instance->guard); … … 316 315 fibril_mutex_unlock(&instance->guard); 317 316 } 317 318 if (status & I_UE) { 319 hc_start_hw(instance); 320 } 321 318 322 } 319 323 /*----------------------------------------------------------------------------*/ … … 450 454 { 451 455 assert(instance); 452 453 456 #define SETUP_ENDPOINT_LIST(type) \ 454 457 do { \ … … 458 461 usb_log_error("Failed(%d) to setup %s endpoint list.\n", \ 459 462 ret, name); \ 460 endpoint_list_fini(&instance->lists[USB_TRANSFER_ISOCHRONOUS]); 463 endpoint_list_fini(&instance->lists[USB_TRANSFER_ISOCHRONOUS]);\ 461 464 endpoint_list_fini(&instance->lists[USB_TRANSFER_INTERRUPT]); \ 462 465 endpoint_list_fini(&instance->lists[USB_TRANSFER_CONTROL]); \ -
uspace/drv/ohci/hcd_endpoint.h
rb2995c3 rf58154c5 37 37 #include <assert.h> 38 38 #include <adt/list.h> 39 40 39 #include <usb/host/endpoint.h> 41 40 … … 43 42 #include "hw_struct/transfer_descriptor.h" 44 43 45 typedef struct hcd_endpoint { 44 typedef struct hcd_endpoint 45 { 46 46 ed_t *ed; 47 47 td_t *td; -
uspace/drv/ohci/hw_struct/transfer_descriptor.c
rb2995c3 rf58154c5 44 44 assert(instance); 45 45 bzero(instance, sizeof(td_t)); 46 instance-> 46 instance->status = 0 47 47 | ((dp[dir] & TD_STATUS_DP_MASK) << TD_STATUS_DP_SHIFT) 48 48 | ((CC_NOACCESS2 & TD_STATUS_CC_MASK) << TD_STATUS_CC_SHIFT); -
uspace/drv/ohci/hw_struct/transfer_descriptor.h
rb2995c3 rf58154c5 41 41 #include "completion_codes.h" 42 42 43 /* OHCI TDs can handle up to 8KB buffers */ 44 #define OHCI_TD_MAX_TRANSFER (8 * 1024) 43 /* OHCI TDs can handle up to 8KB buffers, however, it can use max 2 pages. 44 * Using 4KB buffers guarantees the page count condition. 45 * (OHCI assumes 4KB pages) */ 46 #define OHCI_TD_MAX_TRANSFER (4 * 1024) 45 47 46 48 typedef struct td { -
uspace/drv/uhci-hcd/batch.c
rb2995c3 rf58154c5 45 45 #define DEFAULT_ERROR_COUNT 3 46 46 47 /** UHCI specific data required for USB transfer */ 47 48 typedef struct uhci_transfer_batch { 49 /** Queue head 50 * This QH is used to maintain UHCI schedule structure and the element 51 * pointer points to the first TD of this batch. 52 */ 48 53 qh_t *qh; 54 /** List of TDs needed for the transfer */ 49 55 td_t *tds; 56 /** Number of TDs used by the transfer */ 57 size_t td_count; 58 /** Data buffer, must be accessible by the UHCI hw */ 50 59 void *device_buffer; 51 size_t td_count;52 60 } uhci_transfer_batch_t; 53 61 /*----------------------------------------------------------------------------*/ 54 static void uhci_transfer_batch_dispose(void *uhci_batch)55 {56 uhci_transfer_batch_t *instance = uhci_batch;57 assert(instance);58 free32(instance->device_buffer);59 free(instance);60 }61 /*----------------------------------------------------------------------------*/62 63 62 static void batch_control(usb_transfer_batch_t *instance, 64 63 usb_packet_id data_stage, usb_packet_id status_stage); 65 64 static void batch_data(usb_transfer_batch_t *instance, usb_packet_id pid); 66 65 /*----------------------------------------------------------------------------*/ 66 /** Safely destructs uhci_transfer_batch_t structure 67 * 68 * @param[in] uhci_batch Instance to destroy. 69 */ 70 static void uhci_transfer_batch_dispose(void *uhci_batch) 71 { 72 uhci_transfer_batch_t *instance = uhci_batch; 73 assert(instance); 74 free32(instance->device_buffer); 75 free(instance); 76 } 77 /*----------------------------------------------------------------------------*/ 67 78 /** Allocate memory and initialize internal data structure. 68 79 * … … 173 184 instance->error = td_status(&data->tds[i]); 174 185 if (instance->error != EOK) { 175 usb_log_debug("Batch(%p) found error TD(%zu):%" PRIx32 ".\n",176 instance, i, data->tds[i].status);186 usb_log_debug("Batch(%p) found error TD(%zu):%" 187 PRIx32 ".\n", instance, i, data->tds[i].status); 177 188 td_print_status(&data->tds[i]); 178 189 … … 397 408 /*----------------------------------------------------------------------------*/ 398 409 /** Provides access to QH data structure. 410 * 399 411 * @param[in] instance Batch pointer to use. 400 412 * @return Pointer to the QH used by the batch. -
uspace/drv/uhci-hcd/transfer_list.c
rb2995c3 rf58154c5 34 34 #include <errno.h> 35 35 #include <usb/debug.h> 36 #include <arch/barrier.h> 36 37 37 38 #include "transfer_list.h" … … 71 72 * @param[in] instance Memory place to use. 72 73 * 73 * Frees memory forinternal qh_t structure.74 * Frees memory of the internal qh_t structure. 74 75 */ 75 76 void transfer_list_fini(transfer_list_t *instance) … … 126 127 assert((pa & LINK_POINTER_ADDRESS_MASK) == pa); 127 128 129 /* Make sure all data in the batch are written */ 130 write_barrier(); 131 128 132 /* keep link */ 129 133 batch_qh(batch)->next = last_qh->next; 130 134 qh_set_next_qh(last_qh, batch_qh(batch)); 131 135 132 asm volatile ("": : :"memory"); 136 /* Make sure the pointer is updated */ 137 write_barrier(); 133 138 134 139 /* Add to the driver list */ … … 222 227 == addr_to_phys(batch_qh(batch))); 223 228 prev_qh->next = batch_qh(batch)->next; 224 asm volatile ("": : :"memory"); 229 230 /* Make sure the pointer is updated */ 231 write_barrier(); 232 225 233 /* Remove from the batch list */ 226 234 list_remove(&batch->link); -
uspace/drv/uhci-hcd/utils/malloc32.h
rb2995c3 rf58154c5 74 74 if (size <= SLAB_ELEMENT_SIZE) 75 75 return slab_malloc_g(); 76 assert(false); 76 usb_log_warning("Requested %zu bytes, current allocator can't handle " 77 "that amount, pray that the standard malloc will suffice.", size); 77 78 return memalign(UHCI_STRCUTURES_ALIGNMENT, size); 78 79 } -
uspace/drv/uhci-rhd/port.c
rb2995c3 rf58154c5 227 227 while (uhci_port_read_status(port) & STATUS_IN_RESET); 228 228 } 229 /* PIO delay, should not be longer than 3ms as the device might 230 * enter suspend state. */ 229 231 udelay(10); 230 232 /* Enable the port. */ 231 233 uhci_port_set_enabled(port, true); 232 233 /* Reset recovery period,234 * devices do not have to respond during this period235 */236 async_usleep(10000);237 234 return EOK; 238 235 } -
uspace/lib/usbdev/src/hub.c
rb2995c3 rf58154c5 41 41 #include <assert.h> 42 42 #include <usb/debug.h> 43 #include <time.h> 43 44 44 45 /** How much time to wait between attempts to register endpoint 0:0. … … 218 219 219 220 int rc; 221 struct timeval start_time; 222 223 rc = gettimeofday(&start_time, NULL); 224 if (rc != EOK) { 225 return rc; 226 } 220 227 221 228 rc = usb_hc_connection_open(&hc_conn); … … 264 271 } 265 272 } while (rc != EOK); 273 struct timeval end_time; 274 275 rc = gettimeofday(&end_time, NULL); 276 if (rc != EOK) { 277 goto leave_release_default_address; 278 } 279 280 /* According to the USB spec part 9.1.2 host allows 100ms time for 281 * the insertion process to complete. According to 7.1.7.1 this is the 282 * time between attach detected and port reset. However, the setup done 283 * above might use much of this time so we should only wait to fill 284 * up the 100ms quota*/ 285 suseconds_t elapsed = tv_sub(&end_time, &start_time); 286 if (elapsed < 100000) { 287 async_usleep(100000 - elapsed); 288 } 266 289 267 290 /* … … 273 296 goto leave_release_default_address; 274 297 } 298 /* USB spec 7.1.7.1: The USB System Software guarantees a minimum of 299 * 10ms for reset recovery. Device response to any bus transactions 300 * addressed to the default device address during the reset recovery 301 * time is undefined. 302 */ 303 async_usleep(10000); 275 304 276 305 rc = usb_pipe_probe_default_control(&ctrl_pipe);
Note:
See TracChangeset
for help on using the changeset viewer.