Changeset 6143ce3 in mainline
- Timestamp:
- 2011-03-13T15:37:28Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 8850690
- Parents:
- eb0dc58
- Location:
- uspace/drv/uhci-hcd
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/uhci-hcd/batch.c
reb0dc58 r6143ce3 100 100 bzero(instance, sizeof(batch_t)); 101 101 102 instance->qh = malloc32(sizeof(q ueue_head_t));102 instance->qh = malloc32(sizeof(qh_t)); 103 103 CHECK_NULL_DISPOSE_RETURN(instance->qh, 104 104 "Failed to allocate batch queue head.\n"); 105 q ueue_head_init(instance->qh);105 qh_init(instance->qh); 106 106 107 107 instance->packets = (size + max_packet_size - 1) / max_packet_size; … … 114 114 instance->tds, "Failed to allocate transfer descriptors.\n"); 115 115 bzero(instance->tds, sizeof(td_t) * instance->packets); 116 117 // const size_t transport_size = max_packet_size * instance->packets;118 116 119 117 if (size > 0) { … … 143 141 instance->speed = speed; 144 142 instance->manager = manager; 145 146 if (func_out) 147 instance->callback_out = func_out; 148 if (func_in) 149 instance->callback_in = func_in; 150 151 queue_head_set_element_td(instance->qh, addr_to_phys(instance->tds)); 143 instance->callback_out = func_out; 144 instance->callback_in = func_in; 145 146 qh_set_element_td(instance->qh, addr_to_phys(instance->tds)); 152 147 153 148 usb_log_debug("Batch(%p) %d:%d memory structures ready.\n", -
uspace/drv/uhci-hcd/batch.h
reb0dc58 r6143ce3 50 50 usb_target_t target; 51 51 usb_transfer_type_t transfer_type; 52 union { 53 usbhc_iface_transfer_in_callback_t callback_in; 54 usbhc_iface_transfer_out_callback_t callback_out; 55 }; 52 usbhc_iface_transfer_in_callback_t callback_in; 53 usbhc_iface_transfer_out_callback_t callback_out; 56 54 void *arg; 57 55 char *transport_buffer; … … 65 63 int error; 66 64 ddf_fun_t *fun; 67 q ueue_head_t *qh;65 qh_t *qh; 68 66 td_t *tds; 69 67 void (*next_step)(struct batch*); -
uspace/drv/uhci-hcd/transfer_list.c
reb0dc58 r6143ce3 47 47 * @return Error code 48 48 * 49 * Allocates memory for interna t queue_head_t structure.49 * Allocates memory for internal qh_t structure. 50 50 */ 51 51 int transfer_list_init(transfer_list_t *instance, const char *name) 52 52 { 53 53 assert(instance); 54 instance->next = NULL;55 54 instance->name = name; 56 instance->queue_head = malloc32(sizeof(q ueue_head_t));55 instance->queue_head = malloc32(sizeof(qh_t)); 57 56 if (!instance->queue_head) { 58 57 usb_log_error("Failed to allocate queue head.\n"); … … 61 60 instance->queue_head_pa = addr_to_phys(instance->queue_head); 62 61 63 q ueue_head_init(instance->queue_head);62 qh_init(instance->queue_head); 64 63 list_initialize(&instance->batch_list); 65 64 fibril_mutex_initialize(&instance->guard); … … 72 71 * @param[in] next List to append. 73 72 * @return Error code 73 * 74 * Does not check whether there was a next list already. 74 75 */ 75 76 void transfer_list_set_next(transfer_list_t *instance, transfer_list_t *next) … … 79 80 if (!instance->queue_head) 80 81 return; 81 queue_head_append_qh(instance->queue_head, next->queue_head_pa); 82 instance->queue_head->element = instance->queue_head->next_queue; 82 /* set both next and element to point to the same QH */ 83 qh_set_next_qh(instance->queue_head, next->queue_head_pa); 84 qh_set_element_qh(instance->queue_head, next->queue_head_pa); 83 85 } 84 86 /*----------------------------------------------------------------------------*/ … … 93 95 assert(instance); 94 96 assert(batch); 95 usb_log_debug2( 96 "Adding batch(%p) to queue %s.\n", batch, instance->name); 97 usb_log_debug2("Queue %s: Adding batch(%p).\n", instance->name, batch); 97 98 98 uint32_t pa = (uintptr_t)addr_to_phys(batch->qh);99 const uint32_t pa = addr_to_phys(batch->qh); 99 100 assert((pa & LINK_POINTER_ADDRESS_MASK) == pa); 100 pa |= LINK_POINTER_QUEUE_HEAD_FLAG;101 101 102 batch->qh->next_queue = instance->queue_head->next_queue; 102 /* New batch will be added to the end of the current list 103 * so set the link accordingly */ 104 qh_set_next_qh(batch->qh, instance->queue_head->next); 103 105 104 106 fibril_mutex_lock(&instance->guard); 105 107 106 if (instance->queue_head->element == instance->queue_head->next_queue) { 107 /* there is nothing scheduled */ 108 list_append(&batch->link, &instance->batch_list); 109 instance->queue_head->element = pa; 110 usb_log_debug("Batch(%p) added to queue %s first.\n", 111 batch, instance->name); 112 fibril_mutex_unlock(&instance->guard); 113 return; 108 if (list_empty(&instance->batch_list)) { 109 /* There is nothing scheduled */ 110 qh_t *qh = instance->queue_head; 111 assert(qh->element == qh->next); 112 qh_set_element_qh(qh, pa); 113 } else { 114 /* There is something scheduled */ 115 batch_t *last = list_get_instance( 116 instance->batch_list.prev, batch_t, link); 117 qh_set_next_qh(last->qh, pa); 114 118 } 115 /* now we can be sure that there is someting scheduled */116 assert(!list_empty(&instance->batch_list));117 batch_t *first = list_get_instance(118 instance->batch_list.next, batch_t, link);119 batch_t *last = list_get_instance(120 instance->batch_list.prev, batch_t, link);121 queue_head_append_qh(last->qh, pa);122 119 list_append(&batch->link, &instance->batch_list); 123 120 124 usb_log_debug("Batch(%p) added to queue %s last, first is %p.\n", 121 batch_t *first = list_get_instance( 122 instance->batch_list.next, batch_t, link); 123 usb_log_debug("Batch(%p) added to queue %s, first is %p.\n", 125 124 batch, instance->name, first); 126 125 fibril_mutex_unlock(&instance->guard); 127 126 } 128 127 /*----------------------------------------------------------------------------*/ 129 /** Removes a transfer batch from list and queue.128 /** Removes a transfer batch from the list and queue. 130 129 * 131 130 * @param[in] instance List to use. 132 131 * @param[in] batch Transfer batch to remove. 133 132 * @return Error code 133 * 134 * Does not lock the transfer list, caller is responsible for that. 134 135 */ 135 136 void transfer_list_remove_batch(transfer_list_t *instance, batch_t *batch) … … 140 141 assert(batch->qh); 141 142 usb_log_debug2( 142 " Removing batch(%p) from queue %s.\n", batch, instance->name);143 "Queue %s: removing batch(%p).\n", instance->name, batch); 143 144 145 const char * pos = NULL; 144 146 if (batch->link.prev == &instance->batch_list) { 145 147 /* I'm the first one here */ 146 usb_log_debug( 147 "Batch(%p) removed (FIRST) from %s, next element %x.\n", 148 batch, instance->name, batch->qh->next_queue); 149 instance->queue_head->element = batch->qh->next_queue; 148 qh_set_element_qh(instance->queue_head, batch->qh->next); 149 pos = "FIRST"; 150 150 } else { 151 usb_log_debug(152 "Batch(%p) removed (FIRST:NO) from %s, next element %x.\n",153 batch, instance->name, batch->qh->next_queue);154 151 batch_t *prev = 155 152 list_get_instance(batch->link.prev, batch_t, link); 156 prev->qh->next_queue = batch->qh->next_queue; 153 qh_set_next_qh(prev->qh, batch->qh->next); 154 pos = "NOT FIRST"; 157 155 } 158 156 list_remove(&batch->link); 157 usb_log_debug("Batch(%p) removed (%s) from %s, next element %x.\n", 158 batch, pos, instance->name, batch->qh->next); 159 159 } 160 160 /*----------------------------------------------------------------------------*/ 161 /** Checks list for finished transfers.161 /** Checks list for finished batches. 162 162 * 163 163 * @param[in] instance List to use. -
uspace/drv/uhci-hcd/transfer_list.h
reb0dc58 r6143ce3 44 44 { 45 45 fibril_mutex_t guard; 46 q ueue_head_t *queue_head;46 qh_t *queue_head; 47 47 uint32_t queue_head_pa; 48 struct transfer_list *next;49 48 const char *name; 50 49 link_t batch_list; -
uspace/drv/uhci-hcd/uhci.c
reb0dc58 r6143ce3 437 437 int frnum = pio_read_16(&instance->registers->frnum) & 0x3ff; 438 438 439 uintptr_t expected_pa = instance->frame_list[frnum] & (~0xf); 439 uintptr_t expected_pa = instance->frame_list[frnum] 440 & LINK_POINTER_ADDRESS_MASK; 440 441 uintptr_t real_pa = addr_to_phys(QH(interrupt)); 441 442 if (expected_pa != real_pa) { … … 444 445 } 445 446 446 expected_pa = QH(interrupt)->next _queue & (~0xf);447 expected_pa = QH(interrupt)->next & LINK_POINTER_ADDRESS_MASK; 447 448 real_pa = addr_to_phys(QH(control_slow)); 448 449 if (expected_pa != real_pa) { … … 451 452 } 452 453 453 expected_pa = QH(control_slow)->next _queue & (~0xf);454 expected_pa = QH(control_slow)->next & LINK_POINTER_ADDRESS_MASK; 454 455 real_pa = addr_to_phys(QH(control_full)); 455 456 if (expected_pa != real_pa) { … … 458 459 } 459 460 460 expected_pa = QH(control_full)->next _queue & (~0xf);461 expected_pa = QH(control_full)->next & LINK_POINTER_ADDRESS_MASK; 461 462 real_pa = addr_to_phys(QH(bulk_full)); 462 463 if (expected_pa != real_pa ) { -
uspace/drv/uhci-hcd/uhci_struct/link_pointer.h
reb0dc58 r6143ce3 46 46 #define LINK_POINTER_ADDRESS_MASK 0xfffffff0 /* upper 28 bits */ 47 47 48 #define LINK_POINTER_QH(address) \ 49 ((address & LINK_POINTER_ADDRESS_MASK) | LINK_POINTER_QUEUE_HEAD_FLAG) 50 48 51 #endif 49 52 /** -
uspace/drv/uhci-hcd/uhci_struct/queue_head.h
reb0dc58 r6143ce3 43 43 44 44 typedef struct queue_head { 45 volatile link_pointer_t next _queue;45 volatile link_pointer_t next; 46 46 volatile link_pointer_t element; 47 } __attribute__((packed)) q ueue_head_t;48 49 static inline void q ueue_head_init(queue_head_t *instance)47 } __attribute__((packed)) qh_t; 48 /*----------------------------------------------------------------------------*/ 49 static inline void qh_init(qh_t *instance) 50 50 { 51 51 assert(instance); 52 52 53 53 instance->element = 0 | LINK_POINTER_TERMINATE_FLAG; 54 instance->next _queue= 0 | LINK_POINTER_TERMINATE_FLAG;54 instance->next = 0 | LINK_POINTER_TERMINATE_FLAG; 55 55 } 56 57 static inline void q ueue_head_append_qh(queue_head_t *instance, uint32_t pa)56 /*----------------------------------------------------------------------------*/ 57 static inline void qh_set_next_qh(qh_t *instance, uint32_t pa) 58 58 { 59 if (pa) { 60 instance->next_queue = (pa & LINK_POINTER_ADDRESS_MASK) 59 /* address is valid and not terminal */ 60 if (pa && ((pa & LINK_POINTER_TERMINATE_FLAG) == 0)) { 61 instance->next = (pa & LINK_POINTER_ADDRESS_MASK) 61 62 | LINK_POINTER_QUEUE_HEAD_FLAG; 63 } else { 64 instance->next = 0 | LINK_POINTER_TERMINATE_FLAG; 62 65 } 63 66 } 64 65 static inline void q ueue_head_element_qh(queue_head_t *instance, uint32_t pa)67 /*----------------------------------------------------------------------------*/ 68 static inline void qh_set_element_qh(qh_t *instance, uint32_t pa) 66 69 { 67 if (pa) { 68 instance->next_queue = (pa & LINK_POINTER_ADDRESS_MASK) 70 /* address is valid and not terminal */ 71 if (pa && ((pa & LINK_POINTER_TERMINATE_FLAG) == 0)) { 72 instance->element = (pa & LINK_POINTER_ADDRESS_MASK) 69 73 | LINK_POINTER_QUEUE_HEAD_FLAG; 74 } else { 75 instance->element = 0 | LINK_POINTER_TERMINATE_FLAG; 70 76 } 71 77 } 72 73 static inline void q ueue_head_set_element_td(queue_head_t *instance, uint32_t pa)78 /*----------------------------------------------------------------------------*/ 79 static inline void qh_set_element_td(qh_t *instance, uint32_t pa) 74 80 { 75 if (pa ) {81 if (pa && ((pa & LINK_POINTER_TERMINATE_FLAG) == 0)) { 76 82 instance->element = (pa & LINK_POINTER_ADDRESS_MASK); 83 } else { 84 instance->element = 0 | LINK_POINTER_TERMINATE_FLAG; 77 85 } 78 86 } -
uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.h
reb0dc58 r6143ce3 49 49 #define TD_STATUS_ERROR_COUNT_POS ( 27 ) 50 50 #define TD_STATUS_ERROR_COUNT_MASK ( 0x3 ) 51 #define TD_STATUS_ERROR_COUNT_DEFAULT 352 51 #define TD_STATUS_LOW_SPEED_FLAG ( 1 << 26 ) 53 52 #define TD_STATUS_ISOCHRONOUS_FLAG ( 1 << 25 )
Note:
See TracChangeset
for help on using the changeset viewer.