Changes in / [79d2987:25971d2] in mainline
- Location:
- uspace
- Files:
-
- 2 added
- 2 deleted
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/usbinfo/main.c
r79d2987 r25971d2 81 81 { 82 82 int rc; 83 84 if (str_cmp(path, "uhci") == 0) {85 path = "/hw/pci0/00:01.2";86 }87 83 88 84 devman_handle_t handle; -
uspace/drv/uhci-hcd/Makefile
r79d2987 r25971d2 33 33 34 34 SOURCES = \ 35 callback.c \ 35 36 iface.c \ 36 37 main.c \ … … 39 40 uhci.c \ 40 41 uhci_struct/transfer_descriptor.c \ 41 pci.c \ 42 tracker.c 42 pci.c 43 43 44 44 include $(USPACE_PREFIX)/Makefile.common -
uspace/drv/uhci-hcd/iface.c
r79d2987 r25971d2 106 106 usbhc_iface_transfer_out_callback_t callback, void *arg) 107 107 { 108 size_t max_packet_size = 8; 109 dev_speed_t speed = FULL_SPEED; 110 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 return EOK; 108 assert(dev); 109 uhci_t *hc = dev_to_uhci(dev); 110 assert(hc); 111 return uhci_transfer(hc, dev, target, USB_TRANSFER_INTERRUPT, 0, USB_PID_OUT, 112 false, data, size, callback, NULL, arg); 117 113 } 118 114 /*----------------------------------------------------------------------------*/ … … 121 117 usbhc_iface_transfer_in_callback_t callback, void *arg) 122 118 { 123 size_t max_packet_size = 4; 124 dev_speed_t speed = FULL_SPEED; 125 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 return EOK; 132 } 133 /*----------------------------------------------------------------------------*/ 134 static int control_write(device_t *dev, usb_target_t target, 135 void *setup_data, size_t setup_size, void *data, size_t size, 136 usbhc_iface_transfer_out_callback_t callback, void *arg) 137 { 138 size_t max_packet_size = 8; 139 dev_speed_t speed = FULL_SPEED; 140 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); 146 return EOK; 147 } 148 /*----------------------------------------------------------------------------*/ 149 static int control_read(device_t *dev, usb_target_t target, 150 void *setup_data, size_t setup_size, void *data, size_t size, 151 usbhc_iface_transfer_in_callback_t callback, void *arg) 152 { 153 size_t max_packet_size = 8; 154 dev_speed_t speed = FULL_SPEED; 155 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); 161 return EOK; 119 assert(dev); 120 uhci_t *hc = dev_to_uhci(dev); 121 assert(hc); 122 return uhci_transfer(hc, dev, target, USB_TRANSFER_INTERRUPT, 0, USB_PID_IN, 123 false, data, size, NULL, callback, arg); 162 124 } 163 125 /*----------------------------------------------------------------------------*/ … … 166 128 usbhc_iface_transfer_out_callback_t callback, void *arg) 167 129 { 168 usb_log_warning("Using deprecated API control write setup.\n"); 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); 174 return EOK; 130 assert(dev); 131 uhci_t *hc = dev_to_uhci(dev); 132 assert(hc); 133 return uhci_transfer(hc, dev, target, USB_TRANSFER_CONTROL, 0, USB_PID_SETUP, 134 false, data, size, callback, NULL, arg); 175 135 } 176 136 /*----------------------------------------------------------------------------*/ … … 179 139 usbhc_iface_transfer_out_callback_t callback, void *arg) 180 140 { 181 tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL, 182 size, FULL_SPEED, data, size, NULL, callback, arg); 183 if (!tracker) 184 return ENOMEM; 185 tracker_control_write_data_old(tracker); 186 return EOK; 141 assert(dev); 142 uhci_t *hc = dev_to_uhci(dev); 143 assert(hc); 144 return uhci_transfer(hc, dev, target, USB_TRANSFER_CONTROL, 1, USB_PID_OUT, 145 false, data, size, callback, NULL, arg); 187 146 } 188 147 /*----------------------------------------------------------------------------*/ … … 190 149 usbhc_iface_transfer_in_callback_t callback, void *arg) 191 150 { 192 tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL, 193 0, FULL_SPEED, NULL, 0, callback, NULL, arg); 194 if (!tracker) 195 return ENOMEM; 196 tracker_control_write_status_old(tracker); 197 return EOK; 151 assert(dev); 152 uhci_t *hc = dev_to_uhci(dev); 153 assert(hc); 154 return uhci_transfer(hc, dev, target, USB_TRANSFER_CONTROL, 0, USB_PID_IN, 155 false, NULL, 0, NULL, callback, arg); 198 156 } 199 157 /*----------------------------------------------------------------------------*/ … … 202 160 usbhc_iface_transfer_out_callback_t callback, void *arg) 203 161 { 204 usb_log_warning("Using deprecated API control read setup.\n"); 205 tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL, 206 8, FULL_SPEED, data, size, NULL, callback, arg); 207 if (!tracker) 208 return ENOMEM; 209 tracker_control_setup_old(tracker); 210 return EOK; 162 assert(dev); 163 uhci_t *hc = dev_to_uhci(dev); 164 assert(hc); 165 return uhci_transfer(hc, dev, target, USB_TRANSFER_CONTROL, 0, USB_PID_SETUP, 166 false, data, size, callback, NULL, arg); 211 167 } 212 168 /*----------------------------------------------------------------------------*/ … … 215 171 usbhc_iface_transfer_in_callback_t callback, void *arg) 216 172 { 217 tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL, 218 size, FULL_SPEED, data, size, callback, NULL, arg); 219 if (!tracker) 220 return ENOMEM; 221 tracker_control_read_data_old(tracker); 222 return EOK; 173 assert(dev); 174 uhci_t *hc = dev_to_uhci(dev); 175 assert(hc); 176 return uhci_transfer(hc, dev, target, USB_TRANSFER_CONTROL, 1, USB_PID_IN, 177 false, data, size, NULL, callback, arg); 223 178 } 224 179 /*----------------------------------------------------------------------------*/ … … 226 181 usbhc_iface_transfer_out_callback_t callback, void *arg) 227 182 { 228 tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL,229 0, FULL_SPEED, NULL, 0, NULL, callback, arg);230 if (!tracker)231 return ENOMEM;232 tracker_control_read_status_old(tracker);233 return EOK; 234 } 235 /*----------------------------------------------------------------------------*/ 183 assert(dev); 184 uhci_t *hc = dev_to_uhci(dev); 185 assert(hc); 186 return uhci_transfer(hc, dev, target, USB_TRANSFER_CONTROL, 0, USB_PID_OUT, 187 false, NULL, 0, callback, NULL, arg); 188 } 189 190 236 191 usbhc_iface_t uhci_iface = { 237 192 .tell_address = get_address, … … 245 200 .interrupt_out = interrupt_out, 246 201 .interrupt_in = interrupt_in, 247 248 .control_read = control_read,249 .control_write = control_write,250 202 251 203 .control_write_setup = control_write_setup, -
uspace/drv/uhci-hcd/transfer_list.c
r79d2987 r25971d2 41 41 { 42 42 assert(instance); 43 instance->first = NULL; 44 instance->last = NULL; 43 45 instance->next = NULL; 44 46 instance->name = name; … … 64 66 } 65 67 /*----------------------------------------------------------------------------*/ 66 void transfer_list_add_tracker(transfer_list_t *instance, tracker_t *tracker) 68 int transfer_list_append( 69 transfer_list_t *instance, transfer_descriptor_t *transfer) 67 70 { 68 71 assert(instance); 69 assert(tra cker);72 assert(transfer); 70 73 71 uint32_t pa = (uintptr_t)addr_to_phys(tra cker->td);74 uint32_t pa = (uintptr_t)addr_to_phys(transfer); 72 75 assert((pa & LINK_POINTER_ADDRESS_MASK) == pa); 73 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; 74 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); 75 91 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); 78 /* there is nothing scheduled */ 79 instance->last_tracker = tracker; 80 instance->queue_head->element = pa; 81 usb_log_debug2("Added td(%X:%X) to queue %s first.\n", 82 tracker->td->status, tracker->td->device, instance->name); 83 return; 92 instance->queue_head->element = (pa & LINK_POINTER_ADDRESS_MASK); 84 93 } 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 } 94 usb_log_debug("Successfully added transfer to the hc queue %s.\n", 95 instance->name); 96 return EOK; 101 97 } 102 98 /** -
uspace/drv/uhci-hcd/transfer_list.h
r79d2987 r25971d2 36 36 37 37 #include "uhci_struct/queue_head.h" 38 #include " tracker.h"38 #include "uhci_struct/transfer_descriptor.h" 39 39 40 40 typedef struct transfer_list 41 41 { 42 tra cker_t *last_tracker;43 42 transfer_descriptor_t *first; 43 transfer_descriptor_t *last; 44 44 queue_head_t *queue_head; 45 45 uint32_t queue_head_pa; … … 58 58 } 59 59 60 61 void transfer_list_add_tracker(transfer_list_t *instance, tracker_t *tracker);60 int transfer_list_append( 61 transfer_list_t *instance, transfer_descriptor_t *transfer); 62 62 63 63 #endif -
uspace/drv/uhci-hcd/uhci.c
r79d2987 r25971d2 33 33 */ 34 34 #include <errno.h> 35 #include <adt/list.h>36 35 37 36 #include <usb/debug.h> … … 43 42 static int uhci_clean_finished(void *arg); 44 43 static int uhci_debug_checker(void *arg); 45 static bool allowed_usb_packet(46 bool low_speed, usb_transfer_type_t, size_t size);47 44 48 45 int uhci_init(uhci_t *instance, void *regs, size_t reg_size) … … 87 84 88 85 const uintptr_t pa = (uintptr_t)addr_to_phys(instance->frame_list); 86 89 87 pio_write_32(&instance->registers->flbaseadd, (uint32_t)pa); 90 91 list_initialize(&instance->tracker_list);92 fibril_mutex_initialize(&instance->tracker_list_mutex);93 88 94 89 instance->cleaner = fibril_create(uhci_clean_finished, instance); … … 98 93 fibril_add_ready(instance->debug_checker); 99 94 100 /* Start the hc with large(64 B) packet FSBR */95 /* Start the hc with large(64b) packet FSBR */ 101 96 pio_write_16(&instance->registers->usbcmd, 102 97 UHCI_CMD_RUN_STOP | UHCI_CMD_MAX_PACKET); … … 152 147 } 153 148 /*----------------------------------------------------------------------------*/ 154 int uhci_schedule(uhci_t *instance, tracker_t *tracker) 155 { 156 assert(instance); 157 assert(tracker); 158 const int low_speed = (tracker->speed == LOW_SPEED); 159 if (!allowed_usb_packet( 160 low_speed, tracker->transfer_type, tracker->packet_size)) { 161 usb_log_warning("Invalid USB packet specified %s SPEED %d %zu.\n", 162 low_speed ? "LOW" : "FULL" , tracker->transfer_type, 163 tracker->packet_size); 149 int uhci_transfer( 150 uhci_t *instance, 151 device_t *dev, 152 usb_target_t target, 153 usb_transfer_type_t transfer_type, 154 bool toggle, 155 usb_packet_id pid, 156 bool low_speed, 157 void *buffer, size_t size, 158 usbhc_iface_transfer_out_callback_t callback_out, 159 usbhc_iface_transfer_in_callback_t callback_in, 160 void *arg) 161 { 162 // TODO: Add support for isochronous transfers 163 if (transfer_type == USB_TRANSFER_ISOCHRONOUS) { 164 usb_log_warning("ISO transfer not supported.\n"); 164 165 return ENOTSUP; 165 166 } 166 /* TODO: check available bandwith here */ 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 174 transfer_list_t *list = 175 instance->transfers[low_speed][tracker->transfer_type]; 176 assert(list); 177 transfer_list_add_tracker(list, tracker); 178 list_append(&tracker->link, &instance->tracker_list); 179 180 usb_log_debug2("Scheduler(%d) releasing tracker list mutex.\n", 181 fibril_get_id()); 182 fibril_mutex_unlock(&instance->tracker_list_mutex); 183 usb_log_debug2("Scheduler(%d) released tracker list mutex.\n", 184 fibril_get_id()); 167 168 if (transfer_type == USB_TRANSFER_INTERRUPT 169 && size >= 64) { 170 usb_log_warning("Interrupt transfer too big %zu.\n", size); 171 return ENOTSUP; 172 } 173 174 if (size >= 1024) { 175 usb_log_warning("Transfer too big.\n"); 176 return ENOTSUP; 177 } 178 transfer_list_t *list = instance->transfers[low_speed][transfer_type]; 179 if (!list) { 180 usb_log_warning("UNSUPPORTED transfer %d-%d.\n", low_speed, transfer_type); 181 return ENOTSUP; 182 } 183 184 transfer_descriptor_t *td = NULL; 185 callback_t *job = NULL; 186 int ret = EOK; 187 assert(dev); 188 189 #define CHECK_RET_TRANS_FREE_JOB_TD(message) \ 190 if (ret != EOK) { \ 191 usb_log_error(message); \ 192 if (job) { \ 193 callback_dispose(job); \ 194 } \ 195 if (td) { free32(td); } \ 196 return ret; \ 197 } else (void) 0 198 199 job = callback_get(dev, buffer, size, callback_in, callback_out, arg); 200 ret = job ? EOK : ENOMEM; 201 CHECK_RET_TRANS_FREE_JOB_TD("Failed to allocate callback structure.\n"); 202 203 td = transfer_descriptor_get(3, size, false, target, pid, job->new_buffer); 204 ret = td ? EOK : ENOMEM; 205 CHECK_RET_TRANS_FREE_JOB_TD("Failed to setup transfer descriptor.\n"); 206 207 td->callback = job; 208 209 210 usb_log_debug("Appending a new transfer to queue %s.\n", list->name); 211 212 ret = transfer_list_append(list, td); 213 CHECK_RET_TRANS_FREE_JOB_TD("Failed to append transfer descriptor.\n"); 185 214 186 215 return EOK; 187 216 } 188 /*--------------------------------------------------------------------------- -*/217 /*---------------------------------------------------------------------------*/ 189 218 int uhci_clean_finished(void* arg) 190 219 { … … 194 223 195 224 while(1) { 196 LIST_INITIALIZE(done_trackers); 197 /* tracker iteration */ 198 199 usb_log_debug2("Cleaner(%d) acquiring tracker list mutex.\n", 200 fibril_get_id()); 201 fibril_mutex_lock(&instance->tracker_list_mutex); 202 usb_log_debug2("Cleaner(%d) acquired tracker list mutex.\n", 203 fibril_get_id()); 204 205 link_t *current = instance->tracker_list.next; 206 while (current != &instance->tracker_list) 207 { 208 209 link_t *next = current->next; 210 tracker_t *tracker = list_get_instance(current, tracker_t, link); 211 212 assert(current == &tracker->link); 213 assert(tracker); 214 assert(tracker->next_step); 215 assert(tracker->td); 216 217 if (!transfer_descriptor_is_active(tracker->td)) { 218 usb_log_info("Found inactive tracker with status: %x:%x.\n", 219 tracker->td->status, tracker->td->device); 220 list_remove(current); 221 list_append(current, &done_trackers); 225 usb_log_debug("Running cleaning fibril on: %p.\n", instance); 226 /* iterate all transfer queues */ 227 transfer_list_t *current_list = &instance->transfers_interrupt; 228 while (current_list) { 229 /* Remove inactive transfers from the top of the queue 230 * TODO: should I reach queue head or is this enough? */ 231 volatile transfer_descriptor_t * it = 232 current_list->first; 233 usb_log_debug("Running cleaning fibril on queue: %s (%s).\n", 234 current_list->name, it ? "SOMETHING" : "EMPTY"); 235 236 if (it) { 237 usb_log_debug("First in queue: %p (%x) PA:%x.\n", 238 it, it->status, addr_to_phys((void*)it) ); 239 usb_log_debug("First to send: %x\n", 240 (current_list->queue_head->element) ); 222 241 } 223 current = next; 224 } 225 226 usb_log_debug2("Cleaner(%d) releasing tracker list mutex.\n", 227 fibril_get_id()); 228 fibril_mutex_unlock(&instance->tracker_list_mutex); 229 usb_log_debug2("Cleaner(%d) released tracker list mutex.\n", 230 fibril_get_id()); 231 232 while (!list_empty(&done_trackers)) { 233 tracker_t *tracker = list_get_instance( 234 done_trackers.next, tracker_t, link); 235 list_remove(&tracker->link); 236 tracker->next_step(tracker); 242 243 while (current_list->first && 244 !(current_list->first->status & TD_STATUS_ERROR_ACTIVE)) { 245 transfer_descriptor_t *transfer = current_list->first; 246 usb_log_info("Inactive transfer calling callback with status %x.\n", 247 transfer->status); 248 current_list->first = transfer->next_va; 249 transfer_descriptor_dispose(transfer); 250 } 251 if (!current_list->first) 252 current_list->last = current_list->first; 253 254 current_list = current_list->next; 237 255 } 238 256 async_usleep(UHCI_CLEANER_TIMEOUT); … … 293 311 return 0; 294 312 } 295 /*----------------------------------------------------------------------------*/296 bool allowed_usb_packet(297 bool low_speed, usb_transfer_type_t transfer, size_t size)298 {299 /* see USB specification chapter 5.5-5.8 for magic numbers used here */300 switch(transfer) {301 case USB_TRANSFER_ISOCHRONOUS:302 return (!low_speed && size < 1024);303 case USB_TRANSFER_INTERRUPT:304 return size <= (low_speed ? 8 : 64);305 case USB_TRANSFER_CONTROL: /* device specifies its own max size */306 return (size <= (low_speed ? 8 : 64));307 case USB_TRANSFER_BULK: /* device specifies its own max size */308 return (!low_speed && size <= 64);309 }310 return false;311 }312 313 /** 313 314 * @} -
uspace/drv/uhci-hcd/uhci.h
r79d2987 r25971d2 37 37 38 38 #include <fibril.h> 39 #include <fibril_synch.h>40 #include <adt/list.h>41 39 42 40 #include <usb/addrkeep.h> … … 44 42 45 43 #include "transfer_list.h" 46 #include "tracker.h"47 44 48 45 typedef struct uhci_regs { … … 71 68 } regs_t; 72 69 70 #define TRANSFER_QUEUES 4 73 71 #define UHCI_FRAME_LIST_COUNT 1024 74 72 #define UHCI_CLEANER_TIMEOUT 10000 75 #define UHCI_DEBUGER_TIMEOUT 500000 073 #define UHCI_DEBUGER_TIMEOUT 500000 76 74 77 75 typedef struct uhci { … … 80 78 81 79 link_pointer_t *frame_list; 82 83 link_t tracker_list;84 fibril_mutex_t tracker_list_mutex;85 80 86 81 transfer_list_t transfers_bulk_full; … … 113 108 void *arg ); 114 109 115 int uhci_schedule(uhci_t *instance, tracker_t *tracker);116 117 110 static inline uhci_t * dev_to_uhci(device_t *dev) 118 111 { return (uhci_t*)dev->driver_data; } -
uspace/drv/uhci-hcd/uhci_struct/queue_head.h
r79d2987 r25971d2 43 43 44 44 typedef struct queue_head { 45 volatilelink_pointer_t next_queue;46 volatilelink_pointer_t element;45 link_pointer_t next_queue; 46 link_pointer_t element; 47 47 } __attribute__((packed)) queue_head_t; 48 48 -
uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.c
r79d2987 r25971d2 32 32 * @brief UHCI driver 33 33 */ 34 #include <errno.h>35 34 #include <usb/debug.h> 36 35 37 36 #include "transfer_descriptor.h" 38 #include "utils/malloc32.h"39 37 40 38 void transfer_descriptor_init(transfer_descriptor_t *instance, 41 int error_count, size_t size, bool toggle, bool isochronous,42 usb_target_t target,int pid, void *buffer)39 int error_count, size_t size, bool isochronous, usb_target_t target, 40 int pid, void *buffer) 43 41 { 44 42 assert(instance); 45 43 46 instance->next = 0 | LINK_POINTER_TERMINATE_FLAG; 44 instance->next = 45 0 | LINK_POINTER_TERMINATE_FLAG; 47 46 47 48 assert(size < 1024); 48 49 instance->status = 0 49 50 | ((error_count & TD_STATUS_ERROR_COUNT_MASK) << TD_STATUS_ERROR_COUNT_POS) 50 51 | TD_STATUS_ERROR_ACTIVE; 51 52 52 assert(size < 1024);53 53 instance->device = 0 54 54 | (((size - 1) & TD_DEVICE_MAXLEN_MASK) << TD_DEVICE_MAXLEN_POS) 55 | (toggle ? TD_DEVICE_DATA_TOGGLE_ONE_FLAG : 0)56 55 | ((target.address & TD_DEVICE_ADDRESS_MASK) << TD_DEVICE_ADDRESS_POS) 57 56 | ((target.endpoint & TD_DEVICE_ENDPOINT_MASK) << TD_DEVICE_ENDPOINT_POS) … … 59 58 60 59 instance->buffer_ptr = 0; 60 61 instance->next_va = NULL; 62 instance->callback = NULL; 61 63 62 64 if (size) { … … 104 106 return USB_OUTCOME_CRCERROR; 105 107 106 //assert((((status >> TD_STATUS_ERROR_POS) & TD_STATUS_ERROR_MASK)107 //| TD_STATUS_ERROR_RESERVED) == TD_STATUS_ERROR_RESERVED);108 assert((((status >> TD_STATUS_ERROR_POS) & TD_STATUS_ERROR_MASK) 109 | TD_STATUS_ERROR_RESERVED) == TD_STATUS_ERROR_RESERVED); 108 110 return USB_OUTCOME_OK; 109 111 } 110 /*----------------------------------------------------------------------------*/ 111 int transfer_descriptor_status(transfer_descriptor_t *instance)112 113 void transfer_descriptor_fini(transfer_descriptor_t *instance) 112 114 { 113 115 assert(instance); 114 if (convert_outcome(instance->status)) 115 return EINVAL; //TODO: use sane error value here 116 return EOK; 116 callback_run(instance->callback, 117 convert_outcome(instance->status), 118 ((instance->status >> TD_STATUS_ACTLEN_POS) + 1) & TD_STATUS_ACTLEN_MASK 119 ); 117 120 } 118 121 /** -
uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.h
r79d2987 r25971d2 38 38 #include <usb/usb.h> 39 39 40 #include "utils/malloc32.h" 41 #include "callback.h" 40 42 #include "link_pointer.h" 41 43 … … 84 86 volatile uint32_t buffer_ptr; 85 87 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 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. 89 92 */ 93 struct transfer_descriptor *next_va; 94 callback_t *callback; 90 95 } __attribute__((packed)) transfer_descriptor_t; 91 96 92 97 93 98 void transfer_descriptor_init(transfer_descriptor_t *instance, 94 int error_count, size_t size, bool toggle, bool isochronous,95 usb_target_t target,int pid, void *buffer);99 int error_count, size_t size, bool isochronous, usb_target_t target, 100 int pid, void *buffer); 96 101 97 int transfer_descriptor_status(transfer_descriptor_t *instance); 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)); 98 108 99 static inline bool transfer_descriptor_is_active( 100 transfer_descriptor_t *instance) 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) 101 118 { 102 119 assert(instance); 103 return (instance->status & TD_STATUS_ERROR_ACTIVE) != 0; 120 transfer_descriptor_fini(instance); 121 free32(instance); 122 } 123 124 static inline void transfer_descriptor_append( 125 transfer_descriptor_t *instance, transfer_descriptor_t *item) 126 { 127 assert(instance); 128 instance->next_va = item; 129 instance->next = (uintptr_t)addr_to_phys( item ) & LINK_POINTER_ADDRESS_MASK; 104 130 } 105 131 #endif -
uspace/drv/uhci-rhd/main.c
r79d2987 r25971d2 102 102 int main(int argc, char *argv[]) 103 103 { 104 usb_log_enable(USB_LOG_LEVEL_ ERROR, NAME);104 usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME); 105 105 return driver_main(&uhci_rh_driver); 106 106 } -
uspace/drv/usbhid/hid.h
r79d2987 r25971d2 69 69 device_t *device; 70 70 usb_hid_configuration_t *conf; 71 usb_address_t address; 71 72 usb_hid_report_parser_t *parser; 72 73 73 74 usb_device_connection_t wire; 74 usb_endpoint_pipe_t ctrl_pipe;75 75 usb_endpoint_pipe_t poll_pipe; 76 76 } usb_hid_dev_kbd_t; -
uspace/drv/usbhid/main.c
r79d2987 r25971d2 47 47 #include <usb/classes/hid.h> 48 48 #include <usb/classes/hidparser.h> 49 #include <usb/ request.h>49 #include <usb/devreq.h> 50 50 #include <usb/descriptor.h> 51 51 #include <io/console.h> … … 262 262 } 263 263 264 # if 0 264 265 /* 265 266 * Kbd functions … … 280 281 281 282 // get the descriptor from the device 282 int rc = usb_request_get_descriptor(&kbd_dev->ctrl_pipe, 283 USB_REQUEST_TYPE_CLASS, USB_DESCTYPE_HID_REPORT, 284 i, 0, 285 kbd_dev->conf->interfaces[i].report_desc, length, 283 int rc = usb_drv_req_get_descriptor(kbd_dev->device->parent_phone, 284 kbd_dev->address, USB_REQUEST_TYPE_CLASS, USB_DESCTYPE_HID_REPORT, 285 0, i, kbd_dev->conf->interfaces[i].report_desc, length, 286 286 &actual_size); 287 287 … … 303 303 usb_standard_configuration_descriptor_t config_desc; 304 304 305 int rc; 306 rc = usb_request_get_bare_configuration_descriptor(&kbd_dev->ctrl_pipe, 307 0, &config_desc); 305 int rc = usb_drv_req_get_bare_configuration_descriptor( 306 kbd_dev->device->parent_phone, kbd_dev->address, 0, &config_desc); 308 307 309 308 if (rc != EOK) { … … 319 318 size_t transferred = 0; 320 319 // get full configuration descriptor 321 rc = usb_ request_get_full_configuration_descriptor(&kbd_dev->ctrl_pipe,322 0, descriptors,320 rc = usb_drv_req_get_full_configuration_descriptor( 321 kbd_dev->device->parent_phone, kbd_dev->address, 0, descriptors, 323 322 config_desc.total_length, &transferred); 324 323 … … 364 363 return EOK; 365 364 } 366 365 #endif 367 366 static usb_hid_dev_kbd_t *usbkbd_init_device(device_t *dev) 368 367 { 369 int rc;370 371 368 usb_hid_dev_kbd_t *kbd_dev = (usb_hid_dev_kbd_t *)calloc(1, 372 369 sizeof(usb_hid_dev_kbd_t)); … … 379 376 kbd_dev->device = dev; 380 377 378 // get phone to my HC and save it as my parent's phone 379 // TODO: maybe not a good idea if DDF will use parent_phone 380 int rc = kbd_dev->device->parent_phone = usb_drv_hc_connect_auto(dev, 0); 381 if (rc < 0) { 382 printf("Problem setting phone to HC.\n"); 383 goto error_leave; 384 } 385 386 rc = kbd_dev->address = usb_drv_get_my_address(dev->parent_phone, dev); 387 if (rc < 0) { 388 printf("Problem getting address of the device.\n"); 389 goto error_leave; 390 } 391 392 // doesn't matter now that we have no address 393 // if (kbd_dev->address < 0) { 394 // fprintf(stderr, NAME ": No device address!\n"); 395 // free(kbd_dev); 396 // return NULL; 397 // } 398 399 /* 400 * will need all descriptors: 401 * 1) choose one configuration from configuration descriptors 402 * (set it to the device) 403 * 2) set endpoints from endpoint descriptors 404 */ 405 406 407 // TODO: get descriptors, parse descriptors and save endpoints 408 //usbkbd_process_descriptors(kbd_dev); 409 usb_drv_req_set_configuration( 410 kbd_dev->device->parent_phone, kbd_dev->address, 1); 411 412 413 381 414 /* 382 415 * Initialize the backing connection to the host controller. … … 392 425 * Initialize device pipes. 393 426 */ 394 rc = usb_endpoint_pipe_initialize_default_control(&kbd_dev->ctrl_pipe,395 &kbd_dev->wire);396 if (rc != EOK) {397 printf("Failed to initialize default control pipe: %s.\n",398 str_error(rc));399 goto error_leave;400 }401 402 427 rc = usb_endpoint_pipe_initialize(&kbd_dev->poll_pipe, &kbd_dev->wire, 403 428 GUESSED_POLL_ENDPOINT, USB_TRANSFER_INTERRUPT, 8, USB_DIRECTION_IN); … … 408 433 } 409 434 410 /*411 * will need all descriptors:412 * 1) choose one configuration from configuration descriptors413 * (set it to the device)414 * 2) set endpoints from endpoint descriptors415 */416 417 // TODO: get descriptors, parse descriptors and save endpoints418 usb_endpoint_pipe_start_session(&kbd_dev->ctrl_pipe);419 //usb_request_set_configuration(&kbd_dev->ctrl_pipe, 1);420 usbkbd_process_descriptors(kbd_dev);421 usb_endpoint_pipe_end_session(&kbd_dev->ctrl_pipe);422 435 423 436 return kbd_dev; -
uspace/lib/c/generic/async.c
r79d2987 r25971d2 1567 1567 } 1568 1568 1569 /** Start IPC_M_DATA_READ using the async framework.1570 *1571 * @param phoneid Phone that will be used to contact the receiving side.1572 * @param dst Address of the beginning of the destination buffer.1573 * @param size Size of the destination buffer (in bytes).1574 * @param dataptr Storage of call data (arg 2 holds actual data size).1575 * @return Hash of the sent message or 0 on error.1576 */1577 aid_t async_data_read(int phoneid, void *dst, size_t size, ipc_call_t *dataptr)1578 {1579 return async_send_2(phoneid, IPC_M_DATA_READ, (sysarg_t) dst,1580 (sysarg_t) size, dataptr);1581 }1582 1583 1569 /** Wrapper for IPC_M_DATA_READ calls using the async framework. 1584 1570 * -
uspace/lib/c/include/async.h
r79d2987 r25971d2 340 340 (arg4), (answer)) 341 341 342 extern aid_t async_data_read(int, void *, size_t, ipc_call_t *);343 342 extern int async_data_read_start(int, void *, size_t); 344 343 extern bool async_data_read_receive(ipc_callid_t *, size_t *); -
uspace/lib/drv/generic/remote_usbhc.c
r79d2987 r25971d2 42 42 43 43 static void remote_usbhc_get_address(device_t *, void *, ipc_callid_t, ipc_call_t *); 44 static void remote_usbhc_get_buffer(device_t *, void *, ipc_callid_t, ipc_call_t *); 44 45 static void remote_usbhc_interrupt_out(device_t *, void *, ipc_callid_t, ipc_call_t *); 45 46 static void remote_usbhc_interrupt_in(device_t *, void *, ipc_callid_t, ipc_call_t *); … … 63 64 remote_usbhc_get_address, 64 65 66 remote_usbhc_get_buffer, 67 65 68 remote_usbhc_reserve_default_address, 66 69 remote_usbhc_release_default_address, … … 95 98 typedef struct { 96 99 ipc_callid_t caller; 97 ipc_callid_t data_caller;98 100 void *buffer; 99 101 void *setup_packet; … … 125 127 126 128 trans->caller = caller; 127 trans->data_caller = 0;128 129 trans->buffer = NULL; 129 130 trans->setup_packet = NULL; … … 154 155 } 155 156 157 void remote_usbhc_get_buffer(device_t *device, void *iface, 158 ipc_callid_t callid, ipc_call_t *call) 159 { 160 sysarg_t buffer_hash = DEV_IPC_GET_ARG1(*call); 161 async_transaction_t * trans = (async_transaction_t *)buffer_hash; 162 if (trans == NULL) { 163 async_answer_0(callid, ENOENT); 164 return; 165 } 166 if (trans->buffer == NULL) { 167 async_answer_0(callid, EINVAL); 168 async_transaction_destroy(trans); 169 return; 170 } 171 172 ipc_callid_t cid; 173 size_t accepted_size; 174 if (!async_data_read_receive(&cid, &accepted_size)) { 175 async_answer_0(callid, EINVAL); 176 async_transaction_destroy(trans); 177 return; 178 } 179 180 if (accepted_size > trans->size) { 181 accepted_size = trans->size; 182 } 183 async_data_read_finalize(cid, trans->buffer, accepted_size); 184 185 async_answer_1(callid, EOK, accepted_size); 186 187 async_transaction_destroy(trans); 188 } 189 156 190 void remote_usbhc_reserve_default_address(device_t *device, void *iface, 157 191 ipc_callid_t callid, ipc_call_t *call) … … 256 290 if (outcome != USB_OUTCOME_OK) { 257 291 async_answer_0(trans->caller, outcome); 258 if (trans->data_caller) {259 async_answer_0(trans->data_caller, EINTR);260 }261 292 async_transaction_destroy(trans); 262 293 return; … … 264 295 265 296 trans->size = actual_size; 266 267 if (trans->data_caller) { 268 async_data_read_finalize(trans->data_caller, 269 trans->buffer, actual_size); 270 } 271 272 async_answer_0(trans->caller, USB_OUTCOME_OK); 273 274 async_transaction_destroy(trans); 297 async_answer_1(trans->caller, USB_OUTCOME_OK, (sysarg_t)trans); 275 298 } 276 299 … … 353 376 }; 354 377 355 ipc_callid_t data_callid;356 if (!async_data_read_receive(&data_callid, &len)) {357 async_answer_0(callid, EPARTY);358 return;359 }360 361 378 async_transaction_t *trans = async_transaction_create(callid); 362 379 if (trans == NULL) { … … 364 381 return; 365 382 } 366 trans->data_caller = data_callid;367 383 trans->buffer = malloc(len); 368 384 trans->size = len; … … 614 630 } 615 631 616 ipc_callid_t data_callid;617 if (!async_data_read_receive(&data_callid, &data_len)) {618 async_answer_0(callid, EPARTY);619 free(setup_packet);620 return;621 }622 623 632 async_transaction_t *trans = async_transaction_create(callid); 624 633 if (trans == NULL) { … … 627 636 return; 628 637 } 629 trans->data_caller = data_callid;630 638 trans->setup_packet = setup_packet; 631 639 trans->size = data_len; -
uspace/lib/drv/include/usbhc_iface.h
r79d2987 r25971d2 66 66 * - argument #2 is target endpoint 67 67 * - argument #3 is buffer size 68 * - this call is immediately followed by IPC data read (async version)69 68 * - the call is not answered until the device returns some data (or until 70 69 * error occurs) 70 * - if the call is answered with EOK, first argument of the answer is buffer 71 * hash that could be used to retrieve the actual data 71 72 * 72 73 * Some special methods (NO-DATA transactions) do not send any data. These 73 74 * might behave as both OUT or IN transactions because communication parts 74 75 * where actual buffers are exchanged are omitted. 75 ** 76 * 77 * The mentioned data retrieval can be done any time after receiving EOK 78 * answer to IN method. 79 * This retrieval is done using the IPC_M_USBHC_GET_BUFFER where 80 * the first argument is buffer hash from call answer. 81 * This call must be immediately followed by data read-in and after the 82 * data are transferred, the initial call (IPC_M_USBHC_GET_BUFFER) 83 * is answered. Each buffer can be retrieved only once. 84 * 76 85 * For all these methods, wrap functions exists. Important rule: functions 77 86 * for IN transactions have (as parameters) buffers where retrieved data … … 95 104 IPC_M_USBHC_GET_ADDRESS, 96 105 106 /** Asks for data buffer. 107 * See explanation at usb_iface_funcs_t. 108 * This function does not have counter part in functional interface 109 * as it is handled by the remote part itself. 110 */ 111 IPC_M_USBHC_GET_BUFFER, 112 97 113 98 114 /** Reserve usage of default address. -
uspace/lib/usb/src/usbdrv.c
r79d2987 r25971d2 49 49 /** Storage for actual number of bytes transferred. */ 50 50 size_t *size_transferred; 51 /** Initial call repl y data. */51 /** Initial call replay data. */ 52 52 ipc_call_t reply; 53 53 /** Initial call identifier. */ 54 54 aid_t request; 55 /** Reply data for data read call. */56 ipc_call_t read_reply;57 /** Data read call identifier. */58 aid_t read_request;59 55 } transfer_info_t; 60 56 … … 144 140 145 141 if (rc != EOK) { 142 printf("usb_drv_get_my_address over %d failed: %s\n", phone, str_error(rc)); 146 143 return rc; 147 144 } … … 253 250 } 254 251 255 transfer->read_request = 0;256 252 transfer->size_transferred = NULL; 257 253 transfer->buffer = NULL; … … 319 315 } 320 316 321 transfer->read_request = 0;322 317 transfer->size_transferred = actual_size; 323 318 transfer->buffer = buffer; … … 332 327 &transfer->reply); 333 328 334 if (buffer != NULL) {335 transfer->read_request = async_data_read(phone, buffer, size,336 &transfer->read_reply);337 }338 339 329 *handle = (usb_handle_t) transfer; 340 330 … … 342 332 } 343 333 334 /** Read buffer from HCD. 335 * 336 * @param phone Opened phone to HCD. 337 * @param hash Buffer hash (obtained after completing IN transaction). 338 * @param buffer Buffer where to store data data. 339 * @param size Buffer size. 340 * @param actual_size Storage where actual number of bytes transferred will 341 * be stored. 342 * @return Error status. 343 */ 344 static int read_buffer_in(int phone, sysarg_t hash, 345 void *buffer, size_t size, size_t *actual_size) 346 { 347 ipc_call_t answer_data; 348 sysarg_t answer_rc; 349 aid_t req; 350 int rc; 351 352 req = async_send_2(phone, 353 DEV_IFACE_ID(USBHC_DEV_IFACE), 354 IPC_M_USBHC_GET_BUFFER, 355 hash, 356 &answer_data); 357 358 rc = async_data_read_start(phone, buffer, size); 359 if (rc != EOK) { 360 async_wait_for(req, NULL); 361 return EINVAL; 362 } 363 364 async_wait_for(req, &answer_rc); 365 rc = (int)answer_rc; 366 367 if (rc != EOK) { 368 return rc; 369 } 370 371 *actual_size = IPC_GET_ARG1(answer_data); 372 373 return EOK; 374 } 344 375 345 376 /** Blocks caller until given USB transaction is finished. … … 364 395 365 396 sysarg_t answer_rc; 397 async_wait_for(transfer->request, &answer_rc); 398 399 if (answer_rc != EOK) { 400 rc = (int) answer_rc; 401 goto leave; 402 } 366 403 367 404 /* … … 369 406 */ 370 407 if ((transfer->buffer != NULL) && (transfer->size > 0)) { 371 async_wait_for(transfer->read_request, &answer_rc); 372 373 if (answer_rc != EOK) { 374 rc = (int) answer_rc; 408 /* 409 * The buffer hash identifies the data on the server 410 * side. 411 * We will use it when actually reading-in the data. 412 */ 413 sysarg_t buffer_hash = IPC_GET_ARG1(transfer->reply); 414 if (buffer_hash == 0) { 415 rc = ENOENT; 375 416 goto leave; 376 417 } 377 418 378 if (transfer->size_transferred != NULL) { 379 *(transfer->size_transferred) 380 = IPC_GET_ARG2(transfer->read_reply); 419 size_t actual_size; 420 rc = read_buffer_in(transfer->phone, buffer_hash, 421 transfer->buffer, transfer->size, &actual_size); 422 423 if (rc != EOK) { 424 goto leave; 381 425 } 382 } 383 384 async_wait_for(transfer->request, &answer_rc); 385 386 if (answer_rc != EOK) { 387 rc = (int) answer_rc; 388 goto leave; 426 427 if (transfer->size_transferred) { 428 *(transfer->size_transferred) = actual_size; 429 } 389 430 } 390 431 … … 474 515 } 475 516 476 transfer->read_request = 0;477 517 transfer->size_transferred = NULL; 478 518 transfer->buffer = NULL; … … 580 620 } 581 621 582 transfer->read_request = async_data_read(phone, buffer, buffer_size,583 &transfer->read_reply);584 585 622 *handle = (usb_handle_t) transfer; 586 623
Note:
See TracChangeset
for help on using the changeset viewer.