Changes in / [456aea3:9e195e2c] in mainline
- Files:
-
- 64 added
- 63 deleted
- 81 edited
Legend:
- Unmodified
- Added
- Removed
-
.bzrignore
r456aea3 r9e195e2c 49 49 ./uspace/app/killall/killall 50 50 ./uspace/app/klog/klog 51 ./uspace/app/lsusb/lsusb 51 52 ./uspace/app/mkfat/mkfat 52 53 ./uspace/app/netstart/netstart -
boot/Makefile.common
r456aea3 r9e195e2c 128 128 $(USPACE_PATH)/app/killall/killall \ 129 129 $(USPACE_PATH)/app/mkfat/mkfat \ 130 $(USPACE_PATH)/app/lsusb/lsusb \ 130 131 $(USPACE_PATH)/app/sbi/sbi \ 131 132 $(USPACE_PATH)/app/redir/redir \ … … 140 141 $(USPACE_PATH)/app/stats/stats \ 141 142 $(USPACE_PATH)/app/sysinfo/sysinfo \ 142 $(USPACE_PATH)/app/tasks/tasks \143 143 $(USPACE_PATH)/app/top/top \ 144 144 $(USPACE_PATH)/app/usbinfo/usbinfo \ 145 $(USPACE_PATH)/app/virtusbkbd/vuk \146 145 $(USPACE_PATH)/app/vuhid/vuh \ 147 146 $(USPACE_PATH)/app/websrv/websrv -
uspace/Makefile
r456aea3 r9e195e2c 41 41 app/killall \ 42 42 app/klog \ 43 app/lsusb \ 43 44 app/mkfat \ 44 45 app/redir \ … … 51 52 app/top \ 52 53 app/usbinfo \ 53 app/virtusbkbd \54 54 app/vuhid \ 55 55 app/netecho \ … … 177 177 ifeq ($(UARCH),amd64) 178 178 LIBS += lib/usb 179 LIBS += lib/usbhost 180 LIBS += lib/usbdev 181 LIBS += lib/usbhid 179 182 LIBS += lib/usbvirt 180 183 endif … … 182 185 ifeq ($(UARCH),ia32) 183 186 LIBS += lib/usb 187 LIBS += lib/usbhost 188 LIBS += lib/usbdev 189 LIBS += lib/usbhid 184 190 LIBS += lib/usbvirt 185 191 endif -
uspace/Makefile.common
r456aea3 r9e195e2c 88 88 89 89 LIBUSB_PREFIX = $(LIB_PREFIX)/usb 90 LIBUSBHOST_PREFIX = $(LIB_PREFIX)/usbhost 91 LIBUSBDEV_PREFIX = $(LIB_PREFIX)/usbdev 92 LIBUSBHID_PREFIX = $(LIB_PREFIX)/usbhid 90 93 LIBUSBVIRT_PREFIX = $(LIB_PREFIX)/usbvirt 91 94 LIBDRV_PREFIX = $(LIB_PREFIX)/drv -
uspace/app/tester/Makefile
r456aea3 r9e195e2c 31 31 BINARY = tester 32 32 33 LIBS += $(LIBUSB_PREFIX)/libusb.a34 EXTRA_CFLAGS += -I$(LIBUSB_PREFIX)/include35 36 33 SOURCES = \ 37 34 tester.c \ 38 adt/usbaddrkeep.c \39 35 thread/thread1.c \ 40 36 print/print1.c \ -
uspace/app/tester/tester.c
r456aea3 r9e195e2c 64 64 #include "mm/mapping1.def" 65 65 #include "hw/serial/serial1.def" 66 #include "adt/usbaddrkeep.def"67 66 #include "hw/misc/virtchar1.def" 68 67 #include "devs/devman1.def" -
uspace/app/tester/tester.h
r456aea3 r9e195e2c 80 80 extern const char *test_mapping1(void); 81 81 extern const char *test_serial1(void); 82 extern const char *test_usbaddrkeep(void);83 82 extern const char *test_virtchar1(void); 84 83 extern const char *test_devman1(void); -
uspace/app/usbinfo/Makefile
r456aea3 r9e195e2c 30 30 BINARY = usbinfo 31 31 32 LIBS = $(LIBUSB_PREFIX)/libusb.a $(LIBDRV_PREFIX)/libdrv.a 33 EXTRA_CFLAGS = -I$(LIBUSB_PREFIX)/include -I$(LIBDRV_PREFIX)/include 32 LIBS = \ 33 $(LIBUSBDEV_PREFIX)/libusbdev.a \ 34 $(LIBUSB_PREFIX)/libusb.a \ 35 $(LIBDRV_PREFIX)/libdrv.a 36 EXTRA_CFLAGS = \ 37 -I$(LIBUSB_PREFIX)/include \ 38 -I$(LIBUSBDEV_PREFIX)/include \ 39 -I$(LIBDRV_PREFIX)/include 34 40 35 41 SOURCES = \ -
uspace/app/usbinfo/dev.c
r456aea3 r9e195e2c 40 40 #include "usbinfo.h" 41 41 42 usbinfo_device_t *prepare_device( devman_handle_t hc_handle,43 usb_address_t dev_addr)42 usbinfo_device_t *prepare_device(const char *name, 43 devman_handle_t hc_handle, usb_address_t dev_addr) 44 44 { 45 45 usbinfo_device_t *dev = malloc(sizeof(usbinfo_device_t)); … … 55 55 if (rc != EOK) { 56 56 fprintf(stderr, 57 NAME ": failed to create connection to the device: %s.\n",58 str_error(rc));57 NAME ": failed to create connection to device %s: %s.\n", 58 name, str_error(rc)); 59 59 goto leave; 60 60 } … … 64 64 if (rc != EOK) { 65 65 fprintf(stderr, 66 NAME ": failed to create default control pipe : %s.\n",67 str_error(rc));66 NAME ": failed to create default control pipe to %s: %s.\n", 67 name, str_error(rc)); 68 68 goto leave; 69 69 } … … 71 71 rc = usb_pipe_probe_default_control(&dev->ctrl_pipe); 72 72 if (rc != EOK) { 73 fprintf(stderr, 74 NAME ": probing default control pipe failed: %s.\n", 75 str_error(rc)); 73 if (rc == ENOENT) { 74 fprintf(stderr, NAME ": " \ 75 "device %s not present or malfunctioning.\n", 76 name); 77 } else { 78 fprintf(stderr, NAME ": " \ 79 "probing default control pipe of %s failed: %s.\n", 80 name, str_error(rc)); 81 } 76 82 goto leave; 77 83 } … … 84 90 if (rc != EOK) { 85 91 fprintf(stderr, 86 NAME ": failed to retrieve device descriptor : %s.\n",87 str_error(rc));92 NAME ": failed to retrieve device descriptor of %s: %s.\n", 93 name, str_error(rc)); 88 94 goto leave; 89 95 } … … 93 99 &dev->full_configuration_descriptor_size); 94 100 if (rc != EOK) { 95 fprintf(stderr, 96 NAME ": failed to retrieve configuration descriptor: %s.\n",97 str_error(rc));101 fprintf(stderr, NAME ": " \ 102 "failed to retrieve configuration descriptor of %s: %s.\n", 103 name, str_error(rc)); 98 104 goto leave; 99 105 } -
uspace/app/usbinfo/info.c
r456aea3 r9e195e2c 41 41 #include <usb/request.h> 42 42 #include <usb/classes/classes.h> 43 #include <usb/classes/hid.h>44 43 #include <usb/classes/hub.h> 45 44 #include "usbinfo.h" -
uspace/app/usbinfo/main.c
r456aea3 r9e195e2c 45 45 #include <usb/usbdevice.h> 46 46 #include <usb/pipes.h> 47 #include <usb/host.h> 48 #include <usb/driver.h> 47 49 #include "usbinfo.h" 50 51 static bool try_parse_class_and_address(const char *path, 52 devman_handle_t *out_hc_handle, usb_address_t *out_device_address) 53 { 54 size_t class_index; 55 size_t address; 56 int rc; 57 char *ptr; 58 59 rc = str_size_t(path, &ptr, 10, false, &class_index); 60 if (rc != EOK) { 61 return false; 62 } 63 if ((*ptr == ':') || (*ptr == '.')) { 64 ptr++; 65 } else { 66 return false; 67 } 68 rc = str_size_t(ptr, NULL, 10, true, &address); 69 if (rc != EOK) { 70 return false; 71 } 72 rc = usb_ddf_get_hc_handle_by_class(class_index, out_hc_handle); 73 if (rc != EOK) { 74 return false; 75 } 76 if (out_device_address != NULL) { 77 *out_device_address = (usb_address_t) address; 78 } 79 return true; 80 } 48 81 49 82 static bool resolve_hc_handle_and_dev_addr(const char *devpath, … … 60 93 if (str_cmp(devpath, "virt") == 0) { 61 94 devpath = "/virt/usbhc/usb00_a1/usb00_a2"; 95 } 96 97 if (try_parse_class_and_address(devpath, 98 out_hc_handle, out_device_address)) { 99 return true; 62 100 } 63 101 … … 271 309 } 272 310 273 usbinfo_device_t *dev = prepare_device(hc_handle, dev_addr); 311 usbinfo_device_t *dev = prepare_device(devpath, 312 hc_handle, dev_addr); 274 313 if (dev == NULL) { 275 314 continue; -
uspace/app/usbinfo/usbinfo.h
r456aea3 r9e195e2c 71 71 } 72 72 73 usbinfo_device_t *prepare_device( devman_handle_t, usb_address_t);73 usbinfo_device_t *prepare_device(const char *, devman_handle_t, usb_address_t); 74 74 void destroy_device(usbinfo_device_t *); 75 75 -
uspace/app/vuhid/Makefile
r456aea3 r9e195e2c 34 34 LIBS = \ 35 35 $(LIBUSBVIRT_PREFIX)/libusbvirt.a \ 36 $(LIBUSBHID_PREFIX)/libusbhid.a \ 37 $(LIBUSBDEV_PREFIX)/libusbdev.a \ 36 38 $(LIBUSB_PREFIX)/libusb.a 37 39 EXTRA_CFLAGS = \ 38 40 -I$(LIBUSB_PREFIX)/include \ 41 -I$(LIBUSBDEV_PREFIX)/include \ 42 -I$(LIBUSBHID_PREFIX)/include \ 39 43 -I$(LIBUSBVIRT_PREFIX)/include \ 40 44 -I$(LIBDRV_PREFIX)/include -
uspace/app/vuhid/device.c
r456aea3 r9e195e2c 77 77 { 78 78 vuhid_interface_t *iface = arg; 79 vuhid_data_t *hid_data = iface->vuhid_data; 79 80 80 81 if (iface->live != NULL) { 81 82 iface->live(iface); 82 83 } 84 85 fibril_mutex_lock(&hid_data->iface_count_mutex); 86 hid_data->iface_died_count++; 87 fibril_condvar_broadcast(&hid_data->iface_count_cv); 88 fibril_mutex_unlock(&hid_data->iface_count_mutex); 83 89 84 90 return EOK; … … 110 116 if ((iface->in_data_size == 0) && (iface->out_data_size == 0)) { 111 117 return EEMPTY; 118 } 119 120 // FIXME - we shall set vuhid_data to NULL in the main() rather 121 // than to depend on individual interfaces 122 /* Already used interface. */ 123 if (iface->vuhid_data != NULL) { 124 return EEXISTS; 112 125 } 113 126 … … 252 265 253 266 /* Launch the "life" fibril. */ 267 iface->vuhid_data = hid_data; 254 268 fid_t life_fibril = fibril_create(interface_life_fibril, iface); 255 269 if (life_fibril == 0) { … … 310 324 += total_descr_size; 311 325 326 hid_data->iface_count++; 312 327 fibril_add_ready(life_fibril); 313 328 … … 331 346 } 332 347 348 void wait_for_interfaces_death(usbvirt_device_t *dev) 349 { 350 vuhid_data_t *hid_data = dev->device_data; 351 352 fibril_mutex_lock(&hid_data->iface_count_mutex); 353 while (hid_data->iface_died_count < hid_data->iface_count) { 354 fibril_condvar_wait(&hid_data->iface_count_cv, 355 &hid_data->iface_count_mutex); 356 } 357 fibril_mutex_unlock(&hid_data->iface_count_mutex); 358 } 333 359 334 360 /** @} -
uspace/app/vuhid/hids/bootkbd.c
r456aea3 r9e195e2c 39 39 #include <usb/classes/hidut.h> 40 40 41 #include "../ ../virtusbkbd/report.h"41 #include "../report.h" 42 42 43 43 uint8_t report_descriptor[] = { … … 169 169 .on_data_out = on_data_out, 170 170 171 .live = live 171 .live = live, 172 173 .vuhid_data = NULL 172 174 }; 173 175 -
uspace/app/vuhid/main.c
r456aea3 r9e195e2c 132 132 .in_endpoint_first_free = 1, 133 133 .out_endpoints_mapping = { NULL }, 134 .out_endpoint_first_free = 1 135 }; 134 .out_endpoint_first_free = 1, 135 136 .iface_count = 0, 137 .iface_died_count = 0 138 // mutex and CV must be initialized elsewhere 139 }; 140 136 141 137 142 /** Keyboard device. … … 151 156 152 157 usb_log_enable(USB_LOG_LEVEL_DEBUG2, "vusbhid"); 158 159 fibril_mutex_initialize(&vuhid_data.iface_count_mutex); 160 fibril_condvar_initialize(&vuhid_data.iface_count_cv); 153 161 154 162 /* Determine which interfaces to initialize. */ … … 182 190 printf("Connected to VHCD...\n"); 183 191 184 while (true) { 185 async_usleep(10 * 1000 * 1000); 186 } 192 wait_for_interfaces_death(&hid_dev); 187 193 188 194 printf("Terminating...\n"); 189 195 196 usbvirt_device_unplug(&hid_dev); 197 190 198 return 0; 191 199 } -
uspace/app/vuhid/virthid.h
r456aea3 r9e195e2c 38 38 #include <usb/usb.h> 39 39 #include <usbvirt/device.h> 40 #include <fibril_synch.h> 40 41 41 42 #define VUHID_ENDPOINT_MAX USB11_ENDPOINT_MAX … … 43 44 44 45 typedef struct vuhid_interface vuhid_interface_t; 46 47 typedef struct { 48 vuhid_interface_t *in_endpoints_mapping[VUHID_ENDPOINT_MAX]; 49 size_t in_endpoint_first_free; 50 vuhid_interface_t *out_endpoints_mapping[VUHID_ENDPOINT_MAX]; 51 size_t out_endpoint_first_free; 52 vuhid_interface_t *interface_mapping[VUHID_INTERFACE_MAX]; 53 54 fibril_mutex_t iface_count_mutex; 55 fibril_condvar_t iface_count_cv; 56 size_t iface_count; 57 size_t iface_died_count; 58 } vuhid_data_t; 45 59 46 60 struct vuhid_interface { … … 63 77 64 78 void *interface_data; 79 80 vuhid_data_t *vuhid_data; 65 81 }; 66 67 typedef struct {68 vuhid_interface_t *in_endpoints_mapping[VUHID_ENDPOINT_MAX];69 size_t in_endpoint_first_free;70 vuhid_interface_t *out_endpoints_mapping[VUHID_ENDPOINT_MAX];71 size_t out_endpoint_first_free;72 vuhid_interface_t *interface_mapping[VUHID_INTERFACE_MAX];73 } vuhid_data_t;74 82 75 83 typedef struct { … … 84 92 85 93 int add_interface_by_id(vuhid_interface_t **, const char *, usbvirt_device_t *); 94 void wait_for_interfaces_death(usbvirt_device_t *); 86 95 87 96 #endif -
uspace/doc/doxygroups.h
r456aea3 r9e195e2c 220 220 221 221 /** 222 * @defgroup lsusb HelenOS version of lsusb command 223 * @ingroup usb 224 * @brief Application for listing USB host controllers. 225 * @details 226 * List all found host controllers. 227 */ 228 229 /** 222 230 * @defgroup drvusbmid USB multi interface device driver 223 231 * @ingroup usb -
uspace/drv/ehci-hcd/Makefile
r456aea3 r9e195e2c 28 28 29 29 USPACE_PREFIX = ../.. 30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a 31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include -I. 30 31 LIBS = \ 32 $(LIBUSBHOST_PREFIX)/libusbhost.a \ 33 $(LIBUSB_PREFIX)/libusb.a \ 34 $(LIBDRV_PREFIX)/libdrv.a 35 EXTRA_CFLAGS += \ 36 -I$(LIBUSB_PREFIX)/include \ 37 -I$(LIBUSBHOST_PREFIX)/include \ 38 -I$(LIBDRV_PREFIX)/include 39 32 40 BINARY = ehci-hcd 33 41 -
uspace/drv/ehci-hcd/hc_iface.c
r456aea3 r9e195e2c 106 106 } 107 107 108 /** Find device handle by USB address. 109 * 110 * @param[in] fun DDF function that was called. 111 * @param[in] address Address in question. 112 * @param[out] handle Where to store device handle if found. 113 * @return Error code. 114 */ 115 static int find_by_address(ddf_fun_t *fun, usb_address_t address, 116 devman_handle_t *handle) 117 { 118 UNSUPPORTED("find_by_address"); 119 120 return ENOTSUP; 121 } 122 108 123 /** Release previously requested address. 109 124 * … … 321 336 .request_address = request_address, 322 337 .bind_address = bind_address, 338 .find_by_address = find_by_address, 323 339 .release_address = release_address, 324 340 -
uspace/drv/ehci-hcd/main.c
r456aea3 r9e195e2c 97 97 } 98 98 hc_fun->ops = &hc_ops; 99 99 100 ret = ddf_fun_bind(hc_fun); 100 101 101 CHECK_RET_RETURN(ret, 102 102 "Failed to bind EHCI function: %s.\n", 103 str_error(ret)); 104 ret = ddf_fun_add_to_class(hc_fun, USB_HC_DDF_CLASS_NAME); 105 CHECK_RET_RETURN(ret, 106 "Failed to add EHCI to HC class: %s.\n", 103 107 str_error(ret)); 104 108 -
uspace/drv/ehci-hcd/pci.c
r456aea3 r9e195e2c 54 54 55 55 #define CMD_OFFSET 0x0 56 #define CONFIGFLAG_OFFSET 0x40 56 #define STS_OFFSET 0x4 57 #define CFG_OFFSET 0x40 57 58 58 59 #define USBCMD_RUN 1 … … 264 265 * It would prevent pre-OS code from interfering. */ 265 266 ret = async_req_3_0(parent_phone, DEV_IFACE_ID(PCI_DEV_IFACE), 266 IPC_M_CONFIG_SPACE_WRITE_32, eecp + USBLEGCTLSTS_OFFSET, 0); 267 IPC_M_CONFIG_SPACE_WRITE_32, eecp + USBLEGCTLSTS_OFFSET, 268 0xe0000000); 267 269 CHECK_RET_HANGUP_RETURN(ret, "Failed(%d) zero USBLEGCTLSTS.\n", ret); 268 usb_log_debug("Zeroed USBLEGCTLSTS register.\n");269 270 270 271 /* Read again Legacy Support and Control register */ … … 291 292 volatile uint32_t *usbcmd = 292 293 (uint32_t*)((uint8_t*)registers + operation_offset + CMD_OFFSET); 294 volatile uint32_t *usbsts = 295 (uint32_t*)((uint8_t*)registers + operation_offset + STS_OFFSET); 293 296 volatile uint32_t *usbconfigured = 294 (uint32_t*)((uint8_t*)registers + operation_offset 295 + CONFIGFLAG_OFFSET); 297 (uint32_t*)((uint8_t*)registers + operation_offset + CFG_OFFSET); 296 298 usb_log_debug("USBCMD value: %x.\n", *usbcmd); 297 299 if (*usbcmd & USBCMD_RUN) { 298 300 *usbcmd = 0; 301 while (!(*usbsts & (1 << 12))); /*wait until hc is halted */ 299 302 *usbconfigured = 0; 300 303 usb_log_info("EHCI turned off.\n"); … … 302 305 usb_log_info("EHCI was not running.\n"); 303 306 } 307 usb_log_debug("Registers: %x(0x00080000):%x(0x00001000):%x(0x0).\n", 308 *usbcmd, *usbsts, *usbconfigured); 304 309 305 310 async_hangup(parent_phone); -
uspace/drv/ohci/Makefile
r456aea3 r9e195e2c 28 28 29 29 USPACE_PREFIX = ../.. 30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a 31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include -I. 30 31 LIBS = \ 32 $(LIBUSBHOST_PREFIX)/libusbhost.a \ 33 $(LIBUSBDEV_PREFIX)/libusbdev.a \ 34 $(LIBUSB_PREFIX)/libusb.a \ 35 $(LIBDRV_PREFIX)/libdrv.a 36 EXTRA_CFLAGS += \ 37 -I$(LIBUSB_PREFIX)/include \ 38 -I$(LIBUSBDEV_PREFIX)/include \ 39 -I$(LIBUSBHOST_PREFIX)/include \ 40 -I$(LIBDRV_PREFIX)/include 41 32 42 BINARY = ohci 33 43 -
uspace/drv/ohci/hc.c
r456aea3 r9e195e2c 40 40 #include <usb/usb.h> 41 41 #include <usb/ddfiface.h> 42 #include <usb/usbdevice.h>43 42 44 43 #include "hc.h" … … 49 48 static int interrupt_emulator(hc_t *instance); 50 49 static void hc_gain_control(hc_t *instance); 51 static void hc_init_hw(hc_t *instance);52 50 static int hc_init_transfer_lists(hc_t *instance); 53 51 static int hc_init_memory(hc_t *instance); … … 92 90 usb_log_error("Failed add root hub match-id.\n"); 93 91 } 92 ret = ddf_fun_bind(hub_fun); 94 93 return ret; 95 94 } 96 95 /*----------------------------------------------------------------------------*/ 97 int hc_init(hc_t *instance, ddf_fun_t *fun, ddf_dev_t *dev, 98 uintptr_t regs, size_t reg_size, bool interrupts) 96 int hc_init(hc_t *instance, uintptr_t regs, size_t reg_size, bool interrupts) 99 97 { 100 98 assert(instance); … … 111 109 ret, str_error(ret)); 112 110 111 list_initialize(&instance->pending_batches); 113 112 usb_device_keeper_init(&instance->manager); 114 113 ret = usb_endpoint_manager_init(&instance->ep_manager, … … 117 116 str_error(ret)); 118 117 119 hc_gain_control(instance);120 118 ret = hc_init_memory(instance); 121 119 CHECK_RET_RETURN(ret, "Failed to create OHCI memory structures: %s.\n", 122 120 str_error(ret)); 123 hc_init_hw(instance); 121 #undef CHECK_RET_RETURN 122 123 124 // hc_init_hw(instance); 125 hc_gain_control(instance); 124 126 fibril_mutex_initialize(&instance->guard); 125 127 … … 132 134 } 133 135 134 list_initialize(&instance->pending_batches);135 #undef CHECK_RET_RETURN136 136 return EOK; 137 137 } … … 287 287 { 288 288 assert(instance); 289 usb_log_debug("OHCI interrupt: %x.\n", status);289 usb_log_debug("OHCI(%p) interrupt: %x.\n", instance, status); 290 290 if ((status & ~I_SF) == 0) /* ignore sof status */ 291 291 return; … … 339 339 (uint32_t*)((char*)instance->registers + 0x100); 340 340 usb_log_debug("OHCI legacy register %p: %x.\n", 341 ohci_emulation_reg, *ohci_emulation_reg); 342 *ohci_emulation_reg &= ~0x1; 341 ohci_emulation_reg, *ohci_emulation_reg); 342 /* Do not change A20 state */ 343 *ohci_emulation_reg &= 0x100; 344 usb_log_debug("OHCI legacy register %p: %x.\n", 345 ohci_emulation_reg, *ohci_emulation_reg); 343 346 344 347 /* Interrupt routing enabled => smm driver is active */ … … 350 353 } 351 354 usb_log_info("SMM driver: Ownership taken.\n"); 355 instance->registers->control &= (C_HCFS_RESET << C_HCFS_SHIFT); 356 async_usleep(50000); 352 357 return; 353 358 } … … 375 380 } 376 381 /*----------------------------------------------------------------------------*/ 377 void hc_ init_hw(hc_t *instance)382 void hc_start_hw(hc_t *instance) 378 383 { 379 384 /* OHCI guide page 42 */ … … 474 479 { 475 480 assert(instance); 481 482 bzero(&instance->rh, sizeof(instance->rh)); 476 483 /* Init queues */ 477 484 hc_init_transfer_lists(instance); -
uspace/drv/ohci/hc.h
r456aea3 r9e195e2c 77 77 int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun); 78 78 79 int hc_init(hc_t *instance, ddf_fun_t *fun, ddf_dev_t *dev, 80 uintptr_t regs, size_t reg_size, bool interrupts); 79 int hc_init(hc_t *instance, uintptr_t regs, size_t reg_size, bool interrupts); 80 81 void hc_start_hw(hc_t *instance); 81 82 82 83 /** Safely dispose host controller internal structures -
uspace/drv/ohci/hw_struct/endpoint_descriptor.h
r456aea3 r9e195e2c 40 40 #include <usb/host/endpoint.h> 41 41 42 #include " utils/malloc32.h"42 #include "../utils/malloc32.h" 43 43 #include "transfer_descriptor.h" 44 44 -
uspace/drv/ohci/hw_struct/transfer_descriptor.c
r456aea3 r9e195e2c 33 33 */ 34 34 #include <usb/usb.h> 35 #include "utils/malloc32.h"36 37 35 #include "transfer_descriptor.h" 38 36 -
uspace/drv/ohci/hw_struct/transfer_descriptor.h
r456aea3 r9e195e2c 37 37 #include <bool.h> 38 38 #include <stdint.h> 39 #include " utils/malloc32.h"39 #include "../utils/malloc32.h" 40 40 41 41 #include "completion_codes.h" -
uspace/drv/ohci/iface.c
r456aea3 r9e195e2c 122 122 return EOK; 123 123 } 124 125 126 /** Find device handle by address interface function. 127 * 128 * @param[in] fun DDF function that was called. 129 * @param[in] address Address in question. 130 * @param[out] handle Where to store device handle if found. 131 * @return Error code. 132 */ 133 static int find_by_address(ddf_fun_t *fun, usb_address_t address, 134 devman_handle_t *handle) 135 { 136 assert(fun); 137 hc_t *hc = fun_to_hc(fun); 138 assert(hc); 139 bool found = 140 usb_device_keeper_find_by_address(&hc->manager, address, handle); 141 return found ? EOK : ENOENT; 142 } 143 124 144 /*----------------------------------------------------------------------------*/ 125 145 /** Release address interface function … … 402 422 .request_address = request_address, 403 423 .bind_address = bind_address, 424 .find_by_address = find_by_address, 404 425 .release_address = release_address, 405 426 -
uspace/drv/ohci/main.c
r456aea3 r9e195e2c 43 43 #define NAME "ohci" 44 44 45 static int ohci_add_device(ddf_dev_t *device); 45 /** Initializes a new ddf driver instance of OHCI hcd. 46 * 47 * @param[in] device DDF instance of the device to initialize. 48 * @return Error code. 49 */ 50 static int ohci_add_device(ddf_dev_t *device) 51 { 52 usb_log_debug("ohci_add_device() called\n"); 53 assert(device); 54 55 int ret = device_setup_ohci(device); 56 if (ret != EOK) { 57 usb_log_error("Failed to initialize OHCI driver: %s.\n", 58 str_error(ret)); 59 return ret; 60 } 61 usb_log_info("Controlling new OHCI device '%s'.\n", device->name); 62 63 return EOK; 64 } 46 65 /*----------------------------------------------------------------------------*/ 47 66 static driver_ops_t ohci_driver_ops = { … … 53 72 .driver_ops = &ohci_driver_ops 54 73 }; 55 /*----------------------------------------------------------------------------*/56 /** Initializes a new ddf driver instance of OHCI hcd.57 *58 * @param[in] device DDF instance of the device to initialize.59 * @return Error code.60 */61 int ohci_add_device(ddf_dev_t *device)62 {63 usb_log_debug("ohci_add_device() called\n");64 assert(device);65 ohci_t *ohci = malloc(sizeof(ohci_t));66 if (ohci == NULL) {67 usb_log_error("Failed to allocate OHCI driver.\n");68 return ENOMEM;69 }70 71 int ret = ohci_init(ohci, device);72 if (ret != EOK) {73 usb_log_error("Failed to initialize OHCI driver: %s.\n",74 str_error(ret));75 return ret;76 }77 device->driver_data = ohci;78 79 usb_log_info("Controlling new OHCI device `%s'.\n", device->name);80 81 return EOK;82 }83 74 /*----------------------------------------------------------------------------*/ 84 75 /** Initializes global driver structures (NONE). … … 93 84 { 94 85 usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME); 95 sleep(5);96 86 return ddf_driver_main(&ohci_driver); 97 87 } -
uspace/drv/ohci/ohci.c
r456aea3 r9e195e2c 44 44 #include "iface.h" 45 45 #include "pci.h" 46 #include "hc.h" 47 #include "root_hub.h" 48 49 typedef struct ohci { 50 ddf_fun_t *hc_fun; 51 ddf_fun_t *rh_fun; 52 53 hc_t hc; 54 rh_t rh; 55 } ohci_t; 56 57 static inline ohci_t * dev_to_ohci(ddf_dev_t *dev) 58 { 59 assert(dev); 60 assert(dev->driver_data); 61 return dev->driver_data; 62 } 46 63 47 64 /** IRQ handling callback, identifies device … … 53 70 static void irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call) 54 71 { 55 assert(dev); 56 hc_t *hc = &((ohci_t*)dev->driver_data)->hc; 57 uint16_t status = IPC_GET_ARG1(*call); 72 hc_t *hc = &dev_to_ohci(dev)->hc; 58 73 assert(hc); 74 const uint16_t status = IPC_GET_ARG1(*call); 59 75 hc_interrupt(hc, status); 60 76 } … … 70 86 { 71 87 assert(fun); 72 usb_device_keeper_t *manager = & ((ohci_t*)fun->dev->driver_data)->hc.manager;88 usb_device_keeper_t *manager = &dev_to_ohci(fun->dev)->hc.manager; 73 89 74 90 usb_address_t addr = usb_device_keeper_find(manager, handle); … … 93 109 ddf_fun_t *fun, devman_handle_t *handle) 94 110 { 95 assert(handle); 96 ddf_fun_t *hc_fun = ((ohci_t*)fun->dev->driver_data)->hc_fun; 97 assert(hc_fun != NULL); 98 99 *handle = hc_fun->handle; 111 assert(fun); 112 ddf_fun_t *hc_fun = dev_to_ohci(fun->dev)->hc_fun; 113 assert(hc_fun); 114 115 if (handle != NULL) 116 *handle = hc_fun->handle; 100 117 return EOK; 101 118 } 102 119 /*----------------------------------------------------------------------------*/ 103 /** This iface is generic for both RH and HC.*/120 /** Root hub USB interface */ 104 121 static usb_iface_t usb_iface = { 105 122 .get_hc_handle = usb_iface_get_hc_handle, … … 107 124 }; 108 125 /*----------------------------------------------------------------------------*/ 126 /** Standard USB HC options (HC interface) */ 109 127 static ddf_dev_ops_t hc_ops = { 110 128 .interfaces[USBHC_DEV_IFACE] = &hc_iface, /* see iface.h/c */ 111 129 }; 112 130 /*----------------------------------------------------------------------------*/ 131 /** Standard USB RH options (RH interface) */ 113 132 static ddf_dev_ops_t rh_ops = { 114 133 .interfaces[USB_DEV_IFACE] = &usb_iface, … … 117 136 /** Initialize hc and rh ddf structures and their respective drivers. 118 137 * 138 * @param[in] device DDF instance of the device to use. 119 139 * @param[in] instance OHCI structure to use. 120 * @param[in] device DDF instance of the device to use.121 140 * 122 141 * This function does all the preparatory work for hc and rh drivers: … … 126 145 * - registers interrupt handler 127 146 */ 128 int ohci_init(ohci_t *instance, ddf_dev_t *device) 129 { 130 assert(instance); 131 instance->hc_fun = NULL; 147 int device_setup_ohci(ddf_dev_t *device) 148 { 149 ohci_t *instance = malloc(sizeof(ohci_t)); 150 if (instance == NULL) { 151 usb_log_error("Failed to allocate OHCI driver.\n"); 152 return ENOMEM; 153 } 154 155 #define CHECK_RET_DEST_FREE_RETURN(ret, message...) \ 156 if (ret != EOK) { \ 157 if (instance->hc_fun) { \ 158 instance->hc_fun->ops = NULL; \ 159 instance->hc_fun->driver_data = NULL; \ 160 ddf_fun_destroy(instance->hc_fun); \ 161 } \ 162 if (instance->rh_fun) { \ 163 instance->rh_fun->ops = NULL; \ 164 instance->rh_fun->driver_data = NULL; \ 165 ddf_fun_destroy(instance->rh_fun); \ 166 } \ 167 free(instance); \ 168 usb_log_error(message); \ 169 return ret; \ 170 } else (void)0 171 132 172 instance->rh_fun = NULL; 133 #define CHECK_RET_DEST_FUN_RETURN(ret, message...) \ 134 if (ret != EOK) { \ 135 usb_log_error(message); \ 136 if (instance->hc_fun) \ 137 ddf_fun_destroy(instance->hc_fun); \ 138 if (instance->rh_fun) \ 139 ddf_fun_destroy(instance->rh_fun); \ 140 return ret; \ 141 } 142 143 uintptr_t mem_reg_base = 0; 144 size_t mem_reg_size = 0; 173 instance->hc_fun = ddf_fun_create(device, fun_exposed, "ohci-hc"); 174 int ret = instance->hc_fun ? EOK : ENOMEM; 175 CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create OHCI HC function.\n"); 176 instance->hc_fun->ops = &hc_ops; 177 instance->hc_fun->driver_data = &instance->hc; 178 179 instance->rh_fun = ddf_fun_create(device, fun_inner, "ohci-rh"); 180 ret = instance->rh_fun ? EOK : ENOMEM; 181 CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create OHCI RH function.\n"); 182 instance->rh_fun->ops = &rh_ops; 183 184 uintptr_t reg_base = 0; 185 size_t reg_size = 0; 145 186 int irq = 0; 146 187 147 int ret = 148 pci_get_my_registers(device, &mem_reg_base, &mem_reg_size, &irq); 149 CHECK_RET_DEST_FUN_RETURN(ret, 188 ret = pci_get_my_registers(device, ®_base, ®_size, &irq); 189 CHECK_RET_DEST_FREE_RETURN(ret, 150 190 "Failed to get memory addresses for %" PRIun ": %s.\n", 151 191 device->handle, str_error(ret)); 152 192 usb_log_debug("Memory mapped regs at %p (size %zu), IRQ %d.\n", 153 (void *) mem_reg_base, mem_reg_size, irq); 154 155 ret = pci_disable_legacy(device); 156 CHECK_RET_DEST_FUN_RETURN(ret, 157 "Failed(%d) to disable legacy USB: %s.\n", ret, str_error(ret)); 193 (void *) reg_base, reg_size, irq); 158 194 159 195 bool interrupts = false; 160 196 #ifdef CONFIG_USBHC_NO_INTERRUPTS 161 usb_log_warning("Interrupts disabled in OS config, " \197 usb_log_warning("Interrupts disabled in OS config, " 162 198 "falling back to polling.\n"); 163 199 #else … … 166 202 usb_log_warning("Failed to enable interrupts: %s.\n", 167 203 str_error(ret)); 168 usb_log_info("HW interrupts not available, " \204 usb_log_info("HW interrupts not available, " 169 205 "falling back to polling.\n"); 170 206 } else { … … 174 210 #endif 175 211 176 instance->hc_fun = ddf_fun_create(device, fun_exposed, "ohci-hc"); 177 ret = (instance->hc_fun == NULL) ? ENOMEM : EOK; 178 CHECK_RET_DEST_FUN_RETURN(ret, 179 "Failed(%d) to create HC function.\n", ret); 180 181 ret = hc_init(&instance->hc, instance->hc_fun, device, 182 mem_reg_base, mem_reg_size, interrupts); 183 CHECK_RET_DEST_FUN_RETURN(ret, "Failed(%d) to init ohci-hcd.\n", ret); 184 instance->hc_fun->ops = &hc_ops; 185 instance->hc_fun->driver_data = &instance->hc; 186 ret = ddf_fun_bind(instance->hc_fun); 187 CHECK_RET_DEST_FUN_RETURN(ret, 188 "Failed(%d) to bind OHCI device function: %s.\n", 189 ret, str_error(ret)); 190 #undef CHECK_RET_HC_RETURN 212 ret = hc_init(&instance->hc, reg_base, reg_size, interrupts); 213 CHECK_RET_DEST_FREE_RETURN(ret, "Failed(%d) to init ohci-hcd.\n", ret); 191 214 192 215 #define CHECK_RET_FINI_RETURN(ret, message...) \ 193 216 if (ret != EOK) { \ 194 usb_log_error(message); \195 if (instance->hc_fun) \196 ddf_fun_destroy(instance->hc_fun); \197 if (instance->rh_fun) \198 ddf_fun_destroy(instance->rh_fun); \199 217 hc_fini(&instance->hc); \ 200 return ret; \201 } 218 CHECK_RET_DEST_FREE_RETURN(ret, message); \ 219 } else (void)0 202 220 203 221 /* It does no harm if we register this on polling */ … … 207 225 "Failed(%d) to register interrupt handler.\n", ret); 208 226 209 instance->rh_fun = ddf_fun_create(device, fun_inner, "ohci-rh"); 210 ret = (instance->rh_fun == NULL) ? ENOMEM : EOK; 227 ret = ddf_fun_bind(instance->hc_fun); 211 228 CHECK_RET_FINI_RETURN(ret, 212 "Failed(%d) to create root hub function.\n", ret); 213 229 "Failed(%d) to bind OHCI device function: %s.\n", 230 ret, str_error(ret)); 231 232 ret = ddf_fun_add_to_class(instance->hc_fun, USB_HC_DDF_CLASS_NAME); 233 CHECK_RET_FINI_RETURN(ret, 234 "Failed to add OHCI to HC class: %s.\n", str_error(ret)); 235 236 device->driver_data = instance; 237 238 hc_start_hw(&instance->hc); 214 239 hc_register_hub(&instance->hc, instance->rh_fun); 215 216 instance->rh_fun->ops = &rh_ops;217 instance->rh_fun->driver_data = NULL;218 ret = ddf_fun_bind(instance->rh_fun);219 CHECK_RET_FINI_RETURN(ret,220 "Failed(%d) to register OHCI root hub.\n", ret);221 222 240 return EOK; 241 242 #undef CHECK_RET_DEST_FUN_RETURN 223 243 #undef CHECK_RET_FINI_RETURN 224 244 } -
uspace/drv/ohci/ohci.h
r456aea3 r9e195e2c 38 38 #include <ddf/driver.h> 39 39 40 #include "hc.h" 41 #include "root_hub.h" 42 43 typedef struct ohci { 44 ddf_fun_t *hc_fun; 45 ddf_fun_t *rh_fun; 46 47 hc_t hc; 48 rh_t rh; 49 } ohci_t; 50 51 int ohci_init(ohci_t *instance, ddf_dev_t *device); 40 int device_setup_ohci(ddf_dev_t *device); 52 41 53 42 #endif -
uspace/drv/ohci/pci.c
r456aea3 r9e195e2c 58 58 uintptr_t *mem_reg_address, size_t *mem_reg_size, int *irq_no) 59 59 { 60 assert(dev != NULL); 60 assert(dev); 61 assert(mem_reg_address); 62 assert(mem_reg_size); 63 assert(irq_no); 61 64 62 65 int parent_phone = devman_parent_device_connect(dev->handle, … … 136 139 return enabled ? EOK : EIO; 137 140 } 138 /*----------------------------------------------------------------------------*/139 /** Implements BIOS handoff routine as decribed in OHCI spec140 *141 * @param[in] device Device asking for interrupts142 * @return Error code.143 */144 int pci_disable_legacy(ddf_dev_t *device)145 {146 /* TODO: implement */147 return EOK;148 }149 /*----------------------------------------------------------------------------*/150 141 /** 151 142 * @} -
uspace/drv/ohci/root_hub.c
r456aea3 r9e195e2c 45 45 46 46 /** 47 * 47 * standart device descriptor for ohci root hub 48 48 */ 49 49 static const usb_standard_device_descriptor_t ohci_rh_device_descriptor = { … … 69 69 */ 70 70 static const usb_standard_configuration_descriptor_t ohci_rh_conf_descriptor = { 71 /// \TODO some values are default or guessed72 71 .attributes = 1 << 7, 73 72 .configuration_number = 1, … … 87 86 .endpoint_count = 1, 88 87 .interface_class = USB_CLASS_HUB, 89 /// \TODO is this correct?90 88 .interface_number = 1, 91 89 .interface_protocol = 0, … … 107 105 }; 108 106 107 /** 108 * bitmask of hub features that are valid to be cleared 109 */ 109 110 static const uint32_t hub_clear_feature_valid_mask = 110 111 (1 << USB_HUB_FEATURE_C_HUB_LOCAL_POWER) | 111 112 (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT); 112 113 114 /** 115 * bitmask of hub features that are cleared by writing 1 (and not 0) 116 */ 113 117 static const uint32_t hub_clear_feature_by_writing_one_mask = 114 1 << USB_HUB_FEATURE_C_HUB_LOCAL_POWER; 115 118 1 << USB_HUB_FEATURE_C_HUB_LOCAL_POWER; 119 120 /** 121 * bitmask of hub features that are valid to be set 122 */ 116 123 static const uint32_t hub_set_feature_valid_mask = 117 124 (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT) | 118 125 (1 << USB_HUB_FEATURE_C_HUB_LOCAL_POWER); 119 126 120 127 /** 128 * bitmask of hub features that are set by writing 1 and cleared by writing 0 129 */ 121 130 static const uint32_t hub_set_feature_direct_mask = 122 (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT); 123 131 (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT); 132 133 /** 134 * bitmask of port features that are valid to be set 135 */ 124 136 static const uint32_t port_set_feature_valid_mask = 125 137 (1 << USB_HUB_FEATURE_PORT_ENABLE) | 126 138 (1 << USB_HUB_FEATURE_PORT_SUSPEND) | 127 139 (1 << USB_HUB_FEATURE_PORT_RESET) | 128 140 (1 << USB_HUB_FEATURE_PORT_POWER); 129 141 142 /** 143 * bitmask of port features that can be cleared 144 */ 130 145 static const uint32_t port_clear_feature_valid_mask = 131 146 (1 << USB_HUB_FEATURE_PORT_CONNECTION) | 132 147 (1 << USB_HUB_FEATURE_PORT_SUSPEND) | 133 148 (1 << USB_HUB_FEATURE_PORT_OVER_CURRENT) | … … 141 156 //USB_HUB_FEATURE_PORT_LOW_SPEED 142 157 158 /** 159 * bitmask with port status changes 160 */ 143 161 static const uint32_t port_status_change_mask = 144 (1<< USB_HUB_FEATURE_C_PORT_CONNECTION) |145 (1 << USB_HUB_FEATURE_C_PORT_ENABLE) |146 (1 << USB_HUB_FEATURE_C_PORT_OVER_CURRENT) |147 (1 << USB_HUB_FEATURE_C_PORT_RESET) |148 (1 << USB_HUB_FEATURE_C_PORT_SUSPEND);162 (1 << USB_HUB_FEATURE_C_PORT_CONNECTION) | 163 (1 << USB_HUB_FEATURE_C_PORT_ENABLE) | 164 (1 << USB_HUB_FEATURE_C_PORT_OVER_CURRENT) | 165 (1 << USB_HUB_FEATURE_C_PORT_RESET) | 166 (1 << USB_HUB_FEATURE_C_PORT_SUSPEND); 149 167 150 168 … … 154 172 155 173 static int process_get_port_status_request(rh_t *instance, uint16_t port, 156 174 usb_transfer_batch_t * request); 157 175 158 176 static int process_get_hub_status_request(rh_t *instance, 159 177 usb_transfer_batch_t * request); 160 178 161 179 static int process_get_status_request(rh_t *instance, 162 180 usb_transfer_batch_t * request); 163 181 164 182 static void create_interrupt_mask_in_instance(rh_t *instance); 165 183 166 184 static int process_get_descriptor_request(rh_t *instance, 167 185 usb_transfer_batch_t *request); 168 186 169 187 static int process_get_configuration_request(rh_t *instance, 170 188 usb_transfer_batch_t *request); 171 189 172 190 static int process_hub_feature_set_request(rh_t *instance, uint16_t feature); 173 191 174 192 static int process_hub_feature_clear_request(rh_t *instance, 175 193 uint16_t feature); 176 194 177 195 static int process_port_feature_set_request(rh_t *instance, 178 196 uint16_t feature, uint16_t port); 179 197 180 198 static int process_port_feature_clear_request(rh_t *instance, 181 199 uint16_t feature, uint16_t port); 182 200 183 201 static int process_address_set_request(rh_t *instance, 184 202 uint16_t address); 185 203 186 204 static int process_request_with_output(rh_t *instance, 187 205 usb_transfer_batch_t *request); 188 206 189 207 static int process_request_with_input(rh_t *instance, 190 208 usb_transfer_batch_t *request); 191 209 192 210 static int process_request_without_data(rh_t *instance, 193 211 usb_transfer_batch_t *request); 194 212 195 213 static int process_ctrl_request(rh_t *instance, usb_transfer_batch_t *request); … … 198 216 199 217 static bool is_zeros(void * buffer, size_t size); 200 201 202 218 203 219 /** Root hub initialization … … 210 226 (instance->registers->rh_desc_a >> RHDA_NDS_SHIFT) & RHDA_NDS_MASK; 211 227 int opResult = rh_init_descriptors(instance); 212 if (opResult != EOK){228 if (opResult != EOK) { 213 229 return opResult; 214 230 } … … 216 232 instance->registers->rh_desc_a |= RHDA_NPS_FLAG; 217 233 instance->unfinished_interrupt_transfer = NULL; 218 instance->interrupt_mask_size = (instance->port_count + 8) /8;234 instance->interrupt_mask_size = (instance->port_count + 8) / 8; 219 235 instance->interrupt_buffer = malloc(instance->interrupt_mask_size); 220 if (!instance->interrupt_buffer)236 if (!instance->interrupt_buffer) 221 237 return ENOMEM; 222 223 224 usb_log_info("OHCI root hub with %d ports.\n", instance->port_count); 238 239 usb_log_info("OHCI root hub with %zu ports initialized.\n", 240 instance->port_count); 241 225 242 return EOK; 226 243 } … … 245 262 usb_log_info("Root hub got INTERRUPT packet\n"); 246 263 create_interrupt_mask_in_instance(instance); 247 if (is_zeros(instance->interrupt_buffer,248 instance->interrupt_mask_size)) {264 if (is_zeros(instance->interrupt_buffer, 265 instance->interrupt_mask_size)) { 249 266 usb_log_debug("no changes..\n"); 250 267 instance->unfinished_interrupt_transfer = request; 251 268 //will be finished later 252 } else{269 } else { 253 270 usb_log_debug("processing changes..\n"); 254 271 process_interrupt_mask_in_instance(instance, request); … … 256 273 opResult = EOK; 257 274 } else { 275 258 276 opResult = EINVAL; 259 277 usb_transfer_batch_finish_error(request, opResult); … … 271 289 */ 272 290 void rh_interrupt(rh_t *instance) { 273 if (!instance->unfinished_interrupt_transfer){291 if (!instance->unfinished_interrupt_transfer) { 274 292 return; 275 293 } … … 292 310 static int create_serialized_hub_descriptor(rh_t *instance) { 293 311 size_t size = 7 + 294 ((instance->port_count + 7 )/ 8) * 2;295 size_t var_size = (instance->port_count + 7 )/ 8;312 ((instance->port_count + 7) / 8) * 2; 313 size_t var_size = (instance->port_count + 7) / 8; 296 314 uint8_t * result = (uint8_t*) malloc(size); 297 if (!result) return ENOMEM;315 if (!result) return ENOMEM; 298 316 299 317 bzero(result, size); … … 305 323 uint32_t hub_desc_reg = instance->registers->rh_desc_a; 306 324 result[3] = 307 308 309 310 311 325 ((hub_desc_reg >> 8) % 2) + 326 (((hub_desc_reg >> 9) % 2) << 1) + 327 (((hub_desc_reg >> 10) % 2) << 2) + 328 (((hub_desc_reg >> 11) % 2) << 3) + 329 (((hub_desc_reg >> 12) % 2) << 4); 312 330 result[4] = 0; 313 331 result[5] = /*descriptor->pwr_on_2_good_time*/ 50; 314 332 result[6] = 50; 315 333 316 int port;334 size_t port; 317 335 for (port = 1; port <= instance->port_count; ++port) { 318 336 uint8_t is_non_removable = 319 337 instance->registers->rh_desc_b >> port % 2; 320 338 result[7 + port / 8] += 321 339 is_non_removable << (port % 8); 322 340 } 323 341 size_t i; … … 327 345 instance->hub_descriptor = result; 328 346 instance->descriptor_size = size; 347 329 348 return EOK; 330 349 } … … 340 359 static int rh_init_descriptors(rh_t *instance) { 341 360 memcpy(&instance->descriptors.device, &ohci_rh_device_descriptor, 342 343 361 sizeof (ohci_rh_device_descriptor) 362 ); 344 363 usb_standard_configuration_descriptor_t descriptor; 345 364 memcpy(&descriptor, &ohci_rh_conf_descriptor, 346 365 sizeof (ohci_rh_conf_descriptor)); 347 366 348 367 int opResult = create_serialized_hub_descriptor(instance); 349 if (opResult != EOK){368 if (opResult != EOK) { 350 369 return opResult; 351 370 } 352 371 descriptor.total_length = 353 354 355 356 372 sizeof (usb_standard_configuration_descriptor_t) + 373 sizeof (usb_standard_endpoint_descriptor_t) + 374 sizeof (usb_standard_interface_descriptor_t) + 375 instance->descriptor_size; 357 376 358 377 uint8_t * full_config_descriptor = 359 360 if (!full_config_descriptor){378 (uint8_t*) malloc(descriptor.total_length); 379 if (!full_config_descriptor) { 361 380 return ENOMEM; 362 381 } 363 382 memcpy(full_config_descriptor, &descriptor, sizeof (descriptor)); 364 383 memcpy(full_config_descriptor + sizeof (descriptor), 365 384 &ohci_rh_iface_descriptor, sizeof (ohci_rh_iface_descriptor)); 366 385 memcpy(full_config_descriptor + sizeof (descriptor) + 367 368 386 sizeof (ohci_rh_iface_descriptor), 387 &ohci_rh_ep_descriptor, sizeof (ohci_rh_ep_descriptor)); 369 388 memcpy(full_config_descriptor + sizeof (descriptor) + 370 371 372 373 389 sizeof (ohci_rh_iface_descriptor) + 390 sizeof (ohci_rh_ep_descriptor), 391 instance->hub_descriptor, instance->descriptor_size); 392 374 393 instance->descriptors.configuration = full_config_descriptor; 375 394 instance->descriptors.configuration_size = descriptor.total_length; 395 376 396 return EOK; 377 397 } … … 389 409 */ 390 410 static int process_get_port_status_request(rh_t *instance, uint16_t port, 391 411 usb_transfer_batch_t * request) { 392 412 if (port < 1 || port > instance->port_count) 393 413 return EINVAL; … … 398 418 int i; 399 419 for (i = 0; i < instance->port_count; ++i) { 420 400 421 usb_log_debug("port status %d,x%x\n", 401 402 422 instance->registers->rh_port_status[i], 423 instance->registers->rh_port_status[i]); 403 424 } 404 425 #endif … … 417 438 */ 418 439 static int process_get_hub_status_request(rh_t *instance, 419 440 usb_transfer_batch_t * request) { 420 441 uint32_t * uint32_buffer = (uint32_t*) request->data_buffer; 421 442 request->transfered_size = 4; … … 423 444 uint32_t mask = 1 | (1 << 1) | (1 << 16) | (1 << 17); 424 445 uint32_buffer[0] = mask & instance->registers->rh_status; 446 425 447 return EOK; 426 448 } … … 437 459 */ 438 460 static int process_get_status_request(rh_t *instance, 439 461 usb_transfer_batch_t * request) { 440 462 size_t buffer_size = request->buffer_size; 441 463 usb_device_request_setup_packet_t * request_packet = 442 443 464 (usb_device_request_setup_packet_t*) 465 request->setup_buffer; 444 466 445 467 usb_hub_bm_request_type_t request_type = request_packet->request_type; … … 453 475 if (request_type == USB_HUB_REQ_TYPE_GET_PORT_STATUS) 454 476 return process_get_port_status_request(instance, 455 request_packet->index, 456 request); 477 request_packet->index, 478 request); 479 457 480 return ENOTSUP; 458 481 } … … 472 495 uint8_t * bitmap = (uint8_t*) (instance->interrupt_buffer); 473 496 uint32_t mask = (1 << (USB_HUB_FEATURE_C_HUB_LOCAL_POWER + 16)) 474 497 | (1 << (USB_HUB_FEATURE_C_HUB_OVER_CURRENT + 16)); 475 498 bzero(bitmap, instance->interrupt_mask_size); 476 499 if (instance->registers->rh_status & mask) { 477 500 bitmap[0] = 1; 478 501 } 479 int port;502 size_t port; 480 503 mask = port_status_change_mask; 481 504 for (port = 1; port <= instance->port_count; ++port) { 482 505 if (mask & instance->registers->rh_port_status[port - 1]) { 506 483 507 bitmap[(port) / 8] += 1 << (port % 8); 484 508 } … … 497 521 */ 498 522 static int process_get_descriptor_request(rh_t *instance, 499 523 usb_transfer_batch_t *request) { 500 524 usb_device_request_setup_packet_t * setup_request = 501 525 (usb_device_request_setup_packet_t*) request->setup_buffer; 502 526 size_t size; 503 527 const void * result_descriptor = NULL; … … 543 567 { 544 568 usb_log_debug("USB_DESCTYPE_EINVAL %d \n", 545 569 setup_request->value); 546 570 usb_log_debug("\ttype %d\n\trequest %d\n\tvalue " 547 548 549 550 551 552 553 571 "%d\n\tindex %d\n\tlen %d\n ", 572 setup_request->request_type, 573 setup_request->request, 574 setup_request_value, 575 setup_request->index, 576 setup_request->length 577 ); 554 578 return EINVAL; 555 579 } … … 560 584 request->transfered_size = size; 561 585 memcpy(request->data_buffer, result_descriptor, size); 586 562 587 return EOK; 563 588 } … … 573 598 */ 574 599 static int process_get_configuration_request(rh_t *instance, 575 600 usb_transfer_batch_t *request) { 576 601 //set and get configuration requests do not have any meaning, only dummy 577 602 //values are returned … … 580 605 request->data_buffer[0] = 1; 581 606 request->transfered_size = 1; 607 582 608 return EOK; 583 609 } … … 592 618 */ 593 619 static int process_hub_feature_set_request(rh_t *instance, 594 620 uint16_t feature) { 595 621 if (!((1 << feature) & hub_set_feature_valid_mask)) 596 622 return EINVAL; 597 if (feature == USB_HUB_FEATURE_C_HUB_LOCAL_POWER)623 if (feature == USB_HUB_FEATURE_C_HUB_LOCAL_POWER) 598 624 feature = USB_HUB_FEATURE_C_HUB_LOCAL_POWER << 16; 599 625 instance->registers->rh_status = 600 (instance->registers->rh_status | (1 << feature)) 601 & (~hub_clear_feature_by_writing_one_mask); 626 (instance->registers->rh_status | (1 << feature)) 627 & (~hub_clear_feature_by_writing_one_mask); 628 602 629 return EOK; 603 630 } … … 612 639 */ 613 640 static int process_hub_feature_clear_request(rh_t *instance, 614 641 uint16_t feature) { 615 642 if (!((1 << feature) & hub_clear_feature_valid_mask)) 616 643 return EINVAL; … … 618 645 if ((1 << feature) & hub_set_feature_direct_mask) { 619 646 instance->registers->rh_status = 620 621 647 (instance->registers->rh_status & (~(1 << feature))) 648 & (~hub_clear_feature_by_writing_one_mask); 622 649 } else {//the feature is cleared by writing '1' 650 623 651 instance->registers->rh_status = 624 625 626 652 (instance->registers->rh_status 653 & (~hub_clear_feature_by_writing_one_mask)) 654 | (1 << feature); 627 655 } 628 656 return EOK; … … 640 668 */ 641 669 static int process_port_feature_set_request(rh_t *instance, 642 670 uint16_t feature, uint16_t port) { 643 671 if (!((1 << feature) & port_set_feature_valid_mask)) 644 672 return EINVAL; … … 646 674 return EINVAL; 647 675 instance->registers->rh_port_status[port - 1] = 648 649 676 (instance->registers->rh_port_status[port - 1] | (1 << feature)) 677 & (~port_clear_feature_valid_mask); 650 678 /// \TODO any error? 679 651 680 return EOK; 652 681 } … … 663 692 */ 664 693 static int process_port_feature_clear_request(rh_t *instance, 665 694 uint16_t feature, uint16_t port) { 666 695 if (!((1 << feature) & port_clear_feature_valid_mask)) 667 696 return EINVAL; … … 673 702 feature = USB_HUB_FEATURE_PORT_OVER_CURRENT; 674 703 instance->registers->rh_port_status[port - 1] = 675 676 677 704 (instance->registers->rh_port_status[port - 1] 705 & (~port_clear_feature_valid_mask)) 706 | (1 << feature); 678 707 /// \TODO any error? 708 679 709 return EOK; 680 710 } … … 689 719 */ 690 720 static int process_address_set_request(rh_t *instance, 691 721 uint16_t address) { 692 722 instance->address = address; 723 693 724 return EOK; 694 725 } … … 705 736 */ 706 737 static int process_request_with_output(rh_t *instance, 707 738 usb_transfer_batch_t *request) { 708 739 usb_device_request_setup_packet_t * setup_request = 709 740 (usb_device_request_setup_packet_t*) request->setup_buffer; 710 741 if (setup_request->request == USB_DEVREQ_GET_STATUS) { 711 742 usb_log_debug("USB_DEVREQ_GET_STATUS\n"); … … 718 749 if (setup_request->request == USB_DEVREQ_GET_CONFIGURATION) { 719 750 usb_log_debug("USB_DEVREQ_GET_CONFIGURATION\n"); 751 720 752 return process_get_configuration_request(instance, request); 721 753 } … … 734 766 */ 735 767 static int process_request_with_input(rh_t *instance, 736 768 usb_transfer_batch_t *request) { 737 769 usb_device_request_setup_packet_t * setup_request = 738 770 (usb_device_request_setup_packet_t*) request->setup_buffer; 739 771 request->transfered_size = 0; 740 772 if (setup_request->request == USB_DEVREQ_SET_DESCRIPTOR) { … … 744 776 //set and get configuration requests do not have any meaning, 745 777 //only dummy values are returned 778 746 779 return EOK; 747 780 } … … 760 793 */ 761 794 static int process_request_without_data(rh_t *instance, 762 795 usb_transfer_batch_t *request) { 763 796 usb_device_request_setup_packet_t * setup_request = 764 797 (usb_device_request_setup_packet_t*) request->setup_buffer; 765 798 request->transfered_size = 0; 766 799 if (setup_request->request == USB_DEVREQ_CLEAR_FEATURE) { … … 768 801 usb_log_debug("USB_HUB_REQ_TYPE_SET_HUB_FEATURE\n"); 769 802 return process_hub_feature_clear_request(instance, 770 803 setup_request->value); 771 804 } 772 805 if (setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE) { 773 806 usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n"); 774 807 return process_port_feature_clear_request(instance, 775 776 808 setup_request->value, 809 setup_request->index); 777 810 } 778 811 usb_log_debug("USB_HUB_REQ_TYPE_INVALID %d\n", 779 812 setup_request->request_type); 780 813 return EINVAL; 781 814 } … … 784 817 usb_log_debug("USB_HUB_REQ_TYPE_SET_HUB_FEATURE\n"); 785 818 return process_hub_feature_set_request(instance, 786 819 setup_request->value); 787 820 } 788 821 if (setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE) { 789 822 usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n"); 790 823 return process_port_feature_set_request(instance, 791 792 824 setup_request->value, 825 setup_request->index); 793 826 } 794 827 usb_log_debug("USB_HUB_REQ_TYPE_INVALID %d\n", 795 828 setup_request->request_type); 796 829 return EINVAL; 797 830 } … … 799 832 usb_log_debug("USB_DEVREQ_SET_ADDRESS\n"); 800 833 return process_address_set_request(instance, 801 834 setup_request->value); 802 835 } 803 836 usb_log_debug("USB_DEVREQ_SET_ENOTSUP %d\n", 804 setup_request->request_type); 837 setup_request->request_type); 838 805 839 return ENOTSUP; 806 840 } … … 836 870 } 837 871 usb_log_info("CTRL packet: %s.\n", 838 839 872 usb_debug_str_buffer( 873 (const uint8_t *) request->setup_buffer, 8, 8)); 840 874 usb_device_request_setup_packet_t * setup_request = 841 842 875 (usb_device_request_setup_packet_t*) 876 request->setup_buffer; 843 877 switch (setup_request->request) { 844 878 case USB_DEVREQ_GET_STATUS: … … 847 881 usb_log_debug("processing request with output\n"); 848 882 opResult = process_request_with_output( 849 883 instance, request); 850 884 break; 851 885 case USB_DEVREQ_CLEAR_FEATURE: … … 853 887 case USB_DEVREQ_SET_ADDRESS: 854 888 usb_log_debug("processing request without " 855 889 "additional data\n"); 856 890 opResult = process_request_without_data( 857 891 instance, request); 858 892 break; 859 893 case USB_DEVREQ_SET_DESCRIPTOR: 860 894 case USB_DEVREQ_SET_CONFIGURATION: 861 895 usb_log_debug("processing request with " 862 896 "input\n"); 863 897 opResult = process_request_with_input( 864 instance, request); 898 instance, request); 899 865 900 break; 866 901 default: 867 902 usb_log_warning("received unsuported request: " 868 869 870 903 "%d\n", 904 setup_request->request 905 ); 871 906 opResult = ENOTSUP; 872 907 } … … 888 923 * @return 889 924 */ 890 static int process_interrupt_mask_in_instance(rh_t *instance, usb_transfer_batch_t * request) {925 static int process_interrupt_mask_in_instance(rh_t *instance, usb_transfer_batch_t * request) { 891 926 memcpy(request->data_buffer, instance->interrupt_buffer, 892 927 instance->interrupt_mask_size); … … 894 929 instance->unfinished_interrupt_transfer = NULL; 895 930 usb_transfer_batch_finish_error(request, EOK); 931 896 932 return EOK; 897 933 } … … 907 943 * @return 908 944 */ 909 static bool is_zeros(void * buffer, size_t size) {910 if (!buffer) return true;911 if (!size) return true;945 static bool is_zeros(void * buffer, size_t size) { 946 if (!buffer) return true; 947 if (!size) return true; 912 948 size_t i; 913 for (i=0;i<size;++i){914 if (((char*)buffer)[i])949 for (i = 0; i < size; ++i) { 950 if (((char*) buffer)[i]) 915 951 return false; 916 952 } -
uspace/drv/ohci/root_hub.h
r456aea3 r9e195e2c 51 51 usb_address_t address; 52 52 /** hub port count */ 53 int port_count;53 size_t port_count; 54 54 /** hubs descriptors */ 55 55 usb_device_descriptors_t descriptors; -
uspace/drv/uhci-hcd/Makefile
r456aea3 r9e195e2c 28 28 29 29 USPACE_PREFIX = ../.. 30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a 31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include -I. 30 31 LIBS = \ 32 $(LIBUSBHOST_PREFIX)/libusbhost.a \ 33 $(LIBUSB_PREFIX)/libusb.a \ 34 $(LIBDRV_PREFIX)/libdrv.a 35 EXTRA_CFLAGS += \ 36 -I$(LIBUSB_PREFIX)/include \ 37 -I$(LIBUSBHOST_PREFIX)/include \ 38 -I$(LIBDRV_PREFIX)/include 39 32 40 BINARY = uhci-hcd 33 41 -
uspace/drv/uhci-hcd/hc.c
r456aea3 r9e195e2c 60 60 * 61 61 * @param[in] instance Memory place to initialize. 62 * @param[in] fun DDF function.63 62 * @param[in] regs Address of I/O control registers. 64 63 * @param[in] size Size of I/O control registers. … … 69 68 * interrupt fibrils. 70 69 */ 71 int hc_init(hc_t *instance, ddf_fun_t *fun, 72 void *regs, size_t reg_size, bool interrupts) 70 int hc_init(hc_t *instance, void *regs, size_t reg_size, bool interrupts) 73 71 { 74 72 assert(reg_size >= sizeof(regs_t)); -
uspace/drv/uhci-hcd/hc.h
r456aea3 r9e195e2c 136 136 } hc_t; 137 137 138 int hc_init(hc_t *instance, ddf_fun_t *fun, 139 void *regs, size_t reg_size, bool interupts); 138 int hc_init(hc_t *instance, void *regs, size_t reg_size, bool interupts); 140 139 141 140 int hc_schedule(hc_t *instance, usb_transfer_batch_t *batch); -
uspace/drv/uhci-hcd/hw_struct/queue_head.h
r456aea3 r9e195e2c 38 38 #include "link_pointer.h" 39 39 #include "transfer_descriptor.h" 40 #include " utils/malloc32.h"40 #include "../utils/malloc32.h" 41 41 42 42 /** This structure is defined in UHCI design guide p. 31 */ -
uspace/drv/uhci-hcd/hw_struct/transfer_descriptor.c
r456aea3 r9e195e2c 36 36 37 37 #include "transfer_descriptor.h" 38 #include " utils/malloc32.h"38 #include "../utils/malloc32.h" 39 39 40 40 /** Initialize Transfer Descriptor -
uspace/drv/uhci-hcd/iface.c
r456aea3 r9e195e2c 122 122 return EOK; 123 123 } 124 125 /** Find device handle by address interface function. 126 * 127 * @param[in] fun DDF function that was called. 128 * @param[in] address Address in question. 129 * @param[out] handle Where to store device handle if found. 130 * @return Error code. 131 */ 132 static int find_by_address(ddf_fun_t *fun, usb_address_t address, 133 devman_handle_t *handle) 134 { 135 assert(fun); 136 hc_t *hc = fun_to_hc(fun); 137 assert(hc); 138 bool found = 139 usb_device_keeper_find_by_address(&hc->manager, address, handle); 140 return found ? EOK : ENOENT; 141 } 142 124 143 /*----------------------------------------------------------------------------*/ 125 144 /** Release address interface function … … 352 371 .request_address = request_address, 353 372 .bind_address = bind_address, 373 .find_by_address = find_by_address, 354 374 .release_address = release_address, 355 375 -
uspace/drv/uhci-hcd/main.c
r456aea3 r9e195e2c 64 64 assert(device); 65 65 66 uhci_t *uhci = malloc(sizeof(uhci_t)); 67 if (uhci == NULL) { 68 usb_log_error("Failed to allocate UHCI driver.\n"); 69 return ENOMEM; 70 } 71 72 int ret = uhci_init(uhci, device); 66 int ret = device_setup_uhci(device); 73 67 if (ret != EOK) { 74 68 usb_log_error("Failed to initialize UHCI driver: %s.\n", … … 76 70 return ret; 77 71 } 78 device->driver_data = uhci;79 80 72 usb_log_info("Controlling new UHCI device '%s'.\n", device->name); 81 73 -
uspace/drv/uhci-hcd/uhci.c
r456aea3 r9e195e2c 44 44 #include "pci.h" 45 45 46 #include "hc.h" 47 #include "root_hub.h" 48 49 /** Structure representing both functions of UHCI hc, USB host controller 50 * and USB root hub */ 51 typedef struct uhci { 52 /** Pointer to DDF represenation of UHCI host controller */ 53 ddf_fun_t *hc_fun; 54 /** Pointer to DDF represenation of UHCI root hub */ 55 ddf_fun_t *rh_fun; 56 57 /** Internal driver's represenation of UHCI host controller */ 58 hc_t hc; 59 /** Internal driver's represenation of UHCI root hub */ 60 rh_t rh; 61 } uhci_t; 62 63 static inline uhci_t * dev_to_uhci(ddf_dev_t *dev) 64 { 65 assert(dev); 66 assert(dev->driver_data); 67 return dev->driver_data; 68 } 69 /*----------------------------------------------------------------------------*/ 46 70 /** IRQ handling callback, forward status from call to diver structure. 47 71 * … … 69 93 { 70 94 assert(fun); 71 usb_device_keeper_t *manager = 72 &((uhci_t*)fun->dev->driver_data)->hc.manager; 73 95 usb_device_keeper_t *manager = &dev_to_uhci(fun->dev)->hc.manager; 74 96 usb_address_t addr = usb_device_keeper_find(manager, handle); 97 75 98 if (addr < 0) { 76 99 return addr; … … 93 116 ddf_fun_t *fun, devman_handle_t *handle) 94 117 { 95 assert(handle); 96 ddf_fun_t *hc_fun = ((uhci_t*)fun->dev->driver_data)->hc_fun; 97 assert(hc_fun != NULL); 98 99 *handle = hc_fun->handle; 118 assert(fun); 119 ddf_fun_t *hc_fun = dev_to_uhci(fun->dev)->hc_fun; 120 assert(hc_fun); 121 122 if (handle != NULL) 123 *handle = hc_fun->handle; 100 124 return EOK; 101 125 } … … 126 150 static hw_res_ops_t hw_res_iface = { 127 151 .get_resource_list = get_resource_list, 128 .enable_interrupt = NULL 152 .enable_interrupt = NULL, 129 153 }; 130 154 /*----------------------------------------------------------------------------*/ … … 146 170 * - registers interrupt handler 147 171 */ 148 int uhci_init(uhci_t *instance, ddf_dev_t *device) 149 { 150 assert(instance); 151 instance->hc_fun = NULL; 172 int device_setup_uhci(ddf_dev_t *device) 173 { 174 assert(device); 175 uhci_t *instance = malloc(sizeof(uhci_t)); 176 if (instance == NULL) { 177 usb_log_error("Failed to allocate OHCI driver.\n"); 178 return ENOMEM; 179 } 180 181 #define CHECK_RET_DEST_FREE_RETURN(ret, message...) \ 182 if (ret != EOK) { \ 183 if (instance->hc_fun) \ 184 instance->hc_fun->ops = NULL; \ 185 instance->hc_fun->driver_data = NULL; \ 186 ddf_fun_destroy(instance->hc_fun); \ 187 if (instance->rh_fun) {\ 188 instance->rh_fun->ops = NULL; \ 189 instance->rh_fun->driver_data = NULL; \ 190 ddf_fun_destroy(instance->rh_fun); \ 191 } \ 192 free(instance); \ 193 usb_log_error(message); \ 194 return ret; \ 195 } else (void)0 196 152 197 instance->rh_fun = NULL; 153 #define CHECK_RET_DEST_FUN_RETURN(ret, message...) \ 154 if (ret != EOK) { \ 155 usb_log_error(message); \ 156 if (instance->hc_fun) \ 157 ddf_fun_destroy(instance->hc_fun); \ 158 if (instance->rh_fun) \ 159 ddf_fun_destroy(instance->rh_fun); \ 160 return ret; \ 161 } 162 163 uintptr_t io_reg_base = 0; 164 size_t io_reg_size = 0; 198 instance->hc_fun = ddf_fun_create(device, fun_exposed, "uhci-hc"); 199 int ret = (instance->hc_fun == NULL) ? ENOMEM : EOK; 200 CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create UHCI HC function.\n"); 201 instance->hc_fun->ops = &hc_ops; 202 instance->hc_fun->driver_data = &instance->hc; 203 204 instance->rh_fun = ddf_fun_create(device, fun_inner, "uhci-rh"); 205 ret = (instance->rh_fun == NULL) ? ENOMEM : EOK; 206 CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create UHCI RH function.\n"); 207 instance->rh_fun->ops = &rh_ops; 208 instance->rh_fun->driver_data = &instance->rh; 209 210 uintptr_t reg_base = 0; 211 size_t reg_size = 0; 165 212 int irq = 0; 166 213 167 int ret = 168 pci_get_my_registers(device, &io_reg_base, &io_reg_size, &irq); 169 CHECK_RET_DEST_FUN_RETURN(ret, 214 ret = pci_get_my_registers(device, ®_base, ®_size, &irq); 215 CHECK_RET_DEST_FREE_RETURN(ret, 170 216 "Failed to get I/O addresses for %" PRIun ": %s.\n", 171 217 device->handle, str_error(ret)); 172 218 usb_log_debug("I/O regs at 0x%p (size %zu), IRQ %d.\n", 173 (void *) io_reg_base, io_reg_size, irq);219 (void *) reg_base, reg_size, irq); 174 220 175 221 ret = pci_disable_legacy(device); 176 CHECK_RET_DEST_F UN_RETURN(ret,222 CHECK_RET_DEST_FREE_RETURN(ret, 177 223 "Failed(%d) to disable legacy USB: %s.\n", ret, str_error(ret)); 178 224 … … 194 240 #endif 195 241 196 instance->hc_fun = ddf_fun_create(device, fun_exposed, "uhci-hc"); 197 ret = (instance->hc_fun == NULL) ? ENOMEM : EOK; 198 CHECK_RET_DEST_FUN_RETURN(ret, 199 "Failed(%d) to create HC function: %s.\n", ret, str_error(ret)); 200 201 ret = hc_init(&instance->hc, instance->hc_fun, 202 (void*)io_reg_base, io_reg_size, interrupts); 203 CHECK_RET_DEST_FUN_RETURN(ret, 242 243 ret = hc_init(&instance->hc, (void*)reg_base, reg_size, interrupts); 244 CHECK_RET_DEST_FREE_RETURN(ret, 204 245 "Failed(%d) to init uhci-hcd: %s.\n", ret, str_error(ret)); 205 206 instance->hc_fun->ops = &hc_ops;207 instance->hc_fun->driver_data = &instance->hc;208 ret = ddf_fun_bind(instance->hc_fun);209 CHECK_RET_DEST_FUN_RETURN(ret,210 "Failed(%d) to bind UHCI device function: %s.\n",211 ret, str_error(ret));212 #undef CHECK_RET_HC_RETURN213 246 214 247 #define CHECK_RET_FINI_RETURN(ret, message...) \ 215 248 if (ret != EOK) { \ 216 usb_log_error(message); \217 if (instance->hc_fun) \218 ddf_fun_destroy(instance->hc_fun); \219 if (instance->rh_fun) \220 ddf_fun_destroy(instance->rh_fun); \221 249 hc_fini(&instance->hc); \ 250 CHECK_RET_DEST_FREE_RETURN(ret, message); \ 222 251 return ret; \ 223 } 252 } else (void)0 224 253 225 254 /* It does no harm if we register this on polling */ … … 230 259 ret, str_error(ret)); 231 260 232 instance->rh_fun = ddf_fun_create(device, fun_inner, "uhci-rh"); 233 ret = (instance->rh_fun == NULL) ? ENOMEM : EOK; 234 CHECK_RET_FINI_RETURN(ret, 235 "Failed(%d) to create root hub function: %s.\n", 261 ret = ddf_fun_bind(instance->hc_fun); 262 CHECK_RET_FINI_RETURN(ret, 263 "Failed(%d) to bind UHCI device function: %s.\n", 236 264 ret, str_error(ret)); 265 266 ret = ddf_fun_add_to_class(instance->hc_fun, USB_HC_DDF_CLASS_NAME); 267 CHECK_RET_FINI_RETURN(ret, 268 "Failed to add UHCI to HC class: %s.\n", str_error(ret)); 237 269 238 270 ret = rh_init(&instance->rh, instance->rh_fun, … … 241 273 "Failed(%d) to setup UHCI root hub: %s.\n", ret, str_error(ret)); 242 274 243 instance->rh_fun->ops = &rh_ops;244 instance->rh_fun->driver_data = &instance->rh;245 275 ret = ddf_fun_bind(instance->rh_fun); 246 276 CHECK_RET_FINI_RETURN(ret, 247 277 "Failed(%d) to register UHCI root hub: %s.\n", ret, str_error(ret)); 248 278 279 device->driver_data = instance; 249 280 return EOK; 250 281 #undef CHECK_RET_FINI_RETURN -
uspace/drv/uhci-hcd/uhci.h
r456aea3 r9e195e2c 38 38 #include <ddf/driver.h> 39 39 40 #include "hc.h" 41 #include "root_hub.h" 42 43 /** Structure representing both functions of UHCI hc, USB host controller 44 * and USB root hub */ 45 typedef struct uhci { 46 /** Pointer to DDF represenation of UHCI host controller */ 47 ddf_fun_t *hc_fun; 48 /** Pointer to DDF represenation of UHCI root hub */ 49 ddf_fun_t *rh_fun; 50 51 /** Internal driver's represenation of UHCI host controller */ 52 hc_t hc; 53 /** Internal driver's represenation of UHCI root hub */ 54 rh_t rh; 55 } uhci_t; 56 57 int uhci_init(uhci_t *instance, ddf_dev_t *device); 40 int device_setup_uhci(ddf_dev_t *device); 58 41 #endif 59 42 /** -
uspace/drv/uhci-rhd/Makefile
r456aea3 r9e195e2c 28 28 29 29 USPACE_PREFIX = ../.. 30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a 31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include -I. 30 31 LIBS = \ 32 $(LIBUSBDEV_PREFIX)/libusbdev.a \ 33 $(LIBUSB_PREFIX)/libusb.a \ 34 $(LIBDRV_PREFIX)/libdrv.a 35 EXTRA_CFLAGS += \ 36 -I$(LIBUSB_PREFIX)/include \ 37 -I$(LIBUSBDEV_PREFIX)/include \ 38 -I$(LIBDRV_PREFIX)/include 39 32 40 BINARY = uhci-rhd 33 41 -
uspace/drv/uhci-rhd/port.c
r456aea3 r9e195e2c 32 32 * @brief UHCI root hub port routines 33 33 */ 34 #include <libarch/ddi.h> /* pio_read and pio_write */ 34 #include <libarch/ddi.h> /* pio_read and pio_write */ 35 #include <fibril_synch.h> /* async_usleep */ 35 36 #include <errno.h> 36 37 #include <str_error.h> 37 #include <fibril_synch.h>38 38 39 39 #include <usb/usb.h> /* usb_address_t */ 40 #include <usb/hub.h> 40 #include <usb/hub.h> /* usb_hc_new_device_wrapper */ 41 41 #include <usb/debug.h> 42 42 … … 212 212 213 213 /* 214 * The host then waits for at least 100 ms to allow completion of 215 * an insertion process and for power at the device to become stable. 216 */ 217 async_usleep(100000); 218 219 /* 220 * Resets from root ports should be nominally 50ms 214 * Resets from root ports should be nominally 50ms (USB spec 7.1.7.3) 221 215 */ 222 216 { … … 229 223 port_status &= ~STATUS_IN_RESET; 230 224 uhci_port_write_status(port, port_status); 231 usb_log_debug("%s: Reset Signal stop.\n", port->id_string);232 }233 234 /* the reset recovery time 10ms */235 async_usleep(10000);236 225 while (uhci_port_read_status(port) & STATUS_IN_RESET); 226 // TODO: find a better way to waste time (it should be less than 227 // 10ms, if we reschedule it takes too much time (random 228 // interrupts can be solved by multiple attempts). 229 usb_log_debug2("%s: Reset Signal stop.\n", port->id_string); 230 } 237 231 /* Enable the port. */ 238 232 uhci_port_set_enabled(port, true); 233 234 /* Reset recovery period, 235 * devices do not have to respond during this period 236 */ 237 async_usleep(10000); 239 238 return EOK; 240 239 } … … 255 254 usb_log_debug("%s: Detected new device.\n", port->id_string); 256 255 256 int ret, count = 0; 257 257 usb_address_t dev_addr; 258 int ret = usb_hc_new_device_wrapper(port->rh, &port->hc_connection, 259 speed, uhci_port_reset_enable, port->number, port, 260 &dev_addr, &port->attached_device, NULL, NULL, NULL); 258 do { 259 ret = usb_hc_new_device_wrapper(port->rh, &port->hc_connection, 260 speed, uhci_port_reset_enable, port->number, port, 261 &dev_addr, &port->attached_device, NULL, NULL, NULL); 262 } while (ret != EOK && ++count < 4); 261 263 262 264 if (ret != EOK) { … … 313 315 /* Wait for port to become enabled */ 314 316 do { 315 async_usleep(1000);316 317 port_status = uhci_port_read_status(port); 317 318 } while ((port_status & STATUS_CONNECTED) && -
uspace/drv/usbflbk/Makefile
r456aea3 r9e195e2c 28 28 29 29 USPACE_PREFIX = ../.. 30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a 31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include 30 31 LIBS = \ 32 $(LIBUSBDEV_PREFIX)/libusbdev.a \ 33 $(LIBUSB_PREFIX)/libusb.a \ 34 $(LIBDRV_PREFIX)/libdrv.a 35 EXTRA_CFLAGS += \ 36 -I$(LIBUSB_PREFIX)/include \ 37 -I$(LIBUSBDEV_PREFIX)/include \ 38 -I$(LIBDRV_PREFIX)/include 39 32 40 BINARY = usbflbk 33 41 -
uspace/drv/usbhid/Makefile
r456aea3 r9e195e2c 28 28 29 29 USPACE_PREFIX = ../.. 30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a 31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include -I. 30 31 LIBS = \ 32 $(LIBUSBHID_PREFIX)/libusbhid.a \ 33 $(LIBUSBDEV_PREFIX)/libusbdev.a \ 34 $(LIBUSB_PREFIX)/libusb.a \ 35 $(LIBDRV_PREFIX)/libdrv.a 36 EXTRA_CFLAGS += \ 37 -I. \ 38 -I$(LIBUSB_PREFIX)/include \ 39 -I$(LIBUSBDEV_PREFIX)/include \ 40 -I$(LIBUSBHID_PREFIX)/include \ 41 -I$(LIBDRV_PREFIX)/include 42 32 43 BINARY = usbhid 33 44 -
uspace/drv/usbhid/mouse/mousedev.c
r456aea3 r9e195e2c 309 309 * Wheel 310 310 */ 311 int wheel ;311 int wheel = 0; 312 312 313 313 path = usb_hid_report_path(); -
uspace/drv/usbhub/Makefile
r456aea3 r9e195e2c 28 28 29 29 USPACE_PREFIX = ../.. 30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a 31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include 30 31 LIBS = \ 32 $(LIBUSBDEV_PREFIX)/libusbdev.a \ 33 $(LIBUSB_PREFIX)/libusb.a \ 34 $(LIBDRV_PREFIX)/libdrv.a 35 EXTRA_CFLAGS += \ 36 -I$(LIBUSB_PREFIX)/include \ 37 -I$(LIBUSBDEV_PREFIX)/include \ 38 -I$(LIBDRV_PREFIX)/include 39 32 40 BINARY = usbhub 33 41 -
uspace/drv/usbhub/ports.c
r456aea3 r9e195e2c 53 53 size_t port; 54 54 usb_speed_t speed; 55 }; 56 57 /** 58 * count of port status changes that are not explicitly handled by 59 * any function here and must be cleared by hand 60 */ 61 static const unsigned int non_handled_changes_count = 2; 62 63 /** 64 * port status changes that are not explicitly handled by 65 * any function here and must be cleared by hand 66 */ 67 static const int non_handled_changes[] = { 68 USB_HUB_FEATURE_C_PORT_ENABLE, 69 USB_HUB_FEATURE_C_PORT_SUSPEND 55 70 }; 56 71 … … 131 146 &status, USB_HUB_FEATURE_C_PORT_CONNECTION,false); 132 147 usb_port_status_set_bit( 133 &status, USB_HUB_FEATURE_PORT_RESET,false);134 usb_port_status_set_bit(135 148 &status, USB_HUB_FEATURE_C_PORT_RESET,false); 136 149 usb_port_status_set_bit( 137 150 &status, USB_HUB_FEATURE_C_PORT_OVER_CURRENT,false); 138 /// \TODO what about port power change? 139 if (status >> 16) { 140 usb_log_info("there was unsupported change on port %d: %X\n", 141 port, status); 142 151 152 //clearing not yet handled changes 153 unsigned int feature_idx; 154 for(feature_idx = 0;feature_idx<non_handled_changes_count; 155 ++feature_idx){ 156 unsigned int bit_idx = non_handled_changes[feature_idx]; 157 if(status & (1<<bit_idx)){ 158 usb_log_info( 159 "there was not yet handled change on port %d: %d" 160 ";clearing it\n", 161 port, bit_idx); 162 int opResult = usb_hub_clear_port_feature( 163 hub->control_pipe, 164 port, bit_idx); 165 if (opResult != EOK) { 166 usb_log_warning( 167 "could not clear port flag %d: %d\n", 168 bit_idx, opResult 169 ); 170 } 171 usb_port_status_set_bit( 172 &status, bit_idx,false); 173 } 174 } 175 if(status>>16){ 176 usb_log_info("there is still some unhandled change %X\n", 177 status); 143 178 } 144 179 } … … 222 257 "Port %zu reset complete but port not enabled.\n", 223 258 (size_t) port); 259 } 260 /* Clear the port reset change. */ 261 int rc = usb_hub_clear_port_feature(hub->control_pipe, 262 port, USB_HUB_FEATURE_C_PORT_RESET); 263 if (rc != EOK) { 264 usb_log_error("Failed to clear port %d reset feature: %s.\n", 265 port, str_error(rc)); 224 266 } 225 267 } … … 319 361 fibril_mutex_unlock(&my_port->reset_mutex); 320 362 321 /* Clear the port reset change. */322 rc = usb_hub_clear_port_feature(hub->control_pipe,323 port_no, USB_HUB_FEATURE_C_PORT_RESET);324 if (rc != EOK) {325 usb_log_error("Failed to clear port %d reset feature: %s.\n",326 port_no, str_error(rc));327 return rc;328 }329 330 363 if (my_port->reset_okay) { 331 364 return EOK; -
uspace/drv/usbmast/Makefile
r456aea3 r9e195e2c 28 28 29 29 USPACE_PREFIX = ../.. 30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a 31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include 30 31 LIBS = \ 32 $(LIBUSBDEV_PREFIX)/libusbdev.a \ 33 $(LIBUSB_PREFIX)/libusb.a \ 34 $(LIBDRV_PREFIX)/libdrv.a 35 EXTRA_CFLAGS += \ 36 -I$(LIBUSB_PREFIX)/include \ 37 -I$(LIBUSBDEV_PREFIX)/include \ 38 -I$(LIBDRV_PREFIX)/include 39 32 40 BINARY = usbmast 33 41 34 42 SOURCES = \ 43 inquiry.c \ 35 44 main.c \ 36 45 mast.c -
uspace/drv/usbmast/main.c
r456aea3 r9e195e2c 75 75 }; 76 76 77 #define BITS_GET_MASK(type, bitcount) (((type)(1 << (bitcount)))-1)78 #define BITS_GET_MID_MASK(type, bitcount, offset) \79 ((type)( BITS_GET_MASK(type, (bitcount) + (offset)) - BITS_GET_MASK(type, bitcount) ))80 #define BITS_GET(type, number, bitcount, offset) \81 ((type)( (number) & (BITS_GET_MID_MASK(type, bitcount, offset)) ) >> (offset))82 83 #define INQUIRY_RESPONSE_LENGTH 3584 85 static void try_inquiry(usb_device_t *dev)86 {87 scsi_cmd_inquiry_t inquiry = {88 .op_code = 0x12,89 .lun_evpd = 0,90 .page_code = 0,91 .alloc_length = INQUIRY_RESPONSE_LENGTH,92 .ctrl = 093 };94 size_t response_len;95 uint8_t response[INQUIRY_RESPONSE_LENGTH];96 97 int rc;98 99 rc = usb_massstor_data_in(GET_BULK_IN(dev), GET_BULK_OUT(dev),100 0xDEADBEEF, 0, (uint8_t *) &inquiry, sizeof(inquiry),101 response, INQUIRY_RESPONSE_LENGTH, &response_len);102 103 if (rc != EOK) {104 usb_log_error("Failed to probe device %s using %s: %s.\n",105 dev->ddf_dev->name, "SCSI:INQUIRY", str_error(rc));106 return;107 }108 109 if (response_len < 8) {110 usb_log_error("The SCSI response is too short.\n");111 return;112 }113 114 /*115 * This is an ugly part of the code. We will parse the returned116 * data by hand and try to get as many useful data as possible.117 */118 int device_type = BITS_GET(uint8_t, response[0], 5, 0);119 int removable = BITS_GET(uint8_t, response[1], 1, 7);120 121 usb_log_info("SCSI information for device `%s':\n", dev->ddf_dev->name);122 usb_log_info(" - peripheral device type: %d\n", device_type);123 usb_log_info(" - removable: %s\n", removable ? "yes" : "no");124 125 if (response_len < 32) {126 return;127 }128 129 char dev_vendor[9];130 str_ncpy(dev_vendor, 9, (const char *) &response[8], 8);131 usb_log_info(" - vendor: '%s'\n", dev_vendor);132 133 char dev_product[9];134 str_ncpy(dev_product, 9, (const char *) &response[16], 8);135 usb_log_info(" - product: '%s'\n", dev_vendor);136 }137 138 77 /** Callback when new device is attached and recognized as a mass storage. 139 78 * … … 168 107 (size_t) dev->pipes[BULK_OUT_EP].descriptor->max_packet_size); 169 108 170 try_inquiry(dev); 109 size_t lun_count = usb_masstor_get_lun_count(dev); 110 111 usb_massstor_inquiry_result_t inquiry; 112 rc = usb_massstor_inquiry(dev, BULK_IN_EP, BULK_OUT_EP, &inquiry); 113 if (rc != EOK) { 114 usb_log_warning("Failed to inquiry device `%s': %s.\n", 115 dev->ddf_dev->name, str_error(rc)); 116 return EOK; 117 } 118 119 usb_log_info("Mass storage `%s': " \ 120 "`%s' by `%s' is %s (%s), %zu LUN(s).\n", 121 dev->ddf_dev->name, 122 inquiry.product_and_revision, inquiry.vendor_id, 123 usb_str_masstor_scsi_peripheral_device_type(inquiry.peripheral_device_type), 124 inquiry.removable ? "removable" : "non-removable", 125 lun_count); 171 126 172 127 return EOK; -
uspace/drv/usbmast/mast.c
r456aea3 r9e195e2c 40 40 #include <str_error.h> 41 41 #include <usb/debug.h> 42 #include <usb/request.h> 42 43 43 44 bool usb_mast_verbose = true; … … 63 64 * @return Error code. 64 65 */ 65 int usb_massstor_data_in(usb_pipe_t *bulk_in_pipe, usb_pipe_t *bulk_out_pipe, 66 int usb_massstor_data_in(usb_device_t *dev, 67 size_t bulk_in_pipe_index, size_t bulk_out_pipe_index, 66 68 uint32_t tag, uint8_t lun, void *cmd, size_t cmd_size, 67 69 void *in_buffer, size_t in_buffer_size, size_t *received_size) … … 69 71 int rc; 70 72 size_t act_size; 73 usb_pipe_t *bulk_in_pipe = dev->pipes[bulk_in_pipe_index].pipe; 74 usb_pipe_t *bulk_out_pipe = dev->pipes[bulk_out_pipe_index].pipe; 71 75 72 76 /* Prepare CBW - command block wrapper */ … … 135 139 } 136 140 141 /** Perform bulk-only mass storage reset. 142 * 143 * @param dev Device to be reseted. 144 * @return Error code. 145 */ 146 int usb_massstor_reset(usb_device_t *dev) 147 { 148 return usb_control_request_set(&dev->ctrl_pipe, 149 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 150 0xFF, 0, dev->interface_no, NULL, 0); 151 } 152 153 /** Perform complete reset recovery of bulk-only mass storage. 154 * 155 * Notice that no error is reported because if this fails, the error 156 * would reappear on next transaction somehow. 157 * 158 * @param dev Device to be reseted. 159 * @param bulk_in_idx Index of bulk in pipe. 160 * @param bulk_out_idx Index of bulk out pipe. 161 */ 162 void usb_massstor_reset_recovery(usb_device_t *dev, 163 size_t bulk_in_idx, size_t bulk_out_idx) 164 { 165 /* We would ignore errors here because if this fails 166 * we are doomed anyway and any following transaction would fail. 167 */ 168 usb_massstor_reset(dev); 169 usb_pipe_clear_halt(&dev->ctrl_pipe, dev->pipes[bulk_in_idx].pipe); 170 usb_pipe_clear_halt(&dev->ctrl_pipe, dev->pipes[bulk_out_idx].pipe); 171 } 172 173 /** Get max LUN of a mass storage device. 174 * 175 * @see usb_masstor_get_lun_count 176 * 177 * @warning Error from this command does not necessarily indicate malfunction 178 * of the device. Device does not need to support this request. 179 * You shall rather use usb_masstor_get_lun_count. 180 * 181 * @param dev Mass storage device. 182 * @return Error code of maximum LUN (index, not count). 183 */ 184 int usb_massstor_get_max_lun(usb_device_t *dev) 185 { 186 uint8_t max_lun; 187 size_t data_recv_len; 188 int rc = usb_control_request_get(&dev->ctrl_pipe, 189 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 190 0xFE, 0, dev->interface_no, &max_lun, 1, &data_recv_len); 191 if (rc != EOK) { 192 return rc; 193 } 194 if (data_recv_len != 1) { 195 return EEMPTY; 196 } 197 return (int) max_lun; 198 } 199 200 /** Get number of LUNs supported by mass storage device. 201 * 202 * @warning This function hides any error during the request 203 * (typically that shall not be a problem). 204 * 205 * @param dev Mass storage device. 206 * @return Number of LUNs. 207 */ 208 size_t usb_masstor_get_lun_count(usb_device_t *dev) 209 { 210 int max_lun = usb_massstor_get_max_lun(dev); 211 if (max_lun < 0) { 212 max_lun = 1; 213 } else { 214 max_lun++; 215 } 216 217 return (size_t) max_lun; 218 } 219 137 220 /** 138 221 * @} -
uspace/drv/usbmast/mast.h
r456aea3 r9e195e2c 40 40 #include <usb/usb.h> 41 41 #include <usb/pipes.h> 42 #include <usb/devdrv.h> 42 43 43 int usb_massstor_data_in(usb_pipe_t *, usb_pipe_t *, uint32_t, uint8_t, 44 void *, size_t, void *, size_t, size_t *); 44 /** Result of SCSI INQUIRY command. 45 * This is already parsed structure, not the original buffer returned by 46 * the device. 47 */ 48 typedef struct { 49 /** SCSI peripheral device type. */ 50 int peripheral_device_type; 51 /** Whether the device is removable. */ 52 bool removable; 53 /** Vendor ID string. */ 54 char vendor_id[9]; 55 /** Product ID and product revision string. */ 56 char product_and_revision[12]; 57 } usb_massstor_inquiry_result_t; 58 59 int usb_massstor_data_in(usb_device_t *dev, size_t, size_t, 60 uint32_t, uint8_t, void *, size_t, void *, size_t, size_t *); 61 int usb_massstor_reset(usb_device_t *); 62 void usb_massstor_reset_recovery(usb_device_t *, size_t, size_t); 63 int usb_massstor_get_max_lun(usb_device_t *); 64 size_t usb_masstor_get_lun_count(usb_device_t *); 65 int usb_massstor_inquiry(usb_device_t *, size_t, size_t, 66 usb_massstor_inquiry_result_t *); 67 const char *usb_str_masstor_scsi_peripheral_device_type(int); 45 68 46 69 #endif -
uspace/drv/usbmid/Makefile
r456aea3 r9e195e2c 28 28 29 29 USPACE_PREFIX = ../.. 30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a 31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include 30 31 LIBS = \ 32 $(LIBUSBDEV_PREFIX)/libusbdev.a \ 33 $(LIBUSB_PREFIX)/libusb.a \ 34 $(LIBDRV_PREFIX)/libdrv.a 35 EXTRA_CFLAGS += \ 36 -I$(LIBUSB_PREFIX)/include \ 37 -I$(LIBUSBDEV_PREFIX)/include \ 38 -I$(LIBDRV_PREFIX)/include 39 32 40 BINARY = usbmid 33 41 -
uspace/drv/usbmouse/Makefile
r456aea3 r9e195e2c 28 28 29 29 USPACE_PREFIX = ../.. 30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a 31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include -I. 30 31 LIBS = \ 32 $(LIBUSBHID_PREFIX)/libusbhid.a \ 33 $(LIBUSBDEV_PREFIX)/libusbdev.a \ 34 $(LIBUSB_PREFIX)/libusb.a \ 35 $(LIBDRV_PREFIX)/libdrv.a 36 EXTRA_CFLAGS += \ 37 -I$(LIBUSB_PREFIX)/include \ 38 -I$(LIBUSBDEV_PREFIX)/include \ 39 -I$(LIBUSBHID_PREFIX)/include \ 40 -I$(LIBDRV_PREFIX)/include 32 41 33 42 BINARY = usbmouse -
uspace/drv/vhc/Makefile
r456aea3 r9e195e2c 29 29 USPACE_PREFIX = ../.. 30 30 LIBS = \ 31 $(LIBUSBDEV_PREFIX)/libusbdev.a \ 32 $(LIBUSBHOST_PREFIX)/libusbhost.a \ 31 33 $(LIBUSB_PREFIX)/libusb.a \ 32 34 $(LIBUSBVIRT_PREFIX)/libusbvirt.a \ … … 34 36 EXTRA_CFLAGS += \ 35 37 -I$(LIBUSBVIRT_PREFIX)/include \ 38 -I$(LIBUSBDEV_PREFIX)/include \ 39 -I$(LIBUSBHOST_PREFIX)/include \ 36 40 -I$(LIBUSB_PREFIX)/include \ 37 41 -I$(LIBDRV_PREFIX)/include -
uspace/drv/vhc/connhost.c
r456aea3 r9e195e2c 94 94 } 95 95 96 /** Find device handle by address interface function. 97 * 98 * @param[in] fun DDF function that was called. 99 * @param[in] address Address in question. 100 * @param[out] handle Where to store device handle if found. 101 * @return Error code. 102 */ 103 static int find_by_address(ddf_fun_t *fun, usb_address_t address, 104 devman_handle_t *handle) 105 { 106 VHC_DATA(vhc, fun); 107 bool found = 108 usb_device_keeper_find_by_address(&vhc->dev_keeper, address, handle); 109 return found ? EOK : ENOENT; 110 } 111 96 112 /** Release previously requested address. 97 113 * … … 444 460 .request_address = request_address, 445 461 .bind_address = bind_address, 462 .find_by_address = find_by_address, 446 463 .release_address = release_address, 447 464 -
uspace/drv/vhc/main.c
r456aea3 r9e195e2c 104 104 } 105 105 106 ddf_fun_add_to_class(hc, "usbhc"); 106 rc = ddf_fun_add_to_class(hc, USB_HC_DDF_CLASS_NAME); 107 if (rc != EOK) { 108 usb_log_fatal("Failed to add function to HC class: %s.\n", 109 str_error(rc)); 110 free(data); 111 return rc; 112 } 107 113 108 114 virtual_hub_device_init(hc); -
uspace/drv/vhc/transfer.c
r456aea3 r9e195e2c 135 135 if (transfer->direction == USB_DIRECTION_IN) { 136 136 rc = usbvirt_ipc_send_control_read(phone, 137 transfer->endpoint,138 137 transfer->setup_buffer, transfer->setup_buffer_size, 139 138 transfer->data_buffer, transfer->data_buffer_size, … … 142 141 assert(transfer->direction == USB_DIRECTION_OUT); 143 142 rc = usbvirt_ipc_send_control_write(phone, 144 transfer->endpoint,145 143 transfer->setup_buffer, transfer->setup_buffer_size, 146 144 transfer->data_buffer, transfer->data_buffer_size); -
uspace/lib/c/generic/devman.c
r456aea3 r9e195e2c 374 374 } 375 375 376 int devman_get_device_path(devman_handle_t handle, char *path, size_t path_size) 377 { 378 int phone = devman_get_phone(DEVMAN_CLIENT, 0); 379 380 if (phone < 0) 381 return phone; 382 383 async_serialize_start(); 384 385 ipc_call_t answer; 386 aid_t req = async_send_1(phone, DEVMAN_DEVICE_GET_DEVICE_PATH, 387 handle, &answer); 388 389 ipc_call_t data_request_call; 390 aid_t data_request = async_data_read(phone, path, path_size, 391 &data_request_call); 392 if (data_request == 0) { 393 async_wait_for(req, NULL); 394 async_serialize_end(); 395 return ENOMEM; 396 } 397 398 sysarg_t data_request_rc; 399 sysarg_t opening_request_rc; 400 async_wait_for(data_request, &data_request_rc); 401 async_wait_for(req, &opening_request_rc); 402 403 async_serialize_end(); 404 405 if (data_request_rc != EOK) { 406 /* Prefer the return code of the opening request. */ 407 if (opening_request_rc != EOK) { 408 return (int) opening_request_rc; 409 } else { 410 return (int) data_request_rc; 411 } 412 } 413 if (opening_request_rc != EOK) { 414 return (int) opening_request_rc; 415 } 416 417 path[path_size - 1] = 0; 418 419 if (IPC_GET_ARG2(data_request_call) >= path_size) { 420 return ELIMIT; 421 } 422 423 return EOK; 424 } 425 376 426 377 427 /** @} -
uspace/lib/c/include/devman.h
r456aea3 r9e195e2c 55 55 extern int devman_device_get_handle_by_class(const char *, const char *, 56 56 devman_handle_t *, unsigned int); 57 extern int devman_get_device_path(devman_handle_t, char *, size_t); 57 58 58 59 extern int devman_add_device_to_class(devman_handle_t, const char *); -
uspace/lib/c/include/ipc/devman.h
r456aea3 r9e195e2c 149 149 typedef enum { 150 150 DEVMAN_DEVICE_GET_HANDLE = IPC_FIRST_USER_METHOD, 151 DEVMAN_DEVICE_GET_HANDLE_BY_CLASS 151 DEVMAN_DEVICE_GET_HANDLE_BY_CLASS, 152 DEVMAN_DEVICE_GET_DEVICE_PATH 152 153 } client_to_devman_t; 153 154 -
uspace/lib/drv/generic/remote_usbhc.c
r456aea3 r9e195e2c 52 52 static void remote_usbhc_request_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 53 53 static void remote_usbhc_bind_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 54 static void remote_usbhc_find_by_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 54 55 static void remote_usbhc_release_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 55 56 static void remote_usbhc_register_endpoint(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); … … 61 62 remote_usbhc_request_address, 62 63 remote_usbhc_bind_address, 64 remote_usbhc_find_by_address, 63 65 remote_usbhc_release_address, 64 66 … … 163 165 } 164 166 167 void remote_usbhc_find_by_address(ddf_fun_t *fun, void *iface, 168 ipc_callid_t callid, ipc_call_t *call) 169 { 170 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 171 172 if (!usb_iface->find_by_address) { 173 async_answer_0(callid, ENOTSUP); 174 return; 175 } 176 177 usb_address_t address = (usb_address_t) DEV_IPC_GET_ARG1(*call); 178 devman_handle_t handle; 179 int rc = usb_iface->find_by_address(fun, address, &handle); 180 181 if (rc == EOK) { 182 async_answer_1(callid, EOK, handle); 183 } else { 184 async_answer_0(callid, rc); 185 } 186 } 187 165 188 void remote_usbhc_release_address(ddf_fun_t *fun, void *iface, 166 189 ipc_callid_t callid, ipc_call_t *call) … … 302 325 async_transaction_t *trans = async_transaction_create(callid); 303 326 if (trans == NULL) { 327 async_answer_0(data_callid, ENOMEM); 304 328 async_answer_0(callid, ENOMEM); 305 329 return; … … 314 338 315 339 if (rc != EOK) { 340 async_answer_0(data_callid, rc); 316 341 async_answer_0(callid, rc); 317 342 async_transaction_destroy(trans); … … 460 485 async_transaction_t *trans = async_transaction_create(callid); 461 486 if (trans == NULL) { 487 async_answer_0(data_callid, ENOMEM); 462 488 async_answer_0(callid, ENOMEM); 463 489 free(setup_packet); … … 469 495 trans->buffer = malloc(data_len); 470 496 if (trans->buffer == NULL) { 497 async_answer_0(data_callid, ENOMEM); 471 498 async_answer_0(callid, ENOMEM); 472 499 async_transaction_destroy(trans); … … 480 507 481 508 if (rc != EOK) { 509 async_answer_0(data_callid, rc); 482 510 async_answer_0(callid, rc); 483 511 async_transaction_destroy(trans); -
uspace/lib/drv/include/usb_iface.h
r456aea3 r9e195e2c 49 49 * - arbitrary error code if returned by remote implementation 50 50 * - EOK - handle found, first parameter contains the USB address 51 * 52 * The handle must be the one used for binding USB address with 53 * it (IPC_M_USBHC_BIND_ADDRESS), otherwise the host controller 54 * (that this request would eventually reach) would not be able 55 * to find it. 56 * The problem is that this handle is actually assigned to the 57 * function inside driver of the parent device (usually hub driver). 58 * To bypass this problem, the initial caller specify handle as 59 * zero and the first parent assigns the actual value. 60 * See usb_iface_get_address_hub_child_impl() implementation 61 * that could be assigned to device ops of a child device of in a 62 * hub driver. 63 * For example, the USB multi interface device driver (MID) 64 * passes this initial zero without any modification because the 65 * handle must be resolved by its parent. 51 66 */ 52 67 IPC_M_USB_GET_ADDRESS, -
uspace/lib/drv/include/usbhc_iface.h
r456aea3 r9e195e2c 105 105 IPC_M_USBHC_BIND_ADDRESS, 106 106 107 /** Get handle binded with given USB address. 108 * Parameters 109 * - USB address 110 * Answer: 111 * - EOK - address binded, first parameter is the devman handle 112 * - ENOENT - address is not in use at the moment 113 */ 114 IPC_M_USBHC_GET_HANDLE_BY_ADDRESS, 115 107 116 /** Release address in use. 108 117 * Arguments: … … 207 216 int (*request_address)(ddf_fun_t *, usb_speed_t, usb_address_t *); 208 217 int (*bind_address)(ddf_fun_t *, usb_address_t, devman_handle_t); 218 int (*find_by_address)(ddf_fun_t *, usb_address_t, devman_handle_t *); 209 219 int (*release_address)(ddf_fun_t *, usb_address_t); 210 220 -
uspace/lib/usb/Makefile
r456aea3 r9e195e2c 29 29 USPACE_PREFIX = ../.. 30 30 LIBRARY = libusb 31 LIBS = $(LIBDRV_PREFIX)/libdrv.a 32 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -Iinclude 31 EXTRA_CFLAGS += \ 32 -I$(LIBDRV_PREFIX)/include \ 33 -Iinclude 33 34 34 35 SOURCES = \ 35 src/addrkeep.c \36 src/altiface.c \37 36 src/class.c \ 38 37 src/ddfiface.c \ 39 38 src/debug.c \ 40 src/devdrv.c \ 41 src/devpoll.c \ 42 src/dp.c \ 39 src/driver.c \ 43 40 src/dump.c \ 44 src/hidiface.c \ 45 src/hidpath.c \ 46 src/hidparser.c \ 47 src/hiddescriptor.c \ 48 src/hub.c \ 49 src/pipepriv.c \ 50 src/pipes.c \ 51 src/pipesinit.c \ 52 src/pipesio.c \ 53 src/recognise.c \ 54 src/request.c \ 55 src/usb.c \ 56 src/usbdevice.c \ 57 src/hidreq.c \ 58 src/hidreport.c \ 59 src/host/device_keeper.c \ 60 src/host/batch.c \ 61 src/host/endpoint.c \ 62 src/host/usb_endpoint_manager.c 41 src/host.c \ 42 src/usb.c 63 43 64 44 include $(USPACE_PREFIX)/Makefile.common -
uspace/lib/usb/include/usb/ddfiface.h
r456aea3 r9e195e2c 37 37 38 38 #include <sys/types.h> 39 #include <usb/usbdevice.h>40 39 #include <usb_iface.h> 41 40 -
uspace/lib/usb/include/usb/descriptor.h
r456aea3 r9e195e2c 167 167 } __attribute__ ((packed)) usb_standard_endpoint_descriptor_t; 168 168 169 /** Part of standard USB HID descriptor specifying one class descriptor. 170 * 171 * (See HID Specification, p.22) 172 */ 173 typedef struct { 174 /** Type of class-specific descriptor (Report or Physical). */ 175 uint8_t type; 176 /** Length of class-specific descriptor in bytes. */ 177 uint16_t length; 178 } __attribute__ ((packed)) usb_standard_hid_class_descriptor_info_t; 179 180 /** Standard USB HID descriptor. 181 * 182 * (See HID Specification, p.22) 183 * 184 * It is actually only the "header" of the descriptor, it does not contain 185 * the last two mandatory fields (type and length of the first class-specific 186 * descriptor). 187 */ 188 typedef struct { 189 /** Total size of this descriptor in bytes. 190 * 191 * This includes all class-specific descriptor info - type + length 192 * for each descriptor. 193 */ 194 uint8_t length; 195 /** Descriptor type (USB_DESCTYPE_HID). */ 196 uint8_t descriptor_type; 197 /** HID Class Specification release. */ 198 uint16_t spec_release; 199 /** Country code of localized hardware. */ 200 uint8_t country_code; 201 /** Total number of class-specific (i.e. Report and Physical) 202 * descriptors. 203 * 204 * @note There is always only one Report descriptor. 205 */ 206 uint8_t class_desc_count; 207 /** First mandatory class descriptor (Report) info. */ 208 usb_standard_hid_class_descriptor_info_t report_desc_info; 209 } __attribute__ ((packed)) usb_standard_hid_descriptor_t; 210 169 211 #endif 170 212 /** -
uspace/lib/usb/include/usb/usb.h
r456aea3 r9e195e2c 172 172 } usb_packet_id; 173 173 174 /** Class name for USB host controllers. */ 175 #define USB_HC_DDF_CLASS_NAME "usbhc" 176 174 177 #endif 175 178 /** -
uspace/lib/usb/src/ddfiface.c
r456aea3 r9e195e2c 37 37 #include <async.h> 38 38 #include <usb/ddfiface.h> 39 #include <usb/driver.h> 39 40 #include <usb/debug.h> 40 41 #include <errno.h> -
uspace/lib/usb/src/dump.c
r456aea3 r9e195e2c 41 41 #include <usb/descriptor.h> 42 42 #include <usb/classes/classes.h> 43 #include <usb/classes/hid.h>44 43 45 44 /** Mapping between descriptor id and dumping function. */ -
uspace/lib/usbvirt/Makefile
r456aea3 r9e195e2c 30 30 LIBRARY = libusbvirt 31 31 32 EXTRA_CFLAGS = -I$(LIBUSB_PREFIX)/include -I$(LIBDRV_PREFIX)/include -Iinclude 32 EXTRA_CFLAGS = \ 33 -I$(LIBDRV_PREFIX)/include \ 34 -I$(LIBUSB_PREFIX)/include \ 35 -I$(LIBUSBDEV_PREFIX)/include \ 36 -Iinclude 33 37 34 38 SOURCES = \ 35 src/ipc.c \36 39 src/ctrltransfer.c \ 40 src/device.c \ 41 src/ipc_dev.c \ 42 src/ipc_hc.c \ 37 43 src/stdreq.c \ 38 44 src/transfer.c -
uspace/lib/usbvirt/include/usbvirt/device.h
r456aea3 r9e195e2c 31 31 */ 32 32 /** @file 33 * @briefVirtual USB device.33 * Virtual USB device. 34 34 */ 35 35 #ifndef LIBUSBVIRT_DEVICE_H_ … … 39 39 #include <usb/request.h> 40 40 41 /** Maximum number of endpoints supported by virtual USB. */ 41 42 #define USBVIRT_ENDPOINT_MAX 16 42 43 43 44 typedef struct usbvirt_device usbvirt_device_t; 44 45 45 typedef int (*usbvirt_on_data_to_device_t)(usbvirt_device_t *, usb_endpoint_t, 46 usb_transfer_type_t, void *, size_t); 47 typedef int (*usbvirt_on_data_from_device_t)(usbvirt_device_t *, usb_endpoint_t, 48 usb_transfer_type_t, void *, size_t, size_t *); 49 typedef int (*usbvirt_on_control_t)(usbvirt_device_t *, 50 const usb_device_request_setup_packet_t *, uint8_t *, size_t *); 51 52 typedef struct { 46 /** Callback for data to device (OUT transaction). 47 * 48 * @param dev Virtual device to which the transaction belongs. 49 * @param endpoint Target endpoint number. 50 * @param transfer_type Transfer type. 51 * @param buffer Data buffer. 52 * @param buffer_size Size of the buffer in bytes. 53 * @return Error code. 54 */ 55 typedef int (*usbvirt_on_data_to_device_t)(usbvirt_device_t *dev, 56 usb_endpoint_t endpoint, usb_transfer_type_t transfer_type, 57 void *buffer, size_t buffer_size); 58 59 /** Callback for data from device (IN transaction). 60 * 61 * @param dev Virtual device to which the transaction belongs. 62 * @param endpoint Target endpoint number. 63 * @param transfer_type Transfer type. 64 * @param buffer Data buffer to write answer to. 65 * @param buffer_size Size of the buffer in bytes. 66 * @param act_buffer_size Write here how many bytes were actually written. 67 * @return Error code. 68 */ 69 typedef int (*usbvirt_on_data_from_device_t)(usbvirt_device_t *dev, 70 usb_endpoint_t endpoint, usb_transfer_type_t transfer_type, 71 void *buffer, size_t buffer_size, size_t *act_buffer_size); 72 73 /** Callback for control transfer on endpoint zero. 74 * 75 * Notice that size of the data buffer is expected to be read from the 76 * setup packet. 77 * 78 * @param dev Virtual device to which the transaction belongs. 79 * @param setup_packet Standard setup packet. 80 * @param data Data (might be NULL). 81 * @param act_data_size Size of returned data in bytes. 82 * @return Error code. 83 */ 84 typedef int (*usbvirt_on_control_t)(usbvirt_device_t *dev, 85 const usb_device_request_setup_packet_t *setup_packet, 86 uint8_t *data, size_t *act_data_size); 87 88 /** Callback for control request on a virtual USB device. 89 * 90 * See usbvirt_control_reply_helper() for simple way of answering 91 * control read requests. 92 */ 93 typedef struct { 94 /** Request direction (in or out). */ 53 95 usb_direction_t req_direction; 96 /** Request recipient (device, interface or endpoint). */ 54 97 usb_request_recipient_t req_recipient; 98 /** Request type (standard, class or vendor). */ 55 99 usb_request_type_t req_type; 100 /** Actual request code. */ 56 101 uint8_t request; 102 /** Request handler name for debugging purposes. */ 57 103 const char *name; 104 /** Callback to be executed on matching request. */ 58 105 usbvirt_on_control_t callback; 59 106 } usbvirt_control_request_handler_t; … … 77 124 } usbvirt_device_configuration_t; 78 125 79 /** Standard USB descriptors . */126 /** Standard USB descriptors for virtual device. */ 80 127 typedef struct { 81 128 /** Standard device descriptor. … … 102 149 } usbvirt_device_state_t; 103 150 104 typedef struct { 151 /** Ops structure for virtual USB device. */ 152 typedef struct { 153 /** Callbacks for data to device. 154 * Index zero is ignored. 155 */ 105 156 usbvirt_on_data_to_device_t data_out[USBVIRT_ENDPOINT_MAX]; 157 /** Callbacks for data from device. 158 * Index zero is ignored. 159 */ 106 160 usbvirt_on_data_from_device_t data_in[USBVIRT_ENDPOINT_MAX]; 161 /** Array of control handlers. 162 * Last handler is expected to have the @c callback field set to NULL 163 */ 107 164 usbvirt_control_request_handler_t *control; 165 /** Callback when device changes state. 166 * 167 * The value of @c state attribute of @p dev device is not 168 * defined during call of this function. 169 * 170 * @param dev The virtual USB device. 171 * @param old_state Old device state. 172 * @param new_state New device state. 173 */ 108 174 void (*state_changed)(usbvirt_device_t *dev, 109 175 usbvirt_device_state_t old_state, usbvirt_device_state_t new_state); 110 176 } usbvirt_device_ops_t; 111 177 178 /** Virtual USB device. */ 112 179 struct usbvirt_device { 180 /** Name for debugging purposes. */ 113 181 const char *name; 182 /** Custom device data. */ 114 183 void *device_data; 184 /** Device ops. */ 115 185 usbvirt_device_ops_t *ops; 186 /** Device descriptors. */ 116 187 usbvirt_descriptors_t *descriptors; 188 /** Current device address. 189 * You shall treat this field as read only in your code. 190 */ 117 191 usb_address_t address; 192 /** Current device state. 193 * You shall treat this field as read only in your code. 194 */ 118 195 usbvirt_device_state_t state; 196 /** Phone to the host controller. 197 * You shall treat this field as read only in your code. 198 */ 199 int vhc_phone; 119 200 }; 120 201 121 202 int usbvirt_device_plug(usbvirt_device_t *, const char *); 203 void usbvirt_device_unplug(usbvirt_device_t *); 122 204 123 205 void usbvirt_control_reply_helper(const usb_device_request_setup_packet_t *, -
uspace/lib/usbvirt/include/usbvirt/ipc.h
r456aea3 r9e195e2c 1 1 /* 2 * Copyright (c) 201 0Vojtech Horky2 * Copyright (c) 2011 Vojtech Horky 3 3 * All rights reserved. 4 4 * … … 31 31 */ 32 32 /** @file 33 * @brief Virtual USB device.33 * IPC wrappers for virtual USB. 34 34 */ 35 35 #ifndef LIBUSBVIRT_IPC_H_ … … 40 40 #include <bool.h> 41 41 42 /** IPC methods communication between host controller and virtual device. */ 42 43 typedef enum { 43 44 IPC_M_USBVIRT_GET_NAME = IPC_FIRST_USER_METHOD + 80, … … 45 46 IPC_M_USBVIRT_CONTROL_WRITE, 46 47 IPC_M_USBVIRT_INTERRUPT_IN, 47 IPC_M_USBVIRT_INTERRUPT_OUT 48 } usbvirt_ipc_t; 48 IPC_M_USBVIRT_INTERRUPT_OUT, 49 IPC_M_USBVIRT_BULK_IN, 50 IPC_M_USBVIRT_BULK_OUT 51 } usbvirt_hc_to_device_method_t; 49 52 50 int usbvirt_ipc_send_control_read(int, usb_endpoint_t,void *, size_t,53 int usbvirt_ipc_send_control_read(int, void *, size_t, 51 54 void *, size_t, size_t *); 52 int usbvirt_ipc_send_control_write(int, usb_endpoint_t,void *, size_t,55 int usbvirt_ipc_send_control_write(int, void *, size_t, 53 56 void *, size_t); 54 57 int usbvirt_ipc_send_data_in(int, usb_endpoint_t, usb_transfer_type_t, -
uspace/lib/usbvirt/src/ctrltransfer.c
r456aea3 r9e195e2c 1 /* 2 * Copyright (c) 2011 Vojtech Horky 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * - Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * - Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * - The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /** @addtogroup libusbvirt 30 * @{ 31 */ 32 /** @file 33 * Control transfer handling. 34 */ 1 35 #include "private.h" 2 36 #include <usb/request.h> … … 5 39 #include <errno.h> 6 40 41 /** Find and execute control transfer handler for virtual USB device. 42 * 43 * @param dev Target virtual device. 44 * @param control_handlers Array of control request handlers. 45 * @param setup Setup packet. 46 * @param data Extra data. 47 * @param data_sent_size Size of extra data in bytes. 48 * @return Error code. 49 * @retval EFORWARD No suitable handler found. 50 */ 7 51 int process_control_transfer(usbvirt_device_t *dev, 8 52 usbvirt_control_request_handler_t *control_handlers, … … 52 96 return EFORWARD; 53 97 } 98 99 100 /** 101 * @} 102 */ -
uspace/lib/usbvirt/src/private.h
r456aea3 r9e195e2c 1 /* 2 * Copyright (c) 2011 Vojtech Horky 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * - Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * - Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * - The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /** @addtogroup libusbvirt 30 * @{ 31 */ 32 /** @file 33 * Private definitions. 34 */ 35 #ifndef USBVIRT_PRIVATE_H_ 36 #define USBVIRT_PRIVATE_H_ 37 1 38 #include <usbvirt/device.h> 2 39 … … 7 44 8 45 extern usbvirt_control_request_handler_t library_handlers[]; 46 47 #endif 48 /** 49 * @} 50 */ -
uspace/lib/usbvirt/src/stdreq.c
r456aea3 r9e195e2c 1 /* 2 * Copyright (c) 2011 Vojtech Horky 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * - Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * - Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * - The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /** @addtogroup libusbvirt 30 * @{ 31 */ 32 /** @file 33 * Standard control request handlers. 34 */ 1 35 #include "private.h" 2 36 #include <usb/request.h> … … 4 38 #include <errno.h> 5 39 40 /** Helper for replying to control read transfer from virtual USB device. 41 * 42 * This function takes care of copying data to answer buffer taking care 43 * of buffer sizes properly. 44 * 45 * @param setup_packet The setup packet. 46 * @param data Data buffer to write to. 47 * @param act_size Where to write actual size of returned data. 48 * @param actual_data Data to be returned. 49 * @param actual_data_size Size of answer data (@p actual_data) in bytes. 50 */ 6 51 void usbvirt_control_reply_helper(const usb_device_request_setup_packet_t *setup_packet, 7 52 uint8_t *data, size_t *act_size, … … 144 189 } 145 190 191 /** Standard request handlers. */ 146 192 usbvirt_control_request_handler_t library_handlers[] = { 147 193 { … … 173 219 }; 174 220 221 /** 222 * @} 223 */ -
uspace/lib/usbvirt/src/transfer.c
r456aea3 r9e195e2c 31 31 */ 32 32 /** @file 33 * 33 * Transfer handling. 34 34 */ 35 35 #include <usbvirt/device.h> … … 39 39 #include "private.h" 40 40 41 /** Process a control transfer to the virtual USB device. 42 * 43 * @param dev Target device. 44 * @param setup Setup packet data. 45 * @param setup_size Size of setup packet. 46 * @param data Extra data (DATA stage). 47 * @param data_size Size of extra data in bytes. 48 * @param data_size_sent Number of actually send bytes during the transfer 49 * (only used for READ transfers). 50 * @return Error code. 51 */ 41 52 static int usbvirt_control_transfer(usbvirt_device_t *dev, 42 53 void *setup, size_t setup_size, … … 78 89 } 79 90 91 /** Issue a control write transfer to virtual USB device. 92 * 93 * @see usbvirt_control_transfer 94 * 95 * @param dev Target virtual device. 96 * @param setup Setup data. 97 * @param setup_size Size of setup packet. 98 * @param data Extra data (DATA stage). 99 * @param data_size Size of extra data buffer in bytes. 100 * @return Error code. 101 */ 80 102 int usbvirt_control_write(usbvirt_device_t *dev, void *setup, size_t setup_size, 81 103 void *data, size_t data_size) … … 85 107 } 86 108 109 /** Issue a control read transfer to virtual USB device. 110 * 111 * @see usbvirt_control_transfer 112 * 113 * @param dev Target virtual device. 114 * @param setup Setup data. 115 * @param setup_size Size of setup packet. 116 * @param data Extra data (DATA stage). 117 * @param data_size Size of extra data buffer in bytes. 118 * @param data_size_sent Number of actually send bytes during the transfer. 119 * @return Error code. 120 */ 87 121 int usbvirt_control_read(usbvirt_device_t *dev, void *setup, size_t setup_size, 88 122 void *data, size_t data_size, size_t *data_size_sent) … … 92 126 } 93 127 128 /** Send data to virtual USB device. 129 * 130 * @param dev Target virtual device. 131 * @param transf_type Transfer type (interrupt, bulk). 132 * @param endpoint Endpoint number. 133 * @param data Data sent from the driver to the device. 134 * @param data_size Size of the @p data buffer in bytes. 135 * @return Error code. 136 */ 94 137 int usbvirt_data_out(usbvirt_device_t *dev, usb_transfer_type_t transf_type, 95 138 usb_endpoint_t endpoint, void *data, size_t data_size) … … 108 151 } 109 152 153 /** Request data from virtual USB device. 154 * 155 * @param dev Target virtual device. 156 * @param transf_type Transfer type (interrupt, bulk). 157 * @param endpoint Endpoint number. 158 * @param data Where to stored data the device returns to the driver. 159 * @param data_size Size of the @p data buffer in bytes. 160 * @param data_size_sent Number of actually written bytes. 161 * @return Error code. 162 */ 110 163 int usbvirt_data_in(usbvirt_device_t *dev, usb_transfer_type_t transf_type, 111 164 usb_endpoint_t endpoint, void *data, size_t data_size, size_t *data_size_sent) -
uspace/srv/devman/main.c
r456aea3 r9e195e2c 515 515 } 516 516 517 /** Find device path by its handle. */ 518 static void devman_get_device_path_by_handle(ipc_callid_t iid, 519 ipc_call_t *icall) 520 { 521 devman_handle_t handle = IPC_GET_ARG1(*icall); 522 523 fun_node_t *fun = find_fun_node(&device_tree, handle); 524 if (fun == NULL) { 525 async_answer_0(iid, ENOMEM); 526 return; 527 } 528 529 ipc_callid_t data_callid; 530 size_t data_len; 531 if (!async_data_read_receive(&data_callid, &data_len)) { 532 async_answer_0(iid, EINVAL); 533 return; 534 } 535 536 void *buffer = malloc(data_len); 537 if (buffer == NULL) { 538 async_answer_0(data_callid, ENOMEM); 539 async_answer_0(iid, ENOMEM); 540 return; 541 } 542 543 size_t sent_length = str_size(fun->pathname); 544 if (sent_length > data_len) { 545 sent_length = data_len; 546 } 547 548 async_data_read_finalize(data_callid, fun->pathname, sent_length); 549 async_answer_0(iid, EOK); 550 551 free(buffer); 552 } 553 517 554 518 555 /** Function for handling connections from a client to the device manager. */ … … 536 573 case DEVMAN_DEVICE_GET_HANDLE_BY_CLASS: 537 574 devman_function_get_handle_by_class(callid, &call); 575 break; 576 case DEVMAN_DEVICE_GET_DEVICE_PATH: 577 devman_get_device_path_by_handle(callid, &call); 538 578 break; 539 579 default:
Note:
See TracChangeset
for help on using the changeset viewer.