Changeset 3f189c5 in mainline
- Timestamp:
- 2011-02-07T14:06:57Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- fe10e72
- Parents:
- 7e62b62
- Location:
- uspace/drv/uhci-hcd
- Files:
-
- 2 deleted
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/uhci-hcd/Makefile
r7e62b62 r3f189c5 33 33 34 34 SOURCES = \ 35 callback.c \36 35 iface.c \ 37 36 main.c \ -
uspace/drv/uhci-hcd/transfer_list.c
r7e62b62 r3f189c5 41 41 { 42 42 assert(instance); 43 instance->first = NULL;44 instance->last = NULL;45 43 instance->next = NULL; 46 44 instance->name = name; … … 64 62 return; 65 63 queue_head_add_next(instance->queue_head, next->queue_head_pa); 66 }67 /*----------------------------------------------------------------------------*/68 int transfer_list_append(69 transfer_list_t *instance, transfer_descriptor_t *transfer)70 {71 assert(instance);72 assert(transfer);73 74 uint32_t pa = (uintptr_t)addr_to_phys(transfer);75 assert((pa & LINK_POINTER_ADDRESS_MASK) == pa);76 77 /* empty list */78 if (instance->first == NULL) {79 assert(instance->last == NULL);80 instance->first = instance->last = transfer;81 } else {82 assert(instance->last);83 instance->last->next_va = transfer;84 85 assert(instance->last->next & LINK_POINTER_TERMINATE_FLAG);86 instance->last->next = (pa & LINK_POINTER_ADDRESS_MASK);87 instance->last = transfer;88 }89 90 assert(instance->queue_head);91 if (instance->queue_head->element & LINK_POINTER_TERMINATE_FLAG) {92 instance->queue_head->element = (pa & LINK_POINTER_ADDRESS_MASK);93 }94 usb_log_debug("Successfully added transfer to the hc queue %s.\n",95 instance->name);96 return EOK;97 64 } 98 65 /*----------------------------------------------------------------------------*/ -
uspace/drv/uhci-hcd/transfer_list.h
r7e62b62 r3f189c5 36 36 37 37 #include "uhci_struct/queue_head.h" 38 #include "uhci_struct/transfer_descriptor.h"39 38 #include "tracker.h" 40 39 41 40 typedef struct transfer_list 42 41 { 43 transfer_descriptor_t *first;44 transfer_descriptor_t *last;45 46 42 tracker_t *last_tracker; 47 43 … … 62 58 } 63 59 64 int transfer_list_append(65 transfer_list_t *instance, transfer_descriptor_t *transfer);66 60 67 61 void transfer_list_add_tracker(transfer_list_t *instance, tracker_t *tracker); -
uspace/drv/uhci-hcd/uhci.c
r7e62b62 r3f189c5 96 96 fibril_add_ready(instance->debug_checker); 97 97 98 /* Start the hc with large(64 b) packet FSBR */98 /* Start the hc with large(64B) packet FSBR */ 99 99 pio_write_16(&instance->registers->usbcmd, 100 100 UHCI_CMD_RUN_STOP | UHCI_CMD_MAX_PACKET); … … 146 146 instance->transfers[0][USB_TRANSFER_CONTROL] = 147 147 &instance->transfers_control_full; 148 149 return EOK;150 }151 /*----------------------------------------------------------------------------*/152 int uhci_transfer(153 uhci_t *instance,154 device_t *dev,155 usb_target_t target,156 usb_transfer_type_t transfer_type,157 bool toggle,158 usb_packet_id pid,159 bool low_speed,160 void *buffer, size_t size,161 usbhc_iface_transfer_out_callback_t callback_out,162 usbhc_iface_transfer_in_callback_t callback_in,163 void *arg)164 {165 if (!allowed_usb_packet(low_speed, transfer_type, size)) {166 usb_log_warning("Invalid USB packet specified %s SPEED %d %zu.\n",167 low_speed ? "LOW" : "FULL" , transfer_type, size);168 return ENOTSUP;169 }170 171 // TODO: Add support for isochronous transfers172 if (transfer_type == USB_TRANSFER_ISOCHRONOUS) {173 usb_log_warning("ISO transfer not supported.\n");174 return ENOTSUP;175 }176 177 transfer_list_t *list = instance->transfers[low_speed][transfer_type];178 assert(list);179 180 transfer_descriptor_t *td = NULL;181 callback_t *job = NULL;182 int ret = EOK;183 assert(dev);184 185 #define CHECK_RET_TRANS_FREE_JOB_TD(message) \186 if (ret != EOK) { \187 usb_log_error(message); \188 if (job) { \189 callback_dispose(job); \190 } \191 if (td) { free32(td); } \192 return ret; \193 } else (void) 0194 195 job = callback_get(dev, buffer, size, callback_in, callback_out, arg);196 ret = job ? EOK : ENOMEM;197 CHECK_RET_TRANS_FREE_JOB_TD("Failed to allocate callback structure.\n");198 199 td = transfer_descriptor_get(3, size, false, target, pid, job->new_buffer);200 ret = td ? EOK : ENOMEM;201 CHECK_RET_TRANS_FREE_JOB_TD("Failed to setup transfer descriptor.\n");202 203 td->callback = job;204 205 usb_log_debug("Appending a new transfer to queue %s.\n", list->name);206 207 ret = transfer_list_append(list, td);208 CHECK_RET_TRANS_FREE_JOB_TD("Failed to append transfer descriptor.\n");209 148 210 149 return EOK; … … 256 195 current = next; 257 196 } 258 /* iterate all transfer queues */259 transfer_list_t *current_list = &instance->transfers_interrupt;260 while (current_list) {261 /* Remove inactive transfers from the top of the queue262 * TODO: should I reach queue head or is this enough? */263 volatile transfer_descriptor_t * it =264 current_list->first;265 usb_log_debug("Running cleaning fibril on queue: %s (%s).\n",266 current_list->name, it ? "SOMETHING" : "EMPTY");267 268 if (it) {269 usb_log_debug("First in queue: %p (%x) PA:%x.\n",270 it, it->status, addr_to_phys((void*)it) );271 usb_log_debug("First to send: %x\n",272 (current_list->queue_head->element) );273 }274 275 while (current_list->first &&276 !(current_list->first->status & TD_STATUS_ERROR_ACTIVE)) {277 transfer_descriptor_t *transfer = current_list->first;278 usb_log_info("Inactive transfer calling callback with status %x.\n",279 transfer->status);280 current_list->first = transfer->next_va;281 transfer_descriptor_dispose(transfer);282 }283 if (!current_list->first)284 current_list->last = current_list->first;285 286 current_list = current_list->next;287 }288 197 async_usleep(UHCI_CLEANER_TIMEOUT); 289 198 } … … 352 261 return (!low_speed && size < 1024); 353 262 case USB_TRANSFER_INTERRUPT: 354 return size <= (low_speed ? 8 : 64);263 return size <= (low_speed ? 8 : 64); 355 264 case USB_TRANSFER_CONTROL: /* device specifies its own max size */ 356 265 return (size <= (low_speed ? 8 : 64)); -
uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.c
r7e62b62 r3f189c5 36 36 37 37 #include "transfer_descriptor.h" 38 #include "utils/malloc32.h" 38 39 39 40 void transfer_descriptor_init(transfer_descriptor_t *instance, … … 58 59 59 60 instance->buffer_ptr = 0; 60 61 instance->next_va = NULL;62 instance->callback = NULL;63 61 64 62 if (size) { … … 118 116 return EOK; 119 117 } 120 /*----------------------------------------------------------------------------*/121 void transfer_descriptor_fini(transfer_descriptor_t *instance)122 {123 assert(instance);124 callback_run(instance->callback,125 convert_outcome(instance->status),126 ((instance->status >> TD_STATUS_ACTLEN_POS) + 1) & TD_STATUS_ACTLEN_MASK127 );128 }129 118 /** 130 119 * @} -
uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.h
r7e62b62 r3f189c5 38 38 #include <usb/usb.h> 39 39 40 #include "utils/malloc32.h"41 #include "callback.h"42 40 #include "link_pointer.h" 43 41 … … 86 84 volatile uint32_t buffer_ptr; 87 85 88 /* there is 16 bytes of data available here 89 * those are used to store callback pointer 90 * and next pointer. Thus, there is some free space 91 * on 32bits systems. 86 /* there is 16 bytes of data available here, according to UHCI 87 * Design guide, according to linux kernel the hardware does not care 88 * we don't use it anyway 92 89 */ 93 struct transfer_descriptor *next_va;94 callback_t *callback;95 90 } __attribute__((packed)) transfer_descriptor_t; 96 91 … … 100 95 int pid, void *buffer); 101 96 102 static inline transfer_descriptor_t * transfer_descriptor_get(103 int error_count, size_t size, bool isochronous, usb_target_t target,104 int pid, void *buffer)105 {106 transfer_descriptor_t * instance =107 malloc32(sizeof(transfer_descriptor_t));108 109 if (instance)110 transfer_descriptor_init(111 instance, error_count, size, isochronous, target, pid, buffer);112 return instance;113 }114 115 void transfer_descriptor_fini(transfer_descriptor_t *instance);116 117 static inline void transfer_descriptor_dispose(transfer_descriptor_t *instance)118 {119 assert(instance);120 transfer_descriptor_fini(instance);121 free32(instance);122 }123 97 124 98 int transfer_descriptor_status(transfer_descriptor_t *instance); … … 130 104 return instance->status & TD_STATUS_ERROR_ACTIVE; 131 105 } 132 133 static inline void transfer_descriptor_append(134 transfer_descriptor_t *instance, transfer_descriptor_t *item)135 {136 assert(instance);137 instance->next_va = item;138 instance->next = (uintptr_t)addr_to_phys(item) & LINK_POINTER_ADDRESS_MASK;139 }140 106 #endif 141 107 /**
Note:
See TracChangeset
for help on using the changeset viewer.