Changes in / [54d9058:dc04868] in mainline
- Location:
- uspace/drv/uhci-hcd
- Files:
-
- 2 added
- 2 deleted
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/uhci-hcd/Makefile
r54d9058 rdc04868 40 40 uhci_struct/transfer_descriptor.c \ 41 41 pci.c \ 42 batch.c42 tracker.c 43 43 44 44 include $(USPACE_PREFIX)/Makefile.common -
uspace/drv/uhci-hcd/iface.c
r54d9058 rdc04868 109 109 dev_speed_t speed = FULL_SPEED; 110 110 111 batch_t *batch = batch_get(dev, target, USB_TRANSFER_INTERRUPT,112 max_packet_size, speed, data, size, NULL, 0, NULL,callback, arg);113 if (! batch)114 return ENOMEM; 115 batch_interrupt_out(batch);111 tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_INTERRUPT, 112 max_packet_size, speed, data, size, NULL, callback, arg); 113 if (!tracker) 114 return ENOMEM; 115 tracker_interrupt_out(tracker); 116 116 return EOK; 117 117 } … … 124 124 dev_speed_t speed = FULL_SPEED; 125 125 126 batch_t *batch = batch_get(dev, target, USB_TRANSFER_INTERRUPT,127 max_packet_size, speed, data, size, NULL, 0,callback, NULL, arg);128 if (! batch)129 return ENOMEM; 130 batch_interrupt_in(batch);126 tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_INTERRUPT, 127 max_packet_size, speed, data, size, callback, NULL, arg); 128 if (!tracker) 129 return ENOMEM; 130 tracker_interrupt_in(tracker); 131 131 return EOK; 132 132 } … … 139 139 dev_speed_t speed = FULL_SPEED; 140 140 141 batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL, 142 max_packet_size, speed, data, size, setup_data, setup_size, 143 NULL, callback, arg); 144 if (!batch) 145 return ENOMEM; 146 batch_control_write(batch); 141 tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL, 142 max_packet_size, speed, data, size, NULL, callback, arg); 143 if (!tracker) 144 return ENOMEM; 145 tracker_control_write(tracker, setup_data, setup_size); 147 146 return EOK; 148 147 } … … 155 154 dev_speed_t speed = FULL_SPEED; 156 155 157 batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL, 158 max_packet_size, speed, data, size, setup_data, setup_size, callback, 159 NULL, arg); 160 if (!batch) 161 return ENOMEM; 162 batch_control_read(batch); 156 tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL, 157 max_packet_size, speed, data, size, callback, NULL, arg); 158 if (!tracker) 159 return ENOMEM; 160 tracker_control_read(tracker, setup_data, setup_size); 163 161 return EOK; 164 162 } … … 168 166 usbhc_iface_transfer_out_callback_t callback, void *arg) 169 167 { 170 size_t max_packet_size = 8; 171 dev_speed_t speed = FULL_SPEED; 172 173 usb_log_warning("Using deprecated API %s.\n", __FUNCTION__); 174 batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL, 175 max_packet_size, speed, NULL, 0, data, size, NULL, callback, arg); 176 if (!batch) 177 return ENOMEM; 178 batch_control_setup_old(batch); 168 usb_log_warning("Using deprecated API %s.\n", __FUNCTION__); 169 tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL, 170 8, FULL_SPEED, data, size, NULL, callback, arg); 171 if (!tracker) 172 return ENOMEM; 173 tracker_control_setup_old(tracker); 179 174 return EOK; 180 175 } … … 184 179 usbhc_iface_transfer_out_callback_t callback, void *arg) 185 180 { 186 size_t max_packet_size = 8; 187 dev_speed_t speed = FULL_SPEED; 188 189 usb_log_warning("Using deprecated API %s.\n", __FUNCTION__); 190 batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL, 191 max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg); 192 if (!batch) 193 return ENOMEM; 194 batch_control_write_data_old(batch); 181 usb_log_warning("Using deprecated API %s.\n", __FUNCTION__); 182 tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL, 183 size, FULL_SPEED, data, size, NULL, callback, arg); 184 if (!tracker) 185 return ENOMEM; 186 tracker_control_write_data_old(tracker); 195 187 return EOK; 196 188 } … … 199 191 usbhc_iface_transfer_in_callback_t callback, void *arg) 200 192 { 201 size_t max_packet_size = 8; 202 dev_speed_t speed = FULL_SPEED; 203 204 usb_log_warning("Using deprecated API %s.\n", __FUNCTION__); 205 batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL, 206 max_packet_size, speed, NULL, 0, NULL, 0, callback, NULL, arg); 207 if (!batch) 208 return ENOMEM; 209 batch_control_write_status_old(batch); 193 usb_log_warning("Using deprecated API %s.\n", __FUNCTION__); 194 tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL, 195 0, FULL_SPEED, NULL, 0, callback, NULL, arg); 196 if (!tracker) 197 return ENOMEM; 198 tracker_control_write_status_old(tracker); 210 199 return EOK; 211 200 } … … 215 204 usbhc_iface_transfer_out_callback_t callback, void *arg) 216 205 { 217 size_t max_packet_size = 8; 218 dev_speed_t speed = FULL_SPEED; 219 220 usb_log_warning("Using deprecated API %s.\n", __FUNCTION__); 221 batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL, 222 max_packet_size, speed, NULL, 0, data, size, NULL, callback, arg); 223 if (!batch) 224 return ENOMEM; 225 batch_control_setup_old(batch); 206 usb_log_warning("Using deprecated API %s.\n", __FUNCTION__); 207 tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL, 208 8, FULL_SPEED, data, size, NULL, callback, arg); 209 if (!tracker) 210 return ENOMEM; 211 tracker_control_setup_old(tracker); 226 212 return EOK; 227 213 } … … 231 217 usbhc_iface_transfer_in_callback_t callback, void *arg) 232 218 { 233 size_t max_packet_size = 8; 234 dev_speed_t speed = FULL_SPEED; 235 236 usb_log_warning("Using deprecated API %s.\n", __FUNCTION__); 237 batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL, 238 max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg); 239 if (!batch) 240 return ENOMEM; 241 batch_control_read_data_old(batch); 219 usb_log_warning("Using deprecated API %s.\n", __FUNCTION__); 220 tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL, 221 size, FULL_SPEED, data, size, callback, NULL, arg); 222 if (!tracker) 223 return ENOMEM; 224 tracker_control_read_data_old(tracker); 242 225 return EOK; 243 226 } … … 246 229 usbhc_iface_transfer_out_callback_t callback, void *arg) 247 230 { 248 size_t max_packet_size = 8; 249 dev_speed_t speed = FULL_SPEED; 250 251 usb_log_warning("Using deprecated API %s.\n", __FUNCTION__); 252 batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL, 253 max_packet_size, speed, NULL, 0, NULL, 0, NULL, callback, arg); 254 if (!batch) 255 return ENOMEM; 256 batch_control_read_status_old(batch); 231 usb_log_warning("Using deprecated API %s.\n", __FUNCTION__); 232 tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL, 233 0, FULL_SPEED, NULL, 0, NULL, callback, arg); 234 if (!tracker) 235 return ENOMEM; 236 tracker_control_read_status_old(tracker); 257 237 return EOK; 258 238 } -
uspace/drv/uhci-hcd/transfer_list.c
r54d9058 rdc04868 51 51 52 52 queue_head_init(instance->queue_head); 53 list_initialize(&instance->batch_list);54 fibril_mutex_initialize(&instance->guard);55 53 return EOK; 56 54 } … … 60 58 assert(instance); 61 59 assert(next); 60 instance->next = next; 62 61 if (!instance->queue_head) 63 62 return; 64 queue_head_append_qh(instance->queue_head, next->queue_head_pa); 65 instance->queue_head->element = instance->queue_head->next_queue; 63 queue_head_add_next(instance->queue_head, next->queue_head_pa); 66 64 } 67 65 /*----------------------------------------------------------------------------*/ 68 void transfer_list_add_ batch(transfer_list_t *instance, batch_t *batch)66 void transfer_list_add_tracker(transfer_list_t *instance, tracker_t *tracker) 69 67 { 70 68 assert(instance); 71 assert( batch);69 assert(tracker); 72 70 73 uint32_t pa = (uintptr_t)addr_to_phys( batch->qh);71 uint32_t pa = (uintptr_t)addr_to_phys(tracker->td); 74 72 assert((pa & LINK_POINTER_ADDRESS_MASK) == pa); 75 pa |= LINK_POINTER_QUEUE_HEAD_FLAG;76 73 77 batch->qh->next_queue = instance->queue_head->next_queue;78 74 79 fibril_mutex_lock(&instance->guard);80 81 if (instance->queue_head->element == instance->queue_head->next_queue) {75 if (instance->queue_head->element & LINK_POINTER_TERMINATE_FLAG) { 76 usb_log_debug2("Adding td(%X:%X) to queue %s first.\n", 77 tracker->td->status, tracker->td->device, instance->name); 82 78 /* there is nothing scheduled */ 83 list_append(&batch->link, &instance->batch_list);79 instance->last_tracker = tracker; 84 80 instance->queue_head->element = pa; 85 usb_log_debug2("Added batch(%p) to queue %s first.\n", 86 batch, instance->name); 87 fibril_mutex_unlock(&instance->guard); 81 usb_log_debug2("Added td(%X:%X) to queue %s first.\n", 82 tracker->td->status, tracker->td->device, instance->name); 88 83 return; 89 84 } 90 /* now we can be sure that there is someting scheduled */ 91 assert(!list_empty(&instance->batch_list)); 92 batch_t *first = list_get_instance( 93 instance->batch_list.next, batch_t, link); 94 batch_t *last = list_get_instance( 95 instance->batch_list.prev, batch_t, link); 96 queue_head_append_qh(last->qh, pa); 97 list_append(&batch->link, &instance->batch_list); 98 usb_log_debug2("Added batch(%p) to queue %s last, first is %p.\n", 99 batch, instance->name, first ); 100 fibril_mutex_unlock(&instance->guard); 85 usb_log_debug2("Adding td(%X:%X) to queue %s last.%p\n", 86 tracker->td->status, tracker->td->device, instance->name, 87 instance->last_tracker); 88 /* now we can be sure that last_tracker is a valid pointer */ 89 instance->last_tracker->td->next = pa; 90 instance->last_tracker = tracker; 91 92 usb_log_debug2("Added td(%X:%X) to queue %s last.\n", 93 tracker->td->status, tracker->td->device, instance->name); 94 95 /* check again, may be use atomic compare and swap */ 96 if (instance->queue_head->element & LINK_POINTER_TERMINATE_FLAG) { 97 instance->queue_head->element = pa; 98 usb_log_debug2("Added td(%X:%X) to queue first2 %s.\n", 99 tracker->td->status, tracker->td->device, instance->name); 100 } 101 101 } 102 102 /*----------------------------------------------------------------------------*/ 103 static void transfer_list_remove_batch( 104 transfer_list_t *instance, batch_t *batch) 103 void transfer_list_remove_tracker(transfer_list_t *instance, tracker_t *tracker) 105 104 { 106 105 assert(instance); 107 assert( batch);106 assert(tracker); 108 107 assert(instance->queue_head); 109 assert( batch->qh);108 assert(tracker->td); 110 109 111 /* I'm the first one here */ 112 if (batch->link.prev == &instance->batch_list) { 113 usb_log_debug("Removing tracer %p was first, next element %x.\n", 114 batch, batch->qh->next_queue); 115 instance->queue_head->element = batch->qh->next_queue; 116 } else { 117 usb_log_debug("Removing tracer %p was NOT first, next element %x.\n", 118 batch, batch->qh->next_queue); 119 batch_t *prev = list_get_instance(batch->link.prev, batch_t, link); 120 prev->qh->next_queue = batch->qh->next_queue; 110 uint32_t pa = (uintptr_t)addr_to_phys(tracker->td); 111 if ((instance->queue_head->element & LINK_POINTER_ADDRESS_MASK) == pa) { 112 instance->queue_head->element = tracker->td->next; 121 113 } 122 list_remove(&batch->link);123 }124 /*----------------------------------------------------------------------------*/125 void transfer_list_check(transfer_list_t *instance)126 {127 assert(instance);128 fibril_mutex_lock(&instance->guard);129 link_t *current = instance->batch_list.next;130 while (current != &instance->batch_list) {131 link_t *next = current->next;132 batch_t *batch = list_get_instance(current, batch_t, link);133 134 if (batch_is_complete(batch)) {135 transfer_list_remove_batch(instance, batch);136 batch->next_step(batch);137 }138 current = next;139 }140 fibril_mutex_unlock(&instance->guard);141 114 } 142 115 /** -
uspace/drv/uhci-hcd/transfer_list.h
r54d9058 rdc04868 35 35 #define DRV_UHCI_TRANSFER_LIST_H 36 36 37 #include <fibril_synch.h>38 39 37 #include "uhci_struct/queue_head.h" 40 38 41 #include " batch.h"39 #include "tracker.h" 42 40 43 41 typedef struct transfer_list 44 42 { 45 fibril_mutex_t guard; 43 tracker_t *last_tracker; 44 46 45 queue_head_t *queue_head; 47 46 uint32_t queue_head_pa; 48 47 struct transfer_list *next; 49 48 const char *name; 50 link_t batch_list;51 49 } transfer_list_t; 52 50 … … 55 53 void transfer_list_set_next(transfer_list_t *instance, transfer_list_t *next); 56 54 55 57 56 static inline void transfer_list_fini(transfer_list_t *instance) 58 57 { … … 60 59 queue_head_dispose(instance->queue_head); 61 60 } 62 void transfer_list_check(transfer_list_t *instance);63 61 64 void transfer_list_add_batch(transfer_list_t *instance, batch_t *batch); 62 void transfer_list_add_tracker(transfer_list_t *instance, tracker_t *tracker); 63 64 void transfer_list_remove_tracker(transfer_list_t *instance, tracker_t *track); 65 65 66 #endif 66 67 /** -
uspace/drv/uhci-hcd/uhci.c
r54d9058 rdc04868 89 89 pio_write_32(&instance->registers->flbaseadd, (uint32_t)pa); 90 90 91 list_initialize(&instance-> batch_list);92 fibril_mutex_initialize(&instance-> batch_list_mutex);91 list_initialize(&instance->tracker_list); 92 fibril_mutex_initialize(&instance->tracker_list_mutex); 93 93 94 94 instance->cleaner = fibril_create(uhci_clean_finished, instance); … … 152 152 } 153 153 /*----------------------------------------------------------------------------*/ 154 int uhci_schedule(uhci_t *instance, batch_t *batch)154 int uhci_schedule(uhci_t *instance, tracker_t *tracker) 155 155 { 156 156 assert(instance); 157 assert( batch);158 const int low_speed = ( batch->speed == LOW_SPEED);157 assert(tracker); 158 const int low_speed = (tracker->speed == LOW_SPEED); 159 159 if (!allowed_usb_packet( 160 low_speed, batch->transfer_type, batch->max_packet_size)) {160 low_speed, tracker->transfer_type, tracker->packet_size)) { 161 161 usb_log_warning("Invalid USB packet specified %s SPEED %d %zu.\n", 162 low_speed ? "LOW" : "FULL" , batch->transfer_type,163 batch->max_packet_size);162 low_speed ? "LOW" : "FULL" , tracker->transfer_type, 163 tracker->packet_size); 164 164 return ENOTSUP; 165 165 } 166 166 /* TODO: check available bandwith here */ 167 167 168 usb_log_debug2("Scheduler(%d) acquiring tracker list mutex.\n", 169 fibril_get_id()); 170 fibril_mutex_lock(&instance->tracker_list_mutex); 171 usb_log_debug2("Scheduler(%d) acquired tracker list mutex.\n", 172 fibril_get_id()); 173 168 174 transfer_list_t *list = 169 instance->transfers[low_speed][ batch->transfer_type];175 instance->transfers[low_speed][tracker->transfer_type]; 170 176 assert(list); 171 transfer_list_add_batch(list, batch); 177 transfer_list_add_tracker(list, tracker); 178 list_append(&tracker->link, &instance->tracker_list); 179 180 tracker->scheduled_list = list; 181 182 usb_log_debug2("Scheduler(%d) releasing tracker list mutex.\n", 183 fibril_get_id()); 184 fibril_mutex_unlock(&instance->tracker_list_mutex); 185 usb_log_debug2("Scheduler(%d) released tracker list mutex.\n", 186 fibril_get_id()); 172 187 173 188 return EOK; … … 181 196 182 197 while(1) { 183 transfer_list_check(&instance->transfers_interrupt); 184 transfer_list_check(&instance->transfers_control_slow); 185 transfer_list_check(&instance->transfers_control_full); 186 transfer_list_check(&instance->transfers_bulk_full); 198 LIST_INITIALIZE(done_trackers); 199 /* tracker iteration */ 200 201 usb_log_debug2("Cleaner(%d) acquiring tracker list mutex.\n", 202 fibril_get_id()); 203 fibril_mutex_lock(&instance->tracker_list_mutex); 204 usb_log_debug2("Cleaner(%d) acquired tracker list mutex.\n", 205 fibril_get_id()); 206 207 link_t *current = instance->tracker_list.next; 208 while (current != &instance->tracker_list) 209 { 210 211 link_t *next = current->next; 212 tracker_t *tracker = list_get_instance(current, tracker_t, link); 213 214 assert(current == &tracker->link); 215 assert(tracker); 216 assert(tracker->next_step); 217 assert(tracker->td); 218 219 if (!transfer_descriptor_is_active(tracker->td)) { 220 usb_log_info("Found inactive tracker with status: %x:%x.\n", 221 tracker->td->status, tracker->td->device); 222 list_remove(current); 223 list_append(current, &done_trackers); 224 } 225 current = next; 226 } 227 228 usb_log_debug2("Cleaner(%d) releasing tracker list mutex.\n", 229 fibril_get_id()); 230 fibril_mutex_unlock(&instance->tracker_list_mutex); 231 usb_log_debug2("Cleaner(%d) released tracker list mutex.\n", 232 fibril_get_id()); 233 234 while (!list_empty(&done_trackers)) { 235 tracker_t *tracker = list_get_instance( 236 done_trackers.next, tracker_t, link); 237 list_remove(&tracker->link); 238 tracker->next_step(tracker); 239 } 187 240 async_usleep(UHCI_CLEANER_TIMEOUT); 188 241 } -
uspace/drv/uhci-hcd/uhci.h
r54d9058 rdc04868 44 44 45 45 #include "transfer_list.h" 46 #include " batch.h"46 #include "tracker.h" 47 47 48 48 typedef struct uhci_regs { … … 72 72 73 73 #define UHCI_FRAME_LIST_COUNT 1024 74 #define UHCI_CLEANER_TIMEOUT 1000 074 #define UHCI_CLEANER_TIMEOUT 1000 75 75 #define UHCI_DEBUGER_TIMEOUT 5000000 76 76 … … 81 81 link_pointer_t *frame_list; 82 82 83 link_t batch_list;84 fibril_mutex_t batch_list_mutex;83 link_t tracker_list; 84 fibril_mutex_t tracker_list_mutex; 85 85 86 86 transfer_list_t transfers_bulk_full; … … 113 113 void *arg ); 114 114 115 int uhci_schedule(uhci_t *instance, batch_t *batch);115 int uhci_schedule(uhci_t *instance, tracker_t *tracker); 116 116 117 117 static inline uhci_t * dev_to_uhci(device_t *dev) -
uspace/drv/uhci-hcd/uhci_struct/queue_head.h
r54d9058 rdc04868 55 55 } 56 56 57 static inline void queue_head_a ppend_qh(queue_head_t *instance, uint32_tpa)57 static inline void queue_head_add_next(queue_head_t *instance, uint32_t next_queue_pa) 58 58 { 59 if ( pa) {60 instance->next_queue = ( pa & LINK_POINTER_ADDRESS_MASK)61 59 if (next_queue_pa) { 60 instance->next_queue = (next_queue_pa & LINK_POINTER_ADDRESS_MASK) 61 | LINK_POINTER_QUEUE_HEAD_FLAG; 62 62 } 63 63 } 64 64 65 static inline void queue_head_element_qh(queue_head_t *instance, uint32_t pa) 66 { 67 if (pa) { 68 instance->next_queue = (pa & LINK_POINTER_ADDRESS_MASK) 69 | LINK_POINTER_QUEUE_HEAD_FLAG; 70 } 71 } 72 73 static inline void queue_head_element_td(queue_head_t *instance, uint32_t pa) 74 { 75 if (pa) { 76 instance->element = (pa & LINK_POINTER_ADDRESS_MASK); 77 } 78 } 79 80 static inline queue_head_t * queue_head_get() { 81 queue_head_t *ret = malloc32(sizeof(queue_head_t)); 82 if (ret) 83 queue_head_init(ret); 84 return ret; 85 } 65 static inline queue_head_t * queue_head_get() 66 { return malloc32(sizeof(queue_head_t)); } 86 67 87 68 static inline void queue_head_dispose(queue_head_t *head) -
uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.c
r54d9058 rdc04868 40 40 void transfer_descriptor_init(transfer_descriptor_t *instance, 41 41 int error_count, size_t size, bool toggle, bool isochronous, 42 usb_target_t target, int pid, void *buffer , transfer_descriptor_t *next)42 usb_target_t target, int pid, void *buffer) 43 43 { 44 44 assert(instance); 45 45 46 instance->next = 0 47 | LINK_POINTER_VERTICAL_FLAG 48 | ((next != NULL) ? addr_to_phys(next) : LINK_POINTER_TERMINATE_FLAG); 46 instance->next = 0 | LINK_POINTER_TERMINATE_FLAG; 49 47 50 48 instance->status = 0 -
uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.h
r54d9058 rdc04868 93 93 void transfer_descriptor_init(transfer_descriptor_t *instance, 94 94 int error_count, size_t size, bool toggle, bool isochronous, 95 usb_target_t target, int pid, void *buffer , transfer_descriptor_t * next);95 usb_target_t target, int pid, void *buffer); 96 96 97 97 int transfer_descriptor_status(transfer_descriptor_t *instance); 98 99 static inline size_t transfer_descriptor_actual_size(100 transfer_descriptor_t *instance)101 {102 assert(instance);103 return104 ((instance->status >> TD_STATUS_ACTLEN_POS) + 1) & TD_STATUS_ACTLEN_MASK;105 }106 98 107 99 static inline bool transfer_descriptor_is_active( -
uspace/drv/uhci-hcd/utils/malloc32.h
r54d9058 rdc04868 45 45 #define UHCI_REQUIRED_PAGE_SIZE 4096 46 46 47 static inline uintptr_taddr_to_phys(void *addr)47 static inline void * addr_to_phys(void *addr) 48 48 { 49 49 uintptr_t result; … … 51 51 52 52 assert(ret == 0); 53 return ( result | ((uintptr_t)addr & 0xfff));53 return (void*)(result | ((uintptr_t)addr & 0xfff)); 54 54 } 55 55
Note:
See TracChangeset
for help on using the changeset viewer.