Changeset b01995b in mainline for uspace/drv/uhci-hcd
- Timestamp:
- 2011-03-21T23:42:08Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 11dd29b, 62f4212
- Parents:
- 31b568e (diff), 87644b4 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - Location:
- uspace/drv/uhci-hcd
- Files:
-
- 10 edited
- 8 moved
-
Makefile (modified) (1 diff)
-
batch.c (modified) (1 diff)
-
batch.h (modified) (1 diff)
-
hc.c (moved) (moved from uspace/drv/uhci-hcd/uhci_hc.c ) (16 diffs)
-
hc.h (moved) (moved from uspace/drv/uhci-hcd/uhci_hc.h ) (4 diffs)
-
hw_struct/link_pointer.h (moved) (moved from uspace/drv/uhci-hcd/uhci_struct/link_pointer.h ) (1 diff)
-
hw_struct/queue_head.h (moved) (moved from uspace/drv/uhci-hcd/uhci_struct/queue_head.h ) (3 diffs)
-
hw_struct/transfer_descriptor.c (moved) (moved from uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.c ) (3 diffs)
-
hw_struct/transfer_descriptor.h (moved) (moved from uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.h )
-
iface.c (modified) (14 diffs)
-
iface.h (modified) (1 diff)
-
root_hub.c (moved) (moved from uspace/drv/uhci-hcd/uhci_rh.c ) (2 diffs)
-
root_hub.h (moved) (moved from uspace/drv/uhci-hcd/uhci_rh.h ) (1 diff)
-
transfer_list.c (modified) (4 diffs)
-
transfer_list.h (modified) (1 diff)
-
uhci.c (modified) (8 diffs)
-
uhci.h (modified) (2 diffs)
-
utils/malloc32.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/uhci-hcd/Makefile
r31b568e rb01995b 37 37 transfer_list.c \ 38 38 uhci.c \ 39 uhci_hc.c \40 uhci_rh.c \41 uhci_struct/transfer_descriptor.c \39 hc.c \ 40 root_hub.c \ 41 hw_struct/transfer_descriptor.c \ 42 42 pci.c \ 43 43 batch.c -
uspace/drv/uhci-hcd/batch.c
r31b568e rb01995b 40 40 #include "batch.h" 41 41 #include "transfer_list.h" 42 #include " uhci_hc.h"42 #include "hw_struct/transfer_descriptor.h" 43 43 #include "utils/malloc32.h" 44 #include "uhci_struct/transfer_descriptor.h"45 44 46 45 #define DEFAULT_ERROR_COUNT 3 -
uspace/drv/uhci-hcd/batch.h
r31b568e rb01995b 42 42 #include <usb/host/batch.h> 43 43 44 #include " uhci_struct/queue_head.h"44 #include "hw_struct/queue_head.h" 45 45 46 46 usb_transfer_batch_t * batch_get( -
uspace/drv/uhci-hcd/hc.c
r31b568e rb01995b 42 42 #include <usb_iface.h> 43 43 44 #include " uhci_hc.h"44 #include "hc.h" 45 45 46 46 static irq_cmd_t uhci_cmds[] = { … … 60 60 }; 61 61 /*----------------------------------------------------------------------------*/ 62 static int uhci_hc_init_transfer_lists(uhci_hc_t *instance);63 static int uhci_hc_init_mem_structures(uhci_hc_t *instance);64 static void uhci_hc_init_hw(uhci_hc_t *instance);65 66 static int uhci_hc_interrupt_emulator(void *arg);67 static int uhci_hc_debug_checker(void *arg);62 static int hc_init_transfer_lists(hc_t *instance); 63 static int hc_init_mem_structures(hc_t *instance); 64 static void hc_init_hw(hc_t *instance); 65 66 static int hc_interrupt_emulator(void *arg); 67 static int hc_debug_checker(void *arg); 68 68 69 69 static bool allowed_usb_packet( … … 82 82 * interrupt fibrils. 83 83 */ 84 int uhci_hc_init(uhci_hc_t *instance, ddf_fun_t *fun,84 int hc_init(hc_t *instance, ddf_fun_t *fun, 85 85 void *regs, size_t reg_size, bool interrupts) 86 86 { … … 112 112 io, reg_size); 113 113 114 ret = uhci_hc_init_mem_structures(instance);114 ret = hc_init_mem_structures(instance); 115 115 CHECK_RET_DEST_FUN_RETURN(ret, 116 116 "Failed to initialize UHCI memory structures.\n"); 117 117 118 uhci_hc_init_hw(instance);118 hc_init_hw(instance); 119 119 if (!interrupts) { 120 120 instance->cleaner = 121 fibril_create( uhci_hc_interrupt_emulator, instance);121 fibril_create(hc_interrupt_emulator, instance); 122 122 fibril_add_ready(instance->cleaner); 123 123 } else { … … 125 125 } 126 126 127 instance->debug_checker = fibril_create(uhci_hc_debug_checker, instance); 128 fibril_add_ready(instance->debug_checker); 127 instance->debug_checker = 128 fibril_create(hc_debug_checker, instance); 129 // fibril_add_ready(instance->debug_checker); 129 130 130 131 return EOK; … … 137 138 * For magic values see UHCI Design Guide 138 139 */ 139 void uhci_hc_init_hw(uhci_hc_t *instance)140 void hc_init_hw(hc_t *instance) 140 141 { 141 142 assert(instance); … … 185 186 * - frame list page (needs to be one UHCI hw accessible 4K page) 186 187 */ 187 int uhci_hc_init_mem_structures(uhci_hc_t *instance)188 int hc_init_mem_structures(hc_t *instance) 188 189 { 189 190 assert(instance); … … 214 215 215 216 /* Init transfer lists */ 216 ret = uhci_hc_init_transfer_lists(instance);217 ret = hc_init_transfer_lists(instance); 217 218 CHECK_RET_DEST_CMDS_RETURN(ret, "Failed to init transfer lists.\n"); 218 219 usb_log_debug("Initialized transfer lists.\n"); … … 235 236 236 237 /* Init device keeper*/ 237 usb_device_keeper_init(&instance-> device_manager);238 usb_device_keeper_init(&instance->manager); 238 239 usb_log_debug("Initialized device manager.\n"); 239 240 … … 251 252 * USB scheduling. Sets pointer table for quick access. 252 253 */ 253 int uhci_hc_init_transfer_lists(uhci_hc_t *instance)254 int hc_init_transfer_lists(hc_t *instance) 254 255 { 255 256 assert(instance); … … 317 318 * Checks for bandwidth availability and appends the batch to the proper queue. 318 319 */ 319 int uhci_hc_schedule(uhci_hc_t *instance, usb_transfer_batch_t *batch)320 int hc_schedule(hc_t *instance, usb_transfer_batch_t *batch) 320 321 { 321 322 assert(instance); … … 350 351 * - resume from suspend state (not implemented) 351 352 */ 352 void uhci_hc_interrupt(uhci_hc_t *instance, uint16_t status)353 void hc_interrupt(hc_t *instance, uint16_t status) 353 354 { 354 355 assert(instance); … … 372 373 if (instance->hw_failures < UHCI_ALLOWED_HW_FAIL) { 373 374 /* reinitialize hw, this triggers virtual disconnect*/ 374 uhci_hc_init_hw(instance);375 hc_init_hw(instance); 375 376 } else { 376 377 usb_log_fatal("Too many UHCI hardware failures!.\n"); 377 uhci_hc_fini(instance);378 hc_fini(instance); 378 379 } 379 380 } … … 385 386 * @return EOK (should never return) 386 387 */ 387 int uhci_hc_interrupt_emulator(void* arg)388 int hc_interrupt_emulator(void* arg) 388 389 { 389 390 usb_log_debug("Started interrupt emulator.\n"); 390 uhci_hc_t *instance = (uhci_hc_t*)arg;391 hc_t *instance = (hc_t*)arg; 391 392 assert(instance); 392 393 … … 397 398 if (status != 0) 398 399 usb_log_debug2("UHCI status: %x.\n", status); 399 uhci_hc_interrupt(instance, status);400 hc_interrupt(instance, status); 400 401 async_usleep(UHCI_CLEANER_TIMEOUT); 401 402 } … … 408 409 * @return EOK (should never return) 409 410 */ 410 int uhci_hc_debug_checker(void *arg)411 { 412 uhci_hc_t *instance = (uhci_hc_t*)arg;411 int hc_debug_checker(void *arg) 412 { 413 hc_t *instance = (hc_t*)arg; 413 414 assert(instance); 414 415 -
uspace/drv/uhci-hcd/hc.h
r31b568e rb01995b 82 82 #define UHCI_ALLOWED_HW_FAIL 5 83 83 84 typedef struct uhci_hc {85 usb_device_keeper_t device_manager;84 typedef struct hc { 85 usb_device_keeper_t manager; 86 86 87 87 regs_t *registers; … … 104 104 105 105 ddf_fun_t *ddf_instance; 106 } uhci_hc_t;106 } hc_t; 107 107 108 int uhci_hc_init(uhci_hc_t *instance, ddf_fun_t *fun,108 int hc_init(hc_t *instance, ddf_fun_t *fun, 109 109 void *regs, size_t reg_size, bool interupts); 110 110 111 int uhci_hc_schedule(uhci_hc_t *instance, usb_transfer_batch_t *batch);111 int hc_schedule(hc_t *instance, usb_transfer_batch_t *batch); 112 112 113 void uhci_hc_interrupt(uhci_hc_t *instance, uint16_t status);113 void hc_interrupt(hc_t *instance, uint16_t status); 114 114 115 115 /** Safely dispose host controller internal structures … … 117 117 * @param[in] instance Host controller structure to use. 118 118 */ 119 static inline void uhci_hc_fini(uhci_hc_t *instance) { /* TODO: implement*/ };119 static inline void hc_fini(hc_t *instance) { /* TODO: implement*/ }; 120 120 121 121 /** Get and cast pointer to the driver data … … 124 124 * @return cast pointer to driver_data 125 125 */ 126 static inline uhci_hc_t * fun_to_uhci_hc(ddf_fun_t *fun)127 { return ( uhci_hc_t*)fun->driver_data; }126 static inline hc_t * fun_to_hc(ddf_fun_t *fun) 127 { return (hc_t*)fun->driver_data; } 128 128 #endif 129 129 /** -
uspace/drv/uhci-hcd/hw_struct/link_pointer.h
r31b568e rb01995b 49 49 ((address & LINK_POINTER_ADDRESS_MASK) | LINK_POINTER_QUEUE_HEAD_FLAG) 50 50 51 #define LINK_POINTER_TD(address) \ 52 (address & LINK_POINTER_ADDRESS_MASK) 53 54 #define LINK_POINTER_TERM \ 55 ((link_pointer_t)LINK_POINTER_TERMINATE_FLAG) 56 51 57 #endif 52 58 /** -
uspace/drv/uhci-hcd/hw_struct/queue_head.h
r31b568e rb01995b 72 72 /* Address is valid and not terminal */ 73 73 if (pa && ((pa & LINK_POINTER_TERMINATE_FLAG) == 0)) { 74 instance->next = (pa & LINK_POINTER_ADDRESS_MASK) 75 | LINK_POINTER_QUEUE_HEAD_FLAG; 74 instance->next = LINK_POINTER_QH(pa); 76 75 } else { 77 instance->next = 0 | LINK_POINTER_TERMINATE_FLAG;76 instance->next = LINK_POINTER_TERM; 78 77 } 79 78 } … … 91 90 /* Address is valid and not terminal */ 92 91 if (pa && ((pa & LINK_POINTER_TERMINATE_FLAG) == 0)) { 93 instance->element = (pa & LINK_POINTER_ADDRESS_MASK) 94 | LINK_POINTER_QUEUE_HEAD_FLAG; 92 instance->element = LINK_POINTER_QH(pa); 95 93 } else { 96 instance->element = 0 | LINK_POINTER_TERMINATE_FLAG;94 instance->element = LINK_POINTER_TERM; 97 95 } 98 96 } … … 109 107 { 110 108 if (pa && ((pa & LINK_POINTER_TERMINATE_FLAG) == 0)) { 111 instance->element = (pa & LINK_POINTER_ADDRESS_MASK);109 instance->element = LINK_POINTER_TD(pa); 112 110 } else { 113 instance->element = 0 | LINK_POINTER_TERMINATE_FLAG;111 instance->element = LINK_POINTER_TERM; 114 112 } 115 113 } -
uspace/drv/uhci-hcd/hw_struct/transfer_descriptor.c
r31b568e rb01995b 69 69 || (pid == USB_PID_OUT)); 70 70 71 const uint32_t next_pa = addr_to_phys(next); 72 assert((next_pa & LINK_POINTER_ADDRESS_MASK) == next_pa); 73 71 74 instance->next = 0 72 75 | LINK_POINTER_VERTICAL_FLAG 73 | ( (next != NULL) ? addr_to_phys(next): LINK_POINTER_TERMINATE_FLAG);76 | (next_pa ? next_pa : LINK_POINTER_TERMINATE_FLAG); 74 77 75 78 instance->status = 0 … … 90 93 | ((pid & TD_DEVICE_PID_MASK) << TD_DEVICE_PID_POS); 91 94 92 instance->buffer_ptr = 0; 93 94 if (size) { 95 instance->buffer_ptr = (uintptr_t)addr_to_phys(buffer); 96 } 95 instance->buffer_ptr = addr_to_phys(buffer); 97 96 98 97 usb_log_debug2("Created TD(%p): %X:%X:%X:%X(%p).\n", … … 115 114 assert(instance); 116 115 117 if ((instance->status & TD_STATUS_ERROR_STALLED) != 0) 118 return ESTALL; 116 /* this is hc internal error it should never be reported */ 117 if ((instance->status & TD_STATUS_ERROR_BIT_STUFF) != 0) 118 return EAGAIN; 119 119 120 /* CRC or timeout error, like device not present or bad data, 121 * it won't be reported unless err count reached zero */ 120 122 if ((instance->status & TD_STATUS_ERROR_CRC) != 0) 121 123 return EBADCHECKSUM; 122 124 123 if ((instance->status & TD_STATUS_ERROR_BUFFER) != 0) 125 /* hc does not end transaction on these, it should never be reported */ 126 if ((instance->status & TD_STATUS_ERROR_NAK) != 0) 124 127 return EAGAIN; 125 128 129 /* buffer overrun or underrun */ 130 if ((instance->status & TD_STATUS_ERROR_BUFFER) != 0) 131 return ERANGE; 132 133 /* device babble is something serious */ 126 134 if ((instance->status & TD_STATUS_ERROR_BABBLE) != 0) 127 135 return EIO; 128 136 129 if ((instance->status & TD_STATUS_ERROR_NAK) != 0) 130 return EAGAIN; 131 132 if ((instance->status & TD_STATUS_ERROR_BIT_STUFF) != 0) 133 return EAGAIN; 137 /* stall might represent err count reaching zero or stall response from 138 * the device, is err count reached zero, one of the above is reported*/ 139 if ((instance->status & TD_STATUS_ERROR_STALLED) != 0) 140 return ESTALL; 134 141 135 142 return EOK; -
uspace/drv/uhci-hcd/iface.c
r31b568e rb01995b 33 33 */ 34 34 #include <ddf/driver.h> 35 #include < remote_usbhc.h>35 #include <errno.h> 36 36 37 37 #include <usb/debug.h> 38 38 39 #include <errno.h>40 41 39 #include "iface.h" 42 #include " uhci_hc.h"40 #include "hc.h" 43 41 44 42 /** Reserve default address interface function … … 48 46 * @return Error code. 49 47 */ 50 /*----------------------------------------------------------------------------*/51 48 static int reserve_default_address(ddf_fun_t *fun, usb_speed_t speed) 52 49 { 53 50 assert(fun); 54 uhci_hc_t *hc = fun_to_uhci_hc(fun);51 hc_t *hc = fun_to_hc(fun); 55 52 assert(hc); 56 53 usb_log_debug("Default address request with speed %d.\n", speed); 57 usb_device_keeper_reserve_default_address(&hc-> device_manager, speed);54 usb_device_keeper_reserve_default_address(&hc->manager, speed); 58 55 return EOK; 59 56 } … … 67 64 { 68 65 assert(fun); 69 uhci_hc_t *hc = fun_to_uhci_hc(fun);66 hc_t *hc = fun_to_hc(fun); 70 67 assert(hc); 71 68 usb_log_debug("Default address release.\n"); 72 usb_device_keeper_release_default_address(&hc-> device_manager);69 usb_device_keeper_release_default_address(&hc->manager); 73 70 return EOK; 74 71 } … … 81 78 * @return Error code. 82 79 */ 83 static int request_address( ddf_fun_t *fun, usb_speed_t speed,84 usb_address_t *address)85 { 86 assert(fun); 87 uhci_hc_t *hc = fun_to_uhci_hc(fun);80 static int request_address( 81 ddf_fun_t *fun, usb_speed_t speed, usb_address_t *address) 82 { 83 assert(fun); 84 hc_t *hc = fun_to_hc(fun); 88 85 assert(hc); 89 86 assert(address); 90 87 91 88 usb_log_debug("Address request with speed %d.\n", speed); 92 *address = device_keeper_get_free_address(&hc-> device_manager, speed);89 *address = device_keeper_get_free_address(&hc->manager, speed); 93 90 usb_log_debug("Address request with result: %d.\n", *address); 94 91 if (*address <= 0) 95 return *address;92 return *address; 96 93 return EOK; 97 94 } … … 108 105 { 109 106 assert(fun); 110 uhci_hc_t *hc = fun_to_uhci_hc(fun);107 hc_t *hc = fun_to_hc(fun); 111 108 assert(hc); 112 109 usb_log_debug("Address bind %d-%d.\n", address, handle); 113 usb_device_keeper_bind(&hc-> device_manager, address, handle);110 usb_device_keeper_bind(&hc->manager, address, handle); 114 111 return EOK; 115 112 } … … 124 121 { 125 122 assert(fun); 126 uhci_hc_t *hc = fun_to_uhci_hc(fun);123 hc_t *hc = fun_to_hc(fun); 127 124 assert(hc); 128 125 usb_log_debug("Address release %d.\n", address); 129 usb_device_keeper_release(&hc-> device_manager, address);126 usb_device_keeper_release(&hc->manager, address); 130 127 return EOK; 131 128 } … … 142 139 * @return Error code. 143 140 */ 144 static int interrupt_out(ddf_fun_t *fun, usb_target_t target, 145 size_t max_packet_size, void *data, size_t size, 146 usbhc_iface_transfer_out_callback_t callback, void *arg) 147 { 148 assert(fun); 149 uhci_hc_t *hc = fun_to_uhci_hc(fun); 150 assert(hc); 151 usb_speed_t speed = usb_device_keeper_get_speed(&hc->device_manager, target.address); 141 static int interrupt_out( 142 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data, 143 size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg) 144 { 145 assert(fun); 146 hc_t *hc = fun_to_hc(fun); 147 assert(hc); 148 usb_speed_t speed = 149 usb_device_keeper_get_speed(&hc->manager, target.address); 152 150 153 151 usb_log_debug("Interrupt OUT %d:%d %zu(%zu).\n", 154 152 target.address, target.endpoint, size, max_packet_size); 155 153 156 usb_transfer_batch_t *batch = batch_get(fun, target, USB_TRANSFER_INTERRUPT,157 max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg,158 &hc->device_manager);154 usb_transfer_batch_t *batch = 155 batch_get(fun, target, USB_TRANSFER_INTERRUPT, max_packet_size, 156 speed, data, size, NULL, 0, NULL, callback, arg, &hc->manager); 159 157 if (!batch) 160 158 return ENOMEM; 161 159 batch_interrupt_out(batch); 162 const int ret = uhci_hc_schedule(hc, batch); 163 if (ret != EOK) { 164 batch_dispose(batch); 165 return ret; 166 } 167 return EOK; 160 const int ret = hc_schedule(hc, batch); 161 if (ret != EOK) { 162 batch_dispose(batch); 163 } 164 return ret; 168 165 } 169 166 /*----------------------------------------------------------------------------*/ … … 179 176 * @return Error code. 180 177 */ 181 static int interrupt_in(ddf_fun_t *fun, usb_target_t target, 182 size_t max_packet_size, void *data, size_t size, 183 usbhc_iface_transfer_in_callback_t callback, void *arg) 184 { 185 assert(fun); 186 uhci_hc_t *hc = fun_to_uhci_hc(fun); 187 assert(hc); 188 usb_speed_t speed = usb_device_keeper_get_speed(&hc->device_manager, target.address); 178 static int interrupt_in( 179 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data, 180 size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg) 181 { 182 assert(fun); 183 hc_t *hc = fun_to_hc(fun); 184 assert(hc); 185 usb_speed_t speed = 186 usb_device_keeper_get_speed(&hc->manager, target.address); 189 187 usb_log_debug("Interrupt IN %d:%d %zu(%zu).\n", 190 188 target.address, target.endpoint, size, max_packet_size); 191 189 192 usb_transfer_batch_t *batch = batch_get(fun, target, USB_TRANSFER_INTERRUPT,193 max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg,194 &hc->device_manager);190 usb_transfer_batch_t *batch = 191 batch_get(fun, target, USB_TRANSFER_INTERRUPT, max_packet_size, 192 speed, data, size, NULL, 0, callback, NULL, arg, &hc->manager); 195 193 if (!batch) 196 194 return ENOMEM; 197 195 batch_interrupt_in(batch); 198 const int ret = uhci_hc_schedule(hc, batch); 199 if (ret != EOK) { 200 batch_dispose(batch); 201 return ret; 202 } 203 return EOK; 196 const int ret = hc_schedule(hc, batch); 197 if (ret != EOK) { 198 batch_dispose(batch); 199 } 200 return ret; 204 201 } 205 202 /*----------------------------------------------------------------------------*/ … … 215 212 * @return Error code. 216 213 */ 217 static int bulk_out(ddf_fun_t *fun, usb_target_t target, 218 size_t max_packet_size, void *data, size_t size, 219 usbhc_iface_transfer_out_callback_t callback, void *arg) 220 { 221 assert(fun); 222 uhci_hc_t *hc = fun_to_uhci_hc(fun); 223 assert(hc); 224 usb_speed_t speed = usb_device_keeper_get_speed(&hc->device_manager, target.address); 214 static int bulk_out( 215 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data, 216 size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg) 217 { 218 assert(fun); 219 hc_t *hc = fun_to_hc(fun); 220 assert(hc); 221 usb_speed_t speed = 222 usb_device_keeper_get_speed(&hc->manager, target.address); 225 223 226 224 usb_log_debug("Bulk OUT %d:%d %zu(%zu).\n", 227 225 target.address, target.endpoint, size, max_packet_size); 228 226 229 usb_transfer_batch_t *batch = batch_get(fun, target, USB_TRANSFER_BULK,230 max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg,231 &hc->device_manager);227 usb_transfer_batch_t *batch = 228 batch_get(fun, target, USB_TRANSFER_BULK, max_packet_size, speed, 229 data, size, NULL, 0, NULL, callback, arg, &hc->manager); 232 230 if (!batch) 233 231 return ENOMEM; 234 232 batch_bulk_out(batch); 235 const int ret = uhci_hc_schedule(hc, batch); 236 if (ret != EOK) { 237 batch_dispose(batch); 238 return ret; 239 } 240 return EOK; 233 const int ret = hc_schedule(hc, batch); 234 if (ret != EOK) { 235 batch_dispose(batch); 236 } 237 return ret; 241 238 } 242 239 /*----------------------------------------------------------------------------*/ … … 252 249 * @return Error code. 253 250 */ 254 static int bulk_in(ddf_fun_t *fun, usb_target_t target, 255 size_t max_packet_size, void *data, size_t size, 256 usbhc_iface_transfer_in_callback_t callback, void *arg) 257 { 258 assert(fun); 259 uhci_hc_t *hc = fun_to_uhci_hc(fun); 260 assert(hc); 261 usb_speed_t speed = usb_device_keeper_get_speed(&hc->device_manager, target.address); 251 static int bulk_in( 252 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data, 253 size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg) 254 { 255 assert(fun); 256 hc_t *hc = fun_to_hc(fun); 257 assert(hc); 258 usb_speed_t speed = 259 usb_device_keeper_get_speed(&hc->manager, target.address); 262 260 usb_log_debug("Bulk IN %d:%d %zu(%zu).\n", 263 261 target.address, target.endpoint, size, max_packet_size); 264 262 265 usb_transfer_batch_t *batch = batch_get(fun, target, USB_TRANSFER_BULK,266 max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg,267 &hc->device_manager);263 usb_transfer_batch_t *batch = 264 batch_get(fun, target, USB_TRANSFER_BULK, max_packet_size, speed, 265 data, size, NULL, 0, callback, NULL, arg, &hc->manager); 268 266 if (!batch) 269 267 return ENOMEM; 270 268 batch_bulk_in(batch); 271 const int ret = uhci_hc_schedule(hc, batch); 272 if (ret != EOK) { 273 batch_dispose(batch); 274 return ret; 275 } 276 return EOK; 269 const int ret = hc_schedule(hc, batch); 270 if (ret != EOK) { 271 batch_dispose(batch); 272 } 273 return ret; 277 274 } 278 275 /*----------------------------------------------------------------------------*/ … … 290 287 * @return Error code. 291 288 */ 292 static int control_write( ddf_fun_t *fun, usb_target_t target,293 size_t max_packet_size,289 static int control_write( 290 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, 294 291 void *setup_data, size_t setup_size, void *data, size_t size, 295 292 usbhc_iface_transfer_out_callback_t callback, void *arg) 296 293 { 297 294 assert(fun); 298 uhci_hc_t *hc = fun_to_uhci_hc(fun); 299 assert(hc); 300 usb_speed_t speed = usb_device_keeper_get_speed(&hc->device_manager, target.address); 295 hc_t *hc = fun_to_hc(fun); 296 assert(hc); 297 usb_speed_t speed = 298 usb_device_keeper_get_speed(&hc->manager, target.address); 301 299 usb_log_debug("Control WRITE (%d) %d:%d %zu(%zu).\n", 302 300 speed, target.address, target.endpoint, size, max_packet_size); … … 305 303 return EINVAL; 306 304 307 usb_transfer_batch_t *batch = batch_get(fun, target, USB_TRANSFER_CONTROL, 308 max_packet_size, speed, data, size, setup_data, setup_size, 309 NULL, callback, arg, &hc->device_manager); 310 if (!batch) 311 return ENOMEM; 312 usb_device_keeper_reset_if_need(&hc->device_manager, target, setup_data); 305 usb_transfer_batch_t *batch = 306 batch_get(fun, target, USB_TRANSFER_CONTROL, max_packet_size, speed, 307 data, size, setup_data, setup_size, NULL, callback, arg, 308 &hc->manager); 309 if (!batch) 310 return ENOMEM; 311 usb_device_keeper_reset_if_need(&hc->manager, target, setup_data); 313 312 batch_control_write(batch); 314 const int ret = uhci_hc_schedule(hc, batch); 315 if (ret != EOK) { 316 batch_dispose(batch); 317 return ret; 318 } 319 return EOK; 313 const int ret = hc_schedule(hc, batch); 314 if (ret != EOK) { 315 batch_dispose(batch); 316 } 317 return ret; 320 318 } 321 319 /*----------------------------------------------------------------------------*/ … … 333 331 * @return Error code. 334 332 */ 335 static int control_read( ddf_fun_t *fun, usb_target_t target,336 size_t max_packet_size,333 static int control_read( 334 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, 337 335 void *setup_data, size_t setup_size, void *data, size_t size, 338 336 usbhc_iface_transfer_in_callback_t callback, void *arg) 339 337 { 340 338 assert(fun); 341 uhci_hc_t *hc = fun_to_uhci_hc(fun); 342 assert(hc); 343 usb_speed_t speed = usb_device_keeper_get_speed(&hc->device_manager, target.address); 339 hc_t *hc = fun_to_hc(fun); 340 assert(hc); 341 usb_speed_t speed = 342 usb_device_keeper_get_speed(&hc->manager, target.address); 344 343 345 344 usb_log_debug("Control READ(%d) %d:%d %zu(%zu).\n", 346 345 speed, target.address, target.endpoint, size, max_packet_size); 347 usb_transfer_batch_t *batch = batch_get(fun, target, USB_TRANSFER_CONTROL, 348 max_packet_size, speed, data, size, setup_data, setup_size, callback, 349 NULL, arg, &hc->device_manager); 346 usb_transfer_batch_t *batch = 347 batch_get(fun, target, USB_TRANSFER_CONTROL, max_packet_size, speed, 348 data, size, setup_data, setup_size, callback, NULL, arg, 349 &hc->manager); 350 350 if (!batch) 351 351 return ENOMEM; 352 352 batch_control_read(batch); 353 const int ret = uhci_hc_schedule(hc, batch); 354 if (ret != EOK) { 355 batch_dispose(batch); 356 return ret; 357 } 358 return EOK; 359 } 360 /*----------------------------------------------------------------------------*/ 361 usbhc_iface_t uhci_hc_iface = { 353 const int ret = hc_schedule(hc, batch); 354 if (ret != EOK) { 355 batch_dispose(batch); 356 } 357 return ret; 358 } 359 /*----------------------------------------------------------------------------*/ 360 usbhc_iface_t hc_iface = { 362 361 .reserve_default_address = reserve_default_address, 363 362 .release_default_address = release_default_address, … … 369 368 .interrupt_in = interrupt_in, 370 369 370 .bulk_out = bulk_out, 371 371 .bulk_in = bulk_in, 372 .bulk_out = bulk_out, 373 372 373 .control_write = control_write, 374 374 .control_read = control_read, 375 .control_write = control_write,376 375 }; 377 376 /** -
uspace/drv/uhci-hcd/iface.h
r31b568e rb01995b 38 38 #include <usbhc_iface.h> 39 39 40 extern usbhc_iface_t uhci_hc_iface;40 extern usbhc_iface_t hc_iface; 41 41 42 42 #endif -
uspace/drv/uhci-hcd/root_hub.c
r31b568e rb01995b 39 39 #include <usb/debug.h> 40 40 41 #include "uhci_rh.h" 42 #include "uhci_hc.h" 41 #include "root_hub.h" 43 42 44 43 /** Root hub initialization … … 49 48 * @return Error code. 50 49 */ 51 int uhci_rh_init(52 uhci_rh_t *instance, ddf_fun_t *fun, uintptr_t reg_addr, size_t reg_size)50 int rh_init( 51 rh_t *instance, ddf_fun_t *fun, uintptr_t reg_addr, size_t reg_size) 53 52 { 54 53 assert(fun); -
uspace/drv/uhci-hcd/root_hub.h
r31b568e rb01995b 39 39 #include <ops/hw_res.h> 40 40 41 typedef struct uhci_rh {41 typedef struct rh { 42 42 hw_resource_list_t resource_list; 43 43 hw_resource_t io_regs; 44 } uhci_rh_t;44 } rh_t; 45 45 46 int uhci_rh_init(47 uhci_rh_t *instance, ddf_fun_t *fun, uintptr_t reg_addr, size_t reg_size);46 int rh_init( 47 rh_t *instance, ddf_fun_t *fun, uintptr_t reg_addr, size_t reg_size); 48 48 49 49 #endif -
uspace/drv/uhci-hcd/transfer_list.c
r31b568e rb01995b 79 79 if (!instance->queue_head) 80 80 return; 81 /* Set both next and element to point to the same QH*/81 /* Set both queue_head.next to point to the follower */ 82 82 qh_set_next_qh(instance->queue_head, next->queue_head_pa); 83 qh_set_element_qh(instance->queue_head, next->queue_head_pa);84 83 } 85 84 /*----------------------------------------------------------------------------*/ … … 98 97 usb_log_debug2("Queue %s: Adding batch(%p).\n", instance->name, batch); 99 98 100 const uint32_t pa = addr_to_phys(batch_qh(batch));101 assert((pa & LINK_POINTER_ADDRESS_MASK) == pa);102 103 /* New batch will be added to the end of the current list104 * so set the link accordingly */105 qh_set_next_qh(batch_qh(batch), instance->queue_head->next);106 107 99 fibril_mutex_lock(&instance->guard); 108 100 101 qh_t *last_qh = NULL; 109 102 /* Add to the hardware queue. */ 110 103 if (list_empty(&instance->batch_list)) { 111 104 /* There is nothing scheduled */ 112 qh_t *qh = instance->queue_head; 113 assert(qh->element == qh->next); 114 qh_set_element_qh(qh, pa); 105 last_qh = instance->queue_head; 115 106 } else { 116 107 /* There is something scheduled */ 117 108 usb_transfer_batch_t *last = list_get_instance( 118 109 instance->batch_list.prev, usb_transfer_batch_t, link); 119 qh_set_next_qh(batch_qh(last), pa); 120 } 110 last_qh = batch_qh(last); 111 } 112 const uint32_t pa = addr_to_phys(batch_qh(batch)); 113 assert((pa & LINK_POINTER_ADDRESS_MASK) == pa); 114 115 /* keep link */ 116 batch_qh(batch)->next = last_qh->next; 117 qh_set_next_qh(last_qh, pa); 118 121 119 /* Add to the driver list */ 122 120 list_append(&batch->link, &instance->batch_list); … … 174 172 { 175 173 fibril_mutex_lock(&instance->guard); 176 while ( list_empty(&instance->batch_list)) {174 while (!list_empty(&instance->batch_list)) { 177 175 link_t *current = instance->batch_list.next; 178 176 usb_transfer_batch_t *batch = list_get_instance(current, usb_transfer_batch_t, link); … … 197 195 assert(batch); 198 196 assert(batch_qh(batch)); 197 assert(fibril_mutex_is_locked(&instance->guard)); 198 199 199 usb_log_debug2( 200 200 "Queue %s: removing batch(%p).\n", instance->name, batch); 201 201 202 const char * pos = NULL;202 const char *qpos = NULL; 203 203 /* Remove from the hardware queue */ 204 if ( batch->link.prev == &instance->batch_list) {204 if (instance->batch_list.next == &batch->link) { 205 205 /* I'm the first one here */ 206 qh_set_element_qh(instance->queue_head, batch_qh(batch)->next); 207 pos = "FIRST"; 206 assert((instance->queue_head->next & LINK_POINTER_ADDRESS_MASK) 207 == addr_to_phys(batch_qh(batch))); 208 instance->queue_head->next = batch_qh(batch)->next; 209 qpos = "FIRST"; 208 210 } else { 209 211 usb_transfer_batch_t *prev = 210 212 list_get_instance(batch->link.prev, usb_transfer_batch_t, link); 211 qh_set_next_qh(batch_qh(prev), batch_qh(batch)->next); 212 pos = "NOT FIRST"; 213 } 214 /* Remove from the driver list */ 213 assert((batch_qh(prev)->next & LINK_POINTER_ADDRESS_MASK) 214 == addr_to_phys(batch_qh(batch))); 215 batch_qh(prev)->next = batch_qh(batch)->next; 216 qpos = "NOT FIRST"; 217 } 218 /* Remove from the batch list */ 215 219 list_remove(&batch->link); 216 usb_log_debug("Batch(%p) removed (%s) from %s, next element%x.\n",217 batch, pos, instance->name, batch_qh(batch)->next);220 usb_log_debug("Batch(%p) removed (%s) from %s, next %x.\n", 221 batch, qpos, instance->name, batch_qh(batch)->next); 218 222 } 219 223 /** -
uspace/drv/uhci-hcd/transfer_list.h
r31b568e rb01995b 37 37 #include <fibril_synch.h> 38 38 39 #include "uhci_struct/queue_head.h"40 41 39 #include "batch.h" 40 #include "hw_struct/queue_head.h" 42 41 43 42 typedef struct transfer_list -
uspace/drv/uhci-hcd/uhci.c
r31b568e rb01995b 54 54 { 55 55 assert(dev); 56 uhci_hc_t *hc = &((uhci_t*)dev->driver_data)->hc;56 hc_t *hc = &((uhci_t*)dev->driver_data)->hc; 57 57 uint16_t status = IPC_GET_ARG1(*call); 58 58 assert(hc); 59 uhci_hc_interrupt(hc, status);59 hc_interrupt(hc, status); 60 60 } 61 61 /*----------------------------------------------------------------------------*/ … … 70 70 { 71 71 assert(fun); 72 usb_device_keeper_t *manager = &((uhci_t*)fun->dev->driver_data)->hc. device_manager;72 usb_device_keeper_t *manager = &((uhci_t*)fun->dev->driver_data)->hc.manager; 73 73 74 74 usb_address_t addr = usb_device_keeper_find(manager, handle); … … 107 107 }; 108 108 /*----------------------------------------------------------------------------*/ 109 static ddf_dev_ops_t uhci_hc_ops = {109 static ddf_dev_ops_t hc_ops = { 110 110 .interfaces[USB_DEV_IFACE] = &usb_iface, 111 .interfaces[USBHC_DEV_IFACE] = & uhci_hc_iface, /* see iface.h/c */111 .interfaces[USBHC_DEV_IFACE] = &hc_iface, /* see iface.h/c */ 112 112 }; 113 113 /*----------------------------------------------------------------------------*/ … … 120 120 { 121 121 assert(fun); 122 return &(( uhci_rh_t*)fun->driver_data)->resource_list;122 return &((rh_t*)fun->driver_data)->resource_list; 123 123 } 124 124 /*----------------------------------------------------------------------------*/ … … 128 128 }; 129 129 /*----------------------------------------------------------------------------*/ 130 static ddf_dev_ops_t uhci_rh_ops = {130 static ddf_dev_ops_t rh_ops = { 131 131 .interfaces[USB_DEV_IFACE] = &usb_iface, 132 132 .interfaces[HW_RES_DEV_IFACE] = &hw_res_iface … … 190 190 "Failed(%d) to create HC function.\n", ret); 191 191 192 ret = uhci_hc_init(&instance->hc, instance->hc_fun,192 ret = hc_init(&instance->hc, instance->hc_fun, 193 193 (void*)io_reg_base, io_reg_size, interrupts); 194 194 CHECK_RET_DEST_FUN_RETURN(ret, "Failed(%d) to init uhci-hcd.\n", ret); 195 instance->hc_fun->ops = & uhci_hc_ops;195 instance->hc_fun->ops = &hc_ops; 196 196 instance->hc_fun->driver_data = &instance->hc; 197 197 ret = ddf_fun_bind(instance->hc_fun); … … 208 208 if (instance->rh_fun) \ 209 209 ddf_fun_destroy(instance->rh_fun); \ 210 uhci_hc_fini(&instance->hc); \210 hc_fini(&instance->hc); \ 211 211 return ret; \ 212 212 } … … 223 223 "Failed(%d) to create root hub function.\n", ret); 224 224 225 ret = uhci_rh_init(&instance->rh, instance->rh_fun,225 ret = rh_init(&instance->rh, instance->rh_fun, 226 226 (uintptr_t)instance->hc.registers + 0x10, 4); 227 227 CHECK_RET_FINI_RETURN(ret, 228 228 "Failed(%d) to setup UHCI root hub.\n", ret); 229 229 230 instance->rh_fun->ops = & uhci_rh_ops;230 instance->rh_fun->ops = &rh_ops; 231 231 instance->rh_fun->driver_data = &instance->rh; 232 232 ret = ddf_fun_bind(instance->rh_fun); -
uspace/drv/uhci-hcd/uhci.h
r31b568e rb01995b 38 38 #include <ddf/driver.h> 39 39 40 #include " uhci_hc.h"41 #include " uhci_rh.h"40 #include "hc.h" 41 #include "root_hub.h" 42 42 43 43 typedef struct uhci { … … 45 45 ddf_fun_t *rh_fun; 46 46 47 uhci_hc_t hc;48 uhci_rh_t rh;47 hc_t hc; 48 rh_t rh; 49 49 } uhci_t; 50 50 -
uspace/drv/uhci-hcd/utils/malloc32.h
r31b568e rb01995b 50 50 static inline uintptr_t addr_to_phys(void *addr) 51 51 { 52 if (addr == NULL) 53 return 0; 54 52 55 uintptr_t result; 53 56 int ret = as_get_physical_mapping(addr, &result);
Note:
See TracChangeset
for help on using the changeset viewer.
