Changeset 4deca9b in mainline
- Timestamp:
- 2011-04-12T11:43:35Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 651b352
- Parents:
- 1324ff3 (diff), 910ca3f (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. - Location:
- uspace
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/ohci/batch.c
r1324ff3 r4deca9b 73 73 CHECK_NULL_DISPOSE_RETURN(instance, 74 74 "Failed to allocate batch instance.\n"); 75 usb_target_t target = 76 { .address = ep->address, .endpoint = ep->endpoint }; 77 usb_transfer_batch_init(instance, target, ep->transfer_type, ep->speed, 78 ep->max_packet_size, buffer, NULL, buffer_size, NULL, setup_size, 79 func_in, func_out, arg, fun, ep, NULL); 75 usb_transfer_batch_init(instance, ep, buffer, NULL, buffer_size, 76 NULL, setup_size, func_in, func_out, arg, fun, NULL); 80 77 81 78 ohci_batch_t *data = malloc(sizeof(ohci_batch_t)); … … 101 98 102 99 if (buffer_size > 0) { 103 instance-> transport_buffer = malloc32(buffer_size);104 CHECK_NULL_DISPOSE_RETURN(instance-> transport_buffer,100 instance->data_buffer = malloc32(buffer_size); 101 CHECK_NULL_DISPOSE_RETURN(instance->data_buffer, 105 102 "Failed to allocate device accessible buffer.\n"); 106 103 } … … 124 121 free32(data->tds); 125 122 free32(instance->setup_buffer); 126 free32(instance-> transport_buffer);123 free32(instance->data_buffer); 127 124 free(data); 128 125 free(instance); … … 165 162 assert(instance); 166 163 /* We are data out, we are supposed to provide data */ 167 memcpy(instance->transport_buffer, instance->buffer, 168 instance->buffer_size); 164 memcpy(instance->data_buffer, instance->buffer, instance->buffer_size); 169 165 instance->next_step = batch_call_out_and_dispose; 170 166 batch_control(instance, USB_DIRECTION_OUT, USB_DIRECTION_IN); … … 183 179 { 184 180 assert(instance); 185 assert(instance->direction == USB_DIRECTION_IN);186 181 instance->next_step = batch_call_in_and_dispose; 187 182 batch_data(instance); … … 192 187 { 193 188 assert(instance); 194 assert(instance->direction == USB_DIRECTION_OUT);195 189 /* We are data out, we are supposed to provide data */ 196 memcpy(instance->transport_buffer, instance->buffer, 197 instance->buffer_size); 190 memcpy(instance->data_buffer, instance->buffer, instance->buffer_size); 198 191 instance->next_step = batch_call_out_and_dispose; 199 192 batch_data(instance); … … 204 197 { 205 198 assert(instance); 206 instance->direction = USB_DIRECTION_IN;207 199 instance->next_step = batch_call_in_and_dispose; 208 200 batch_data(instance); … … 213 205 { 214 206 assert(instance); 215 instance->direction = USB_DIRECTION_IN;216 207 instance->next_step = batch_call_in_and_dispose; 217 208 batch_data(instance); … … 249 240 size_t td_current = 1; 250 241 size_t remain_size = instance->buffer_size; 251 char * transfer_buffer = instance->transport_buffer;242 char *buffer = instance->data_buffer; 252 243 while (remain_size > 0) { 253 244 size_t transfer_size = remain_size > OHCI_TD_MAX_TRANSFER ? … … 255 246 toggle = 1 - toggle; 256 247 257 td_init(&data->tds[td_current], data_dir, transfer_buffer,248 td_init(&data->tds[td_current], data_dir, buffer, 258 249 transfer_size, toggle); 259 250 td_set_next(&data->tds[td_current], &data->tds[td_current + 1]); … … 262 253 data->tds[td_current].next, data->tds[td_current].be); 263 254 264 transfer_buffer += transfer_size;255 buffer += transfer_size; 265 256 remain_size -= transfer_size; 266 257 assert(td_current < data->td_count - 2); … … 290 281 size_t td_current = 0; 291 282 size_t remain_size = instance->buffer_size; 292 char * transfer_buffer = instance->transport_buffer;283 char *buffer = instance->data_buffer; 293 284 while (remain_size > 0) { 294 285 size_t transfer_size = remain_size > OHCI_TD_MAX_TRANSFER ? … … 296 287 297 288 td_init(&data->tds[td_current], instance->ep->direction, 298 transfer_buffer, transfer_size, -1);289 buffer, transfer_size, -1); 299 290 td_set_next(&data->tds[td_current], &data->tds[td_current + 1]); 300 291 usb_log_debug("Created DATA TD: %x:%x:%x:%x.\n", … … 302 293 data->tds[td_current].next, data->tds[td_current].be); 303 294 304 transfer_buffer += transfer_size;295 buffer += transfer_size; 305 296 remain_size -= transfer_size; 306 297 assert(td_current < data->td_count); -
uspace/drv/ohci/hc.c
r1324ff3 r4deca9b 55 55 assert(hub_fun); 56 56 57 int ret; 58 57 59 usb_address_t hub_address = 58 60 device_keeper_get_free_address(&instance->manager, USB_SPEED_FULL); 61 if (hub_address <= 0) { 62 usb_log_error("Failed to get OHCI root hub address.\n"); 63 return hub_address; 64 } 59 65 instance->rh.address = hub_address; 60 66 usb_device_keeper_bind( 61 67 &instance->manager, hub_address, hub_fun->handle); 62 68 63 endpoint_t *ep = malloc(sizeof(endpoint_t)); 64 assert(ep); 65 int ret = endpoint_init(ep, hub_address, 0, USB_DIRECTION_BOTH, 66 USB_TRANSFER_CONTROL, USB_SPEED_FULL, 64); 67 assert(ret == EOK); 68 ret = usb_endpoint_manager_register_ep(&instance->ep_manager, ep, 0); 69 assert(ret == EOK); 69 ret = usb_endpoint_manager_add_ep(&instance->ep_manager, 70 hub_address, 0, USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL, 71 USB_SPEED_FULL, 64, 0); 72 if (ret != EOK) { 73 usb_log_error("Failed to add OHCI rh endpoint 0.\n"); 74 usb_device_keeper_release(&instance->manager, hub_address); 75 return ret; 76 } 70 77 71 78 char *match_str = NULL; 79 /* DDF needs heap allocated string */ 72 80 ret = asprintf(&match_str, "usb&class=hub"); 73 // ret = (match_str == NULL) ? ret : EOK;74 81 if (ret < 0) { 75 82 usb_log_error( 76 83 "Failed(%d) to create root hub match-id string.\n", ret); 84 usb_device_keeper_release(&instance->manager, hub_address); 77 85 return ret; 78 86 } … … 80 88 ret = ddf_fun_add_match_id(hub_fun, match_str, 100); 81 89 if (ret != EOK) { 82 usb_log_error("Failed add createroot hub match-id.\n");90 usb_log_error("Failed add root hub match-id.\n"); 83 91 } 84 92 return ret; … … 115 123 fibril_mutex_initialize(&instance->guard); 116 124 117 rh_init(&instance->rh, dev,instance->registers);125 rh_init(&instance->rh, instance->registers); 118 126 119 127 if (!interrupts) { … … 130 138 assert(instance); 131 139 assert(batch); 140 assert(batch->ep); 132 141 133 142 /* check for root hub communication */ 134 if (batch-> target.address == instance->rh.address) {143 if (batch->ep->address == instance->rh.address) { 135 144 return rh_request(&instance->rh, batch); 136 145 } 137 146 138 147 fibril_mutex_lock(&instance->guard); 139 switch (batch-> transfer_type) {148 switch (batch->ep->transfer_type) { 140 149 case USB_TRANSFER_CONTROL: 141 150 instance->registers->control &= ~C_CLE; 142 151 transfer_list_add_batch( 143 instance->transfers[batch-> transfer_type], batch);152 instance->transfers[batch->ep->transfer_type], batch); 144 153 instance->registers->command_status |= CS_CLF; 145 154 usb_log_debug2("Set CS control transfer filled: %x.\n", … … 151 160 instance->registers->control &= ~C_BLE; 152 161 transfer_list_add_batch( 153 instance->transfers[batch-> transfer_type], batch);162 instance->transfers[batch->ep->transfer_type], batch); 154 163 instance->registers->command_status |= CS_BLF; 155 164 usb_log_debug2("Set bulk transfer filled: %x.\n", … … 161 170 instance->registers->control &= (~C_PLE & ~C_IE); 162 171 transfer_list_add_batch( 163 instance->transfers[batch-> transfer_type], batch);172 instance->transfers[batch->ep->transfer_type], batch); 164 173 instance->registers->control |= C_PLE | C_IE; 165 174 usb_log_debug2("Added periodic transfer: %x.\n", -
uspace/drv/ohci/root_hub.c
r1324ff3 r4deca9b 205 205 * @return Error code. 206 206 */ 207 int rh_init(rh_t *instance, ddf_dev_t *dev,ohci_regs_t *regs) {207 int rh_init(rh_t *instance, ohci_regs_t *regs) { 208 208 assert(instance); 209 //instance->address = -1;210 209 instance->registers = regs; 211 instance->device = dev;212 210 instance->port_count = 213 211 (instance->registers->rh_desc_a >> RHDA_NDS_SHIFT) & RHDA_NDS_MASK; 214 212 rh_init_descriptors(instance); 215 213 // set port power mode to no-power-switching 216 instance->registers->rh_desc_a = 217 instance->registers->rh_desc_a | (1<<9); 214 instance->registers->rh_desc_a |= RHDA_NPS_FLAG; 218 215 219 216 usb_log_info("OHCI root hub with %d ports.\n", instance->port_count); 220 221 //start generic usb hub driver222 223 /* TODO: implement */224 217 return EOK; 225 218 } … … 237 230 assert(request); 238 231 int opResult; 239 if (request-> transfer_type == USB_TRANSFER_CONTROL) {232 if (request->ep->transfer_type == USB_TRANSFER_CONTROL) { 240 233 usb_log_info("Root hub got CONTROL packet\n"); 241 234 opResult = process_ctrl_request(instance, request); 242 } else if (request-> transfer_type == USB_TRANSFER_INTERRUPT) {235 } else if (request->ep->transfer_type == USB_TRANSFER_INTERRUPT) { 243 236 usb_log_info("Root hub got INTERRUPT packet\n"); 244 237 void * buffer; 245 238 create_interrupt_mask(instance, &buffer, 246 239 &(request->transfered_size)); 247 memcpy(request-> transport_buffer, buffer,240 memcpy(request->data_buffer, buffer, 248 241 request->transfered_size); 249 242 opResult = EOK; … … 374 367 if (port < 1 || port > instance->port_count) 375 368 return EINVAL; 376 uint32_t * uint32_buffer = (uint32_t*) request-> transport_buffer;369 uint32_t * uint32_buffer = (uint32_t*) request->data_buffer; 377 370 request->transfered_size = 4; 378 371 uint32_buffer[0] = instance->registers->rh_port_status[port - 1]; … … 400 393 static int process_get_hub_status_request(rh_t *instance, 401 394 usb_transfer_batch_t * request) { 402 uint32_t * uint32_buffer = (uint32_t*) request-> transport_buffer;395 uint32_t * uint32_buffer = (uint32_t*) request->data_buffer; 403 396 request->transfered_size = 4; 404 397 //bits, 0,1,16,17 … … 550 543 } 551 544 request->transfered_size = size; 552 memcpy(request-> transport_buffer, result_descriptor, size);545 memcpy(request->data_buffer, result_descriptor, size); 553 546 if (del) 554 547 free(result_descriptor); … … 571 564 if (request->buffer_size != 1) 572 565 return EINVAL; 573 request-> transport_buffer[0] = 1;566 request->data_buffer[0] = 1; 574 567 request->transfered_size = 1; 575 568 return EOK; -
uspace/drv/ohci/root_hub.h
r1324ff3 r4deca9b 50 50 /** usb address of the root hub */ 51 51 usb_address_t address; 52 /** ddf device information */53 ddf_dev_t *device;54 52 /** hub port count */ 55 53 int port_count; … … 58 56 } rh_t; 59 57 60 int rh_init(rh_t *instance, ddf_dev_t *dev,ohci_regs_t *regs);58 int rh_init(rh_t *instance, ohci_regs_t *regs); 61 59 62 60 int rh_request(rh_t *instance, usb_transfer_batch_t *request); -
uspace/drv/uhci-hcd/batch.c
r1324ff3 r4deca9b 30 30 */ 31 31 /** @file 32 * @brief UHCI driver USB trans actionstructure32 * @brief UHCI driver USB transfer structure 33 33 */ 34 34 #include <errno.h> … … 48 48 qh_t *qh; 49 49 td_t *tds; 50 size_t t ransfers;50 size_t td_count; 51 51 } uhci_batch_t; 52 52 … … 61 61 * 62 62 * @param[in] fun DDF function to pass to callback. 63 * @param[in] target Device and endpoint target of the transaction. 64 * @param[in] transfer_type Interrupt, Control or Bulk. 65 * @param[in] max_packet_size maximum allowed size of data transfers. 66 * @param[in] speed Speed of the transaction. 63 * @param[in] ep Communication target 67 64 * @param[in] buffer Data source/destination. 68 65 * @param[in] size Size of the buffer. 69 66 * @param[in] setup_buffer Setup data source (if not NULL) 70 67 * @param[in] setup_size Size of setup_buffer (should be always 8) 71 * @param[in] func_in function to call on inbound trans actioncompletion72 * @param[in] func_out function to call on outbound trans actioncompletion68 * @param[in] func_in function to call on inbound transfer completion 69 * @param[in] func_out function to call on outbound transfer completion 73 70 * @param[in] arg additional parameter to func_in or func_out 74 * @param[in] ep Pointer to endpoint toggle management structure.75 71 * @return Valid pointer if all substructures were successfully created, 76 72 * NULL otherwise. 77 73 * 78 * Determines the number of needed transfer s (TDs). Prepares a transport buffer79 * (that is accessible by the hardware). Initializes parameters needed for the80 * transactionand callback.74 * Determines the number of needed transfer descriptors (TDs). 75 * Prepares a transport buffer (that is accessible by the hardware). 76 * Initializes parameters needed for the transfer and callback. 81 77 */ 82 78 usb_transfer_batch_t * batch_get(ddf_fun_t *fun, endpoint_t *ep, … … 103 99 usb_target_t target = 104 100 { .address = ep->address, .endpoint = ep->endpoint }; 105 usb_transfer_batch_init(instance, target, ep->transfer_type, ep->speed,106 ep->max_packet_size,buffer, NULL, buffer_size, NULL, setup_size,107 func_in, func_out, arg, fun, ep,NULL);101 usb_transfer_batch_init(instance, ep, 102 buffer, NULL, buffer_size, NULL, setup_size, 103 func_in, func_out, arg, fun, NULL); 108 104 109 105 … … 113 109 instance->private_data = data; 114 110 115 data->t ransfers=111 data->td_count = 116 112 (buffer_size + ep->max_packet_size - 1) / ep->max_packet_size; 117 113 if (ep->transfer_type == USB_TRANSFER_CONTROL) { 118 data->t ransfers+= 2;119 } 120 121 data->tds = malloc32(sizeof(td_t) * data->t ransfers);114 data->td_count += 2; 115 } 116 117 data->tds = malloc32(sizeof(td_t) * data->td_count); 122 118 CHECK_NULL_DISPOSE_RETURN( 123 119 data->tds, "Failed to allocate transfer descriptors.\n"); 124 bzero(data->tds, sizeof(td_t) * data->t ransfers);120 bzero(data->tds, sizeof(td_t) * data->td_count); 125 121 126 122 data->qh = malloc32(sizeof(qh_t)); … … 131 127 132 128 if (buffer_size > 0) { 133 instance-> transport_buffer = malloc32(buffer_size);134 CHECK_NULL_DISPOSE_RETURN(instance-> transport_buffer,129 instance->data_buffer = malloc32(buffer_size); 130 CHECK_NULL_DISPOSE_RETURN(instance->data_buffer, 135 131 "Failed to allocate device accessible buffer.\n"); 136 132 } … … 154 150 * 155 151 * Walk all TDs. Stop with false if there is an active one (it is to be 156 * processed). Stop with true if an error is found. Return true if the last T S152 * processed). Stop with true if an error is found. Return true if the last TD 157 153 * is reached. 158 154 */ … … 164 160 165 161 usb_log_debug2("Batch(%p) checking %d transfer(s) for completion.\n", 166 instance, data->t ransfers);162 instance, data->td_count); 167 163 instance->transfered_size = 0; 168 164 size_t i = 0; 169 for (;i < data->t ransfers; ++i) {165 for (;i < data->td_count; ++i) { 170 166 if (td_is_active(&data->tds[i])) { 171 167 return false; … … 177 173 instance, i, data->tds[i].status); 178 174 td_print_status(&data->tds[i]); 175 179 176 assert(instance->ep != NULL); 180 181 177 endpoint_toggle_set(instance->ep, 182 178 td_toggle(&data->tds[i])); … … 195 191 } 196 192 /*----------------------------------------------------------------------------*/ 197 /** Prepares control write trans action.198 * 199 * @param[in] instance Batch structure to use. 200 * 201 * Uses gener circontrol function with pids OUT and IN.193 /** Prepares control write transfer. 194 * 195 * @param[in] instance Batch structure to use. 196 * 197 * Uses generic control function with pids OUT and IN. 202 198 */ 203 199 void batch_control_write(usb_transfer_batch_t *instance) … … 205 201 assert(instance); 206 202 /* We are data out, we are supposed to provide data */ 207 memcpy(instance->transport_buffer, instance->buffer, 208 instance->buffer_size); 203 memcpy(instance->data_buffer, instance->buffer, instance->buffer_size); 209 204 batch_control(instance, USB_PID_OUT, USB_PID_IN); 210 205 instance->next_step = batch_call_out_and_dispose; … … 212 207 } 213 208 /*----------------------------------------------------------------------------*/ 214 /** Prepares control read trans action.209 /** Prepares control read transfer. 215 210 * 216 211 * @param[in] instance Batch structure to use. … … 226 221 } 227 222 /*----------------------------------------------------------------------------*/ 228 /** Prepare interrupt in trans action.229 * 230 * @param[in] instance Batch structure to use. 231 * 232 * Data trans actionwith PID_IN.223 /** Prepare interrupt in transfer. 224 * 225 * @param[in] instance Batch structure to use. 226 * 227 * Data transfer with PID_IN. 233 228 */ 234 229 void batch_interrupt_in(usb_transfer_batch_t *instance) 235 230 { 236 231 assert(instance); 237 instance->direction = USB_DIRECTION_IN;238 232 batch_data(instance, USB_PID_IN); 239 233 instance->next_step = batch_call_in_and_dispose; … … 241 235 } 242 236 /*----------------------------------------------------------------------------*/ 243 /** Prepare interrupt out trans action.244 * 245 * @param[in] instance Batch structure to use. 246 * 247 * Data trans actionwith PID_OUT.237 /** Prepare interrupt out transfer. 238 * 239 * @param[in] instance Batch structure to use. 240 * 241 * Data transfer with PID_OUT. 248 242 */ 249 243 void batch_interrupt_out(usb_transfer_batch_t *instance) 250 244 { 251 245 assert(instance); 252 instance->direction = USB_DIRECTION_OUT;253 246 /* We are data out, we are supposed to provide data */ 254 memcpy(instance->transport_buffer, instance->buffer, 255 instance->buffer_size); 247 memcpy(instance->data_buffer, instance->buffer, instance->buffer_size); 256 248 batch_data(instance, USB_PID_OUT); 257 249 instance->next_step = batch_call_out_and_dispose; … … 259 251 } 260 252 /*----------------------------------------------------------------------------*/ 261 /** Prepare bulk in trans action.262 * 263 * @param[in] instance Batch structure to use. 264 * 265 * Data trans actionwith PID_IN.253 /** Prepare bulk in transfer. 254 * 255 * @param[in] instance Batch structure to use. 256 * 257 * Data transfer with PID_IN. 266 258 */ 267 259 void batch_bulk_in(usb_transfer_batch_t *instance) … … 269 261 assert(instance); 270 262 batch_data(instance, USB_PID_IN); 271 instance->direction = USB_DIRECTION_IN;272 263 instance->next_step = batch_call_in_and_dispose; 273 264 usb_log_debug("Batch(%p) BULK IN initialized.\n", instance); 274 265 } 275 266 /*----------------------------------------------------------------------------*/ 276 /** Prepare bulk out trans action.277 * 278 * @param[in] instance Batch structure to use. 279 * 280 * Data trans actionwith PID_OUT.267 /** Prepare bulk out transfer. 268 * 269 * @param[in] instance Batch structure to use. 270 * 271 * Data transfer with PID_OUT. 281 272 */ 282 273 void batch_bulk_out(usb_transfer_batch_t *instance) 283 274 { 284 275 assert(instance); 285 instance->direction = USB_DIRECTION_OUT;286 276 /* We are data out, we are supposed to provide data */ 287 memcpy(instance->transport_buffer, instance->buffer, 288 instance->buffer_size); 277 memcpy(instance->data_buffer, instance->buffer, instance->buffer_size); 289 278 batch_data(instance, USB_PID_OUT); 290 279 instance->next_step = batch_call_out_and_dispose; … … 292 281 } 293 282 /*----------------------------------------------------------------------------*/ 294 /** Prepare generic data trans action295 * 296 * @param[in] instance Batch structure to use. 297 * @param[in] pid Pid to use for data trans fers.298 * 299 * Packets with alternating toggle bit and supplied pid value.283 /** Prepare generic data transfer 284 * 285 * @param[in] instance Batch structure to use. 286 * @param[in] pid Pid to use for data transactions. 287 * 288 * Transactions with alternating toggle bit and supplied pid value. 300 289 * The last transfer is marked with IOC flag. 301 290 */ … … 306 295 assert(data); 307 296 308 const bool low_speed = instance-> speed == USB_SPEED_LOW;297 const bool low_speed = instance->ep->speed == USB_SPEED_LOW; 309 298 int toggle = endpoint_toggle_get(instance->ep); 310 299 assert(toggle == 0 || toggle == 1); 311 300 312 size_t t ransfer= 0;301 size_t td = 0; 313 302 size_t remain_size = instance->buffer_size; 303 char *buffer = instance->data_buffer; 314 304 while (remain_size > 0) { 315 char *trans_data =316 instance->transport_buffer + instance->buffer_size317 - remain_size;318 319 305 const size_t packet_size = 320 (instance->max_packet_size > remain_size) ? 321 remain_size : instance->max_packet_size; 322 323 td_t *next_transfer = (transfer + 1 < data->transfers) 324 ? &data->tds[transfer + 1] : NULL; 325 326 assert(transfer < data->transfers); 306 (instance->ep->max_packet_size > remain_size) ? 307 remain_size : instance->ep->max_packet_size; 308 309 td_t *next_td = (td + 1 < data->td_count) 310 ? &data->tds[td + 1] : NULL; 311 312 313 usb_target_t target = 314 { instance->ep->address, instance->ep->endpoint }; 315 316 assert(td < data->td_count); 317 td_init( 318 &data->tds[td], DEFAULT_ERROR_COUNT, packet_size, 319 toggle, false, low_speed, target, pid, buffer, next_td); 320 321 ++td; 322 toggle = 1 - toggle; 323 buffer += packet_size; 327 324 assert(packet_size <= remain_size); 328 329 td_init(330 &data->tds[transfer], DEFAULT_ERROR_COUNT, packet_size,331 toggle, false, low_speed, instance->target, pid, trans_data,332 next_transfer);333 334 335 toggle = 1 - toggle;336 325 remain_size -= packet_size; 337 ++transfer; 338 } 339 td_set_ioc(&data->tds[transfer - 1]); 326 } 327 td_set_ioc(&data->tds[td - 1]); 340 328 endpoint_toggle_set(instance->ep, toggle); 341 329 } 342 330 /*----------------------------------------------------------------------------*/ 343 /** Prepare generic control trans action344 * 345 * @param[in] instance Batch structure to use. 346 * @param[in] data_stage Pid to use for data t ransfers.347 * @param[in] status_stage Pid to use for data t ransfers.331 /** Prepare generic control transfer 332 * 333 * @param[in] instance Batch structure to use. 334 * @param[in] data_stage Pid to use for data tds. 335 * @param[in] status_stage Pid to use for data tds. 348 336 * 349 337 * Setup stage with toggle 0 and USB_PID_SETUP. … … 358 346 uhci_batch_t *data = instance->private_data; 359 347 assert(data); 360 assert(data->transfers >= 2); 361 362 const bool low_speed = instance->speed == USB_SPEED_LOW; 363 int toggle = 0; 348 assert(data->td_count >= 2); 349 350 const bool low_speed = instance->ep->speed == USB_SPEED_LOW; 351 const usb_target_t target = 352 { instance->ep->address, instance->ep->endpoint }; 353 364 354 /* setup stage */ 365 355 td_init( 366 data->tds, DEFAULT_ERROR_COUNT, instance->setup_size, toggle, false,367 low_speed, instance->target, USB_PID_SETUP, instance->setup_buffer,356 data->tds, DEFAULT_ERROR_COUNT, instance->setup_size, 0, false, 357 low_speed, target, USB_PID_SETUP, instance->setup_buffer, 368 358 &data->tds[1]); 369 359 370 360 /* data stage */ 371 size_t transfer = 1; 361 size_t td = 1; 362 unsigned toggle = 1; 372 363 size_t remain_size = instance->buffer_size; 364 char *buffer = instance->data_buffer; 373 365 while (remain_size > 0) { 374 char *control_data = 375 instance->transport_buffer + instance->buffer_size 376 - remain_size; 377 366 const size_t packet_size = 367 (instance->ep->max_packet_size > remain_size) ? 368 remain_size : instance->ep->max_packet_size; 369 370 td_init( 371 &data->tds[td], DEFAULT_ERROR_COUNT, packet_size, 372 toggle, false, low_speed, target, data_stage, 373 buffer, &data->tds[td + 1]); 374 375 ++td; 378 376 toggle = 1 - toggle; 379 380 const size_t packet_size = 381 (instance->max_packet_size > remain_size) ? 382 remain_size : instance->max_packet_size; 383 384 td_init( 385 &data->tds[transfer], DEFAULT_ERROR_COUNT, packet_size, 386 toggle, false, low_speed, instance->target, data_stage, 387 control_data, &data->tds[transfer + 1]); 388 389 ++transfer; 390 assert(transfer < data->transfers); 377 buffer += packet_size; 378 assert(td < data->td_count); 391 379 assert(packet_size <= remain_size); 392 380 remain_size -= packet_size; … … 394 382 395 383 /* status stage */ 396 assert(t ransfer == data->transfers- 1);384 assert(td == data->td_count - 1); 397 385 398 386 td_init( 399 &data->tds[t ransfer], DEFAULT_ERROR_COUNT, 0, 1, false, low_speed,400 instance->target, status_stage, NULL, NULL);401 td_set_ioc(&data->tds[t ransfer]);387 &data->tds[td], DEFAULT_ERROR_COUNT, 0, 1, false, low_speed, 388 target, status_stage, NULL, NULL); 389 td_set_ioc(&data->tds[td]); 402 390 403 391 usb_log_debug2("Control last TD status: %x.\n", 404 data->tds[t ransfer].status);392 data->tds[td].status); 405 393 } 406 394 /*----------------------------------------------------------------------------*/ … … 413 401 } 414 402 /*----------------------------------------------------------------------------*/ 415 /** Helper function calls callback and correctly disposes ofbatch structure.403 /** Helper function, calls callback and correctly destroys batch structure. 416 404 * 417 405 * @param[in] instance Batch structure to use. … … 424 412 } 425 413 /*----------------------------------------------------------------------------*/ 426 /** Helper function calls callback and correctly d isposes ofbatch structure.414 /** Helper function calls callback and correctly destroys batch structure. 427 415 * 428 416 * @param[in] instance Batch structure to use. … … 449 437 free32(data->qh); 450 438 free32(instance->setup_buffer); 451 free32(instance-> transport_buffer);439 free32(instance->data_buffer); 452 440 free(data); 453 441 free(instance); -
uspace/drv/uhci-hcd/hc.c
r1324ff3 r4deca9b 329 329 330 330 transfer_list_t *list = 331 instance->transfers[batch-> speed][batch->transfer_type];331 instance->transfers[batch->ep->speed][batch->ep->transfer_type]; 332 332 assert(list); 333 333 transfer_list_add_batch(list, batch); -
uspace/drv/uhci-hcd/iface.c
r1324ff3 r4deca9b 148 148 assert(hc); 149 149 const size_t size = max_packet_size; 150 int ret;151 150 usb_speed_t speed = usb_device_keeper_get_speed(&hc->manager, address); 152 151 if (speed >= USB_SPEED_MAX) { … … 157 156 usb_str_speed(speed), direction, size, max_packet_size, interval); 158 157 159 160 endpoint_t *ep = malloc(sizeof(endpoint_t)); 161 if (ep == NULL) 162 return ENOMEM; 163 ret = endpoint_init(ep, address, endpoint, direction, 164 transfer_type, speed, max_packet_size); 165 if (ret != EOK) { 166 free(ep); 167 return ret; 168 } 169 170 ret = usb_endpoint_manager_register_ep(&hc->ep_manager, ep, size); 171 if (ret != EOK) { 172 endpoint_destroy(ep); 173 } 174 return ret; 158 return usb_endpoint_manager_add_ep(&hc->ep_manager, address, endpoint, 159 direction, transfer_type, speed, max_packet_size, size); 175 160 } 176 161 /*----------------------------------------------------------------------------*/ -
uspace/lib/usb/include/usb/host/batch.h
r1324ff3 r4deca9b 43 43 typedef struct usb_transfer_batch usb_transfer_batch_t; 44 44 struct usb_transfer_batch { 45 endpoint_t *ep; 45 46 link_t link; 46 usb_target_t target;47 usb_transfer_type_t transfer_type;48 usb_speed_t speed;49 usb_direction_t direction;50 47 usbhc_iface_transfer_in_callback_t callback_in; 51 48 usbhc_iface_transfer_out_callback_t callback_out; 49 void *arg; 52 50 char *buffer; 53 char * transport_buffer;51 char *data_buffer; 54 52 size_t buffer_size; 55 53 char *setup_buffer; 56 54 size_t setup_size; 57 size_t max_packet_size;58 55 size_t transfered_size; 59 56 void (*next_step)(usb_transfer_batch_t *); 60 57 int error; 61 58 ddf_fun_t *fun; 62 void *arg;63 endpoint_t *ep;64 59 void *private_data; 65 60 }; … … 67 62 void usb_transfer_batch_init( 68 63 usb_transfer_batch_t *instance, 69 usb_target_t target, 70 usb_transfer_type_t transfer_type, 71 usb_speed_t speed, 72 size_t max_packet_size, 64 endpoint_t *ep, 73 65 char *buffer, 74 char * transport_buffer,66 char *data_buffer, 75 67 size_t buffer_size, 76 68 char *setup_buffer, … … 80 72 void *arg, 81 73 ddf_fun_t *fun, 82 endpoint_t *ep,83 74 void *private_data 84 75 ); -
uspace/lib/usb/include/usb/host/device_keeper.h
r1324ff3 r4deca9b 54 54 usb_speed_t speed; 55 55 bool occupied; 56 link_t endpoints;57 uint16_t control_used;58 56 devman_handle_t handle; 59 57 }; … … 65 63 struct usb_device_info devices[USB_ADDRESS_COUNT]; 66 64 fibril_mutex_t guard; 67 fibril_condvar_t change;68 65 usb_address_t last_address; 69 66 } usb_device_keeper_t; 70 67 71 68 void usb_device_keeper_init(usb_device_keeper_t *instance); 72 73 void usb_device_keeper_reserve_default_address(74 usb_device_keeper_t *instance, usb_speed_t speed);75 76 void usb_device_keeper_release_default_address(usb_device_keeper_t *instance);77 78 void usb_device_keeper_reset_if_need(usb_device_keeper_t *instance,79 usb_target_t target, const uint8_t *setup_data);80 69 81 70 usb_address_t device_keeper_get_free_address(usb_device_keeper_t *instance, -
uspace/lib/usb/include/usb/host/usb_endpoint_manager.h
r1324ff3 r4deca9b 66 66 endpoint_t *ep, size_t data_size); 67 67 68 int usb_endpoint_manager_register_ep_wait(usb_endpoint_manager_t *instance,69 usb_address_t address, usb_endpoint_t ep, usb_direction_t direction,70 void *data, void (*data_remove_callback)(void* data, void* arg), void *arg,71 size_t bw);72 73 68 int usb_endpoint_manager_unregister_ep(usb_endpoint_manager_t *instance, 74 69 usb_address_t address, usb_endpoint_t ep, usb_direction_t direction); … … 80 75 void usb_endpoint_manager_reset_if_need( 81 76 usb_endpoint_manager_t *instance, usb_target_t target, const uint8_t *data); 77 78 static inline int usb_endpoint_manager_add_ep(usb_endpoint_manager_t *instance, 79 usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction, 80 usb_transfer_type_t type, usb_speed_t speed, size_t max_packet_size, 81 size_t data_size) 82 { 83 endpoint_t *ep = malloc(sizeof(endpoint_t)); 84 if (ep == NULL) 85 return ENOMEM; 86 87 int ret = endpoint_init(ep, address, endpoint, direction, type, speed, 88 max_packet_size); 89 if (ret != EOK) { 90 free(ep); 91 return ret; 92 } 93 94 ret = usb_endpoint_manager_register_ep(instance, ep, data_size); 95 if (ret != EOK) { 96 endpoint_destroy(ep); 97 return ret; 98 } 99 return EOK; 100 } 82 101 #endif 83 102 /** -
uspace/lib/usb/src/host/batch.c
r1324ff3 r4deca9b 41 41 void usb_transfer_batch_init( 42 42 usb_transfer_batch_t *instance, 43 usb_target_t target, 44 usb_transfer_type_t transfer_type, 45 usb_speed_t speed, 46 size_t max_packet_size, 43 endpoint_t *ep, 47 44 char *buffer, 48 char * transport_buffer,45 char *data_buffer, 49 46 size_t buffer_size, 50 47 char *setup_buffer, … … 54 51 void *arg, 55 52 ddf_fun_t *fun, 56 endpoint_t *ep,57 53 void *private_data 58 54 ) … … 60 56 assert(instance); 61 57 link_initialize(&instance->link); 62 instance->target = target; 63 instance->transfer_type = transfer_type; 64 instance->speed = speed; 65 instance->direction = ep->direction; 58 instance->ep = ep; 66 59 instance->callback_in = func_in; 67 60 instance->callback_out = func_out; 68 61 instance->arg = arg; 69 62 instance->buffer = buffer; 70 instance-> transport_buffer = transport_buffer;63 instance->data_buffer = data_buffer; 71 64 instance->buffer_size = buffer_size; 72 65 instance->setup_buffer = setup_buffer; 73 66 instance->setup_size = setup_size; 74 instance->max_packet_size = max_packet_size;75 67 instance->fun = fun; 76 68 instance->private_data = private_data; … … 78 70 instance->next_step = NULL; 79 71 instance->error = EOK; 80 instance->ep = ep;81 72 endpoint_use(instance->ep); 82 73 } … … 105 96 assert(instance); 106 97 assert(instance->callback_in); 98 assert(instance->ep); 107 99 108 100 /* We are data in, we need data */ 109 memcpy(instance->buffer, instance->transport_buffer, 110 instance->buffer_size); 101 memcpy(instance->buffer, instance->data_buffer, instance->buffer_size); 111 102 112 103 usb_log_debug("Batch %p done (T%d.%d, %s %s in, %zuB): %s (%d).\n", 113 instance, 114 instance->target.address, instance->target.endpoint, 115 usb_str_speed(instance->speed), 116 usb_str_transfer_type_short(instance->transfer_type), 117 instance->transfered_size, 118 str_error(instance->error), instance->error); 104 instance, instance->ep->address, instance->ep->endpoint, 105 usb_str_speed(instance->ep->speed), 106 usb_str_transfer_type_short(instance->ep->transfer_type), 107 instance->transfered_size, str_error(instance->error), instance->error); 119 108 120 109 instance->callback_in(instance->fun, instance->error, … … 132 121 133 122 usb_log_debug("Batch %p done (T%d.%d, %s %s out): %s (%d).\n", 134 instance, 135 instance->target.address, instance->target.endpoint, 136 usb_str_speed(instance->speed), 137 usb_str_transfer_type_short(instance->transfer_type), 123 instance, instance->ep->address, instance->ep->endpoint, 124 usb_str_speed(instance->ep->speed), 125 usb_str_transfer_type_short(instance->ep->transfer_type), 138 126 str_error(instance->error), instance->error); 139 127 -
uspace/lib/usb/src/host/device_keeper.c
r1324ff3 r4deca9b 48 48 { 49 49 assert(instance); 50 fibril_mutex_initialize(&instance->guard);51 fibril_condvar_initialize(&instance->change);52 instance->last_address = 0;53 50 unsigned i = 0; 54 51 for (; i < USB_ADDRESS_COUNT; ++i) { … … 60 57 // (it is needed to allow smooth registration at default address) 61 58 instance->devices[0].occupied = true; 59 instance->last_address = 0; 60 fibril_mutex_initialize(&instance->guard); 62 61 } 63 /*----------------------------------------------------------------------------*/64 /** Attempt to obtain address 0, blocks.65 *66 * @param[in] instance Device keeper structure to use.67 * @param[in] speed Speed of the device requesting default address.68 */69 void usb_device_keeper_reserve_default_address(70 usb_device_keeper_t *instance, usb_speed_t speed)71 {72 assert(instance);73 fibril_mutex_lock(&instance->guard);74 while (instance->devices[USB_ADDRESS_DEFAULT].occupied) {75 fibril_condvar_wait(&instance->change, &instance->guard);76 }77 instance->devices[USB_ADDRESS_DEFAULT].occupied = true;78 instance->devices[USB_ADDRESS_DEFAULT].speed = speed;79 fibril_mutex_unlock(&instance->guard);80 }81 /*----------------------------------------------------------------------------*/82 /** Attempt to obtain address 0, blocks.83 *84 * @param[in] instance Device keeper structure to use.85 * @param[in] speed Speed of the device requesting default address.86 */87 void usb_device_keeper_release_default_address(usb_device_keeper_t *instance)88 {89 assert(instance);90 fibril_mutex_lock(&instance->guard);91 instance->devices[USB_ADDRESS_DEFAULT].occupied = false;92 fibril_mutex_unlock(&instance->guard);93 fibril_condvar_signal(&instance->change);94 }95 /*----------------------------------------------------------------------------*/96 62 /*----------------------------------------------------------------------------*/ 97 63 /** Get a free USB address … … 120 86 assert(new_address != USB_ADDRESS_DEFAULT); 121 87 assert(instance->devices[new_address].occupied == false); 88 122 89 instance->devices[new_address].occupied = true; 123 90 instance->devices[new_address].speed = speed; 124 91 instance->last_address = new_address; 92 125 93 fibril_mutex_unlock(&instance->guard); 126 94 return new_address; … … 138 106 assert(instance); 139 107 fibril_mutex_lock(&instance->guard); 108 140 109 assert(address > 0); 141 110 assert(address <= USB11_ADDRESS_MAX); 142 111 assert(instance->devices[address].occupied); 112 143 113 instance->devices[address].handle = handle; 144 114 fibril_mutex_unlock(&instance->guard); … … 159 129 fibril_mutex_lock(&instance->guard); 160 130 assert(instance->devices[address].occupied); 131 161 132 instance->devices[address].occupied = false; 162 133 fibril_mutex_unlock(&instance->guard); … … 177 148 while (address <= USB11_ADDRESS_MAX) { 178 149 if (instance->devices[address].handle == handle) { 150 assert(instance->devices[address].occupied); 179 151 fibril_mutex_unlock(&instance->guard); 180 152 return address; … … 198 170 assert(address >= 0); 199 171 assert(address <= USB11_ADDRESS_MAX); 172 200 173 return instance->devices[address].speed; 201 174 }
Note:
See TracChangeset
for help on using the changeset viewer.