Changeset ace12560 in mainline
- Timestamp:
- 2011-02-20T21:52:43Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- b317b0b, d37b235
- Parents:
- 62066b4 (diff), 41e645c (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. - Files:
-
- 9 added
- 27 edited
Legend:
- Unmodified
- Added
- Removed
-
.bzrignore
r62066b4 race12560 88 88 ./uspace/drv/usbhub/usbhub 89 89 ./uspace/drv/usbhid/usbhid 90 ./uspace/drv/usbmid/usbmid 90 91 ./uspace/drv/vhc/vhc 91 92 ./uspace/srv/bd/ata_bd/ata_bd -
boot/arch/amd64/Makefile.inc
r62066b4 race12560 47 47 usbhub \ 48 48 usbhid \ 49 usbmid \ 49 50 vhc 50 51 -
uspace/Makefile
r62066b4 race12560 121 121 drv/usbhid \ 122 122 drv/usbhub \ 123 drv/usbmid \ 123 124 drv/vhc 124 125 endif … … 136 137 drv/usbhid \ 137 138 drv/usbhub \ 139 drv/usbmid \ 138 140 drv/vhc 139 141 endif -
uspace/doc/doxygroups.h
r62066b4 race12560 220 220 221 221 /** 222 * @defgroup drvusbmid USB multi interface device driver 223 * @ingroup usb 224 * @brief USB multi interface device driver 225 * @details 226 * This driver serves as a mini hub (or bus) driver for devices 227 * that have the class defined at interface level (those devices 228 * usually have several interfaces). 229 * 230 * The term multi interface device driver (MID) was borrowed 231 * Solaris operating system. 232 */ 233 234 /** 222 235 * @defgroup drvusbhub USB hub driver 223 236 * @ingroup usb -
uspace/drv/uhci-hcd/iface.c
r62066b4 race12560 42 42 #include "uhci.h" 43 43 44 static int get_address(device_t *dev, devman_handle_t handle,45 usb_address_t *address)46 {47 assert(dev);48 uhci_t *hc = dev_to_uhci(dev);49 assert(hc);50 *address = usb_address_keeping_find(&hc->address_manager, handle);51 if (*address <= 0)52 return *address;53 return EOK;54 }55 44 /*----------------------------------------------------------------------------*/ 56 45 static int reserve_default_address(device_t *dev, usb_speed_t speed) … … 168 157 /*----------------------------------------------------------------------------*/ 169 158 usbhc_iface_t uhci_iface = { 170 .tell_address = get_address,171 172 159 .reserve_default_address = reserve_default_address, 173 160 .release_default_address = release_default_address, -
uspace/drv/uhci-hcd/main.c
r62066b4 race12560 34 34 #include <driver.h> 35 35 #include <usb_iface.h> 36 #include <usb/ddfiface.h> 36 37 #include <device/hw_res.h> 37 38 … … 48 49 49 50 static int uhci_add_device(device_t *device); 50 static int usb_iface_get_hc_handle(device_t *dev, devman_handle_t *handle); 51 /*----------------------------------------------------------------------------*/ 52 static int usb_iface_get_hc_handle(device_t *dev, devman_handle_t *handle)51 52 static int usb_iface_get_address(device_t *dev, devman_handle_t handle, 53 usb_address_t *address) 53 54 { 54 /* This shall be called only for the UHCI itself. */ 55 assert(dev->parent == NULL); 55 assert(dev); 56 uhci_t *hc = dev_to_uhci(dev); 57 assert(hc); 56 58 57 *handle = dev->handle; 59 usb_address_t addr = usb_address_keeping_find(&hc->address_manager, 60 handle); 61 if (addr < 0) { 62 return addr; 63 } 64 65 if (address != NULL) { 66 *address = addr; 67 } 68 58 69 return EOK; 59 70 } 60 /*----------------------------------------------------------------------------*/ 71 72 61 73 static usb_iface_t hc_usb_iface = { 62 .get_hc_handle = usb_iface_get_hc_handle 74 .get_hc_handle = usb_iface_get_hc_handle_hc_impl, 75 .get_address = usb_iface_get_address 63 76 }; 64 77 /*----------------------------------------------------------------------------*/ -
uspace/drv/uhci-rhd/main.c
r62066b4 race12560 34 34 #include <driver.h> 35 35 #include <usb_iface.h> 36 #include <usb/ddfiface.h> 36 37 37 38 #include <errno.h> … … 56 57 57 58 static usb_iface_t uhci_rh_usb_iface = { 58 .get_hc_handle = usb_iface_get_hc_handle 59 .get_hc_handle = usb_iface_get_hc_handle, 60 .get_address = usb_iface_get_address_hub_impl 59 61 }; 60 62 -
uspace/drv/usbhid/main.c
r62066b4 race12560 265 265 for (i = 0; i < count; ++i) { 266 266 printf("%d ", key_codes[i]); 267 } 268 printf("\n"); 269 270 for (i = 0; i < count; ++i) { 267 271 // TODO: Key press / release 268 272 269 273 // TODO: NOT WORKING 270 274 unsigned int key = usbkbd_parse_scancode(key_codes[i]); 275 276 if (key == 0) { 277 continue; 278 } 271 279 kbd_push_ev(KEY_PRESS, key); 272 280 } … … 348 356 { 349 357 .pipe = &kbd_dev->poll_pipe, 350 .description = &poll_endpoint_description 358 .description = &poll_endpoint_description, 359 .interface_no = 360 usb_device_get_assigned_interface(kbd_dev->device) 351 361 } 352 362 }; -
uspace/drv/usbhub/usbhub.c
r62066b4 race12560 39 39 40 40 #include <usb_iface.h> 41 #include <usb/ddfiface.h> 41 42 #include <usb/usbdrv.h> 42 43 #include <usb/descriptor.h> … … 52 53 #include "usb/pipes.h" 53 54 54 static int iface_get_hc_handle(device_t *device, devman_handle_t *handle)55 {56 return usb_hc_find(device->handle, handle);57 }58 59 static usb_iface_t hub_usb_iface = {60 .get_hc_handle = iface_get_hc_handle61 };62 63 55 static device_ops_t hub_device_ops = { 64 .interfaces[USB_DEV_IFACE] = & hub_usb_iface56 .interfaces[USB_DEV_IFACE] = &usb_iface_hub_impl 65 57 }; 66 58 -
uspace/drv/vhc/conn.h
r62066b4 race12560 38 38 #include <usb/usb.h> 39 39 #include <usbhc_iface.h> 40 #include <usb_iface.h> 40 41 #include "vhcd.h" 41 42 #include "devices.h" … … 43 44 void connection_handler_host(sysarg_t); 44 45 45 usbhc_iface_t vhc_iface; 46 extern usbhc_iface_t vhc_iface; 47 extern usb_iface_t vhc_usb_iface; 46 48 47 49 void address_init(void); -
uspace/drv/vhc/connhost.c
r62066b4 race12560 37 37 #include <usb/usb.h> 38 38 #include <usb/addrkeep.h> 39 #include <usb/ddfiface.h> 39 40 40 41 #include "vhcd.h" … … 313 314 static usb_address_keeping_t addresses; 314 315 316 static int tell_address(device_t *dev, devman_handle_t handle, 317 usb_address_t *address) 318 { 319 usb_address_t addr = usb_address_keeping_find(&addresses, handle); 320 if (addr < 0) { 321 return addr; 322 } 323 324 *address = addr; 325 return EOK; 326 } 315 327 316 328 static int reserve_default_address(device_t *dev, usb_speed_t ignored) … … 350 362 } 351 363 352 static int tell_address(device_t *dev, devman_handle_t handle,353 usb_address_t *address)354 {355 usb_address_t addr = usb_address_keeping_find(&addresses, handle);356 if (addr < 0) {357 return addr;358 }359 360 *address = addr;361 return EOK;362 }363 364 364 void address_init(void) 365 365 { … … 368 368 369 369 usbhc_iface_t vhc_iface = { 370 .tell_address = tell_address,371 372 370 .reserve_default_address = reserve_default_address, 373 371 .release_default_address = release_default_address, … … 383 381 }; 384 382 383 usb_iface_t vhc_usb_iface = { 384 .get_hc_handle = usb_iface_get_hc_handle_hc_impl, 385 .get_address = tell_address 386 }; 387 388 385 389 /** 386 390 * @} -
uspace/drv/vhc/hcd.c
r62066b4 race12560 45 45 46 46 #include <usb/usb.h> 47 #include <usb/ddfiface.h> 47 48 #include <usb_iface.h> 48 49 #include "vhcd.h" … … 52 53 #include "conn.h" 53 54 54 static int usb_iface_get_hc_handle(device_t *dev, devman_handle_t *handle)55 {56 /* This shall be called only for VHC device. */57 assert(dev->parent == NULL);58 59 *handle = dev->handle;60 return EOK;61 }62 63 static usb_iface_t hc_usb_iface = {64 .get_hc_handle = usb_iface_get_hc_handle65 };66 67 55 static device_ops_t vhc_ops = { 68 56 .interfaces[USBHC_DEV_IFACE] = &vhc_iface, 69 .interfaces[USB_DEV_IFACE] = & hc_usb_iface,57 .interfaces[USB_DEV_IFACE] = &vhc_usb_iface, 70 58 .close = on_client_close, 71 59 .default_handler = default_connection_handler -
uspace/lib/drv/generic/remote_usb.c
r62066b4 race12560 40 40 41 41 42 static void remote_usb_get_address(device_t *, void *, ipc_callid_t, ipc_call_t *); 43 static void remote_usb_get_interface(device_t *, void *, ipc_callid_t, ipc_call_t *); 42 44 static void remote_usb_get_hc_handle(device_t *, void *, ipc_callid_t, ipc_call_t *); 43 45 //static void remote_usb(device_t *, void *, ipc_callid_t, ipc_call_t *); … … 45 47 /** Remote USB interface operations. */ 46 48 static remote_iface_func_ptr_t remote_usb_iface_ops [] = { 49 remote_usb_get_address, 50 remote_usb_get_interface, 47 51 remote_usb_get_hc_handle 48 52 }; … … 56 60 }; 57 61 62 63 void remote_usb_get_address(device_t *device, void *iface, 64 ipc_callid_t callid, ipc_call_t *call) 65 { 66 usb_iface_t *usb_iface = (usb_iface_t *) iface; 67 68 if (usb_iface->get_address == NULL) { 69 async_answer_0(callid, ENOTSUP); 70 return; 71 } 72 73 devman_handle_t handle = DEV_IPC_GET_ARG1(*call); 74 75 usb_address_t address; 76 int rc = usb_iface->get_address(device, handle, &address); 77 if (rc != EOK) { 78 async_answer_0(callid, rc); 79 } else { 80 async_answer_1(callid, EOK, address); 81 } 82 } 83 84 void remote_usb_get_interface(device_t *device, void *iface, 85 ipc_callid_t callid, ipc_call_t *call) 86 { 87 usb_iface_t *usb_iface = (usb_iface_t *) iface; 88 89 if (usb_iface->get_interface == NULL) { 90 async_answer_0(callid, ENOTSUP); 91 return; 92 } 93 94 devman_handle_t handle = DEV_IPC_GET_ARG1(*call); 95 96 int iface_no; 97 int rc = usb_iface->get_interface(device, handle, &iface_no); 98 if (rc != EOK) { 99 async_answer_0(callid, rc); 100 } else { 101 async_answer_1(callid, EOK, iface_no); 102 } 103 } 58 104 59 105 void remote_usb_get_hc_handle(device_t *device, void *iface, -
uspace/lib/drv/generic/remote_usbhc.c
r62066b4 race12560 43 43 #define HACK_MAX_PACKET_SIZE_INTERRUPT_IN 4 44 44 45 static void remote_usbhc_get_address(device_t *, void *, ipc_callid_t, ipc_call_t *);46 45 static void remote_usbhc_interrupt_out(device_t *, void *, ipc_callid_t, ipc_call_t *); 47 46 static void remote_usbhc_interrupt_in(device_t *, void *, ipc_callid_t, ipc_call_t *); 47 static void remote_usbhc_bulk_out(device_t *, void *, ipc_callid_t, ipc_call_t *); 48 static void remote_usbhc_bulk_in(device_t *, void *, ipc_callid_t, ipc_call_t *); 48 49 static void remote_usbhc_control_write(device_t *, void *, ipc_callid_t, ipc_call_t *); 49 50 static void remote_usbhc_control_read(device_t *, void *, ipc_callid_t, ipc_call_t *); … … 57 58 /** Remote USB host controller interface operations. */ 58 59 static remote_iface_func_ptr_t remote_usbhc_iface_ops [] = { 59 remote_usbhc_get_address,60 61 60 remote_usbhc_reserve_default_address, 62 61 remote_usbhc_release_default_address, … … 68 67 remote_usbhc_interrupt_out, 69 68 remote_usbhc_interrupt_in, 69 70 remote_usbhc_bulk_out, 71 remote_usbhc_bulk_in, 70 72 71 73 remote_usbhc_control_write, … … 121 123 } 122 124 123 void remote_usbhc_get_address(device_t *device, void *iface,124 ipc_callid_t callid, ipc_call_t *call)125 {126 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;127 128 if (!usb_iface->tell_address) {129 async_answer_0(callid, ENOTSUP);130 return;131 }132 133 devman_handle_t handle = DEV_IPC_GET_ARG1(*call);134 135 usb_address_t address;136 int rc = usb_iface->tell_address(device, handle, &address);137 if (rc != EOK) {138 async_answer_0(callid, rc);139 } else {140 async_answer_1(callid, EOK, address);141 }142 }143 144 125 void remote_usbhc_reserve_default_address(device_t *device, void *iface, 145 126 ipc_callid_t callid, ipc_call_t *call) … … 389 370 return remote_usbhc_in_transfer(device, callid, call, 390 371 usb_iface->interrupt_in); 372 } 373 374 void remote_usbhc_bulk_out(device_t *device, void *iface, 375 ipc_callid_t callid, ipc_call_t *call) 376 { 377 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 378 assert(usb_iface != NULL); 379 380 return remote_usbhc_out_transfer(device, callid, call, 381 usb_iface->bulk_out); 382 } 383 384 void remote_usbhc_bulk_in(device_t *device, void *iface, 385 ipc_callid_t callid, ipc_call_t *call) 386 { 387 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 388 assert(usb_iface != NULL); 389 390 return remote_usbhc_in_transfer(device, callid, call, 391 usb_iface->bulk_in); 391 392 } 392 393 -
uspace/lib/drv/include/usb_iface.h
r62066b4 race12560 41 41 #include <usb/usb.h> 42 42 typedef enum { 43 /** Tell USB address assigned to device. 44 * Parameters: 45 * - devman handle id 46 * Answer: 47 * - EINVAL - unknown handle or handle not managed by this driver 48 * - ENOTSUP - operation not supported (shall not happen) 49 * - arbitrary error code if returned by remote implementation 50 * - EOK - handle found, first parameter contains the USB address 51 */ 52 IPC_M_USB_GET_ADDRESS, 53 54 /** Tell interface number given device can use. 55 * Parameters 56 * - devman handle id of the device 57 * Answer: 58 * - ENOTSUP - operation not supported (can also mean any interface) 59 * - EOK - operation okay, first parameter contains interface number 60 */ 61 IPC_M_USB_GET_INTERFACE, 62 43 63 /** Tell devman handle of device host controller. 44 64 * Parameters: … … 55 75 /** USB device communication interface. */ 56 76 typedef struct { 77 int (*get_address)(device_t *, devman_handle_t, usb_address_t *); 78 int (*get_interface)(device_t *, devman_handle_t, int *); 57 79 int (*get_hc_handle)(device_t *, devman_handle_t *); 58 80 } usb_iface_t; -
uspace/lib/drv/include/usbhc_iface.h
r62066b4 race12560 85 85 */ 86 86 typedef enum { 87 /** Tell USB address assigned to device.88 * Parameters:89 * - devman handle id90 * Answer:91 * - EINVAL - unknown handle or handle not managed by this driver92 * - ENOTSUP - operation not supported by HC (shall not happen)93 * - arbitrary error code if returned by remote implementation94 * - EOK - handle found, first parameter contains the USB address95 */96 IPC_M_USBHC_GET_ADDRESS,97 98 99 87 /** Reserve usage of default address. 100 88 * This call informs the host controller that the caller will be … … 153 141 IPC_M_USBHC_INTERRUPT_IN, 154 142 143 /** Send bulk data to device. 144 * See explanation at usb_iface_funcs_t (OUT transaction). 145 */ 146 IPC_M_USBHC_BULK_OUT, 147 148 /** Get bulk data from device. 149 * See explanation at usb_iface_funcs_t (IN transaction). 150 */ 151 IPC_M_USBHC_BULK_IN, 152 155 153 /** Issue control WRITE transfer. 156 154 * See explanation at usb_iface_funcs_t (OUT transaction) for … … 196 194 /** USB host controller communication interface. */ 197 195 typedef struct { 198 int (*tell_address)(device_t *, devman_handle_t, usb_address_t *);199 200 196 int (*reserve_default_address)(device_t *, usb_speed_t); 201 197 int (*release_default_address)(device_t *); … … 207 203 usbhc_iface_transfer_in_t interrupt_in; 208 204 205 usbhc_iface_transfer_out_t bulk_out; 206 usbhc_iface_transfer_in_t bulk_in; 207 209 208 int (*control_write)(device_t *, usb_target_t, 210 209 size_t, -
uspace/lib/usb/Makefile
r62066b4 race12560 35 35 src/addrkeep.c \ 36 36 src/class.c \ 37 src/ddfiface.c \ 37 38 src/debug.c \ 38 39 src/dp.c \ -
uspace/lib/usb/include/usb/dp.h
r62066b4 race12560 45 45 } usb_dp_descriptor_nesting_t; 46 46 47 extern usb_dp_descriptor_nesting_t usb_dp_standard_descriptor_nesting[]; 48 47 49 typedef struct { 48 50 usb_dp_descriptor_nesting_t *nesting; -
uspace/lib/usb/include/usb/pipes.h
r62066b4 race12560 107 107 /** Endpoint description. */ 108 108 const usb_endpoint_description_t *description; 109 /** Interface number the endpoint must belong to (-1 for any). */ 110 const int interface_no; 109 111 /** Found descriptor fitting the description. */ 110 112 usb_standard_endpoint_descriptor_t *descriptor; … … 121 123 int usb_device_connection_initialize(usb_device_connection_t *, 122 124 devman_handle_t, usb_address_t); 125 126 int usb_device_get_assigned_interface(device_t *); 123 127 124 128 int usb_endpoint_pipe_initialize(usb_endpoint_pipe_t *, -
uspace/lib/usb/include/usb/recognise.h
r62066b4 race12560 41 41 #include <ipc/devman.h> 42 42 43 int usb_device_create_match_ids_from_interface( 44 const usb_standard_device_descriptor_t *, 45 const usb_standard_interface_descriptor_t *, match_id_list_t *); 46 43 47 int usb_device_create_match_ids(usb_endpoint_pipe_t *, match_id_list_t *); 44 48 -
uspace/lib/usb/include/usb/usbdrv.h
r62066b4 race12560 103 103 int usb_drv_create_match_ids_from_device_descriptor(match_id_list_t *, 104 104 const usb_standard_device_descriptor_t *); 105 int usb_drv_create_match_ids_from_configuration_descriptor(match_id_list_t *,106 const void *, size_t);107 108 105 109 106 #endif -
uspace/lib/usb/src/dp.c
r62066b4 race12560 40 40 #include <bool.h> 41 41 #include <usb/dp.h> 42 #include <usb/descriptor.h> 43 44 #define NESTING(parentname, childname) \ 45 { \ 46 .child = USB_DESCTYPE_##childname, \ 47 .parent = USB_DESCTYPE_##parentname, \ 48 } 49 #define LAST_NESTING { -1, -1 } 50 51 /** Nesting of standard USB descriptors. */ 52 usb_dp_descriptor_nesting_t usb_dp_standard_descriptor_nesting[] = { 53 NESTING(CONFIGURATION, INTERFACE), 54 NESTING(INTERFACE, ENDPOINT), 55 NESTING(INTERFACE, HUB), 56 NESTING(INTERFACE, HID), 57 NESTING(HID, HID_REPORT), 58 LAST_NESTING 59 }; 60 61 #undef NESTING 62 #undef LAST_NESTING 42 63 43 64 /** Tells whether pointer points inside descriptor data. -
uspace/lib/usb/src/hub.c
r62066b4 race12560 301 301 } 302 302 303 304 303 /** 305 304 * @} -
uspace/lib/usb/src/pipes.c
r62066b4 race12560 36 36 #include <usb/pipes.h> 37 37 #include <usbhc_iface.h> 38 #include <usb_iface.h> 38 39 #include <errno.h> 39 40 #include <assert.h> … … 41 42 /** Tell USB address assigned to given device. 42 43 * 43 * @param phone Phone to my HC.44 * @param phone Phone to parent device. 44 45 * @param dev Device in question. 45 46 * @return USB address or error code. … … 48 49 { 49 50 sysarg_t address; 50 int rc = async_req_2_1(phone, DEV_IFACE_ID(USB HC_DEV_IFACE),51 IPC_M_USB HC_GET_ADDRESS,51 int rc = async_req_2_1(phone, DEV_IFACE_ID(USB_DEV_IFACE), 52 IPC_M_USB_GET_ADDRESS, 52 53 dev->handle, &address); 53 54 … … 57 58 58 59 return (usb_address_t) address; 60 } 61 62 /** Tell USB interface assigned to given device. 63 * 64 * @param device Device in question. 65 * @return Interface number (negative code means any). 66 */ 67 int usb_device_get_assigned_interface(device_t *device) 68 { 69 int parent_phone = devman_parent_device_connect(device->handle, 70 IPC_FLAG_BLOCKING); 71 if (parent_phone < 0) { 72 return -1; 73 } 74 75 sysarg_t iface_no; 76 int rc = async_req_2_1(parent_phone, DEV_IFACE_ID(USB_DEV_IFACE), 77 IPC_M_USB_GET_INTERFACE, 78 device->handle, &iface_no); 79 80 async_hangup(parent_phone); 81 82 if (rc != EOK) { 83 return -1; 84 } 85 86 return (int) iface_no; 59 87 } 60 88 … … 80 108 } 81 109 82 int hc_phone = devman_device_connect(hc_handle, 0); 83 if (hc_phone < 0) { 84 return hc_phone; 85 } 86 87 my_address = get_my_address(hc_phone, device); 110 int parent_phone = devman_parent_device_connect(device->handle, 111 IPC_FLAG_BLOCKING); 112 if (parent_phone < 0) { 113 return parent_phone; 114 } 115 116 my_address = get_my_address(parent_phone, device); 88 117 if (my_address < 0) { 89 118 rc = my_address; … … 95 124 96 125 leave: 97 async_hangup( hc_phone);126 async_hangup(parent_phone); 98 127 return rc; 99 128 } -
uspace/lib/usb/src/pipesinit.c
r62066b4 race12560 109 109 * @param mapping_count Number of endpoint mappings in @p mapping. 110 110 * @param found_endpoint Description of found endpoint. 111 * @param interface_number Number of currently processed interface. 111 112 * @return Endpoint mapping corresponding to @p found_endpoint. 112 113 * @retval NULL No corresponding endpoint found. … … 114 115 static usb_endpoint_mapping_t *find_endpoint_mapping( 115 116 usb_endpoint_mapping_t *mapping, size_t mapping_count, 116 usb_endpoint_description_t *found_endpoint) 117 usb_endpoint_description_t *found_endpoint, 118 int interface_number) 117 119 { 118 120 while (mapping_count > 0) { 119 if (endpoint_fits_description(mapping->description, 120 found_endpoint)) { 121 bool interface_number_fits = (mapping->interface_no < 0) 122 || (mapping->interface_no == interface_number); 123 124 bool endpoint_descriptions_fits = endpoint_fits_description( 125 mapping->description, found_endpoint); 126 127 if (interface_number_fits && endpoint_descriptions_fits) { 121 128 return mapping; 122 129 } … … 169 176 */ 170 177 usb_endpoint_mapping_t *ep_mapping = find_endpoint_mapping(mapping, 171 mapping_count, &description );178 mapping_count, &description, interface->interface_number); 172 179 if (ep_mapping == NULL) { 173 180 return ENOENT; -
uspace/lib/usb/src/pipesio.c
r62066b4 race12560 71 71 ipc_method = IPC_M_USBHC_INTERRUPT_IN; 72 72 break; 73 case USB_TRANSFER_BULK: 74 ipc_method = IPC_M_USBHC_BULK_IN; 75 break; 73 76 default: 74 77 return ENOTSUP; … … 194 197 case USB_TRANSFER_INTERRUPT: 195 198 ipc_method = IPC_M_USBHC_INTERRUPT_OUT; 199 break; 200 case USB_TRANSFER_BULK: 201 ipc_method = IPC_M_USBHC_BULK_OUT; 196 202 break; 197 203 default: -
uspace/lib/usb/src/recognise.c
r62066b4 race12560 34 34 */ 35 35 #include <sys/types.h> 36 #include <usb_iface.h>37 36 #include <usb/usbdrv.h> 38 37 #include <usb/pipes.h> 39 38 #include <usb/recognise.h> 39 #include <usb/ddfiface.h> 40 40 #include <usb/request.h> 41 41 #include <usb/classes/classes.h> … … 46 46 static FIBRIL_MUTEX_INITIALIZE(device_name_index_mutex); 47 47 48 /** Callback for getting host controller handle.49 *50 * @param dev Device in question.51 * @param[out] handle Devman handle of the host controller.52 * @return Error code.53 */54 static int usb_iface_get_hc_handle(device_t *dev, devman_handle_t *handle)55 {56 assert(dev);57 assert(dev->parent != NULL);58 59 device_t *parent = dev->parent;60 61 if (parent->ops && parent->ops->interfaces[USB_DEV_IFACE]) {62 usb_iface_t *usb_iface63 = (usb_iface_t *) parent->ops->interfaces[USB_DEV_IFACE];64 assert(usb_iface != NULL);65 if (usb_iface->get_hc_handle) {66 int rc = usb_iface->get_hc_handle(parent, handle);67 return rc;68 }69 }70 71 return ENOTSUP;72 }73 74 static usb_iface_t usb_iface = {75 .get_hc_handle = usb_iface_get_hc_handle76 };77 78 48 device_ops_t child_ops = { 79 .interfaces[USB_DEV_IFACE] = &usb_iface 49 .interfaces[USB_DEV_IFACE] = &usb_iface_hub_child_impl 80 50 }; 81 51 … … 142 112 } 143 113 114 #define ADD_MATCHID_OR_RETURN(match_ids, score, format, ...) \ 115 do { \ 116 int __rc = usb_add_match_id((match_ids), (score), \ 117 format, ##__VA_ARGS__); \ 118 if (__rc != EOK) { \ 119 return __rc; \ 120 } \ 121 } while (0) 122 123 /** Create device match ids based on its interface. 124 * 125 * @param[in] descriptor Interface descriptor. 126 * @param[out] matches Initialized list of match ids. 127 * @return Error code (the two mentioned are not the only ones). 128 * @retval EINVAL Invalid input parameters (expects non NULL pointers). 129 * @retval ENOENT Interface does not specify class. 130 */ 131 int usb_device_create_match_ids_from_interface( 132 const usb_standard_device_descriptor_t *desc_device, 133 const usb_standard_interface_descriptor_t *desc_interface, 134 match_id_list_t *matches) 135 { 136 if (desc_interface == NULL) { 137 return EINVAL; 138 } 139 if (matches == NULL) { 140 return EINVAL; 141 } 142 143 if (desc_interface->interface_class == USB_CLASS_USE_INTERFACE) { 144 return ENOENT; 145 } 146 147 const char *classname = usb_str_class(desc_interface->interface_class); 148 assert(classname != NULL); 149 150 #define IFACE_PROTOCOL_FMT "interface&class=%s&subclass=0x%02x&protocol=0x%02x" 151 #define IFACE_PROTOCOL_ARGS classname, desc_interface->interface_subclass, \ 152 desc_interface->interface_protocol 153 154 #define IFACE_SUBCLASS_FMT "interface&class=%s&subclass=0x%02x" 155 #define IFACE_SUBCLASS_ARGS classname, desc_interface->interface_subclass 156 157 #define IFACE_CLASS_FMT "interface&class=%s" 158 #define IFACE_CLASS_ARGS classname 159 160 #define VENDOR_RELEASE_FMT "vendor=0x%04x&product=0x%04x&release=" BCD_FMT 161 #define VENDOR_RELEASE_ARGS desc_device->vendor_id, desc_device->product_id, \ 162 BCD_ARGS(desc_device->device_version) 163 164 #define VENDOR_PRODUCT_FMT "vendor=0x%04x&product=0x%04x" 165 #define VENDOR_PRODUCT_ARGS desc_device->vendor_id, desc_device->product_id 166 167 #define VENDOR_ONLY_FMT "vendor=0x%04x" 168 #define VENDOR_ONLY_ARGS desc_device->vendor_id 169 170 /* 171 * If the vendor is specified, create match ids with vendor with 172 * higher score. 173 * Then the same ones without the vendor part. 174 */ 175 if ((desc_device != NULL) && (desc_device->vendor_id != 0)) { 176 /* First, interface matches with device release number. */ 177 ADD_MATCHID_OR_RETURN(matches, 250, 178 "usb&" VENDOR_RELEASE_FMT "&" IFACE_PROTOCOL_FMT, 179 VENDOR_RELEASE_ARGS, IFACE_PROTOCOL_ARGS); 180 ADD_MATCHID_OR_RETURN(matches, 240, 181 "usb&" VENDOR_RELEASE_FMT "&" IFACE_SUBCLASS_FMT, 182 VENDOR_RELEASE_ARGS, IFACE_SUBCLASS_ARGS); 183 ADD_MATCHID_OR_RETURN(matches, 230, 184 "usb&" VENDOR_RELEASE_FMT "&" IFACE_CLASS_FMT, 185 VENDOR_RELEASE_ARGS, IFACE_CLASS_ARGS); 186 187 /* Next, interface matches without release number. */ 188 ADD_MATCHID_OR_RETURN(matches, 220, 189 "usb&" VENDOR_PRODUCT_FMT "&" IFACE_PROTOCOL_FMT, 190 VENDOR_PRODUCT_ARGS, IFACE_PROTOCOL_ARGS); 191 ADD_MATCHID_OR_RETURN(matches, 210, 192 "usb&" VENDOR_PRODUCT_FMT "&" IFACE_SUBCLASS_FMT, 193 VENDOR_PRODUCT_ARGS, IFACE_SUBCLASS_ARGS); 194 ADD_MATCHID_OR_RETURN(matches, 200, 195 "usb&" VENDOR_PRODUCT_FMT "&" IFACE_CLASS_FMT, 196 VENDOR_PRODUCT_ARGS, IFACE_CLASS_ARGS); 197 198 /* Finally, interface matches with only vendor. */ 199 ADD_MATCHID_OR_RETURN(matches, 190, 200 "usb&" VENDOR_ONLY_FMT "&" IFACE_PROTOCOL_FMT, 201 VENDOR_ONLY_ARGS, IFACE_PROTOCOL_ARGS); 202 ADD_MATCHID_OR_RETURN(matches, 180, 203 "usb&" VENDOR_ONLY_FMT "&" IFACE_SUBCLASS_FMT, 204 VENDOR_ONLY_ARGS, IFACE_SUBCLASS_ARGS); 205 ADD_MATCHID_OR_RETURN(matches, 170, 206 "usb&" VENDOR_ONLY_FMT "&" IFACE_CLASS_FMT, 207 VENDOR_ONLY_ARGS, IFACE_CLASS_ARGS); 208 } 209 210 /* Now, the same but without any vendor specification. */ 211 ADD_MATCHID_OR_RETURN(matches, 160, 212 "usb&" IFACE_PROTOCOL_FMT, 213 IFACE_PROTOCOL_ARGS); 214 ADD_MATCHID_OR_RETURN(matches, 150, 215 "usb&" IFACE_SUBCLASS_FMT, 216 IFACE_SUBCLASS_ARGS); 217 ADD_MATCHID_OR_RETURN(matches, 140, 218 "usb&" IFACE_CLASS_FMT, 219 IFACE_CLASS_ARGS); 220 221 #undef IFACE_PROTOCOL_FMT 222 #undef IFACE_PROTOCOL_ARGS 223 #undef IFACE_SUBCLASS_FMT 224 #undef IFACE_SUBCLASS_ARGS 225 #undef IFACE_CLASS_FMT 226 #undef IFACE_CLASS_ARGS 227 #undef VENDOR_RELEASE_FMT 228 #undef VENDOR_RELEASE_ARGS 229 #undef VENDOR_PRODUCT_FMT 230 #undef VENDOR_PRODUCT_ARGS 231 #undef VENDOR_ONLY_FMT 232 #undef VENDOR_ONLY_ARGS 233 234 return EOK; 235 } 236 144 237 /** Create DDF match ids from USB device descriptor. 145 238 * … … 152 245 const usb_standard_device_descriptor_t *device_descriptor) 153 246 { 154 int rc;155 156 247 /* 157 248 * Unless the vendor id is 0, the pair idVendor-idProduct … … 160 251 if (device_descriptor->vendor_id != 0) { 161 252 /* First, with release number. */ 162 rc = usb_add_match_id(matches, 100,253 ADD_MATCHID_OR_RETURN(matches, 100, 163 254 "usb&vendor=0x%04x&product=0x%04x&release=" BCD_FMT, 164 255 (int) device_descriptor->vendor_id, 165 256 (int) device_descriptor->product_id, 166 257 BCD_ARGS(device_descriptor->device_version)); 167 if (rc != EOK) {168 return rc;169 }170 258 171 259 /* Next, without release number. */ 172 rc = usb_add_match_id(matches, 90,260 ADD_MATCHID_OR_RETURN(matches, 90, 173 261 "usb&vendor=0x%04x&product=0x%04x", 174 262 (int) device_descriptor->vendor_id, 175 263 (int) device_descriptor->product_id); 176 if (rc != EOK) {177 return rc;178 }179 264 } 180 265 181 266 /* 182 267 * If the device class points to interface we skip adding 183 * class directly .268 * class directly but we add a multi interface device. 184 269 */ 185 270 if (device_descriptor->device_class != USB_CLASS_USE_INTERFACE) { 186 rc = usb_add_match_id(matches, 50, "usb&class=%s",271 ADD_MATCHID_OR_RETURN(matches, 50, "usb&class=%s", 187 272 usb_str_class(device_descriptor->device_class)); 188 if (rc != EOK) { 189 return rc; 190 } 273 } else { 274 ADD_MATCHID_OR_RETURN(matches, 50, "usb&mid"); 191 275 } 192 276 … … 194 278 } 195 279 196 /** Create DDF match ids from USB configuration descriptor.197 * The configuration descriptor is expected to be in the complete form,198 * i.e. including interface, endpoint etc. descriptors.199 *200 * @param matches List of match ids to extend.201 * @param config_descriptor Configuration descriptor returned by given device.202 * @param total_size Size of the @p config_descriptor.203 * @return Error code.204 */205 int usb_drv_create_match_ids_from_configuration_descriptor(206 match_id_list_t *matches,207 const void *config_descriptor, size_t total_size)208 {209 /*210 * Iterate through config descriptor to find the interface211 * descriptors.212 */213 size_t position = sizeof(usb_standard_configuration_descriptor_t);214 while (position + 1 < total_size) {215 uint8_t *current_descriptor216 = ((uint8_t *) config_descriptor) + position;217 uint8_t cur_descr_len = current_descriptor[0];218 uint8_t cur_descr_type = current_descriptor[1];219 220 if (cur_descr_len == 0) {221 return ENOENT;222 }223 224 position += cur_descr_len;225 226 if (cur_descr_type != USB_DESCTYPE_INTERFACE) {227 continue;228 }229 230 /*231 * Finally, we found an interface descriptor.232 */233 usb_standard_interface_descriptor_t *interface234 = (usb_standard_interface_descriptor_t *)235 current_descriptor;236 237 int rc = usb_add_match_id(matches, 50,238 "usb&interface&class=%s",239 usb_str_class(interface->interface_class));240 if (rc != EOK) {241 return rc;242 }243 }244 245 return EOK;246 }247 248 /** Add match ids based on configuration descriptor.249 *250 * @param pipe Control pipe to the device.251 * @param matches Match ids list to add matches to.252 * @param config_count Number of configurations the device has.253 * @return Error code.254 */255 static int usb_add_config_descriptor_match_ids(usb_endpoint_pipe_t *pipe,256 match_id_list_t *matches, int config_count)257 {258 int final_rc = EOK;259 260 int config_index;261 for (config_index = 0; config_index < config_count; config_index++) {262 int rc;263 usb_standard_configuration_descriptor_t config_descriptor;264 rc = usb_request_get_bare_configuration_descriptor(pipe,265 config_index, &config_descriptor);266 if (rc != EOK) {267 final_rc = rc;268 continue;269 }270 271 size_t full_config_descriptor_size;272 void *full_config_descriptor273 = malloc(config_descriptor.total_length);274 rc = usb_request_get_full_configuration_descriptor(pipe,275 config_index,276 full_config_descriptor, config_descriptor.total_length,277 &full_config_descriptor_size);278 if (rc != EOK) {279 final_rc = rc;280 continue;281 }282 if (full_config_descriptor_size283 != config_descriptor.total_length) {284 final_rc = ERANGE;285 continue;286 }287 288 rc = usb_drv_create_match_ids_from_configuration_descriptor(289 matches,290 full_config_descriptor, full_config_descriptor_size);291 if (rc != EOK) {292 final_rc = rc;293 continue;294 }295 296 }297 298 return final_rc;299 }300 280 301 281 /** Create match ids describing attached device. … … 330 310 331 311 /* 332 * Go through all configurations and add matches333 * based on interface class.334 */335 rc = usb_add_config_descriptor_match_ids(ctrl_pipe, matches,336 device_descriptor.configuration_count);337 if (rc != EOK) {338 return rc;339 }340 341 /*342 312 * As a fallback, provide the simplest match id possible. 343 313 */ 344 rc = usb_add_match_id(matches, 1, "usb&fallback"); 345 if (rc != EOK) { 346 return rc; 347 } 314 ADD_MATCHID_OR_RETURN(matches, 1, "usb&fallback"); 348 315 349 316 return EOK;
Note:
See TracChangeset
for help on using the changeset viewer.