Changeset 20a3465 in mainline for uspace/drv
- Timestamp:
- 2011-10-30T19:50:54Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 3ce78580, 48902fa
- Parents:
- 4c3ad56 (diff), 45bf63c (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/bus/usb
- Files:
-
- 6 deleted
- 49 edited
-
ohci/endpoint_list.c (modified) (2 diffs)
-
ohci/endpoint_list.h (modified) (1 diff)
-
ohci/hc.c (modified) (6 diffs)
-
ohci/hc.h (modified) (1 diff)
-
ohci/hw_struct/endpoint_descriptor.c (modified) (1 diff)
-
ohci/hw_struct/endpoint_descriptor.h (modified) (5 diffs)
-
ohci/hw_struct/hcca.h (modified) (2 diffs)
-
ohci/hw_struct/transfer_descriptor.c (modified) (2 diffs)
-
ohci/hw_struct/transfer_descriptor.h (modified) (3 diffs)
-
ohci/ohci.c (modified) (1 diff)
-
ohci/ohci_batch.c (modified) (9 diffs)
-
ohci/ohci_endpoint.c (modified) (2 diffs)
-
ohci/ohci_endpoint.h (modified) (2 diffs)
-
ohci/ohci_regs.h (modified) (1 diff)
-
ohci/root_hub.c (modified) (20 diffs)
-
ohci/root_hub.h (modified) (1 diff)
-
ohci/utils/malloc32.h (modified) (2 diffs)
-
uhci/hc.c (modified) (1 diff)
-
uhci/uhci.c (modified) (1 diff)
-
uhci/uhci_batch.c (modified) (1 diff)
-
usbflbk/main.c (modified) (2 diffs)
-
usbhid/generic/hiddev.c (modified) (12 diffs)
-
usbhid/generic/hiddev.h (modified) (2 diffs)
-
usbhid/kbd/conv.c (modified) (7 diffs)
-
usbhid/kbd/kbddev.c (modified) (34 diffs)
-
usbhid/kbd/kbddev.h (modified) (2 diffs)
-
usbhid/kbd/kbdrepeat.c (modified) (7 diffs)
-
usbhid/kbd/kbdrepeat.h (modified) (1 diff)
-
usbhid/main.c (modified) (10 diffs)
-
usbhid/mouse/mousedev.c (modified) (28 diffs)
-
usbhid/mouse/mousedev.h (modified) (1 diff)
-
usbhid/multimedia/multimedia.c (modified) (10 diffs)
-
usbhid/subdrivers.c (modified) (3 diffs)
-
usbhid/subdrivers.h (modified) (2 diffs)
-
usbhid/usbhid.c (modified) (35 diffs)
-
usbhid/usbhid.h (modified) (3 diffs)
-
usbhub/main.c (modified) (2 diffs)
-
usbhub/port.c (modified) (1 diff)
-
usbhub/port.h (modified) (1 diff)
-
usbhub/usbhub.c (modified) (8 diffs)
-
usbhub/usbhub.h (modified) (1 diff)
-
usbmast/main.c (modified) (10 diffs)
-
usbmast/usbmast.h (modified) (2 diffs)
-
usbmid/dump.c (modified) (4 diffs)
-
usbmid/explore.c (modified) (4 diffs)
-
usbmid/main.c (modified) (1 diff)
-
usbmid/usbmid.c (modified) (5 diffs)
-
usbmid/usbmid.h (modified) (2 diffs)
-
usbmouse/Makefile (deleted)
-
usbmouse/init.c (deleted)
-
usbmouse/main.c (deleted)
-
usbmouse/mouse.c (deleted)
-
usbmouse/mouse.h (deleted)
-
usbmouse/usbmouse.ma (deleted)
-
vhc/connhost.c (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ohci/endpoint_list.c
r4c3ad56 r20a3465 60 60 name, instance->list_head, instance->list_head_pa); 61 61 62 ed_init(instance->list_head, NULL );62 ed_init(instance->list_head, NULL, NULL); 63 63 list_initialize(&instance->endpoint_list); 64 64 fibril_mutex_initialize(&instance->guard); … … 73 73 * Does not check whether this replaces an existing list. 74 74 */ 75 void endpoint_list_set_next(endpoint_list_t *instance, endpoint_list_t *next) 75 void endpoint_list_set_next( 76 const endpoint_list_t *instance, const endpoint_list_t *next) 76 77 { 77 78 assert(instance); -
uspace/drv/bus/usb/ohci/endpoint_list.h
r4c3ad56 r20a3465 68 68 69 69 int endpoint_list_init(endpoint_list_t *instance, const char *name); 70 void endpoint_list_set_next(endpoint_list_t *instance, endpoint_list_t *next); 70 void endpoint_list_set_next( 71 const endpoint_list_t *instance, const endpoint_list_t *next); 71 72 void endpoint_list_add_ep(endpoint_list_t *instance, ohci_endpoint_t *ep); 72 73 void endpoint_list_remove_ep(endpoint_list_t *instance, ohci_endpoint_t *ep); -
uspace/drv/bus/usb/ohci/hc.c
r4c3ad56 r20a3465 142 142 if (ret != EOK) { \ 143 143 usb_log_error(message); \ 144 usb_endpoint_manager_unregister_ep( \ 145 &instance->generic.ep_manager, hub_address, 0, USB_DIRECTION_BOTH);\ 144 usb_endpoint_manager_remove_ep( \ 145 &instance->generic.ep_manager, hub_address, 0, USB_DIRECTION_BOTH, \ 146 NULL, NULL);\ 146 147 usb_device_manager_release( \ 147 148 &instance->generic.dev_manager, hub_address); \ … … 150 151 int ret = usb_endpoint_manager_add_ep( 151 152 &instance->generic.ep_manager, hub_address, 0, USB_DIRECTION_BOTH, 152 USB_TRANSFER_CONTROL, USB_SPEED_FULL, 64, 0 );153 USB_TRANSFER_CONTROL, USB_SPEED_FULL, 64, 0, NULL, NULL); 153 154 CHECK_RET_UNREG_RETURN(ret, 154 155 "Failed to register root hub control endpoint: %s.\n", … … 192 193 list_initialize(&instance->pending_batches); 193 194 194 ret =hcd_init(&instance->generic, BANDWIDTH_AVAILABLE_USB11,195 hcd_init(&instance->generic, BANDWIDTH_AVAILABLE_USB11, 195 196 bandwidth_count_usb11); 196 CHECK_RET_RETURN(ret, "Failed to initialize generic driver: %s.\n",197 str_error(ret));198 197 instance->generic.private_data = instance; 199 198 instance->generic.schedule = hc_schedule; 200 199 instance->generic.ep_add_hook = ohci_endpoint_init; 200 instance->generic.ep_remove_hook = ohci_endpoint_fini; 201 201 202 202 ret = hc_init_memory(instance); … … 221 221 } 222 222 /*----------------------------------------------------------------------------*/ 223 void hc_enqueue_endpoint(hc_t *instance, endpoint_t *ep) 224 { 223 void hc_enqueue_endpoint(hc_t *instance, const endpoint_t *ep) 224 { 225 assert(instance); 226 assert(ep); 227 225 228 endpoint_list_t *list = &instance->lists[ep->transfer_type]; 226 229 ohci_endpoint_t *ohci_ep = ohci_endpoint_get(ep); 230 assert(list); 231 assert(ohci_ep); 232 227 233 /* Enqueue ep */ 228 234 switch (ep->transfer_type) { … … 247 253 } 248 254 /*----------------------------------------------------------------------------*/ 249 void hc_dequeue_endpoint(hc_t *instance, endpoint_t *ep) 250 { 255 void hc_dequeue_endpoint(hc_t *instance, const endpoint_t *ep) 256 { 257 assert(instance); 258 assert(ep); 259 251 260 /* Dequeue ep */ 252 261 endpoint_list_t *list = &instance->lists[ep->transfer_type]; 253 262 ohci_endpoint_t *ohci_ep = ohci_endpoint_get(ep); 263 264 assert(list); 265 assert(ohci_ep); 254 266 switch (ep->transfer_type) { 255 267 case USB_TRANSFER_CONTROL: … … 565 577 566 578 /*Init HCCA */ 567 instance->hcca = malloc32(sizeof(hcca_t));579 instance->hcca = hcca_get(); 568 580 if (instance->hcca == NULL) 569 581 return ENOMEM; -
uspace/drv/bus/usb/ohci/hc.h
r4c3ad56 r20a3465 86 86 static inline void hc_fini(hc_t *instance) { /* TODO: implement*/ }; 87 87 88 void hc_enqueue_endpoint(hc_t *instance, endpoint_t *ep);89 void hc_dequeue_endpoint(hc_t *instance, endpoint_t *ep);88 void hc_enqueue_endpoint(hc_t *instance, const endpoint_t *ep); 89 void hc_dequeue_endpoint(hc_t *instance, const endpoint_t *ep); 90 90 91 91 void hc_interrupt(hc_t *instance, uint32_t status); -
uspace/drv/bus/usb/ohci/hw_struct/endpoint_descriptor.c
r4c3ad56 r20a3465 34 34 #include "endpoint_descriptor.h" 35 35 36 static unsigned direc[3] = 37 { ED_STATUS_D_IN, ED_STATUS_D_OUT, ED_STATUS_D_TRANSFER }; 36 /** USB direction to OHCI values translation table. */ 37 static const uint32_t dir[] = { 38 [USB_DIRECTION_IN] = ED_STATUS_D_IN, 39 [USB_DIRECTION_OUT] = ED_STATUS_D_OUT, 40 [USB_DIRECTION_BOTH] = ED_STATUS_D_TD, 41 }; 38 42 39 void ed_init(ed_t *instance, endpoint_t *ep) 43 /** 44 * Initialize ED. 45 * 46 * @param instance ED structure to initialize. 47 * @param ep Driver endpoint to use. 48 * @param td TD to put in the list. 49 * 50 * If @param ep is NULL, dummy ED is initalized with only skip flag set. 51 */ 52 void ed_init(ed_t *instance, const endpoint_t *ep, const td_t *td) 40 53 { 41 54 assert(instance); 42 55 bzero(instance, sizeof(ed_t)); 56 43 57 if (ep == NULL) { 58 /* Mark as dead, used for dummy EDs at the beginning of 59 * endpoint lists. */ 44 60 instance->status = ED_STATUS_K_FLAG; 45 61 return; 46 62 } 47 assert(ep); 63 /* Non-dummy ED must have TD assigned */ 64 assert(td); 65 66 /* Status: address, endpoint nr, direction mask and max packet size. */ 48 67 instance->status = 0 49 68 | ((ep->address & ED_STATUS_FA_MASK) << ED_STATUS_FA_SHIFT) 50 69 | ((ep->endpoint & ED_STATUS_EN_MASK) << ED_STATUS_EN_SHIFT) 51 | ((dir ec[ep->direction] & ED_STATUS_D_MASK) << ED_STATUS_D_SHIFT)70 | ((dir[ep->direction] & ED_STATUS_D_MASK) << ED_STATUS_D_SHIFT) 52 71 | ((ep->max_packet_size & ED_STATUS_MPS_MASK) 53 72 << ED_STATUS_MPS_SHIFT); 54 73 55 74 /* Low speed flag */ 56 75 if (ep->speed == USB_SPEED_LOW) 57 76 instance->status |= ED_STATUS_S_FLAG; 77 78 /* Isochronous format flag */ 58 79 if (ep->transfer_type == USB_TRANSFER_ISOCHRONOUS) 59 80 instance->status |= ED_STATUS_F_FLAG; 60 81 82 /* Set TD to the list */ 83 const uintptr_t pa = addr_to_phys(td); 84 instance->td_head = pa & ED_TDHEAD_PTR_MASK; 85 instance->td_tail = pa & ED_TDTAIL_PTR_MASK; 86 87 /* Set toggle bit */ 61 88 if (ep->toggle) 62 89 instance->td_head |= ED_TDHEAD_TOGGLE_CARRY; 90 63 91 } 64 92 /** -
uspace/drv/bus/usb/ohci/hw_struct/endpoint_descriptor.h
r4c3ad56 r20a3465 45 45 #include "completion_codes.h" 46 46 47 /** 48 * OHCI Endpoint Descriptor representation. 49 * 50 * See OHCI spec. Chapter 4.2, page 16 (pdf page 30) for details */ 47 51 typedef struct ed { 52 /** 53 * Status field. 54 * 55 * See table 4-1, p. 17 OHCI spec (pdf page 31). 56 */ 48 57 volatile uint32_t status; 49 58 #define ED_STATUS_FA_MASK (0x7f) /* USB device address */ … … 51 60 #define ED_STATUS_EN_MASK (0xf) /* USB endpoint address */ 52 61 #define ED_STATUS_EN_SHIFT (7) 53 #define ED_STATUS_D_MASK (0x3) /* direction */62 #define ED_STATUS_D_MASK (0x3) /* Direction */ 54 63 #define ED_STATUS_D_SHIFT (11) 55 64 #define ED_STATUS_D_OUT (0x1) 56 65 #define ED_STATUS_D_IN (0x2) 57 #define ED_STATUS_D_T RANSFER (0x3)66 #define ED_STATUS_D_TD (0x3) /* Direction is specified by TD */ 58 67 59 #define ED_STATUS_S_FLAG (1 << 13) /* speed flag: 1 = low */60 #define ED_STATUS_K_FLAG (1 << 14) /* skip flag (no not execute this ED) */61 #define ED_STATUS_F_FLAG (1 << 15) /* format: 1 = isochronous*/62 #define ED_STATUS_MPS_MASK (0x3ff) /* max_packet_size*/68 #define ED_STATUS_S_FLAG (1 << 13) /* Speed flag: 1 = low */ 69 #define ED_STATUS_K_FLAG (1 << 14) /* Skip flag (no not execute this ED) */ 70 #define ED_STATUS_F_FLAG (1 << 15) /* Format: 1 = isochronous */ 71 #define ED_STATUS_MPS_MASK (0x3ff) /* Maximum packet size */ 63 72 #define ED_STATUS_MPS_SHIFT (16) 64 73 74 /** 75 * Pointer to the last TD. 76 * 77 * OHCI hw never changes this field and uses it only for a reference. 78 */ 65 79 volatile uint32_t td_tail; 66 80 #define ED_TDTAIL_PTR_MASK (0xfffffff0) 67 81 #define ED_TDTAIL_PTR_SHIFT (0) 68 82 83 /** 84 * Pointer to the first TD. 85 * 86 * Driver should not change this field if the ED is active. 87 * This field is updated by OHCI hw and points to the next TD 88 * to be executed. 89 */ 69 90 volatile uint32_t td_head; 70 91 #define ED_TDHEAD_PTR_MASK (0xfffffff0) … … 75 96 #define ED_TDHEAD_HALTED_FLAG (0x1) 76 97 98 /** 99 * Pointer to the next ED. 100 * 101 * Driver should not change this field on active EDs. 102 */ 77 103 volatile uint32_t next; 78 104 #define ED_NEXT_PTR_MASK (0xfffffff0) … … 80 106 } __attribute__((packed)) ed_t; 81 107 82 void ed_init(ed_t *instance, endpoint_t *ep);108 void ed_init(ed_t *instance, const endpoint_t *ep, const td_t *td); 83 109 84 static inline void ed_set_td(ed_t *instance, td_t *td) 110 /** 111 * Check for SKIP or HALTED flag being set. 112 * @param instance ED 113 * @return true if either SKIP or HALTED flag is set, false otherwise. 114 */ 115 static inline bool ed_inactive(const ed_t *instance) 85 116 { 86 117 assert(instance); 87 uintptr_t pa = addr_to_phys(td); 88 instance->td_head = 89 ((pa & ED_TDHEAD_PTR_MASK) 90 | (instance->td_head & ~ED_TDHEAD_PTR_MASK)); 118 return (instance->td_head & ED_TDHEAD_HALTED_FLAG) 119 || (instance->status & ED_STATUS_K_FLAG); 120 } 121 122 /** 123 * Check whether this ED contains TD to be executed. 124 * @param instance ED 125 * @return true if there are pending TDs, false otherwise. 126 */ 127 static inline bool ed_transfer_pending(const ed_t *instance) 128 { 129 assert(instance); 130 return (instance->td_head & ED_TDHEAD_PTR_MASK) 131 != (instance->td_tail & ED_TDTAIL_PTR_MASK); 132 } 133 134 /** 135 * Set the last element of TD list 136 * @param instance ED 137 * @param instance TD to set as the last item. 138 */ 139 static inline void ed_set_tail_td(ed_t *instance, const td_t *td) 140 { 141 assert(instance); 142 const uintptr_t pa = addr_to_phys(td); 91 143 instance->td_tail = pa & ED_TDTAIL_PTR_MASK; 92 144 } 93 145 94 static inline void ed_set_end_td(ed_t *instance, td_t *td) 95 { 96 assert(instance); 97 uintptr_t pa = addr_to_phys(td); 98 instance->td_tail = pa & ED_TDTAIL_PTR_MASK; 99 } 100 101 static inline void ed_append_ed(ed_t *instance, ed_t *next) 146 /** 147 * Set next ED in ED chain. 148 * @param instance ED to modify 149 * @param next ED to append 150 */ 151 static inline void ed_append_ed(ed_t *instance, const ed_t *next) 102 152 { 103 153 assert(instance); 104 154 assert(next); 105 uint32_t pa = addr_to_phys(next);155 const uint32_t pa = addr_to_phys(next); 106 156 assert((pa & ED_NEXT_PTR_MASK) << ED_NEXT_PTR_SHIFT == pa); 107 157 instance->next = pa; 108 158 } 109 159 110 static inline int ed_toggle_get(ed_t *instance) 160 /** 161 * Get toggle bit value stored in this ED 162 * @param instance ED 163 * @return Toggle bit value 164 */ 165 static inline int ed_toggle_get(const ed_t *instance) 111 166 { 112 167 assert(instance); … … 114 169 } 115 170 116 static inline void ed_toggle_set(ed_t *instance, int toggle) 171 /** 172 * Set toggle bit value stored in this ED 173 * @param instance ED 174 * @param toggle Toggle bit value 175 */ 176 static inline void ed_toggle_set(ed_t *instance, bool toggle) 117 177 { 118 178 assert(instance); 119 assert(toggle == 0 || toggle == 1); 120 if (toggle == 1) { 179 if (toggle) { 121 180 instance->td_head |= ED_TDHEAD_TOGGLE_CARRY; 122 181 } else { 123 /* clear halted flag when reseting toggle*/182 /* Clear halted flag when reseting toggle TODO: Why? */ 124 183 instance->td_head &= ~ED_TDHEAD_TOGGLE_CARRY; 125 184 instance->td_head &= ~ED_TDHEAD_HALTED_FLAG; -
uspace/drv/bus/usb/ohci/hw_struct/hcca.h
r4c3ad56 r20a3465 36 36 37 37 #include <stdint.h> 38 #include <malloc.h> 38 39 39 40 /** Host controller communication area. … … 48 49 } __attribute__((packed, aligned)) hcca_t; 49 50 51 static inline void * hcca_get(void) 52 { 53 assert(sizeof(hcca_t) == 256); 54 return memalign(256, sizeof(hcca_t)); 55 } 50 56 #endif 51 57 /** -
uspace/drv/bus/usb/ohci/hw_struct/transfer_descriptor.c
r4c3ad56 r20a3465 35 35 #include "transfer_descriptor.h" 36 36 37 static unsigned dp[3] = 38 { TD_STATUS_DP_IN, TD_STATUS_DP_OUT, TD_STATUS_DP_SETUP }; 39 static unsigned togg[2] = { TD_STATUS_T_0, TD_STATUS_T_1 }; 37 /** USB direction to OHCI TD values translation table */ 38 static const uint32_t dir[] = { 39 [USB_DIRECTION_IN] = TD_STATUS_DP_IN, 40 [USB_DIRECTION_OUT] = TD_STATUS_DP_OUT, 41 [USB_DIRECTION_BOTH] = TD_STATUS_DP_SETUP, 42 }; 40 43 41 void td_init(td_t *instance, 42 usb_direction_t dir, const void *buffer, size_t size, int toggle) 44 /** 45 * Initialize OHCI TD. 46 * @param instance TD structure to initialize. 47 * @param next Next TD in ED list. 48 * @param direction Used to determine PID, BOTH means setup PID. 49 * @param buffer Pointer to the first byte of transferred data. 50 * @param size Size of the buffer. 51 * @param toggle Toggle bit value, use 0/1 to set explicitly, 52 * any other value means that ED toggle will be used. 53 */ 54 void td_init(td_t *instance, const td_t *next, 55 usb_direction_t direction, const void *buffer, size_t size, int toggle) 43 56 { 44 57 assert(instance); 45 58 bzero(instance, sizeof(td_t)); 59 /* Set PID and Error code */ 46 60 instance->status = 0 47 | ((d p[dir] & TD_STATUS_DP_MASK) << TD_STATUS_DP_SHIFT)61 | ((dir[direction] & TD_STATUS_DP_MASK) << TD_STATUS_DP_SHIFT) 48 62 | ((CC_NOACCESS2 & TD_STATUS_CC_MASK) << TD_STATUS_CC_SHIFT); 63 49 64 if (toggle == 0 || toggle == 1) { 50 instance->status |= togg[toggle] << TD_STATUS_T_SHIFT; 65 /* Set explicit toggle bit */ 66 instance->status |= TD_STATUS_T_USE_TD_FLAG; 67 instance->status |= toggle ? TD_STATUS_T_FLAG : 0; 51 68 } 69 70 /* Alow less data on input. */ 52 71 if (dir == USB_DIRECTION_IN) { 53 72 instance->status |= TD_STATUS_ROUND_FLAG; 54 73 } 74 55 75 if (buffer != NULL) { 56 76 assert(size != 0); … … 58 78 instance->be = addr_to_phys(buffer + size - 1); 59 79 } 80 81 instance->next = addr_to_phys(next) & TD_NEXT_PTR_MASK; 82 60 83 } 61 84 /** -
uspace/drv/bus/usb/ohci/hw_struct/transfer_descriptor.h
r4c3ad56 r20a3465 37 37 #include <bool.h> 38 38 #include <stdint.h> 39 39 40 #include "../utils/malloc32.h" 40 41 41 #include "completion_codes.h" 42 42 … … 46 46 #define OHCI_TD_MAX_TRANSFER (4 * 1024) 47 47 48 /** 49 * Transfer Descriptor representation. 50 * 51 * See OHCI spec chapter 4.3.1 General Transfer Descriptor on page 19 52 * (pdf page 33) for details. 53 */ 48 54 typedef struct td { 55 /** Status field. Do not touch on active TDs. */ 49 56 volatile uint32_t status; 50 57 #define TD_STATUS_ROUND_FLAG (1 << 18) 51 #define TD_STATUS_DP_MASK (0x3) /* direction/PID */58 #define TD_STATUS_DP_MASK (0x3) /* Direction/PID */ 52 59 #define TD_STATUS_DP_SHIFT (19) 53 60 #define TD_STATUS_DP_SETUP (0x0) 54 61 #define TD_STATUS_DP_OUT (0x1) 55 62 #define TD_STATUS_DP_IN (0x2) 56 #define TD_STATUS_DI_MASK (0x7) /* delay interrupt, wait DI frames before int*/63 #define TD_STATUS_DI_MASK (0x7) /* Delay interrupt, wait n frames before irq */ 57 64 #define TD_STATUS_DI_SHIFT (21) 58 65 #define TD_STATUS_DI_NO_INTERRUPT (0x7) 59 #define TD_STATUS_T_MASK (0x3) /* data toggle 1x = use ED toggle carry */ 60 #define TD_STATUS_T_SHIFT (24) 61 #define TD_STATUS_T_0 (0x2) 62 #define TD_STATUS_T_1 (0x3) 63 #define TD_STATUS_T_ED (0) 64 #define TD_STATUS_EC_MASK (0x3) /* error count */ 66 #define TD_STATUS_T_FLAG (1 << 24) /* Explicit toggle bit value for this TD */ 67 #define TD_STATUS_T_USE_TD_FLAG (1 << 25) /* 1 = use bit 24 as toggle bit */ 68 #define TD_STATUS_EC_MASK (0x3) /* Error count */ 65 69 #define TD_STATUS_EC_SHIFT (26) 66 #define TD_STATUS_CC_MASK (0xf) /* condition code */70 #define TD_STATUS_CC_MASK (0xf) /* Condition code */ 67 71 #define TD_STATUS_CC_SHIFT (28) 68 72 69 volatile uint32_t cbp; /* current buffer ptr, data to be transfered */ 73 /** 74 * Current buffer pointer. 75 * Phys address of the first byte to be transferred. */ 76 volatile uint32_t cbp; 77 78 /** Pointer to the next TD in chain. 16-byte aligned. */ 70 79 volatile uint32_t next; 71 80 #define TD_NEXT_PTR_MASK (0xfffffff0) 72 81 #define TD_NEXT_PTR_SHIFT (0) 73 82 74 volatile uint32_t be; /* buffer end, address of the last byte */ 83 /** 84 * Buffer end. 85 * Phys address of the last byte of the transfer. 86 * @note this does not have to be on the same page as cbp. 87 */ 88 volatile uint32_t be; 75 89 } __attribute__((packed)) td_t; 76 90 77 void td_init(td_t *instance, 91 void td_init(td_t *instance, const td_t *next, 78 92 usb_direction_t dir, const void *buffer, size_t size, int toggle); 79 93 80 inline static void td_set_next(td_t *instance, td_t *next) 94 /** 95 * Check TD for completion. 96 * @param instance TD structure. 97 * @return true if the TD was accessed and processed by hw, false otherwise. 98 */ 99 inline static bool td_is_finished(const td_t *instance) 81 100 { 82 101 assert(instance); 83 instance->next = addr_to_phys(next) & TD_NEXT_PTR_MASK; 84 } 85 86 inline static bool td_is_finished(td_t *instance) 87 { 88 assert(instance); 89 int cc = (instance->status >> TD_STATUS_CC_SHIFT) & TD_STATUS_CC_MASK; 90 /* something went wrong, error code is set */ 102 const int cc = 103 (instance->status >> TD_STATUS_CC_SHIFT) & TD_STATUS_CC_MASK; 104 /* This value is changed on transfer completion, 105 * either to CC_NOERROR or and error code. 106 * See OHCI spec 4.3.1.3.5 p. 23 (pdf 37) */ 91 107 if (cc != CC_NOACCESS1 && cc != CC_NOACCESS2) { 92 return true;93 }94 /* everything done */95 if (cc == CC_NOERROR && instance->cbp == 0) {96 108 return true; 97 109 } … … 99 111 } 100 112 101 static inline int td_error(td_t *instance) 113 /** 114 * Get error code that indicates transfer status. 115 * @param instance TD structure. 116 * @return Error code. 117 */ 118 static inline int td_error(const td_t *instance) 102 119 { 103 120 assert(instance); 104 int cc = (instance->status >> TD_STATUS_CC_SHIFT) & TD_STATUS_CC_MASK; 121 const int cc = 122 (instance->status >> TD_STATUS_CC_SHIFT) & TD_STATUS_CC_MASK; 105 123 return cc_to_rc(cc); 106 124 } 107 125 126 /** 127 * Get remaining portion of buffer to be read/written 128 * @param instance TD structure 129 * @return size of remaining buffer. 130 */ 108 131 static inline size_t td_remain_size(td_t *instance) 109 132 { 110 133 assert(instance); 134 /* Current buffer pointer is cleared on successful transfer */ 111 135 if (instance->cbp == 0) 112 136 return 0; 137 /* Buffer end points to the last byte of transfer buffer, so add 1 */ 113 138 return instance->be - instance->cbp + 1; 114 139 } -
uspace/drv/bus/usb/ohci/ohci.c
r4c3ad56 r20a3465 89 89 &dev_to_ohci(fun->dev)->hc.generic.dev_manager; 90 90 91 const usb_address_t addr = usb_device_manager_find(manager, handle); 91 const usb_address_t addr = 92 usb_device_manager_find_address(manager, handle); 92 93 if (addr < 0) { 93 94 return addr; -
uspace/drv/bus/usb/ohci/ohci_batch.c
r4c3ad56 r20a3465 59 59 free(ohci_batch->tds); 60 60 } 61 usb_transfer_batch_d ispose(ohci_batch->usb_batch);61 usb_transfer_batch_destroy(ohci_batch->usb_batch); 62 62 free32(ohci_batch->device_buffer); 63 63 free(ohci_batch); … … 163 163 ohci_batch->ed->td_tail, ohci_batch->ed->next); 164 164 165 size_t i = 0; 166 for (; i < ohci_batch->td_count; ++i) { 165 if (!ed_inactive(ohci_batch->ed) && ed_transfer_pending(ohci_batch->ed)) 166 return false; 167 168 /* Now we may be sure that either the ED is inactive because of errors 169 * or all transfer descriptors completed successfully */ 170 171 /* Assume all data got through */ 172 ohci_batch->usb_batch->transfered_size = 173 ohci_batch->usb_batch->buffer_size; 174 175 /* Assume we will leave the last(unused) TD behind */ 176 ohci_batch->leave_td = ohci_batch->td_count; 177 178 /* Check all TDs */ 179 for (size_t i = 0; i < ohci_batch->td_count; ++i) { 167 180 assert(ohci_batch->tds[i] != NULL); 168 181 usb_log_debug("TD %zu: %08x:%08x:%08x:%08x.\n", i, 169 182 ohci_batch->tds[i]->status, ohci_batch->tds[i]->cbp, 170 183 ohci_batch->tds[i]->next, ohci_batch->tds[i]->be); 171 if (!td_is_finished(ohci_batch->tds[i])) { 172 return false; 173 } 184 185 /* If the TD got all its data through, it will report 0 bytes 186 * remain, the sole exception is INPUT with data rounding flag 187 * (short), i.e. every INPUT. Nice thing is that short packets 188 * will correctly report remaining data, thus making 189 * this computation correct (short packets need to be produced 190 * by the last TD) 191 * NOTE: This also works for CONTROL transfer as 192 * the first TD will return 0 remain. 193 * NOTE: Short packets don't break the assumption that 194 * we leave the very last(unused) TD behind. 195 */ 196 ohci_batch->usb_batch->transfered_size 197 -= td_remain_size(ohci_batch->tds[i]); 198 174 199 ohci_batch->usb_batch->error = td_error(ohci_batch->tds[i]); 175 200 if (ohci_batch->usb_batch->error != EOK) { … … 177 202 ohci_batch->usb_batch, i, 178 203 ohci_batch->tds[i]->status); 179 /* Make sure TD queue is empty (one TD), 180 * ED should be marked as halted */ 181 ohci_batch->ed->td_tail = 182 (ohci_batch->ed->td_head & ED_TDTAIL_PTR_MASK); 183 ++i; 204 205 /* ED should be stopped because of errors */ 206 assert((ohci_batch->ed->td_head & ED_TDHEAD_HALTED_FLAG) != 0); 207 208 /* Now we have a problem: we don't know what TD 209 * the head pointer points to, the retiring rules 210 * described in specs say it should be the one after 211 * the failed one so set the tail pointer accordingly. 212 * It will be the one TD we leave behind. 213 */ 214 ohci_batch->leave_td = i + 1; 215 216 /* Check TD assumption */ 217 const uint32_t pa = addr_to_phys( 218 ohci_batch->tds[ohci_batch->leave_td]); 219 assert((ohci_batch->ed->td_head & ED_TDTAIL_PTR_MASK) 220 == pa); 221 222 ed_set_tail_td(ohci_batch->ed, 223 ohci_batch->tds[ohci_batch->leave_td]); 224 225 /* Clear possible ED HALT */ 226 ohci_batch->ed->td_head &= ~ED_TDHEAD_HALTED_FLAG; 184 227 break; 185 228 } 186 229 } 187 188 assert(i <= ohci_batch->td_count);189 ohci_batch->leave_td = i; 190 230 assert(ohci_batch->usb_batch->transfered_size <= 231 ohci_batch->usb_batch->buffer_size); 232 233 /* Store the remaining TD */ 191 234 ohci_endpoint_t *ohci_ep = ohci_endpoint_get(ohci_batch->usb_batch->ep); 192 235 assert(ohci_ep); 193 236 ohci_ep->td = ohci_batch->tds[ohci_batch->leave_td]; 194 assert(i > 0); 195 ohci_batch->usb_batch->transfered_size = 196 ohci_batch->usb_batch->buffer_size; 197 for (--i;i < ohci_batch->td_count; ++i) { 198 ohci_batch->usb_batch->transfered_size 199 -= td_remain_size(ohci_batch->tds[i]); 200 } 201 202 /* Clear possible ED HALT */ 203 ohci_batch->ed->td_head &= ~ED_TDHEAD_HALTED_FLAG; 204 /* just make sure that we are leaving the right TD behind */ 237 238 /* Make sure that we are leaving the right TD behind */ 205 239 const uint32_t pa = addr_to_phys(ohci_ep->td); 206 240 assert(pa == (ohci_batch->ed->td_head & ED_TDHEAD_PTR_MASK)); … … 217 251 { 218 252 assert(ohci_batch); 219 ed_set_ end_td(ohci_batch->ed, ohci_batch->tds[ohci_batch->td_count]);253 ed_set_tail_td(ohci_batch->ed, ohci_batch->tds[ohci_batch->td_count]); 220 254 } 221 255 /*----------------------------------------------------------------------------*/ … … 247 281 const usb_direction_t status_dir = reverse_dir[dir]; 248 282 249 /* setup stage */250 td_init( ohci_batch->tds[0], USB_DIRECTION_BOTH, buffer,251 ohci_batch->usb_batch->setup_size, toggle);252 td_set_next(ohci_batch->tds[0], ohci_batch->tds[1]);283 /* Setup stage */ 284 td_init( 285 ohci_batch->tds[0], ohci_batch->tds[1], USB_DIRECTION_BOTH, 286 buffer, ohci_batch->usb_batch->setup_size, toggle); 253 287 usb_log_debug("Created CONTROL SETUP TD: %08x:%08x:%08x:%08x.\n", 254 288 ohci_batch->tds[0]->status, ohci_batch->tds[0]->cbp, … … 256 290 buffer += ohci_batch->usb_batch->setup_size; 257 291 258 /* data stage */292 /* Data stage */ 259 293 size_t td_current = 1; 260 294 size_t remain_size = ohci_batch->usb_batch->buffer_size; … … 265 299 toggle = 1 - toggle; 266 300 267 td_init(ohci_batch->tds[td_current], data_dir, buffer, 268 transfer_size, toggle); 269 td_set_next(ohci_batch->tds[td_current], 270 ohci_batch->tds[td_current + 1]); 301 td_init(ohci_batch->tds[td_current], 302 ohci_batch->tds[td_current + 1], 303 data_dir, buffer, transfer_size, toggle); 271 304 usb_log_debug("Created CONTROL DATA TD: %08x:%08x:%08x:%08x.\n", 272 305 ohci_batch->tds[td_current]->status, … … 281 314 } 282 315 283 /* status stage */316 /* Status stage */ 284 317 assert(td_current == ohci_batch->td_count - 1); 285 td_init(ohci_batch->tds[td_current], status_dir, NULL, 0, 1); 286 td_set_next(ohci_batch->tds[td_current], 287 ohci_batch->tds[td_current + 1]); 318 td_init(ohci_batch->tds[td_current], ohci_batch->tds[td_current + 1], 319 status_dir, NULL, 0, 1); 288 320 usb_log_debug("Created CONTROL STATUS TD: %08x:%08x:%08x:%08x.\n", 289 321 ohci_batch->tds[td_current]->status, … … 323 355 ? OHCI_TD_MAX_TRANSFER : remain_size; 324 356 325 td_init(ohci_batch->tds[td_current], dir, buffer, 326 transfer_size, -1); 327 td_set_next(ohci_batch->tds[td_current], 328 ohci_batch->tds[td_current + 1]); 357 td_init( 358 ohci_batch->tds[td_current], ohci_batch->tds[td_current + 1], 359 dir, buffer, transfer_size, -1); 329 360 330 361 usb_log_debug("Created DATA TD: %08x:%08x:%08x:%08x.\n", -
uspace/drv/bus/usb/ohci/ohci_endpoint.c
r4c3ad56 r20a3465 62 62 } 63 63 /*----------------------------------------------------------------------------*/ 64 /** Disposes hcd endpoint structure65 *66 * @param[in] hcd_ep endpoint structure67 */68 static void ohci_endpoint_fini(endpoint_t *ep)69 {70 ohci_endpoint_t *instance = ep->hc_data.data;71 hc_dequeue_endpoint(instance->hcd->private_data, ep);72 if (instance) {73 free32(instance->ed);74 free32(instance->td);75 free(instance);76 }77 }78 /*----------------------------------------------------------------------------*/79 64 /** Creates new hcd endpoint representation. 80 65 * 81 66 * @param[in] ep USBD endpoint structure 82 * @return pointer to a new hcd endpoint structure, NULL on failure.67 * @return Error code. 83 68 */ 84 69 int ohci_endpoint_init(hcd_t *hcd, endpoint_t *ep) … … 102 87 } 103 88 104 ed_init(ohci_ep->ed, ep); 105 ed_set_td(ohci_ep->ed, ohci_ep->td); 89 ed_init(ohci_ep->ed, ep, ohci_ep->td); 106 90 endpoint_set_hc_data( 107 ep, ohci_ep, ohci_endpoint_fini, ohci_ep_toggle_get, ohci_ep_toggle_set); 108 ohci_ep->hcd = hcd; 91 ep, ohci_ep, ohci_ep_toggle_get, ohci_ep_toggle_set); 109 92 hc_enqueue_endpoint(hcd->private_data, ep); 110 93 return EOK; 94 } 95 /*----------------------------------------------------------------------------*/ 96 /** Disposes hcd endpoint structure 97 * 98 * @param[in] hcd driver using this instance. 99 * @param[in] ep endpoint structure. 100 */ 101 void ohci_endpoint_fini(hcd_t *hcd, endpoint_t *ep) 102 { 103 assert(hcd); 104 assert(ep); 105 ohci_endpoint_t *instance = ohci_endpoint_get(ep); 106 hc_dequeue_endpoint(hcd->private_data, ep); 107 if (instance) { 108 free32(instance->ed); 109 free32(instance->td); 110 free(instance); 111 } 112 endpoint_clear_hc_data(ep); 111 113 } 112 114 /** -
uspace/drv/bus/usb/ohci/ohci_endpoint.h
r4c3ad56 r20a3465 51 51 /** Linked list used by driver software */ 52 52 link_t link; 53 /** Device using this ep */54 hcd_t *hcd;55 53 } ohci_endpoint_t; 56 54 57 55 int ohci_endpoint_init(hcd_t *hcd, endpoint_t *ep); 56 void ohci_endpoint_fini(hcd_t *hcd, endpoint_t *ep); 58 57 59 58 /** Get and convert assigned ohci_endpoint_t structure … … 61 60 * @return Pointer to assigned hcd endpoint structure 62 61 */ 63 static inline ohci_endpoint_t * ohci_endpoint_get( endpoint_t *ep)62 static inline ohci_endpoint_t * ohci_endpoint_get(const endpoint_t *ep) 64 63 { 65 64 assert(ep); -
uspace/drv/bus/usb/ohci/ohci_regs.h
r4c3ad56 r20a3465 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /** @addtogroup drvusbohci hc28 /** @addtogroup drvusbohci 29 29 * @{ 30 30 */ -
uspace/drv/bus/usb/ohci/root_hub.c
r4c3ad56 r20a3465 35 35 #include <errno.h> 36 36 #include <str_error.h> 37 #include <fibril_synch.h> 37 38 38 39 #include <usb/debug.h> 40 #include <usb/dev/request.h> 41 #include <usb/classes/hub.h> 39 42 40 43 #include "root_hub.h" … … 43 46 #include <usb/dev/driver.h> 44 47 #include "ohci_regs.h" 45 46 #include <usb/dev/request.h>47 #include <usb/classes/hub.h>48 48 49 49 /** … … 108 108 static void create_serialized_hub_descriptor(rh_t *instance); 109 109 static void rh_init_descriptors(rh_t *instance); 110 static uint16_t create_interrupt_mask(rh_t *instance); 111 static int get_status(rh_t *instance, usb_transfer_batch_t *request); 112 static int get_descriptor(rh_t *instance, usb_transfer_batch_t *request); 113 static int set_feature(rh_t *instance, usb_transfer_batch_t *request); 114 static int clear_feature(rh_t *instance, usb_transfer_batch_t *request); 115 static int set_feature_port(rh_t *instance, uint16_t feature, uint16_t port); 116 static int clear_feature_port(rh_t *instance, uint16_t feature, uint16_t port); 110 static uint16_t create_interrupt_mask(const rh_t *instance); 111 static int get_status(const rh_t *instance, usb_transfer_batch_t *request); 112 static int get_descriptor(const rh_t *instance, usb_transfer_batch_t *request); 113 static int set_feature(const rh_t *instance, usb_transfer_batch_t *request); 114 static int clear_feature(const rh_t *instance, usb_transfer_batch_t *request); 115 static int set_feature_port( 116 const rh_t *instance, uint16_t feature, uint16_t port); 117 static int clear_feature_port( 118 const rh_t *instance, uint16_t feature, uint16_t port); 117 119 static int control_request(rh_t *instance, usb_transfer_batch_t *request); 118 120 static inline void interrupt_request( … … 153 155 instance->unfinished_interrupt_transfer = NULL; 154 156 155 #if defOHCI_POWER_SWITCH_no157 #if defined OHCI_POWER_SWITCH_no 156 158 /* Set port power mode to no power-switching. (always on) */ 157 159 instance->registers->rh_desc_a |= RHDA_NPS_FLAG; 160 158 161 /* Set to no over-current reporting */ 159 162 instance->registers->rh_desc_a |= RHDA_NOCP_FLAG; 163 160 164 #elif defined OHCI_POWER_SWITCH_ganged 161 165 /* Set port power mode to no ganged power-switching. */ … … 163 167 instance->registers->rh_desc_a &= ~RHDA_PSM_FLAG; 164 168 instance->registers->rh_status = RHS_CLEAR_GLOBAL_POWER; 169 165 170 /* Set to global over-current */ 166 171 instance->registers->rh_desc_a &= ~RHDA_NOCP_FLAG; … … 174 179 instance->registers->rh_desc_b &= (RHDB_PCC_MASK << RHDB_PCC_SHIFT); 175 180 instance->registers->rh_status = RHS_CLEAR_GLOBAL_POWER; 181 176 182 /* Return control to per port state */ 177 183 instance->registers->rh_desc_b |= 178 184 ((1 << (instance->port_count + 1)) - 1) << RHDB_PCC_SHIFT; 185 179 186 /* Set per port over-current */ 180 187 instance->registers->rh_desc_a &= ~RHDA_NOCP_FLAG; … … 182 189 #endif 183 190 191 fibril_mutex_initialize(&instance->guard); 184 192 rh_init_descriptors(instance); 185 193 … … 209 217 case USB_TRANSFER_INTERRUPT: 210 218 usb_log_debug("Root hub got INTERRUPT packet\n"); 219 fibril_mutex_lock(&instance->guard); 220 assert(instance->unfinished_interrupt_transfer == NULL); 211 221 const uint16_t mask = create_interrupt_mask(instance); 212 222 if (mask == 0) { 213 223 usb_log_debug("No changes..\n"); 214 assert(instance->unfinished_interrupt_transfer == NULL);215 224 instance->unfinished_interrupt_transfer = request; 225 fibril_mutex_unlock(&instance->guard); 216 226 return; 217 227 } 218 228 usb_log_debug("Processing changes...\n"); 219 229 interrupt_request(request, mask, instance->interrupt_mask_size); 230 fibril_mutex_unlock(&instance->guard); 220 231 break; 221 232 … … 224 235 usb_transfer_batch_finish_error(request, NULL, 0, EINVAL); 225 236 } 226 usb_transfer_batch_d ispose(request);237 usb_transfer_batch_destroy(request); 227 238 } 228 239 /*----------------------------------------------------------------------------*/ … … 237 248 assert(instance); 238 249 239 if (!instance->unfinished_interrupt_transfer) 240 return; 241 242 usb_log_debug("Finalizing interrupt transfer\n"); 243 const uint16_t mask = create_interrupt_mask(instance); 244 interrupt_request(instance->unfinished_interrupt_transfer, 245 mask, instance->interrupt_mask_size); 246 usb_transfer_batch_dispose(instance->unfinished_interrupt_transfer); 247 248 instance->unfinished_interrupt_transfer = NULL; 250 fibril_mutex_lock(&instance->guard); 251 if (instance->unfinished_interrupt_transfer) { 252 usb_log_debug("Finalizing interrupt transfer\n"); 253 const uint16_t mask = create_interrupt_mask(instance); 254 interrupt_request(instance->unfinished_interrupt_transfer, 255 mask, instance->interrupt_mask_size); 256 usb_transfer_batch_destroy( 257 instance->unfinished_interrupt_transfer); 258 instance->unfinished_interrupt_transfer = NULL; 259 } 260 fibril_mutex_unlock(&instance->guard); 249 261 } 250 262 /*----------------------------------------------------------------------------*/ … … 342 354 * @return Mask of changes. 343 355 */ 344 uint16_t create_interrupt_mask( rh_t *instance)356 uint16_t create_interrupt_mask(const rh_t *instance) 345 357 { 346 358 assert(instance); … … 372 384 * @return error code 373 385 */ 374 int get_status( rh_t *instance, usb_transfer_batch_t *request)386 int get_status(const rh_t *instance, usb_transfer_batch_t *request) 375 387 { 376 388 assert(instance); … … 418 430 * @return Error code 419 431 */ 420 int get_descriptor( rh_t *instance, usb_transfer_batch_t *request)432 int get_descriptor(const rh_t *instance, usb_transfer_batch_t *request) 421 433 { 422 434 assert(instance); … … 496 508 * @return error code 497 509 */ 498 int set_feature_port( rh_t *instance, uint16_t feature, uint16_t port)510 int set_feature_port(const rh_t *instance, uint16_t feature, uint16_t port) 499 511 { 500 512 assert(instance); … … 535 547 * @return error code 536 548 */ 537 int clear_feature_port( rh_t *instance, uint16_t feature, uint16_t port)549 int clear_feature_port(const rh_t *instance, uint16_t feature, uint16_t port) 538 550 { 539 551 assert(instance); … … 592 604 * @return error code 593 605 */ 594 int set_feature( rh_t *instance, usb_transfer_batch_t *request)606 int set_feature(const rh_t *instance, usb_transfer_batch_t *request) 595 607 { 596 608 assert(instance); … … 628 640 * @return error code 629 641 */ 630 int clear_feature( rh_t *instance, usb_transfer_batch_t *request)642 int clear_feature(const rh_t *instance, usb_transfer_batch_t *request) 631 643 { 632 644 assert(instance); … … 635 647 const usb_device_request_setup_packet_t *setup_request = 636 648 (usb_device_request_setup_packet_t *) request->setup_buffer; 649 637 650 request->transfered_size = 0; 651 638 652 switch (setup_request->request_type) 639 653 { … … 647 661 /* 648 662 * Chapter 11.16.2 specifies that only C_HUB_LOCAL_POWER and 649 * C_HUB_OVER_CURRENT are supported. C_HUB_OVER_CURRENT is represented 650 * by OHCI RHS_OCIC_FLAG. C_HUB_LOCAL_POWER is not supported 663 * C_HUB_OVER_CURRENT are supported. 664 * C_HUB_OVER_CURRENT is represented by OHCI RHS_OCIC_FLAG. 665 * C_HUB_LOCAL_POWER is not supported 651 666 * as root hubs do not support local power status feature. 652 667 * (OHCI pg. 127) */ … … 720 735 "additional data\n"); 721 736 return clear_feature(instance, request); 737 722 738 case USB_DEVREQ_SET_FEATURE: 723 739 usb_log_debug2("Processing request without " -
uspace/drv/bus/usb/ohci/root_hub.h
r4c3ad56 r20a3465 47 47 */ 48 48 typedef struct rh { 49 fibril_mutex_t guard; 49 50 /** pointer to ohci driver registers */ 50 51 ohci_regs_t *registers; -
uspace/drv/bus/usb/ohci/utils/malloc32.h
r4c3ad56 r20a3465 41 41 #include <as.h> 42 42 43 /* Generic TDs and EDs require 16byte alignment, 44 * Isochronous TD require 32byte alignment, 45 * buffers do not have to be aligned. 46 */ 47 #define OHCI_ALIGN 32 48 43 49 /** Get physical address translation 44 50 * … … 62 68 */ 63 69 static inline void * malloc32(size_t size) 64 { return memalign( size, size); }70 { return memalign(OHCI_ALIGN, size); } 65 71 /*----------------------------------------------------------------------------*/ 66 72 /** Physical mallocator simulator -
uspace/drv/bus/usb/uhci/hc.c
r4c3ad56 r20a3465 192 192 "Device registers at %p (%zuB) accessible.\n", io, reg_size); 193 193 194 ret = hcd_init(&instance->generic, BANDWIDTH_AVAILABLE_USB11, 194 ret = hc_init_mem_structures(instance); 195 CHECK_RET_RETURN(ret, 196 "Failed to initialize UHCI memory structures: %s.\n", 197 str_error(ret)); 198 199 #undef CHECK_RET_RETURN 200 201 hcd_init(&instance->generic, BANDWIDTH_AVAILABLE_USB11, 195 202 bandwidth_count_usb11); 196 CHECK_RET_RETURN(ret, "Failed to initialize HCD generic driver: %s.\n",197 str_error(ret));198 203 199 204 instance->generic.private_data = instance; 200 205 instance->generic.schedule = hc_schedule; 201 206 instance->generic.ep_add_hook = NULL; 202 203 #undef CHECK_RET_DEST_FUN_RETURN204 205 ret = hc_init_mem_structures(instance);206 if (ret != EOK) {207 usb_log_error(208 "Failed to initialize UHCI memory structures: %s.\n",209 str_error(ret));210 hcd_destroy(&instance->generic);211 return ret;212 }213 207 214 208 hc_init_hw(instance); -
uspace/drv/bus/usb/uhci/uhci.c
r4c3ad56 r20a3465 101 101 usb_device_manager_t *manager = 102 102 &dev_to_uhci(fun->dev)->hc.generic.dev_manager; 103 const usb_address_t addr = usb_device_manager_find(manager, handle); 103 const usb_address_t addr = 104 usb_device_manager_find_address(manager, handle); 104 105 105 106 if (addr < 0) { -
uspace/drv/bus/usb/uhci/uhci_batch.c
r4c3ad56 r20a3465 48 48 { 49 49 if (uhci_batch) { 50 usb_transfer_batch_d ispose(uhci_batch->usb_batch);50 usb_transfer_batch_destroy(uhci_batch->usb_batch); 51 51 free32(uhci_batch->device_buffer); 52 52 free(uhci_batch); -
uspace/drv/bus/usb/usbflbk/main.c
r4c3ad56 r20a3465 64 64 } 65 65 66 dev->driver_data = ctl_fun; 67 66 68 usb_log_info("Pretending to control %s `%s'" \ 67 69 " (node `%s', handle %" PRIun ").\n", … … 72 74 } 73 75 76 /** Callback when new device is about to be removed. 77 * 78 * @param dev Representation of a generic DDF device. 79 * @return Error code. 80 */ 81 static int usbfallback_device_remove(usb_device_t *dev) 82 { 83 return EOK; 84 } 85 86 /** Callback when new device is removed and recognized as gone by DDF. 87 * 88 * @param dev Representation of a generic DDF device. 89 * @return Error code. 90 */ 91 static int usbfallback_device_gone(usb_device_t *dev) 92 { 93 assert(dev); 94 ddf_fun_t *ctl_fun = dev->driver_data; 95 const int ret = ddf_fun_unbind(ctl_fun); 96 if (ret != EOK) { 97 usb_log_error("Failed to unbind %s.\n", ctl_fun->name); 98 return ret; 99 } 100 ddf_fun_destroy(ctl_fun); 101 dev->driver_data = NULL; 102 103 return EOK; 104 } 105 74 106 /** USB fallback driver ops. */ 75 static usb_driver_ops_t usbfallback_driver_ops = {107 static const usb_driver_ops_t usbfallback_driver_ops = { 76 108 .device_add = usbfallback_device_add, 109 .device_rem = usbfallback_device_remove, 110 .device_gone = usbfallback_device_gone, 77 111 }; 78 112 79 113 /** USB fallback driver. */ 80 static usb_driver_t usbfallback_driver = {114 static const usb_driver_t usbfallback_driver = { 81 115 .name = NAME, 82 116 .ops = &usbfallback_driver_ops, -
uspace/drv/bus/usb/usbhid/generic/hiddev.c
r4c3ad56 r20a3465 48 48 /*----------------------------------------------------------------------------*/ 49 49 50 usb_endpoint_description_t usb_hid_generic_poll_endpoint_description = {50 const usb_endpoint_description_t usb_hid_generic_poll_endpoint_description = { 51 51 .transfer_type = USB_TRANSFER_INTERRUPT, 52 52 .direction = USB_DIRECTION_IN, 53 53 .interface_class = USB_CLASS_HID, 54 .interface_subclass = -1, 55 .interface_protocol = -1, 54 56 .flags = 0 55 57 }; … … 92 94 usb_log_debug2("Generic HID: Get event length (fun: %p, " 93 95 "fun->driver_data: %p.\n", fun, fun->driver_data); 94 96 95 97 if (fun == NULL || fun->driver_data == NULL) { 96 98 return 0; … … 98 100 99 101 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data; 100 102 101 103 usb_log_debug2("hid_dev: %p, Max input report size (%zu).\n", 102 104 hid_dev, hid_dev->max_input_report_size); 103 105 104 106 return hid_dev->max_input_report_size; 105 107 } … … 111 113 { 112 114 usb_log_debug2("Generic HID: Get event.\n"); 113 115 114 116 if (fun == NULL || fun->driver_data == NULL || buffer == NULL 115 117 || act_size == NULL || event_nr == NULL) { … … 119 121 120 122 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data; 121 123 122 124 if (hid_dev->input_report_size > size) { 123 125 usb_log_debug("input_report_size > size (%zu, %zu)\n", … … 125 127 return EINVAL; // TODO: other error code 126 128 } 127 129 128 130 /*! @todo This should probably be somehow atomic. */ 129 131 memcpy(buffer, hid_dev->input_report, … … 131 133 *act_size = hid_dev->input_report_size; 132 134 *event_nr = usb_hid_report_number(hid_dev); 133 135 134 136 usb_log_debug2("OK\n"); 135 137 136 138 return EOK; 137 139 } … … 142 144 { 143 145 usb_log_debug("Generic HID: Get report descriptor length.\n"); 144 146 145 147 if (fun == NULL || fun->driver_data == NULL) { 146 148 usb_log_debug("No function"); 147 149 return EINVAL; 148 150 } 149 150 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data; 151 151 152 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data; 153 152 154 usb_log_debug2("hid_dev->report_desc_size = %zu\n", 153 155 hid_dev->report_desc_size); 154 156 155 157 return hid_dev->report_desc_size; 156 158 } … … 162 164 { 163 165 usb_log_debug2("Generic HID: Get report descriptor.\n"); 164 166 165 167 if (fun == NULL || fun->driver_data == NULL) { 166 168 usb_log_debug("No function"); 167 169 return EINVAL; 168 170 } 169 170 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data; 171 171 172 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data; 173 172 174 if (hid_dev->report_desc_size > size) { 173 175 return EINVAL; 174 176 } 175 177 176 178 memcpy(desc, hid_dev->report_desc, hid_dev->report_desc_size); 177 179 *actual_size = hid_dev->report_desc_size; 178 180 179 181 return EOK; 180 182 } … … 190 192 /*----------------------------------------------------------------------------*/ 191 193 192 static int usb_generic_hid_create_function(usb_hid_dev_t *hid_dev) 193 { 194 void usb_generic_hid_deinit(usb_hid_dev_t *hid_dev, void *data) 195 { 196 ddf_fun_t *fun = data; 197 const int ret = ddf_fun_unbind(fun); 198 if (ret != EOK) { 199 usb_log_error("Failed to unbind generic hid fun.\n"); 200 return; 201 } 202 usb_log_debug2("%s unbound.\n", fun->name); 203 /* We did not allocate this, so leave this alone 204 * the device would take care of it */ 205 fun->driver_data = NULL; 206 ddf_fun_destroy(fun); 207 } 208 209 /*----------------------------------------------------------------------------*/ 210 211 int usb_generic_hid_init(usb_hid_dev_t *hid_dev, void **data) 212 { 213 if (hid_dev == NULL) { 214 return EINVAL; 215 } 216 194 217 /* Create the exposed function. */ 195 218 /** @todo Generate numbers for the devices? */ … … 201 224 return ENOMEM; 202 225 } 203 226 204 227 fun->ops = &usb_generic_hid_ops; 205 fun->driver_data = hid_dev;206 228 207 229 int rc = ddf_fun_bind(fun); … … 212 234 return rc; 213 235 } 214 236 /* This is nasty both device and this function have the same 237 * driver data, thus destruction would lead to double free */ 238 fun->driver_data = hid_dev; 239 215 240 usb_log_debug("HID function created. Handle: %" PRIun "\n", fun->handle); 216 217 return EOK; 218 } 219 220 /*----------------------------------------------------------------------------*/ 221 222 int usb_generic_hid_init(usb_hid_dev_t *hid_dev, void **data) 223 { 224 if (hid_dev == NULL) { 225 return EINVAL; 226 } 227 228 return usb_generic_hid_create_function(hid_dev); 241 *data = fun; 242 243 return EOK; 229 244 } 230 245 -
uspace/drv/bus/usb/usbhid/generic/hiddev.h
r4c3ad56 r20a3465 41 41 struct usb_hid_dev; 42 42 43 usb_endpoint_description_t usb_hid_generic_poll_endpoint_description; 43 extern const usb_endpoint_description_t 44 usb_hid_generic_poll_endpoint_description; 44 45 45 46 const char *HID_GENERIC_FUN_NAME; … … 50 51 int usb_generic_hid_init(struct usb_hid_dev *hid_dev, void **data); 51 52 53 void usb_generic_hid_deinit(struct usb_hid_dev *hid_dev, void *data); 54 52 55 bool usb_generic_hid_polling_callback(struct usb_hid_dev *hid_dev, void *data); 53 56 -
uspace/drv/bus/usb/usbhid/kbd/conv.c
r4c3ad56 r20a3465 87 87 [0x26] = KC_9, 88 88 [0x27] = KC_0, 89 89 90 90 [0x28] = KC_ENTER, 91 91 [0x29] = KC_ESCAPE, … … 109 109 110 110 [0x39] = KC_CAPS_LOCK, 111 111 112 112 [0x3a] = KC_F1, 113 113 [0x3b] = KC_F2, … … 122 122 [0x44] = KC_F11, 123 123 [0x45] = KC_F12, 124 124 125 125 [0x46] = KC_PRTSCR, 126 126 [0x47] = KC_SCROLL_LOCK, … … 136 136 [0x51] = KC_DOWN, 137 137 [0x52] = KC_UP, 138 138 139 139 //[0x64] = // some funny key 140 140 141 141 [0xe0] = KC_LCTRL, 142 142 [0xe1] = KC_LSHIFT, … … 147 147 [0xe6] = KC_RALT, 148 148 //[0xe7] = KC_R // TODO: right GUI 149 149 150 150 [0x53] = KC_NUM_LOCK, 151 151 [0x54] = KC_NSLASH, … … 165 165 [0x62] = KC_N0, 166 166 [0x63] = KC_NPERIOD 167 167 168 168 }; 169 169 … … 186 186 187 187 key = map[scancode]; 188 188 189 189 return key; 190 190 } -
uspace/drv/bus/usb/usbhid/kbd/kbddev.c
r4c3ad56 r20a3465 88 88 89 89 /** Keyboard polling endpoint description for boot protocol class. */ 90 usb_endpoint_description_t usb_hid_kbd_poll_endpoint_description = {90 const usb_endpoint_description_t usb_hid_kbd_poll_endpoint_description = { 91 91 .transfer_type = USB_TRANSFER_INTERRUPT, 92 92 .direction = USB_DIRECTION_IN, … … 174 174 { 175 175 sysarg_t method = IPC_GET_IMETHOD(*icall); 176 176 177 177 usb_kbd_t *kbd_dev = (usb_kbd_t *) fun->driver_data; 178 178 if (kbd_dev == NULL) { … … 182 182 return; 183 183 } 184 184 185 185 async_sess_t *sess = 186 186 async_callback_receive_start(EXCHANGE_SERIALIZE, icall); … … 237 237 238 238 usb_hid_report_field_t *field = usb_hid_report_get_sibling( 239 hid_dev->report, NULL, kbd_dev->led_path,239 &hid_dev->report, NULL, kbd_dev->led_path, 240 240 USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 241 241 USB_HID_REPORT_TYPE_OUTPUT); 242 242 243 243 while (field != NULL) { 244 245 if ((field->usage == USB_HID_LED_NUM_LOCK) 244 245 if ((field->usage == USB_HID_LED_NUM_LOCK) 246 246 && (kbd_dev->mods & KM_NUM_LOCK)){ 247 247 field->value = 1; 248 248 } 249 249 250 if ((field->usage == USB_HID_LED_CAPS_LOCK) 250 if ((field->usage == USB_HID_LED_CAPS_LOCK) 251 251 && (kbd_dev->mods & KM_CAPS_LOCK)){ 252 252 field->value = 1; 253 253 } 254 254 255 if ((field->usage == USB_HID_LED_SCROLL_LOCK) 255 if ((field->usage == USB_HID_LED_SCROLL_LOCK) 256 256 && (kbd_dev->mods & KM_SCROLL_LOCK)){ 257 257 field->value = 1; 258 258 } 259 260 field = usb_hid_report_get_sibling( hid_dev->report, field,261 kbd_dev->led_path,262 USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,263 USB_HID_REPORT_TYPE_OUTPUT);264 } 265 259 260 field = usb_hid_report_get_sibling( 261 &hid_dev->report, field, kbd_dev->led_path, 262 USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 263 USB_HID_REPORT_TYPE_OUTPUT); 264 } 265 266 266 // TODO: what about the Report ID? 267 int rc = usb_hid_report_output_translate( hid_dev->report, 0,267 int rc = usb_hid_report_output_translate(&hid_dev->report, 0, 268 268 kbd_dev->output_buffer, kbd_dev->output_size); 269 269 270 270 if (rc != EOK) { 271 271 usb_log_warning("Error translating LED output to output report" … … 273 273 return; 274 274 } 275 275 276 276 usb_log_debug("Output report buffer: %s\n", 277 277 usb_debug_str_buffer(kbd_dev->output_buffer, kbd_dev->output_size, 278 278 0)); 279 279 280 280 usbhid_req_set_report(&hid_dev->usb_dev->ctrl_pipe, 281 281 hid_dev->usb_dev->interface_no, USB_HID_REPORT_TYPE_OUTPUT, … … 300 300 return; 301 301 } 302 302 303 303 async_exch_t *exch = async_exchange_begin(kbd_dev->console_sess); 304 304 async_msg_2(exch, KBDEV_EVENT, type, key); … … 347 347 unsigned int key; 348 348 size_t i; 349 349 350 350 /* 351 351 * First of all, check if the kbd have reported phantom state. … … 362 362 return; 363 363 } 364 364 365 365 /* 366 366 * Key releases … … 382 382 } 383 383 } 384 384 385 385 /* 386 386 * Key presses … … 402 402 } 403 403 } 404 404 405 405 memcpy(kbd_dev->keys_old, kbd_dev->keys, kbd_dev->key_count * 4); 406 406 407 407 char key_buffer[512]; 408 408 ddf_dump_buffer(key_buffer, 512, … … 432 432 static void usb_kbd_process_data(usb_hid_dev_t *hid_dev, usb_kbd_t *kbd_dev) 433 433 { 434 assert(hid_dev->report != NULL);435 434 assert(hid_dev != NULL); 436 435 assert(kbd_dev != NULL); 437 436 438 437 usb_hid_report_path_t *path = usb_hid_report_path(); 439 438 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0); 440 439 441 440 usb_hid_report_path_set_report_id (path, hid_dev->report_id); 442 441 443 442 // fill in the currently pressed keys 444 443 445 444 usb_hid_report_field_t *field = usb_hid_report_get_sibling( 446 hid_dev->report, NULL, path,447 USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 445 &hid_dev->report, NULL, path, 446 USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 448 447 USB_HID_REPORT_TYPE_INPUT); 449 448 unsigned i = 0; 450 449 451 450 while (field != NULL) { 452 451 usb_log_debug2("FIELD (%p) - VALUE(%d) USAGE(%u)\n", … … 454 453 455 454 assert(i < kbd_dev->key_count); 456 455 457 456 // save the key usage 458 457 if (field->value != 0) { … … 463 462 } 464 463 usb_log_debug2("Saved %u. key usage %d\n", i, kbd_dev->keys[i]); 465 464 466 465 ++i; 467 field = usb_hid_report_get_sibling( hid_dev->report, field, path,468 USB_HID_PATH_COMPARE_END469 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,466 field = usb_hid_report_get_sibling( 467 &hid_dev->report, field, path, USB_HID_PATH_COMPARE_END 468 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 470 469 USB_HID_REPORT_TYPE_INPUT); 471 470 } 472 471 473 472 usb_hid_report_path_free(path); 474 473 475 474 usb_kbd_check_key_changes(hid_dev, kbd_dev); 476 475 } … … 502 501 503 502 if (kbd_dev == NULL) { 504 usb_log_ fatal("No memory!\n");503 usb_log_error("No memory!\n"); 505 504 return NULL; 506 505 } 507 506 508 507 kbd_dev->console_sess = NULL; 509 508 kbd_dev->initialized = USB_KBD_STATUS_UNINITIALIZED; 510 509 511 510 return kbd_dev; 512 511 } … … 514 513 /*----------------------------------------------------------------------------*/ 515 514 516 static int usb_kbd_create_function(usb_hid_dev_t *hid_dev, usb_kbd_t *kbd_dev) 517 { 518 assert(hid_dev != NULL); 519 assert(hid_dev->usb_dev != NULL); 515 static int usb_kbd_create_function(usb_kbd_t *kbd_dev) 516 { 520 517 assert(kbd_dev != NULL); 521 518 assert(kbd_dev->hid_dev != NULL); 519 assert(kbd_dev->hid_dev->usb_dev != NULL); 520 522 521 /* Create the exposed function. */ 523 522 usb_log_debug("Creating DDF function %s...\n", HID_KBD_FUN_NAME); 524 ddf_fun_t *fun = ddf_fun_create( hid_dev->usb_dev->ddf_dev, fun_exposed,525 HID_KBD_FUN_NAME);523 ddf_fun_t *fun = ddf_fun_create(kbd_dev->hid_dev->usb_dev->ddf_dev, 524 fun_exposed, HID_KBD_FUN_NAME); 526 525 if (fun == NULL) { 527 526 usb_log_error("Could not create DDF function node.\n"); 528 527 return ENOMEM; 529 528 } 530 529 531 530 /* 532 531 * Store the initialized HID device and HID ops … … 540 539 usb_log_error("Could not bind DDF function: %s.\n", 541 540 str_error(rc)); 541 fun->driver_data = NULL; /* We need this later */ 542 542 ddf_fun_destroy(fun); 543 543 return rc; 544 544 } 545 545 546 546 usb_log_debug("%s function created. Handle: %" PRIun "\n", 547 547 HID_KBD_FUN_NAME, fun->handle); 548 548 549 549 usb_log_debug("Adding DDF function to category %s...\n", 550 550 HID_KBD_CLASS_NAME); … … 554 554 "Could not add DDF function to category %s: %s.\n", 555 555 HID_KBD_CLASS_NAME, str_error(rc)); 556 fun->driver_data = NULL; /* We need this later */ 556 557 ddf_fun_destroy(fun); 557 558 return rc; 558 559 } 559 560 kbd_dev->fun = fun; 561 560 562 return EOK; 561 563 } … … 587 589 { 588 590 usb_log_debug("Initializing HID/KBD structure...\n"); 589 591 590 592 if (hid_dev == NULL) { 591 593 usb_log_error("Failed to init keyboard structure: no structure" … … 593 595 return EINVAL; 594 596 } 595 597 596 598 usb_kbd_t *kbd_dev = usb_kbd_new(); 597 599 if (kbd_dev == NULL) { … … 603 605 /* Store link to HID device */ 604 606 kbd_dev->hid_dev = hid_dev; 605 607 606 608 /* 607 609 * TODO: make more general … … 609 611 usb_hid_report_path_t *path = usb_hid_report_path(); 610 612 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0); 611 613 612 614 usb_hid_report_path_set_report_id(path, 0); 613 615 614 616 kbd_dev->key_count = usb_hid_report_size( 615 hid_dev->report, 0, USB_HID_REPORT_TYPE_INPUT);617 &hid_dev->report, 0, USB_HID_REPORT_TYPE_INPUT); 616 618 usb_hid_report_path_free(path); 617 619 618 620 usb_log_debug("Size of the input report: %zu\n", kbd_dev->key_count); 619 620 kbd_dev->keys = (int32_t *)calloc(kbd_dev->key_count, sizeof(int32_t));621 621 622 kbd_dev->keys = calloc(kbd_dev->key_count, sizeof(int32_t)); 623 622 624 if (kbd_dev->keys == NULL) { 623 usb_log_ fatal("No memory!\n");625 usb_log_error("No memory!\n"); 624 626 free(kbd_dev); 625 627 return ENOMEM; 626 628 } 627 629 628 630 kbd_dev->keys_old = 629 631 (int32_t *)calloc(kbd_dev->key_count, sizeof(int32_t)); 630 632 631 633 if (kbd_dev->keys_old == NULL) { 632 usb_log_ fatal("No memory!\n");634 usb_log_error("No memory!\n"); 633 635 free(kbd_dev->keys); 634 636 free(kbd_dev); 635 637 return ENOMEM; 636 638 } 637 639 638 640 /* 639 641 * Output report 640 642 */ 641 643 kbd_dev->output_size = 0; 642 kbd_dev->output_buffer = usb_hid_report_output( hid_dev->report,644 kbd_dev->output_buffer = usb_hid_report_output(&hid_dev->report, 643 645 &kbd_dev->output_size, 0); 644 646 if (kbd_dev->output_buffer == NULL) { … … 647 649 return ENOMEM; 648 650 } 649 651 650 652 usb_log_debug("Output buffer size: %zu\n", kbd_dev->output_size); 651 653 652 654 kbd_dev->led_path = usb_hid_report_path(); 653 655 usb_hid_report_path_append_item( 654 656 kbd_dev->led_path, USB_HIDUT_PAGE_LED, 0); 655 656 kbd_dev->led_output_size = usb_hid_report_size( hid_dev->report,657 0, USB_HID_REPORT_TYPE_OUTPUT);658 657 658 kbd_dev->led_output_size = usb_hid_report_size( 659 &hid_dev->report, 0, USB_HID_REPORT_TYPE_OUTPUT); 660 659 661 usb_log_debug("Output report size (in items): %zu\n", 660 662 kbd_dev->led_output_size); 661 663 662 664 kbd_dev->led_data = (int32_t *)calloc( 663 665 kbd_dev->led_output_size, sizeof(int32_t)); 664 666 665 667 if (kbd_dev->led_data == NULL) { 666 668 usb_log_warning("Error creating buffer for LED output report." … … 671 673 return ENOMEM; 672 674 } 673 675 674 676 /* 675 677 * Modifiers and locks … … 678 680 kbd_dev->mods = DEFAULT_ACTIVE_MODS; 679 681 kbd_dev->lock_keys = 0; 680 682 681 683 /* 682 684 * Autorepeat … … 686 688 kbd_dev->repeat.delay_before = DEFAULT_DELAY_BEFORE_FIRST_REPEAT; 687 689 kbd_dev->repeat.delay_between = DEFAULT_REPEAT_DELAY; 688 689 kbd_dev->repeat_mtx = (fibril_mutex_t *)( 690 malloc(sizeof(fibril_mutex_t))); 691 if (kbd_dev->repeat_mtx == NULL) { 692 usb_log_fatal("No memory!\n"); 693 free(kbd_dev->keys); 694 usb_hid_report_output_free(kbd_dev->output_buffer); 695 free(kbd_dev); 696 return ENOMEM; 697 } 698 699 fibril_mutex_initialize(kbd_dev->repeat_mtx); 700 690 691 fibril_mutex_initialize(&kbd_dev->repeat_mtx); 692 701 693 // save the KBD device structure into the HID device structure 702 694 *data = kbd_dev; 703 695 704 696 // set handler for incoming calls 705 697 kbd_dev->ops.default_handler = default_connection_handler; 706 698 707 699 /* 708 700 * Set LEDs according to initial setup. … … 710 702 */ 711 703 usb_kbd_set_led(hid_dev, kbd_dev); 712 704 713 705 usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe, 714 706 hid_dev->usb_dev->interface_no, IDLE_RATE); 715 707 716 708 /* 717 709 * Create new fibril for auto-repeat … … 723 715 } 724 716 fibril_add_ready(fid); 725 717 726 718 kbd_dev->initialized = USB_KBD_STATUS_INITIALIZED; 727 719 usb_log_debug("HID/KBD device structure initialized.\n"); 728 720 729 721 usb_log_debug("Creating KBD function...\n"); 730 int rc = usb_kbd_create_function( hid_dev,kbd_dev);722 int rc = usb_kbd_create_function(kbd_dev); 731 723 if (rc != EOK) { 732 724 usb_kbd_destroy(kbd_dev); 733 725 return rc; 734 726 } 735 727 736 728 return EOK; 737 729 } … … 745 737 return false; 746 738 } 747 739 748 740 usb_kbd_t *kbd_dev = (usb_kbd_t *)data; 749 741 assert(kbd_dev != NULL); 750 742 751 743 // TODO: add return value from this function 752 744 usb_kbd_process_data(hid_dev, kbd_dev); 753 745 754 746 return true; 755 747 } … … 780 772 return; 781 773 } 782 774 783 775 // hangup session to the console 784 776 async_hangup(kbd_dev->console_sess); 785 786 if (kbd_dev->repeat_mtx != NULL) { 787 //assert(!fibril_mutex_is_locked((*kbd_dev)->repeat_mtx)); 788 // FIXME - the fibril_mutex_is_locked may not cause 789 // fibril scheduling 790 while (fibril_mutex_is_locked(kbd_dev->repeat_mtx)) {} 791 free(kbd_dev->repeat_mtx); 792 } 793 777 778 //assert(!fibril_mutex_is_locked((*kbd_dev)->repeat_mtx)); 779 // FIXME - the fibril_mutex_is_locked may not cause 780 // fibril scheduling 781 while (fibril_mutex_is_locked(&kbd_dev->repeat_mtx)) {} 782 794 783 // free all buffers 795 if (kbd_dev->keys != NULL) { 796 free(kbd_dev->keys); 797 } 798 if (kbd_dev->keys_old != NULL) { 799 free(kbd_dev->keys_old); 800 } 801 if (kbd_dev->led_data != NULL) { 802 free(kbd_dev->led_data); 803 } 784 free(kbd_dev->keys); 785 free(kbd_dev->keys_old); 786 free(kbd_dev->led_data); 787 804 788 if (kbd_dev->led_path != NULL) { 805 789 usb_hid_report_path_free(kbd_dev->led_path); … … 808 792 usb_hid_report_output_free(kbd_dev->output_buffer); 809 793 } 794 795 if (ddf_fun_unbind(kbd_dev->fun) != EOK) { 796 usb_log_warning("Failed to unbind kbd function.\n"); 797 } else { 798 usb_log_debug2("%s unbound.\n", kbd_dev->fun->name); 799 kbd_dev->fun->driver_data = NULL; 800 ddf_fun_destroy(kbd_dev->fun); 801 } 810 802 } 811 803 … … 817 809 return; 818 810 } 819 811 820 812 if (data != NULL) { 821 usb_kbd_t *kbd_dev = (usb_kbd_t *)data;813 usb_kbd_t *kbd_dev = data; 822 814 if (usb_kbd_is_initialized(kbd_dev)) { 823 815 usb_kbd_mark_unusable(kbd_dev); 824 } else { 816 /* wait for autorepeat */ 817 async_usleep(CHECK_DELAY); 825 818 usb_kbd_destroy(kbd_dev); 826 819 } … … 832 825 int usb_kbd_set_boot_protocol(usb_hid_dev_t *hid_dev) 833 826 { 834 int rc = usb_hid_parse_report_descriptor( hid_dev->report,835 USB_KBD_BOOT_REPORT_DESCRIPTOR,827 int rc = usb_hid_parse_report_descriptor( 828 &hid_dev->report, USB_KBD_BOOT_REPORT_DESCRIPTOR, 836 829 USB_KBD_BOOT_REPORT_DESCRIPTOR_SIZE); 837 830 838 831 if (rc != EOK) { 839 832 usb_log_error("Failed to parse boot report descriptor: %s\n", … … 841 834 return rc; 842 835 } 843 844 rc = usbhid_req_set_protocol(&hid_dev->usb_dev->ctrl_pipe, 836 837 rc = usbhid_req_set_protocol(&hid_dev->usb_dev->ctrl_pipe, 845 838 hid_dev->usb_dev->interface_no, USB_HID_PROTOCOL_BOOT); 846 839 847 840 if (rc != EOK) { 848 841 usb_log_warning("Failed to set boot protocol to the device: " … … 850 843 return rc; 851 844 } 852 845 853 846 return EOK; 854 847 } -
uspace/drv/bus/usb/usbhid/kbd/kbddev.h
r4c3ad56 r20a3465 75 75 /** Currently pressed modifiers (bitmap). */ 76 76 uint8_t modifiers; 77 77 78 78 /** Currently active modifiers including locks. Sent to the console. */ 79 79 unsigned mods; 80 80 81 81 /** Currently active lock keys. */ 82 82 unsigned lock_keys; 83 83 84 84 /** IPC session to the console device (for sending key events). */ 85 85 async_sess_t *console_sess; 86 86 87 87 /** @todo What is this actually? */ 88 88 ddf_dev_ops_t ops; 89 89 90 90 /** Information for auto-repeat of keys. */ 91 91 usb_kbd_repeat_t repeat; 92 92 93 93 /** Mutex for accessing the information about auto-repeat. */ 94 fibril_mutex_t *repeat_mtx;95 94 fibril_mutex_t repeat_mtx; 95 96 96 uint8_t *output_buffer; 97 97 98 98 size_t output_size; 99 99 100 100 size_t led_output_size; 101 101 102 102 usb_hid_report_path_t *led_path; 103 103 104 104 int32_t *led_data; 105 105 106 106 /** State of the structure (for checking before use). 107 107 * … … 111 111 */ 112 112 int initialized; 113 114 /** DDF function */ 115 ddf_fun_t *fun; 113 116 } usb_kbd_t; 114 117 115 118 /*----------------------------------------------------------------------------*/ 116 119 117 usb_endpoint_description_t usb_hid_kbd_poll_endpoint_description;120 extern const usb_endpoint_description_t usb_hid_kbd_poll_endpoint_description; 118 121 119 122 const char *HID_KBD_FUN_NAME; -
uspace/drv/bus/usb/usbhid/kbd/kbdrepeat.c
r4c3ad56 r20a3465 46 46 47 47 48 /** Delay between auto-repeat state checks when no key is being repeated. */49 static unsigned int CHECK_DELAY = 10000;50 48 51 49 /*----------------------------------------------------------------------------*/ … … 73 71 { 74 72 unsigned int delay = 0; 75 73 76 74 usb_log_debug("Starting autorepeat loop.\n"); 77 75 … … 79 77 // check if the kbd structure is usable 80 78 if (!usb_kbd_is_initialized(kbd)) { 81 if (usb_kbd_is_ready_to_destroy(kbd)) { 82 usb_kbd_destroy(kbd); 83 } 79 usb_log_warning("kbd not ready, exiting autorepeat.\n"); 84 80 return; 85 81 } 86 82 87 fibril_mutex_lock( kbd->repeat_mtx);83 fibril_mutex_lock(&kbd->repeat_mtx); 88 84 89 85 if (kbd->repeat.key_new > 0) { … … 109 105 delay = CHECK_DELAY; 110 106 } 111 fibril_mutex_unlock( kbd->repeat_mtx);107 fibril_mutex_unlock(&kbd->repeat_mtx); 112 108 113 109 async_usleep(delay); … … 130 126 { 131 127 usb_log_debug("Autorepeat fibril spawned.\n"); 132 128 133 129 if (arg == NULL) { 134 130 usb_log_error("No device!\n"); 135 131 return EINVAL; 136 132 } 137 133 138 134 usb_kbd_t *kbd = (usb_kbd_t *)arg; 139 135 140 136 usb_kbd_repeat_loop(kbd); 141 137 142 138 return EOK; 143 139 } … … 156 152 void usb_kbd_repeat_start(usb_kbd_t *kbd, unsigned int key) 157 153 { 158 fibril_mutex_lock( kbd->repeat_mtx);154 fibril_mutex_lock(&kbd->repeat_mtx); 159 155 kbd->repeat.key_new = key; 160 fibril_mutex_unlock( kbd->repeat_mtx);156 fibril_mutex_unlock(&kbd->repeat_mtx); 161 157 } 162 158 … … 174 170 void usb_kbd_repeat_stop(usb_kbd_t *kbd, unsigned int key) 175 171 { 176 fibril_mutex_lock( kbd->repeat_mtx);172 fibril_mutex_lock(&kbd->repeat_mtx); 177 173 if (key == kbd->repeat.key_new) { 178 174 kbd->repeat.key_new = 0; 179 175 } 180 fibril_mutex_unlock( kbd->repeat_mtx);176 fibril_mutex_unlock(&kbd->repeat_mtx); 181 177 } 182 178 -
uspace/drv/bus/usb/usbhid/kbd/kbdrepeat.h
r4c3ad56 r20a3465 37 37 #define USB_HID_KBDREPEAT_H_ 38 38 39 /** Delay between auto-repeat state checks when no key is being repeated. */ 40 #define CHECK_DELAY 10000 41 39 42 struct usb_kbd_t; 40 43 -
uspace/drv/bus/usb/usbhid/main.c
r4c3ad56 r20a3465 46 46 #include "usbhid.h" 47 47 48 /*----------------------------------------------------------------------------*/49 50 48 #define NAME "usbhid" 51 49 … … 67 65 * 68 66 * @param dev Device to add. 69 * 70 * @retval EOK if successful. 71 * @retval ENOMEM if there 72 * @return Other error code inherited from one of functions usb_kbd_init(), 73 * ddf_fun_bind() and ddf_fun_add_to_class(). 67 * @return Error code. 74 68 */ 75 69 static int usb_hid_try_add_device(usb_device_t *dev) 76 70 { 77 71 assert(dev != NULL); 78 79 /* 80 * Initialize device (get and process descriptors, get address, etc.) 81 */ 72 73 /* Initialize device (get and process descriptors, get address, etc.) */ 82 74 usb_log_debug("Initializing USB/HID device...\n"); 83 84 usb_hid_dev_t *hid_dev = usb_hid_new(); 75 76 usb_hid_dev_t *hid_dev = 77 usb_device_data_alloc(dev, sizeof(usb_hid_dev_t)); 85 78 if (hid_dev == NULL) { 86 79 usb_log_error("Error while creating USB/HID device " … … 88 81 return ENOMEM; 89 82 } 90 83 91 84 int rc = usb_hid_init(hid_dev, dev); 92 85 93 86 if (rc != EOK) { 94 87 usb_log_error("Failed to initialize USB/HID device.\n"); 95 usb_hid_de stroy(hid_dev);88 usb_hid_deinit(hid_dev); 96 89 return rc; 97 } 98 90 } 91 99 92 usb_log_debug("USB/HID device structure initialized.\n"); 100 93 101 94 /* 102 95 * 1) subdriver vytvori vlastnu ddf_fun, vlastne ddf_dev_ops, ktore da … … 109 102 * pouzit usb/classes/hid/iface.h - prvy int je telefon 110 103 */ 111 104 112 105 /* Start automated polling function. 113 106 * This will create a separate fibril that will query the device … … 125 118 /* Custom argument. */ 126 119 hid_dev); 127 128 120 129 121 if (rc != EOK) { 130 122 usb_log_error("Failed to start polling fibril for `%s'.\n", 131 123 dev->ddf_dev->name); 124 usb_hid_deinit(hid_dev); 132 125 return rc; 133 126 } 127 hid_dev->running = true; 134 128 135 129 /* … … 138 132 return EOK; 139 133 } 140 141 134 /*----------------------------------------------------------------------------*/ 142 135 /** … … 146 139 * 147 140 * @param dev Structure representing the new device. 148 * 149 * @retval EOK if successful. 150 * @retval EREFUSED if the device is not supported. 141 * @return Error code. 151 142 */ 152 143 static int usb_hid_device_add(usb_device_t *dev) 153 144 { 154 145 usb_log_debug("usb_hid_device_add()\n"); 155 146 156 147 if (dev == NULL) { 157 148 usb_log_warning("Wrong parameter given for add_device().\n"); 158 149 return EINVAL; 159 150 } 160 151 161 152 if (dev->interface_no < 0) { 162 153 usb_log_warning("Device is not a supported HID device.\n"); … … 165 156 return ENOTSUP; 166 157 } 167 158 168 159 int rc = usb_hid_try_add_device(dev); 169 160 170 161 if (rc != EOK) { 171 162 usb_log_warning("Device is not a supported HID device.\n"); … … 174 165 return rc; 175 166 } 176 167 177 168 usb_log_info("HID device `%s' ready to use.\n", dev->ddf_dev->name); 178 169 179 170 return EOK; 180 171 } 181 182 /*----------------------------------------------------------------------------*/ 183 184 /* Currently, the framework supports only device adding. Once the framework 185 * supports unplug, more callbacks will be added. */ 186 static usb_driver_ops_t usb_hid_driver_ops = { 187 .device_add = usb_hid_device_add, 172 /*----------------------------------------------------------------------------*/ 173 /** 174 * Callback for a device about to be removed from the driver. 175 * 176 * @param dev Structure representing the device. 177 * @return Error code. 178 */ 179 static int usb_hid_device_rem(usb_device_t *dev) 180 { 181 return EOK; 182 } 183 /*----------------------------------------------------------------------------*/ 184 /** 185 * Callback for removing a device from the driver. 186 * 187 * @param dev Structure representing the device. 188 * @return Error code. 189 */ 190 static int usb_hid_device_gone(usb_device_t *dev) 191 { 192 usb_hid_dev_t *hid_dev = dev->driver_data; 193 unsigned tries = 10; 194 while (hid_dev->running) { 195 async_usleep(100000); 196 if (!tries--) { 197 usb_log_error("Can't remove hub, still running.\n"); 198 return EBUSY; 199 } 200 } 201 202 assert(!hid_dev->running); 203 usb_hid_deinit(hid_dev); 204 usb_log_debug2("%s destruction complete.\n", dev->ddf_dev->name); 205 return EOK; 206 } 207 /*----------------------------------------------------------------------------*/ 208 /** USB generic driver callbacks */ 209 static const usb_driver_ops_t usb_hid_driver_ops = { 210 .device_add = usb_hid_device_add, 211 .device_rem = usb_hid_device_rem, 212 .device_gone = usb_hid_device_gone, 188 213 }; 189 190 191 /* The driver itself. */ 192 static usb_driver_t usb_hid_driver = { 214 /*----------------------------------------------------------------------------*/ 215 /** The driver itself. */ 216 static const usb_driver_t usb_hid_driver = { 193 217 .name = NAME, 194 218 .ops = &usb_hid_driver_ops, 195 219 .endpoints = usb_hid_endpoints 196 220 }; 197 198 /*----------------------------------------------------------------------------*/ 199 221 /*----------------------------------------------------------------------------*/ 200 222 int main(int argc, char *argv[]) 201 223 { … … 206 228 return usb_driver_main(&usb_hid_driver); 207 229 } 208 209 230 /** 210 231 * @} -
uspace/drv/bus/usb/usbhid/mouse/mousedev.c
r4c3ad56 r20a3465 59 59 /*----------------------------------------------------------------------------*/ 60 60 61 usb_endpoint_description_t usb_hid_mouse_poll_endpoint_description = {61 const usb_endpoint_description_t usb_hid_mouse_poll_endpoint_description = { 62 62 .transfer_type = USB_TRANSFER_INTERRUPT, 63 63 .direction = USB_DIRECTION_IN, … … 124 124 { 125 125 usb_mouse_t *mouse_dev = (usb_mouse_t *) fun->driver_data; 126 126 127 127 if (mouse_dev == NULL) { 128 128 usb_log_debug("default_connection_handler: Missing " … … 131 131 return; 132 132 } 133 133 134 134 usb_log_debug("default_connection_handler: fun->name: %s\n", 135 135 fun->name); 136 136 usb_log_debug("default_connection_handler: mouse_sess: %p, " 137 137 "wheel_sess: %p\n", mouse_dev->mouse_sess, mouse_dev->wheel_sess); 138 138 139 139 async_sess_t **sess_ptr = 140 140 (str_cmp(fun->name, HID_MOUSE_FUN_NAME) == 0) ? 141 141 &mouse_dev->mouse_sess : &mouse_dev->wheel_sess; 142 142 143 143 async_sess_t *sess = 144 144 async_callback_receive_start(EXCHANGE_SERIALIZE, icall); … … 170 170 mouse->mouse_sess = NULL; 171 171 mouse->wheel_sess = NULL; 172 172 173 173 return mouse; 174 174 } … … 179 179 { 180 180 assert(mouse_dev != NULL); 181 181 182 182 // hangup session to the console 183 183 if (mouse_dev->mouse_sess != NULL) 184 184 async_hangup(mouse_dev->mouse_sess); 185 185 186 186 if (mouse_dev->wheel_sess != NULL) 187 187 async_hangup(mouse_dev->wheel_sess); 188 int ret = ddf_fun_unbind(mouse_dev->mouse_fun); 189 if (ret != EOK) { 190 usb_log_error("Failed to unbind mouse function.\n"); 191 } else { 192 ddf_fun_destroy(mouse_dev->mouse_fun); 193 /* Prevent double free */ 194 mouse_dev->wheel_fun->driver_data = NULL; 195 } 196 197 ret = ddf_fun_unbind(mouse_dev->wheel_fun); 198 if (ret != EOK) { 199 usb_log_error("Failed to unbind wheel function.\n"); 200 } else { 201 ddf_fun_destroy(mouse_dev->wheel_fun); 202 } 188 203 } 189 204 … … 199 214 return; 200 215 } 201 216 202 217 int count = ((wheel < 0) ? -wheel : wheel) * ARROWS_PER_SINGLE_WHEEL; 203 218 int i; 204 219 205 220 for (i = 0; i < count; i++) { 206 221 /* Send arrow press and release. */ … … 246 261 { 247 262 assert(mouse_dev != NULL); 248 263 249 264 if (mouse_dev->mouse_sess == NULL) { 250 265 usb_log_warning(NAME " No console session.\n"); … … 253 268 254 269 int shift_x = get_mouse_axis_move_value(hid_dev->report_id, 255 hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_X);270 &hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_X); 256 271 int shift_y = get_mouse_axis_move_value(hid_dev->report_id, 257 hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_Y);272 &hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_Y); 258 273 int wheel = get_mouse_axis_move_value(hid_dev->report_id, 259 hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_WHEEL);274 &hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_WHEEL); 260 275 261 276 if ((shift_x != 0) || (shift_y != 0)) { 262 async_exch_t *exch = async_exchange_begin(mouse_dev->mouse_sess); 277 async_exch_t *exch = 278 async_exchange_begin(mouse_dev->mouse_sess); 263 279 async_req_2_0(exch, MOUSEEV_MOVE_EVENT, shift_x, shift_y); 264 280 async_exchange_end(exch); 265 281 } 266 282 267 283 if (wheel != 0) 268 284 usb_mouse_send_wheel(mouse_dev, wheel); 269 285 270 286 /* 271 287 * Buttons … … 274 290 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_BUTTON, 0); 275 291 usb_hid_report_path_set_report_id(path, hid_dev->report_id); 276 292 277 293 usb_hid_report_field_t *field = usb_hid_report_get_sibling( 278 hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END 279 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 280 USB_HID_REPORT_TYPE_INPUT); 294 &hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END 295 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, USB_HID_REPORT_TYPE_INPUT); 281 296 282 297 while (field != NULL) { … … 299 314 async_req_2_0(exch, MOUSEEV_BUTTON_EVENT, field->usage, 0); 300 315 async_exchange_end(exch); 301 316 302 317 mouse_dev->buttons[field->usage - field->usage_minimum] = 303 318 field->value; 304 319 } 305 320 306 321 field = usb_hid_report_get_sibling( 307 hid_dev->report, field, path, USB_HID_PATH_COMPARE_END308 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 322 &hid_dev->report, field, path, USB_HID_PATH_COMPARE_END 323 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 309 324 USB_HID_REPORT_TYPE_INPUT); 310 325 } 311 326 312 327 usb_hid_report_path_free(path); 313 328 … … 321 336 assert(hid_dev != NULL); 322 337 assert(mouse != NULL); 323 338 324 339 /* Create the exposed function. */ 325 340 usb_log_debug("Creating DDF function %s...\n", HID_MOUSE_FUN_NAME); … … 330 345 return ENOMEM; 331 346 } 332 347 333 348 fun->ops = &mouse->ops; 334 349 fun->driver_data = mouse; … … 338 353 usb_log_error("Could not bind DDF function: %s.\n", 339 354 str_error(rc)); 340 ddf_fun_destroy(fun); 341 return rc; 342 } 343 355 return rc; 356 } 357 344 358 usb_log_debug("Adding DDF function to category %s...\n", 345 359 HID_MOUSE_CATEGORY); … … 349 363 "Could not add DDF function to category %s: %s.\n", 350 364 HID_MOUSE_CATEGORY, str_error(rc)); 351 ddf_fun_destroy(fun);352 return rc;353 }354 365 return rc; 366 } 367 mouse->mouse_fun = fun; 368 355 369 /* 356 370 * Special function for acting as keyboard (wheel) … … 364 378 return ENOMEM; 365 379 } 366 380 367 381 /* 368 382 * Store the initialized HID device and HID ops … … 376 390 usb_log_error("Could not bind DDF function: %s.\n", 377 391 str_error(rc)); 378 ddf_fun_destroy(fun); 379 return rc; 380 } 381 392 return rc; 393 } 394 382 395 usb_log_debug("Adding DDF function to category %s...\n", 383 396 HID_MOUSE_WHEEL_CATEGORY); … … 387 400 "Could not add DDF function to category %s: %s.\n", 388 401 HID_MOUSE_WHEEL_CATEGORY, str_error(rc)); 389 ddf_fun_destroy(fun);390 return rc;391 }392 402 return rc; 403 } 404 mouse->wheel_fun = fun; 405 393 406 return EOK; 394 407 } … … 441 454 { 442 455 usb_log_debug("Initializing HID/Mouse structure...\n"); 443 456 444 457 if (hid_dev == NULL) { 445 458 usb_log_error("Failed to init keyboard structure: no structure" … … 447 460 return EINVAL; 448 461 } 449 462 450 463 usb_mouse_t *mouse_dev = usb_mouse_new(); 451 464 if (mouse_dev == NULL) { … … 454 467 return ENOMEM; 455 468 } 456 469 457 470 // FIXME: This may not be optimal since stupid hardware vendor may 458 471 // use buttons 1, 2, 3 and 6000 and we would allocate array of … … 461 474 // that the current solution is good enough. 462 475 /* Adding 1 because we will be accessing buttons[highest]. */ 463 mouse_dev->buttons_count = usb_mouse_get_highest_button(hid_dev->report,464 hid_dev->report_id) + 1;476 mouse_dev->buttons_count = 1 + usb_mouse_get_highest_button( 477 &hid_dev->report, hid_dev->report_id); 465 478 mouse_dev->buttons = calloc(mouse_dev->buttons_count, sizeof(int32_t)); 466 479 467 480 if (mouse_dev->buttons == NULL) { 468 481 usb_log_error(NAME ": out of memory, giving up on device!\n"); … … 474 487 // save the Mouse device structure into the HID device structure 475 488 *data = mouse_dev; 476 489 477 490 // set handler for incoming calls 478 491 mouse_dev->ops.default_handler = default_connection_handler; 479 492 480 493 // TODO: how to know if the device supports the request??? 481 494 usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe, 482 495 hid_dev->usb_dev->interface_no, IDLE_RATE); 483 496 484 497 int rc = usb_mouse_create_function(hid_dev, mouse_dev); 485 498 if (rc != EOK) { … … 487 500 return rc; 488 501 } 489 502 490 503 return EOK; 491 504 } … … 500 513 return false; 501 514 } 502 515 503 516 usb_mouse_t *mouse_dev = (usb_mouse_t *)data; 504 517 … … 511 524 { 512 525 if (data != NULL) { 513 usb_mouse_destroy( (usb_mouse_t *)data);526 usb_mouse_destroy(data); 514 527 } 515 528 } … … 519 532 int usb_mouse_set_boot_protocol(usb_hid_dev_t *hid_dev) 520 533 { 521 int rc = usb_hid_parse_report_descriptor( hid_dev->report,522 USB_MOUSE_BOOT_REPORT_DESCRIPTOR,534 int rc = usb_hid_parse_report_descriptor( 535 &hid_dev->report, USB_MOUSE_BOOT_REPORT_DESCRIPTOR, 523 536 USB_MOUSE_BOOT_REPORT_DESCRIPTOR_SIZE); 524 537 525 538 if (rc != EOK) { 526 539 usb_log_error("Failed to parse boot report descriptor: %s\n", … … 528 541 return rc; 529 542 } 530 531 rc = usbhid_req_set_protocol(&hid_dev->usb_dev->ctrl_pipe, 543 544 rc = usbhid_req_set_protocol(&hid_dev->usb_dev->ctrl_pipe, 532 545 hid_dev->usb_dev->interface_no, USB_HID_PROTOCOL_BOOT); 533 546 534 547 if (rc != EOK) { 535 548 usb_log_warning("Failed to set boot protocol to the device: " … … 537 550 return rc; 538 551 } 539 552 540 553 return EOK; 541 554 } -
uspace/drv/bus/usb/usbhid/mouse/mousedev.h
r4c3ad56 r20a3465 49 49 async_sess_t *mouse_sess; 50 50 async_sess_t *wheel_sess; 51 51 52 52 /* Mouse buttons statuses. */ 53 53 int32_t *buttons; 54 54 size_t buttons_count; 55 55 56 56 ddf_dev_ops_t ops; 57 /* DDF mouse function */ 58 ddf_fun_t *mouse_fun; 59 /* DDF mouse function */ 60 ddf_fun_t *wheel_fun; 57 61 } usb_mouse_t; 58 62 59 63 /*----------------------------------------------------------------------------*/ 60 64 61 usb_endpoint_description_t usb_hid_mouse_poll_endpoint_description;65 extern const usb_endpoint_description_t usb_hid_mouse_poll_endpoint_description; 62 66 63 67 const char *HID_MOUSE_FUN_NAME; -
uspace/drv/bus/usb/usbhid/multimedia/multimedia.c
r4c3ad56 r20a3465 64 64 //int32_t *keys; 65 65 /** Count of stored keys (i.e. number of keys in the report). */ 66 //size_t key_count; 66 //size_t key_count; 67 67 /** IPC session to the console device (for sending key events). */ 68 68 async_sess_t *console_sess; 69 /** DDF function */ 70 ddf_fun_t *fun; 69 71 } usb_multimedia_t; 70 72 … … 86 88 { 87 89 usb_log_debug(NAME " default_connection_handler()\n"); 88 90 89 91 usb_multimedia_t *multim_dev = (usb_multimedia_t *)fun->driver_data; 90 92 91 93 if (multim_dev == NULL) { 92 94 async_answer_0(icallid, EINVAL); 93 95 return; 94 96 } 95 97 96 98 async_sess_t *sess = 97 99 async_callback_receive_start(EXCHANGE_SERIALIZE, icall); … … 137 139 assert(hid_dev != NULL); 138 140 assert(multim_dev != NULL); 139 141 140 142 kbd_event_t ev; 141 143 142 144 ev.type = type; 143 145 ev.key = key; … … 151 153 return; 152 154 } 153 155 154 156 async_exch_t *exch = async_exchange_begin(multim_dev->console_sess); 155 157 async_msg_4(exch, KBDEV_EVENT, ev.type, ev.key, ev.mods, ev.c); … … 159 161 /*----------------------------------------------------------------------------*/ 160 162 161 static int usb_multimedia_create_function(usb_hid_dev_t *hid_dev, 162 usb_multimedia_t *multim_dev) 163 { 163 int usb_multimedia_init(struct usb_hid_dev *hid_dev, void **data) 164 { 165 if (hid_dev == NULL || hid_dev->usb_dev == NULL) { 166 return EINVAL; /*! @todo Other return code? */ 167 } 168 169 usb_log_debug(NAME " Initializing HID/multimedia structure...\n"); 170 164 171 /* Create the exposed function. */ 165 ddf_fun_t *fun = ddf_fun_create( hid_dev->usb_dev->ddf_dev, fun_exposed,166 NAME);172 ddf_fun_t *fun = ddf_fun_create( 173 hid_dev->usb_dev->ddf_dev, fun_exposed, NAME); 167 174 if (fun == NULL) { 168 175 usb_log_error("Could not create DDF function node.\n"); 169 176 return ENOMEM; 170 177 } 171 178 172 179 fun->ops = &multimedia_ops; 173 fun->driver_data = multim_dev; // TODO: maybe change to hid_dev->data 174 180 181 usb_multimedia_t *multim_dev = 182 ddf_fun_data_alloc(fun, sizeof(usb_multimedia_t)); 183 if (multim_dev == NULL) { 184 ddf_fun_destroy(fun); 185 return ENOMEM; 186 } 187 188 multim_dev->console_sess = NULL; 189 multim_dev->fun = fun; 190 191 //todo Autorepeat? 192 175 193 int rc = ddf_fun_bind(fun); 176 194 if (rc != EOK) { 177 195 usb_log_error("Could not bind DDF function: %s.\n", 178 196 str_error(rc)); 179 // TODO: Can / should I destroy the DDF function?180 197 ddf_fun_destroy(fun); 181 198 return rc; 182 199 } 183 200 184 201 usb_log_debug("%s function created (handle: %" PRIun ").\n", 185 202 NAME, fun->handle); 186 203 187 204 rc = ddf_fun_add_to_category(fun, "keyboard"); 188 205 if (rc != EOK) { … … 190 207 "Could not add DDF function to category 'keyboard': %s.\n", 191 208 str_error(rc)); 192 // TODO: Can / should I destroy the DDF function?193 209 ddf_fun_destroy(fun); 194 210 return rc; 195 211 } 196 197 return EOK; 198 } 199 200 /*----------------------------------------------------------------------------*/ 201 202 int usb_multimedia_init(struct usb_hid_dev *hid_dev, void **data) 203 { 204 if (hid_dev == NULL || hid_dev->usb_dev == NULL) { 205 return EINVAL; /*! @todo Other return code? */ 206 } 207 208 usb_log_debug(NAME " Initializing HID/multimedia structure...\n"); 209 210 usb_multimedia_t *multim_dev = (usb_multimedia_t *)malloc( 211 sizeof(usb_multimedia_t)); 212 if (multim_dev == NULL) { 213 return ENOMEM; 214 } 215 216 multim_dev->console_sess = NULL; 217 218 /*! @todo Autorepeat */ 219 220 // save the KBD device structure into the HID device structure 212 213 /* Save the KBD device structure into the HID device structure. */ 221 214 *data = multim_dev; 222 223 usb_log_debug(NAME " HID/multimedia device structure initialized.\n"); 224 225 int rc = usb_multimedia_create_function(hid_dev, multim_dev); 226 if (rc != EOK) 227 return rc; 228 215 229 216 usb_log_debug(NAME " HID/multimedia structure initialized.\n"); 230 231 217 return EOK; 232 218 } … … 239 225 return; 240 226 } 241 227 242 228 if (data != NULL) { 243 229 usb_multimedia_t *multim_dev = (usb_multimedia_t *)data; 244 230 // hangup session to the console 245 231 async_hangup(multim_dev->console_sess); 232 const int ret = ddf_fun_unbind(multim_dev->fun); 233 if (ret != EOK) { 234 usb_log_error("Failed to unbind multim function.\n"); 235 } else { 236 usb_log_debug2("%s unbound.\n", multim_dev->fun->name); 237 ddf_fun_destroy(multim_dev->fun); 238 } 246 239 } 247 240 } … … 257 250 258 251 usb_multimedia_t *multim_dev = (usb_multimedia_t *)data; 259 252 260 253 usb_hid_report_path_t *path = usb_hid_report_path(); 261 254 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_CONSUMER, 0); … … 264 257 265 258 usb_hid_report_field_t *field = usb_hid_report_get_sibling( 266 hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END267 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 259 &hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END 260 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 268 261 USB_HID_REPORT_TYPE_INPUT); 269 262 … … 283 276 key); 284 277 } 285 278 286 279 field = usb_hid_report_get_sibling( 287 hid_dev->report, field, path, USB_HID_PATH_COMPARE_END280 &hid_dev->report, field, path, USB_HID_PATH_COMPARE_END 288 281 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 289 282 USB_HID_REPORT_TYPE_INPUT); 290 } 283 } 291 284 292 285 usb_hid_report_path_free(path); 293 286 294 287 return true; 295 288 } -
uspace/drv/bus/usb/usbhid/subdrivers.c
r4c3ad56 r20a3465 42 42 #include "generic/hiddev.h" 43 43 44 static usb_hid_subdriver_usage_t path_kbd[] = {45 {USB_HIDUT_PAGE_GENERIC_DESKTOP, 46 USB_HIDUT_USAGE_GENERIC_DESKTOP_KEYBOARD}, 44 static const usb_hid_subdriver_usage_t path_kbd[] = { 45 {USB_HIDUT_PAGE_GENERIC_DESKTOP, 46 USB_HIDUT_USAGE_GENERIC_DESKTOP_KEYBOARD}, 47 47 {0, 0} 48 48 }; 49 49 50 static usb_hid_subdriver_usage_t path_mouse[] = {50 static const usb_hid_subdriver_usage_t path_mouse[] = { 51 51 {USB_HIDUT_PAGE_GENERIC_DESKTOP, USB_HIDUT_USAGE_GENERIC_DESKTOP_MOUSE}, 52 52 {0, 0} 53 53 }; 54 54 55 static usb_hid_subdriver_usage_t multim_key_path[] = {55 static const usb_hid_subdriver_usage_t multim_key_path[] = { 56 56 {USB_HIDUT_PAGE_CONSUMER, USB_HIDUT_USAGE_CONSUMER_CONSUMER_CONTROL}, 57 57 {0, 0} … … 71 71 .poll_end = NULL 72 72 }, 73 74 73 }, 75 74 { … … 102 101 }; 103 102 103 const int USB_HID_MAX_SUBDRIVERS = 104 sizeof(usb_hid_subdrivers) / sizeof(usb_hid_subdrivers[0]); 105 104 106 /** 105 107 * @} -
uspace/drv/bus/usb/usbhid/subdrivers.h
r4c3ad56 r20a3465 64 64 */ 65 65 const usb_hid_subdriver_usage_t *usage_path; 66 66 67 67 /** Report ID for which the path should apply. */ 68 68 int report_id; 69 69 70 70 /** Compare type for the Usage path. */ 71 71 int compare; 72 72 73 73 /** Vendor ID (set to -1 if not specified). */ 74 74 int vendor_id; 75 75 76 76 /** Product ID (set to -1 if not specified). */ 77 77 int product_id; 78 78 79 79 /** Subdriver for controlling this device. */ 80 usb_hid_subdriver_t subdriver;80 const usb_hid_subdriver_t subdriver; 81 81 } usb_hid_subdriver_mapping_t; 82 82 … … 84 84 85 85 extern const usb_hid_subdriver_mapping_t usb_hid_subdrivers[]; 86 extern const int USB_HID_MAX_SUBDRIVERS; 86 87 87 88 /*----------------------------------------------------------------------------*/ -
uspace/drv/bus/usb/usbhid/usbhid.c
r4c3ad56 r20a3465 54 54 55 55 /* Array of endpoints expected on the device, NULL terminated. */ 56 usb_endpoint_description_t *usb_hid_endpoints[USB_HID_POLL_EP_COUNT + 1] = {56 const usb_endpoint_description_t *usb_hid_endpoints[] = { 57 57 &usb_hid_kbd_poll_endpoint_description, 58 58 &usb_hid_mouse_poll_endpoint_description, … … 61 61 }; 62 62 63 static const int USB_HID_MAX_SUBDRIVERS = 10;64 65 63 /*----------------------------------------------------------------------------*/ 66 64 67 65 static int usb_hid_set_boot_kbd_subdriver(usb_hid_dev_t *hid_dev) 68 66 { 69 assert(hid_dev != NULL && hid_dev->subdriver_count == 0);70 71 hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc( 72 sizeof(usb_hid_subdriver_t));67 assert(hid_dev != NULL); 68 assert(hid_dev->subdriver_count == 0); 69 70 hid_dev->subdrivers = malloc(sizeof(usb_hid_subdriver_t)); 73 71 if (hid_dev->subdrivers == NULL) { 74 72 return ENOMEM; 75 73 } 76 77 assert(hid_dev->subdriver_count >= 0); 78 79 // set the init callback 80 hid_dev->subdrivers[hid_dev->subdriver_count].init = usb_kbd_init; 81 82 // set the polling callback 83 hid_dev->subdrivers[hid_dev->subdriver_count].poll = 84 usb_kbd_polling_callback; 85 86 // set the polling ended callback 87 hid_dev->subdrivers[hid_dev->subdriver_count].poll_end = NULL; 88 89 // set the deinit callback 90 hid_dev->subdrivers[hid_dev->subdriver_count].deinit = usb_kbd_deinit; 91 92 // set subdriver count 93 ++hid_dev->subdriver_count; 94 74 hid_dev->subdriver_count = 1; 75 // TODO 0 should be keyboard, but find a better way 76 hid_dev->subdrivers[0] = usb_hid_subdrivers[0].subdriver; 77 95 78 return EOK; 96 79 } … … 100 83 static int usb_hid_set_boot_mouse_subdriver(usb_hid_dev_t *hid_dev) 101 84 { 102 assert(hid_dev != NULL && hid_dev->subdriver_count == 0);103 104 hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc( 105 sizeof(usb_hid_subdriver_t));85 assert(hid_dev != NULL); 86 assert(hid_dev->subdriver_count == 0); 87 88 hid_dev->subdrivers = malloc(sizeof(usb_hid_subdriver_t)); 106 89 if (hid_dev->subdrivers == NULL) { 107 90 return ENOMEM; 108 91 } 109 110 assert(hid_dev->subdriver_count >= 0); 111 112 // set the init callback 113 hid_dev->subdrivers[hid_dev->subdriver_count].init = usb_mouse_init; 114 115 // set the polling callback 116 hid_dev->subdrivers[hid_dev->subdriver_count].poll = 117 usb_mouse_polling_callback; 118 119 // set the polling ended callback 120 hid_dev->subdrivers[hid_dev->subdriver_count].poll_end = NULL; 121 122 // set the deinit callback 123 hid_dev->subdrivers[hid_dev->subdriver_count].deinit = usb_mouse_deinit; 124 125 // set subdriver count 126 ++hid_dev->subdriver_count; 127 92 hid_dev->subdriver_count = 1; 93 // TODO 2 should be mouse, but find a better way 94 hid_dev->subdrivers[2] = usb_hid_subdrivers[0].subdriver; 95 128 96 return EOK; 129 97 } … … 134 102 { 135 103 assert(hid_dev != NULL && hid_dev->subdriver_count == 0); 136 137 hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc( 138 sizeof(usb_hid_subdriver_t)); 104 105 hid_dev->subdrivers = malloc(sizeof(usb_hid_subdriver_t)); 139 106 if (hid_dev->subdrivers == NULL) { 140 107 return ENOMEM; 141 108 } 142 143 assert(hid_dev->subdriver_count >= 0); 144 145 // set the init callback 146 hid_dev->subdrivers[hid_dev->subdriver_count].init = 147 usb_generic_hid_init; 148 149 // set the polling callback 150 hid_dev->subdrivers[hid_dev->subdriver_count].poll = 151 usb_generic_hid_polling_callback; 152 153 // set the polling ended callback 154 hid_dev->subdrivers[hid_dev->subdriver_count].poll_end = NULL; 155 156 // set the deinit callback 157 hid_dev->subdrivers[hid_dev->subdriver_count].deinit = NULL; 158 159 // set subdriver count 160 ++hid_dev->subdriver_count; 161 109 hid_dev->subdriver_count = 1; 110 111 /* Set generic hid subdriver routines */ 112 hid_dev->subdrivers[0].init = usb_generic_hid_init; 113 hid_dev->subdrivers[0].poll = usb_generic_hid_polling_callback; 114 hid_dev->subdrivers[0].poll_end = NULL; 115 hid_dev->subdrivers[0].deinit = usb_generic_hid_deinit; 116 162 117 return EOK; 163 118 } … … 165 120 /*----------------------------------------------------------------------------*/ 166 121 167 static bool usb_hid_ids_match( usb_hid_dev_t *hid_dev,122 static bool usb_hid_ids_match(const usb_hid_dev_t *hid_dev, 168 123 const usb_hid_subdriver_mapping_t *mapping) 169 124 { 170 125 assert(hid_dev != NULL); 171 126 assert(hid_dev->usb_dev != NULL); 172 173 return (hid_dev->usb_dev->descriptors.device.vendor_id 127 128 return (hid_dev->usb_dev->descriptors.device.vendor_id 174 129 == mapping->vendor_id 175 130 && hid_dev->usb_dev->descriptors.device.product_id … … 179 134 /*----------------------------------------------------------------------------*/ 180 135 181 static bool usb_hid_path_matches(usb_hid_dev_t *hid_dev, 136 static bool usb_hid_path_matches(usb_hid_dev_t *hid_dev, 182 137 const usb_hid_subdriver_mapping_t *mapping) 183 138 { 184 139 assert(hid_dev != NULL); 185 140 assert(mapping != NULL); 186 141 187 142 usb_hid_report_path_t *usage_path = usb_hid_report_path(); 188 143 if (usage_path == NULL) { … … 191 146 } 192 147 int i = 0; 193 while (mapping->usage_path[i].usage != 0 148 while (mapping->usage_path[i].usage != 0 194 149 || mapping->usage_path[i].usage_page != 0) { 195 if (usb_hid_report_path_append_item(usage_path, 196 mapping->usage_path[i].usage_page, 150 if (usb_hid_report_path_append_item(usage_path, 151 mapping->usage_path[i].usage_page, 197 152 mapping->usage_path[i].usage) != EOK) { 198 153 usb_log_debug("Failed to append to usage path.\n"); … … 202 157 ++i; 203 158 } 204 205 assert(hid_dev->report != NULL); 206 159 207 160 usb_log_debug("Compare flags: %d\n", mapping->compare); 208 161 209 162 bool matches = false; 210 163 uint8_t report_id = mapping->report_id; … … 212 165 do { 213 166 usb_log_debug("Trying report id %u\n", report_id); 214 167 215 168 if (report_id != 0) { 216 169 usb_hid_report_path_set_report_id(usage_path, … … 219 172 220 173 usb_hid_report_field_t *field = usb_hid_report_get_sibling( 221 hid_dev->report, 222 NULL, usage_path, mapping->compare, 174 &hid_dev->report, NULL, usage_path, mapping->compare, 223 175 USB_HID_REPORT_TYPE_INPUT); 224 176 225 177 usb_log_debug("Field: %p\n", field); 226 178 … … 229 181 break; 230 182 } 231 183 232 184 report_id = usb_hid_get_next_report_id( 233 hid_dev->report, report_id, 234 USB_HID_REPORT_TYPE_INPUT); 185 &hid_dev->report, report_id, USB_HID_REPORT_TYPE_INPUT); 235 186 } while (!matches && report_id != 0); 236 187 237 188 usb_hid_report_path_free(usage_path); 238 189 239 190 return matches; 240 191 } … … 242 193 /*----------------------------------------------------------------------------*/ 243 194 244 static int usb_hid_save_subdrivers(usb_hid_dev_t *hid_dev, 195 static int usb_hid_save_subdrivers(usb_hid_dev_t *hid_dev, 245 196 const usb_hid_subdriver_t **subdrivers, int count) 246 197 { 247 198 int i; 248 199 249 200 if (count <= 0) { 250 201 hid_dev->subdriver_count = 0; … … 252 203 return EOK; 253 204 } 254 255 // add one generic HID subdriver per device 256 257 hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc((count + 1) * 258 sizeof(usb_hid_subdriver_t)); 205 206 /* +1 for generic hid subdriver */ 207 hid_dev->subdrivers = calloc((count + 1), sizeof(usb_hid_subdriver_t)); 259 208 if (hid_dev->subdrivers == NULL) { 260 209 return ENOMEM; 261 210 } 262 211 263 212 for (i = 0; i < count; ++i) { 264 213 hid_dev->subdrivers[i].init = subdrivers[i]->init; … … 267 216 hid_dev->subdrivers[i].poll_end = subdrivers[i]->poll_end; 268 217 } 269 218 219 /* Add one generic HID subdriver per device */ 270 220 hid_dev->subdrivers[count].init = usb_generic_hid_init; 271 221 hid_dev->subdrivers[count].poll = usb_generic_hid_polling_callback; 272 hid_dev->subdrivers[count].deinit = NULL;222 hid_dev->subdrivers[count].deinit = usb_generic_hid_deinit; 273 223 hid_dev->subdrivers[count].poll_end = NULL; 274 224 275 225 hid_dev->subdriver_count = count + 1; 276 226 277 227 return EOK; 278 228 } … … 283 233 { 284 234 assert(hid_dev != NULL); 285 235 286 236 const usb_hid_subdriver_t *subdrivers[USB_HID_MAX_SUBDRIVERS]; 287 237 288 238 int i = 0, count = 0; 289 239 const usb_hid_subdriver_mapping_t *mapping = &usb_hid_subdrivers[i]; … … 291 241 bool ids_matched; 292 242 bool matched; 293 243 294 244 while (count < USB_HID_MAX_SUBDRIVERS && 295 245 (mapping->usage_path != NULL … … 306 256 return EINVAL; 307 257 } 308 258 309 259 ids_matched = false; 310 260 matched = false; 311 261 312 262 if (mapping->vendor_id >= 0) { 313 263 assert(mapping->product_id >= 0); … … 320 270 } 321 271 } 322 272 323 273 if (mapping->usage_path != NULL) { 324 274 usb_log_debug("Comparing device against usage path.\n"); … … 331 281 matched = ids_matched; 332 282 } 333 283 334 284 if (matched) { 335 285 usb_log_debug("Subdriver matched.\n"); 336 286 subdrivers[count++] = &mapping->subdriver; 337 287 } 338 288 339 289 mapping = &usb_hid_subdrivers[++i]; 340 290 } 341 342 // we have all subdrivers determined, save them into the hid device 291 292 /* We have all subdrivers determined, save them into the hid device */ 293 // TODO Dowe really need this complicated stuff if there is 294 // max_subdrivers limitation? 343 295 return usb_hid_save_subdrivers(hid_dev, subdrivers, count); 344 296 } … … 346 298 /*----------------------------------------------------------------------------*/ 347 299 348 static int usb_hid_check_pipes(usb_hid_dev_t *hid_dev, usb_device_t *dev) 349 { 350 assert(hid_dev != NULL && dev != NULL); 351 352 int rc = EOK; 353 300 static int usb_hid_check_pipes(usb_hid_dev_t *hid_dev, const usb_device_t *dev) 301 { 302 assert(hid_dev); 303 assert(dev); 304 354 305 if (dev->pipes[USB_HID_KBD_POLL_EP_NO].present) { 355 306 usb_log_debug("Found keyboard endpoint.\n"); … … 367 318 usb_log_error("None of supported endpoints found - probably" 368 319 " not a supported device.\n"); 369 r c =ENOTSUP;370 } 371 372 return rc;320 return ENOTSUP; 321 } 322 323 return EOK; 373 324 } 374 325 … … 377 328 static int usb_hid_init_report(usb_hid_dev_t *hid_dev) 378 329 { 379 assert(hid_dev != NULL && hid_dev->report != NULL);380 330 assert(hid_dev != NULL); 331 381 332 uint8_t report_id = 0; 382 size_t size;383 384 333 size_t max_size = 0; 385 334 386 335 do { 387 336 usb_log_debug("Getting size of the report.\n"); 388 size = usb_hid_report_byte_size(hid_dev->report, report_id, 389 USB_HID_REPORT_TYPE_INPUT); 337 const size_t size = 338 usb_hid_report_byte_size(&hid_dev->report, report_id, 339 USB_HID_REPORT_TYPE_INPUT); 390 340 usb_log_debug("Report ID: %u, size: %zu\n", report_id, size); 391 341 max_size = (size > max_size) ? size : max_size; 392 342 usb_log_debug("Getting next report ID\n"); 393 report_id = usb_hid_get_next_report_id( hid_dev->report,343 report_id = usb_hid_get_next_report_id(&hid_dev->report, 394 344 report_id, USB_HID_REPORT_TYPE_INPUT); 395 345 } while (report_id != 0); 396 346 397 347 usb_log_debug("Max size of input report: %zu\n", max_size); 398 399 hid_dev->max_input_report_size = max_size; 348 400 349 assert(hid_dev->input_report == NULL); 401 402 hid_dev->input_report = malloc(max_size);350 351 hid_dev->input_report = calloc(1, max_size); 403 352 if (hid_dev->input_report == NULL) { 404 353 return ENOMEM; 405 354 } 406 memset(hid_dev->input_report, 0, max_size);407 355 hid_dev->max_input_report_size = max_size; 356 408 357 return EOK; 409 358 } … … 411 360 /*----------------------------------------------------------------------------*/ 412 361 413 usb_hid_dev_t *usb_hid_new(void)414 {415 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)calloc(1,416 sizeof(usb_hid_dev_t));417 418 if (hid_dev == NULL) {419 usb_log_fatal("No memory!\n");420 return NULL;421 }422 423 hid_dev->report = (usb_hid_report_t *)(malloc(sizeof(424 usb_hid_report_t)));425 if (hid_dev->report == NULL) {426 usb_log_fatal("No memory!\n");427 free(hid_dev);428 return NULL;429 }430 431 hid_dev->poll_pipe_index = -1;432 433 return hid_dev;434 }435 436 /*----------------------------------------------------------------------------*/437 438 362 int usb_hid_init(usb_hid_dev_t *hid_dev, usb_device_t *dev) 439 363 { 440 364 int rc, i; 441 365 442 366 usb_log_debug("Initializing HID structure...\n"); 443 367 444 368 if (hid_dev == NULL) { 445 369 usb_log_error("Failed to init HID structure: no structure given" … … 447 371 return EINVAL; 448 372 } 449 373 450 374 if (dev == NULL) { 451 375 usb_log_error("Failed to init HID structure: no USB device" … … 453 377 return EINVAL; 454 378 } 455 379 380 usb_hid_report_init(&hid_dev->report); 381 456 382 /* The USB device should already be initialized, save it in structure */ 457 383 hid_dev->usb_dev = dev; 458 384 hid_dev->poll_pipe_index = -1; 385 459 386 rc = usb_hid_check_pipes(hid_dev, dev); 460 387 if (rc != EOK) { 461 388 return rc; 462 389 } 463 390 464 391 /* Get the report descriptor and parse it. */ 465 rc = usb_hid_process_report_descriptor(hid_dev->usb_dev, 466 hid_dev->report, &hid_dev->report_desc, &hid_dev->report_desc_size);467 392 rc = usb_hid_process_report_descriptor(hid_dev->usb_dev, 393 &hid_dev->report, &hid_dev->report_desc, &hid_dev->report_desc_size); 394 468 395 bool fallback = false; 469 396 470 397 if (rc == EOK) { 471 398 // try to find subdrivers that may want to handle this device … … 484 411 fallback = true; 485 412 } 486 413 487 414 if (fallback) { 488 415 // fall back to boot protocol … … 503 430 break; 504 431 default: 505 assert(hid_dev->poll_pipe_index 432 assert(hid_dev->poll_pipe_index 506 433 == USB_HID_GENERIC_POLL_EP_NO); 507 434 508 435 usb_log_info("Falling back to generic HID driver.\n"); 509 436 rc = usb_hid_set_generic_hid_subdriver(hid_dev); 510 437 } 511 438 } 512 439 513 440 if (rc != EOK) { 514 441 usb_log_error("No subdriver for handling this device could be" 515 442 " initialized: %s.\n", str_error(rc)); 516 usb_log_debug("Subdriver count: %d\n", 443 usb_log_debug("Subdriver count: %d\n", 517 444 hid_dev->subdriver_count); 518 519 445 } else { 520 446 bool ok = false; 521 522 usb_log_debug("Subdriver count: %d\n", 447 448 usb_log_debug("Subdriver count: %d\n", 523 449 hid_dev->subdriver_count); 524 450 525 451 for (i = 0; i < hid_dev->subdriver_count; ++i) { 526 452 if (hid_dev->subdrivers[i].init != NULL) { … … 539 465 } 540 466 } 541 467 542 468 rc = (ok) ? EOK : -1; // what error to report 543 469 } 544 545 470 471 546 472 if (rc == EOK) { 547 473 // save max input report size and allocate space for the report … … 552 478 } 553 479 } 554 555 480 556 481 return rc; 557 482 } … … 559 484 /*----------------------------------------------------------------------------*/ 560 485 561 bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer, 486 bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer, 562 487 size_t buffer_size, void *arg) 563 488 { 564 int i;565 566 489 if (dev == NULL || arg == NULL || buffer == NULL) { 567 490 usb_log_error("Missing arguments to polling callback.\n"); 568 491 return false; 569 492 } 570 571 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg; 572 493 usb_hid_dev_t *hid_dev = arg; 494 573 495 assert(hid_dev->input_report != NULL); 496 574 497 usb_log_debug("New data [%zu/%zu]: %s\n", buffer_size, 575 498 hid_dev->max_input_report_size, … … 582 505 usb_hid_new_report(hid_dev); 583 506 } 584 585 // parse the input report 586 587 int rc = usb_hid_parse_report(hid_dev->report, buffer, buffer_size, 588 &hid_dev->report_id); 589 507 508 /* Parse the input report */ 509 const int rc = usb_hid_parse_report( 510 &hid_dev->report, buffer, buffer_size, &hid_dev->report_id); 590 511 if (rc != EOK) { 591 512 usb_log_warning("Error in usb_hid_parse_report():" 592 513 "%s\n", str_error(rc)); 593 } 594 514 } 515 595 516 bool cont = false; 596 597 // continue if at least one of the subdrivers want to continue 598 for (i = 0; i < hid_dev->subdriver_count; ++i) { 599 if (hid_dev->subdrivers[i].poll != NULL 600 && hid_dev->subdrivers[i].poll(hid_dev, 601 hid_dev->subdrivers[i].data)) { 602 cont = true; 603 } 604 } 605 517 /* Continue if at least one of the subdrivers want to continue */ 518 for (int i = 0; i < hid_dev->subdriver_count; ++i) { 519 if (hid_dev->subdrivers[i].poll != NULL) { 520 cont = cont || hid_dev->subdrivers[i].poll( 521 hid_dev, hid_dev->subdrivers[i].data); 522 } 523 } 524 606 525 return cont; 607 526 } … … 609 528 /*----------------------------------------------------------------------------*/ 610 529 611 void usb_hid_polling_ended_callback(usb_device_t *dev, bool reason, 612 void *arg) 613 { 614 int i; 615 616 if (dev == NULL || arg == NULL) { 617 return; 618 } 619 620 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg; 621 622 for (i = 0; i < hid_dev->subdriver_count; ++i) { 530 void usb_hid_polling_ended_callback(usb_device_t *dev, bool reason, void *arg) 531 { 532 assert(dev); 533 assert(arg); 534 535 usb_hid_dev_t *hid_dev = arg; 536 537 for (int i = 0; i < hid_dev->subdriver_count; ++i) { 623 538 if (hid_dev->subdrivers[i].poll_end != NULL) { 624 hid_dev->subdrivers[i].poll_end( hid_dev,625 hid_dev ->subdrivers[i].data, reason);626 } 627 } 628 629 usb_hid_destroy(hid_dev);539 hid_dev->subdrivers[i].poll_end( 540 hid_dev, hid_dev->subdrivers[i].data, reason); 541 } 542 } 543 544 hid_dev->running = false; 630 545 } 631 546 … … 639 554 /*----------------------------------------------------------------------------*/ 640 555 641 int usb_hid_report_number( usb_hid_dev_t *hid_dev)556 int usb_hid_report_number(const usb_hid_dev_t *hid_dev) 642 557 { 643 558 return hid_dev->report_nr; … … 646 561 /*----------------------------------------------------------------------------*/ 647 562 648 void usb_hid_destroy(usb_hid_dev_t *hid_dev) 649 { 650 int i; 651 652 if (hid_dev == NULL) { 653 return; 654 } 655 563 void usb_hid_deinit(usb_hid_dev_t *hid_dev) 564 { 565 assert(hid_dev); 566 assert(hid_dev->subdrivers != NULL || hid_dev->subdriver_count == 0); 567 568 656 569 usb_log_debug("Subdrivers: %p, subdriver count: %d\n", 657 570 hid_dev->subdrivers, hid_dev->subdriver_count); 658 659 assert(hid_dev->subdrivers != NULL 660 || hid_dev->subdriver_count == 0); 661 662 for (i = 0; i < hid_dev->subdriver_count; ++i) { 571 572 for (int i = 0; i < hid_dev->subdriver_count; ++i) { 663 573 if (hid_dev->subdrivers[i].deinit != NULL) { 664 574 hid_dev->subdrivers[i].deinit(hid_dev, … … 666 576 } 667 577 } 668 669 // free the subdrivers info 670 if (hid_dev->subdrivers != NULL) { 671 free(hid_dev->subdrivers); 672 } 673 674 // destroy the parser 675 if (hid_dev->report != NULL) { 676 usb_hid_free_report(hid_dev->report); 677 } 678 679 if (hid_dev->report_desc != NULL) { 680 free(hid_dev->report_desc); 681 } 578 579 /* Free allocated structures */ 580 free(hid_dev->subdrivers); 581 free(hid_dev->report_desc); 582 583 /* Destroy the parser */ 584 usb_hid_report_deinit(&hid_dev->report); 585 682 586 } 683 587 -
uspace/drv/bus/usb/usbhid/usbhid.h
r4c3ad56 r20a3465 102 102 /** Structure holding generic USB device information. */ 103 103 usb_device_t *usb_dev; 104 104 105 105 /** Index of the polling pipe in usb_hid_endpoints array. */ 106 106 int poll_pipe_index; 107 107 108 108 /** Subdrivers. */ 109 109 usb_hid_subdriver_t *subdrivers; 110 110 111 111 /** Number of subdrivers. */ 112 112 int subdriver_count; 113 113 114 114 /** Report descriptor. */ 115 115 uint8_t *report_desc; … … 117 117 /** Report descriptor size. */ 118 118 size_t report_desc_size; 119 119 120 120 /** HID Report parser. */ 121 usb_hid_report_t *report;122 121 usb_hid_report_t report; 122 123 123 uint8_t report_id; 124 124 125 125 uint8_t *input_report; 126 126 127 127 size_t input_report_size; 128 128 size_t max_input_report_size; 129 129 130 130 int report_nr; 131 volatile bool running; 131 132 }; 132 133 … … 140 141 }; 141 142 142 usb_endpoint_description_t *usb_hid_endpoints[USB_HID_POLL_EP_COUNT + 1];143 extern const usb_endpoint_description_t *usb_hid_endpoints[]; 143 144 144 145 /*----------------------------------------------------------------------------*/ 145 146 146 usb_hid_dev_t *usb_hid_new(void);147 148 147 int usb_hid_init(usb_hid_dev_t *hid_dev, usb_device_t *dev); 149 148 150 bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer, 151 size_t buffer_size, void *arg); 149 void usb_hid_deinit(usb_hid_dev_t *hid_dev); 152 150 153 void usb_hid_polling_ended_callback(usb_device_t *dev, bool reason, 154 void *arg); 151 bool usb_hid_polling_callback(usb_device_t *dev, 152 uint8_t *buffer, size_t buffer_size, void *arg); 153 154 void usb_hid_polling_ended_callback(usb_device_t *dev, bool reason, void *arg); 155 155 156 156 void usb_hid_new_report(usb_hid_dev_t *hid_dev); 157 157 158 int usb_hid_report_number(usb_hid_dev_t *hid_dev); 159 160 void usb_hid_destroy(usb_hid_dev_t *hid_dev); 158 int usb_hid_report_number(const usb_hid_dev_t *hid_dev); 161 159 162 160 #endif /* USB_HID_USBHID_H_ */ -
uspace/drv/bus/usb/usbhub/main.c
r4c3ad56 r20a3465 47 47 * For more information see section 11.15.1 of USB 1.1 specification. 48 48 */ 49 static usb_endpoint_description_t hub_status_change_endpoint_description = { 49 static const usb_endpoint_description_t hub_status_change_endpoint_description = 50 { 50 51 .transfer_type = USB_TRANSFER_INTERRUPT, 51 52 .direction = USB_DIRECTION_IN, … … 56 57 }; 57 58 58 /** 59 * USB hub driver operations 60 * 61 * The most important one is device_add, which is set to usb_hub_device_add. 62 */ 63 static usb_driver_ops_t usb_hub_driver_ops = { 59 /** USB hub driver operations. */ 60 static const usb_driver_ops_t usb_hub_driver_ops = { 64 61 .device_add = usb_hub_device_add, 62 // .device_rem = usb_hub_device_remove, 65 63 .device_gone = usb_hub_device_gone, 66 64 }; 67 65 68 66 /** Hub endpoints, excluding control endpoint. */ 69 static usb_endpoint_description_t *usb_hub_endpoints[] = {67 static const usb_endpoint_description_t *usb_hub_endpoints[] = { 70 68 &hub_status_change_endpoint_description, 71 69 NULL, 72 70 }; 73 71 /** Static usb hub driver information. */ 74 static usb_driver_t usb_hub_driver = {72 static const usb_driver_t usb_hub_driver = { 75 73 .name = NAME, 76 74 .ops = &usb_hub_driver_ops, 77 75 .endpoints = usb_hub_endpoints 78 76 }; 79 80 77 81 78 int main(int argc, char *argv[]) -
uspace/drv/bus/usb/usbhub/port.c
r4c3ad56 r20a3465 288 288 port->attached_device.fun = NULL; 289 289 290 ret = usb_hc_unregister_device(&hub->connection, 291 port->attached_device.address); 292 if (ret != EOK) { 293 usb_log_warning("Failed to unregister address of the removed " 294 "device: %s.\n", str_error(ret)); 295 } 290 ret = usb_hc_connection_open(&hub->connection); 291 if (ret == EOK) { 292 ret = usb_hc_unregister_device(&hub->connection, 293 port->attached_device.address); 294 if (ret != EOK) { 295 usb_log_warning("Failed to unregister address of the " 296 "removed device: %s.\n", str_error(ret)); 297 } 298 ret = usb_hc_connection_close(&hub->connection); 299 if (ret != EOK) { 300 usb_log_warning("Failed to close hc connection %s.\n", 301 str_error(ret)); 302 } 303 304 } else { 305 usb_log_warning("Failed to open hc connection %s.\n", 306 str_error(ret)); 307 } 308 296 309 port->attached_device.address = -1; 297 310 fibril_mutex_unlock(&port->mutex); -
uspace/drv/bus/usb/usbhub/port.h
r4c3ad56 r20a3465 44 44 /** Information about single port on a hub. */ 45 45 typedef struct { 46 /* Port number as reporteed in descriptors. */ 46 47 size_t port_number; 48 /** Device communication pipe. */ 47 49 usb_pipe_t *control_pipe; 48 50 /** Mutex needed not only by CV for checking port reset. */ -
uspace/drv/bus/usb/usbhub/usbhub.c
r4c3ad56 r20a3465 68 68 69 69 static int usb_set_first_configuration(usb_device_t *usb_device); 70 static usb_hub_dev_t * usb_hub_dev_create(usb_device_t *usb_dev);71 70 static int usb_hub_process_hub_specific_info(usb_hub_dev_t *hub_dev); 72 71 static void usb_hub_over_current(const usb_hub_dev_t *hub_dev, … … 75 74 static void usb_hub_polling_terminated_callback(usb_device_t *device, 76 75 bool was_error, void *data); 77 /** 78 * Initialize hub device driver fibril 76 77 /** 78 * Initialize hub device driver structure. 79 79 * 80 80 * Creates hub representation and fibril that periodically checks hub's status. 81 81 * Hub representation is passed to the fibril. 82 * @param usb_dev generic usb device information 83 * @return error code 84 */ 85 int usb_hub_device_add(usb_device_t *usb_dev) 86 { 87 assert(usb_dev); 88 /* Create driver soft-state structure */ 89 usb_hub_dev_t *hub_dev = 90 usb_device_data_alloc(usb_dev, sizeof(usb_hub_dev_t)); 91 if (hub_dev == NULL) { 92 usb_log_error("Failed to create hub driver structure.\n"); 93 return ENOMEM; 94 } 95 hub_dev->usb_device = usb_dev; 96 hub_dev->pending_ops_count = 0; 97 hub_dev->running = false; 98 fibril_mutex_initialize(&hub_dev->pending_ops_mutex); 99 fibril_condvar_initialize(&hub_dev->pending_ops_cv); 100 101 /* Create hc connection */ 102 usb_log_debug("Initializing USB wire abstraction.\n"); 103 int opResult = usb_hc_connection_initialize_from_device( 104 &hub_dev->connection, hub_dev->usb_device->ddf_dev); 105 if (opResult != EOK) { 106 usb_log_error("Could not initialize connection to device: %s\n", 107 str_error(opResult)); 108 return opResult; 109 } 110 111 /* Set hub's first configuration. (There should be only one) */ 112 opResult = usb_set_first_configuration(usb_dev); 113 if (opResult != EOK) { 114 usb_log_error("Could not set hub configuration: %s\n", 115 str_error(opResult)); 116 return opResult; 117 } 118 119 /* Get port count and create attached_devices. */ 120 opResult = usb_hub_process_hub_specific_info(hub_dev); 121 if (opResult != EOK) { 122 usb_log_error("Could process hub specific info, %s\n", 123 str_error(opResult)); 124 return opResult; 125 } 126 127 /* Create hub control function. */ 128 usb_log_debug("Creating DDF function '" HUB_FNC_NAME "'.\n"); 129 hub_dev->hub_fun = ddf_fun_create(hub_dev->usb_device->ddf_dev, 130 fun_exposed, HUB_FNC_NAME); 131 if (hub_dev->hub_fun == NULL) { 132 usb_log_error("Failed to create hub function.\n"); 133 return ENOMEM; 134 } 135 136 /* Bind hub control function. */ 137 opResult = ddf_fun_bind(hub_dev->hub_fun); 138 if (opResult != EOK) { 139 usb_log_error("Failed to bind hub function: %s.\n", 140 str_error(opResult)); 141 ddf_fun_destroy(hub_dev->hub_fun); 142 return opResult; 143 } 144 145 /* Start hub operation. */ 146 opResult = usb_device_auto_poll(hub_dev->usb_device, 0, 147 hub_port_changes_callback, ((hub_dev->port_count + 1 + 8) / 8), 148 usb_hub_polling_terminated_callback, hub_dev); 149 if (opResult != EOK) { 150 /* Function is already bound */ 151 ddf_fun_unbind(hub_dev->hub_fun); 152 ddf_fun_destroy(hub_dev->hub_fun); 153 usb_log_error("Failed to create polling fibril: %s.\n", 154 str_error(opResult)); 155 return opResult; 156 } 157 hub_dev->running = true; 158 usb_log_info("Controlling hub '%s' (%zu ports).\n", 159 hub_dev->usb_device->ddf_dev->name, hub_dev->port_count); 160 161 return EOK; 162 } 163 /*----------------------------------------------------------------------------*/ 164 /** 165 * Turn off power to all ports. 166 * 167 * @param usb_dev generic usb device information 168 * @return error code 169 */ 170 int usb_hub_device_remove(usb_device_t *usb_dev) 171 { 172 assert(usb_dev); 173 usb_hub_dev_t *hub_dev = usb_dev->driver_data; 174 assert(hub_dev); 175 //TODO: Cascade the call here. 176 //TODO: Enable after cascading is implemented. 177 return ENOTSUP; 178 if (!hub_dev->power_switched) { 179 /* That is all we can do. */ 180 return EOK; 181 } 182 int ret = EOK; 183 usb_log_info("Hub is about to be removed, powering down all ports.\n"); 184 for (size_t port = 0; port < hub_dev->port_count; ++port) { 185 usb_log_debug("Powering down port %zu.\n", port); 186 int pret = usb_hub_port_clear_feature( 187 &hub_dev->ports[port], USB_HUB_FEATURE_PORT_POWER); 188 if (pret != EOK) { 189 usb_log_error("Cannot power down port %zu: %s.\n", 190 hub_dev->ports[port].port_number, str_error(pret)); 191 ret = pret; 192 } else { 193 if (!hub_dev->per_port_power) { 194 usb_log_debug("Ganged power switching mode, " 195 "one port is enough.\n"); 196 break; 197 } 198 } 199 } 200 return ret; 201 } 202 /*----------------------------------------------------------------------------*/ 203 /** 204 * Remove all attached devices 82 205 * @param usb_dev generic usb device information 83 206 * @return error code … … 117 240 ddf_fun_destroy(hub->hub_fun); 118 241 119 free(hub);120 usb_dev->driver_data = NULL;121 242 usb_log_info("USB hub driver, stopped and cleaned.\n"); 122 return EOK;123 }124 /*----------------------------------------------------------------------------*/125 /**126 * Initialize hub device driver fibril127 *128 * Creates hub representation and fibril that periodically checks hub's status.129 * Hub representation is passed to the fibril.130 * @param usb_dev generic usb device information131 * @return error code132 */133 int usb_hub_device_add(usb_device_t *usb_dev)134 {135 assert(usb_dev);136 /* Create driver soft-state structure */137 usb_hub_dev_t *hub_dev = usb_hub_dev_create(usb_dev);138 if (hub_dev == NULL) {139 usb_log_error("Failed to create hun driver structure.\n");140 return ENOMEM;141 }142 143 /* Create hc connection */144 usb_log_debug("Initializing USB wire abstraction.\n");145 int opResult = usb_hc_connection_initialize_from_device(146 &hub_dev->connection, hub_dev->usb_device->ddf_dev);147 if (opResult != EOK) {148 usb_log_error("Could not initialize connection to device: %s\n",149 str_error(opResult));150 free(hub_dev);151 return opResult;152 }153 154 /* Set hub's first configuration. (There should be only one) */155 opResult = usb_set_first_configuration(usb_dev);156 if (opResult != EOK) {157 usb_log_error("Could not set hub configuration: %s\n",158 str_error(opResult));159 free(hub_dev);160 return opResult;161 }162 163 /* Get port count and create attached_devices. */164 opResult = usb_hub_process_hub_specific_info(hub_dev);165 if (opResult != EOK) {166 usb_log_error("Could process hub specific info, %s\n",167 str_error(opResult));168 free(hub_dev);169 return opResult;170 }171 172 usb_log_debug("Creating DDF function '" HUB_FNC_NAME "'.\n");173 hub_dev->hub_fun = ddf_fun_create(hub_dev->usb_device->ddf_dev,174 fun_exposed, HUB_FNC_NAME);175 if (hub_dev->hub_fun == NULL) {176 usb_log_error("Failed to create hub function.\n");177 free(hub_dev);178 return ENOMEM;179 }180 181 opResult = ddf_fun_bind(hub_dev->hub_fun);182 if (opResult != EOK) {183 usb_log_error("Failed to bind hub function: %s.\n",184 str_error(opResult));185 free(hub_dev);186 ddf_fun_destroy(hub_dev->hub_fun);187 return opResult;188 }189 190 opResult = usb_device_auto_poll(hub_dev->usb_device, 0,191 hub_port_changes_callback, ((hub_dev->port_count + 1 + 8) / 8),192 usb_hub_polling_terminated_callback, hub_dev);193 if (opResult != EOK) {194 /* Function is already bound */195 ddf_fun_unbind(hub_dev->hub_fun);196 ddf_fun_destroy(hub_dev->hub_fun);197 free(hub_dev);198 usb_log_error("Failed to create polling fibril: %s.\n",199 str_error(opResult));200 return opResult;201 }202 hub_dev->running = true;203 usb_log_info("Controlling hub '%s' (%zu ports).\n",204 hub_dev->usb_device->ddf_dev->name, hub_dev->port_count);205 206 243 return EOK; 207 244 } … … 245 282 /*----------------------------------------------------------------------------*/ 246 283 /** 247 * create usb_hub_dev_t structure248 *249 * Does only basic copying of known information into new structure.250 * @param usb_dev usb device structure251 * @return basic usb_hub_dev_t structure252 */253 static usb_hub_dev_t * usb_hub_dev_create(usb_device_t *usb_dev)254 {255 assert(usb_dev);256 usb_hub_dev_t *hub_dev = malloc(sizeof(usb_hub_dev_t));257 if (!hub_dev)258 return NULL;259 260 hub_dev->usb_device = usb_dev;261 262 hub_dev->ports = NULL;263 hub_dev->port_count = 0;264 hub_dev->pending_ops_count = 0;265 hub_dev->running = false;266 fibril_mutex_initialize(&hub_dev->pending_ops_mutex);267 fibril_condvar_initialize(&hub_dev->pending_ops_cv);268 usb_dev->driver_data = hub_dev;269 270 return hub_dev;271 }272 /*----------------------------------------------------------------------------*/273 /**274 284 * Load hub-specific information into hub_dev structure and process if needed 275 285 * … … 314 324 } 315 325 316 const bool is_power_switched =326 hub_dev->power_switched = 317 327 !(descriptor.characteristics & HUB_CHAR_NO_POWER_SWITCH_FLAG); 318 if (is_power_switched) { 319 usb_log_debug("Hub power switched\n"); 320 const bool per_port_power = descriptor.characteristics 321 & HUB_CHAR_POWER_PER_PORT_FLAG; 322 323 for (size_t port = 0; port < hub_dev->port_count; ++port) { 324 usb_log_debug("Powering port %zu.\n", port); 325 opResult = usb_hub_port_set_feature( 326 &hub_dev->ports[port], USB_HUB_FEATURE_PORT_POWER); 327 if (opResult != EOK) { 328 usb_log_error("Cannot power on port %zu: %s.\n", 329 port, str_error(opResult)); 330 } else { 331 if (!per_port_power) { 332 usb_log_debug( 333 "Ganged power switching mode, " 334 "one port is enough.\n"); 335 break; 336 } 328 hub_dev->per_port_power = 329 descriptor.characteristics & HUB_CHAR_POWER_PER_PORT_FLAG; 330 331 if (!hub_dev->power_switched) { 332 usb_log_info( 333 "Power switching not supported, ports always powered.\n"); 334 return EOK; 335 } 336 337 usb_log_info("Hub port power switching enabled.\n"); 338 339 for (size_t port = 0; port < hub_dev->port_count; ++port) { 340 usb_log_debug("Powering port %zu.\n", port); 341 const int ret = usb_hub_port_set_feature( 342 &hub_dev->ports[port], USB_HUB_FEATURE_PORT_POWER); 343 344 if (ret != EOK) { 345 usb_log_error("Cannot power on port %zu: %s.\n", 346 hub_dev->ports[port].port_number, str_error(ret)); 347 } else { 348 if (!hub_dev->per_port_power) { 349 usb_log_debug("Ganged power switching, " 350 "one port is enough.\n"); 351 break; 337 352 } 338 353 } 339 } else {340 usb_log_debug("Power not switched, ports always powered\n");341 354 } 342 355 return EOK; … … 405 418 usb_log_warning("Detected hub over-current condition, " 406 419 "all ports should be powered off."); 407 } else { 408 /* Over-current condition is gone, it is safe to turn the 409 * ports on. */ 410 for (size_t port = 0; port < hub_dev->port_count; ++port) { 411 const int opResult = usb_hub_port_set_feature( 412 &hub_dev->ports[port], USB_HUB_FEATURE_PORT_POWER); 413 // TODO: consider power policy here 414 if (opResult != EOK) { 415 usb_log_warning( 416 "HUB OVER-CURRENT GONE: Cannot power on " 417 "port %zu; %s\n", 418 port, str_error(opResult)); 419 } 420 } 421 } 422 const int opResult = usb_request_clear_feature( 423 &hub_dev->usb_device->ctrl_pipe, USB_REQUEST_TYPE_CLASS, 424 USB_REQUEST_RECIPIENT_DEVICE, 425 USB_HUB_FEATURE_C_HUB_LOCAL_POWER, 0); 426 if (opResult != EOK) { 427 usb_log_error( 428 "Failed to clear hub over-current change flag: %s.\n", 429 str_error(opResult)); 430 } 420 return; 421 } 422 423 /* Ports are always powered. */ 424 if (!hub_dev->power_switched) 425 return; 426 427 /* Over-current condition is gone, it is safe to turn the ports on. */ 428 for (size_t port = 0; port < hub_dev->port_count; ++port) { 429 const int ret = usb_hub_port_set_feature( 430 &hub_dev->ports[port], USB_HUB_FEATURE_PORT_POWER); 431 if (ret != EOK) { 432 usb_log_warning("HUB OVER-CURRENT GONE: Cannot power on" 433 " port %zu: %s\n", hub_dev->ports[port].port_number, 434 str_error(ret)); 435 } else { 436 if (!hub_dev->per_port_power) 437 return; 438 } 439 } 440 431 441 } 432 442 /*----------------------------------------------------------------------------*/ … … 464 474 if (status & USB_HUB_STATUS_C_OVER_CURRENT) { 465 475 usb_hub_over_current(hub_dev, status); 476 /* Ack change in hub OC flag */ 477 const int ret = usb_request_clear_feature( 478 &hub_dev->usb_device->ctrl_pipe, USB_REQUEST_TYPE_CLASS, 479 USB_REQUEST_RECIPIENT_DEVICE, 480 USB_HUB_FEATURE_C_HUB_OVER_CURRENT, 0); 481 if (ret != EOK) { 482 usb_log_error("Failed to clear hub over-current " 483 "change flag: %s.\n", str_error(opResult)); 484 } 466 485 } 467 486 … … 480 499 * Just ACK the change. 481 500 */ 482 const int opResult = usb_request_clear_feature(501 const int ret = usb_request_clear_feature( 483 502 control_pipe, USB_REQUEST_TYPE_CLASS, 484 503 USB_REQUEST_RECIPIENT_DEVICE, 485 504 USB_HUB_FEATURE_C_HUB_LOCAL_POWER, 0); 486 505 if (opResult != EOK) { 487 usb_log_error( 488 "Failed to clear hub power change flag: %s.\n", 489 str_error(opResult)); 506 usb_log_error("Failed to clear hub power change " 507 "flag: %s.\n", str_error(ret)); 490 508 } 491 509 } -
uspace/drv/bus/usb/usbhub/usbhub.h
r4c3ad56 r20a3465 77 77 /** Status indicator */ 78 78 bool running; 79 /** Hub supports port power switching. */ 80 bool power_switched; 81 /** Each port is switched individually. */ 82 bool per_port_power; 79 83 }; 80 84 81 85 int usb_hub_device_add(usb_device_t *usb_dev); 86 int usb_hub_device_remove(usb_device_t *usb_dev); 82 87 int usb_hub_device_gone(usb_device_t *usb_dev); 83 88 -
uspace/drv/bus/usb/usbmast/main.c
r4c3ad56 r20a3465 55 55 #define GET_BULK_OUT(dev) ((dev)->pipes[BULK_OUT_EP].pipe) 56 56 57 static usb_endpoint_description_t bulk_in_ep = {57 static const usb_endpoint_description_t bulk_in_ep = { 58 58 .transfer_type = USB_TRANSFER_BULK, 59 59 .direction = USB_DIRECTION_IN, … … 63 63 .flags = 0 64 64 }; 65 static usb_endpoint_description_t bulk_out_ep = {65 static const usb_endpoint_description_t bulk_out_ep = { 66 66 .transfer_type = USB_TRANSFER_BULK, 67 67 .direction = USB_DIRECTION_OUT, … … 72 72 }; 73 73 74 usb_endpoint_description_t *mast_endpoints[] = {74 static const usb_endpoint_description_t *mast_endpoints[] = { 75 75 &bulk_in_ep, 76 76 &bulk_out_ep, … … 82 82 void *arg); 83 83 84 /** Callback when a device is removed from the system. 85 * 86 * @param dev Representation of USB device. 87 * @return Error code. 88 */ 89 static int usbmast_device_gone(usb_device_t *dev) 90 { 91 usbmast_dev_t *mdev = dev->driver_data; 92 assert(mdev); 93 94 for (size_t i = 0; i < mdev->lun_count; ++i) { 95 const int rc = ddf_fun_unbind(mdev->luns[i]); 96 if (rc != EOK) { 97 usb_log_error("Failed to unbind LUN function %zu: " 98 "%s\n", i, str_error(rc)); 99 return rc; 100 } 101 ddf_fun_destroy(mdev->luns[i]); 102 mdev->luns[i] = NULL; 103 } 104 free(mdev->luns); 105 return EOK; 106 } 107 108 /** Callback when a device is about to be removed. 109 * 110 * @param dev Representation of USB device. 111 * @return Error code. 112 */ 113 static int usbmast_device_remove(usb_device_t *dev) 114 { 115 //TODO: flush buffers, or whatever. 116 return ENOTSUP; 117 } 118 84 119 /** Callback when new device is attached and recognized as a mass storage. 85 120 * 86 * @param dev Representation of a theUSB device.121 * @param dev Representation of USB device. 87 122 * @return Error code. 88 123 */ … … 94 129 95 130 /* Allocate softstate */ 96 dev->driver_data = mdev = malloc(sizeof(usbmast_dev_t));131 mdev = usb_device_data_alloc(dev, sizeof(usbmast_dev_t)); 97 132 if (mdev == NULL) { 98 133 usb_log_error("Failed allocating softstate.\n"); … … 112 147 113 148 usb_log_debug("Get LUN count...\n"); 114 mdev->luns = usb_masstor_get_lun_count(mdev); 115 116 for (i = 0; i < mdev->luns; i++) { 149 mdev->lun_count = usb_masstor_get_lun_count(mdev); 150 mdev->luns = calloc(mdev->lun_count, sizeof(ddf_fun_t*)); 151 if (mdev->luns == NULL) { 152 rc = ENOMEM; 153 usb_log_error("Failed allocating luns table.\n"); 154 goto error; 155 } 156 157 for (i = 0; i < mdev->lun_count; i++) { 117 158 rc = usbmast_fun_create(mdev, i); 118 159 if (rc != EOK) … … 122 163 return EOK; 123 164 error: 124 /* XXX Destroy functions */ 165 /* Destroy functions */ 166 for (size_t i = 0; i < mdev->lun_count; ++i) { 167 if (mdev->luns[i] == NULL) 168 continue; 169 const int rc = ddf_fun_unbind(mdev->luns[i]); 170 if (rc != EOK) { 171 usb_log_warning("Failed to unbind LUN function %zu: " 172 "%s.\n", i, str_error(rc)); 173 } 174 ddf_fun_destroy(mdev->luns[i]); 175 } 176 free(mdev->luns); 125 177 return rc; 126 178 } … … 162 214 } 163 215 216 mfun->ddf_fun = fun; 164 217 mfun->mdev = mdev; 165 218 mfun->lun = lun; … … 212 265 213 266 free(fun_name); 267 mdev->luns[lun] = fun; 214 268 215 269 return EOK; … … 293 347 294 348 /** USB mass storage driver ops. */ 295 static usb_driver_ops_t usbmast_driver_ops = {349 static const usb_driver_ops_t usbmast_driver_ops = { 296 350 .device_add = usbmast_device_add, 351 .device_rem = usbmast_device_remove, 352 .device_gone = usbmast_device_gone, 297 353 }; 298 354 299 355 /** USB mass storage driver. */ 300 static usb_driver_t usbmast_driver = {356 static const usb_driver_t usbmast_driver = { 301 357 .name = NAME, 302 358 .ops = &usbmast_driver_ops, -
uspace/drv/bus/usb/usbmast/usbmast.h
r4c3ad56 r20a3465 41 41 42 42 /** Mass storage device. */ 43 typedef struct {43 typedef struct usbmast_dev { 44 44 /** DDF device */ 45 45 ddf_dev_t *ddf_dev; … … 47 47 usb_device_t *usb_dev; 48 48 /** Number of LUNs */ 49 unsigned luns; 49 unsigned lun_count; 50 /** LUN functions */ 51 ddf_fun_t **luns; 50 52 } usbmast_dev_t; 53 51 54 52 55 /** Mass storage function. -
uspace/drv/bus/usb/usbmid/dump.c
r4c3ad56 r20a3465 47 47 * @param depth Nesting depth. 48 48 */ 49 static void dump_tree_descriptor( uint8_t *data, size_t depth)49 static void dump_tree_descriptor(const uint8_t *data, size_t depth) 50 50 { 51 51 if (data == NULL) { 52 52 return; 53 53 } 54 int type = (int) *(data + 1);54 const int type = data[1]; 55 55 if (type == USB_DESCTYPE_INTERFACE) { 56 56 usb_standard_interface_descriptor_t *descriptor … … 71 71 * @param depth Nesting depth. 72 72 */ 73 static void dump_tree_internal(usb_dp_parser_t *parser, usb_dp_parser_data_t *data, 74 uint8_t *root, size_t depth) 73 static void dump_tree_internal( 74 usb_dp_parser_t *parser, usb_dp_parser_data_t *data, 75 const uint8_t *root, size_t depth) 75 76 { 76 77 if (root == NULL) { … … 78 79 } 79 80 dump_tree_descriptor(root, depth); 80 uint8_t *child = usb_dp_get_nested_descriptor(parser, data, root);81 const uint8_t *child = usb_dp_get_nested_descriptor(parser, data, root); 81 82 do { 82 83 dump_tree_internal(parser, data, child, depth + 1); … … 92 93 static void dump_tree(usb_dp_parser_t *parser, usb_dp_parser_data_t *data) 93 94 { 94 uint8_t *ptr = data->data;95 const uint8_t *ptr = data->data; 95 96 dump_tree_internal(parser, data, ptr, 0); 96 97 } -
uspace/drv/bus/usb/usbmid/explore.c
r4c3ad56 r20a3465 73 73 * @param list List where to add the interfaces. 74 74 */ 75 static void create_interfaces( uint8_t *config_descriptor,75 static void create_interfaces(const uint8_t *config_descriptor, 76 76 size_t config_descriptor_size, list_t *list) 77 77 { 78 usb_dp_parser_data_t data = {78 const usb_dp_parser_data_t data = { 79 79 .data = config_descriptor, 80 80 .size = config_descriptor_size, … … 86 86 }; 87 87 88 uint8_t *interface_ptr = usb_dp_get_nested_descriptor(&parser, &data,89 data.data);88 const uint8_t *interface_ptr = 89 usb_dp_get_nested_descriptor(&parser, &data, data.data); 90 90 if (interface_ptr == NULL) { 91 91 return; … … 149 149 150 150 /* Short cuts to save on typing ;-). */ 151 uint8_t*config_descriptor_raw = dev->descriptors.configuration;151 const void *config_descriptor_raw = dev->descriptors.configuration; 152 152 size_t config_descriptor_size = dev->descriptors.configuration_size; 153 usb_standard_configuration_descriptor_t *config_descriptor =154 (usb_standard_configuration_descriptor_t *)config_descriptor_raw;153 const usb_standard_configuration_descriptor_t *config_descriptor = 154 config_descriptor_raw; 155 155 156 156 /* Select the first configuration */ … … 163 163 } 164 164 165 usb_mid_t *usb_mid = usb_device_data_alloc(dev, sizeof(usb_mid_t)); 166 if (!usb_mid) { 167 usb_log_error("Failed to create USB MID structure.\n"); 168 return false; 169 } 170 165 171 /* Create control function */ 166 ddf_fun_t *ctl_fun = ddf_fun_create(dev->ddf_dev, fun_exposed, "ctl");167 if ( ctl_fun == NULL) {172 usb_mid->ctl_fun = ddf_fun_create(dev->ddf_dev, fun_exposed, "ctl"); 173 if (usb_mid->ctl_fun == NULL) { 168 174 usb_log_error("Failed to create control function.\n"); 169 175 return false; 170 176 } 171 177 172 ctl_fun->ops = &mid_device_ops;173 174 rc = ddf_fun_bind( ctl_fun);178 usb_mid->ctl_fun->ops = &mid_device_ops; 179 180 rc = ddf_fun_bind(usb_mid->ctl_fun); 175 181 if (rc != EOK) { 176 182 usb_log_error("Failed to bind control function: %s.\n", 177 183 str_error(rc)); 178 return false; 179 } 184 ddf_fun_destroy(usb_mid->ctl_fun); 185 return false; 186 } 187 180 188 181 189 /* Create interface children. */ 182 list_t interface_list; 183 list_initialize(&interface_list); 190 list_initialize(&usb_mid->interface_list); 184 191 create_interfaces(config_descriptor_raw, config_descriptor_size, 185 & interface_list);186 187 list_foreach( interface_list, link) {192 &usb_mid->interface_list); 193 194 list_foreach(usb_mid->interface_list, link) { 188 195 usbmid_interface_t *iface = list_get_instance(link, 189 196 usbmid_interface_t, link); -
uspace/drv/bus/usb/usbmid/main.c
r4c3ad56 r20a3465 65 65 return EOK; 66 66 } 67 /*----------------------------------------------------------------------------*/ 68 /** Callback when a MID device is about to be removed from the host. 69 * 70 * @param gen_dev Generic DDF device representing the removed device. 71 * @return Error code. 72 */ 73 static int usbmid_device_remove(usb_device_t *dev) 74 { 75 assert(dev); 76 int ret = ENOTSUP; 77 usb_mid_t *usb_mid = dev->driver_data; 78 assert(usb_mid); 79 80 /* Signal all interface functions */ 81 list_foreach(usb_mid->interface_list, item) { 82 usbmid_interface_t *iface = usbmid_interface_from_link(item); 83 84 usb_log_info("Signaling remove to child for interface " 85 "%d (%s).\n", iface->interface_no, 86 usb_str_class(iface->interface->interface_class)); 87 // TODO cascade the call. 88 } 89 return ret; 90 } 91 /*----------------------------------------------------------------------------*/ 92 /** Callback when a MID device was removed from the host. 93 * 94 * @param gen_dev Generic DDF device representing the removed device. 95 * @return Error code. 96 */ 97 static int usbmid_device_gone(usb_device_t *dev) 98 { 99 assert(dev); 100 usb_log_info("USB MID gone: `%s'.\n", dev->ddf_dev->name); 101 102 /* Remove ctl function */ 103 usb_mid_t *usb_mid = dev->driver_data; 104 int ret = ddf_fun_unbind(usb_mid->ctl_fun); 105 if (ret != EOK) { 106 usb_log_error("Failed to unbind USB MID ctl function: %s.\n", 107 str_error(ret)); 108 return ret; 109 } 110 ddf_fun_destroy(usb_mid->ctl_fun); 111 112 /* Now remove all other functions */ 113 while (!list_empty(&usb_mid->interface_list)) { 114 link_t *item = list_first(&usb_mid->interface_list); 115 list_remove(item); 116 117 usbmid_interface_t *iface = usbmid_interface_from_link(item); 118 119 usb_log_info("Removing child for interface %d (%s).\n", 120 iface->interface_no, 121 usb_str_class(iface->interface->interface_class)); 122 123 const int pret = usbmid_interface_destroy(iface); 124 if (pret != EOK) { 125 usb_log_error("Failed to remove child for interface " 126 "%d (%s): %s\n", 127 iface->interface_no, 128 usb_str_class(iface->interface->interface_class), 129 str_error(pret)); 130 ret = pret; 131 } 132 } 133 return ret; 134 } 67 135 68 136 /** USB MID driver ops. */ 69 static usb_driver_ops_t mid_driver_ops = {137 static const usb_driver_ops_t mid_driver_ops = { 70 138 .device_add = usbmid_device_add, 139 .device_rem = usbmid_device_remove, 140 .device_gone = usbmid_device_gone, 71 141 }; 72 142 73 143 /** USB MID driver. */ 74 static usb_driver_t mid_driver = {144 static const usb_driver_t mid_driver = { 75 145 .name = NAME, 76 146 .ops = &mid_driver_ops, -
uspace/drv/bus/usb/usbmid/usbmid.c
r4c3ad56 r20a3465 45 45 46 46 /** Callback for DDF USB interface. */ 47 static int usb_iface_get_address_impl(ddf_fun_t *fun, devman_handle_t handle,48 usb_address_t *address)49 {50 return usb_iface_get_address_hub_impl(fun, handle, address);51 }52 53 /** Callback for DDF USB interface. */54 47 static int usb_iface_get_interface_impl(ddf_fun_t *fun, devman_handle_t handle, 55 48 int *iface_no) … … 70 63 static usb_iface_t child_usb_iface = { 71 64 .get_hc_handle = usb_iface_get_hc_handle_hub_child_impl, 72 .get_address = usb_iface_get_address_ impl,65 .get_address = usb_iface_get_address_hub_impl, 73 66 .get_interface = usb_iface_get_interface_impl 74 67 }; … … 79 72 }; 80 73 74 int usbmid_interface_destroy(usbmid_interface_t *mid_iface) 75 { 76 assert(mid_iface); 77 assert_link_not_used(&mid_iface->link); 78 const int ret = ddf_fun_unbind(mid_iface->fun); 79 if (ret != EOK) { 80 return ret; 81 } 82 /* NOTE: usbmid->interface points somewhere, but we did not 83 * allocate that space, so don't touch */ 84 ddf_fun_destroy(mid_iface->fun); 85 /* NOTE: mid_iface is invalid at this point, it was assigned to 86 * mid_iface->fun->driver_data and freed in ddf_fun_destroy */ 87 return EOK; 88 } 81 89 82 90 /** Spawn new child device from one interface. … … 106 114 (int) interface_descriptor->interface_number); 107 115 if (rc < 0) { 108 goto error_leave;116 return ENOMEM; 109 117 } 110 118 111 119 /* Create the device. */ 112 120 child = ddf_fun_create(parent->ddf_dev, fun_inner, child_name); 121 free(child_name); 113 122 if (child == NULL) { 114 rc = ENOMEM; 115 goto error_leave; 123 return ENOMEM; 116 124 } 117 125 … … 122 130 123 131 rc = usb_device_create_match_ids_from_interface(device_descriptor, 124 interface_descriptor, 125 &child->match_ids); 132 interface_descriptor, &child->match_ids); 126 133 if (rc != EOK) { 127 goto error_leave; 134 ddf_fun_destroy(child); 135 return rc; 128 136 } 129 137 130 138 rc = ddf_fun_bind(child); 131 139 if (rc != EOK) { 132 goto error_leave; 140 /* This takes care of match_id deallocation as well. */ 141 ddf_fun_destroy(child); 142 return rc; 133 143 } 134 144 135 145 return EOK; 136 137 error_leave:138 if (child != NULL) {139 child->name = NULL;140 /* This takes care of match_id deallocation as well. */141 ddf_fun_destroy(child);142 }143 if (child_name != NULL) {144 free(child_name);145 }146 147 return rc;148 146 } 149 147 -
uspace/drv/bus/usb/usbmid/usbmid.h
r4c3ad56 r20a3465 58 58 } usbmid_interface_t; 59 59 60 /** Container to hold all the function pointers */ 61 typedef struct usb_mid { 62 ddf_fun_t *ctl_fun; 63 list_t interface_list; 64 } usb_mid_t; 65 60 66 bool usbmid_explore_device(usb_device_t *); 61 67 int usbmid_spawn_interface_child(usb_device_t *, usbmid_interface_t *, … … 63 69 const usb_standard_interface_descriptor_t *); 64 70 void usbmid_dump_descriptors(uint8_t *, size_t); 71 int usbmid_interface_destroy(usbmid_interface_t *mid_iface); 72 73 static inline usbmid_interface_t * usbmid_interface_from_link(link_t *item) 74 { 75 return list_get_instance(item, usbmid_interface_t, link); 76 } 65 77 66 78 #endif -
uspace/drv/bus/usb/vhc/connhost.c
r4c3ad56 r20a3465 104 104 { 105 105 VHC_DATA(vhc, fun); 106 bool found = 107 usb_device_manager_find_by_address(&vhc->dev_manager, address, handle); 108 return found ? EOK : ENOENT; 106 return usb_device_manager_get_info_by_address( 107 &vhc->dev_manager, address, handle, NULL); 109 108 } 110 109 … … 141 140 size_t max_packet_size, unsigned int interval) 142 141 { 143 /* TODO: Use usb_endpoint_manager_add_ep */ 144 VHC_DATA(vhc, fun); 145 146 endpoint_t *ep = endpoint_get( 147 address, endpoint, direction, transfer_type, USB_SPEED_FULL, 1); 148 if (ep == NULL) { 149 return ENOMEM; 150 } 151 152 int rc = usb_endpoint_manager_register_ep(&vhc->ep_manager, ep, 1); 153 if (rc != EOK) { 154 endpoint_destroy(ep); 155 return rc; 156 } 157 158 return EOK; 142 VHC_DATA(vhc, fun); 143 144 return usb_endpoint_manager_add_ep(&vhc->ep_manager, 145 address, endpoint, direction, transfer_type, USB_SPEED_FULL, 1, 0, 146 NULL, NULL); 147 159 148 } 160 149 … … 172 161 VHC_DATA(vhc, fun); 173 162 174 int rc = usb_endpoint_manager_ unregister_ep(&vhc->ep_manager,175 address, endpoint, direction );163 int rc = usb_endpoint_manager_remove_ep(&vhc->ep_manager, 164 address, endpoint, direction, NULL, NULL); 176 165 177 166 return rc; … … 414 403 VHC_DATA(vhc, fun); 415 404 416 endpoint_t *ep = usb_endpoint_manager_ get_ep(&vhc->ep_manager,417 target.address, target.endpoint, USB_DIRECTION_IN , NULL);405 endpoint_t *ep = usb_endpoint_manager_find_ep(&vhc->ep_manager, 406 target.address, target.endpoint, USB_DIRECTION_IN); 418 407 if (ep == NULL) { 419 408 return ENOENT; … … 456 445 VHC_DATA(vhc, fun); 457 446 458 endpoint_t *ep = usb_endpoint_manager_ get_ep(&vhc->ep_manager,459 target.address, target.endpoint, USB_DIRECTION_OUT , NULL);447 endpoint_t *ep = usb_endpoint_manager_find_ep(&vhc->ep_manager, 448 target.address, target.endpoint, USB_DIRECTION_OUT); 460 449 if (ep == NULL) { 461 450 return ENOENT; … … 518 507 519 508 usb_log_debug("tell_address_rh(handle=%" PRIun ")\n", handle); 520 usb_address_t addr = usb_device_manager_find(&vhc->dev_manager, handle); 509 const usb_address_t addr = 510 usb_device_manager_find_address(&vhc->dev_manager, handle); 521 511 if (addr < 0) { 522 512 return addr;
Note:
See TracChangeset
for help on using the changeset viewer.
