Changeset 9a818a9 in mainline
- Timestamp:
- 2011-02-07T12:49:19Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- e2172cf8
- Parents:
- da17cf0
- Location:
- uspace/drv/uhci-hcd
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/uhci-hcd/tracker.c
rda17cf0 r9a818a9 33 33 */ 34 34 #include <errno.h> 35 #include <mem.h>36 35 37 36 #include <usb/debug.h> 38 37 39 38 #include "tracker.h" 39 #include "uhci.h" 40 #include "utils/malloc32.h" 40 41 41 42 #define SETUP_PACKET_DATA_SIZE 8 … … 44 45 #define MIN(a,b) ((a < b) ? a : b) 45 46 47 static int tracker_schedule(tracker_t *instance); 48 46 49 static void tracker_control_read_data(tracker_t *instance); 47 50 static void tracker_control_write_data(tracker_t *instance); 48 51 static void tracker_control_read_status(tracker_t *instance); 49 52 static void tracker_control_write_status(tracker_t *instance); 50 51 52 int tracker_init(tracker_t *instance, device_t *dev, usb_target_t target, 53 size_t max_packet_size, dev_speed_t speed, char *buffer, size_t size, 53 static void tracker_call_in(tracker_t *instance); 54 static void tracker_call_out(tracker_t *instance); 55 static void tracker_call_in_and_dispose(tracker_t *instance); 56 static void tracker_call_out_and_dispose(tracker_t *instance); 57 58 59 tracker_t * tracker_get(device_t *dev, usb_target_t target, 60 usb_transfer_type_t transfer_type, size_t max_packet_size, 61 dev_speed_t speed, char *buffer, size_t size, 54 62 usbhc_iface_transfer_in_callback_t func_in, 55 63 usbhc_iface_transfer_out_callback_t func_out, void *arg) 56 64 { 57 assert(instance);58 65 assert(func_in == NULL || func_out == NULL); 59 66 assert(func_in != NULL || func_out != NULL); 67 68 tracker_t *instance = malloc(sizeof(tracker_t)); 69 if (!instance) { 70 usb_log_error("Failed to allocate tracker isntance.\n"); 71 return NULL; 72 } 60 73 61 74 instance->td = malloc32(sizeof(transfer_descriptor_t)); 62 75 if (!instance->td) { 63 76 usb_log_error("Failed to allocate transfer descriptor.\n"); 64 return ENOMEM; 77 free(instance); 78 return NULL; 65 79 } 66 80 … … 69 83 usb_log_error("Failed to allocate device acessible buffer.\n"); 70 84 free32(instance->td); 71 return ENOMEM; 85 free(instance); 86 return NULL; 72 87 } 73 88 instance->max_packet_size = max_packet_size; … … 77 92 link_initialize(&instance->link); 78 93 instance->target = target; 94 instance->transfer_type = transfer_type; 79 95 80 96 if (func_out) … … 87 103 instance->arg = arg; 88 104 instance->toggle = 0; 89 return EOK; 105 106 return instance; 90 107 } 91 108 /*----------------------------------------------------------------------------*/ … … 94 111 assert(instance); 95 112 assert(instance->buffer_offset == 0); 113 96 114 instance->packet_size = SETUP_PACKET_DATA_SIZE; 97 115 memcpy(instance->packet, instance->buffer, SETUP_PACKET_DATA_SIZE); 116 98 117 transfer_descriptor_init(instance->td, DEFAULT_ERROR_COUNT, 99 118 SETUP_PACKET_DATA_SIZE, false, instance->target, USB_PID_SETUP, 100 119 instance->packet); 120 101 121 instance->buffer_offset += SETUP_PACKET_DATA_SIZE; 102 122 instance->next_step = tracker_control_write_data; 103 //TODO: add to scheduler 123 124 tracker_schedule(instance); 104 125 } 105 126 /*----------------------------------------------------------------------------*/ … … 108 129 assert(instance); 109 130 assert(instance->buffer_offset == 0); 131 110 132 instance->packet_size = SETUP_PACKET_DATA_SIZE; 111 133 memcpy(instance->packet, instance->buffer, SETUP_PACKET_DATA_SIZE); 134 112 135 transfer_descriptor_init(instance->td, DEFAULT_ERROR_COUNT, 113 136 SETUP_PACKET_DATA_SIZE, false, instance->target, USB_PID_SETUP, 114 137 instance->packet); 138 115 139 instance->buffer_offset += SETUP_PACKET_DATA_SIZE; 116 140 instance->next_step = tracker_control_read_data; 117 //TODO: add to scheduler 141 142 tracker_schedule(instance); 118 143 } 119 144 /*----------------------------------------------------------------------------*/ … … 136 161 /* prepare next packet, no copy, we are receiving data */ 137 162 instance->packet_size = MIN(instance->max_packet_size, 138 instance->buffer_size - instance->buffer_offset); 139 transfer_descriptor_init(instance->td, DEFAULT_ERROR_COUNT, 140 instance->packet_size, false, instance->target, USB_PID_IN, 141 instance->packet); 142 // TODO: add to uhci scheduler 163 instance->buffer_size - instance->buffer_offset); 164 165 transfer_descriptor_init(instance->td, DEFAULT_ERROR_COUNT, 166 instance->packet_size, false, instance->target, USB_PID_IN, 167 instance->packet); 168 169 tracker_schedule(instance); 143 170 144 171 /* set next step */ … … 166 193 /* prepare next packet, copy data to packet */ 167 194 instance->packet_size = MIN(instance->max_packet_size, 168 195 instance->buffer_size - instance->buffer_offset); 169 196 memcpy(instance->packet, instance->buffer + instance->buffer_offset, 170 197 instance->packet_size); 171 198 transfer_descriptor_init(instance->td, DEFAULT_ERROR_COUNT, 172 instance->packet_size, false, instance->target, USB_PID_OUT, 173 instance->packet); 174 // TODO: add to uhci scheduler 199 instance->packet_size, false, instance->target, USB_PID_OUT, 200 instance->packet); 201 202 tracker_schedule(instance); 175 203 176 204 /* set next step */ … … 202 230 instance->packet_size = 0; 203 231 transfer_descriptor_init(instance->td, DEFAULT_ERROR_COUNT, 204 0, false, instance->target, USB_PID_OUT, NULL); 205 // TODO: add to uhci scheduler 232 0, false, instance->target, USB_PID_OUT, NULL); 233 234 tracker_schedule(instance); 206 235 207 236 /* set next step, callback and cleanup */ … … 229 258 instance->packet_size = 0; 230 259 transfer_descriptor_init(instance->td, DEFAULT_ERROR_COUNT, 231 0, false, instance->target, USB_PID_OUT, NULL); 232 // TODO: add to uhci scheduler 260 0, false, instance->target, USB_PID_OUT, NULL); 261 262 tracker_schedule(instance); 233 263 234 264 /* set next step, callback and cleanup */ … … 288 318 free(instance); 289 319 } 320 /*----------------------------------------------------------------------------*/ 321 int tracker_schedule(tracker_t *instance) 322 { 323 assert(instance); 324 uhci_t *hc = dev_to_uhci(instance->dev); 325 assert(hc); 326 return uhci_schedule(hc, instance); 327 } 328 /*----------------------------------------------------------------------------*/ 290 329 /* DEPRECATED FUNCTIONS NEEDED BY THE OLD API */ 291 330 void tracker_control_setup_old(tracker_t *instance) … … 293 332 assert(instance); 294 333 assert(instance->buffer_offset == 0); 334 295 335 instance->packet_size = SETUP_PACKET_DATA_SIZE; 296 336 memcpy(instance->packet, instance->buffer, SETUP_PACKET_DATA_SIZE); 337 297 338 transfer_descriptor_init(instance->td, DEFAULT_ERROR_COUNT, 298 339 SETUP_PACKET_DATA_SIZE, false, instance->target, USB_PID_SETUP, 299 340 instance->packet); 341 300 342 instance->buffer_offset += SETUP_PACKET_DATA_SIZE; 301 343 instance->next_step = tracker_call_out_and_dispose; 302 //TODO: add to scheduler 344 345 tracker_schedule(instance); 303 346 } 304 347 … … 307 350 assert(instance); 308 351 assert(instance->max_packet_size == instance->buffer_size); 352 309 353 memcpy(instance->packet, instance->buffer, instance->max_packet_size); 310 354 instance->packet_size = instance->max_packet_size; 311 transfer_descriptor_init(instance->td, DEFAULT_ERROR_COUNT, 312 instance->packet_size, false, instance->target, USB_PID_OUT, 313 instance->packet); 355 356 transfer_descriptor_init(instance->td, DEFAULT_ERROR_COUNT, 357 instance->packet_size, false, instance->target, USB_PID_OUT, 358 instance->packet); 314 359 instance->next_step = tracker_call_out_and_dispose; 360 361 tracker_schedule(instance); 315 362 } 316 363 … … 319 366 assert(instance); 320 367 assert(instance->max_packet_size == instance->buffer_size); 368 321 369 instance->packet_size = instance->max_packet_size; 322 transfer_descriptor_init(instance->td, DEFAULT_ERROR_COUNT, 323 instance->packet_size, false, instance->target, USB_PID_IN, 324 instance->packet); 370 371 transfer_descriptor_init(instance->td, DEFAULT_ERROR_COUNT, 372 instance->packet_size, false, instance->target, USB_PID_IN, 373 instance->packet); 374 325 375 instance->next_step = tracker_call_in_and_dispose; 376 377 tracker_schedule(instance); 326 378 } 327 379 … … 334 386 335 387 instance->packet_size = instance->max_packet_size; 336 transfer_descriptor_init(instance->td, DEFAULT_ERROR_COUNT,337 instance->packet_size, false, instance->target, USB_PID_IN,338 instance->packet);339 388 instance->next_step = tracker_call_in_and_dispose; 389 390 transfer_descriptor_init(instance->td, DEFAULT_ERROR_COUNT, 391 instance->packet_size, false, instance->target, USB_PID_IN, 392 instance->packet); 393 394 tracker_schedule(instance); 340 395 } 341 396 … … 348 403 349 404 instance->packet_size = instance->max_packet_size; 350 transfer_descriptor_init(instance->td, DEFAULT_ERROR_COUNT,351 instance->packet_size, false, instance->target, USB_PID_OUT,352 instance->packet);353 405 instance->next_step = tracker_call_out_and_dispose; 406 407 transfer_descriptor_init(instance->td, DEFAULT_ERROR_COUNT, 408 instance->packet_size, false, instance->target, USB_PID_OUT, 409 instance->packet); 410 411 tracker_schedule(instance); 354 412 } 355 413 /** -
uspace/drv/uhci-hcd/tracker.h
rda17cf0 r9a818a9 51 51 link_t link; 52 52 usb_target_t target; 53 usb_transfer_type_t transfer_type; 53 54 union { 54 55 usbhc_iface_transfer_in_callback_t callback_in; … … 70 71 71 72 72 int tracker_init(tracker_t *instance, device_t *dev, usb_target_t target, 73 size_t packet_size, dev_speed_t speed, char *buffer, size_t size, 73 tracker_t * tracker_get(device_t *dev, usb_target_t target, 74 usb_transfer_type_t transfer_type, size_t max_packet_size, 75 dev_speed_t speed, char *buffer, size_t size, 74 76 usbhc_iface_transfer_in_callback_t func_in, 75 77 usbhc_iface_transfer_out_callback_t func_out, void *arg); … … 82 84 83 85 void tracker_interrupt_out(tracker_t *instance); 84 85 void tracker_call_in(tracker_t *instance);86 87 void tracker_call_out(tracker_t *instance);88 89 void tracker_call_in_and_dispose(tracker_t *instance);90 91 void tracker_call_out_and_dispose(tracker_t *instance);92 86 93 87 /* DEPRECATED FUNCTIONS NEEDED BY THE OLD API */ -
uspace/drv/uhci-hcd/transfer_list.c
rda17cf0 r9a818a9 96 96 return EOK; 97 97 } 98 /*----------------------------------------------------------------------------*/ 99 void transfer_list_add_tracker(transfer_list_t *instance, tracker_t *tracker) 100 { 101 assert(instance); 102 assert(tracker); 103 104 uint32_t pa = (uintptr_t)addr_to_phys(tracker->td); 105 assert((pa & LINK_POINTER_ADDRESS_MASK) == pa); 106 107 if (instance->queue_head->element & LINK_POINTER_TERMINATE_FLAG) { 108 /* there is nothing scheduled */ 109 instance->last_tracker = tracker; 110 instance->queue_head->element = pa; 111 return; 112 } 113 /* now we can be sure that last_tracker is a valid pointer */ 114 instance->last_tracker->td->next = pa; 115 instance->last_tracker = tracker; 116 117 /* check again, may be use atomic compare and swap */ 118 if (instance->queue_head->element & LINK_POINTER_TERMINATE_FLAG) { 119 instance->queue_head->element = pa; 120 } 121 } 98 122 /** 99 123 * @} -
uspace/drv/uhci-hcd/transfer_list.h
rda17cf0 r9a818a9 37 37 #include "uhci_struct/queue_head.h" 38 38 #include "uhci_struct/transfer_descriptor.h" 39 #include "tracker.h" 39 40 40 41 typedef struct transfer_list … … 42 43 transfer_descriptor_t *first; 43 44 transfer_descriptor_t *last; 45 46 tracker_t *last_tracker; 47 44 48 queue_head_t *queue_head; 45 49 uint32_t queue_head_pa; … … 61 65 transfer_list_t *instance, transfer_descriptor_t *transfer); 62 66 67 void transfer_list_add_tracker(transfer_list_t *instance, tracker_t *tracker); 68 63 69 #endif 64 70 /** -
uspace/drv/uhci-hcd/uhci.c
rda17cf0 r9a818a9 86 86 87 87 const uintptr_t pa = (uintptr_t)addr_to_phys(instance->frame_list); 88 89 88 pio_write_32(&instance->registers->flbaseadd, (uint32_t)pa); 89 90 list_initialize(&instance->tracker_list); 90 91 91 92 instance->cleaner = fibril_create(uhci_clean_finished, instance); … … 209 210 return EOK; 210 211 } 211 /*---------------------------------------------------------------------------*/ 212 /*----------------------------------------------------------------------------*/ 213 int uhci_schedule(uhci_t *instance, tracker_t *tracker) 214 { 215 assert(instance); 216 assert(tracker); 217 const int low_speed = (tracker->speed == LOW_SPEED); 218 if (!allowed_usb_packet( 219 low_speed, tracker->transfer_type, tracker->packet_size)) { 220 usb_log_warning("Invalid USB packet specified %s SPEED %d %zu.\n", 221 low_speed ? "LOW" : "FULL" , tracker->transfer_type, 222 tracker->packet_size); 223 return ENOTSUP; 224 } 225 /* TODO: check available bandwith here */ 226 227 transfer_list_t *list = 228 instance->transfers[low_speed][tracker->transfer_type]; 229 assert(list); 230 transfer_list_add_tracker(list, tracker); 231 list_append(&tracker->link, &instance->tracker_list); 232 233 return EOK; 234 } 235 /*----------------------------------------------------------------------------*/ 212 236 int uhci_clean_finished(void* arg) 213 237 { … … 217 241 218 242 while(1) { 219 usb_log_debug("Running cleaning fibril on: %p.\n", instance); 243 /* tracker iteration */ 244 link_t *current = instance->tracker_list.next; 245 while (current != &instance->tracker_list) 246 { 247 link_t *next = current->next; 248 tracker_t *tracker = list_get_instance(current, tracker_t, link); 249 assert(current == &tracker->link); 250 if (!transfer_descriptor_is_active(tracker->td)) { 251 usb_log_debug("Found inactive tracker.\n"); 252 list_remove(current); 253 tracker->next_step(tracker); 254 } 255 current = next; 256 } 220 257 /* iterate all transfer queues */ 221 258 transfer_list_t *current_list = &instance->transfers_interrupt; -
uspace/drv/uhci-hcd/uhci.h
rda17cf0 r9a818a9 37 37 38 38 #include <fibril.h> 39 #include <adt/list.h> 39 40 40 41 #include <usb/addrkeep.h> … … 42 43 43 44 #include "transfer_list.h" 45 #include "tracker.h" 44 46 45 47 typedef struct uhci_regs { … … 79 81 link_pointer_t *frame_list; 80 82 83 link_t tracker_list; 84 81 85 transfer_list_t transfers_bulk_full; 82 86 transfer_list_t transfers_control_full; … … 108 112 void *arg ); 109 113 114 int uhci_schedule(uhci_t *instance, tracker_t *tracker); 115 110 116 static inline uhci_t * dev_to_uhci(device_t *dev) 111 117 { return (uhci_t*)dev->driver_data; } -
uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.h
rda17cf0 r9a818a9 124 124 int transfer_descriptor_status(transfer_descriptor_t *instance); 125 125 126 static inline bool transfer_descriptor_is_active( 127 transfer_descriptor_t *instance) 128 { 129 assert(instance); 130 return instance->status & TD_STATUS_ERROR_ACTIVE; 131 } 132 126 133 static inline void transfer_descriptor_append( 127 134 transfer_descriptor_t *instance, transfer_descriptor_t *item)
Note:
See TracChangeset
for help on using the changeset viewer.