Changes in / [6bb83c7:070f11e] in mainline
- Files:
-
- 9 added
- 42 edited
Legend:
- Unmodified
- Added
- Removed
-
.bzrignore
r6bb83c7 r070f11e 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
r6bb83c7 r070f11e 47 47 usbhub \ 48 48 usbhid \ 49 usbmid \ 49 50 vhc 50 51 -
uspace/Makefile
r6bb83c7 r070f11e 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
r6bb83c7 r070f11e 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/pciintel/pci.c
r6bb83c7 r070f11e 49 49 #include <ipc/devman.h> 50 50 #include <ipc/dev_iface.h> 51 #include <ipc/irc.h> 52 #include <ipc/ns.h> 53 #include <ipc/services.h> 54 #include <sysinfo.h> 51 55 #include <ops/hw_res.h> 52 56 #include <device/hw_res.h> … … 72 76 static bool pciintel_enable_child_interrupt(device_t *dev) 73 77 { 74 /* TODO */ 75 76 return false; 78 /* This is an old ugly way, copied from ne2000 driver */ 79 assert(dev); 80 pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data; 81 82 sysarg_t apic; 83 sysarg_t i8259; 84 int irc_phone = -1; 85 int irc_service = 0; 86 87 if ((sysinfo_get_value("apic", &apic) == EOK) && (apic)) { 88 irc_service = SERVICE_APIC; 89 } else if ((sysinfo_get_value("i8259", &i8259) == EOK) && (i8259)) { 90 irc_service = SERVICE_I8259; 91 } 92 93 if (irc_service) { 94 while (irc_phone < 0) 95 irc_phone = service_connect_blocking(irc_service, 0, 0); 96 } else { 97 return false; 98 } 99 100 size_t i; 101 for (i = 0; i < dev_data->hw_resources.count; i++) { 102 if (dev_data->hw_resources.resources[i].type == INTERRUPT) { 103 int irq = dev_data->hw_resources.resources[i].res.interrupt.irq; 104 async_msg_1(irc_phone, IRC_ENABLE_INTERRUPT, irq); 105 } 106 } 107 108 async_hangup(irc_phone); 109 return true; 77 110 } 78 111 -
uspace/drv/uhci-hcd/batch.c
r6bb83c7 r070f11e 141 141 usb_log_debug("Checking(%p) %d packet for completion.\n", 142 142 instance, instance->packets); 143 /* This is just an ugly trick to support the old API */144 143 instance->transfered_size = 0; 145 144 size_t i = 0; … … 157 156 transfer_descriptor_actual_size(&instance->tds[i]); 158 157 } 158 /* This is just an ugly trick to support the old API */ 159 159 instance->transfered_size -= instance->setup_size; 160 160 return true; … … 191 191 0, 1, false, instance->target, USB_PID_IN, NULL, NULL); 192 192 193 instance->tds[i].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG; 194 193 195 instance->next_step = batch_call_out_and_dispose; 194 196 batch_schedule(instance); … … 221 223 transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT, 222 224 0, 1, false, instance->target, USB_PID_OUT, NULL, NULL); 225 226 instance->tds[i].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG; 223 227 224 228 instance->next_step = batch_call_in_and_dispose; … … 244 248 } 245 249 250 instance->tds[i - 1].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG; 251 246 252 instance->next_step = batch_call_in_and_dispose; 247 253 batch_schedule(instance); … … 268 274 } 269 275 276 instance->tds[i - 1].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG; 277 270 278 instance->next_step = batch_call_out_and_dispose; 271 279 batch_schedule(instance); -
uspace/drv/uhci-hcd/iface.c
r6bb83c7 r070f11e 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 static int reserve_default_address(device_t *dev, bool full_speed)45 static int reserve_default_address(device_t *dev, usb_speed_t speed) 57 46 { 58 47 assert(dev); … … 72 61 } 73 62 /*----------------------------------------------------------------------------*/ 74 static int request_address(device_t *dev, bool full_speed,63 static int request_address(device_t *dev, usb_speed_t speed, 75 64 usb_address_t *address) 76 65 { … … 164 153 return EOK; 165 154 } 166 /*----------------------------------------------------------------------------*/167 static int control_write_setup(device_t *dev, usb_target_t target,168 size_t max_packet_size,169 void *data, size_t size,170 usbhc_iface_transfer_out_callback_t callback, void *arg)171 {172 dev_speed_t speed = FULL_SPEED;173 155 174 usb_log_warning("Using deprecated API %s.\n", __FUNCTION__);175 batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL,176 max_packet_size, speed, NULL, 0, data, size, NULL, callback, arg);177 if (!batch)178 return ENOMEM;179 batch_control_setup_old(batch);180 return EOK;181 }182 /*----------------------------------------------------------------------------*/183 static int control_write_data(device_t *dev, usb_target_t target,184 size_t max_packet_size,185 void *data, size_t size,186 usbhc_iface_transfer_out_callback_t callback, void *arg)187 {188 dev_speed_t speed = FULL_SPEED;189 156 190 usb_log_warning("Using deprecated API %s.\n", __FUNCTION__);191 batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL,192 max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg);193 if (!batch)194 return ENOMEM;195 batch_control_write_data_old(batch);196 return EOK;197 }198 /*----------------------------------------------------------------------------*/199 static int control_write_status(device_t *dev, usb_target_t target,200 usbhc_iface_transfer_in_callback_t callback, void *arg)201 {202 size_t max_packet_size = 8;203 dev_speed_t speed = FULL_SPEED;204 205 usb_log_warning("Using deprecated API %s.\n", __FUNCTION__);206 batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL,207 max_packet_size, speed, NULL, 0, NULL, 0, callback, NULL, arg);208 if (!batch)209 return ENOMEM;210 batch_control_write_status_old(batch);211 return EOK;212 }213 /*----------------------------------------------------------------------------*/214 static int control_read_setup(device_t *dev, usb_target_t target,215 size_t max_packet_size,216 void *data, size_t size,217 usbhc_iface_transfer_out_callback_t callback, void *arg)218 {219 dev_speed_t speed = FULL_SPEED;220 221 usb_log_warning("Using deprecated API %s.\n", __FUNCTION__);222 batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL,223 max_packet_size, speed, NULL, 0, data, size, NULL, callback, arg);224 if (!batch)225 return ENOMEM;226 batch_control_setup_old(batch);227 return EOK;228 }229 /*----------------------------------------------------------------------------*/230 static int control_read_data(device_t *dev, usb_target_t target,231 size_t max_packet_size,232 void *data, size_t size,233 usbhc_iface_transfer_in_callback_t callback, void *arg)234 {235 dev_speed_t speed = FULL_SPEED;236 237 usb_log_warning("Using deprecated API %s.\n", __FUNCTION__);238 batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL,239 max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg);240 if (!batch)241 return ENOMEM;242 batch_control_read_data_old(batch);243 return EOK;244 }245 /*----------------------------------------------------------------------------*/246 static int control_read_status(device_t *dev, usb_target_t target,247 usbhc_iface_transfer_out_callback_t callback, void *arg)248 {249 size_t max_packet_size = 8;250 dev_speed_t speed = FULL_SPEED;251 252 usb_log_warning("Using deprecated API %s.\n", __FUNCTION__);253 batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL,254 max_packet_size, speed, NULL, 0, NULL, 0, NULL, callback, arg);255 if (!batch)256 return ENOMEM;257 batch_control_read_status_old(batch);258 return EOK;259 }260 157 /*----------------------------------------------------------------------------*/ 261 158 usbhc_iface_t uhci_iface = { 262 .tell_address = get_address,263 264 159 .reserve_default_address = reserve_default_address, 265 160 .release_default_address = release_default_address, … … 273 168 .control_read = control_read, 274 169 .control_write = control_write, 275 276 .control_write_setup = control_write_setup,277 .control_write_data = control_write_data,278 .control_write_status = control_write_status,279 280 .control_read_setup = control_read_setup,281 .control_read_data = control_read_data,282 .control_read_status = control_read_status283 170 }; 284 171 /** -
uspace/drv/uhci-hcd/main.c
r6bb83c7 r070f11e 34 34 #include <driver.h> 35 35 #include <usb_iface.h> 36 #include <usb/ddfiface.h> 37 #include <device/hw_res.h> 36 38 37 39 #include <errno.h> … … 46 48 #define NAME "uhci-hcd" 47 49 48 static int usb_iface_get_hc_handle(device_t *dev, devman_handle_t *handle) 50 static int uhci_add_device(device_t *device); 51 52 static int usb_iface_get_address(device_t *dev, devman_handle_t handle, 53 usb_address_t *address) 49 54 { 50 /* This shall be called only for the UHCI itself. */ 51 assert(dev->parent == NULL); 55 assert(dev); 56 uhci_t *hc = dev_to_uhci(dev); 57 assert(hc); 52 58 53 *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 54 69 return EOK; 55 70 } 56 71 72 57 73 static usb_iface_t hc_usb_iface = { 58 .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 59 76 }; 60 77 /*----------------------------------------------------------------------------*/ 61 78 static device_ops_t uhci_ops = { 62 79 .interfaces[USB_DEV_IFACE] = &hc_usb_iface, 63 80 .interfaces[USBHC_DEV_IFACE] = &uhci_iface 64 81 }; 82 /*----------------------------------------------------------------------------*/ 83 static driver_ops_t uhci_driver_ops = { 84 .add_device = uhci_add_device, 85 }; 86 /*----------------------------------------------------------------------------*/ 87 static driver_t uhci_driver = { 88 .name = NAME, 89 .driver_ops = &uhci_driver_ops 90 }; 91 /*----------------------------------------------------------------------------*/ 92 static void irq_handler(device_t *device, ipc_callid_t iid, ipc_call_t *call) 93 { 94 assert(device); 95 uhci_t *hc = dev_to_uhci(device); 96 uint16_t status = IPC_GET_ARG1(*call); 97 assert(hc); 98 uhci_interrupt(hc, status); 99 } 100 /*----------------------------------------------------------------------------*/ 101 #define CHECK_RET_RETURN(ret, message...) \ 102 if (ret != EOK) { \ 103 usb_log_error(message); \ 104 return ret; \ 105 } 65 106 66 107 static int uhci_add_device(device_t *device) … … 75 116 int irq; 76 117 77 int r c = pci_get_my_registers(device,78 &io_reg_base, &io_reg_size, &irq);118 int ret = 119 pci_get_my_registers(device, &io_reg_base, &io_reg_size, &irq); 79 120 80 if (rc != EOK) { 81 usb_log_error("Failed(%d) to get I/O registers addresses for device:.\n", 82 rc, device->handle); 83 return rc; 84 } 85 121 CHECK_RET_RETURN(ret, 122 "Failed(%d) to get I/O addresses:.\n", ret, device->handle); 86 123 usb_log_info("I/O regs at 0x%X (size %zu), IRQ %d.\n", 87 124 io_reg_base, io_reg_size, irq); 88 125 126 ret = pci_enable_interrupts(device); 127 CHECK_RET_RETURN(ret, "Failed(%d) to get enable interrupts:\n", ret); 128 89 129 uhci_t *uhci_hc = malloc(sizeof(uhci_t)); 90 if (!uhci_hc) { 91 usb_log_error("Failed to allocaete memory for uhci hcd driver.\n"); 92 return ENOMEM; 130 ret = (uhci_hc != NULL) ? EOK : ENOMEM; 131 CHECK_RET_RETURN(ret, "Failed to allocate memory for uhci hcd driver.\n"); 132 133 ret = uhci_init(uhci_hc, (void*)io_reg_base, io_reg_size); 134 if (ret != EOK) { 135 usb_log_error("Failed to init uhci-hcd.\n"); 136 free(uhci_hc); 137 return ret; 93 138 } 94 139 95 int ret = uhci_init(uhci_hc, (void*)io_reg_base, io_reg_size); 140 ret = register_interrupt_handler(device, irq, irq_handler, 141 &uhci_hc->interrupt_code); 96 142 if (ret != EOK) { 97 usb_log_error("Failed to init uhci-hcd.\n"); 143 usb_log_error("Failed to register interrupt handler.\n"); 144 uhci_fini(uhci_hc); 145 free(uhci_hc); 98 146 return ret; 99 147 } 148 100 149 device_t *rh; 101 150 ret = setup_root_hub(&rh, device); 102 103 151 if (ret != EOK) { 104 152 usb_log_error("Failed to setup uhci root hub.\n"); 105 /* TODO: destroy uhci here */ 153 uhci_fini(uhci_hc); 154 free(uhci_hc); 106 155 return ret; 107 156 } … … 110 159 if (ret != EOK) { 111 160 usb_log_error("Failed to register root hub.\n"); 112 /* TODO: destroy uhci here */ 161 uhci_fini(uhci_hc); 162 free(uhci_hc); 163 free(rh); 113 164 return ret; 114 165 } 115 166 116 167 device->driver_data = uhci_hc; 117 118 168 return EOK; 119 169 } 120 121 static driver_ops_t uhci_driver_ops = { 122 .add_device = uhci_add_device, 123 }; 124 125 static driver_t uhci_driver = { 126 .name = NAME, 127 .driver_ops = &uhci_driver_ops 128 }; 129 170 /*----------------------------------------------------------------------------*/ 130 171 int main(int argc, char *argv[]) 131 172 { 132 /* 133 * Do some global initializations. 134 */ 135 sleep(5); 136 usb_log_enable(USB_LOG_LEVEL_INFO, NAME); 173 sleep(3); 174 usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME); 137 175 138 176 return driver_main(&uhci_driver); -
uspace/drv/uhci-hcd/pci.c
r6bb83c7 r070f11e 121 121 return rc; 122 122 } 123 123 /*----------------------------------------------------------------------------*/ 124 int pci_enable_interrupts(device_t *device) 125 { 126 int parent_phone = devman_parent_device_connect(device->handle, 127 IPC_FLAG_BLOCKING); 128 bool enabled = hw_res_enable_interrupt(parent_phone); 129 return enabled ? EOK : EIO; 130 } 124 131 /** 125 132 * @} -
uspace/drv/uhci-hcd/pci.h
r6bb83c7 r070f11e 39 39 40 40 int pci_get_my_registers(device_t *, uintptr_t *, size_t *, int *); 41 int pci_enable_interrupts(device_t *device); 41 42 42 43 #endif -
uspace/drv/uhci-hcd/transfer_list.c
r6bb83c7 r070f11e 111 111 /* I'm the first one here */ 112 112 if (batch->link.prev == &instance->batch_list) { 113 usb_log_debug("Removing tracer%p was first, next element %x.\n",113 usb_log_debug("Removing batch %p was first, next element %x.\n", 114 114 batch, batch->qh->next_queue); 115 115 instance->queue_head->element = batch->qh->next_queue; 116 116 } else { 117 usb_log_debug("Removing tracer%p was NOT first, next element %x.\n",117 usb_log_debug("Removing batch %p was NOT first, next element %x.\n", 118 118 batch, batch->qh->next_queue); 119 119 batch_t *prev = list_get_instance(batch->link.prev, batch_t, link); -
uspace/drv/uhci-hcd/uhci-hcd.ma
r6bb83c7 r070f11e 1 1 10 pci/ven=8086&dev=7020 2 2 10 pci/ven=8086&dev=7112 -
uspace/drv/uhci-hcd/uhci.c
r6bb83c7 r070f11e 39 39 40 40 #include "uhci.h" 41 static irq_cmd_t uhci_cmds[] = { 42 { 43 .cmd = CMD_PIO_READ_16, 44 .addr = (void*)0xc022, 45 .dstarg = 1 46 }, 47 { 48 .cmd = CMD_PIO_WRITE_16, 49 .addr = (void*)0xc022, 50 .value = 0x1f 51 }, 52 { 53 .cmd = CMD_ACCEPT 54 } 55 }; 41 56 42 57 static int uhci_init_transfer_lists(uhci_t *instance); 43 static int uhci_clean_finished(void *arg); 58 static int uhci_init_mem_structures(uhci_t *instance); 59 static void uhci_init_hw(uhci_t *instance); 60 61 static int uhci_interrupt_emulator(void *arg); 44 62 static int uhci_debug_checker(void *arg); 63 45 64 static bool allowed_usb_packet( 46 65 bool low_speed, usb_transfer_type_t, size_t size); 47 66 48 int uhci_init(uhci_t *instance, void *regs, size_t reg_size) 49 { 50 #define CHECK_RET_RETURN(message...) \ 67 #define CHECK_RET_RETURN(ret, message...) \ 51 68 if (ret != EOK) { \ 52 69 usb_log_error(message); \ … … 54 71 } else (void) 0 55 72 56 /* init address keeper(libusb) */ 57 usb_address_keeping_init(&instance->address_manager, USB11_ADDRESS_MAX); 58 usb_log_debug("Initialized address manager.\n");73 int uhci_init(uhci_t *instance, void *regs, size_t reg_size) 74 { 75 assert(reg_size >= sizeof(regs_t)); 59 76 60 77 /* allow access to hc control registers */ 61 78 regs_t *io; 62 assert(reg_size >= sizeof(regs_t));63 79 int ret = pio_enable(regs, reg_size, (void**)&io); 64 CHECK_RET_RETURN( "Failed to gain access to registers at %p.\n", io);80 CHECK_RET_RETURN(ret, "Failed to gain access to registers at %p.\n", io); 65 81 instance->registers = io; 66 82 usb_log_debug("Device registers accessible.\n"); 67 83 84 ret = uhci_init_mem_structures(instance); 85 CHECK_RET_RETURN(ret, "Failed to initialize memory structures.\n"); 86 87 uhci_init_hw(instance); 88 89 instance->cleaner = fibril_create(uhci_interrupt_emulator, instance); 90 // fibril_add_ready(instance->cleaner); 91 92 instance->debug_checker = fibril_create(uhci_debug_checker, instance); 93 fibril_add_ready(instance->debug_checker); 94 95 return EOK; 96 } 97 /*----------------------------------------------------------------------------*/ 98 void uhci_init_hw(uhci_t *instance) 99 { 100 101 /* set framelist pointer */ 102 const uint32_t pa = addr_to_phys(instance->frame_list); 103 pio_write_32(&instance->registers->flbaseadd, pa); 104 105 /* enable all interrupts, but resume interrupt */ 106 pio_write_16(&instance->registers->usbintr, 107 UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET); 108 109 /* Start the hc with large(64B) packet FSBR */ 110 pio_write_16(&instance->registers->usbcmd, 111 UHCI_CMD_RUN_STOP | UHCI_CMD_MAX_PACKET | UHCI_CMD_CONFIGURE); 112 usb_log_debug("Started UHCI HC.\n"); 113 } 114 /*----------------------------------------------------------------------------*/ 115 int uhci_init_mem_structures(uhci_t *instance) 116 { 117 assert(instance); 118 119 /* init interrupt code */ 120 irq_cmd_t *interrupt_commands = malloc(sizeof(uhci_cmds)); 121 if (interrupt_commands == NULL) { 122 return ENOMEM; 123 } 124 memcpy(interrupt_commands, uhci_cmds, sizeof(uhci_cmds)); 125 interrupt_commands[0].addr = (void*)&instance->registers->usbsts; 126 interrupt_commands[1].addr = (void*)&instance->registers->usbsts; 127 instance->interrupt_code.cmds = interrupt_commands; 128 instance->interrupt_code.cmdcount = 129 sizeof(uhci_cmds) / sizeof(irq_cmd_t); 130 68 131 /* init transfer lists */ 69 ret = uhci_init_transfer_lists(instance); 70 CHECK_RET_RETURN("Failed to initialize transfer lists.\n"); 71 usb_log_debug("Transfer lists initialized.\n"); 72 73 74 usb_log_debug("Initializing frame list.\n"); 132 int ret = uhci_init_transfer_lists(instance); 133 CHECK_RET_RETURN(ret, "Failed to initialize transfer lists.\n"); 134 usb_log_debug("Initialized transfer lists.\n"); 135 136 /* frame list initialization */ 75 137 instance->frame_list = get_page(); 76 138 ret = instance ? EOK : ENOMEM; 77 CHECK_RET_RETURN("Failed to get frame list page.\n"); 139 CHECK_RET_RETURN(ret, "Failed to get frame list page.\n"); 140 usb_log_debug("Initialized frame list.\n"); 78 141 79 142 /* initialize all frames to point to the first queue head */ … … 86 149 } 87 150 88 const uintptr_t pa = (uintptr_t)addr_to_phys(instance->frame_list); 89 pio_write_32(&instance->registers->flbaseadd, (uint32_t)pa); 90 91 list_initialize(&instance->batch_list); 92 fibril_mutex_initialize(&instance->batch_list_mutex); 93 94 instance->cleaner = fibril_create(uhci_clean_finished, instance); 95 fibril_add_ready(instance->cleaner); 96 97 instance->debug_checker = fibril_create(uhci_debug_checker, instance); 98 fibril_add_ready(instance->debug_checker); 99 100 /* Start the hc with large(64B) packet FSBR */ 101 pio_write_16(&instance->registers->usbcmd, 102 UHCI_CMD_RUN_STOP | UHCI_CMD_MAX_PACKET); 103 usb_log_debug("Started UHCI HC.\n"); 104 105 uint16_t cmd = pio_read_16(&instance->registers->usbcmd); 106 cmd |= UHCI_CMD_DEBUG; 107 pio_write_16(&instance->registers->usbcmd, cmd); 151 /* init address keeper(libusb) */ 152 usb_address_keeping_init(&instance->address_manager, USB11_ADDRESS_MAX); 153 usb_log_debug("Initialized address manager.\n"); 108 154 109 155 return EOK; … … 114 160 assert(instance); 115 161 116 /* initialize */162 /* initialize TODO: check errors */ 117 163 int ret; 118 164 ret = transfer_list_init(&instance->transfers_bulk_full, "BULK_FULL"); … … 146 192 instance->transfers[1][USB_TRANSFER_CONTROL] = 147 193 &instance->transfers_control_slow; 148 instance->transfers[0][USB_TRANSFER_ CONTROL] =149 &instance->transfers_ control_full;194 instance->transfers[0][USB_TRANSFER_BULK] = 195 &instance->transfers_bulk_full; 150 196 151 197 return EOK; … … 174 220 } 175 221 /*----------------------------------------------------------------------------*/ 176 int uhci_clean_finished(void* arg) 177 { 178 usb_log_debug("Started cleaning fibril.\n"); 222 void uhci_interrupt(uhci_t *instance, uint16_t status) 223 { 224 assert(instance); 225 if ((status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) == 0) 226 return; 227 usb_log_debug("UHCI interrupt: %X.\n", status); 228 transfer_list_check(&instance->transfers_interrupt); 229 transfer_list_check(&instance->transfers_control_slow); 230 transfer_list_check(&instance->transfers_control_full); 231 transfer_list_check(&instance->transfers_bulk_full); 232 } 233 /*----------------------------------------------------------------------------*/ 234 int uhci_interrupt_emulator(void* arg) 235 { 236 usb_log_debug("Started interrupt emulator.\n"); 179 237 uhci_t *instance = (uhci_t*)arg; 180 238 assert(instance); 181 239 182 240 while(1) { 183 transfer_list_check(&instance->transfers_interrupt); 184 transfer_list_check(&instance->transfers_control_slow); 185 transfer_list_check(&instance->transfers_control_full); 186 transfer_list_check(&instance->transfers_bulk_full); 241 uint16_t status = pio_read_16(&instance->registers->usbsts); 242 uhci_interrupt(instance, status); 187 243 async_usleep(UHCI_CLEANER_TIMEOUT); 188 244 } … … 195 251 assert(instance); 196 252 while (1) { 197 uint16_t cmd = pio_read_16(&instance->registers->usbcmd); 198 uint16_t sts = pio_read_16(&instance->registers->usbsts); 199 usb_log_debug("Command register: %X Status register: %X\n", cmd, sts); 253 const uint16_t cmd = pio_read_16(&instance->registers->usbcmd); 254 const uint16_t sts = pio_read_16(&instance->registers->usbsts); 255 const uint16_t intr = pio_read_16(&instance->registers->usbintr); 256 usb_log_debug("Command: %X Status: %X Interrupts: %x\n", 257 cmd, sts, intr); 200 258 201 259 uintptr_t frame_list = pio_read_32(&instance->registers->flbaseadd); 202 if (frame_list != (uintptr_t)addr_to_phys(instance->frame_list)) {260 if (frame_list != addr_to_phys(instance->frame_list)) { 203 261 usb_log_debug("Framelist address: %p vs. %p.\n", 204 262 frame_list, addr_to_phys(instance->frame_list)); -
uspace/drv/uhci-hcd/uhci.h
r6bb83c7 r070f11e 66 66 67 67 uint16_t usbintr; 68 #define UHCI_INTR_SHORT_PACKET (1 << 3) 69 #define UHCI_INTR_COMPLETE (1 << 2) 70 #define UHCI_INTR_RESUME (1 << 1) 71 #define UHCI_INTR_CRC (1 << 0) 72 68 73 uint16_t frnum; 69 74 uint32_t flbaseadd; … … 81 86 link_pointer_t *frame_list; 82 87 83 link_t batch_list;84 fibril_mutex_t batch_list_mutex;85 86 88 transfer_list_t transfers_bulk_full; 87 89 transfer_list_t transfers_control_full; … … 90 92 91 93 transfer_list_t *transfers[2][4]; 94 95 irq_code_t interrupt_code; 92 96 93 97 fid_t cleaner; … … 98 102 int uhci_init(uhci_t *instance, void *regs, size_t reg_size); 99 103 100 int uhci_fini(uhci_t *device); 101 102 int uhci_transfer( 103 uhci_t *instance, 104 device_t *dev, 105 usb_target_t target, 106 usb_transfer_type_t transfer_type, 107 bool toggle, 108 usb_packet_id pid, 109 bool low_speed, 110 void *buffer, size_t size, 111 usbhc_iface_transfer_out_callback_t callback_out, 112 usbhc_iface_transfer_in_callback_t callback_in, 113 void *arg ); 104 static inline void uhci_fini(uhci_t *instance) {}; 114 105 115 106 int uhci_schedule(uhci_t *instance, batch_t *batch); 116 107 108 void uhci_interrupt(uhci_t *instance, uint16_t status); 109 117 110 static inline uhci_t * dev_to_uhci(device_t *dev) 118 111 { return (uhci_t*)dev->driver_data; } 112 119 113 120 114 #endif -
uspace/drv/uhci-rhd/main.c
r6bb83c7 r070f11e 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/uhci-rhd/port.c
r6bb83c7 r070f11e 131 131 return EOK; 132 132 } 133 /*----------------------------------------------------------------------------*/ 134 static int uhci_port_new_device(uhci_port_t *port) 135 { 136 assert(port); 137 assert(usb_hc_connection_is_opened(&port->hc_connection)); 138 139 usb_log_info("Adding new device on port %d.\n", port->number); 140 141 /* get address of the future device */ 142 const usb_address_t usb_address = usb_hc_request_address( 143 &port->hc_connection, true); 144 145 if (usb_address <= 0) { 146 usb_log_error("Recieved invalid address(%d).\n", usb_address); 147 return usb_address; 148 } 149 usb_log_debug("Sucessfully obtained address %d for port %d.\n", 150 usb_address, port->number); 151 152 /* get default address */ 153 int ret = usb_hc_reserve_default_address(&port->hc_connection, true); 154 if (ret != EOK) { 155 usb_log_error("Failed to reserve default address on port %d.\n", 156 port->number); 157 int ret2 = usb_hc_unregister_device(&port->hc_connection, 158 usb_address); 159 if (ret2 != EOK) { 160 usb_log_fatal("Failed to return requested address on port %d.\n", 161 port->number); 162 return ret2; 163 } 164 usb_log_debug("Successfully returned reserved address on port %d.\n", 165 port->number); 166 return ret; 167 } 168 usb_log_debug("Sucessfully obtained default address for port %d.\n", 169 port->number); 133 134 /** Callback for enabling port during adding a new device. 135 * 136 * @param portno Port number (unused). 137 * @param arg Pointer to uhci_port_t of port with the new device. 138 * @return Error code. 139 */ 140 static int new_device_enable_port(int portno, void *arg) 141 { 142 uhci_port_t *port = (uhci_port_t *) arg; 143 144 usb_log_debug("new_device_enable_port(%d)\n", port->number); 170 145 171 146 /* 172 * the host then waits for at least 100 ms to allow completion of147 * The host then waits for at least 100 ms to allow completion of 173 148 * an insertion process and for power at the device to become stable. 174 149 */ 175 150 async_usleep(100000); 176 151 177 /* enable port*/152 /* Enable the port. */ 178 153 uhci_port_set_enabled(port, true); 179 154 … … 197 172 } 198 173 199 /* 200 * Initialize connection to the device. 201 */ 202 /* FIXME: check for errors. */ 203 usb_device_connection_t new_dev_connection; 204 usb_endpoint_pipe_t new_dev_ctrl_pipe; 205 usb_device_connection_initialize_on_default_address( 206 &new_dev_connection, &port->hc_connection); 207 usb_endpoint_pipe_initialize_default_control(&new_dev_ctrl_pipe, 208 &new_dev_connection); 209 210 /* 211 * Assign new address to the device. This function updates 212 * the backing connection to still point to the same device. 213 */ 214 /* FIXME: check for errors. */ 215 usb_endpoint_pipe_start_session(&new_dev_ctrl_pipe); 216 ret = usb_request_set_address(&new_dev_ctrl_pipe, usb_address); 217 usb_endpoint_pipe_end_session(&new_dev_ctrl_pipe); 218 219 if (ret != EOK) { /* address assigning went wrong */ 220 usb_log_error("Failed(%d) to assign address to the device.\n", ret); 174 return EOK; 175 } 176 177 /*----------------------------------------------------------------------------*/ 178 static int uhci_port_new_device(uhci_port_t *port) 179 { 180 assert(port); 181 assert(usb_hc_connection_is_opened(&port->hc_connection)); 182 183 usb_log_info("Detected new device on port %u.\n", port->number); 184 185 usb_address_t dev_addr; 186 int rc = usb_hc_new_device_wrapper(port->rh, &port->hc_connection, 187 USB_SPEED_FULL, 188 new_device_enable_port, port->number, port, 189 &dev_addr, &port->attached_device); 190 if (rc != EOK) { 191 usb_log_error("Failed adding new device on port %u: %s.\n", 192 port->number, str_error(rc)); 221 193 uhci_port_set_enabled(port, false); 222 int release = usb_hc_release_default_address(&port->hc_connection); 223 if (release != EOK) { 224 usb_log_error("Failed to release default address on port %d.\n", 225 port->number); 226 return release; 227 } 228 usb_log_debug("Sucessfully released default address on port %d.\n", 229 port->number); 230 return ret; 231 } 232 usb_log_debug("Sucessfully assigned address %d for port %d.\n", 233 usb_address, port->number); 234 235 /* release default address */ 236 ret = usb_hc_release_default_address(&port->hc_connection); 237 if (ret != EOK) { 238 usb_log_error("Failed to release default address on port %d.\n", 239 port->number); 240 return ret; 241 } 242 usb_log_debug("Sucessfully released default address on port %d.\n", 243 port->number); 244 245 /* communicate and possibly report to devman */ 246 assert(port->attached_device == 0); 247 248 ret = usb_device_register_child_in_devman(new_dev_connection.address, 249 new_dev_connection.hc_handle, port->rh, &port->attached_device); 250 251 if (ret != EOK) { /* something went wrong */ 252 usb_log_error("Failed(%d) in usb_drv_register_child.\n", ret); 253 uhci_port_set_enabled(port, false); 254 return ENOMEM; 255 } 256 usb_log_info("Sucessfully added device on port(%d) address(%d) handle %d.\n", 257 port->number, usb_address, port->attached_device); 258 259 /* 260 * Register the device in the host controller. 261 */ 262 usb_hc_attached_device_t new_device = { 263 .address = new_dev_connection.address, 264 .handle = port->attached_device 265 }; 266 267 ret = usb_hc_register_device(&port->hc_connection, &new_device); 268 // TODO: proper error check here 269 assert(ret == EOK); 270 271 return EOK; 272 } 194 return rc; 195 } 196 197 usb_log_info("New device on port %u has address %d (handle %zu).\n", 198 port->number, dev_addr, port->attached_device); 199 200 return EOK; 201 } 202 273 203 /*----------------------------------------------------------------------------*/ 274 204 static int uhci_port_remove_device(uhci_port_t *port) -
uspace/drv/uhci-rhd/root_hub.c
r6bb83c7 r070f11e 47 47 assert(rh); 48 48 int ret; 49 ret = usb_ drv_find_hc(rh, &instance->hc_handle);49 ret = usb_hc_find(rh->handle, &instance->hc_handle); 50 50 usb_log_info("rh found(%d) hc handle: %d.\n", ret, instance->hc_handle); 51 51 if (ret != EOK) { -
uspace/drv/usbhid/main.c
r6bb83c7 r070f11e 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
r6bb83c7 r070f11e 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 usb_iface_t hub_usb_iface = {55 .get_hc_handle = usb_drv_find_hc56 };57 58 55 static device_ops_t hub_device_ops = { 59 .interfaces[USB_DEV_IFACE] = & hub_usb_iface56 .interfaces[USB_DEV_IFACE] = &usb_iface_hub_impl 60 57 }; 61 58 -
uspace/drv/vhc/conn.h
r6bb83c7 r070f11e 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
r6bb83c7 r070f11e 37 37 #include <usb/usb.h> 38 38 #include <usb/addrkeep.h> 39 #include <usb/ddfiface.h> 39 40 40 41 #include "vhcd.h" … … 234 235 } 235 236 236 static int enqueue_transfer_setup(device_t *dev,237 usb_target_t target, usb_transfer_type_t transfer_type,238 void *buffer, size_t size,239 usbhc_iface_transfer_out_callback_t callback, void *arg)240 {241 usb_log_debug2("Transfer SETUP [%d.%d (%s); %zu].\n",242 target.address, target.endpoint,243 usb_str_transfer_type(transfer_type),244 size);245 246 transfer_info_t *transfer247 = create_transfer_info(dev, USB_DIRECTION_OUT, arg);248 transfer->out_callback = callback;249 250 hc_add_transaction_to_device(true, target, transfer_type, buffer, size,251 universal_callback, transfer);252 253 return EOK;254 }255 256 237 static int enqueue_transfer_in(device_t *dev, 257 238 usb_target_t target, usb_transfer_type_t transfer_type, … … 292 273 return enqueue_transfer_in(dev, target, USB_TRANSFER_INTERRUPT, 293 274 data, size, 294 callback, arg);295 }296 297 static int control_write_setup(device_t *dev, usb_target_t target,298 size_t max_packet_size,299 void *data, size_t size,300 usbhc_iface_transfer_out_callback_t callback, void *arg)301 {302 return enqueue_transfer_setup(dev, target, USB_TRANSFER_CONTROL,303 data, size,304 callback, arg);305 }306 307 static int control_write_data(device_t *dev, usb_target_t target,308 size_t max_packet_size,309 void *data, size_t size,310 usbhc_iface_transfer_out_callback_t callback, void *arg)311 {312 return enqueue_transfer_out(dev, target, USB_TRANSFER_CONTROL,313 data, size,314 callback, arg);315 }316 317 static int control_write_status(device_t *dev, usb_target_t target,318 usbhc_iface_transfer_in_callback_t callback, void *arg)319 {320 return enqueue_transfer_in(dev, target, USB_TRANSFER_CONTROL,321 NULL, 0,322 275 callback, arg); 323 276 } … … 341 294 } 342 295 343 static int control_read_setup(device_t *dev, usb_target_t target,344 size_t max_packet_size,345 void *data, size_t size,346 usbhc_iface_transfer_out_callback_t callback, void *arg)347 {348 return enqueue_transfer_setup(dev, target, USB_TRANSFER_CONTROL,349 data, size,350 callback, arg);351 }352 353 static int control_read_data(device_t *dev, usb_target_t target,354 size_t max_packet_size,355 void *data, size_t size,356 usbhc_iface_transfer_in_callback_t callback, void *arg)357 {358 return enqueue_transfer_in(dev, target, USB_TRANSFER_CONTROL,359 data, size,360 callback, arg);361 }362 363 static int control_read_status(device_t *dev, usb_target_t target,364 usbhc_iface_transfer_out_callback_t callback, void *arg)365 {366 return enqueue_transfer_out(dev, target, USB_TRANSFER_CONTROL,367 NULL, 0,368 callback, arg);369 }370 371 296 static int control_read(device_t *dev, usb_target_t target, 372 297 size_t max_packet_size, … … 389 314 static usb_address_keeping_t addresses; 390 315 391 392 static int reserve_default_address(device_t *dev, bool ignored) 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 } 327 328 static int reserve_default_address(device_t *dev, usb_speed_t ignored) 393 329 { 394 330 usb_address_keeping_reserve_default(&addresses); … … 402 338 } 403 339 404 static int request_address(device_t *dev, bool ignored, usb_address_t *address) 340 static int request_address(device_t *dev, usb_speed_t ignored, 341 usb_address_t *address) 405 342 { 406 343 usb_address_t addr = usb_address_keeping_request(&addresses); … … 425 362 } 426 363 427 static int tell_address(device_t *dev, devman_handle_t handle,428 usb_address_t *address)429 {430 usb_address_t addr = usb_address_keeping_find(&addresses, handle);431 if (addr < 0) {432 return addr;433 }434 435 *address = addr;436 return EOK;437 }438 439 364 void address_init(void) 440 365 { … … 443 368 444 369 usbhc_iface_t vhc_iface = { 445 .tell_address = tell_address,446 447 370 .reserve_default_address = reserve_default_address, 448 371 .release_default_address = release_default_address, … … 454 377 .interrupt_in = interrupt_in, 455 378 456 .control_write_setup = control_write_setup,457 .control_write_data = control_write_data,458 .control_write_status = control_write_status,459 460 379 .control_write = control_write, 461 462 .control_read_setup = control_read_setup,463 .control_read_data = control_read_data,464 .control_read_status = control_read_status,465 466 380 .control_read = control_read 467 381 }; 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 468 388 469 389 /** -
uspace/drv/vhc/hcd.c
r6bb83c7 r070f11e 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/c/generic/str_error.c
r6bb83c7 r070f11e 73 73 case EBADCHECKSUM: 74 74 return "Bad checksum"; 75 case ESTALL: 76 return "Operation stalled"; 75 77 case EAGAIN: 76 78 return "Resource temporarily unavailable"; -
uspace/lib/c/include/errno.h
r6bb83c7 r070f11e 59 59 #define EBADCHECKSUM (-300) 60 60 61 /** USB: stalled operation. */ 62 #define ESTALL (-301) 63 61 64 /** An API function is called while another blocking function is in progress. */ 62 65 #define EINPROGRESS (-10036) -
uspace/lib/drv/generic/remote_usb.c
r6bb83c7 r070f11e 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
r6bb83c7 r070f11e 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 *); 48 static void remote_usbhc_control_write_setup(device_t *, void *, ipc_callid_t, ipc_call_t *); 49 static void remote_usbhc_control_write_data(device_t *, void *, ipc_callid_t, ipc_call_t *); 50 static void remote_usbhc_control_write_status(device_t *, void *, ipc_callid_t, ipc_call_t *); 51 static void remote_usbhc_control_read_setup(device_t *, void *, ipc_callid_t, ipc_call_t *); 52 static void remote_usbhc_control_read_data(device_t *, void *, ipc_callid_t, ipc_call_t *); 53 static void remote_usbhc_control_read_status(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 *); 54 49 static void remote_usbhc_control_write(device_t *, void *, ipc_callid_t, ipc_call_t *); 55 50 static void remote_usbhc_control_read(device_t *, void *, ipc_callid_t, ipc_call_t *); … … 63 58 /** Remote USB host controller interface operations. */ 64 59 static remote_iface_func_ptr_t remote_usbhc_iface_ops [] = { 65 remote_usbhc_get_address,66 67 60 remote_usbhc_reserve_default_address, 68 61 remote_usbhc_release_default_address, … … 75 68 remote_usbhc_interrupt_in, 76 69 77 remote_usbhc_control_write_setup, 78 remote_usbhc_control_write_data, 79 remote_usbhc_control_write_status, 80 81 remote_usbhc_control_read_setup, 82 remote_usbhc_control_read_data, 83 remote_usbhc_control_read_status, 70 remote_usbhc_bulk_out, 71 remote_usbhc_bulk_in, 84 72 85 73 remote_usbhc_control_write, … … 135 123 } 136 124 137 void remote_usbhc_get_address(device_t *device, void *iface, 138 ipc_callid_t callid, ipc_call_t *call) 139 { 140 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 141 142 if (!usb_iface->tell_address) { 143 async_answer_0(callid, ENOTSUP); 144 return; 145 } 146 147 devman_handle_t handle = DEV_IPC_GET_ARG1(*call); 125 void remote_usbhc_reserve_default_address(device_t *device, void *iface, 126 ipc_callid_t callid, ipc_call_t *call) 127 { 128 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 129 130 if (!usb_iface->reserve_default_address) { 131 async_answer_0(callid, ENOTSUP); 132 return; 133 } 134 135 usb_speed_t speed = DEV_IPC_GET_ARG1(*call); 136 137 int rc = usb_iface->reserve_default_address(device, speed); 138 139 async_answer_0(callid, rc); 140 } 141 142 void remote_usbhc_release_default_address(device_t *device, void *iface, 143 ipc_callid_t callid, ipc_call_t *call) 144 { 145 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 146 147 if (!usb_iface->release_default_address) { 148 async_answer_0(callid, ENOTSUP); 149 return; 150 } 151 152 int rc = usb_iface->release_default_address(device); 153 154 async_answer_0(callid, rc); 155 } 156 157 void remote_usbhc_request_address(device_t *device, void *iface, 158 ipc_callid_t callid, ipc_call_t *call) 159 { 160 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 161 162 if (!usb_iface->request_address) { 163 async_answer_0(callid, ENOTSUP); 164 return; 165 } 166 167 usb_speed_t speed = DEV_IPC_GET_ARG1(*call); 148 168 149 169 usb_address_t address; 150 int rc = usb_iface->tell_address(device, handle, &address); 151 if (rc != EOK) { 152 async_answer_0(callid, rc); 153 } else { 154 async_answer_1(callid, EOK, address); 155 } 156 } 157 158 void remote_usbhc_reserve_default_address(device_t *device, void *iface, 159 ipc_callid_t callid, ipc_call_t *call) 160 { 161 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 162 163 if (!usb_iface->reserve_default_address) { 164 async_answer_0(callid, ENOTSUP); 165 return; 166 } 167 168 bool full_speed = DEV_IPC_GET_ARG1(*call); 169 170 int rc = usb_iface->reserve_default_address(device, full_speed); 171 172 async_answer_0(callid, rc); 173 } 174 175 void remote_usbhc_release_default_address(device_t *device, void *iface, 176 ipc_callid_t callid, ipc_call_t *call) 177 { 178 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 179 180 if (!usb_iface->release_default_address) { 181 async_answer_0(callid, ENOTSUP); 182 return; 183 } 184 185 int rc = usb_iface->release_default_address(device); 186 187 async_answer_0(callid, rc); 188 } 189 190 void remote_usbhc_request_address(device_t *device, void *iface, 191 ipc_callid_t callid, ipc_call_t *call) 192 { 193 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 194 195 if (!usb_iface->request_address) { 196 async_answer_0(callid, ENOTSUP); 197 return; 198 } 199 200 bool full_speed = DEV_IPC_GET_ARG1(*call); 201 202 usb_address_t address; 203 int rc = usb_iface->request_address(device, full_speed, &address); 170 int rc = usb_iface->request_address(device, speed, &address); 204 171 if (rc != EOK) { 205 172 async_answer_0(callid, rc); … … 297 264 } 298 265 299 size_t expected_len= DEV_IPC_GET_ARG3(*call);266 size_t max_packet_size = DEV_IPC_GET_ARG3(*call); 300 267 usb_target_t target = { 301 268 .address = DEV_IPC_GET_ARG1(*call), … … 305 272 size_t len = 0; 306 273 void *buffer = NULL; 307 if (expected_len > 0) { 308 int rc = async_data_write_accept(&buffer, false, 309 1, USB_MAX_PAYLOAD_SIZE, 310 0, &len); 311 312 if (rc != EOK) { 313 async_answer_0(callid, rc); 314 return; 315 } 274 275 int rc = async_data_write_accept(&buffer, false, 276 1, USB_MAX_PAYLOAD_SIZE, 277 0, &len); 278 279 if (rc != EOK) { 280 async_answer_0(callid, rc); 281 return; 316 282 } 317 283 … … 328 294 trans->size = len; 329 295 330 int rc = transfer_func(device, target, HACK_MAX_PACKET_SIZE,296 rc = transfer_func(device, target, max_packet_size, 331 297 buffer, len, 332 298 callback_out, trans); … … 354 320 } 355 321 356 size_t len= DEV_IPC_GET_ARG3(*call);322 size_t max_packet_size = DEV_IPC_GET_ARG3(*call); 357 323 usb_target_t target = { 358 324 .address = DEV_IPC_GET_ARG1(*call), … … 360 326 }; 361 327 328 size_t len; 362 329 ipc_callid_t data_callid; 363 330 if (!async_data_read_receive(&data_callid, &len)) { … … 375 342 trans->size = len; 376 343 377 int rc = transfer_func(device, target, HACK_MAX_PACKET_SIZE_INTERRUPT_IN,344 int rc = transfer_func(device, target, max_packet_size, 378 345 trans->buffer, len, 379 346 callback_in, trans); … … 385 352 } 386 353 387 /** Process status part of control transfer.388 *389 * @param device Target device.390 * @param callid Initiating caller.391 * @param call Initiating call.392 * @param direction Transfer direction (read ~ in, write ~ out).393 * @param transfer_in_func Transfer function for control read (might be NULL).394 * @param transfer_out_func Transfer function for control write (might be NULL).395 */396 static void remote_usbhc_status_transfer(device_t *device,397 ipc_callid_t callid, ipc_call_t *call,398 usb_direction_t direction,399 int (*transfer_in_func)(device_t *, usb_target_t,400 usbhc_iface_transfer_in_callback_t, void *),401 int (*transfer_out_func)(device_t *, usb_target_t,402 usbhc_iface_transfer_out_callback_t, void *))403 {404 switch (direction) {405 case USB_DIRECTION_IN:406 if (!transfer_in_func) {407 async_answer_0(callid, ENOTSUP);408 return;409 }410 break;411 case USB_DIRECTION_OUT:412 if (!transfer_out_func) {413 async_answer_0(callid, ENOTSUP);414 return;415 }416 break;417 default:418 assert(false && "unreachable code");419 break;420 }421 422 usb_target_t target = {423 .address = DEV_IPC_GET_ARG1(*call),424 .endpoint = DEV_IPC_GET_ARG2(*call)425 };426 427 async_transaction_t *trans = async_transaction_create(callid);428 if (trans == NULL) {429 async_answer_0(callid, ENOMEM);430 return;431 }432 433 int rc;434 switch (direction) {435 case USB_DIRECTION_IN:436 rc = transfer_in_func(device, target,437 callback_in, trans);438 break;439 case USB_DIRECTION_OUT:440 rc = transfer_out_func(device, target,441 callback_out, trans);442 break;443 default:444 assert(false && "unreachable code");445 break;446 }447 448 if (rc != EOK) {449 async_answer_0(callid, rc);450 async_transaction_destroy(trans);451 }452 }453 454 455 354 void remote_usbhc_interrupt_out(device_t *device, void *iface, 456 355 ipc_callid_t callid, ipc_call_t *call) … … 473 372 } 474 373 475 void remote_usbhc_ control_write_setup(device_t *device, void *iface,374 void remote_usbhc_bulk_out(device_t *device, void *iface, 476 375 ipc_callid_t callid, ipc_call_t *call) 477 376 { … … 480 379 481 380 return remote_usbhc_out_transfer(device, callid, call, 482 usb_iface-> control_write_setup);483 } 484 485 void remote_usbhc_ control_write_data(device_t *device, void *iface,381 usb_iface->bulk_out); 382 } 383 384 void remote_usbhc_bulk_in(device_t *device, void *iface, 486 385 ipc_callid_t callid, ipc_call_t *call) 487 386 { … … 489 388 assert(usb_iface != NULL); 490 389 491 return remote_usbhc_out_transfer(device, callid, call,492 usb_iface->control_write_data);493 }494 495 void remote_usbhc_control_write_status(device_t *device, void *iface,496 ipc_callid_t callid, ipc_call_t *call)497 {498 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;499 assert(usb_iface != NULL);500 501 return remote_usbhc_status_transfer(device, callid, call,502 USB_DIRECTION_IN, usb_iface->control_write_status, NULL);503 }504 505 void remote_usbhc_control_read_setup(device_t *device, void *iface,506 ipc_callid_t callid, ipc_call_t *call)507 {508 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;509 assert(usb_iface != NULL);510 511 return remote_usbhc_out_transfer(device, callid, call,512 usb_iface->control_read_setup);513 }514 515 void remote_usbhc_control_read_data(device_t *device, void *iface,516 ipc_callid_t callid, ipc_call_t *call)517 {518 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;519 assert(usb_iface != NULL);520 521 390 return remote_usbhc_in_transfer(device, callid, call, 522 usb_iface->control_read_data); 523 } 524 525 void remote_usbhc_control_read_status(device_t *device, void *iface, 526 ipc_callid_t callid, ipc_call_t *call) 527 { 528 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 529 assert(usb_iface != NULL); 530 531 return remote_usbhc_status_transfer(device, callid, call, 532 USB_DIRECTION_OUT, NULL, usb_iface->control_read_status); 391 usb_iface->bulk_in); 533 392 } 534 393 … … 549 408 }; 550 409 size_t data_buffer_len = DEV_IPC_GET_ARG3(*call); 410 size_t max_packet_size = DEV_IPC_GET_ARG4(*call); 551 411 552 412 int rc; … … 584 444 trans->size = data_buffer_len; 585 445 586 rc = usb_iface->control_write(device, target, HACK_MAX_PACKET_SIZE,446 rc = usb_iface->control_write(device, target, max_packet_size, 587 447 setup_packet, setup_packet_len, 588 448 data_buffer, data_buffer_len, … … 611 471 .endpoint = DEV_IPC_GET_ARG2(*call) 612 472 }; 473 size_t max_packet_size = DEV_IPC_GET_ARG3(*call); 613 474 614 475 int rc; … … 648 509 } 649 510 650 rc = usb_iface->control_read(device, target, HACK_MAX_PACKET_SIZE,511 rc = usb_iface->control_read(device, target, max_packet_size, 651 512 setup_packet, setup_packet_len, 652 513 trans->buffer, trans->size, -
uspace/lib/drv/include/usb_iface.h
r6bb83c7 r070f11e 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
r6bb83c7 r070f11e 53 53 * - argument #1 is target address 54 54 * - argument #2 is target endpoint 55 * - argument #3 is buffer size55 * - argument #3 is max packet size of the endpoint 56 56 * - this call is immediately followed by IPC data write (from caller) 57 57 * - the initial call (and the whole transaction) is answer after the … … 66 66 * - argument #1 is target address 67 67 * - argument #2 is target endpoint 68 * - argument #3 is buffer size68 * - argument #3 is max packet size of the endpoint 69 69 * - this call is immediately followed by IPC data read (async version) 70 70 * - the call is not answered until the device returns some data (or until … … 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 155 156 /** Start WRITE control transfer. 143 /** Send bulk data to device. 157 144 * See explanation at usb_iface_funcs_t (OUT transaction). 158 145 */ 159 IPC_M_USBHC_CONTROL_WRITE_SETUP, 160 161 /** Send control-transfer data to device. 162 * See explanation at usb_iface_funcs_t (OUT transaction). 163 */ 164 IPC_M_USBHC_CONTROL_WRITE_DATA, 165 166 /** Terminate WRITE control transfer. 167 * See explanation at usb_iface_funcs_t (NO-DATA transaction). 168 */ 169 IPC_M_USBHC_CONTROL_WRITE_STATUS, 170 171 172 173 /** Start READ control transfer. 174 * See explanation at usb_iface_funcs_t (OUT transaction). 175 */ 176 IPC_M_USBHC_CONTROL_READ_SETUP, 177 178 /** Get control-transfer data from device. 146 IPC_M_USBHC_BULK_OUT, 147 148 /** Get bulk data from device. 179 149 * See explanation at usb_iface_funcs_t (IN transaction). 180 150 */ 181 IPC_M_USBHC_CONTROL_READ_DATA, 182 183 /** Terminate READ control transfer. 184 * See explanation at usb_iface_funcs_t (NO-DATA transaction). 185 */ 186 IPC_M_USBHC_CONTROL_READ_STATUS, 151 IPC_M_USBHC_BULK_IN, 187 152 188 153 /** Issue control WRITE transfer. … … 194 159 IPC_M_USBHC_CONTROL_WRITE, 195 160 196 /** Issue control WRITEtransfer.161 /** Issue control READ transfer. 197 162 * See explanation at usb_iface_funcs_t (IN transaction) for 198 163 * call parameters. 199 * This call is immediately followed by IPC data read from the caller 200 * (setup packet). 201 * Actual data are retrieved through IPC_M_USBHC_GET_BUFFER. 164 * This call is immediately followed by IPC data write from the caller 165 * (setup packet) and IPC data read (buffer that was read). 202 166 */ 203 167 IPC_M_USBHC_CONTROL_READ, … … 230 194 /** USB host controller communication interface. */ 231 195 typedef struct { 232 int (*tell_address)(device_t *, devman_handle_t, usb_address_t *); 233 234 int (*reserve_default_address)(device_t *, bool); 196 int (*reserve_default_address)(device_t *, usb_speed_t); 235 197 int (*release_default_address)(device_t *); 236 int (*request_address)(device_t *, bool, usb_address_t *);198 int (*request_address)(device_t *, usb_speed_t, usb_address_t *); 237 199 int (*bind_address)(device_t *, usb_address_t, devman_handle_t); 238 200 int (*release_address)(device_t *, usb_address_t); … … 241 203 usbhc_iface_transfer_in_t interrupt_in; 242 204 243 usbhc_iface_transfer_setup_t control_write_setup; 244 usbhc_iface_transfer_out_t control_write_data; 245 int (*control_write_status)(device_t *, usb_target_t, 246 usbhc_iface_transfer_in_callback_t, void *); 247 248 usbhc_iface_transfer_setup_t control_read_setup; 249 usbhc_iface_transfer_in_t control_read_data; 250 int (*control_read_status)(device_t *, usb_target_t, 251 usbhc_iface_transfer_out_callback_t, void *); 205 usbhc_iface_transfer_out_t bulk_out; 206 usbhc_iface_transfer_in_t bulk_in; 252 207 253 208 int (*control_write)(device_t *, usb_target_t, -
uspace/lib/usb/Makefile
r6bb83c7 r070f11e 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
r6bb83c7 r070f11e 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/hub.h
r6bb83c7 r070f11e 39 39 #include <usb/usbdevice.h> 40 40 41 int usb_hc_new_device_wrapper(device_t *, usb_hc_connection_t *, usb_speed_t, 42 int (*)(int, void *), int, void *, usb_address_t *, devman_handle_t *); 41 43 42 44 /** Info about device attached to host controller. … … 53 55 } usb_hc_attached_device_t; 54 56 55 int usb_hc_reserve_default_address(usb_hc_connection_t *, bool);57 int usb_hc_reserve_default_address(usb_hc_connection_t *, usb_speed_t); 56 58 int usb_hc_release_default_address(usb_hc_connection_t *); 57 59 58 usb_address_t usb_hc_request_address(usb_hc_connection_t *, bool);60 usb_address_t usb_hc_request_address(usb_hc_connection_t *, usb_speed_t); 59 61 int usb_hc_register_device(usb_hc_connection_t *, 60 62 const usb_hc_attached_device_t *); -
uspace/lib/usb/include/usb/pipes.h
r6bb83c7 r070f11e 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
r6bb83c7 r070f11e 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/usb.h
r6bb83c7 r070f11e 68 68 USB_DIRECTION_BOTH 69 69 } usb_direction_t; 70 71 /** USB speeds. */ 72 typedef enum { 73 /** USB 1.1 low speed (1.5Mbits/s). */ 74 USB_SPEED_LOW, 75 /** USB 1.1 full speed (12Mbits/s). */ 76 USB_SPEED_FULL, 77 /** USB 2.0 high speed (480Mbits/s). */ 78 USB_SPEED_HIGH 79 } usb_speed_t; 70 80 71 81 /** USB request type target. */ -
uspace/lib/usb/include/usb/usbdrv.h
r6bb83c7 r070f11e 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
r6bb83c7 r070f11e 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
r6bb83c7 r070f11e 34 34 */ 35 35 #include <usb/hub.h> 36 #include <usb/pipes.h> 37 #include <usb/request.h> 38 #include <usb/recognise.h> 36 39 #include <usbhc_iface.h> 37 40 #include <errno.h> … … 56 59 */ 57 60 int usb_hc_reserve_default_address(usb_hc_connection_t *connection, 58 bool full_speed)61 usb_speed_t speed) 59 62 { 60 63 CHECK_CONNECTION(connection); … … 62 65 return async_req_2_0(connection->hc_phone, 63 66 DEV_IFACE_ID(USBHC_DEV_IFACE), 64 IPC_M_USBHC_RESERVE_DEFAULT_ADDRESS, full_speed);67 IPC_M_USBHC_RESERVE_DEFAULT_ADDRESS, speed); 65 68 } 66 69 … … 85 88 */ 86 89 usb_address_t usb_hc_request_address(usb_hc_connection_t *connection, 87 bool full_speed)90 usb_speed_t speed) 88 91 { 89 92 CHECK_CONNECTION(connection); … … 92 95 int rc = async_req_2_1(connection->hc_phone, 93 96 DEV_IFACE_ID(USBHC_DEV_IFACE), 94 IPC_M_USBHC_REQUEST_ADDRESS, full_speed,97 IPC_M_USBHC_REQUEST_ADDRESS, speed, 95 98 &address); 96 99 if (rc != EOK) { … … 138 141 139 142 143 /** Wrapper for registering attached device to the hub. 144 * 145 * The @p enable_port function is expected to enable singalling on given 146 * port. 147 * The two arguments to it can have arbitrary meaning 148 * (the @p port_no is only a suggestion) 149 * and are not touched at all by this function 150 * (they are passed as is to the @p enable_port function). 151 * 152 * If the @p enable_port fails (i.e. does not return EOK), the device 153 * addition is cancelled. 154 * The return value is then returned (it is good idea to use different 155 * error codes than those listed as return codes by this function itself). 156 * 157 * @param parent Parent device (i.e. the hub device). 158 * @param connection Opened connection to host controller. 159 * @param dev_speed New device speed. 160 * @param enable_port Function for enabling signalling through the port the 161 * device is attached to. 162 * @param port_no Port number (passed through to @p enable_port). 163 * @param arg Any data argument to @p enable_port. 164 * @param[out] assigned_address USB address of the device. 165 * @param[out] assigned_handle Devman handle of the new device. 166 * @return Error code. 167 * @retval ENOENT Connection to HC not opened. 168 * @retval EADDRNOTAVAIL Failed retrieving free address from host controller. 169 * @retval EBUSY Failed reserving default USB address. 170 * @retval ENOTCONN Problem connecting to the host controller via USB pipe. 171 * @retval ESTALL Problem communication with device (either SET_ADDRESS 172 * request or requests for descriptors when creating match ids). 173 */ 174 int usb_hc_new_device_wrapper(device_t *parent, usb_hc_connection_t *connection, 175 usb_speed_t dev_speed, 176 int (*enable_port)(int port_no, void *arg), int port_no, void *arg, 177 usb_address_t *assigned_address, devman_handle_t *assigned_handle) 178 { 179 CHECK_CONNECTION(connection); 180 181 /* 182 * Request new address. 183 */ 184 usb_address_t dev_addr = usb_hc_request_address(connection, dev_speed); 185 if (dev_addr < 0) { 186 return EADDRNOTAVAIL; 187 } 188 189 int rc; 190 191 /* 192 * Reserve the default address. 193 */ 194 rc = usb_hc_reserve_default_address(connection, dev_speed); 195 if (rc != EOK) { 196 rc = EBUSY; 197 goto leave_release_free_address; 198 } 199 200 /* 201 * Enable the port (i.e. allow signalling through this port). 202 */ 203 rc = enable_port(port_no, arg); 204 if (rc != EOK) { 205 goto leave_release_default_address; 206 } 207 208 /* 209 * Change the address from default to the free one. 210 * We need to create a new control pipe for that. 211 */ 212 usb_device_connection_t dev_conn; 213 rc = usb_device_connection_initialize_on_default_address(&dev_conn, 214 connection); 215 if (rc != EOK) { 216 rc = ENOTCONN; 217 goto leave_release_default_address; 218 } 219 220 usb_endpoint_pipe_t ctrl_pipe; 221 rc = usb_endpoint_pipe_initialize_default_control(&ctrl_pipe, 222 &dev_conn); 223 if (rc != EOK) { 224 rc = ENOTCONN; 225 goto leave_release_default_address; 226 } 227 228 rc = usb_endpoint_pipe_start_session(&ctrl_pipe); 229 if (rc != EOK) { 230 rc = ENOTCONN; 231 goto leave_release_default_address; 232 } 233 234 rc = usb_request_set_address(&ctrl_pipe, dev_addr); 235 if (rc != EOK) { 236 rc = ESTALL; 237 goto leave_stop_session; 238 } 239 240 usb_endpoint_pipe_end_session(&ctrl_pipe); 241 242 /* 243 * Once the address is changed, we can return the default address. 244 */ 245 usb_hc_release_default_address(connection); 246 247 /* 248 * It is time to register the device with devman. 249 */ 250 /* FIXME: create device_register that will get opened ctrl pipe. */ 251 devman_handle_t child_handle; 252 rc = usb_device_register_child_in_devman(dev_addr, dev_conn.hc_handle, 253 parent, &child_handle); 254 if (rc != EOK) { 255 rc = ESTALL; 256 goto leave_release_free_address; 257 } 258 259 /* 260 * And now inform the host controller about the handle. 261 */ 262 usb_hc_attached_device_t new_device = { 263 .address = dev_addr, 264 .handle = child_handle 265 }; 266 rc = usb_hc_register_device(connection, &new_device); 267 if (rc != EOK) { 268 rc = EDESTADDRREQ; 269 goto leave_release_free_address; 270 } 271 272 /* 273 * And we are done. 274 */ 275 if (assigned_address != NULL) { 276 *assigned_address = dev_addr; 277 } 278 if (assigned_handle != NULL) { 279 *assigned_handle = child_handle; 280 } 281 282 return EOK; 283 284 285 286 /* 287 * Error handling (like nested exceptions) starts here. 288 * Completely ignoring errors here. 289 */ 290 291 leave_stop_session: 292 usb_endpoint_pipe_end_session(&ctrl_pipe); 293 294 leave_release_default_address: 295 usb_hc_release_default_address(connection); 296 297 leave_release_free_address: 298 usb_hc_unregister_device(connection, dev_addr); 299 300 return rc; 301 } 302 140 303 /** 141 304 * @} -
uspace/lib/usb/src/pipes.c
r6bb83c7 r070f11e 35 35 #include <usb/usb.h> 36 36 #include <usb/pipes.h> 37 #include <usbhc_iface.h> 38 #include <usb_iface.h> 37 39 #include <errno.h> 38 40 #include <assert.h> 39 #include <usb/usbdrv.h> 41 42 /** Tell USB address assigned to given device. 43 * 44 * @param phone Phone to parent device. 45 * @param dev Device in question. 46 * @return USB address or error code. 47 */ 48 static usb_address_t get_my_address(int phone, device_t *dev) 49 { 50 sysarg_t address; 51 int rc = async_req_2_1(phone, DEV_IFACE_ID(USB_DEV_IFACE), 52 IPC_M_USB_GET_ADDRESS, 53 dev->handle, &address); 54 55 if (rc != EOK) { 56 return rc; 57 } 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; 87 } 40 88 41 89 /** Initialize connection to USB device. … … 55 103 usb_address_t my_address; 56 104 57 rc = usb_ drv_find_hc(device, &hc_handle);105 rc = usb_hc_find(device->handle, &hc_handle); 58 106 if (rc != EOK) { 59 107 return rc; 60 108 } 61 109 62 int hc_phone = devman_device_connect(hc_handle, 0); 63 if (hc_phone < 0) { 64 return hc_phone; 65 } 66 67 my_address = usb_drv_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); 68 117 if (my_address < 0) { 69 118 rc = my_address; … … 75 124 76 125 leave: 77 async_hangup( hc_phone);126 async_hangup(parent_phone); 78 127 return rc; 79 128 } -
uspace/lib/usb/src/pipesinit.c
r6bb83c7 r070f11e 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
r6bb83c7 r070f11e 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; … … 78 81 * Make call identifying target USB device and type of transfer. 79 82 */ 80 aid_t opening_request = async_send_ 3(pipe->hc_phone,83 aid_t opening_request = async_send_4(pipe->hc_phone, 81 84 DEV_IFACE_ID(USBHC_DEV_IFACE), ipc_method, 82 85 pipe->wire->address, pipe->endpoint_no, 86 pipe->max_packet_size, 83 87 NULL); 84 88 if (opening_request == 0) { … … 194 198 ipc_method = IPC_M_USBHC_INTERRUPT_OUT; 195 199 break; 200 case USB_TRANSFER_BULK: 201 ipc_method = IPC_M_USBHC_BULK_OUT; 202 break; 196 203 default: 197 204 return ENOTSUP; … … 201 208 * Make call identifying target USB device and type of transfer. 202 209 */ 203 aid_t opening_request = async_send_ 3(pipe->hc_phone,210 aid_t opening_request = async_send_4(pipe->hc_phone, 204 211 DEV_IFACE_ID(USBHC_DEV_IFACE), ipc_method, 205 212 pipe->wire->address, pipe->endpoint_no, 213 pipe->max_packet_size, 206 214 NULL); 207 215 if (opening_request == 0) { … … 283 291 * Make call identifying target USB device and control transfer type. 284 292 */ 285 aid_t opening_request = async_send_ 3(pipe->hc_phone,293 aid_t opening_request = async_send_4(pipe->hc_phone, 286 294 DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_CONTROL_READ, 287 295 pipe->wire->address, pipe->endpoint_no, 296 pipe->max_packet_size, 288 297 NULL); 289 298 if (opening_request == 0) { … … 402 411 * Make call identifying target USB device and control transfer type. 403 412 */ 404 aid_t opening_request = async_send_ 4(pipe->hc_phone,413 aid_t opening_request = async_send_5(pipe->hc_phone, 405 414 DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_CONTROL_WRITE, 406 415 pipe->wire->address, pipe->endpoint_no, 407 416 data_buffer_size, 417 pipe->max_packet_size, 408 418 NULL); 409 419 if (opening_request == 0) { -
uspace/lib/usb/src/recognise.c
r6bb83c7 r070f11e 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; -
uspace/lib/usb/src/usbdrv.c
r6bb83c7 r070f11e 34 34 */ 35 35 #include <usb/usbdrv.h> 36 #include <usbhc_iface.h>37 #include <usb_iface.h>38 36 #include <errno.h> 39 #include <str_error.h> 40 41 /** Information about pending transaction on HC. */ 42 typedef struct { 43 /** Phone to host controller driver. */ 44 int phone; 45 /** Data buffer. */ 46 void *buffer; 47 /** Buffer size. */ 48 size_t size; 49 /** Storage for actual number of bytes transferred. */ 50 size_t *size_transferred; 51 /** Initial call reply data. */ 52 ipc_call_t reply; 53 /** Initial call identifier. */ 54 aid_t request; 55 /** Reply data for data read call. */ 56 ipc_call_t read_reply; 57 /** Data read call identifier. */ 58 aid_t read_request; 59 } transfer_info_t; 37 60 38 61 39 /** Find handle of host controller the device is physically attached to. … … 67 45 int usb_drv_find_hc(device_t *dev, devman_handle_t *handle) 68 46 { 69 if (dev == NULL) { 70 return EBADMEM; 71 } 72 if (handle == NULL) { 73 return EBADMEM; 74 } 75 76 int parent_phone = devman_parent_device_connect(dev->handle, 77 IPC_FLAG_BLOCKING); 78 if (parent_phone < 0) { 79 return parent_phone; 80 } 81 82 devman_handle_t h; 83 int rc = async_req_1_1(parent_phone, DEV_IFACE_ID(USB_DEV_IFACE), 84 IPC_M_USB_GET_HOST_CONTROLLER_HANDLE, &h); 85 86 async_hangup(parent_phone); 87 88 if (rc != EOK) { 89 return rc; 90 } 91 92 *handle = h; 93 94 return EOK; 47 return ENOTSUP; 95 48 } 96 49 … … 105 58 unsigned int flags) 106 59 { 107 return devman_device_connect(hc_handle, flags);60 return ENOTSUP; 108 61 } 109 62 … … 116 69 int usb_drv_hc_connect_auto(device_t *dev, unsigned int flags) 117 70 { 118 int rc; 119 devman_handle_t hc_handle; 120 121 /* 122 * Call parent hub to obtain device handle of respective HC. 123 */ 124 rc = usb_drv_find_hc(dev, &hc_handle); 125 if (rc != EOK) { 126 return rc; 127 } 128 129 return usb_drv_hc_connect(dev, hc_handle, flags); 71 return ENOTSUP; 130 72 } 131 73 … … 138 80 usb_address_t usb_drv_get_my_address(int phone, device_t *dev) 139 81 { 140 sysarg_t address; 141 int rc = async_req_2_1(phone, DEV_IFACE_ID(USBHC_DEV_IFACE), 142 IPC_M_USBHC_GET_ADDRESS, 143 dev->handle, &address); 144 145 if (rc != EOK) { 146 return rc; 147 } 148 149 return (usb_address_t) address; 82 return ENOTSUP; 150 83 } 151 84 … … 157 90 int usb_drv_reserve_default_address(int phone) 158 91 { 159 return async_req_1_0(phone, DEV_IFACE_ID(USBHC_DEV_IFACE), 160 IPC_M_USBHC_RESERVE_DEFAULT_ADDRESS); 92 return ENOTSUP; 161 93 } 162 94 … … 168 100 int usb_drv_release_default_address(int phone) 169 101 { 170 return async_req_1_0(phone, DEV_IFACE_ID(USBHC_DEV_IFACE), 171 IPC_M_USBHC_RELEASE_DEFAULT_ADDRESS); 102 return ENOTSUP; 172 103 } 173 104 … … 179 110 usb_address_t usb_drv_request_address(int phone) 180 111 { 181 sysarg_t address; 182 int rc = async_req_1_1(phone, DEV_IFACE_ID(USBHC_DEV_IFACE), 183 IPC_M_USBHC_REQUEST_ADDRESS, &address); 184 if (rc != EOK) { 185 return rc; 186 } else { 187 return (usb_address_t) address; 188 } 112 return ENOTSUP; 189 113 } 190 114 … … 199 123 devman_handle_t handle) 200 124 { 201 int rc = async_req_3_0(phone, DEV_IFACE_ID(USBHC_DEV_IFACE), 202 IPC_M_USBHC_BIND_ADDRESS, 203 address, handle); 204 205 return rc; 125 return ENOTSUP; 206 126 } 207 127 … … 214 134 int usb_drv_release_address(int phone, usb_address_t address) 215 135 { 216 return async_req_2_0(phone, DEV_IFACE_ID(USBHC_DEV_IFACE), 217 IPC_M_USBHC_RELEASE_ADDRESS, address); 218 } 219 220 /** Send data to HCD. 221 * 222 * @param phone Phone to HC. 223 * @param method Method used for calling. 224 * @param target Targeted device. 225 * @param buffer Data buffer (NULL to skip data transfer phase). 226 * @param size Buffer size (must be zero when @p buffer is NULL). 227 * @param handle Storage for transaction handle (cannot be NULL). 228 * @return Error status. 229 * @retval EINVAL Invalid parameter. 230 * @retval ENOMEM Not enough memory to complete the operation. 231 */ 232 static int async_send_buffer(int phone, int method, 233 usb_target_t target, 234 void *buffer, size_t size, 235 usb_handle_t *handle) 236 { 237 if (phone < 0) { 238 return EINVAL; 239 } 240 241 if ((buffer == NULL) && (size > 0)) { 242 return EINVAL; 243 } 244 245 if (handle == NULL) { 246 return EINVAL; 247 } 248 249 transfer_info_t *transfer 250 = (transfer_info_t *) malloc(sizeof(transfer_info_t)); 251 if (transfer == NULL) { 252 return ENOMEM; 253 } 254 255 transfer->read_request = 0; 256 transfer->size_transferred = NULL; 257 transfer->buffer = NULL; 258 transfer->size = 0; 259 transfer->phone = phone; 260 261 int rc; 262 263 transfer->request = async_send_4(phone, 264 DEV_IFACE_ID(USBHC_DEV_IFACE), 265 method, 266 target.address, target.endpoint, 267 size, 268 &transfer->reply); 269 270 if (size > 0) { 271 rc = async_data_write_start(phone, buffer, size); 272 if (rc != EOK) { 273 async_wait_for(transfer->request, NULL); 274 return rc; 275 } 276 } 277 278 *handle = (usb_handle_t) transfer; 279 280 return EOK; 281 } 282 283 /** Prepare data retrieval. 284 * 285 * @param phone Opened phone to HCD. 286 * @param method Method used for calling. 287 * @param target Targeted device. 288 * @param buffer Buffer where to store retrieved data 289 * (NULL to skip data transfer phase). 290 * @param size Buffer size (must be zero when @p buffer is NULL). 291 * @param actual_size Storage where actual number of bytes transferred will 292 * be stored. 293 * @param handle Storage for transaction handle (cannot be NULL). 294 * @return Error status. 295 * @retval EINVAL Invalid parameter. 296 * @retval ENOMEM Not enough memory to complete the operation. 297 */ 298 static int async_recv_buffer(int phone, int method, 299 usb_target_t target, 300 void *buffer, size_t size, size_t *actual_size, 301 usb_handle_t *handle) 302 { 303 if (phone < 0) { 304 return EINVAL; 305 } 306 307 if ((buffer == NULL) && (size > 0)) { 308 return EINVAL; 309 } 310 311 if (handle == NULL) { 312 return EINVAL; 313 } 314 315 transfer_info_t *transfer 316 = (transfer_info_t *) malloc(sizeof(transfer_info_t)); 317 if (transfer == NULL) { 318 return ENOMEM; 319 } 320 321 transfer->read_request = 0; 322 transfer->size_transferred = actual_size; 323 transfer->buffer = buffer; 324 transfer->size = size; 325 transfer->phone = phone; 326 327 transfer->request = async_send_4(phone, 328 DEV_IFACE_ID(USBHC_DEV_IFACE), 329 method, 330 target.address, target.endpoint, 331 size, 332 &transfer->reply); 333 334 if (buffer != NULL) { 335 transfer->read_request = async_data_read(phone, buffer, size, 336 &transfer->read_reply); 337 } 338 339 *handle = (usb_handle_t) transfer; 340 341 return EOK; 342 } 343 136 return ENOTSUP; 137 } 344 138 345 139 /** Blocks caller until given USB transaction is finished. … … 355 149 int usb_drv_async_wait_for(usb_handle_t handle) 356 150 { 357 if (handle == 0) { 358 return EBADMEM; 359 } 360 361 int rc = EOK; 362 363 transfer_info_t *transfer = (transfer_info_t *) handle; 364 365 sysarg_t answer_rc; 366 367 /* 368 * If the buffer is not NULL, we must accept some data. 369 */ 370 if ((transfer->buffer != NULL) && (transfer->size > 0)) { 371 async_wait_for(transfer->read_request, &answer_rc); 372 373 if (answer_rc != EOK) { 374 rc = (int) answer_rc; 375 goto leave; 376 } 377 378 if (transfer->size_transferred != NULL) { 379 *(transfer->size_transferred) 380 = IPC_GET_ARG2(transfer->read_reply); 381 } 382 } 383 384 async_wait_for(transfer->request, &answer_rc); 385 386 if (answer_rc != EOK) { 387 rc = (int) answer_rc; 388 goto leave; 389 } 390 391 leave: 392 free(transfer); 393 394 return rc; 151 return ENOTSUP; 395 152 } 396 153 … … 400 157 usb_handle_t *handle) 401 158 { 402 return async_send_buffer(phone, 403 IPC_M_USBHC_INTERRUPT_OUT, 404 target, 405 buffer, size, 406 handle); 159 return ENOTSUP; 407 160 } 408 161 … … 412 165 usb_handle_t *handle) 413 166 { 414 return async_recv_buffer(phone, 415 IPC_M_USBHC_INTERRUPT_IN, 416 target, 417 buffer, size, actual_size, 418 handle); 167 return ENOTSUP; 419 168 } 420 169 … … 424 173 usb_handle_t *handle) 425 174 { 426 return async_send_buffer(phone, 427 IPC_M_USBHC_CONTROL_WRITE_SETUP, 428 target, 429 buffer, size, 430 handle); 175 return ENOTSUP; 431 176 } 432 177 … … 436 181 usb_handle_t *handle) 437 182 { 438 return async_send_buffer(phone, 439 IPC_M_USBHC_CONTROL_WRITE_DATA, 440 target, 441 buffer, size, 442 handle); 183 return ENOTSUP; 443 184 } 444 185 … … 447 188 usb_handle_t *handle) 448 189 { 449 return async_recv_buffer(phone, 450 IPC_M_USBHC_CONTROL_WRITE_STATUS, 451 target, 452 NULL, 0, NULL, 453 handle); 190 return ENOTSUP; 454 191 } 455 192 … … 460 197 usb_handle_t *handle) 461 198 { 462 // FIXME - check input parameters instead of asserting them 463 assert(phone > 0); 464 assert(setup_packet != NULL); 465 assert(setup_packet_size > 0); 466 assert(((buffer != NULL) && (buffer_size > 0)) 467 || ((buffer == NULL) && (buffer_size == 0))); 468 assert(handle != NULL); 469 470 transfer_info_t *transfer 471 = (transfer_info_t *) malloc(sizeof(transfer_info_t)); 472 if (transfer == NULL) { 473 return ENOMEM; 474 } 475 476 transfer->read_request = 0; 477 transfer->size_transferred = NULL; 478 transfer->buffer = NULL; 479 transfer->size = 0; 480 transfer->phone = phone; 481 482 int rc; 483 484 transfer->request = async_send_3(phone, 485 DEV_IFACE_ID(USBHC_DEV_IFACE), 486 IPC_M_USBHC_CONTROL_WRITE, 487 target.address, target.endpoint, 488 &transfer->reply); 489 490 rc = async_data_write_start(phone, setup_packet, setup_packet_size); 491 if (rc != EOK) { 492 async_wait_for(transfer->request, NULL); 493 return rc; 494 } 495 496 if (buffer_size > 0) { 497 rc = async_data_write_start(phone, buffer, buffer_size); 498 if (rc != EOK) { 499 async_wait_for(transfer->request, NULL); 500 return rc; 501 } 502 } 503 504 *handle = (usb_handle_t) transfer; 505 506 return EOK; 199 return ENOTSUP; 507 200 } 508 201 … … 512 205 usb_handle_t *handle) 513 206 { 514 return async_send_buffer(phone, 515 IPC_M_USBHC_CONTROL_READ_SETUP, 516 target, 517 buffer, size, 518 handle); 207 return ENOTSUP; 519 208 } 520 209 … … 524 213 usb_handle_t *handle) 525 214 { 526 return async_recv_buffer(phone, 527 IPC_M_USBHC_CONTROL_READ_DATA, 528 target, 529 buffer, size, actual_size, 530 handle); 215 return ENOTSUP; 531 216 } 532 217 … … 535 220 usb_handle_t *handle) 536 221 { 537 return async_send_buffer(phone, 538 IPC_M_USBHC_CONTROL_READ_STATUS, 539 target, 540 NULL, 0, 541 handle); 222 return ENOTSUP; 542 223 } 543 224 … … 548 229 usb_handle_t *handle) 549 230 { 550 // FIXME - check input parameters instead of asserting them 551 assert(phone > 0); 552 assert(setup_packet != NULL); 553 assert(setup_packet_size > 0); 554 assert(buffer != NULL); 555 assert(buffer_size > 0); 556 assert(handle != NULL); 557 558 transfer_info_t *transfer 559 = (transfer_info_t *) malloc(sizeof(transfer_info_t)); 560 if (transfer == NULL) { 561 return ENOMEM; 562 } 563 564 transfer->size_transferred = actual_size; 565 transfer->buffer = buffer; 566 transfer->size = buffer_size; 567 transfer->phone = phone; 568 569 int rc; 570 571 transfer->request = async_send_4(phone, 572 DEV_IFACE_ID(USBHC_DEV_IFACE), 573 IPC_M_USBHC_CONTROL_READ, 574 target.address, target.endpoint, 575 buffer_size, 576 &transfer->reply); 577 578 rc = async_data_write_start(phone, setup_packet, setup_packet_size); 579 if (rc != EOK) { 580 async_wait_for(transfer->request, NULL); 581 return rc; 582 } 583 584 transfer->read_request = async_data_read(phone, buffer, buffer_size, 585 &transfer->read_reply); 586 587 *handle = (usb_handle_t) transfer; 588 589 return EOK; 231 return ENOTSUP; 590 232 } 591 233
Note:
See TracChangeset
for help on using the changeset viewer.