Changes in / [291b8bc:889e8e3] in mainline
- Files:
-
- 17 added
- 19 deleted
- 28 edited
Legend:
- Unmodified
- Added
- Removed
-
boot/arch/amd64/Makefile.inc
r291b8bc r889e8e3 49 49 usbflbk \ 50 50 usbhub \ 51 usb kbd \51 usbhid \ 52 52 usbmid \ 53 53 usbmouse \ -
kernel/generic/src/console/console.c
r291b8bc r889e8e3 53 53 #include <str.h> 54 54 55 /*56 * devman produces a lot of output and by giving so many pages57 * we to allow /app/klog to catch-up.58 */59 #ifdef CONFIG_DEVMAN_EARLY_LAUNCH60 #define KLOG_PAGES 6461 #else62 55 #define KLOG_PAGES 4 63 #endif64 65 56 #define KLOG_LENGTH (KLOG_PAGES * PAGE_SIZE / sizeof(wchar_t)) 66 57 #define KLOG_LATENCY 8 -
kernel/generic/src/mm/as.c
r291b8bc r889e8e3 1949 1949 sysarg_t sys_as_area_create(uintptr_t address, size_t size, unsigned int flags) 1950 1950 { 1951 if (as_area_create(AS, flags , size, address,1951 if (as_area_create(AS, flags | AS_AREA_CACHEABLE, size, address, 1952 1952 AS_AREA_ATTR_NONE, &anon_backend, NULL)) 1953 1953 return (sysarg_t) address; -
uspace/Makefile
r291b8bc r889e8e3 122 122 drv/uhci-rhd \ 123 123 drv/usbflbk \ 124 drv/usb kbd \124 drv/usbhid \ 125 125 drv/usbhub \ 126 126 drv/usbmid \ … … 142 142 drv/uhci-rhd \ 143 143 drv/usbflbk \ 144 drv/usb kbd \144 drv/usbhid \ 145 145 drv/usbhub \ 146 146 drv/usbmid \ -
uspace/app/init/init.c
r291b8bc r889e8e3 288 288 289 289 spawn("/srv/clip"); 290 291 #ifdef CONFIG_DEVMAN_EARLY_LAUNCH 292 spawn("/srv/devman"); 293 #endif 290 294 291 295 /* … … 314 318 getterm("term/vc6", "/app/klog", false); 315 319 316 #ifdef CONFIG_DEVMAN_EARLY_LAUNCH 317 spawn("/srv/devman"); 318 #else 320 #ifndef CONFIG_DEVMAN_EARLY_LAUNCH 319 321 getterm("term/vc7", "/srv/devman", false); 320 322 #endif -
uspace/drv/ohci/Makefile
r291b8bc r889e8e3 37 37 main.c \ 38 38 hc.c \ 39 ohci.c \40 39 root_hub.c \ 41 40 pci.c -
uspace/drv/ohci/batch.c
r291b8bc r889e8e3 118 118 instance->next_step = batch_call_in_and_dispose; 119 119 /* TODO: implement */ 120 usb_log_debug("Batch(%p) CONTROL READinitialized.\n", instance);120 usb_log_debug("Batch(%p) CONTROL WRITE initialized.\n", instance); 121 121 } 122 122 /*----------------------------------------------------------------------------*/ -
uspace/drv/ohci/hc.c
r291b8bc r889e8e3 39 39 #include <usb/debug.h> 40 40 #include <usb/usb.h> 41 #include <usb/hub.h> 41 42 #include <usb/ddfiface.h> 42 43 #include <usb/usbdevice.h> … … 44 45 #include "hc.h" 45 46 47 static int dummy_reset(int foo, void *arg); 46 48 static int interrupt_emulator(hc_t *instance); 47 /*----------------------------------------------------------------------------*/48 int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun)49 {50 assert(instance);51 assert(hub_fun);52 53 usb_address_t hub_address =54 device_keeper_get_free_address(&instance->manager, USB_SPEED_FULL);55 instance->rh.address = hub_address;56 usb_device_keeper_bind(57 &instance->manager, hub_address, hub_fun->handle);58 59 char *match_str = NULL;60 int ret = asprintf(&match_str, "usb&mid");61 ret = (match_str == NULL) ? ret : EOK;62 if (ret < 0) {63 usb_log_error("Failed to create root hub match-id string.\n");64 return ret;65 }66 67 ret = ddf_fun_add_match_id(hub_fun, match_str, 100);68 if (ret != EOK) {69 usb_log_error("Failed add create root hub match-id.\n");70 }71 return ret;72 }73 49 /*----------------------------------------------------------------------------*/ 74 50 int hc_init(hc_t *instance, ddf_fun_t *fun, ddf_dev_t *dev, … … 92 68 } 93 69 70 94 71 rh_init(&instance->rh, dev, instance->registers); 72 /* TODO: implement */ 73 return EOK; 74 } 75 /*----------------------------------------------------------------------------*/ 76 int hc_register_hub(hc_t *instance) 77 { 78 async_usleep(1000000); 79 #define CHECK_RET_RETURN(ret, msg...) \ 80 if (ret != EOK) { \ 81 usb_log_error(msg); \ 82 return ret; \ 83 } else (void)0 84 assert(instance); 85 assert(instance->ddf_instance); 86 assert(instance->ddf_instance->handle); 87 ddf_dev_t *dev = instance->rh.device; 88 int ret = EOK; 95 89 96 /* TODO: implement */ 90 usb_hc_connection_t conn; 91 ret = 92 usb_hc_connection_initialize(&conn, instance->ddf_instance->handle); 93 CHECK_RET_RETURN(ret, "Failed to initialize hc connection.\n"); 94 95 ret = usb_hc_connection_open(&conn); 96 CHECK_RET_RETURN(ret, "Failed to open hc connection.\n"); 97 98 usb_address_t address; 99 devman_handle_t handle; 100 ret = usb_hc_new_device_wrapper(dev, &conn, USB_SPEED_FULL, dummy_reset, 101 0, instance, &address, &handle, NULL, NULL, NULL); 102 if (ret != EOK) { 103 usb_log_error("Failed to add rh device.\n"); 104 instance->rh.address = -1; 105 return ret; 106 } 107 108 ret = usb_hc_connection_close(&conn); 109 CHECK_RET_RETURN(ret, "Failed to close hc connection.\n"); 97 110 return EOK; 98 111 } … … 121 134 } 122 135 /*----------------------------------------------------------------------------*/ 123 int interrupt_emulator(hc_t *instance) 136 static int dummy_reset(int foo, void *arg) 137 { 138 hc_t *hc = (hc_t*)arg; 139 assert(hc); 140 hc->rh.address = 0; 141 return EOK; 142 } 143 /*----------------------------------------------------------------------------*/ 144 static int interrupt_emulator(hc_t *instance) 124 145 { 125 146 assert(instance); -
uspace/drv/ohci/hc.h
r291b8bc r889e8e3 57 57 } hc_t; 58 58 59 int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun);60 61 59 int hc_init(hc_t *instance, ddf_fun_t *fun, ddf_dev_t *dev, 62 60 uintptr_t regs, size_t reg_size, bool interrupts); 61 62 int hc_register_hub(hc_t *instance); 63 63 64 64 int hc_schedule(hc_t *instance, usb_transfer_batch_t *batch); -
uspace/drv/ohci/iface.h
r291b8bc r889e8e3 33 33 * Common OHCI definitions. 34 34 */ 35 #ifndef DRV_OHCI_ IFACE_H36 #define DRV_OHCI_ IFACE_H35 #ifndef DRV_OHCI_OHCI_H 36 #define DRV_OHCI_OHCI_H 37 37 38 38 #include <usbhc_iface.h> 39 40 #define NAME "ohci" 39 41 40 42 extern usbhc_iface_t hc_iface; -
uspace/drv/ohci/main.c
r291b8bc r889e8e3 34 34 */ 35 35 #include <ddf/driver.h> 36 #include <ddf/interrupt.h> 37 #include <device/hw_res.h> 36 38 #include <errno.h> 37 39 #include <str_error.h> 38 40 41 #include <usb_iface.h> 42 #include <usb/ddfiface.h> 39 43 #include <usb/debug.h> 40 44 41 #include " ohci.h"42 43 # define NAME "ohci"45 #include "pci.h" 46 #include "iface.h" 47 #include "hc.h" 44 48 45 49 static int ohci_add_device(ddf_dev_t *device); 50 static int get_hc_handle(ddf_fun_t *fun, devman_handle_t *handle) 51 { 52 assert(handle); 53 assert(fun != NULL); 54 55 *handle = fun->handle; 56 return EOK; 57 } 58 /*----------------------------------------------------------------------------*/ 59 static int get_address( 60 ddf_fun_t *fun, devman_handle_t handle, usb_address_t *address) 61 { 62 assert(fun); 63 usb_device_keeper_t *manager = &fun_to_hc(fun)->manager; 64 usb_address_t addr = usb_device_keeper_find(manager, handle); 65 if (addr < 0) { 66 return addr; 67 } 68 69 if (address != NULL) { 70 *address = addr; 71 } 72 73 return EOK; 74 } 75 /*----------------------------------------------------------------------------*/ 76 /** IRQ handling callback, identifies device 77 * 78 * @param[in] dev DDF instance of the device to use. 79 * @param[in] iid (Unused). 80 * @param[in] call Pointer to the call that represents interrupt. 81 */ 82 static void irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call) 83 { 84 assert(dev); 85 hc_t *hc = (hc_t*)dev->driver_data; 86 assert(hc); 87 hc_interrupt(hc, 0); 88 } 46 89 /*----------------------------------------------------------------------------*/ 47 90 static driver_ops_t ohci_driver_ops = { … … 54 97 }; 55 98 /*----------------------------------------------------------------------------*/ 99 static usb_iface_t hc_usb_iface = { 100 .get_address = get_address, 101 .get_hc_handle = get_hc_handle, 102 }; 103 /*----------------------------------------------------------------------------*/ 104 static ddf_dev_ops_t hc_ops = { 105 .interfaces[USB_DEV_IFACE] = &hc_usb_iface, 106 .interfaces[USBHC_DEV_IFACE] = &hc_iface, 107 }; 108 /*----------------------------------------------------------------------------*/ 56 109 /** Initializes a new ddf driver instance of OHCI hcd. 57 110 * … … 59 112 * @return Error code. 60 113 */ 61 int ohci_add_device(ddf_dev_t *device) 62 { 63 usb_log_debug("ohci_add_device() called\n"); 114 static int ohci_add_device(ddf_dev_t *device) 115 { 64 116 assert(device); 65 ohci_t *ohci = malloc(sizeof(ohci_t)); 66 if (ohci == NULL) { 117 #define CHECK_RET_RETURN(ret, message...) \ 118 if (ret != EOK) { \ 119 usb_log_error(message); \ 120 return ret; \ 121 } 122 123 uintptr_t mem_reg_base = 0; 124 size_t mem_reg_size = 0; 125 int irq = 0; 126 127 int ret = 128 pci_get_my_registers(device, &mem_reg_base, &mem_reg_size, &irq); 129 CHECK_RET_RETURN(ret, 130 "Failed(%d) to get memory addresses:.\n", ret, device->handle); 131 usb_log_info("Memory mapped regs at 0x%X (size %zu), IRQ %d.\n", 132 mem_reg_base, mem_reg_size, irq); 133 134 ret = pci_disable_legacy(device); 135 CHECK_RET_RETURN(ret, 136 "Failed(%d) disable legacy USB: %s.\n", ret, str_error(ret)); 137 138 hc_t *hcd = malloc(sizeof(hc_t)); 139 if (hcd == NULL) { 67 140 usb_log_error("Failed to allocate OHCI driver.\n"); 68 141 return ENOMEM; 69 142 } 70 143 71 int ret = ohci_init(ohci, device); 144 ddf_fun_t *hc_fun = ddf_fun_create(device, fun_exposed, "ohci-hc"); 145 if (hc_fun == NULL) { 146 usb_log_error("Failed to create OHCI function.\n"); 147 free(hcd); 148 return ENOMEM; 149 } 150 151 152 bool interrupts = false; 153 #ifdef CONFIG_USBHC_NO_INTERRUPTS 154 usb_log_warning("Interrupts disabled in OS config, " \ 155 "falling back to polling.\n"); 156 #else 157 ret = pci_enable_interrupts(device); 72 158 if (ret != EOK) { 73 usb_log_ error("Failed to initialize OHCI driver: %s.\n",159 usb_log_warning("Failed to enable interrupts: %s.\n", 74 160 str_error(ret)); 161 usb_log_info("HW interrupts not available, " \ 162 "falling back to polling.\n"); 163 } else { 164 usb_log_debug("Hw interrupts enabled.\n"); 165 interrupts = true; 166 } 167 #endif 168 169 ret = hc_init(hcd, hc_fun, device, mem_reg_base, mem_reg_size, interrupts); 170 if (ret != EOK) { 171 usb_log_error("Failed to initialize OHCI driver.\n"); 172 free(hcd); 75 173 return ret; 76 174 } 77 device->driver_data = ohci; 78 79 usb_log_info("Controlling new OHCI device `%s'.\n", device->name); 175 176 ret = register_interrupt_handler(device, irq, irq_handler, NULL); 177 178 hc_fun->ops = &hc_ops; 179 ret = ddf_fun_bind(hc_fun); 180 if (ret != EOK) { 181 usb_log_error("Failed to bind OHCI function.\n"); 182 ddf_fun_destroy(hc_fun); 183 free(hcd); 184 return ret; 185 } 186 hc_fun->driver_data = hcd; 187 188 fid_t later = fibril_create((int(*)(void*))hc_register_hub, hcd); 189 fibril_add_ready(later); 190 191 usb_log_info("Controlling new OHCI device `%s' (handle %llu).\n", 192 device->name, device->handle); 80 193 81 194 return EOK; 195 #undef CHECK_RET_RETURN 82 196 } 83 197 /*----------------------------------------------------------------------------*/ -
uspace/drv/ohci/root_hub.c
r291b8bc r889e8e3 39 39 40 40 #include "root_hub.h" 41 #include "usb/classes/classes.h"42 #include <usb/request.h>43 #include <usb/classes/hub.h>44 45 static const usb_standard_device_descriptor_t ohci_rh_device_descriptor =46 {47 .configuration_count = 1,48 .descriptor_type = USB_DESCTYPE_DEVICE,49 .device_class = USB_CLASS_HUB,50 .device_protocol = 0,51 .device_subclass = 0,52 .device_version = 0,53 .length = sizeof(usb_standard_device_descriptor_t),54 /// \TODO this value is guessed55 .max_packet_size = 8,56 .vendor_id = 0x16db,57 .product_id = 0x0001,58 /// \TODO these values migt be different59 .str_serial_number = 0,60 .usb_spec_version = 0,61 };62 63 static const usb_standard_configuration_descriptor_t ohci_rh_conf_descriptor =64 {65 /// \TODO some values are default or guessed66 .attributes = 1<<7,67 .configuration_number = 1,68 .descriptor_type = USB_DESCTYPE_CONFIGURATION,69 .interface_count = 1,70 .length = sizeof(usb_standard_configuration_descriptor_t),71 .max_power = 100,72 .str_configuration = 0,73 };74 75 static const usb_standard_interface_descriptor_t ohci_rh_iface_descriptor =76 {77 .alternate_setting = 0,78 .descriptor_type = USB_DESCTYPE_INTERFACE,79 .endpoint_count = 1,80 .interface_class = USB_CLASS_HUB,81 /// \TODO is this correct?82 .interface_number = 1,83 .interface_protocol = 0,84 .interface_subclass = 0,85 .length = sizeof(usb_standard_interface_descriptor_t),86 .str_interface = 0,87 };88 89 static const usb_standard_endpoint_descriptor_t ohci_rh_ep_descriptor =90 {91 .attributes = USB_TRANSFER_INTERRUPT,92 .descriptor_type = USB_DESCTYPE_ENDPOINT,93 .endpoint_address = 1 + (1<<7),94 .length = sizeof(usb_standard_endpoint_descriptor_t),95 .max_packet_size = 8,96 .poll_interval = 255,97 };98 41 99 42 /** Root hub initialization … … 107 50 instance->device = dev; 108 51 109 110 52 usb_log_info("OHCI root hub with %d ports.\n", regs->rh_desc_a & 0xff); 111 53 112 //start generic usb hub driver113 114 54 /* TODO: implement */ 115 55 return EOK; 116 56 } 117 57 /*----------------------------------------------------------------------------*/ 118 119 120 static int process_get_port_status_request(rh_t *instance, uint16_t port,121 usb_transfer_batch_t * request){122 if(port<1 || port>instance->port_count)123 return EINVAL;124 uint32_t * uint32_buffer = (uint32_t*)request->buffer;125 request->transfered_size = 4;126 uint32_buffer[0] = instance->registers->rh_port_status[port -1];127 return EOK;128 }129 130 static int process_get_hub_status_request(rh_t *instance,131 usb_transfer_batch_t * request){132 uint32_t * uint32_buffer = (uint32_t*)request->buffer;133 //bits, 0,1,16,17134 request->transfered_size = 4;135 uint32_t mask = 1 & (1<<1) & (1<<16) & (1<<17);136 uint32_buffer[0] = mask & instance->registers->rh_status;137 return EOK;138 139 }140 141 static void usb_create_serialized_hub_descriptor(rh_t *instance, uint8_t ** out_result,142 size_t * out_size) {143 //base size144 size_t size = 7;145 //variable size according to port count146 size_t var_size = instance->port_count / 8 +147 ((instance->port_count % 8 > 0) ? 1 : 0);148 size += 2 * var_size;149 uint8_t * result = (uint8_t*) malloc(size);150 bzero(result,size);151 //size152 result[0] = size;153 //descriptor type154 result[1] = USB_DESCTYPE_HUB;155 result[2] = instance->port_count;156 uint32_t hub_desc_reg = instance->registers->rh_desc_a;157 result[3] =158 ((hub_desc_reg >> 8) %2) +159 (((hub_desc_reg >> 9) %2) << 1) +160 (((hub_desc_reg >> 10) %2) << 2) +161 (((hub_desc_reg >> 11) %2) << 3) +162 (((hub_desc_reg >> 12) %2) << 4);163 result[4] = 0;164 result[5] = /*descriptor->pwr_on_2_good_time*/ 50;165 result[6] = 50;166 167 int port;168 for (port = 1; port <= instance->port_count; ++port) {169 result[7 + port/8] +=170 ((instance->registers->rh_desc_b >> port)%2) << (port%8);171 }172 size_t i;173 for (i = 0; i < var_size; ++i) {174 result[7 + var_size + i] = 255;175 }176 (*out_result) = result;177 (*out_size) = size;178 }179 180 181 static int process_get_status_request(rh_t *instance,182 usb_transfer_batch_t * request)183 {184 size_t buffer_size = request->buffer_size;185 usb_device_request_setup_packet_t * request_packet =186 (usb_device_request_setup_packet_t*)187 request->setup_buffer;188 189 usb_hub_bm_request_type_t request_type = request_packet->request_type;190 if(buffer_size<4/*request_packet->length*/){///\TODO191 usb_log_warning("requested more data than buffer size\n");192 return EINVAL;193 }194 195 if(request_type == USB_HUB_REQ_TYPE_GET_HUB_STATUS)196 return process_get_hub_status_request(instance, request);197 if(request_type == USB_HUB_REQ_TYPE_GET_PORT_STATUS)198 return process_get_port_status_request(instance, request_packet->index,199 request);200 return ENOTSUP;201 }202 203 static void create_interrupt_mask(rh_t *instance, void ** buffer,204 size_t * buffer_size){205 int bit_count = instance->port_count + 1;206 (*buffer_size) = (bit_count / 8) + (bit_count%8==0)?0:1;207 (*buffer) = malloc(*buffer_size);208 uint8_t * bitmap = (uint8_t*)(*buffer);209 uint32_t mask = (1<<16) + (1<<17);210 bzero(bitmap,(*buffer_size));211 if(instance->registers->rh_status & mask){212 bitmap[0] = 1;213 }214 int port;215 mask = 0;216 int i;217 for(i=16;i<=20;++i)218 mask += 1<<i;219 for(port = 1; port<=instance->port_count;++port){220 if(mask & instance->registers->rh_port_status[port-1]){221 bitmap[(port+1)/8] += 1<<(port%8);222 }223 }224 }225 226 227 static int process_get_descriptor_request(rh_t *instance,228 usb_transfer_batch_t *request){229 /// \TODO230 usb_device_request_setup_packet_t * setup_request =231 (usb_device_request_setup_packet_t*)request->setup_buffer;232 size_t size;233 const void * result_descriptor;234 const uint16_t setup_request_value = setup_request->value_high;235 //(setup_request->value_low << 8);236 bool del = false;237 238 switch (setup_request_value)239 {240 case USB_DESCTYPE_HUB: {241 uint8_t * descriptor;242 usb_create_serialized_hub_descriptor(243 instance, &descriptor, &size);244 result_descriptor = descriptor;245 break;246 }247 case USB_DESCTYPE_DEVICE: {248 usb_log_debug("USB_DESCTYPE_DEVICE\n");249 result_descriptor = &ohci_rh_device_descriptor;250 size = sizeof(ohci_rh_device_descriptor);251 break;252 }253 case USB_DESCTYPE_CONFIGURATION: {254 usb_log_debug("USB_DESCTYPE_CONFIGURATION\n");255 usb_standard_configuration_descriptor_t * descriptor =256 malloc(sizeof(usb_standard_configuration_descriptor_t));257 memcpy(descriptor, &ohci_rh_conf_descriptor,258 sizeof(usb_standard_configuration_descriptor_t));259 /// \TODO should this include device descriptor?260 const size_t hub_descriptor_size = 7 +261 2* (instance->port_count / 8 +262 ((instance->port_count % 8 > 0) ? 1 : 0));263 descriptor->total_length =264 sizeof(usb_standard_configuration_descriptor_t)+265 sizeof(usb_standard_endpoint_descriptor_t)+266 sizeof(usb_standard_interface_descriptor_t)+267 hub_descriptor_size;268 result_descriptor = descriptor;269 size = sizeof(usb_standard_configuration_descriptor_t);270 del = true;271 break;272 }273 case USB_DESCTYPE_INTERFACE: {274 usb_log_debug("USB_DESCTYPE_INTERFACE\n");275 result_descriptor = &ohci_rh_iface_descriptor;276 size = sizeof(ohci_rh_iface_descriptor);277 break;278 }279 case USB_DESCTYPE_ENDPOINT: {280 usb_log_debug("USB_DESCTYPE_ENDPOINT\n");281 result_descriptor = &ohci_rh_ep_descriptor;282 size = sizeof(ohci_rh_ep_descriptor);283 break;284 }285 default: {286 usb_log_debug("USB_DESCTYPE_EINVAL %d \n",setup_request->value);287 usb_log_debug("\ttype %d\n\trequest %d\n\tvalue %d\n\tindex %d\n\tlen %d\n ",288 setup_request->request_type,289 setup_request->request,290 setup_request_value,291 setup_request->index,292 setup_request->length293 );294 return EINVAL;295 }296 }297 #if 0298 if(setup_request_value == USB_DESCTYPE_HUB){299 usb_log_debug("USB_DESCTYPE_HUB\n");300 //create hub descriptor301 uint8_t * descriptor;302 usb_create_serialized_hub_descriptor(instance,303 &descriptor, &size);304 result_descriptor = descriptor;305 }else if(setup_request_value == USB_DESCTYPE_DEVICE){306 //create std device descriptor307 usb_log_debug("USB_DESCTYPE_DEVICE\n");308 usb_standard_device_descriptor_t * descriptor =309 (usb_standard_device_descriptor_t*)310 malloc(sizeof(usb_standard_device_descriptor_t));311 descriptor->configuration_count = 1;312 descriptor->descriptor_type = USB_DESCTYPE_DEVICE;313 descriptor->device_class = USB_CLASS_HUB;314 descriptor->device_protocol = 0;315 descriptor->device_subclass = 0;316 descriptor->device_version = 0;317 descriptor->length = sizeof(usb_standard_device_descriptor_t);318 /// \TODO this value is guessed319 descriptor->max_packet_size = 8;320 descriptor->product_id = 0x0001;321 /// \TODO these values migt be different322 descriptor->str_serial_number = 0;323 descriptor->str_serial_number = 0;324 descriptor->usb_spec_version = 0;325 descriptor->vendor_id = 0x16db;326 result_descriptor = descriptor;327 size = sizeof(usb_standard_device_descriptor_t);328 }else if(setup_request_value == USB_DESCTYPE_CONFIGURATION){329 usb_log_debug("USB_DESCTYPE_CONFIGURATION\n");330 usb_standard_configuration_descriptor_t * descriptor =331 (usb_standard_configuration_descriptor_t*)332 malloc(sizeof(usb_standard_configuration_descriptor_t));333 /// \TODO some values are default or guessed334 descriptor->attributes = 1<<7;335 descriptor->configuration_number = 1;336 descriptor->descriptor_type = USB_DESCTYPE_CONFIGURATION;337 descriptor->interface_count = 1;338 descriptor->length = sizeof(usb_standard_configuration_descriptor_t);339 descriptor->max_power = 100;340 descriptor->str_configuration = 0;341 /// \TODO should this include device descriptor?342 size_t hub_descriptor_size = 7 +343 2* (instance->port_count / 8 +344 ((instance->port_count % 8 > 0) ? 1 : 0));345 descriptor->total_length =346 sizeof(usb_standard_configuration_descriptor_t)+347 sizeof(usb_standard_endpoint_descriptor_t)+348 sizeof(usb_standard_interface_descriptor_t)+349 hub_descriptor_size;350 result_descriptor = descriptor;351 size = sizeof(usb_standard_configuration_descriptor_t);352 353 }else if(setup_request_value == USB_DESCTYPE_INTERFACE){354 usb_log_debug("USB_DESCTYPE_INTERFACE\n");355 usb_standard_interface_descriptor_t * descriptor =356 (usb_standard_interface_descriptor_t*)357 malloc(sizeof(usb_standard_interface_descriptor_t));358 descriptor->alternate_setting = 0;359 descriptor->descriptor_type = USB_DESCTYPE_INTERFACE;360 descriptor->endpoint_count = 1;361 descriptor->interface_class = USB_CLASS_HUB;362 /// \TODO is this correct?363 descriptor->interface_number = 1;364 descriptor->interface_protocol = 0;365 descriptor->interface_subclass = 0;366 descriptor->length = sizeof(usb_standard_interface_descriptor_t);367 descriptor->str_interface = 0;368 result_descriptor = descriptor;369 size = sizeof(usb_standard_interface_descriptor_t);370 }else if(setup_request_value == USB_DESCTYPE_ENDPOINT){371 usb_log_debug("USB_DESCTYPE_ENDPOINT\n");372 usb_standard_endpoint_descriptor_t * descriptor =373 (usb_standard_endpoint_descriptor_t*)374 malloc(sizeof(usb_standard_endpoint_descriptor_t));375 descriptor->attributes = USB_TRANSFER_INTERRUPT;376 descriptor->descriptor_type = USB_DESCTYPE_ENDPOINT;377 descriptor->endpoint_address = 1 + (1<<7);378 descriptor->length = sizeof(usb_standard_endpoint_descriptor_t);379 descriptor->max_packet_size = 8;380 descriptor->poll_interval = 255;381 result_descriptor = descriptor;382 size = sizeof(usb_standard_endpoint_descriptor_t);383 }else{384 usb_log_debug("USB_DESCTYPE_EINVAL %d \n",setup_request->value);385 usb_log_debug("\ttype %d\n\trequest %d\n\tvalue %d\n\tindex %d\n\tlen %d\n ",386 setup_request->request_type,387 setup_request->request,388 setup_request_value,389 setup_request->index,390 setup_request->length391 );392 return EINVAL;393 }394 #endif395 if(request->buffer_size < size){396 size = request->buffer_size;397 }398 request->transfered_size = size;399 memcpy(request->buffer,result_descriptor,size);400 if (del)401 free(result_descriptor);402 return EOK;403 }404 405 static int process_get_configuration_request(rh_t *instance,406 usb_transfer_batch_t *request){407 //set and get configuration requests do not have any meaning, only dummy408 //values are returned409 if(request->buffer_size != 1)410 return EINVAL;411 request->buffer[0] = 1;412 request->transfered_size = 1;413 return EOK;414 }415 416 static int process_hub_feature_set_request(rh_t *instance,417 uint16_t feature, bool enable){418 if(feature > USB_HUB_FEATURE_C_HUB_OVER_CURRENT)419 return EINVAL;420 instance->registers->rh_status =421 enable ?422 (instance->registers->rh_status | (1<<feature))423 :424 (instance->registers->rh_status & (~(1<<feature)));425 /// \TODO any error?426 return EOK;427 }428 429 static int process_port_feature_set_request(rh_t *instance,430 uint16_t feature, uint16_t port, bool enable){431 if(feature > USB_HUB_FEATURE_C_PORT_RESET)432 return EINVAL;433 if(port<1 || port>instance->port_count)434 return EINVAL;435 instance->registers->rh_port_status[port - 1] =436 enable ?437 (instance->registers->rh_port_status[port - 1] | (1<<feature))438 :439 (instance->registers->rh_port_status[port - 1] & (~(1<<feature)));440 /// \TODO any error?441 return EOK;442 }443 444 static int process_address_set_request(rh_t *instance,445 uint16_t address){446 instance->address = address;447 return EOK;448 }449 450 static int process_request_with_output(rh_t *instance,451 usb_transfer_batch_t *request){452 usb_device_request_setup_packet_t * setup_request =453 (usb_device_request_setup_packet_t*)request->setup_buffer;454 if(setup_request->request == USB_DEVREQ_GET_STATUS){455 usb_log_debug("USB_DEVREQ_GET_STATUS\n");456 return process_get_status_request(instance, request);457 }458 if(setup_request->request == USB_DEVREQ_GET_DESCRIPTOR){459 usb_log_debug("USB_DEVREQ_GET_DESCRIPTOR\n");460 return process_get_descriptor_request(instance, request);461 }462 if(setup_request->request == USB_DEVREQ_GET_CONFIGURATION){463 usb_log_debug("USB_DEVREQ_GET_CONFIGURATION\n");464 return process_get_configuration_request(instance, request);465 }466 return ENOTSUP;467 }468 469 static int process_request_with_input(rh_t *instance,470 usb_transfer_batch_t *request){471 usb_device_request_setup_packet_t * setup_request =472 (usb_device_request_setup_packet_t*)request->setup_buffer;473 request->transfered_size = 0;474 if(setup_request->request == USB_DEVREQ_SET_DESCRIPTOR){475 return ENOTSUP;476 }477 if(setup_request->request == USB_DEVREQ_SET_CONFIGURATION){478 //set and get configuration requests do not have any meaning,479 //only dummy values are returned480 return EOK;481 }482 return ENOTSUP;483 }484 485 486 static int process_request_without_data(rh_t *instance,487 usb_transfer_batch_t *request){488 usb_device_request_setup_packet_t * setup_request =489 (usb_device_request_setup_packet_t*)request->setup_buffer;490 request->transfered_size = 0;491 if(setup_request->request == USB_DEVREQ_CLEAR_FEATURE492 || setup_request->request == USB_DEVREQ_SET_FEATURE){493 if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_HUB_FEATURE){494 usb_log_debug("USB_HUB_REQ_TYPE_SET_HUB_FEATURE\n");495 return process_hub_feature_set_request(instance, setup_request->value,496 setup_request->request == USB_DEVREQ_SET_FEATURE);497 }498 if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE){499 usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n");500 return process_port_feature_set_request(instance, setup_request->value,501 setup_request->index,502 setup_request->request == USB_DEVREQ_SET_FEATURE);503 }504 usb_log_debug("USB_HUB_REQ_TYPE_INVALID %d\n",setup_request->request_type);505 return EINVAL;506 }507 if(setup_request->request == USB_DEVREQ_SET_ADDRESS){508 usb_log_debug("USB_DEVREQ_SET_ADDRESS\n");509 return process_address_set_request(instance, setup_request->value);510 }511 usb_log_debug("USB_DEVREQ_SET_ENOTSUP %d\n",setup_request->request_type);512 return ENOTSUP;513 }514 515 516 /**517 *518 * @param instance519 * @param request520 * @return521 */522 58 int rh_request(rh_t *instance, usb_transfer_batch_t *request) 523 59 { 524 60 assert(instance); 525 61 assert(request); 526 int opResult; 527 if(request->transfer_type == USB_TRANSFER_CONTROL){ 528 if (request->setup_buffer) { 529 usb_log_info("Root hub got CTRL packet: %s.\n", 530 usb_debug_str_buffer((const uint8_t *)request->setup_buffer, 8, 8)); 531 if(sizeof(usb_device_request_setup_packet_t)>request->setup_size){ 532 usb_log_error("setup packet too small\n"); 533 return EINVAL; 534 } 535 usb_device_request_setup_packet_t * setup_request = 536 (usb_device_request_setup_packet_t*)request->setup_buffer; 537 if( 538 setup_request->request == USB_DEVREQ_GET_STATUS 539 || setup_request->request == USB_DEVREQ_GET_DESCRIPTOR 540 || setup_request->request == USB_DEVREQ_GET_CONFIGURATION 541 ){ 542 usb_log_debug("processing request with output\n"); 543 opResult = process_request_with_output(instance,request); 544 }else if( 545 setup_request->request == USB_DEVREQ_CLEAR_FEATURE 546 || setup_request->request == USB_DEVREQ_SET_FEATURE 547 || setup_request->request == USB_DEVREQ_SET_ADDRESS 548 ){ 549 usb_log_debug("processing request without additional data\n"); 550 opResult = process_request_without_data(instance,request); 551 }else if(setup_request->request == USB_DEVREQ_SET_DESCRIPTOR 552 || setup_request->request == USB_DEVREQ_SET_CONFIGURATION 553 ){ 554 usb_log_debug("processing request with input\n"); 555 opResult = process_request_with_input(instance,request); 556 }else{ 557 usb_log_warning("received unsuported request: %d\n", 558 setup_request->request 559 ); 560 opResult = ENOTSUP; 561 } 562 }else{ 563 usb_log_error("root hub received empty transaction?"); 564 opResult = EINVAL; 565 } 566 }else if(request->transfer_type == USB_TRANSFER_INTERRUPT){ 567 usb_log_info("Root hub got INTERRUPT packet\n"); 568 void * buffer; 569 create_interrupt_mask(instance, &buffer, 570 &(request->transfered_size)); 571 memcpy(request->transport_buffer,buffer, request->transfered_size); 572 opResult = EOK; 573 }else{ 574 opResult = EINVAL; 62 /* TODO: implement */ 63 if (request->setup_buffer) { 64 usb_log_info("Root hub got SETUP packet: %s.\n", 65 usb_debug_str_buffer((const uint8_t *)request->setup_buffer, 8, 8)); 575 66 } 576 usb_transfer_batch_finish(request, opResult); 67 usb_log_error("Root hub request processing not implemented.\n"); 68 usb_transfer_batch_finish(request, ENOTSUP); 577 69 return EOK; 578 70 } 579 71 /*----------------------------------------------------------------------------*/ 580 581 582 72 void rh_interrupt(rh_t *instance) 583 73 { -
uspace/drv/ohci/root_hub.h
r291b8bc r889e8e3 45 45 usb_address_t address; 46 46 ddf_dev_t *device; 47 int port_count;48 47 } rh_t; 49 48 -
uspace/drv/uhci-hcd/Makefile
r291b8bc r889e8e3 40 40 root_hub.c \ 41 41 hw_struct/transfer_descriptor.c \ 42 utils/slab.c \43 42 pci.c \ 44 43 batch.c -
uspace/drv/uhci-hcd/hc.c
r291b8bc r889e8e3 223 223 ret = instance ? EOK : ENOMEM; 224 224 CHECK_RET_DEST_CMDS_RETURN(ret, "Failed to get frame list page.\n"); 225 usb_log_debug("Initialized frame list at %p.\n", instance->frame_list);225 usb_log_debug("Initialized frame list.\n"); 226 226 227 227 /* Set all frames to point to the first queue head */ … … 336 336 instance->transfers[batch->speed][batch->transfer_type]; 337 337 assert(list); 338 if (batch->transfer_type == USB_TRANSFER_CONTROL) {339 usb_device_keeper_use_control(340 &instance->manager, batch->target.address);341 }342 338 transfer_list_add_batch(list, batch); 343 339 … … 361 357 /* Lower 2 bits are transaction error and transaction complete */ 362 358 if (status & 0x3) { 363 LIST_INITIALIZE(done); 364 transfer_list_remove_finished( 365 &instance->transfers_interrupt, &done); 366 transfer_list_remove_finished( 367 &instance->transfers_control_slow, &done); 368 transfer_list_remove_finished( 369 &instance->transfers_control_full, &done); 370 transfer_list_remove_finished( 371 &instance->transfers_bulk_full, &done); 372 373 while (!list_empty(&done)) { 374 link_t *item = done.next; 375 list_remove(item); 376 usb_transfer_batch_t *batch = 377 list_get_instance(item, usb_transfer_batch_t, link); 378 if (batch->transfer_type == USB_TRANSFER_CONTROL) { 379 usb_device_keeper_release_control( 380 &instance->manager, batch->target.address); 381 } 382 batch->next_step(batch); 383 } 359 transfer_list_remove_finished(&instance->transfers_interrupt); 360 transfer_list_remove_finished(&instance->transfers_control_slow); 361 transfer_list_remove_finished(&instance->transfers_control_full); 362 transfer_list_remove_finished(&instance->transfers_bulk_full); 384 363 } 385 364 /* bits 4 and 5 indicate hc error */ -
uspace/drv/uhci-hcd/root_hub.c
r291b8bc r889e8e3 48 48 * @return Error code. 49 49 */ 50 int rh_init(rh_t *instance, ddf_fun_t *fun, uintptr_t reg_addr, size_t reg_size) 50 int rh_init( 51 rh_t *instance, ddf_fun_t *fun, uintptr_t reg_addr, size_t reg_size) 51 52 { 52 53 assert(fun); -
uspace/drv/uhci-hcd/transfer_list.c
r291b8bc r889e8e3 58 58 } 59 59 instance->queue_head_pa = addr_to_phys(instance->queue_head); 60 usb_log_debug2("Transfer list %s setup with QH: %p(%p).\n",61 name, instance->queue_head, instance->queue_head_pa);62 60 63 61 qh_init(instance->queue_head); … … 120 118 qh_set_next_qh(last_qh, pa); 121 119 122 asm volatile ("": : :"memory");123 124 120 /* Add to the driver list */ 125 121 list_append(&batch->link, &instance->batch_list); … … 141 137 * this transfer list leading to the deadlock if its done inline. 142 138 */ 143 void transfer_list_remove_finished(transfer_list_t *instance, link_t *done) 144 { 145 assert(instance); 146 assert(done); 139 void transfer_list_remove_finished(transfer_list_t *instance) 140 { 141 assert(instance); 142 143 LIST_INITIALIZE(done); 147 144 148 145 fibril_mutex_lock(&instance->guard); … … 156 153 /* Save for post-processing */ 157 154 transfer_list_remove_batch(instance, batch); 158 list_append(current, done);155 list_append(current, &done); 159 156 } 160 157 current = next; … … 162 159 fibril_mutex_unlock(&instance->guard); 163 160 161 while (!list_empty(&done)) { 162 link_t *item = done.next; 163 list_remove(item); 164 usb_transfer_batch_t *batch = 165 list_get_instance(item, usb_transfer_batch_t, link); 166 batch->next_step(batch); 167 } 164 168 } 165 169 /*----------------------------------------------------------------------------*/ … … 218 222 qpos = "NOT FIRST"; 219 223 } 220 asm volatile ("": : :"memory");221 224 /* Remove from the batch list */ 222 225 list_remove(&batch->link); -
uspace/drv/uhci-hcd/transfer_list.h
r291b8bc r889e8e3 67 67 void transfer_list_add_batch(transfer_list_t *instance, usb_transfer_batch_t *batch); 68 68 69 void transfer_list_remove_finished(transfer_list_t *instance , link_t *done);69 void transfer_list_remove_finished(transfer_list_t *instance); 70 70 71 71 void transfer_list_abort_all(transfer_list_t *instance); -
uspace/drv/uhci-hcd/uhci.c
r291b8bc r889e8e3 44 44 #include "pci.h" 45 45 46 46 47 /** IRQ handling callback, identifies device 47 48 * … … 107 108 /*----------------------------------------------------------------------------*/ 108 109 static ddf_dev_ops_t hc_ops = { 109 //.interfaces[USB_DEV_IFACE] = &usb_iface,110 .interfaces[USB_DEV_IFACE] = &usb_iface, 110 111 .interfaces[USBHC_DEV_IFACE] = &hc_iface, /* see iface.h/c */ 111 112 }; -
uspace/drv/uhci-hcd/utils/malloc32.h
r291b8bc r889e8e3 40 40 #include <as.h> 41 41 42 #include "slab.h"43 44 42 #define UHCI_STRCUTURES_ALIGNMENT 16 45 43 #define UHCI_REQUIRED_PAGE_SIZE 4096 46 47 44 48 45 /** Get physical address translation … … 57 54 58 55 uintptr_t result; 59 const int ret = as_get_physical_mapping(addr, &result); 60 assert(ret == EOK); 56 int ret = as_get_physical_mapping(addr, &result); 61 57 62 58 if (ret != EOK) … … 70 66 * @return Address of the alligned and big enough memory place, NULL on failure. 71 67 */ 72 static inline void * malloc32(size_t size) { 73 if (size <= SLAB_ELEMENT_SIZE) 74 return slab_malloc_g(); 75 assert(false); 76 return memalign(UHCI_STRCUTURES_ALIGNMENT, size); 77 } 68 static inline void * malloc32(size_t size) 69 { return memalign(UHCI_STRCUTURES_ALIGNMENT, size); } 78 70 /*----------------------------------------------------------------------------*/ 79 71 /** Physical mallocator simulator … … 81 73 * @param[in] addr Address of the place allocated by malloc32 82 74 */ 83 static inline void free32(void *addr) { 84 if (!addr) 85 return; 86 if (slab_in_range_g(addr)) 87 return slab_free_g(addr); 88 free(addr); 89 } 75 static inline void free32(void *addr) 76 { if (addr) free(addr); } 90 77 /*----------------------------------------------------------------------------*/ 91 78 /** Create 4KB page mapping … … 95 82 static inline void * get_page(void) 96 83 { 97 void * free_address = as_get_mappable_page(UHCI_REQUIRED_PAGE_SIZE);98 assert(free_address); /* TODO: remove this assert */84 void * free_address = as_get_mappable_page(UHCI_REQUIRED_PAGE_SIZE); 85 assert(free_address); 99 86 if (free_address == 0) 100 87 return NULL; 101 void *ret = as_area_create(free_address, UHCI_REQUIRED_PAGE_SIZE, 88 void* ret = 89 as_area_create(free_address, UHCI_REQUIRED_PAGE_SIZE, 102 90 AS_AREA_READ | AS_AREA_WRITE); 103 91 if (ret != free_address) -
uspace/drv/usbhub/port_status.h
r291b8bc r889e8e3 30 30 */ 31 31 32 #ifndef HUB_PORT_STATUS_H33 #define HUB_PORT_STATUS_H32 #ifndef PORT_STATUS_H 33 #define PORT_STATUS_H 34 34 35 35 #include <bool.h> … … 335 335 336 336 337 #endif /* HUB_PORT_STATUS_H */337 #endif /* PORT_STATUS_H */ 338 338 339 339 /** -
uspace/drv/usbhub/usbhub.c
r291b8bc r889e8e3 162 162 std_descriptor->configuration_count); 163 163 if(std_descriptor->configuration_count<1){ 164 usb_log_error("there are no configurations available\n"); 164 usb_log_error("THERE ARE NO CONFIGURATIONS AVAILABLE\n"); 165 //shouldn`t I return? 166 //definitely 165 167 return EINVAL; 166 168 } -
uspace/lib/c/generic/malloc.c
r291b8bc r889e8e3 240 240 size_t asize = ALIGN_UP(size, PAGE_SIZE); 241 241 242 astart = as_area_create(astart, asize, AS_AREA_WRITE | AS_AREA_READ | AS_AREA_CACHEABLE);242 astart = as_area_create(astart, asize, AS_AREA_WRITE | AS_AREA_READ); 243 243 if (astart == (void *) -1) 244 244 return false; -
uspace/lib/usb/Makefile
r291b8bc r889e8e3 50 50 src/usb.c \ 51 51 src/usbdevice.c \ 52 src/hidreq.c \53 src/hidreport.c \54 52 src/host/device_keeper.c \ 55 53 src/host/batch.c -
uspace/lib/usb/include/usb/classes/hidparser.h
r291b8bc r889e8e3 70 70 * Description of path of usage pages and usages in report descriptor 71 71 */ 72 #define USB_HID_PATH_COMPARE_STRICT 073 #define USB_HID_PATH_COMPARE_END 174 #define USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY 475 76 72 typedef struct { 77 73 int32_t usage_page; 78 int32_t usage;79 80 link_t link;81 } usb_hid_report_usage_path_t;82 83 typedef struct {84 int depth;85 link_t link;86 74 } usb_hid_report_path_t; 87 75 … … 91 79 typedef struct { 92 80 int32_t id; 81 int32_t usage_page; 82 int32_t usage; 93 83 int32_t usage_minimum; 94 84 int32_t usage_maximum; … … 117 107 uint8_t item_flags; 118 108 119 usb_hid_report_path_t *usage_path;120 109 link_t link; 121 110 } usb_hid_report_item_t; … … 128 117 link_t feature; 129 118 } usb_hid_report_parser_t; 119 130 120 131 121 … … 204 194 int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 205 195 const uint8_t *data, size_t size, 206 usb_hid_report_path_t *path, int flags,207 196 const usb_hid_report_in_callbacks_t *callbacks, void *arg); 208 197 209 198 int usb_hid_report_input_length(const usb_hid_report_parser_t *parser, 210 usb_hid_report_path_t *path, int flags);199 const usb_hid_report_path_t *path); 211 200 212 201 … … 215 204 void usb_hid_descriptor_print(usb_hid_report_parser_t *parser); 216 205 217 /* usage path functions */218 usb_hid_report_path_t *usb_hid_report_path(void);219 void usb_hid_report_path_free(usb_hid_report_path_t *path);220 int usb_hid_report_path_append_item(usb_hid_report_path_t *usage_path, int32_t usage_page, int32_t usage);221 void usb_hid_report_remove_last_item(usb_hid_report_path_t *usage_path);222 void usb_hid_report_null_last_item(usb_hid_report_path_t *usage_path);223 void usb_hid_report_set_last_item(usb_hid_report_path_t *usage_path, int32_t tag, int32_t data);224 int usb_hid_report_compare_usage_path(usb_hid_report_path_t *report_path, usb_hid_report_path_t *path, int flags);225 int usb_hid_report_path_clone(usb_hid_report_path_t *new_usage_path, usb_hid_report_path_t *usage_path);226 227 228 // output229 // - funkce co vrati cesty poli v output reportu230 // - funkce co pro danou cestu nastavi data231 // - finalize232 233 206 #endif 234 207 /** -
uspace/lib/usb/include/usb/host/device_keeper.h
r291b8bc r889e8e3 51 51 usb_speed_t speed; 52 52 bool occupied; 53 bool control_used;54 53 uint16_t toggle_status[2]; 55 54 devman_handle_t handle; … … 62 61 struct usb_device_info devices[USB_ADDRESS_COUNT]; 63 62 fibril_mutex_t guard; 64 fibril_condvar_t change;63 fibril_condvar_t default_address_occupied; 65 64 usb_address_t last_address; 66 65 } usb_device_keeper_t; … … 98 97 usb_address_t address); 99 98 100 void usb_device_keeper_use_control(usb_device_keeper_t *instance,101 usb_address_t address);102 103 void usb_device_keeper_release_control(usb_device_keeper_t *instance,104 usb_address_t address);105 106 99 #endif 107 100 /** -
uspace/lib/usb/src/hidparser.c
r291b8bc r889e8e3 47 47 48 48 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size, 49 usb_hid_report_item_t *report_item , usb_hid_report_path_t *usage_path);49 usb_hid_report_item_t *report_item); 50 50 int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size, 51 usb_hid_report_item_t *report_item , usb_hid_report_path_t *usage_path);51 usb_hid_report_item_t *report_item); 52 52 int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size, 53 usb_hid_report_item_t *report_item , usb_hid_report_path_t *usage_path);53 usb_hid_report_item_t *report_item); 54 54 int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size, 55 usb_hid_report_item_t *report_item , usb_hid_report_path_t *usage_path);55 usb_hid_report_item_t *report_item); 56 56 57 57 void usb_hid_descriptor_print_list(link_t *head); … … 63 63 int usb_pow(int a, int b); 64 64 65 66 65 int usb_pow(int a, int b) 67 66 { … … 85 84 { 86 85 if(parser == NULL) { 87 return EINVAL;86 return -1; 88 87 } 89 88 … … 111 110 int ret; 112 111 usb_hid_report_item_t *report_item=0; 113 usb_hid_report_item_t *new_report_item; 114 usb_hid_report_path_t *usage_path; 115 usb_hid_report_path_t *tmp_usage_path; 112 usb_hid_report_item_t *new_report_item; 116 113 117 114 size_t offset_input=0; … … 120 117 121 118 122 /* parser structure initialization*/123 if(usb_hid_parser_init(parser) != EOK) {124 return EINVAL;125 }126 127 128 /*report item initialization*/129 119 if(!(report_item=malloc(sizeof(usb_hid_report_item_t)))){ 130 120 return ENOMEM; 131 121 } 132 122 memset(report_item, 0, sizeof(usb_hid_report_item_t)); 133 list_initialize(&(report_item->link)); 134 135 /* usage path context initialization */ 136 if(!(usage_path=usb_hid_report_path())){ 137 return ENOMEM; 138 } 139 123 124 link_initialize(&(report_item->link)); 125 140 126 while(i<size){ 141 127 if(!USB_HID_ITEM_IS_LONG(data[i])){ 142 128 143 129 if((i+USB_HID_ITEM_SIZE(data[i]))>= size){ 144 return EINVAL; // TODO ERROR CODE130 return -1; // TODO ERROR CODE 145 131 } 146 132 … … 155 141 156 142 ret = usb_hid_report_parse_tag(tag,class,data+i+1, 157 item_size,report_item, usage_path);143 item_size,report_item); 158 144 usb_log_debug2("ret: %u\n", ret); 159 145 switch(ret){ 160 146 case USB_HID_NEW_REPORT_ITEM: 161 147 // store report item to report and create the new one 162 usb_log_debug("\nNEW REPORT ITEM: %X",ret); 163 164 // store current usage path 165 report_item->usage_path = usage_path; 166 167 // new current usage path 168 tmp_usage_path = usb_hid_report_path(); 169 170 // copy old path to the new one 171 usb_hid_report_path_clone(tmp_usage_path, usage_path); 172 173 // swap 174 usage_path = tmp_usage_path; 175 tmp_usage_path = NULL; 176 148 usb_log_debug("\nNEW REPORT ITEM: %X",tag); 177 149 178 150 switch(tag) { … … 212 184 link_initialize(&(new_report_item->link)); 213 185 report_item = new_report_item; 214 186 215 187 break; 216 188 case USB_HID_REPORT_TAG_PUSH: … … 312 284 */ 313 285 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size, 314 usb_hid_report_item_t *report_item , usb_hid_report_path_t *usage_path)286 usb_hid_report_item_t *report_item) 315 287 { 316 288 int ret; … … 319 291 case USB_HID_TAG_CLASS_MAIN: 320 292 321 if((ret=usb_hid_report_parse_main_tag(tag,data,item_size,report_item , usage_path)) == EOK) {293 if((ret=usb_hid_report_parse_main_tag(tag,data,item_size,report_item)) == EOK) { 322 294 return USB_HID_NEW_REPORT_ITEM; 323 295 } … … 329 301 330 302 case USB_HID_TAG_CLASS_GLOBAL: 331 return usb_hid_report_parse_global_tag(tag,data,item_size,report_item , usage_path);303 return usb_hid_report_parse_global_tag(tag,data,item_size,report_item); 332 304 break; 333 305 334 306 case USB_HID_TAG_CLASS_LOCAL: 335 return usb_hid_report_parse_local_tag(tag,data,item_size,report_item , usage_path);307 return usb_hid_report_parse_local_tag(tag,data,item_size,report_item); 336 308 break; 337 309 default: … … 351 323 352 324 int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size, 353 usb_hid_report_item_t *report_item , usb_hid_report_path_t *usage_path)354 { 325 usb_hid_report_item_t *report_item) 326 { 355 327 switch(tag) 356 328 { … … 363 335 364 336 case USB_HID_REPORT_TAG_COLLECTION: 365 usb_hid_report_path_append_item(usage_path, 0, 0); 366 337 // TODO 367 338 return USB_HID_NO_ACTION; 368 339 break; 369 340 370 341 case USB_HID_REPORT_TAG_END_COLLECTION: 371 // TODO 372 // znici posledni uroven ve vsech usage paths 373 // otazka jestli nema nicit dve, respektive novou posledni vynulovat? 374 usb_hid_report_remove_last_item(usage_path); 342 /* should be ignored */ 375 343 return USB_HID_NO_ACTION; 376 344 break; … … 393 361 394 362 int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size, 395 usb_hid_report_item_t *report_item , usb_hid_report_path_t *usage_path)363 usb_hid_report_item_t *report_item) 396 364 { 397 365 // TODO take care about the bit length of data … … 399 367 { 400 368 case USB_HID_REPORT_TAG_USAGE_PAGE: 401 // zmeni to jenom v poslednim poli aktualni usage path 402 usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_GLOBAL, 403 usb_hid_report_tag_data_int32(data,item_size)); 369 report_item->usage_page = usb_hid_report_tag_data_int32(data,item_size); 404 370 break; 405 371 case USB_HID_REPORT_TAG_LOGICAL_MINIMUM: … … 452 418 */ 453 419 int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size, 454 usb_hid_report_item_t *report_item , usb_hid_report_path_t *usage_path)420 usb_hid_report_item_t *report_item) 455 421 { 456 422 switch(tag) 457 423 { 458 424 case USB_HID_REPORT_TAG_USAGE: 459 usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_LOCAL, 460 usb_hid_report_tag_data_int32(data,item_size)); 425 report_item->usage = usb_hid_report_tag_data_int32(data,item_size); 461 426 break; 462 427 case USB_HID_REPORT_TAG_USAGE_MINIMUM: … … 526 491 { 527 492 usb_hid_report_item_t *report_item; 528 usb_hid_report_usage_path_t *path_item;529 link_t *path;530 493 link_t *item; 531 494 … … 544 507 usb_log_debug("\tCONSTANT/VAR: %X\n", USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags)); 545 508 usb_log_debug("\tVARIABLE/ARRAY: %X\n", USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags)); 546 usb_log_debug("\tUSAGE PATH:\n"); 547 548 path = report_item->usage_path->link.next; 549 while(path != &report_item->usage_path->link) { 550 path_item = list_get_instance(path, usb_hid_report_usage_path_t, link); 551 usb_log_debug("\t\tUSAGE PAGE: %X, USAGE: %X\n", path_item->usage_page, path_item->usage); 552 path = path->next; 553 } 554 555 556 // usb_log_debug("\tUSAGE: %X\n", report_item->usage); 557 // usb_log_debug("\tUSAGE PAGE: %X\n", report_item->usage_page); 509 usb_log_debug("\tUSAGE: %X\n", report_item->usage); 510 usb_log_debug("\tUSAGE PAGE: %X\n", report_item->usage_page); 558 511 usb_log_debug("\tLOGMIN: %X\n", report_item->logical_minimum); 559 512 usb_log_debug("\tLOGMAX: %X\n", report_item->logical_maximum); … … 577 530 void usb_hid_descriptor_print(usb_hid_report_parser_t *parser) 578 531 { 579 if(parser == NULL) {580 return;581 }582 583 532 usb_log_debug("INPUT:\n"); 584 533 usb_hid_descriptor_print_list(&parser->input); … … 612 561 613 562 report_item = list_get_instance(next, usb_hid_report_item_t, link); 614 615 while(!list_empty(&report_item->usage_path->link)) {616 usb_hid_report_remove_last_item(report_item->usage_path);617 }618 619 620 563 next = next->next; 621 564 … … 657 600 int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 658 601 const uint8_t *data, size_t size, 659 usb_hid_report_path_t *path, int flags,660 602 const usb_hid_report_in_callbacks_t *callbacks, void *arg) 661 603 { … … 673 615 size_t j=0; 674 616 675 if(parser == NULL) {676 return EINVAL;677 }678 679 680 617 // get the size of result keycodes array 681 key_count = usb_hid_report_input_length(parser, path, flags); 618 usb_hid_report_path_t path; 619 path.usage_page = BAD_HACK_USAGE_PAGE; 620 key_count = usb_hid_report_input_length(parser, &path); 682 621 683 622 if(!(keys = malloc(sizeof(uint8_t) * key_count))){ … … 690 629 691 630 item = list_get_instance(list_item, usb_hid_report_item_t, link); 692 if(!USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) && 693 ( usb_hid_report_compare_usage_path(item->usage_path, path, flags) == EOK)) {631 if(!USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) && 632 (item->usage_page == path.usage_page)) { 694 633 for(j=0; j<(size_t)(item->count); j++) { 695 634 if((USB_HID_ITEM_FLAG_VARIABLE(item->item_flags) == 0) || … … 701 640 // bitmapa 702 641 if((item_value = usb_hid_translate_data(item, data, j)) != 0) { 703 keys[i++] = (item->count - 1 - j)+ item->usage_minimum;642 keys[i++] = j + item->usage_minimum; 704 643 } 705 644 else { … … 797 736 798 737 int usb_hid_report_input_length(const usb_hid_report_parser_t *parser, 799 usb_hid_report_path_t *path, int flags)800 { 738 const usb_hid_report_path_t *path) 739 { 801 740 int ret = 0; 802 741 link_t *item; 803 742 usb_hid_report_item_t *report_item; 804 743 805 if(parser == NULL) {806 return EINVAL;807 }808 809 744 item = (&parser->input)->next; 810 745 while(&parser->input != item) { 811 746 report_item = list_get_instance(item, usb_hid_report_item_t, link); 812 747 if(!USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags) && 813 ( usb_hid_report_compare_usage_path(report_item->usage_path, path, flags) == EOK)) {748 (report_item->usage_page == path->usage_page)) { 814 749 ret += report_item->count; 815 750 } … … 822 757 823 758 824 /**825 *826 */827 int usb_hid_report_path_append_item(usb_hid_report_path_t *usage_path,828 int32_t usage_page, int32_t usage)829 {830 usb_hid_report_usage_path_t *item;831 832 if(!(item=malloc(sizeof(usb_hid_report_usage_path_t)))) {833 return ENOMEM;834 }835 list_initialize(&item->link);836 837 item->usage = usage;838 item->usage_page = usage_page;839 840 list_append (&usage_path->link, &item->link);841 usage_path->depth++;842 return EOK;843 }844 845 /**846 *847 */848 void usb_hid_report_remove_last_item(usb_hid_report_path_t *usage_path)849 {850 usb_hid_report_usage_path_t *item;851 852 if(!list_empty(&usage_path->link)){853 item = list_get_instance(usage_path->link.prev, usb_hid_report_usage_path_t, link);854 list_remove(usage_path->link.prev);855 usage_path->depth--;856 free(item);857 }858 }859 860 /**861 *862 */863 void usb_hid_report_null_last_item(usb_hid_report_path_t *usage_path)864 {865 usb_hid_report_usage_path_t *item;866 867 if(!list_empty(&usage_path->link)){868 item = list_get_instance(usage_path->link.prev, usb_hid_report_usage_path_t, link);869 memset(item, 0, sizeof(usb_hid_report_usage_path_t));870 }871 }872 873 /**874 *875 */876 void usb_hid_report_set_last_item(usb_hid_report_path_t *usage_path, int32_t tag, int32_t data)877 {878 usb_hid_report_usage_path_t *item;879 880 if(!list_empty(&usage_path->link)){881 item = list_get_instance(usage_path->link.prev, usb_hid_report_usage_path_t, link);882 883 switch(tag) {884 case USB_HID_TAG_CLASS_GLOBAL:885 item->usage_page = data;886 break;887 case USB_HID_TAG_CLASS_LOCAL:888 item->usage = data;889 break;890 }891 }892 893 }894 895 /**896 *897 */898 int usb_hid_report_compare_usage_path(usb_hid_report_path_t *report_path,899 usb_hid_report_path_t *path,900 int flags)901 {902 usb_hid_report_usage_path_t *report_item;903 usb_hid_report_usage_path_t *path_item;904 905 link_t *report_link;906 link_t *path_link;907 908 int only_page;909 910 if(path->depth == 0){911 return EOK;912 }913 914 915 if((only_page = flags & USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY) != 0){916 flags -= USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY;917 }918 919 switch(flags){920 /* path must be completly identical */921 case USB_HID_PATH_COMPARE_STRICT:922 if(report_path->depth != path->depth){923 return 1;924 }925 926 report_link = report_path->link.next;927 path_link = path->link.next;928 929 while((report_link != &report_path->link) && (path_link != &path->link)) {930 report_item = list_get_instance(report_link, usb_hid_report_usage_path_t, link);931 path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link);932 933 if((report_item->usage_page != path_item->usage_page) ||934 ((only_page == 0) && (report_item->usage != path_item->usage))) {935 return 1;936 } else {937 report_link = report_link->next;938 path_link = path_link->next;939 }940 941 }942 943 if((report_link == &report_path->link) && (path_link == &path->link)) {944 return EOK;945 }946 else {947 return 1;948 }949 break;950 951 /* given path must be the end of the report one*/952 case USB_HID_PATH_COMPARE_END:953 report_link = report_path->link.prev;954 path_link = path->link.prev;955 956 if(list_empty(&path->link)){957 return EOK;958 }959 960 while((report_link != &report_path->link) && (path_link != &path->link)) {961 report_item = list_get_instance(report_link, usb_hid_report_usage_path_t, link);962 path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link);963 964 if((report_item->usage_page != path_item->usage_page) ||965 ((only_page == 0) && (report_item->usage != path_item->usage))) {966 return 1;967 } else {968 report_link = report_link->prev;969 path_link = path_link->prev;970 }971 972 }973 974 if(path_link == &path->link) {975 return EOK;976 }977 else {978 return 1;979 }980 981 break;982 983 default:984 return EINVAL;985 }986 987 988 989 990 }991 992 /**993 *994 */995 usb_hid_report_path_t *usb_hid_report_path(void)996 {997 usb_hid_report_path_t *path;998 path = malloc(sizeof(usb_hid_report_path_t));999 if(!path){1000 return NULL;1001 }1002 else {1003 path->depth = 0;1004 list_initialize(&path->link);1005 return path;1006 }1007 }1008 1009 /**1010 *1011 */1012 void usb_hid_report_path_free(usb_hid_report_path_t *path)1013 {1014 while(!list_empty(&path->link)){1015 usb_hid_report_remove_last_item(path);1016 }1017 }1018 1019 1020 /**1021 *1022 */1023 int usb_hid_report_path_clone(usb_hid_report_path_t *new_usage_path, usb_hid_report_path_t *usage_path)1024 {1025 usb_hid_report_usage_path_t *path_item;1026 link_t *path_link;1027 1028 1029 if(list_empty(&usage_path->link)){1030 return EOK;1031 }1032 1033 path_link = usage_path->link.next;1034 while(path_link != &usage_path->link) {1035 path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link);1036 usb_hid_report_path_append_item (new_usage_path, path_item->usage_page, path_item->usage);1037 1038 path_link = path_link->next;1039 }1040 1041 return EOK;1042 }1043 1044 759 1045 760 /** -
uspace/lib/usb/src/host/device_keeper.c
r291b8bc r889e8e3 49 49 assert(instance); 50 50 fibril_mutex_initialize(&instance->guard); 51 fibril_condvar_initialize(&instance-> change);51 fibril_condvar_initialize(&instance->default_address_occupied); 52 52 instance->last_address = 0; 53 53 unsigned i = 0; 54 54 for (; i < USB_ADDRESS_COUNT; ++i) { 55 55 instance->devices[i].occupied = false; 56 instance->devices[i].control_used = false;57 56 instance->devices[i].handle = 0; 58 57 instance->devices[i].toggle_status[0] = 0; … … 72 71 fibril_mutex_lock(&instance->guard); 73 72 while (instance->devices[USB_ADDRESS_DEFAULT].occupied) { 74 fibril_condvar_wait(&instance->change, &instance->guard); 73 fibril_condvar_wait(&instance->default_address_occupied, 74 &instance->guard); 75 75 } 76 76 instance->devices[USB_ADDRESS_DEFAULT].occupied = true; … … 90 90 instance->devices[USB_ADDRESS_DEFAULT].occupied = false; 91 91 fibril_mutex_unlock(&instance->guard); 92 fibril_condvar_signal(&instance-> change);92 fibril_condvar_signal(&instance->default_address_occupied); 93 93 } 94 94 /*----------------------------------------------------------------------------*/ … … 309 309 return instance->devices[address].speed; 310 310 } 311 /*----------------------------------------------------------------------------*/ 312 void usb_device_keeper_use_control(usb_device_keeper_t *instance, 313 usb_address_t address) 314 { 315 assert(instance); 316 fibril_mutex_lock(&instance->guard); 317 while (instance->devices[address].control_used) { 318 fibril_condvar_wait(&instance->change, &instance->guard); 319 } 320 instance->devices[address].control_used = true; 321 fibril_mutex_unlock(&instance->guard); 322 } 323 /*----------------------------------------------------------------------------*/ 324 void usb_device_keeper_release_control(usb_device_keeper_t *instance, 325 usb_address_t address) 326 { 327 assert(instance); 328 fibril_mutex_lock(&instance->guard); 329 instance->devices[address].control_used = false; 330 fibril_mutex_unlock(&instance->guard); 331 fibril_condvar_signal(&instance->change); 332 } 311 333 312 /** 334 313 * @}
Note:
See TracChangeset
for help on using the changeset viewer.