Changeset 747ef72 in mainline for uspace/drv/bus
- Timestamp:
- 2011-11-10T11:29:10Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 54464f6a, c2245a3, c6f189f7
- Parents:
- 2e1b9dc (diff), 2d1ba51 (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:
-
- 28 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ehci/hc_iface.c
r2e1b9dc r747ef72 56 56 * @return Error code. 57 57 */ 58 static int request_address(ddf_fun_t *fun, usb_ speed_t speed,59 usb_ address_t *address)58 static int request_address(ddf_fun_t *fun, usb_address_t *address, bool strict, 59 usb_speed_t speed) 60 60 { 61 61 UNSUPPORTED("request_address"); … … 120 120 */ 121 121 static int register_endpoint(ddf_fun_t *fun, 122 usb_address_t address, usb_ speed_t speed, usb_endpoint_t endpoint,122 usb_address_t address, usb_endpoint_t endpoint, 123 123 usb_transfer_type_t transfer_type, usb_direction_t direction, 124 124 size_t max_packet_size, unsigned int interval) -
uspace/drv/bus/usb/ohci/hc.c
r2e1b9dc r747ef72 127 127 assert(hub_fun); 128 128 129 const usb_address_t hub_address = 130 usb_device_manager_get_free_address( 131 &instance->generic.dev_manager, USB_SPEED_FULL); 132 if (hub_address <= 0) { 129 /* Try to get address 1 for root hub. */ 130 instance->rh.address = 1; 131 int ret = usb_device_manager_request_address( 132 &instance->generic.dev_manager, &instance->rh.address, false, 133 USB_SPEED_FULL); 134 if (ret != EOK) { 133 135 usb_log_error("Failed to get OHCI root hub address: %s\n", 134 str_error(hub_address)); 135 return hub_address; 136 } 137 instance->rh.address = hub_address; 138 usb_device_manager_bind( 139 &instance->generic.dev_manager, hub_address, hub_fun->handle); 136 str_error(ret)); 137 return ret; 138 } 139 usb_device_manager_bind_address(&instance->generic.dev_manager, 140 instance->rh.address, hub_fun->handle); 140 141 141 142 #define CHECK_RET_UNREG_RETURN(ret, message...) \ … … 143 144 usb_log_error(message); \ 144 145 usb_endpoint_manager_remove_ep( \ 145 &instance->generic.ep_manager, hub_address, 0, USB_DIRECTION_BOTH, \146 NULL, NULL);\147 usb_device_manager_release ( \148 &instance->generic.dev_manager, hub_address); \146 &instance->generic.ep_manager, instance->rh.address, 0, \ 147 USB_DIRECTION_BOTH, NULL, NULL); \ 148 usb_device_manager_release_address( \ 149 &instance->generic.dev_manager, instance->rh.address); \ 149 150 return ret; \ 150 151 } else (void)0 151 int ret = usb_endpoint_manager_add_ep( 152 &instance->generic.ep_manager, hub_address, 0, USB_DIRECTION_BOTH, 153 USB_TRANSFER_CONTROL, USB_SPEED_FULL, 64, 0, NULL, NULL); 152 ret = usb_endpoint_manager_add_ep( 153 &instance->generic.ep_manager, instance->rh.address, 0, 154 USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL, USB_SPEED_FULL, 64, 155 0, NULL, NULL); 154 156 CHECK_RET_UNREG_RETURN(ret, 155 157 "Failed to register root hub control endpoint: %s.\n", … … 193 195 list_initialize(&instance->pending_batches); 194 196 195 hcd_init(&instance->generic, BANDWIDTH_AVAILABLE_USB11,196 bandwidth_count_usb11);197 hcd_init(&instance->generic, USB_SPEED_FULL, 198 BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11); 197 199 instance->generic.private_data = instance; 198 200 instance->generic.schedule = hc_schedule; -
uspace/drv/bus/usb/ohci/ohci.c
r2e1b9dc r747ef72 76 76 } 77 77 /*----------------------------------------------------------------------------*/ 78 /** Get address of the device identified by handle. 79 * 80 * @param[in] dev DDF instance of the device to use. 81 * @param[in] iid (Unused). 82 * @param[in] call Pointer to the call that represents interrupt. 83 */ 84 static int usb_iface_get_address( 85 ddf_fun_t *fun, devman_handle_t handle, usb_address_t *address) 78 /** Get USB address assigned to root hub. 79 * 80 * @param[in] fun Root hub function. 81 * @param[out] address Store the address here. 82 * @return Error code. 83 */ 84 static int rh_get_my_address(ddf_fun_t *fun, usb_address_t *address) 86 85 { 87 86 assert(fun); 88 usb_device_manager_t *manager =89 &dev_to_ohci(fun->dev)->hc.generic.dev_manager;90 91 const usb_address_t addr =92 usb_device_manager_find_address(manager, handle);93 if (addr < 0) {94 return addr;95 }96 87 97 88 if (address != NULL) { 98 *address = addr;89 *address = dev_to_ohci(fun->dev)->hc.rh.address; 99 90 } 100 91 … … 108 99 * @return Error code. 109 100 */ 110 static int usb_iface_get_hc_handle(101 static int rh_get_hc_handle( 111 102 ddf_fun_t *fun, devman_handle_t *handle) 112 103 { … … 122 113 /** Root hub USB interface */ 123 114 static usb_iface_t usb_iface = { 124 .get_hc_handle = usb_iface_get_hc_handle,125 .get_ address = usb_iface_get_address115 .get_hc_handle = rh_get_hc_handle, 116 .get_my_address = rh_get_my_address, 126 117 }; 127 118 /*----------------------------------------------------------------------------*/ -
uspace/drv/bus/usb/uhci/hc.c
r2e1b9dc r747ef72 199 199 #undef CHECK_RET_RETURN 200 200 201 hcd_init(&instance->generic, BANDWIDTH_AVAILABLE_USB11,202 bandwidth_count_usb11);201 hcd_init(&instance->generic, USB_SPEED_FULL, 202 BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11); 203 203 204 204 instance->generic.private_data = instance; -
uspace/drv/bus/usb/uhci/uhci.c
r2e1b9dc r747ef72 89 89 }; 90 90 /*----------------------------------------------------------------------------*/ 91 /** Get address of the device identified by handle.92 *93 * @param[in] fun DDF instance of the function to use.94 * @param[in] handle DDF handle of the driver seeking its USB address.95 * @param[out] address Found address.96 */97 static int usb_iface_get_address(98 ddf_fun_t *fun, devman_handle_t handle, usb_address_t *address)99 {100 assert(fun);101 usb_device_manager_t *manager =102 &dev_to_uhci(fun->dev)->hc.generic.dev_manager;103 const usb_address_t addr =104 usb_device_manager_find_address(manager, handle);105 106 if (addr < 0) {107 return addr;108 }109 110 if (address != NULL) {111 *address = addr;112 }113 114 return EOK;115 }116 /*----------------------------------------------------------------------------*/117 91 /** Gets handle of the respective hc. 118 92 * … … 135 109 static usb_iface_t usb_iface = { 136 110 .get_hc_handle = usb_iface_get_hc_handle, 137 .get_address = usb_iface_get_address138 111 }; 139 112 /*----------------------------------------------------------------------------*/ -
uspace/drv/bus/usb/usbflbk/main.c
r2e1b9dc r747ef72 74 74 } 75 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 76 /** Callback when new device is removed and recognized as gone by DDF. 87 77 * … … 107 97 static const usb_driver_ops_t usbfallback_driver_ops = { 108 98 .device_add = usbfallback_device_add, 109 .device_rem = usbfallback_device_ remove,99 .device_rem = usbfallback_device_gone, 110 100 .device_gone = usbfallback_device_gone, 111 101 }; -
uspace/drv/bus/usb/usbhid/generic/hiddev.c
r2e1b9dc r747ef72 61 61 62 62 /*----------------------------------------------------------------------------*/ 63 64 63 static size_t usb_generic_hid_get_event_length(ddf_fun_t *fun); 65 66 static int usb_generic_hid_get_event(ddf_fun_t *fun, uint8_t *buffer, 64 static int usb_generic_hid_get_event(ddf_fun_t *fun, uint8_t *buffer, 67 65 size_t size, size_t *act_size, int *event_nr, unsigned int flags); 68 69 66 static int usb_generic_hid_client_connected(ddf_fun_t *fun); 70 71 67 static size_t usb_generic_get_report_descriptor_length(ddf_fun_t *fun); 72 73 static int usb_generic_get_report_descriptor(ddf_fun_t *fun, uint8_t *desc, 68 static int usb_generic_get_report_descriptor(ddf_fun_t *fun, uint8_t *desc, 74 69 size_t size, size_t *actual_size); 75 76 /*----------------------------------------------------------------------------*/ 77 70 /*----------------------------------------------------------------------------*/ 78 71 static usbhid_iface_t usb_generic_iface = { 79 72 .get_event = usb_generic_hid_get_event, … … 82 75 .get_report_descriptor = usb_generic_get_report_descriptor 83 76 }; 84 77 /*----------------------------------------------------------------------------*/ 85 78 static ddf_dev_ops_t usb_generic_hid_ops = { 86 79 .interfaces[USBHID_DEV_IFACE] = &usb_generic_iface, 87 80 .open = usb_generic_hid_client_connected 88 81 }; 89 90 /*----------------------------------------------------------------------------*/ 91 82 /*----------------------------------------------------------------------------*/ 92 83 static size_t usb_generic_hid_get_event_length(ddf_fun_t *fun) 93 84 { … … 99 90 } 100 91 101 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;92 const usb_hid_dev_t *hid_dev = fun->driver_data; 102 93 103 94 usb_log_debug2("hid_dev: %p, Max input report size (%zu).\n", … … 106 97 return hid_dev->max_input_report_size; 107 98 } 108 109 /*----------------------------------------------------------------------------*/ 110 111 static int usb_generic_hid_get_event(ddf_fun_t *fun, uint8_t *buffer, 99 /*----------------------------------------------------------------------------*/ 100 static int usb_generic_hid_get_event(ddf_fun_t *fun, uint8_t *buffer, 112 101 size_t size, size_t *act_size, int *event_nr, unsigned int flags) 113 102 { … … 120 109 } 121 110 122 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;111 const usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data; 123 112 124 113 if (hid_dev->input_report_size > size) { 125 usb_log_debug("input_report_size > size (%zu, %zu)\n", 114 usb_log_debug("input_report_size > size (%zu, %zu)\n", 126 115 hid_dev->input_report_size, size); 127 116 return EINVAL; // TODO: other error code … … 129 118 130 119 /*! @todo This should probably be somehow atomic. */ 131 memcpy(buffer, hid_dev->input_report, 120 memcpy(buffer, hid_dev->input_report, 132 121 hid_dev->input_report_size); 133 122 *act_size = hid_dev->input_report_size; … … 138 127 return EOK; 139 128 } 140 141 /*----------------------------------------------------------------------------*/ 142 129 /*----------------------------------------------------------------------------*/ 143 130 static size_t usb_generic_get_report_descriptor_length(ddf_fun_t *fun) 144 131 { … … 150 137 } 151 138 152 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;153 154 usb_log_debug2("hid_dev->report_desc_size = %zu\n", 139 const usb_hid_dev_t *hid_dev = fun->driver_data; 140 141 usb_log_debug2("hid_dev->report_desc_size = %zu\n", 155 142 hid_dev->report_desc_size); 156 143 157 144 return hid_dev->report_desc_size; 158 145 } 159 160 /*----------------------------------------------------------------------------*/ 161 162 static int usb_generic_get_report_descriptor(ddf_fun_t *fun, uint8_t *desc, 146 /*----------------------------------------------------------------------------*/ 147 static int usb_generic_get_report_descriptor(ddf_fun_t *fun, uint8_t *desc, 163 148 size_t size, size_t *actual_size) 164 149 { … … 170 155 } 171 156 172 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;157 const usb_hid_dev_t *hid_dev = fun->driver_data; 173 158 174 159 if (hid_dev->report_desc_size > size) { … … 181 166 return EOK; 182 167 } 183 184 /*----------------------------------------------------------------------------*/ 185 168 /*----------------------------------------------------------------------------*/ 186 169 static int usb_generic_hid_client_connected(ddf_fun_t *fun) 187 170 { … … 189 172 return EOK; 190 173 } 191 192 /*----------------------------------------------------------------------------*/ 193 174 /*----------------------------------------------------------------------------*/ 194 175 void usb_generic_hid_deinit(usb_hid_dev_t *hid_dev, void *data) 195 176 { 196 177 ddf_fun_t *fun = data; 197 const int ret = ddf_fun_unbind(fun); 198 if (ret != EOK) { 178 if (fun == NULL) 179 return; 180 181 if (ddf_fun_unbind(fun) != EOK) { 199 182 usb_log_error("Failed to unbind generic hid fun.\n"); 200 183 return; … … 206 189 ddf_fun_destroy(fun); 207 190 } 208 209 /*----------------------------------------------------------------------------*/ 210 191 /*----------------------------------------------------------------------------*/ 211 192 int usb_generic_hid_init(usb_hid_dev_t *hid_dev, void **data) 212 193 { … … 216 197 217 198 /* Create the exposed function. */ 218 /** @todo Generate numbers for the devices? */219 199 usb_log_debug("Creating DDF function %s...\n", HID_GENERIC_FUN_NAME); 220 200 ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed, … … 225 205 } 226 206 207 /* This is nasty, both device and this function have the same 208 * driver data, thus destruction causes to double free */ 209 fun->driver_data = hid_dev; 227 210 fun->ops = &usb_generic_hid_ops; 228 211 … … 231 214 usb_log_error("Could not bind DDF function: %s.\n", 232 215 str_error(rc)); 216 fun->driver_data = NULL; 233 217 ddf_fun_destroy(fun); 234 218 return rc; 235 219 } 236 /* This is nasty both device and this function have the same237 * driver data, thus destruction would lead to double free */238 fun->driver_data = hid_dev;239 220 240 221 usb_log_debug("HID function created. Handle: %" PRIun "\n", fun->handle); … … 243 224 return EOK; 244 225 } 245 246 /*----------------------------------------------------------------------------*/ 247 226 /*----------------------------------------------------------------------------*/ 248 227 bool usb_generic_hid_polling_callback(usb_hid_dev_t *hid_dev, void *data) 249 228 { 250 229 return true; 251 230 } 252 253 231 /** 254 232 * @} -
uspace/drv/bus/usb/usbhid/kbd/kbddev.c
r2e1b9dc r747ef72 41 41 #include <io/keycode.h> 42 42 #include <io/console.h> 43 #include <abi/ipc/methods.h> 43 44 #include <ipc/kbdev.h> 44 45 #include <async.h> … … 86 87 87 88 /*----------------------------------------------------------------------------*/ 88 89 89 /** Keyboard polling endpoint description for boot protocol class. */ 90 90 const usb_endpoint_description_t usb_hid_kbd_poll_endpoint_description = { … … 101 101 102 102 static void usb_kbd_set_led(usb_hid_dev_t *hid_dev, usb_kbd_t *kbd_dev); 103 104 /*----------------------------------------------------------------------------*/ 105 106 enum { 107 USB_KBD_BOOT_REPORT_DESCRIPTOR_SIZE = 63 103 /*----------------------------------------------------------------------------*/ 104 static const uint8_t USB_KBD_BOOT_REPORT_DESCRIPTOR[] = { 105 0x05, 0x01, /* Usage Page (Generic Desktop), */ 106 0x09, 0x06, /* Usage (Keyboard), */ 107 0xA1, 0x01, /* Collection (Application), */ 108 0x75, 0x01, /* Report Size (1), */ 109 0x95, 0x08, /* Report Count (8), */ 110 0x05, 0x07, /* Usage Page (Key Codes); */ 111 0x19, 0xE0, /* Usage Minimum (224), */ 112 0x29, 0xE7, /* Usage Maximum (231), */ 113 0x15, 0x00, /* Logical Minimum (0), */ 114 0x25, 0x01, /* Logical Maximum (1), */ 115 0x81, 0x02, /* Input (Data, Variable, Absolute), ; Modifier byte */ 116 0x95, 0x01, /* Report Count (1), */ 117 0x75, 0x08, /* Report Size (8), */ 118 0x81, 0x01, /* Input (Constant), ; Reserved byte */ 119 0x95, 0x05, /* Report Count (5), */ 120 0x75, 0x01, /* Report Size (1), */ 121 0x05, 0x08, /* Usage Page (Page# for LEDs), */ 122 0x19, 0x01, /* Usage Minimum (1), */ 123 0x29, 0x05, /* Usage Maxmimum (5), */ 124 0x91, 0x02, /* Output (Data, Variable, Absolute), ; LED report */ 125 0x95, 0x01, /* Report Count (1), */ 126 0x75, 0x03, /* Report Size (3), */ 127 0x91, 0x01, /* Output (Constant), ; LED report padding */ 128 0x95, 0x06, /* Report Count (6), */ 129 0x75, 0x08, /* Report Size (8), */ 130 0x15, 0x00, /* Logical Minimum (0), */ 131 0x25, 0xff, /* Logical Maximum (255), */ 132 0x05, 0x07, /* Usage Page (Key Codes), */ 133 0x19, 0x00, /* Usage Minimum (0), */ 134 0x29, 0xff, /* Usage Maximum (255), */ 135 0x81, 0x00, /* Input (Data, Array), ; Key arrays (6 bytes) */ 136 0xC0 /* End Collection */ 108 137 }; 109 110 static const uint8_t USB_KBD_BOOT_REPORT_DESCRIPTOR[ 111 USB_KBD_BOOT_REPORT_DESCRIPTOR_SIZE] = { 112 0x05, 0x01, // Usage Page (Generic Desktop), 113 0x09, 0x06, // Usage (Keyboard), 114 0xA1, 0x01, // Collection (Application), 115 0x75, 0x01, // Report Size (1), 116 0x95, 0x08, // Report Count (8), 117 0x05, 0x07, // Usage Page (Key Codes); 118 0x19, 0xE0, // Usage Minimum (224), 119 0x29, 0xE7, // Usage Maximum (231), 120 0x15, 0x00, // Logical Minimum (0), 121 0x25, 0x01, // Logical Maximum (1), 122 0x81, 0x02, // Input (Data, Variable, Absolute), ; Modifier byte 123 0x95, 0x01, // Report Count (1), 124 0x75, 0x08, // Report Size (8), 125 0x81, 0x01, // Input (Constant), ; Reserved byte 126 0x95, 0x05, // Report Count (5), 127 0x75, 0x01, // Report Size (1), 128 0x05, 0x08, // Usage Page (Page# for LEDs), 129 0x19, 0x01, // Usage Minimum (1), 130 0x29, 0x05, // Usage Maxmimum (5), 131 0x91, 0x02, // Output (Data, Variable, Absolute), ; LED report 132 0x95, 0x01, // Report Count (1), 133 0x75, 0x03, // Report Size (3), 134 0x91, 0x01, // Output (Constant), ; LED report padding 135 0x95, 0x06, // Report Count (6), 136 0x75, 0x08, // Report Size (8), 137 0x15, 0x00, // Logical Minimum (0), 138 0x25, 0xff, // Logical Maximum (255), 139 0x05, 0x07, // Usage Page (Key Codes), 140 0x19, 0x00, // Usage Minimum (0), 141 0x29, 0xff, // Usage Maximum (255), 142 0x81, 0x00, // Input (Data, Array), ; Key arrays (6 bytes) 143 0xC0 // End Collection 144 145 }; 146 147 /*----------------------------------------------------------------------------*/ 148 138 /*----------------------------------------------------------------------------*/ 149 139 typedef enum usb_kbd_flags { 150 140 USB_KBD_STATUS_UNINITIALIZED = 0, … … 152 142 USB_KBD_STATUS_TO_DESTROY = -1 153 143 } usb_kbd_flags; 154 155 144 /*----------------------------------------------------------------------------*/ 156 145 /* IPC method handler */ 157 146 /*----------------------------------------------------------------------------*/ 158 159 static void default_connection_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *);160 161 147 /** 162 148 * Default handler for IPC methods not handled by DDF. 163 149 * 164 * Currently recognizes only one method (IPC_M_CONNECT_TO_ME), in which case it 165 * assumes the caller is the console and thus it stores IPC session to it for 166 * later use by the driver to notify about key events. 150 * Currently recognizes only two methods (IPC_M_CONNECT_TO_ME and KBDEV_SET_IND) 151 * IPC_M_CONNECT_TO_ME assumes the caller is the console and stores IPC 152 * session to it for later use by the driver to notify about key events. 153 * KBDEV_SET_IND sets LED keyboard indicators. 167 154 * 168 155 * @param fun Device function handling the call. … … 173 160 ipc_callid_t icallid, ipc_call_t *icall) 174 161 { 175 sysarg_t method = IPC_GET_IMETHOD(*icall); 176 177 usb_kbd_t *kbd_dev = (usb_kbd_t *) fun->driver_data; 178 if (kbd_dev == NULL) { 179 usb_log_debug("default_connection_handler: " 180 "Missing parameter.\n"); 162 if (fun == NULL || fun->driver_data == NULL) { 163 usb_log_error("%s: Missing parameter.\n", __FUNCTION__); 181 164 async_answer_0(icallid, EINVAL); 182 165 return; 183 166 } 184 167 185 async_sess_t *sess = 186 async_callback_receive_start(EXCHANGE_SERIALIZE, icall); 187 if (sess != NULL) { 168 const sysarg_t method = IPC_GET_IMETHOD(*icall); 169 usb_kbd_t *kbd_dev = fun->driver_data; 170 171 switch (method) { 172 case KBDEV_SET_IND: 173 kbd_dev->mods = IPC_GET_ARG1(*icall); 174 usb_kbd_set_led(kbd_dev->hid_dev, kbd_dev); 175 async_answer_0(icallid, EOK); 176 break; 177 /* This might be ugly but async_callback_receive_start makes no 178 * difference for incorrect call and malloc failure. */ 179 case IPC_M_CONNECT_TO_ME: { 180 async_sess_t *sess = 181 async_callback_receive_start(EXCHANGE_SERIALIZE, icall); 182 /* Probably ENOMEM error, try again. */ 183 if (sess == NULL) { 184 usb_log_warning( 185 "Failed to create start console session.\n"); 186 async_answer_0(icallid, EAGAIN); 187 break; 188 } 188 189 if (kbd_dev->console_sess == NULL) { 189 190 kbd_dev->console_sess = sess; 190 usb_log_debug(" default_connection_handler: OK\n");191 usb_log_debug("%s: OK\n", __FUNCTION__); 191 192 async_answer_0(icallid, EOK); 192 193 } else { 193 usb_log_ debug("default_connection_handler: "194 "console session already set\n");194 usb_log_error("%s: console session already set\n", 195 __FUNCTION__); 195 196 async_answer_0(icallid, ELIMIT); 196 197 } 197 } else { 198 switch (method) { 199 case KBDEV_SET_IND: 200 kbd_dev->mods = IPC_GET_ARG1(*icall); 201 usb_kbd_set_led(kbd_dev->hid_dev, kbd_dev); 202 async_answer_0(icallid, EOK); 203 break; 204 default: 205 usb_log_debug("default_connection_handler: Wrong function.\n"); 198 break; 199 } 200 default: 201 usb_log_error("%s: Unknown method: %d.\n", 202 __FUNCTION__, (int) method); 206 203 async_answer_0(icallid, EINVAL); 207 204 break; 208 } 209 } 210 } 211 205 } 206 207 } 212 208 /*----------------------------------------------------------------------------*/ 213 209 /* Key processing functions */ … … 226 222 * @param kbd_dev Keyboard device structure. 227 223 */ 228 static void usb_kbd_set_led(usb_hid_dev_t *hid_dev, usb_kbd_t *kbd_dev) 224 static void usb_kbd_set_led(usb_hid_dev_t *hid_dev, usb_kbd_t *kbd_dev) 229 225 { 230 226 if (kbd_dev->output_size == 0) { … … 274 270 } 275 271 276 usb_log_debug("Output report buffer: %s\n", 277 usb_debug_str_buffer(kbd_dev->output_buffer, kbd_dev->output_size, 272 usb_log_debug("Output report buffer: %s\n", 273 usb_debug_str_buffer(kbd_dev->output_buffer, kbd_dev->output_size, 278 274 0)); 279 275 280 usbhid_req_set_report(&hid_dev->usb_dev->ctrl_pipe,281 hid_dev->usb_dev->interface_no, USB_HID_REPORT_TYPE_OUTPUT, 276 rc = usbhid_req_set_report(&hid_dev->usb_dev->ctrl_pipe, 277 hid_dev->usb_dev->interface_no, USB_HID_REPORT_TYPE_OUTPUT, 282 278 kbd_dev->output_buffer, kbd_dev->output_size); 283 } 284 279 if (rc != EOK) { 280 usb_log_warning("Failed to set kbd indicators.\n"); 281 } 282 } 285 283 /*----------------------------------------------------------------------------*/ 286 284 /** Send key event. … … 291 289 * @param key Key code 292 290 */ 293 void usb_kbd_push_ev(usb_hid_dev_t *hid_dev, usb_kbd_t *kbd_dev, int type, 294 unsigned int key) 291 void usb_kbd_push_ev(usb_kbd_t *kbd_dev, int type, unsigned key) 295 292 { 296 293 usb_log_debug2("Sending kbdev event %d/%d to the console\n", type, key); … … 302 299 303 300 async_exch_t *exch = async_exchange_begin(kbd_dev->console_sess); 304 async_msg_2(exch, KBDEV_EVENT, type, key); 305 async_exchange_end(exch); 306 } 307 308 /*----------------------------------------------------------------------------*/ 309 310 static inline int usb_kbd_is_lock(unsigned int key_code) 301 if (exch != NULL) { 302 async_msg_2(exch, KBDEV_EVENT, type, key); 303 async_exchange_end(exch); 304 } else { 305 usb_log_warning("Failed to send key to console.\n"); 306 } 307 } 308 /*----------------------------------------------------------------------------*/ 309 static inline int usb_kbd_is_lock(unsigned int key_code) 311 310 { 312 311 return (key_code == KC_NUM_LOCK … … 314 313 || key_code == KC_CAPS_LOCK); 315 314 } 316 315 /*----------------------------------------------------------------------------*/ 317 316 static size_t find_in_array_int32(int32_t val, int32_t *arr, size_t arr_size) 318 317 { … … 325 324 return (size_t) -1; 326 325 } 327 328 326 /*----------------------------------------------------------------------------*/ 329 327 /** … … 342 340 * @sa usb_kbd_push_ev(), usb_kbd_repeat_start(), usb_kbd_repeat_stop() 343 341 */ 344 static void usb_kbd_check_key_changes(usb_hid_dev_t *hid_dev, 342 static void usb_kbd_check_key_changes(usb_hid_dev_t *hid_dev, 345 343 usb_kbd_t *kbd_dev) 346 344 { 347 unsigned int key;348 size_t i;349 345 350 346 /* … … 356 352 * whole input report. 357 353 */ 358 i = find_in_array_int32(ERROR_ROLLOVER, kbd_dev->keys,354 size_t i = find_in_array_int32(ERROR_ROLLOVER, kbd_dev->keys, 359 355 kbd_dev->key_count); 360 356 if (i != (size_t) -1) { 361 usb_log_ debug("Detected phantom state.\n");357 usb_log_error("Detected phantom state.\n"); 362 358 return; 363 359 } … … 367 363 */ 368 364 for (i = 0; i < kbd_dev->key_count; i++) { 369 int32_t old_key = kbd_dev->keys_old[i];365 const int32_t old_key = kbd_dev->keys_old[i]; 370 366 /* Find the old key among currently pressed keys. */ 371 size_t pos = find_in_array_int32(old_key, kbd_dev->keys,367 const size_t pos = find_in_array_int32(old_key, kbd_dev->keys, 372 368 kbd_dev->key_count); 373 369 /* If the key was not found, we need to signal release. */ 374 370 if (pos == (size_t) -1) { 375 key = usbhid_parse_scancode(old_key);371 const unsigned key = usbhid_parse_scancode(old_key); 376 372 if (!usb_kbd_is_lock(key)) { 377 373 usb_kbd_repeat_stop(kbd_dev, key); 378 374 } 379 usb_kbd_push_ev( hid_dev,kbd_dev, KEY_RELEASE, key);375 usb_kbd_push_ev(kbd_dev, KEY_RELEASE, key); 380 376 usb_log_debug2("Key released: %u " 381 377 "(USB code %" PRIu32 ")\n", key, old_key); … … 387 383 */ 388 384 for (i = 0; i < kbd_dev->key_count; ++i) { 389 int32_t new_key = kbd_dev->keys[i];385 const int32_t new_key = kbd_dev->keys[i]; 390 386 /* Find the new key among already pressed keys. */ 391 size_t pos = find_in_array_int32(new_key, kbd_dev->keys_old,392 kbd_dev->key _count);387 const size_t pos = find_in_array_int32(new_key, 388 kbd_dev->keys_old, kbd_dev->key_count); 393 389 /* If the key was not found, we need to signal press. */ 394 390 if (pos == (size_t) -1) { 395 key = usbhid_parse_scancode(kbd_dev->keys[i]);391 unsigned key = usbhid_parse_scancode(kbd_dev->keys[i]); 396 392 if (!usb_kbd_is_lock(key)) { 397 393 usb_kbd_repeat_start(kbd_dev, key); 398 394 } 399 usb_kbd_push_ev( hid_dev,kbd_dev, KEY_PRESS, key);395 usb_kbd_push_ev(kbd_dev, KEY_PRESS, key); 400 396 usb_log_debug2("Key pressed: %u " 401 397 "(USB code %" PRIu32 ")\n", key, new_key); … … 405 401 memcpy(kbd_dev->keys_old, kbd_dev->keys, kbd_dev->key_count * 4); 406 402 403 // TODO Get rid of this 407 404 char key_buffer[512]; 408 405 ddf_dump_buffer(key_buffer, 512, … … 410 407 usb_log_debug2("Stored keys %s.\n", key_buffer); 411 408 } 412 413 409 /*----------------------------------------------------------------------------*/ 414 410 /* General kbd functions */ … … 436 432 437 433 usb_hid_report_path_t *path = usb_hid_report_path(); 438 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0); 439 440 usb_hid_report_path_set_report_id (path, hid_dev->report_id); 441 442 // fill in the currently pressed keys 443 434 if (path == NULL) { 435 usb_log_error("Failed to create hid/kbd report path.\n"); 436 return; 437 } 438 439 int ret = 440 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0); 441 if (ret != EOK) { 442 usb_log_error("Failed to append to hid/kbd report path.\n"); 443 return; 444 } 445 446 usb_hid_report_path_set_report_id(path, hid_dev->report_id); 447 448 /* Fill in the currently pressed keys. */ 444 449 usb_hid_report_field_t *field = usb_hid_report_get_sibling( 445 450 &hid_dev->report, NULL, path, … … 449 454 450 455 while (field != NULL) { 451 usb_log_debug2("FIELD (%p) - VALUE(%d) USAGE(%u)\n", 456 usb_log_debug2("FIELD (%p) - VALUE(%d) USAGE(%u)\n", 452 457 field, field->value, field->usage); 453 458 454 459 assert(i < kbd_dev->key_count); 455 460 456 / / save the key usage461 /* Save the key usage. */ 457 462 if (field->value != 0) { 458 463 kbd_dev->keys[i] = field->usage; … … 474 479 usb_kbd_check_key_changes(hid_dev, kbd_dev); 475 480 } 476 477 481 /*----------------------------------------------------------------------------*/ 478 482 /* HID/KBD structure manipulation */ 479 483 /*----------------------------------------------------------------------------*/ 480 481 static void usb_kbd_mark_unusable(usb_kbd_t *kbd_dev)482 {483 kbd_dev->initialized = USB_KBD_STATUS_TO_DESTROY;484 }485 486 /*----------------------------------------------------------------------------*/487 488 /**489 * Creates a new USB/HID keyboard structure.490 *491 * The structure returned by this function is not initialized. Use492 * usb_kbd_init() to initialize it prior to polling.493 *494 * @return New uninitialized structure for representing a USB/HID keyboard or495 * NULL if not successful (memory error).496 */497 static usb_kbd_t *usb_kbd_new(void)498 {499 usb_kbd_t *kbd_dev =500 (usb_kbd_t *)calloc(1, sizeof(usb_kbd_t));501 502 if (kbd_dev == NULL) {503 usb_log_error("No memory!\n");504 return NULL;505 }506 507 kbd_dev->console_sess = NULL;508 kbd_dev->initialized = USB_KBD_STATUS_UNINITIALIZED;509 510 return kbd_dev;511 }512 513 /*----------------------------------------------------------------------------*/514 515 484 static int usb_kbd_create_function(usb_kbd_t *kbd_dev) 516 485 { … … 528 497 } 529 498 530 /* 531 * Store the initialized HID device and HID ops 532 * to the DDF function. 533 */ 499 /* Store the initialized HID device and HID ops 500 * to the DDF function. */ 534 501 fun->ops = &kbd_dev->ops; 535 502 fun->driver_data = kbd_dev; … … 539 506 usb_log_error("Could not bind DDF function: %s.\n", 540 507 str_error(rc)); 541 fun->driver_data = NULL; /* We need this later*/508 fun->driver_data = NULL; /* We did not allocate this. */ 542 509 ddf_fun_destroy(fun); 543 510 return rc; … … 547 514 HID_KBD_FUN_NAME, fun->handle); 548 515 549 usb_log_debug("Adding DDF function to category %s...\n", 516 usb_log_debug("Adding DDF function to category %s...\n", 550 517 HID_KBD_CLASS_NAME); 551 518 rc = ddf_fun_add_to_category(fun, HID_KBD_CATEGORY_NAME); … … 554 521 "Could not add DDF function to category %s: %s.\n", 555 522 HID_KBD_CLASS_NAME, str_error(rc)); 556 fun->driver_data = NULL; /* We need this later */ 557 ddf_fun_destroy(fun); 523 if (ddf_fun_unbind(fun) == EOK) { 524 fun->driver_data = NULL; /* We did not allocate this. */ 525 ddf_fun_destroy(fun); 526 } else { 527 usb_log_error( 528 "Failed to unbind `%s', will not destroy.\n", 529 fun->name); 530 } 558 531 return rc; 559 532 } … … 562 535 return EOK; 563 536 } 564 565 537 /*----------------------------------------------------------------------------*/ 566 538 /* API functions */ … … 591 563 592 564 if (hid_dev == NULL) { 593 usb_log_error( "Failed to init keyboard structure: no structure"594 " given.\n");565 usb_log_error( 566 "Failed to init keyboard structure: no structure given.\n"); 595 567 return EINVAL; 596 568 } 597 569 598 usb_kbd_t *kbd_dev = usb_kbd_new();570 usb_kbd_t *kbd_dev = calloc(1, sizeof(usb_kbd_t)); 599 571 if (kbd_dev == NULL) { 600 usb_log_error("Error while creating USB/HID KBD device " 601 "structure.\n"); 602 return ENOMEM; // TODO: some other code?? 603 } 572 usb_log_error("Failed to allocate KBD device structure.\n"); 573 return ENOMEM; 574 } 575 /* Default values */ 576 fibril_mutex_initialize(&kbd_dev->repeat_mtx); 577 kbd_dev->initialized = USB_KBD_STATUS_UNINITIALIZED; 578 kbd_dev->ops.default_handler = default_connection_handler; 604 579 605 580 /* Store link to HID device */ 606 581 kbd_dev->hid_dev = hid_dev; 607 582 608 /* 609 * TODO: make more general 610 */ 583 /* Modifiers and locks */ 584 kbd_dev->mods = DEFAULT_ACTIVE_MODS; 585 586 /* Autorepeat */ 587 kbd_dev->repeat.delay_before = DEFAULT_DELAY_BEFORE_FIRST_REPEAT; 588 kbd_dev->repeat.delay_between = DEFAULT_REPEAT_DELAY; 589 590 591 // TODO: make more general 611 592 usb_hid_report_path_t *path = usb_hid_report_path(); 612 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0); 593 if (path == NULL) { 594 usb_log_error("Failed to create kbd report path.\n"); 595 usb_kbd_destroy(kbd_dev); 596 return ENOMEM; 597 } 598 599 int ret = 600 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0); 601 if (ret != EOK) { 602 usb_log_error("Failed to append item to kbd report path.\n"); 603 usb_hid_report_path_free(path); 604 usb_kbd_destroy(kbd_dev); 605 return ret; 606 } 613 607 614 608 usb_hid_report_path_set_report_id(path, 0); 615 609 616 kbd_dev->key_count = usb_hid_report_size( 617 &hid_dev->report, 0, USB_HID_REPORT_TYPE_INPUT); 610 kbd_dev->key_count = 611 usb_hid_report_size(&hid_dev->report, 0, USB_HID_REPORT_TYPE_INPUT); 612 618 613 usb_hid_report_path_free(path); 619 614 … … 621 616 622 617 kbd_dev->keys = calloc(kbd_dev->key_count, sizeof(int32_t)); 623 624 618 if (kbd_dev->keys == NULL) { 625 usb_log_error(" No memory!\n");626 free(kbd_dev);619 usb_log_error("Failed to allocate key buffer.\n"); 620 usb_kbd_destroy(kbd_dev); 627 621 return ENOMEM; 628 622 } 629 623 630 kbd_dev->keys_old = 631 (int32_t *)calloc(kbd_dev->key_count, sizeof(int32_t)); 632 624 kbd_dev->keys_old = calloc(kbd_dev->key_count, sizeof(int32_t)); 633 625 if (kbd_dev->keys_old == NULL) { 634 usb_log_error("No memory!\n"); 635 free(kbd_dev->keys); 636 free(kbd_dev); 626 usb_log_error("Failed to allocate old_key buffer.\n"); 627 usb_kbd_destroy(kbd_dev); 637 628 return ENOMEM; 638 629 } 639 630 640 /* 641 * Output report 642 */ 631 /* Output report */ 643 632 kbd_dev->output_size = 0; 644 633 kbd_dev->output_buffer = usb_hid_report_output(&hid_dev->report, 645 634 &kbd_dev->output_size, 0); 646 635 if (kbd_dev->output_buffer == NULL) { 647 usb_log_ warning("Error creating output report buffer.\n");648 free(kbd_dev->keys);636 usb_log_error("Error creating output report buffer.\n"); 637 usb_kbd_destroy(kbd_dev); 649 638 return ENOMEM; 650 639 } … … 653 642 654 643 kbd_dev->led_path = usb_hid_report_path(); 655 usb_hid_report_path_append_item( 644 if (kbd_dev->led_path == NULL) { 645 usb_log_error("Failed to create kbd led report path.\n"); 646 usb_kbd_destroy(kbd_dev); 647 return ENOMEM; 648 } 649 650 ret = usb_hid_report_path_append_item( 656 651 kbd_dev->led_path, USB_HIDUT_PAGE_LED, 0); 652 if (ret != EOK) { 653 usb_log_error("Failed to append to kbd/led report path.\n"); 654 usb_kbd_destroy(kbd_dev); 655 return ret; 656 } 657 657 658 658 kbd_dev->led_output_size = usb_hid_report_size( 659 659 &hid_dev->report, 0, USB_HID_REPORT_TYPE_OUTPUT); 660 660 661 usb_log_debug("Output report size (in items): %zu\n", 661 usb_log_debug("Output report size (in items): %zu\n", 662 662 kbd_dev->led_output_size); 663 663 664 kbd_dev->led_data = (int32_t *)calloc( 665 kbd_dev->led_output_size, sizeof(int32_t)); 666 664 kbd_dev->led_data = calloc(kbd_dev->led_output_size, sizeof(int32_t)); 667 665 if (kbd_dev->led_data == NULL) { 668 usb_log_warning("Error creating buffer for LED output report." 669 "\n"); 670 free(kbd_dev->keys); 671 usb_hid_report_output_free(kbd_dev->output_buffer); 672 free(kbd_dev); 666 usb_log_error("Error creating buffer for LED output report.\n"); 667 usb_kbd_destroy(kbd_dev); 673 668 return ENOMEM; 674 669 } 675 670 676 /* 677 * Modifiers and locks 678 */ 679 kbd_dev->modifiers = 0; 680 kbd_dev->mods = DEFAULT_ACTIVE_MODS; 681 kbd_dev->lock_keys = 0; 682 683 /* 684 * Autorepeat 685 */ 686 kbd_dev->repeat.key_new = 0; 687 kbd_dev->repeat.key_repeated = 0; 688 kbd_dev->repeat.delay_before = DEFAULT_DELAY_BEFORE_FIRST_REPEAT; 689 kbd_dev->repeat.delay_between = DEFAULT_REPEAT_DELAY; 690 691 fibril_mutex_initialize(&kbd_dev->repeat_mtx); 692 693 // save the KBD device structure into the HID device structure 671 /* Set LEDs according to initial setup. 672 * Set Idle rate */ 673 usb_kbd_set_led(hid_dev, kbd_dev); 674 675 usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe, 676 hid_dev->usb_dev->interface_no, IDLE_RATE); 677 678 /* Save the KBD device structure into the HID device structure. */ 694 679 *data = kbd_dev; 695 680 696 // set handler for incoming calls 697 kbd_dev->ops.default_handler = default_connection_handler; 698 699 /* 700 * Set LEDs according to initial setup. 701 * Set Idle rate 702 */ 703 usb_kbd_set_led(hid_dev, kbd_dev); 704 705 usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe, 706 hid_dev->usb_dev->interface_no, IDLE_RATE); 707 708 /* 709 * Create new fibril for auto-repeat 710 */ 681 kbd_dev->initialized = USB_KBD_STATUS_INITIALIZED; 682 usb_log_debug("HID/KBD device structure initialized.\n"); 683 684 usb_log_debug("Creating KBD function...\n"); 685 ret = usb_kbd_create_function(kbd_dev); 686 if (ret != EOK) { 687 usb_kbd_destroy(kbd_dev); 688 return ret; 689 } 690 691 /* Create new fibril for auto-repeat. */ 711 692 fid_t fid = fibril_create(usb_kbd_repeat_fibril, kbd_dev); 712 693 if (fid == 0) { 713 694 usb_log_error("Failed to start fibril for KBD auto-repeat"); 695 usb_kbd_destroy(kbd_dev); 714 696 return ENOMEM; 715 697 } 716 698 fibril_add_ready(fid); 717 699 718 kbd_dev->initialized = USB_KBD_STATUS_INITIALIZED;719 usb_log_debug("HID/KBD device structure initialized.\n");720 721 usb_log_debug("Creating KBD function...\n");722 int rc = usb_kbd_create_function(kbd_dev);723 if (rc != EOK) {724 usb_kbd_destroy(kbd_dev);725 return rc;726 }727 728 700 return EOK; 729 701 } 730 731 /*----------------------------------------------------------------------------*/ 732 702 /*----------------------------------------------------------------------------*/ 733 703 bool usb_kbd_polling_callback(usb_hid_dev_t *hid_dev, void *data) 734 704 { 735 if (hid_dev == NULL /* || buffer == NULL*/|| data == NULL) {736 / / do not continue polling (???)705 if (hid_dev == NULL || data == NULL) { 706 /* This means something serious */ 737 707 return false; 738 708 } 739 709 740 usb_kbd_t *kbd_dev = (usb_kbd_t *)data; 741 assert(kbd_dev != NULL); 742 710 usb_kbd_t *kbd_dev = data; 743 711 // TODO: add return value from this function 744 712 usb_kbd_process_data(hid_dev, kbd_dev); … … 746 714 return true; 747 715 } 748 749 /*----------------------------------------------------------------------------*/ 750 716 /*----------------------------------------------------------------------------*/ 751 717 int usb_kbd_is_initialized(const usb_kbd_t *kbd_dev) 752 718 { 753 719 return (kbd_dev->initialized == USB_KBD_STATUS_INITIALIZED); 754 720 } 755 756 /*----------------------------------------------------------------------------*/ 757 721 /*----------------------------------------------------------------------------*/ 758 722 int usb_kbd_is_ready_to_destroy(const usb_kbd_t *kbd_dev) 759 723 { 760 724 return (kbd_dev->initialized == USB_KBD_STATUS_TO_DESTROY); 761 725 } 762 763 726 /*----------------------------------------------------------------------------*/ 764 727 /** … … 773 736 } 774 737 775 // hangup session to the console 776 async_hangup(kbd_dev->console_sess); 738 /* Hangup session to the console. */ 739 if (kbd_dev->console_sess) 740 async_hangup(kbd_dev->console_sess); 777 741 778 742 //assert(!fibril_mutex_is_locked((*kbd_dev)->repeat_mtx)); … … 781 745 while (fibril_mutex_is_locked(&kbd_dev->repeat_mtx)) {} 782 746 783 / / free all buffers747 /* Free all buffers. */ 784 748 free(kbd_dev->keys); 785 749 free(kbd_dev->keys_old); 786 750 free(kbd_dev->led_data); 787 751 788 if (kbd_dev->led_path != NULL) { 789 usb_hid_report_path_free(kbd_dev->led_path); 790 } 791 if (kbd_dev->output_buffer != NULL) { 792 usb_hid_report_output_free(kbd_dev->output_buffer); 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 } 802 } 803 804 /*----------------------------------------------------------------------------*/ 805 752 usb_hid_report_path_free(kbd_dev->led_path); 753 usb_hid_report_output_free(kbd_dev->output_buffer); 754 755 if (kbd_dev->fun) { 756 if (ddf_fun_unbind(kbd_dev->fun) != EOK) { 757 usb_log_warning("Failed to unbind %s.\n", 758 kbd_dev->fun->name); 759 } else { 760 usb_log_debug2("%s unbound.\n", kbd_dev->fun->name); 761 kbd_dev->fun->driver_data = NULL; 762 ddf_fun_destroy(kbd_dev->fun); 763 } 764 } 765 free(kbd_dev); 766 } 767 /*----------------------------------------------------------------------------*/ 806 768 void usb_kbd_deinit(usb_hid_dev_t *hid_dev, void *data) 807 769 { 808 if (hid_dev == NULL) {809 return;810 }811 812 770 if (data != NULL) { 813 771 usb_kbd_t *kbd_dev = data; 814 772 if (usb_kbd_is_initialized(kbd_dev)) { 815 usb_kbd_mark_unusable(kbd_dev);816 /* wait for autorepeat */773 kbd_dev->initialized = USB_KBD_STATUS_TO_DESTROY; 774 /* Wait for autorepeat */ 817 775 async_usleep(CHECK_DELAY); 818 usb_kbd_destroy(kbd_dev); 819 } 820 } 821 } 822 823 /*----------------------------------------------------------------------------*/ 824 776 } 777 usb_kbd_destroy(kbd_dev); 778 } 779 } 780 /*----------------------------------------------------------------------------*/ 825 781 int usb_kbd_set_boot_protocol(usb_hid_dev_t *hid_dev) 826 782 { 783 assert(hid_dev); 827 784 int rc = usb_hid_parse_report_descriptor( 828 785 &hid_dev->report, USB_KBD_BOOT_REPORT_DESCRIPTOR, 829 USB_KBD_BOOT_REPORT_DESCRIPTOR_SIZE);786 sizeof(USB_KBD_BOOT_REPORT_DESCRIPTOR)); 830 787 831 788 if (rc != EOK) { … … 846 803 return EOK; 847 804 } 848 849 805 /** 850 806 * @} -
uspace/drv/bus/usb/usbhid/kbd/kbddev.h
r2e1b9dc r747ef72 135 135 void usb_kbd_destroy(usb_kbd_t *kbd_dev); 136 136 137 void usb_kbd_push_ev( struct usb_hid_dev *hid_dev,usb_kbd_t *kbd_dev,137 void usb_kbd_push_ev(usb_kbd_t *kbd_dev, 138 138 int type, unsigned int key); 139 139 -
uspace/drv/bus/usb/usbhid/kbd/kbdrepeat.c
r2e1b9dc r747ef72 45 45 #include "kbddev.h" 46 46 47 48 49 /*----------------------------------------------------------------------------*/50 47 /** 51 48 * Main loop handling the auto-repeat of keys. … … 58 55 * If the same key is still pressed, it uses the delay between repeats stored 59 56 * in the keyboard structure to wait until the key should be repeated. 60 * 57 * 61 58 * If the currently repeated key is not pressed any more ( 62 * usb_kbd_repeat_stop() was called), it stops repeating it and starts 59 * usb_kbd_repeat_stop() was called), it stops repeating it and starts 63 60 * checking again. 64 61 * 65 62 * @note For accessing the keyboard device auto-repeat information a fibril 66 63 * mutex (repeat_mtx) from the @a kbd structure is used. 67 * 64 * 68 65 * @param kbd Keyboard device structure. 69 66 */ … … 75 72 76 73 while (true) { 77 / / check if the kbd structure is usable74 /* Check if the kbd structure is usable. */ 78 75 if (!usb_kbd_is_initialized(kbd)) { 79 76 usb_log_warning("kbd not ready, exiting autorepeat.\n"); 80 77 return; 81 78 } 82 79 83 80 fibril_mutex_lock(&kbd->repeat_mtx); 84 81 85 82 if (kbd->repeat.key_new > 0) { 86 83 if (kbd->repeat.key_new == kbd->repeat.key_repeated) { 87 usb_log_debug2("Repeating key: %u.\n", 84 usb_log_debug2("Repeating key: %u.\n", 88 85 kbd->repeat.key_repeated); 89 // ugly hack with the NULL 90 usb_kbd_push_ev(NULL, kbd, KEY_PRESS, 86 usb_kbd_push_ev(kbd, KEY_PRESS, 91 87 kbd->repeat.key_repeated); 92 88 delay = kbd->repeat.delay_between; … … 106 102 } 107 103 fibril_mutex_unlock(&kbd->repeat_mtx); 108 109 104 async_usleep(delay); 110 105 } 111 106 } 112 113 107 /*----------------------------------------------------------------------------*/ 114 108 /** … … 116 110 * 117 111 * Starts the loop for checking changes in auto-repeat. 118 * 112 * 119 113 * @param arg User-specified argument. Expects pointer to the keyboard device 120 114 * structure representing the keyboard. … … 132 126 } 133 127 134 usb_kbd_t *kbd = (usb_kbd_t *)arg;128 usb_kbd_t *kbd = arg; 135 129 136 130 usb_kbd_repeat_loop(kbd); … … 138 132 return EOK; 139 133 } 140 141 134 /*----------------------------------------------------------------------------*/ 142 135 /** … … 156 149 fibril_mutex_unlock(&kbd->repeat_mtx); 157 150 } 158 159 151 /*----------------------------------------------------------------------------*/ 160 152 /** … … 162 154 * 163 155 * @note Only one key is repeated at any time, but this function may be called 164 * even with key that is not currently repeated (in that case nothing 156 * even with key that is not currently repeated (in that case nothing 165 157 * happens). 166 158 * … … 176 168 fibril_mutex_unlock(&kbd->repeat_mtx); 177 169 } 178 179 170 /** 180 171 * @} -
uspace/drv/bus/usb/usbhid/main.c
r2e1b9dc r747ef72 49 49 50 50 /** 51 * Function for adding a new device of type USB/HID/keyboard.51 * Callback for passing a new device to the driver. 52 52 * 53 * This functions initializes required structures from the device's descriptors 54 * and starts new fibril for polling the keyboard for events and another one for 55 * handling auto-repeat of keys. 53 * @note Currently, only boot-protocol keyboards are supported by this driver. 56 54 * 57 * During initialization, the keyboard is switched into boot protocol, the idle 58 * rate is set to 0 (infinity), resulting in the keyboard only reporting event 59 * when a key is pressed or released. Finally, the LED lights are turned on 60 * according to the default setup of lock keys. 61 * 62 * @note By default, the keyboards is initialized with Num Lock turned on and 63 * other locks turned off. 64 * @note Currently supports only boot-protocol keyboards. 65 * 66 * @param dev Device to add. 55 * @param dev Structure representing the new device. 67 56 * @return Error code. 68 57 */ 69 static int usb_hid_ try_add_device(usb_device_t *dev)58 static int usb_hid_device_add(usb_device_t *dev) 70 59 { 71 assert(dev != NULL);60 usb_log_debug("%s\n", __FUNCTION__); 72 61 73 /* Initialize device (get and process descriptors, get address, etc.) */ 74 usb_log_debug("Initializing USB/HID device...\n"); 62 if (dev == NULL) { 63 usb_log_error("Wrong parameter given for add_device().\n"); 64 return EINVAL; 65 } 75 66 67 if (dev->interface_no < 0) { 68 usb_log_error("Failed to add HID device: endpoints not found." 69 "\n"); 70 return ENOTSUP; 71 } 76 72 usb_hid_dev_t *hid_dev = 77 73 usb_device_data_alloc(dev, sizeof(usb_hid_dev_t)); 78 74 if (hid_dev == NULL) { 79 usb_log_error("Error while creating USB/HID device " 80 "structure.\n"); 75 usb_log_error("Failed to create USB/HID device structure.\n"); 81 76 return ENOMEM; 82 77 } 83 78 84 79 int rc = usb_hid_init(hid_dev, dev); 85 86 80 if (rc != EOK) { 87 81 usb_log_error("Failed to initialize USB/HID device.\n"); … … 92 86 usb_log_debug("USB/HID device structure initialized.\n"); 93 87 94 /*95 * 1) subdriver vytvori vlastnu ddf_fun, vlastne ddf_dev_ops, ktore da96 * do nej.97 * 2) do tych ops do .interfaces[DEV_IFACE_USBHID (asi)] priradi98 * vyplnenu strukturu usbhid_iface_t.99 * 3) klientska aplikacia - musi si rucne vytvorit telefon100 * (devman_device_connect() - cesta k zariadeniu (/hw/pci0/...) az101 * k tej fcii.102 * pouzit usb/classes/hid/iface.h - prvy int je telefon103 */104 105 88 /* Start automated polling function. 106 89 * This will create a separate fibril that will query the device 107 * for the data continuously 108 */ 90 * for the data continuously. */ 109 91 rc = usb_device_auto_poll(dev, 110 92 /* Index of the polling pipe. */ … … 113 95 usb_hid_polling_callback, 114 96 /* How much data to request. */ 115 dev->pipes[hid_dev->poll_pipe_index].pipe ->max_packet_size,97 dev->pipes[hid_dev->poll_pipe_index].pipe.max_packet_size, 116 98 /* Callback when the polling ends. */ 117 99 usb_hid_polling_ended_callback, … … 126 108 } 127 109 hid_dev->running = true; 128 129 /*130 * Hurrah, device is initialized.131 */132 return EOK;133 }134 /*----------------------------------------------------------------------------*/135 /**136 * Callback for passing a new device to the driver.137 *138 * @note Currently, only boot-protocol keyboards are supported by this driver.139 *140 * @param dev Structure representing the new device.141 * @return Error code.142 */143 static int usb_hid_device_add(usb_device_t *dev)144 {145 usb_log_debug("usb_hid_device_add()\n");146 147 if (dev == NULL) {148 usb_log_warning("Wrong parameter given for add_device().\n");149 return EINVAL;150 }151 152 if (dev->interface_no < 0) {153 usb_log_warning("Device is not a supported HID device.\n");154 usb_log_error("Failed to add HID device: endpoints not found."155 "\n");156 return ENOTSUP;157 }158 159 int rc = usb_hid_try_add_device(dev);160 161 if (rc != EOK) {162 usb_log_warning("Device is not a supported HID device.\n");163 usb_log_error("Failed to add HID device: %s.\n",164 str_error(rc));165 return rc;166 }167 110 168 111 usb_log_info("HID device `%s' ready to use.\n", dev->ddf_dev->name); … … 179 122 static int usb_hid_device_rem(usb_device_t *dev) 180 123 { 181 return EOK; 124 // TODO: Stop device polling 125 // TODO: Call deinit (stops autorepeat too) 126 return ENOTSUP; 182 127 } 183 128 /*----------------------------------------------------------------------------*/ … … 190 135 static int usb_hid_device_gone(usb_device_t *dev) 191 136 { 137 assert(dev); 138 assert(dev->driver_data); 192 139 usb_hid_dev_t *hid_dev = dev->driver_data; 193 unsigned tries = 10; 194 while (hid_dev->running) { 140 unsigned tries = 100; 141 /* Wait for fail. */ 142 while (hid_dev->running && tries--) { 195 143 async_usleep(100000); 196 if (!tries--) {197 usb_log_error("Can't remove hub, still running.\n");198 return EBUSY;199 }144 } 145 if (hid_dev->running) { 146 usb_log_error("Can't remove hid, still running.\n"); 147 return EBUSY; 200 148 } 201 149 202 assert(!hid_dev->running);203 150 usb_hid_deinit(hid_dev); 204 151 usb_log_debug2("%s destruction complete.\n", dev->ddf_dev->name); -
uspace/drv/bus/usb/usbhid/mouse/mousedev.c
r2e1b9dc r747ef72 55 55 #define ARROWS_PER_SINGLE_WHEEL 3 56 56 57 #define NAME 57 #define NAME "mouse" 58 58 59 59 /*----------------------------------------------------------------------------*/ … … 77 77 78 78 /*----------------------------------------------------------------------------*/ 79 80 enum { 81 USB_MOUSE_BOOT_REPORT_DESCRIPTOR_SIZE = 63 82 }; 83 84 static const uint8_t USB_MOUSE_BOOT_REPORT_DESCRIPTOR[ 85 USB_MOUSE_BOOT_REPORT_DESCRIPTOR_SIZE] = { 79 static const uint8_t USB_MOUSE_BOOT_REPORT_DESCRIPTOR[] = { 86 80 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 87 81 0x09, 0x02, // USAGE (Mouse) … … 123 117 ipc_callid_t icallid, ipc_call_t *icall) 124 118 { 125 usb_mouse_t *mouse_dev = (usb_mouse_t *)fun->driver_data;119 usb_mouse_t *mouse_dev = fun->driver_data; 126 120 127 121 if (mouse_dev == NULL) { 128 usb_log_debug("default_connection_handler: Missing " 129 "parameters.\n"); 122 usb_log_debug("%s: Missing parameters.\n", __FUNCTION__); 130 123 async_answer_0(icallid, EINVAL); 131 124 return; 132 125 } 133 126 134 usb_log_debug("default_connection_handler: fun->name: %s\n", 135 fun->name); 136 usb_log_debug("default_connection_handler: mouse_sess: %p, " 137 "wheel_sess: %p\n", mouse_dev->mouse_sess, mouse_dev->wheel_sess); 138 139 async_sess_t **sess_ptr = 140 (str_cmp(fun->name, HID_MOUSE_FUN_NAME) == 0) ? 127 usb_log_debug("%s: fun->name: %s\n", __FUNCTION__, fun->name); 128 usb_log_debug("%s: mouse_sess: %p, wheel_sess: %p\n", 129 __FUNCTION__, mouse_dev->mouse_sess, mouse_dev->wheel_sess); 130 131 async_sess_t **sess_ptr = (fun == mouse_dev->mouse_fun) ? 141 132 &mouse_dev->mouse_sess : &mouse_dev->wheel_sess; 142 133 … … 146 137 if (*sess_ptr == NULL) { 147 138 *sess_ptr = sess; 148 usb_log_debug("Console session to mouseset ok (%p).\n",149 sess);139 usb_log_debug("Console session to %s set ok (%p).\n", 140 fun->name, sess); 150 141 async_answer_0(icallid, EOK); 151 142 } else { 152 usb_log_ debug("default_connection_handler: Console "153 "session to mouse already set.\n");143 usb_log_error("Console session to %s already set.\n", 144 fun->name); 154 145 async_answer_0(icallid, ELIMIT); 155 146 } 156 147 } else { 157 usb_log_debug(" default_connection_handler: Invalid function.\n");148 usb_log_debug("%s: Invalid function.\n", __FUNCTION__); 158 149 async_answer_0(icallid, EINVAL); 159 }160 }161 162 /*----------------------------------------------------------------------------*/163 164 static usb_mouse_t *usb_mouse_new(void)165 {166 usb_mouse_t *mouse = calloc(1, sizeof(usb_mouse_t));167 if (mouse == NULL) {168 return NULL;169 }170 mouse->mouse_sess = NULL;171 mouse->wheel_sess = NULL;172 173 return mouse;174 }175 176 /*----------------------------------------------------------------------------*/177 178 static void usb_mouse_destroy(usb_mouse_t *mouse_dev)179 {180 assert(mouse_dev != NULL);181 182 // hangup session to the console183 if (mouse_dev->mouse_sess != NULL)184 async_hangup(mouse_dev->mouse_sess);185 186 if (mouse_dev->wheel_sess != NULL)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 150 } 203 151 } … … 215 163 } 216 164 217 int count = ((wheel < 0) ? -wheel : wheel) * ARROWS_PER_SINGLE_WHEEL; 218 int i; 219 220 for (i = 0; i < count; i++) { 165 const unsigned count = 166 ((wheel < 0) ? -wheel : wheel) * ARROWS_PER_SINGLE_WHEEL; 167 for (unsigned i = 0; i < count; i++) { 221 168 /* Send arrow press and release. */ 222 169 usb_log_debug2("Sending key %d to the console\n", key); … … 267 214 } 268 215 269 int shift_x = get_mouse_axis_move_value(hid_dev->report_id,216 const int shift_x = get_mouse_axis_move_value(hid_dev->report_id, 270 217 &hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_X); 271 int shift_y = get_mouse_axis_move_value(hid_dev->report_id,218 const int shift_y = get_mouse_axis_move_value(hid_dev->report_id, 272 219 &hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_Y); 273 int wheel = get_mouse_axis_move_value(hid_dev->report_id,220 const int wheel = get_mouse_axis_move_value(hid_dev->report_id, 274 221 &hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_WHEEL); 275 222 … … 277 224 async_exch_t *exch = 278 225 async_exchange_begin(mouse_dev->mouse_sess); 279 async_req_2_0(exch, MOUSEEV_MOVE_EVENT, shift_x, shift_y); 280 async_exchange_end(exch); 226 if (exch != NULL) { 227 async_req_2_0(exch, MOUSEEV_MOVE_EVENT, shift_x, shift_y); 228 async_exchange_end(exch); 229 } 281 230 } 282 231 … … 284 233 usb_mouse_send_wheel(mouse_dev, wheel); 285 234 286 /* 287 * Buttons 288 */ 235 /* Buttons */ 289 236 usb_hid_report_path_t *path = usb_hid_report_path(); 290 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_BUTTON, 0); 237 if (path == NULL) { 238 usb_log_warning("Failed to create USB HID report path.\n"); 239 return true; 240 } 241 int ret = 242 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_BUTTON, 0); 243 if (ret != EOK) { 244 usb_hid_report_path_free(path); 245 usb_log_warning("Failed to add buttons to report path.\n"); 246 return true; 247 } 291 248 usb_hid_report_path_set_report_id(path, hid_dev->report_id); 292 249 … … 298 255 usb_log_debug2(NAME " VALUE(%X) USAGE(%X)\n", field->value, 299 256 field->usage); 300 301 if (mouse_dev->buttons[field->usage - field->usage_minimum] == 0 302 && field->value != 0) { 257 assert(field->usage > field->usage_minimum); 258 const unsigned index = field->usage - field->usage_minimum; 259 assert(index < mouse_dev->buttons_count); 260 261 if (mouse_dev->buttons[index] == 0 && field->value != 0) { 303 262 async_exch_t *exch = 304 263 async_exchange_begin(mouse_dev->mouse_sess); 305 async_req_2_0(exch, MOUSEEV_BUTTON_EVENT, field->usage, 1); 306 async_exchange_end(exch); 307 308 mouse_dev->buttons[field->usage - field->usage_minimum] 309 = field->value; 310 } else if (mouse_dev->buttons[field->usage - field->usage_minimum] != 0 311 && field->value == 0) { 264 if (exch != NULL) { 265 async_req_2_0(exch, MOUSEEV_BUTTON_EVENT, 266 field->usage, 1); 267 async_exchange_end(exch); 268 mouse_dev->buttons[index] = field->value; 269 } 270 271 } else if (mouse_dev->buttons[index] != 0 && field->value == 0) { 312 272 async_exch_t *exch = 313 273 async_exchange_begin(mouse_dev->mouse_sess); 314 async_req_2_0(exch, MOUSEEV_BUTTON_EVENT, field->usage, 0); 315 async_exchange_end(exch); 316 317 mouse_dev->buttons[field->usage - field->usage_minimum] = 318 field->value; 274 if (exch != NULL) { 275 async_req_2_0(exch, MOUSEEV_BUTTON_EVENT, 276 field->usage, 0); 277 async_exchange_end(exch); 278 mouse_dev->buttons[index] = field->value; 279 } 319 280 } 320 281 … … 329 290 return true; 330 291 } 331 332 /*----------------------------------------------------------------------------*/ 333 292 /*----------------------------------------------------------------------------*/ 293 #define FUN_UNBIND_DESTROY(fun) \ 294 if (fun) { \ 295 if (ddf_fun_unbind((fun)) == EOK) { \ 296 (fun)->driver_data = NULL; \ 297 ddf_fun_destroy((fun)); \ 298 } else { \ 299 usb_log_error("Could not unbind function `%s', it " \ 300 "will not be destroyed.\n", (fun)->name); \ 301 } \ 302 } else (void)0 303 /*----------------------------------------------------------------------------*/ 334 304 static int usb_mouse_create_function(usb_hid_dev_t *hid_dev, usb_mouse_t *mouse) 335 305 { … … 339 309 /* Create the exposed function. */ 340 310 usb_log_debug("Creating DDF function %s...\n", HID_MOUSE_FUN_NAME); 341 ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed, 311 ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed, 342 312 HID_MOUSE_FUN_NAME); 343 313 if (fun == NULL) { 344 usb_log_error("Could not create DDF function node.\n"); 314 usb_log_error("Could not create DDF function node `%s'.\n", 315 HID_MOUSE_FUN_NAME); 345 316 return ENOMEM; 346 317 } … … 351 322 int rc = ddf_fun_bind(fun); 352 323 if (rc != EOK) { 353 usb_log_error("Could not bind DDF function: %s.\n", 354 str_error(rc)); 355 return rc; 356 } 357 358 usb_log_debug("Adding DDF function to category %s...\n", 359 HID_MOUSE_CATEGORY); 324 usb_log_error("Could not bind DDF function `%s': %s.\n", 325 fun->name, str_error(rc)); 326 fun->driver_data = NULL; 327 ddf_fun_destroy(fun); 328 return rc; 329 } 330 331 usb_log_debug("Adding DDF function `%s' to category %s...\n", 332 fun->name, HID_MOUSE_CATEGORY); 360 333 rc = ddf_fun_add_to_category(fun, HID_MOUSE_CATEGORY); 361 334 if (rc != EOK) { … … 363 336 "Could not add DDF function to category %s: %s.\n", 364 337 HID_MOUSE_CATEGORY, str_error(rc)); 338 FUN_UNBIND_DESTROY(fun); 365 339 return rc; 366 340 } … … 370 344 * Special function for acting as keyboard (wheel) 371 345 */ 372 usb_log_debug("Creating DDF function %s...\n", 346 usb_log_debug("Creating DDF function %s...\n", 373 347 HID_MOUSE_WHEEL_FUN_NAME); 374 fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed, 348 fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed, 375 349 HID_MOUSE_WHEEL_FUN_NAME); 376 350 if (fun == NULL) { 377 usb_log_error("Could not create DDF function node.\n"); 351 usb_log_error("Could not create DDF function node `%s'.\n", 352 HID_MOUSE_WHEEL_FUN_NAME); 353 FUN_UNBIND_DESTROY(mouse->mouse_fun); 354 mouse->mouse_fun = NULL; 378 355 return ENOMEM; 379 356 } … … 388 365 rc = ddf_fun_bind(fun); 389 366 if (rc != EOK) { 390 usb_log_error("Could not bind DDF function: %s.\n", 391 str_error(rc)); 367 usb_log_error("Could not bind DDF function `%s': %s.\n", 368 fun->name, str_error(rc)); 369 FUN_UNBIND_DESTROY(mouse->mouse_fun); 370 mouse->mouse_fun = NULL; 371 372 fun->driver_data = NULL; 373 ddf_fun_destroy(fun); 392 374 return rc; 393 375 } … … 400 382 "Could not add DDF function to category %s: %s.\n", 401 383 HID_MOUSE_WHEEL_CATEGORY, str_error(rc)); 384 385 FUN_UNBIND_DESTROY(mouse->mouse_fun); 386 mouse->mouse_fun = NULL; 387 FUN_UNBIND_DESTROY(fun); 402 388 return rc; 403 389 } … … 448 434 return highest_button; 449 435 } 450 451 /*----------------------------------------------------------------------------*/ 452 436 /*----------------------------------------------------------------------------*/ 453 437 int usb_mouse_init(usb_hid_dev_t *hid_dev, void **data) 454 438 { … … 461 445 } 462 446 463 usb_mouse_t *mouse_dev = usb_mouse_new();447 usb_mouse_t *mouse_dev = calloc(1, sizeof(usb_mouse_t)); 464 448 if (mouse_dev == NULL) { 465 449 usb_log_error("Error while creating USB/HID Mouse device " … … 484 468 } 485 469 486 487 // save the Mouse device structure into the HID device structure488 *data = mouse_dev;489 490 470 // set handler for incoming calls 491 471 mouse_dev->ops.default_handler = default_connection_handler; 492 472 493 473 // TODO: how to know if the device supports the request??? 494 usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe, 474 usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe, 495 475 hid_dev->usb_dev->interface_no, IDLE_RATE); 496 476 497 477 int rc = usb_mouse_create_function(hid_dev, mouse_dev); 498 478 if (rc != EOK) { 499 usb_mouse_destroy(mouse_dev); 500 return rc; 501 } 479 free(mouse_dev->buttons); 480 free(mouse_dev); 481 return rc; 482 } 483 484 /* Save the Mouse device structure into the HID device structure. */ 485 *data = mouse_dev; 502 486 503 487 return EOK; 504 488 } 505 506 /*----------------------------------------------------------------------------*/ 507 489 /*----------------------------------------------------------------------------*/ 508 490 bool usb_mouse_polling_callback(usb_hid_dev_t *hid_dev, void *data) 509 491 { 510 492 if (hid_dev == NULL || data == NULL) { 511 usb_log_error( "Missing argument to the mouse polling callback."512 " \n");493 usb_log_error( 494 "Missing argument to the mouse polling callback.\n"); 513 495 return false; 514 496 } 515 497 516 usb_mouse_t *mouse_dev = (usb_mouse_t *)data;517 498 usb_mouse_t *mouse_dev = data; 499 518 500 return usb_mouse_process_report(hid_dev, mouse_dev); 519 501 } 520 521 /*----------------------------------------------------------------------------*/ 522 502 /*----------------------------------------------------------------------------*/ 523 503 void usb_mouse_deinit(usb_hid_dev_t *hid_dev, void *data) 524 504 { 525 if (data != NULL) { 526 usb_mouse_destroy(data); 527 } 528 } 529 530 /*----------------------------------------------------------------------------*/ 531 505 if (data == NULL) 506 return; 507 508 usb_mouse_t *mouse_dev = data; 509 510 /* Hangup session to the console */ 511 if (mouse_dev->mouse_sess != NULL) { 512 const int ret = async_hangup(mouse_dev->mouse_sess); 513 if (ret != EOK) 514 usb_log_warning("Failed to hang up mouse session: " 515 "%p, %s.\n", mouse_dev->mouse_sess, str_error(ret)); 516 } 517 518 if (mouse_dev->wheel_sess != NULL) { 519 const int ret = async_hangup(mouse_dev->wheel_sess); 520 if (ret != EOK) 521 usb_log_warning("Failed to hang up wheel session: " 522 "%p, %s.\n", mouse_dev->wheel_sess, str_error(ret)); 523 } 524 525 FUN_UNBIND_DESTROY(mouse_dev->mouse_fun); 526 FUN_UNBIND_DESTROY(mouse_dev->wheel_fun); 527 528 free(mouse_dev->buttons); 529 free(mouse_dev); 530 } 531 /*----------------------------------------------------------------------------*/ 532 532 int usb_mouse_set_boot_protocol(usb_hid_dev_t *hid_dev) 533 533 { 534 534 int rc = usb_hid_parse_report_descriptor( 535 535 &hid_dev->report, USB_MOUSE_BOOT_REPORT_DESCRIPTOR, 536 USB_MOUSE_BOOT_REPORT_DESCRIPTOR_SIZE);536 sizeof(USB_MOUSE_BOOT_REPORT_DESCRIPTOR)); 537 537 538 538 if (rc != EOK) { -
uspace/drv/bus/usb/usbhid/multimedia/multimedia.c
r2e1b9dc r747ef72 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;71 69 } usb_multimedia_t; 72 70 73 71 74 72 /*----------------------------------------------------------------------------*/ 75 /** 73 /** 76 74 * Default handler for IPC methods not handled by DDF. 77 75 * … … 88 86 { 89 87 usb_log_debug(NAME " default_connection_handler()\n"); 90 91 usb_multimedia_t *multim_dev = (usb_multimedia_t *)fun->driver_data; 92 93 if (multim_dev == NULL) { 88 if (fun == NULL || fun->driver_data == NULL) { 94 89 async_answer_0(icallid, EINVAL); 95 90 return; 96 91 } 92 93 usb_multimedia_t *multim_dev = fun->driver_data; 97 94 98 95 async_sess_t *sess = … … 109 106 async_answer_0(icallid, EINVAL); 110 107 } 111 112 /*----------------------------------------------------------------------------*/ 113 108 /*----------------------------------------------------------------------------*/ 114 109 static ddf_dev_ops_t multimedia_ops = { 115 110 .default_handler = default_connection_handler 116 111 }; 117 118 112 /*----------------------------------------------------------------------------*/ 119 113 /** … … 127 121 * sends also these keys to application (otherwise it cannot use those 128 122 * keys at all). 129 * 130 * @param hid_dev 131 * @param lgtch_dev132 * @param type Type of the event (press / release). Recognized values: 123 * 124 * @param hid_dev 125 * @param multim_dev 126 * @param type Type of the event (press / release). Recognized values: 133 127 * KEY_PRESS, KEY_RELEASE 134 128 * @param key Key code of the key according to HID Usage Tables. 135 129 */ 136 static void usb_multimedia_push_ev( usb_hid_dev_t *hid_dev,130 static void usb_multimedia_push_ev( 137 131 usb_multimedia_t *multim_dev, int type, unsigned int key) 138 132 { 139 assert(hid_dev != NULL);140 133 assert(multim_dev != NULL); 141 134 142 kbd_event_t ev;143 144 ev.type = type;145 ev.key = key;146 ev.mods = 0;147 ev.c = 0;135 const kbd_event_t ev = { 136 .type = type, 137 .key = key, 138 .mods = 0, 139 .c = 0, 140 }; 148 141 149 142 usb_log_debug2(NAME " Sending key %d to the console\n", ev.key); … … 155 148 156 149 async_exch_t *exch = async_exchange_begin(multim_dev->console_sess); 157 async_msg_4(exch, KBDEV_EVENT, ev.type, ev.key, ev.mods, ev.c); 158 async_exchange_end(exch); 159 } 160 161 /*----------------------------------------------------------------------------*/ 162 150 if (exch != NULL) { 151 async_msg_4(exch, KBDEV_EVENT, ev.type, ev.key, ev.mods, ev.c); 152 async_exchange_end(exch); 153 } else { 154 usb_log_warning("Failed to send multimedia key.\n"); 155 } 156 } 157 /*----------------------------------------------------------------------------*/ 163 158 int usb_multimedia_init(struct usb_hid_dev *hid_dev, void **data) 164 159 { 165 160 if (hid_dev == NULL || hid_dev->usb_dev == NULL) { 166 return EINVAL; /*! @todo Other return code? */161 return EINVAL; 167 162 } 168 163 … … 187 182 188 183 multim_dev->console_sess = NULL; 189 multim_dev->fun = fun;190 184 191 185 //todo Autorepeat? … … 199 193 } 200 194 201 usb_log_debug( "%sfunction created (handle: %" PRIun ").\n",202 NAME,fun->handle);195 usb_log_debug(NAME " function created (handle: %" PRIun ").\n", 196 fun->handle); 203 197 204 198 rc = ddf_fun_add_to_category(fun, "keyboard"); … … 207 201 "Could not add DDF function to category 'keyboard': %s.\n", 208 202 str_error(rc)); 209 ddf_fun_destroy(fun); 203 if (ddf_fun_unbind(fun) != EOK) { 204 usb_log_error("Failed to unbind %s, won't destroy.\n", 205 fun->name); 206 } else { 207 ddf_fun_destroy(fun); 208 } 210 209 return rc; 211 210 } 212 211 213 212 /* Save the KBD device structure into the HID device structure. */ 214 *data = multim_dev;213 *data = fun; 215 214 216 215 usb_log_debug(NAME " HID/multimedia structure initialized.\n"); 217 216 return EOK; 218 217 } 219 220 /*----------------------------------------------------------------------------*/ 221 218 /*----------------------------------------------------------------------------*/ 222 219 void usb_multimedia_deinit(struct usb_hid_dev *hid_dev, void *data) 223 220 { 224 if (hid_dev == NULL) { 225 return; 226 } 227 228 if (data != NULL) { 229 usb_multimedia_t *multim_dev = (usb_multimedia_t *)data; 230 // hangup session to the console 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"); 221 ddf_fun_t *fun = data; 222 if (fun != NULL && fun->driver_data != NULL) { 223 usb_multimedia_t *multim_dev = fun->driver_data; 224 /* Hangup session to the console */ 225 if (multim_dev->console_sess) 226 async_hangup(multim_dev->console_sess); 227 if (ddf_fun_unbind(fun) != EOK) { 228 usb_log_error("Failed to unbind %s, won't destroy.\n", 229 fun->name); 235 230 } else { 236 usb_log_debug2("%s unbound.\n", multim_dev->fun->name); 237 ddf_fun_destroy(multim_dev->fun); 231 usb_log_debug2("%s unbound.\n", fun->name); 232 /* This frees multim_dev too as it was stored in 233 * fun->data */ 234 ddf_fun_destroy(fun); 238 235 } 239 } 240 } 241 242 /*----------------------------------------------------------------------------*/ 243 236 } else { 237 usb_log_error( 238 "Failed to deinit multimedia subdriver, data missing.\n"); 239 } 240 } 241 /*----------------------------------------------------------------------------*/ 244 242 bool usb_multimedia_polling_callback(struct usb_hid_dev *hid_dev, void *data) 245 243 { 246 244 // TODO: checks 247 if (hid_dev == NULL || data == NULL) { 245 ddf_fun_t *fun = data; 246 if (hid_dev == NULL || fun == NULL || fun->driver_data == NULL) { 248 247 return false; 249 248 } 250 249 251 usb_multimedia_t *multim_dev = (usb_multimedia_t *)data;250 usb_multimedia_t *multim_dev = fun->driver_data; 252 251 253 252 usb_hid_report_path_t *path = usb_hid_report_path(); 254 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_CONSUMER, 0); 253 if (path == NULL) 254 return true; /* This might be a temporary failure. */ 255 256 int ret = 257 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_CONSUMER, 0); 258 if (ret != EOK) { 259 usb_hid_report_path_free(path); 260 return true; /* This might be a temporary failure. */ 261 } 255 262 256 263 usb_hid_report_path_set_report_id(path, hid_dev->report_id); … … 261 268 USB_HID_REPORT_TYPE_INPUT); 262 269 263 /*! @todo Is this iterating OK if done multiple times? 264 * @todo The parsing is not OK 265 */ 270 //FIXME Is this iterating OK if done multiple times? 271 //FIXME The parsing is not OK. (what's wrong?) 266 272 while (field != NULL) { 267 if (field->value != 0) {268 usb_log_debug(NAME " KEY VALUE(%X) USAGE(%X)\n", 273 if (field->value != 0) { 274 usb_log_debug(NAME " KEY VALUE(%X) USAGE(%X)\n", 269 275 field->value, field->usage); 270 unsigned int key =276 const unsigned key = 271 277 usb_multimedia_map_usage(field->usage); 272 const char *key_str = 278 const char *key_str = 273 279 usbhid_multimedia_usage_to_str(field->usage); 274 280 usb_log_info("Pressed key: %s\n", key_str); 275 usb_multimedia_push_ev(hid_dev, multim_dev, KEY_PRESS, 276 key); 281 usb_multimedia_push_ev(multim_dev, KEY_PRESS, key); 277 282 } 278 283 279 284 field = usb_hid_report_get_sibling( 280 285 &hid_dev->report, field, path, USB_HID_PATH_COMPARE_END 281 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 286 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 282 287 USB_HID_REPORT_TYPE_INPUT); 283 288 } … … 287 292 return true; 288 293 } 289 290 294 /** 291 295 * @} -
uspace/drv/bus/usb/usbhid/subdrivers.c
r2e1b9dc r747ef72 98 98 } 99 99 }, 100 {NULL, -1, 0, -1, -1, {NULL, NULL, NULL, NULL, NULL}}101 100 }; 102 101 103 const int USB_HID_MAX_SUBDRIVERS =102 const size_t USB_HID_MAX_SUBDRIVERS = 104 103 sizeof(usb_hid_subdrivers) / sizeof(usb_hid_subdrivers[0]); 105 104 -
uspace/drv/bus/usb/usbhid/subdrivers.h
r2e1b9dc r747ef72 84 84 85 85 extern const usb_hid_subdriver_mapping_t usb_hid_subdrivers[]; 86 extern const int USB_HID_MAX_SUBDRIVERS;86 extern const size_t USB_HID_MAX_SUBDRIVERS; 87 87 88 88 /*----------------------------------------------------------------------------*/ -
uspace/drv/bus/usb/usbhid/usbhid.c
r2e1b9dc r747ef72 51 51 #include "subdrivers.h" 52 52 53 /*----------------------------------------------------------------------------*/54 55 53 /* Array of endpoints expected on the device, NULL terminated. */ 56 54 const usb_endpoint_description_t *usb_hid_endpoints[] = { … … 60 58 NULL 61 59 }; 62 63 /*----------------------------------------------------------------------------*/ 64 60 /*----------------------------------------------------------------------------*/ 65 61 static int usb_hid_set_boot_kbd_subdriver(usb_hid_dev_t *hid_dev) 66 62 { … … 78 74 return EOK; 79 75 } 80 81 /*----------------------------------------------------------------------------*/ 82 76 /*----------------------------------------------------------------------------*/ 83 77 static int usb_hid_set_boot_mouse_subdriver(usb_hid_dev_t *hid_dev) 84 78 { … … 92 86 hid_dev->subdriver_count = 1; 93 87 // TODO 2 should be mouse, but find a better way 94 hid_dev->subdrivers[ 2] = usb_hid_subdrivers[0].subdriver;88 hid_dev->subdrivers[0] = usb_hid_subdrivers[2].subdriver; 95 89 96 90 return EOK; 97 91 } 98 99 /*----------------------------------------------------------------------------*/ 100 92 /*----------------------------------------------------------------------------*/ 101 93 static int usb_hid_set_generic_hid_subdriver(usb_hid_dev_t *hid_dev) 102 94 { 103 assert(hid_dev != NULL && hid_dev->subdriver_count == 0); 95 assert(hid_dev != NULL); 96 assert(hid_dev->subdriver_count == 0); 104 97 105 98 hid_dev->subdrivers = malloc(sizeof(usb_hid_subdriver_t)); … … 117 110 return EOK; 118 111 } 119 120 /*----------------------------------------------------------------------------*/ 121 112 /*----------------------------------------------------------------------------*/ 122 113 static bool usb_hid_ids_match(const usb_hid_dev_t *hid_dev, 123 114 const usb_hid_subdriver_mapping_t *mapping) … … 128 119 return (hid_dev->usb_dev->descriptors.device.vendor_id 129 120 == mapping->vendor_id 130 && hid_dev->usb_dev->descriptors.device.product_id 121 && hid_dev->usb_dev->descriptors.device.product_id 131 122 == mapping->product_id); 132 123 } 133 134 /*----------------------------------------------------------------------------*/ 135 124 /*----------------------------------------------------------------------------*/ 136 125 static bool usb_hid_path_matches(usb_hid_dev_t *hid_dev, 137 126 const usb_hid_subdriver_mapping_t *mapping) … … 145 134 return false; 146 135 } 147 int i = 0; 148 while (mapping->usage_path[i].usage != 0149 || mapping->usage_path[i].usage_page != 0 ) {136 137 for (int i = 0; mapping->usage_path[i].usage != 0 138 || mapping->usage_path[i].usage_page != 0; ++i) { 150 139 if (usb_hid_report_path_append_item(usage_path, 151 140 mapping->usage_path[i].usage_page, … … 155 144 return false; 156 145 } 157 ++i;158 146 } 159 147 … … 165 153 do { 166 154 usb_log_debug("Trying report id %u\n", report_id); 167 168 155 if (report_id != 0) { 169 156 usb_hid_report_path_set_report_id(usage_path, … … 171 158 } 172 159 173 usb_hid_report_field_t *field = usb_hid_report_get_sibling( 174 &hid_dev->report, NULL, usage_path, mapping->compare, 175 USB_HID_REPORT_TYPE_INPUT); 160 const usb_hid_report_field_t *field = 161 usb_hid_report_get_sibling( 162 &hid_dev->report, NULL, usage_path, mapping->compare, 163 USB_HID_REPORT_TYPE_INPUT); 176 164 177 165 usb_log_debug("Field: %p\n", field); … … 190 178 return matches; 191 179 } 192 193 /*----------------------------------------------------------------------------*/ 194 180 /*----------------------------------------------------------------------------*/ 195 181 static int usb_hid_save_subdrivers(usb_hid_dev_t *hid_dev, 196 const usb_hid_subdriver_t **subdrivers, int count) 197 { 198 int i; 199 200 if (count <= 0) { 182 const usb_hid_subdriver_t **subdrivers, unsigned count) 183 { 184 assert(hid_dev); 185 assert(subdrivers); 186 187 if (count == 0) { 201 188 hid_dev->subdriver_count = 0; 202 189 hid_dev->subdrivers = NULL; … … 210 197 } 211 198 212 for (i = 0; i < count; ++i) { 213 hid_dev->subdrivers[i].init = subdrivers[i]->init; 214 hid_dev->subdrivers[i].deinit = subdrivers[i]->deinit; 215 hid_dev->subdrivers[i].poll = subdrivers[i]->poll; 216 hid_dev->subdrivers[i].poll_end = subdrivers[i]->poll_end; 199 for (unsigned i = 0; i < count; ++i) { 200 hid_dev->subdrivers[i] = *subdrivers[i]; 217 201 } 218 202 … … 227 211 return EOK; 228 212 } 229 230 /*----------------------------------------------------------------------------*/ 231 213 /*----------------------------------------------------------------------------*/ 232 214 static int usb_hid_find_subdrivers(usb_hid_dev_t *hid_dev) 233 215 { … … 235 217 236 218 const usb_hid_subdriver_t *subdrivers[USB_HID_MAX_SUBDRIVERS]; 237 238 int i = 0, count = 0; 239 const usb_hid_subdriver_mapping_t *mapping = &usb_hid_subdrivers[i]; 240 241 bool ids_matched; 242 bool matched; 243 244 while (count < USB_HID_MAX_SUBDRIVERS && 245 (mapping->usage_path != NULL 246 || mapping->vendor_id >= 0 || mapping->product_id >= 0)) { 247 // check the vendor & product ID 219 unsigned count = 0; 220 221 for (unsigned i = 0; i < USB_HID_MAX_SUBDRIVERS; ++i) { 222 const usb_hid_subdriver_mapping_t *mapping = 223 &usb_hid_subdrivers[i]; 224 /* Check the vendor & product ID. */ 248 225 if (mapping->vendor_id >= 0 && mapping->product_id < 0) { 249 usb_log_warning("Missing Product ID for Vendor ID %d\n", 250 mapping->vendor_id); 251 return EINVAL; 226 usb_log_warning("Mapping[%d]: Missing Product ID for " 227 "Vendor ID %d\n", i, mapping->vendor_id); 252 228 } 253 229 if (mapping->product_id >= 0 && mapping->vendor_id < 0) { 254 usb_log_warning("Missing Vendor ID for Product ID %d\n", 255 mapping->product_id); 256 return EINVAL; 257 } 258 259 ids_matched = false; 260 matched = false; 261 262 if (mapping->vendor_id >= 0) { 263 assert(mapping->product_id >= 0); 230 usb_log_warning("Mapping[%d]: Missing Vendor ID for " 231 "Product ID %d\n", i, mapping->product_id); 232 } 233 234 bool matched = false; 235 236 /* Check ID match. */ 237 if (mapping->vendor_id >= 0 && mapping->product_id >= 0) { 264 238 usb_log_debug("Comparing device against vendor ID %u" 265 239 " and product ID %u.\n", mapping->vendor_id, … … 267 241 if (usb_hid_ids_match(hid_dev, mapping)) { 268 242 usb_log_debug("IDs matched.\n"); 269 ids_matched = true;243 matched = true; 270 244 } 271 245 } 272 246 247 /* Check usage match. */ 273 248 if (mapping->usage_path != NULL) { 274 249 usb_log_debug("Comparing device against usage path.\n"); 275 250 if (usb_hid_path_matches(hid_dev, mapping)) { 276 / / does not matter if IDs were matched251 /* Does not matter if IDs were matched. */ 277 252 matched = true; 278 253 } 279 } else {280 // matched only if IDs were matched and there is no path281 matched = ids_matched;282 254 } 283 255 … … 286 258 subdrivers[count++] = &mapping->subdriver; 287 259 } 288 289 mapping = &usb_hid_subdrivers[++i];290 260 } 291 261 292 262 /* We have all subdrivers determined, save them into the hid device */ 293 // TODO Dowe really need this complicated stuff if there is294 // max_subdrivers limitation?295 263 return usb_hid_save_subdrivers(hid_dev, subdrivers, count); 296 264 } 297 298 /*----------------------------------------------------------------------------*/ 299 265 /*----------------------------------------------------------------------------*/ 300 266 static int usb_hid_check_pipes(usb_hid_dev_t *hid_dev, const usb_device_t *dev) 301 267 { … … 303 269 assert(dev); 304 270 305 if (dev->pipes[USB_HID_KBD_POLL_EP_NO].present) { 306 usb_log_debug("Found keyboard endpoint.\n"); 307 // save the pipe index 308 hid_dev->poll_pipe_index = USB_HID_KBD_POLL_EP_NO; 309 } else if (dev->pipes[USB_HID_MOUSE_POLL_EP_NO].present) { 310 usb_log_debug("Found mouse endpoint.\n"); 311 // save the pipe index 312 hid_dev->poll_pipe_index = USB_HID_MOUSE_POLL_EP_NO; 313 } else if (dev->pipes[USB_HID_GENERIC_POLL_EP_NO].present) { 314 usb_log_debug("Found generic HID endpoint.\n"); 315 // save the pipe index 316 hid_dev->poll_pipe_index = USB_HID_GENERIC_POLL_EP_NO; 317 } else { 318 usb_log_error("None of supported endpoints found - probably" 319 " not a supported device.\n"); 320 return ENOTSUP; 321 } 322 323 return EOK; 324 } 325 326 /*----------------------------------------------------------------------------*/ 327 271 static const struct { 272 unsigned ep_number; 273 const char* description; 274 } endpoints[] = { 275 {USB_HID_KBD_POLL_EP_NO, "Keyboard endpoint"}, 276 {USB_HID_MOUSE_POLL_EP_NO, "Mouse endpoint"}, 277 {USB_HID_GENERIC_POLL_EP_NO, "Generic HID endpoint"}, 278 }; 279 280 for (unsigned i = 0; i < sizeof(endpoints)/sizeof(endpoints[0]); ++i) { 281 if (endpoints[i].ep_number >= dev->pipes_count) { 282 return EINVAL; 283 } 284 if (dev->pipes[endpoints[i].ep_number].present) { 285 usb_log_debug("Found: %s.\n", endpoints[i].description); 286 hid_dev->poll_pipe_index = endpoints[i].ep_number; 287 return EOK; 288 } 289 } 290 return ENOTSUP; 291 } 292 /*----------------------------------------------------------------------------*/ 328 293 static int usb_hid_init_report(usb_hid_dev_t *hid_dev) 329 294 { … … 357 322 return EOK; 358 323 } 359 360 /*----------------------------------------------------------------------------*/ 361 324 /*----------------------------------------------------------------------------*/ 325 /* 326 * This functions initializes required structures from the device's descriptors 327 * and starts new fibril for polling the keyboard for events and another one for 328 * handling auto-repeat of keys. 329 * 330 * During initialization, the keyboard is switched into boot protocol, the idle 331 * rate is set to 0 (infinity), resulting in the keyboard only reporting event 332 * when a key is pressed or released. Finally, the LED lights are turned on 333 * according to the default setup of lock keys. 334 * 335 * @note By default, the keyboards is initialized with Num Lock turned on and 336 * other locks turned off. 337 * 338 * @param hid_dev Device to initialize, non-NULL. 339 * @param dev USB device, non-NULL. 340 * @return Error code. 341 */ 362 342 int usb_hid_init(usb_hid_dev_t *hid_dev, usb_device_t *dev) 363 343 { 364 int rc, i; 344 assert(hid_dev); 345 assert(dev); 365 346 366 347 usb_log_debug("Initializing HID structure...\n"); 367 368 if (hid_dev == NULL) {369 usb_log_error("Failed to init HID structure: no structure given"370 ".\n");371 return EINVAL;372 }373 374 if (dev == NULL) {375 usb_log_error("Failed to init HID structure: no USB device"376 " given.\n");377 return EINVAL;378 }379 348 380 349 usb_hid_report_init(&hid_dev->report); … … 384 353 hid_dev->poll_pipe_index = -1; 385 354 386 rc = usb_hid_check_pipes(hid_dev, dev);355 int rc = usb_hid_check_pipes(hid_dev, dev); 387 356 if (rc != EOK) { 388 357 return rc; … … 390 359 391 360 /* Get the report descriptor and parse it. */ 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 395 bool fallback = false; 396 361 rc = usb_hid_process_report_descriptor( 362 hid_dev->usb_dev, &hid_dev->report, &hid_dev->report_desc, 363 &hid_dev->report_desc_size); 364 365 /* If report parsing went well, find subdrivers. */ 397 366 if (rc == EOK) { 398 // try to find subdrivers that may want to handle this device 399 rc = usb_hid_find_subdrivers(hid_dev); 400 if (rc != EOK || hid_dev->subdriver_count == 0) { 401 // try to fall back to the boot protocol if available 402 usb_log_info("No subdrivers found to handle this" 403 " device.\n"); 404 fallback = true; 405 assert(hid_dev->subdrivers == NULL); 406 assert(hid_dev->subdriver_count == 0); 407 } 367 usb_hid_find_subdrivers(hid_dev); 408 368 } else { 409 usb_log_error("Failed to parse Report descriptor.\n"); 410 // try to fall back to the boot protocol if available 411 fallback = true; 412 } 413 414 if (fallback) { 415 // fall back to boot protocol 369 usb_log_error("Failed to parse report descriptor: fallback.\n"); 370 hid_dev->subdrivers = NULL; 371 hid_dev->subdriver_count = 0; 372 } 373 374 usb_log_debug("Subdriver count(before trying boot protocol): %d\n", 375 hid_dev->subdriver_count); 376 377 /* No subdrivers, fall back to the boot protocol if available. */ 378 if (hid_dev->subdriver_count == 0) { 379 assert(hid_dev->subdrivers == NULL); 380 usb_log_info("No subdrivers found to handle device, trying " 381 "boot protocol.\n"); 382 416 383 switch (hid_dev->poll_pipe_index) { 417 384 case USB_HID_KBD_POLL_EP_NO: … … 419 386 rc = usb_kbd_set_boot_protocol(hid_dev); 420 387 if (rc == EOK) { 421 rc =usb_hid_set_boot_kbd_subdriver(hid_dev);388 usb_hid_set_boot_kbd_subdriver(hid_dev); 422 389 } 423 390 break; … … 426 393 rc = usb_mouse_set_boot_protocol(hid_dev); 427 394 if (rc == EOK) { 428 rc =usb_hid_set_boot_mouse_subdriver(hid_dev);395 usb_hid_set_boot_mouse_subdriver(hid_dev); 429 396 } 430 397 break; … … 432 399 assert(hid_dev->poll_pipe_index 433 400 == USB_HID_GENERIC_POLL_EP_NO); 434 435 401 usb_log_info("Falling back to generic HID driver.\n"); 436 rc = usb_hid_set_generic_hid_subdriver(hid_dev); 437 } 438 } 439 440 if (rc != EOK) { 441 usb_log_error("No subdriver for handling this device could be" 442 " initialized: %s.\n", str_error(rc)); 443 usb_log_debug("Subdriver count: %d\n", 444 hid_dev->subdriver_count); 445 } else { 446 bool ok = false; 447 448 usb_log_debug("Subdriver count: %d\n", 449 hid_dev->subdriver_count); 450 451 for (i = 0; i < hid_dev->subdriver_count; ++i) { 452 if (hid_dev->subdrivers[i].init != NULL) { 453 usb_log_debug("Initializing subdriver %d.\n",i); 454 rc = hid_dev->subdrivers[i].init(hid_dev, 455 &hid_dev->subdrivers[i].data); 456 if (rc != EOK) { 457 usb_log_warning("Failed to initialize" 458 " HID subdriver structure.\n"); 459 } else { 460 // at least one subdriver initialized 461 ok = true; 462 } 402 usb_hid_set_generic_hid_subdriver(hid_dev); 403 } 404 } 405 406 usb_log_debug("Subdriver count(after trying boot protocol): %d\n", 407 hid_dev->subdriver_count); 408 409 /* Still no subdrivers? */ 410 if (hid_dev->subdriver_count == 0) { 411 assert(hid_dev->subdrivers == NULL); 412 usb_log_error( 413 "No subdriver for handling this device could be found.\n"); 414 return ENOTSUP; 415 } 416 417 /* 418 * 1) subdriver vytvori vlastnu ddf_fun, vlastne ddf_dev_ops, ktore da 419 * do nej. 420 * 2) do tych ops do .interfaces[DEV_IFACE_USBHID (asi)] priradi 421 * vyplnenu strukturu usbhid_iface_t. 422 * 3) klientska aplikacia - musi si rucne vytvorit telefon 423 * (devman_device_connect() - cesta k zariadeniu (/hw/pci0/...) az 424 * k tej fcii. 425 * pouzit usb/classes/hid/iface.h - prvy int je telefon 426 */ 427 bool ok = false; 428 for (unsigned i = 0; i < hid_dev->subdriver_count; ++i) { 429 if (hid_dev->subdrivers[i].init != NULL) { 430 usb_log_debug("Initializing subdriver %d.\n",i); 431 const int pret = hid_dev->subdrivers[i].init(hid_dev, 432 &hid_dev->subdrivers[i].data); 433 if (pret != EOK) { 434 usb_log_warning("Failed to initialize" 435 " HID subdriver structure: %s.\n", 436 str_error(pret)); 437 rc = pret; 463 438 } else { 439 /* At least one subdriver initialized. */ 464 440 ok = true; 465 441 } 466 } 467 468 rc = (ok) ? EOK : -1; // what error to report 469 } 470 471 472 if (rc == EOK) { 473 // save max input report size and allocate space for the report 442 } else { 443 /* Does not need initialization. */ 444 ok = true; 445 } 446 } 447 448 if (ok) { 449 /* Save max input report size and 450 * allocate space for the report */ 474 451 rc = usb_hid_init_report(hid_dev); 475 452 if (rc != EOK) { … … 481 458 return rc; 482 459 } 483 484 /*----------------------------------------------------------------------------*/ 485 460 /*----------------------------------------------------------------------------*/ 486 461 bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer, 487 462 size_t buffer_size, void *arg) … … 516 491 bool cont = false; 517 492 /* Continue if at least one of the subdrivers want to continue */ 518 for ( inti = 0; i < hid_dev->subdriver_count; ++i) {493 for (unsigned i = 0; i < hid_dev->subdriver_count; ++i) { 519 494 if (hid_dev->subdrivers[i].poll != NULL) { 520 495 cont = cont || hid_dev->subdrivers[i].poll( … … 525 500 return cont; 526 501 } 527 528 /*----------------------------------------------------------------------------*/ 529 502 /*----------------------------------------------------------------------------*/ 530 503 void usb_hid_polling_ended_callback(usb_device_t *dev, bool reason, void *arg) 531 504 { … … 535 508 usb_hid_dev_t *hid_dev = arg; 536 509 537 for ( inti = 0; i < hid_dev->subdriver_count; ++i) {510 for (unsigned i = 0; i < hid_dev->subdriver_count; ++i) { 538 511 if (hid_dev->subdrivers[i].poll_end != NULL) { 539 512 hid_dev->subdrivers[i].poll_end( … … 544 517 hid_dev->running = false; 545 518 } 546 547 /*----------------------------------------------------------------------------*/ 548 519 /*----------------------------------------------------------------------------*/ 549 520 void usb_hid_new_report(usb_hid_dev_t *hid_dev) 550 521 { 551 522 ++hid_dev->report_nr; 552 523 } 553 554 /*----------------------------------------------------------------------------*/ 555 524 /*----------------------------------------------------------------------------*/ 556 525 int usb_hid_report_number(const usb_hid_dev_t *hid_dev) 557 526 { 558 527 return hid_dev->report_nr; 559 528 } 560 561 /*----------------------------------------------------------------------------*/ 562 529 /*----------------------------------------------------------------------------*/ 563 530 void usb_hid_deinit(usb_hid_dev_t *hid_dev) 564 531 { … … 570 537 hid_dev->subdrivers, hid_dev->subdriver_count); 571 538 572 for ( inti = 0; i < hid_dev->subdriver_count; ++i) {539 for (unsigned i = 0; i < hid_dev->subdriver_count; ++i) { 573 540 if (hid_dev->subdrivers[i].deinit != NULL) { 574 541 hid_dev->subdrivers[i].deinit(hid_dev, -
uspace/drv/bus/usb/usbhid/usbhid.h
r2e1b9dc r747ef72 104 104 105 105 /** Index of the polling pipe in usb_hid_endpoints array. */ 106 intpoll_pipe_index;106 unsigned poll_pipe_index; 107 107 108 108 /** Subdrivers. */ … … 110 110 111 111 /** Number of subdrivers. */ 112 intsubdriver_count;112 unsigned subdriver_count; 113 113 114 114 /** Report descriptor. */ -
uspace/drv/bus/usb/usbhub/port.c
r2e1b9dc r747ef72 401 401 { 402 402 usb_hub_port_t *port = arg; 403 assert(port); 403 404 const int rc = 404 405 usb_hub_port_set_feature(port, USB_HUB_FEATURE_PORT_RESET); … … 440 441 data->port, &new_address, NULL, NULL, &child_fun); 441 442 442 if (rc != EOK) { 443 if (rc == EOK) { 444 fibril_mutex_lock(&data->port->mutex); 445 data->port->attached_device.fun = child_fun; 446 data->port->attached_device.address = new_address; 447 fibril_mutex_unlock(&data->port->mutex); 448 449 usb_log_info("Detected new device on `%s' (port %zu), " 450 "address %d (handle %" PRIun ").\n", 451 data->hub->usb_device->ddf_dev->name, 452 data->port->port_number, new_address, child_fun->handle); 453 } else { 443 454 usb_log_error("Failed registering device on port %zu: %s.\n", 444 455 data->port->port_number, str_error(rc)); 445 goto leave; 446 } 447 448 fibril_mutex_lock(&data->port->mutex); 449 data->port->attached_device.fun = child_fun; 450 data->port->attached_device.address = new_address; 451 fibril_mutex_unlock(&data->port->mutex); 452 453 usb_log_info("Detected new device on `%s' (port %zu), " 454 "address %d (handle %" PRIun ").\n", 455 data->hub->usb_device->ddf_dev->name, data->port->port_number, 456 new_address, child_fun->handle); 457 458 leave: 456 } 457 458 459 459 fibril_mutex_lock(&data->hub->pending_ops_mutex); 460 460 assert(data->hub->pending_ops_count > 0); -
uspace/drv/bus/usb/usbhub/port.h
r2e1b9dc r747ef72 44 44 /** Information about single port on a hub. */ 45 45 typedef struct { 46 /* Port number as reporte ed in descriptors. */46 /* Port number as reported in descriptors. */ 47 47 size_t port_number; 48 48 /** Device communication pipe. */ -
uspace/drv/bus/usb/usbhub/usbhub.c
r2e1b9dc r747ef72 170 170 int usb_hub_device_remove(usb_device_t *usb_dev) 171 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 172 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 173 } 202 174 /*----------------------------------------------------------------------------*/ -
uspace/drv/bus/usb/usbmast/bo_trans.c
r2e1b9dc r747ef72 67 67 int retval = EOK; 68 68 size_t act_size; 69 usb_pipe_t *bulk_in_pipe = mfun->mdev->usb_dev->pipes[BULK_IN_EP].pipe;70 usb_pipe_t *bulk_out_pipe = mfun->mdev->usb_dev->pipes[BULK_OUT_EP].pipe;69 usb_pipe_t *bulk_in_pipe = &mfun->mdev->usb_dev->pipes[BULK_IN_EP].pipe; 70 usb_pipe_t *bulk_out_pipe = &mfun->mdev->usb_dev->pipes[BULK_OUT_EP].pipe; 71 71 usb_direction_t ddir; 72 72 void *dbuf; … … 118 118 if (ddir == USB_DIRECTION_IN) { 119 119 usb_pipe_clear_halt(&mfun->mdev->usb_dev->ctrl_pipe, 120 mfun->mdev->usb_dev->pipes[BULK_IN_EP].pipe);120 &mfun->mdev->usb_dev->pipes[BULK_IN_EP].pipe); 121 121 } else { 122 122 usb_pipe_clear_halt(&mfun->mdev->usb_dev->ctrl_pipe, 123 mfun->mdev->usb_dev->pipes[BULK_OUT_EP].pipe);123 &mfun->mdev->usb_dev->pipes[BULK_OUT_EP].pipe); 124 124 } 125 125 } else if (rc != EOK) { … … 216 216 usb_massstor_reset(mdev); 217 217 usb_pipe_clear_halt(&mdev->usb_dev->ctrl_pipe, 218 mdev->usb_dev->pipes[BULK_IN_EP].pipe);218 &mdev->usb_dev->pipes[BULK_IN_EP].pipe); 219 219 usb_pipe_clear_halt(&mdev->usb_dev->ctrl_pipe, 220 mdev->usb_dev->pipes[BULK_OUT_EP].pipe);220 &mdev->usb_dev->pipes[BULK_OUT_EP].pipe); 221 221 } 222 222 -
uspace/drv/bus/usb/usbmast/main.c
r2e1b9dc r747ef72 114 114 { 115 115 //TODO: flush buffers, or whatever. 116 //TODO: remove device 116 117 return ENOTSUP; 117 118 } … … 139 140 140 141 usb_log_info("Initializing mass storage `%s'.\n", dev->ddf_dev->name); 141 usb_log_debug(" 142 dev->pipes[BULK_IN_EP].pipe ->endpoint_no,143 (size_t) dev->pipes[BULK_IN_EP].descriptor->max_packet_size);142 usb_log_debug("Bulk in endpoint: %d [%zuB].\n", 143 dev->pipes[BULK_IN_EP].pipe.endpoint_no, 144 dev->pipes[BULK_IN_EP].pipe.max_packet_size); 144 145 usb_log_debug("Bulk out endpoint: %d [%zuB].\n", 145 dev->pipes[BULK_OUT_EP].pipe ->endpoint_no,146 (size_t) dev->pipes[BULK_OUT_EP].descriptor->max_packet_size);146 dev->pipes[BULK_OUT_EP].pipe.endpoint_no, 147 dev->pipes[BULK_OUT_EP].pipe.max_packet_size); 147 148 148 149 usb_log_debug("Get LUN count...\n"); -
uspace/drv/bus/usb/usbmid/explore.c
r2e1b9dc r747ef72 57 57 { 58 58 list_foreach(*list, l) { 59 usbmid_interface_t *iface 60 = list_get_instance(l, usbmid_interface_t, link); 59 usbmid_interface_t *iface = usbmid_interface_from_link(l); 61 60 if (iface->interface_no == interface_no) { 62 61 return true; … … 82 81 }; 83 82 84 usb_dp_parser_t parser = {83 static const usb_dp_parser_t parser = { 85 84 .nesting = usb_dp_standard_descriptor_nesting 86 85 }; 87 86 88 87 const uint8_t *interface_ptr = 89 usb_dp_get_nested_descriptor(&parser, &data, data.data); 90 if (interface_ptr == NULL) { 91 return; 92 } 93 94 do { 95 if (interface_ptr[1] != USB_DESCTYPE_INTERFACE) { 96 goto next_descriptor; 97 } 98 99 usb_standard_interface_descriptor_t *interface 88 usb_dp_get_nested_descriptor(&parser, &data, config_descriptor); 89 90 /* Walk all descriptors nested in the current configuration decriptor; 91 * i.e. all interface descriptors. */ 92 for (;interface_ptr != NULL; 93 interface_ptr = usb_dp_get_sibling_descriptor( 94 &parser, &data, config_descriptor, interface_ptr)) 95 { 96 /* The second byte is DESCTYPE byte in all desriptors. */ 97 if (interface_ptr[1] != USB_DESCTYPE_INTERFACE) 98 continue; 99 100 const usb_standard_interface_descriptor_t *interface 100 101 = (usb_standard_interface_descriptor_t *) interface_ptr; 101 102 102 103 /* Skip alternate interfaces. */ 103 if (!interface_in_list(list, interface->interface_number)) { 104 usbmid_interface_t *iface 105 = malloc(sizeof(usbmid_interface_t)); 106 if (iface == NULL) { 107 break; 108 } 109 link_initialize(&iface->link); 110 iface->fun = NULL; 111 iface->interface_no = interface->interface_number; 112 iface->interface = interface; 113 114 list_append(&iface->link, list); 115 } 116 117 /* TODO: add the alternatives and create match ids from them 118 * as well. 119 */ 120 121 next_descriptor: 122 interface_ptr = usb_dp_get_sibling_descriptor(&parser, &data, 123 data.data, interface_ptr); 124 125 } while (interface_ptr != NULL); 126 104 if (interface_in_list(list, interface->interface_number)) { 105 /* TODO: add the alternatives and create match ids 106 * for them. */ 107 continue; 108 } 109 usbmid_interface_t *iface = malloc(sizeof(usbmid_interface_t)); 110 if (iface == NULL) { 111 //TODO: Do something about that failure. 112 break; 113 } 114 115 link_initialize(&iface->link); 116 iface->fun = NULL; 117 iface->interface_no = interface->interface_number; 118 iface->interface = interface; 119 120 list_append(&iface->link, list); 121 } 127 122 } 128 123 … … 139 134 int rc; 140 135 141 intdev_class = dev->descriptors.device.device_class;136 unsigned dev_class = dev->descriptors.device.device_class; 142 137 if (dev_class != USB_CLASS_USE_INTERFACE) { 143 138 usb_log_warning( 144 "Device class: %d (%s), but expected class 0.\n", 145 dev_class, usb_str_class(dev_class)); 139 "Device class: %u (%s), but expected class %u.\n", 140 dev_class, usb_str_class(dev_class), 141 USB_CLASS_USE_INTERFACE); 146 142 usb_log_error("Not multi interface device, refusing.\n"); 147 143 return false; 148 144 } 149 145 150 /* Short 146 /* Shortcuts to save on typing ;-). */ 151 147 const void *config_descriptor_raw = dev->descriptors.configuration; 152 148 size_t config_descriptor_size = dev->descriptors.configuration_size; … … 163 159 } 164 160 161 /* Create driver soft-state. */ 165 162 usb_mid_t *usb_mid = usb_device_data_alloc(dev, sizeof(usb_mid_t)); 166 163 if (!usb_mid) { … … 169 166 } 170 167 171 /* Create control function */168 /* Create control function. */ 172 169 usb_mid->ctl_fun = ddf_fun_create(dev->ddf_dev, fun_exposed, "ctl"); 173 170 if (usb_mid->ctl_fun == NULL) { … … 175 172 return false; 176 173 } 177 178 174 usb_mid->ctl_fun->ops = &mid_device_ops; 179 175 176 /* Bind control function. */ 180 177 rc = ddf_fun_bind(usb_mid->ctl_fun); 181 178 if (rc != EOK) { … … 192 189 &usb_mid->interface_list); 193 190 191 /* Start child function for every interface. */ 194 192 list_foreach(usb_mid->interface_list, link) { 195 usbmid_interface_t *iface = list_get_instance(link, 196 usbmid_interface_t, link); 193 usbmid_interface_t *iface = usbmid_interface_from_link(link); 197 194 198 195 usb_log_info("Creating child for interface %d (%s).\n", 199 (int)iface->interface_no,196 iface->interface_no, 200 197 usb_str_class(iface->interface->interface_class)); 201 198 -
uspace/drv/bus/usb/usbmid/main.c
r2e1b9dc r747ef72 68 68 /** Callback when a MID device is about to be removed from the host. 69 69 * 70 * @param gen_dev Generic DDFdevice representing the removed device.70 * @param dev USB device representing the removed device. 71 71 * @return Error code. 72 72 */ … … 74 74 { 75 75 assert(dev); 76 int ret = ENOTSUP;77 76 usb_mid_t *usb_mid = dev->driver_data; 78 77 assert(usb_mid); 79 78 80 /* Signal all interface functions */ 81 list_foreach(usb_mid->interface_list, item) { 79 /* Remove ctl function */ 80 int ret = ddf_fun_unbind(usb_mid->ctl_fun); 81 if (ret != EOK) { 82 usb_log_error("Failed to unbind USB MID ctl function: %s.\n", 83 str_error(ret)); 84 return ret; 85 } 86 ddf_fun_destroy(usb_mid->ctl_fun); 87 88 /* Remove all children */ 89 while (!list_empty(&usb_mid->interface_list)) { 90 link_t *item = list_first(&usb_mid->interface_list); 91 list_remove(item); 92 82 93 usbmid_interface_t *iface = usbmid_interface_from_link(item); 83 94 84 usb_log_info(" Signaling remove to child for interface "85 "%d (%s).\n",iface->interface_no,95 usb_log_info("Removing child for interface %d (%s).\n", 96 iface->interface_no, 86 97 usb_str_class(iface->interface->interface_class)); 87 // TODO cascade the call. 98 99 /* Tell the child to go off-line. */ 100 int pret = ddf_fun_offline(iface->fun); 101 if (pret != EOK) { 102 usb_log_warning("Failed to turn off child for interface" 103 " %d (%s): %s\n", iface->interface_no, 104 usb_str_class(iface->interface->interface_class), 105 str_error(pret)); 106 ret = pret; 107 } 108 109 /* Now remove the child. */ 110 pret = usbmid_interface_destroy(iface); 111 if (pret != EOK) { 112 usb_log_error("Failed to destroy child for interface " 113 "%d (%s): %s\n", iface->interface_no, 114 usb_str_class(iface->interface->interface_class), 115 str_error(pret)); 116 ret = pret; 117 } 88 118 } 89 119 return ret; … … 92 122 /** Callback when a MID device was removed from the host. 93 123 * 94 * @param gen_dev Generic DDFdevice representing the removed device.124 * @param dev USB device representing the removed device. 95 125 * @return Error code. 96 126 */ … … 98 128 { 99 129 assert(dev); 130 usb_mid_t *usb_mid = dev->driver_data; 131 assert(usb_mid); 132 100 133 usb_log_info("USB MID gone: `%s'.\n", dev->ddf_dev->name); 101 134 102 135 /* Remove ctl function */ 103 usb_mid_t *usb_mid = dev->driver_data;104 136 int ret = ddf_fun_unbind(usb_mid->ctl_fun); 105 137 if (ret != EOK) { … … 117 149 usbmid_interface_t *iface = usbmid_interface_from_link(item); 118 150 119 usb_log_info(" Removing child for interface %d (%s).\n",151 usb_log_info("Child for interface %d (%s) gone.\n", 120 152 iface->interface_no, 121 153 usb_str_class(iface->interface->interface_class)); -
uspace/drv/bus/usb/usbmid/usbmid.c
r2e1b9dc r747ef72 62 62 /** DDF interface of the child - interface function. */ 63 63 static usb_iface_t child_usb_iface = { 64 .get_hc_handle = usb_iface_get_hc_handle_ hub_child_impl,65 .get_ address = usb_iface_get_address_hub_impl,66 .get_interface = usb_iface_get_interface_impl 64 .get_hc_handle = usb_iface_get_hc_handle_device_impl, 65 .get_my_address = usb_iface_get_my_address_forward_impl, 66 .get_interface = usb_iface_get_interface_impl, 67 67 }; 68 68 … … 110 110 * class name something humanly understandable. 111 111 */ 112 rc = asprintf(&child_name, "%s% d",112 rc = asprintf(&child_name, "%s%hhu", 113 113 usb_str_class(interface_descriptor->interface_class), 114 (int)interface_descriptor->interface_number);114 interface_descriptor->interface_number); 115 115 if (rc < 0) { 116 116 return ENOMEM; … … 123 123 return ENOMEM; 124 124 } 125 126 iface->fun = child;127 128 child->driver_data = iface;129 child->ops = &child_device_ops;130 125 131 126 rc = usb_device_create_match_ids_from_interface(device_descriptor, … … 143 138 } 144 139 140 iface->fun = child; 141 child->driver_data = iface; 142 child->ops = &child_device_ops; 143 145 144 return EOK; 146 145 } -
uspace/drv/bus/usb/usbmid/usbmid.h
r2e1b9dc r747ef72 51 51 ddf_fun_t *fun; 52 52 /** Interface descriptor. */ 53 usb_standard_interface_descriptor_t *interface;53 const usb_standard_interface_descriptor_t *interface; 54 54 /** Interface number. */ 55 55 int interface_no; -
uspace/drv/bus/usb/vhc/connhost.c
r2e1b9dc r747ef72 57 57 * @return Error code. 58 58 */ 59 static int request_address(ddf_fun_t *fun, usb_speed_t speed, 60 usb_address_t *address) 61 { 62 VHC_DATA(vhc, fun); 63 64 usb_address_t addr = usb_device_manager_get_free_address( 65 &vhc->dev_manager, USB_SPEED_HIGH); 66 if (addr < 0) { 67 return addr; 68 } 69 70 if (address != NULL) { 71 *address = addr; 72 } 73 74 return EOK; 59 static int request_address(ddf_fun_t *fun, usb_address_t *address, bool strict, 60 usb_speed_t speed) 61 { 62 VHC_DATA(vhc, fun); 63 64 assert(address); 65 return usb_device_manager_request_address( 66 &vhc->dev_manager, address, strict, speed); 75 67 } 76 68 … … 88 80 usb_log_debug("Binding handle %" PRIun " to address %d.\n", 89 81 handle, address); 90 usb_device_manager_bind (&vhc->dev_manager, address, handle);82 usb_device_manager_bind_address(&vhc->dev_manager, address, handle); 91 83 92 84 return EOK; … … 118 110 VHC_DATA(vhc, fun); 119 111 usb_log_debug("Releasing address %d...\n", address); 120 usb_device_manager_release (&vhc->dev_manager, address);112 usb_device_manager_release_address(&vhc->dev_manager, address); 121 113 122 114 return ENOTSUP; … … 136 128 */ 137 129 static int register_endpoint(ddf_fun_t *fun, 138 usb_address_t address, usb_ speed_t speed, usb_endpoint_t endpoint,130 usb_address_t address, usb_endpoint_t endpoint, 139 131 usb_transfer_type_t transfer_type, usb_direction_t direction, 140 132 size_t max_packet_size, unsigned int interval) … … 479 471 } 480 472 481 static int tell_address(ddf_fun_t *fun, devman_handle_t handle, 482 usb_address_t *address) 473 static int tell_address(ddf_fun_t *fun, usb_address_t *address) 483 474 { 484 475 UNSUPPORTED("tell_address"); … … 497 488 } 498 489 499 static int tell_address_rh(ddf_fun_t *root_hub_fun, devman_handle_t handle, 500 usb_address_t *address) 490 static int tell_address_rh(ddf_fun_t *root_hub_fun, usb_address_t *address) 501 491 { 502 492 VHC_DATA(vhc, root_hub_fun); 503 493 504 if (handle == 0) { 505 handle = root_hub_fun->handle; 506 } 494 devman_handle_t handle = root_hub_fun->handle; 507 495 508 496 usb_log_debug("tell_address_rh(handle=%" PRIun ")\n", handle); … … 532 520 usb_iface_t vhc_usb_iface = { 533 521 .get_hc_handle = usb_iface_get_hc_handle_hc_impl, 534 .get_ address = tell_address522 .get_my_address = tell_address 535 523 }; 536 524 537 525 usb_iface_t rh_usb_iface = { 538 526 .get_hc_handle = usb_iface_get_hc_handle_rh_impl, 539 .get_ address = tell_address_rh527 .get_my_address = tell_address_rh 540 528 }; 541 529 -
uspace/drv/bus/usb/vhc/main.c
r2e1b9dc r747ef72 80 80 return rc; 81 81 } 82 usb_device_manager_init(&data->dev_manager );82 usb_device_manager_init(&data->dev_manager, USB_SPEED_MAX); 83 83 84 84 ddf_fun_t *hc = ddf_fun_create(dev, fun_exposed, "hc");
Note:
See TracChangeset
for help on using the changeset viewer.