Changes in / [b666608:94c19b8] in mainline
- Files:
-
- 2 deleted
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/include/ipc/ipc.h
rb666608 r94c19b8 43 43 #define IPC_CALL_LEN 6 44 44 45 /** Maximum active async calls per phone */ 46 #define IPC_MAX_ASYNC_CALLS 4 45 /** Maximum active async calls per thread */ 46 #ifdef CONFIG_DEBUG 47 #define IPC_MAX_ASYNC_CALLS 16 48 #else 49 #define IPC_MAX_ASYNC_CALLS 4000 50 #endif 47 51 48 52 /* Flags for calls */ -
kernel/generic/include/proc/task.h
rb666608 r94c19b8 93 93 phone_t phones[IPC_MAX_PHONES]; 94 94 stats_ipc_t ipc_info; /**< IPC statistics */ 95 /** 96 * Active asynchronous messages. It is used for limiting uspace to 97 * certain extent. 98 */ 99 atomic_t active_calls; 95 100 /** List of synchronous answerboxes. */ 96 101 link_t sync_box_head; -
kernel/generic/src/ipc/ipc.c
rb666608 r94c19b8 655 655 (call->flags & IPC_CALL_NOTIF)); 656 656 657 /* 658 * Record the receipt of this call in the current task's counter 659 * of active calls. IPC_M_PHONE_HUNGUP calls do not contribute 660 * to this counter so do not record answers to them either. 661 */ 662 if (!(call->flags & IPC_CALL_DISCARD_ANSWER)) 663 atomic_dec(&TASK->active_calls); 664 657 665 ipc_call_free(call); 658 666 } -
kernel/generic/src/ipc/sysipc.c
rb666608 r94c19b8 644 644 } 645 645 646 /** Check that the task did not exceed the allowed limit of asynchronous calls 647 * made over a phone. 648 * 649 * @param phone Phone to check the limit against. 646 /** Check that the task did not exceed the allowed limit of asynchronous calls. 647 * 650 648 * @return 0 if limit not reached or -1 if limit exceeded. 651 649 * 652 650 */ 653 static int check_call_limit(phone_t *phone) 654 { 655 if (atomic_get(&phone->active_calls) >= IPC_MAX_ASYNC_CALLS) 651 static int check_call_limit(void) 652 { 653 if (atomic_preinc(&TASK->active_calls) > IPC_MAX_ASYNC_CALLS) { 654 atomic_dec(&TASK->active_calls); 656 655 return -1; 656 } 657 657 658 658 return 0; … … 680 680 unative_t arg1, unative_t arg2, unative_t arg3, unative_t arg4) 681 681 { 682 if (check_call_limit()) 683 return IPC_CALLRET_TEMPORARY; 684 682 685 phone_t *phone; 683 686 if (phone_get(phoneid, &phone) != EOK) 684 687 return IPC_CALLRET_FATAL; 685 686 if (check_call_limit(phone))687 return IPC_CALLRET_TEMPORARY;688 688 689 689 call_t *call = ipc_call_alloc(0); … … 720 720 unative_t sys_ipc_call_async_slow(unative_t phoneid, ipc_data_t *data) 721 721 { 722 if (check_call_limit()) 723 return IPC_CALLRET_TEMPORARY; 724 722 725 phone_t *phone; 723 726 if (phone_get(phoneid, &phone) != EOK) 724 727 return IPC_CALLRET_FATAL; 725 726 if (check_call_limit(phone))727 return IPC_CALLRET_TEMPORARY;728 728 729 729 call_t *call = ipc_call_alloc(0); … … 1046 1046 ipc_call_free(call); 1047 1047 goto restart; 1048 } else { 1049 /* 1050 * Decrement the counter of active calls only if the 1051 * call is not an answer to IPC_M_PHONE_HUNGUP, 1052 * which doesn't contribute to the counter. 1053 */ 1054 atomic_dec(&TASK->active_calls); 1048 1055 } 1049 1056 -
kernel/generic/src/proc/task.c
rb666608 r94c19b8 151 151 atomic_set(&task->refcount, 0); 152 152 atomic_set(&task->lifecount, 0); 153 atomic_set(&task->active_calls, 0); 153 154 154 155 irq_spinlock_initialize(&task->lock, "task_t_lock"); … … 477 478 #ifdef __32_BITS__ 478 479 if (*additional) 479 printf("%-8" PRIu64 " %9" PRIua , task->taskid,480 atomic_get(&task->refcount) );480 printf("%-8" PRIu64 " %9" PRIua " %7" PRIua, task->taskid, 481 atomic_get(&task->refcount), atomic_get(&task->active_calls)); 481 482 else 482 483 printf("%-8" PRIu64 " %-14s %-5" PRIu32 " %10p %10p" … … 489 490 if (*additional) 490 491 printf("%-8" PRIu64 " %9" PRIu64 "%c %9" PRIu64 "%c " 491 "%9" PRIua, task->taskid, ucycles, usuffix, kcycles, 492 ksuffix, atomic_get(&task->refcount)); 492 "%9" PRIua " %7" PRIua, 493 task->taskid, ucycles, usuffix, kcycles, ksuffix, 494 atomic_get(&task->refcount), atomic_get(&task->active_calls)); 493 495 else 494 496 printf("%-8" PRIu64 " %-14s %-5" PRIu32 " %18p %18p\n", -
uspace/app/usbinfo/dump.c
rb666608 r94c19b8 69 69 } 70 70 71 void dump_match_ids(match_id_list_t *matches)72 {73 printf("Match ids:\n");74 link_t *link;75 for (link = matches->ids.next;76 link != &matches->ids;77 link = link->next) {78 match_id_t *match = list_get_instance(link, match_id_t, link);79 80 printf(INDENT "%d %s\n", match->score, match->id);81 }82 }83 84 71 void dump_standard_device_descriptor(usb_standard_device_descriptor_t *d) 85 72 { -
uspace/app/usbinfo/main.c
rb666608 r94c19b8 112 112 113 113 /* 114 * Dump information about possible match ids.115 */116 match_id_list_t match_id_list;117 init_match_ids(&match_id_list);118 rc = usb_drv_create_device_match_ids(hc_phone, &match_id_list, address);119 if (rc != EOK) {120 fprintf(stderr,121 NAME ": failed to fetch match ids of the device: %s.\n",122 str_error(rc));123 return rc;124 }125 dump_match_ids(&match_id_list);126 127 /*128 114 * Get device descriptor and dump it. 129 115 */ -
uspace/app/usbinfo/usbinfo.h
rb666608 r94c19b8 39 39 #include <usb/descriptor.h> 40 40 #include <usb/debug.h> 41 #include <ipc/devman.h>42 41 43 42 … … 45 44 46 45 void dump_buffer(const char *, const uint8_t *, size_t); 47 void dump_match_ids(match_id_list_t *matches);48 46 void dump_standard_device_descriptor(usb_standard_device_descriptor_t *); 49 47 void dump_standard_configuration_descriptor(int, -
uspace/app/virtusbkbd/Makefile
rb666608 r94c19b8 33 33 34 34 LIBS = $(LIBUSB_PREFIX)/libusb.a $(LIBUSBVIRT_PREFIX)/libusbvirt.a 35 EXTRA_CFLAGS = -I$(LIBUSB_PREFIX)/include -I$(LIB_PREFIX) -I$(LIBDRV_PREFIX)/include35 EXTRA_CFLAGS = -I$(LIBUSB_PREFIX)/include -I$(LIB_PREFIX) 36 36 37 37 SOURCES = \ -
uspace/drv/usbkbd/main.c
rb666608 r94c19b8 28 28 #include <usb/usbdrv.h> 29 29 #include <driver.h> 30 #include <ipc/driver.h>31 30 #include <errno.h> 32 #include <fibril.h>33 #include <usb/classes/hid.h>34 #include <usb/classes/hidparser.h>35 #include <usb/devreq.h>36 #include <usb/descriptor.h>37 31 38 32 #define BUFFER_SIZE 32 39 #define NAME "usbkbd"40 33 41 static const usb_endpoint_t CONTROL_EP = 0; 42 43 /* 44 * Callbacks for parser 45 */ 46 static void usbkbd_process_keycodes(const uint16_t *key_codes, size_t count, 47 void *arg) 48 { 49 50 } 51 52 /* 53 * Kbd functions 54 */ 55 static int usbkbd_parse_descriptors(usb_hid_dev_kbd_t *kbd_dev, 56 const uint8_t *data, size_t size) 57 { 58 // const uint8_t *pos = data; 59 60 // // get the configuration descriptor (should be first) 61 // if (*pos != sizeof(usb_standard_configuration_descriptor_t) 62 // || *(pos + 1) != USB_DESCTYPE_CONFIGURATION) { 63 // fprintf(stderr, "Wrong format of configuration descriptor"); 64 // return EINVAL; 65 // } 66 67 // usb_standard_configuration_descriptor_t config_descriptor; 68 // memcpy(&config_descriptor, pos, 69 // sizeof(usb_standard_configuration_descriptor_t)); 70 // pos += sizeof(usb_standard_configuration_descriptor_t); 71 72 // // parse other descriptors 73 // while (pos - data < size) { 74 // //uint8_t desc_size = *pos; 75 // uint8_t desc_type = *(pos + 1); 76 // switch (desc_type) { 77 // case USB_DESCTYPE_INTERFACE: 78 // break; 79 // case USB_DESCTYPE_ENDPOINT: 80 // break; 81 // case USB_DESCTYPE_HID: 82 // break; 83 // case USB_DESCTYPE_HID_REPORT: 84 // break; 85 // case USB_DESCTYPE_HID_PHYSICAL: 86 // break; 87 // } 88 // } 89 90 return EOK; 91 } 92 93 static int usbkbd_get_descriptors(usb_hid_dev_kbd_t *kbd_dev) 94 { 95 // get the first configuration descriptor (TODO: or some other??) 96 usb_standard_configuration_descriptor_t config_desc; 97 98 int rc = usb_drv_req_get_bare_configuration_descriptor( 99 kbd_dev->device->parent_phone, kbd_dev->address, 0, &config_desc); 100 101 if (rc != EOK) { 102 return rc; 103 } 104 105 // prepare space for all underlying descriptors 106 uint8_t *descriptors = (uint8_t *)malloc(config_desc.total_length); 107 if (descriptors == NULL) { 108 return ENOMEM; 109 } 110 111 size_t transferred = 0; 112 // get full configuration descriptor 113 rc = usb_drv_req_get_full_configuration_descriptor( 114 kbd_dev->device->parent_phone, kbd_dev->address, 0, descriptors, 115 config_desc.total_length, &transferred); 116 117 if (rc != EOK) { 118 return rc; 119 } 120 if (transferred != config_desc.total_length) { 121 return ELIMIT; 122 } 123 124 rc = usbkbd_parse_descriptors(kbd_dev, descriptors, transferred); 125 free(descriptors); 126 127 return rc; 128 } 129 130 static usb_hid_dev_kbd_t *usbkbd_init_device(device_t *dev) 131 { 132 usb_hid_dev_kbd_t *kbd_dev = (usb_hid_dev_kbd_t *)malloc( 133 sizeof(usb_hid_dev_kbd_t)); 134 135 if (kbd_dev == NULL) { 136 fprintf(stderr, NAME ": No memory!\n"); 137 return NULL; 138 } 139 140 kbd_dev->device = dev; 141 142 // get phone to my HC and save it as my parent's phone 143 // TODO: maybe not a good idea if DDF will use parent_phone 144 kbd_dev->device->parent_phone = usb_drv_hc_connect(dev, 0); 145 146 kbd_dev->address = usb_drv_get_my_address(dev->parent_phone, 147 dev); 148 149 // doesn't matter now that we have no address 150 // if (kbd_dev->address < 0) { 151 // fprintf(stderr, NAME ": No device address!\n"); 152 // free(kbd_dev); 153 // return NULL; 154 // } 155 156 // default endpoint 157 kbd_dev->default_ep = CONTROL_EP; 158 159 /* 160 * will need all descriptors: 161 * 1) choose one configuration from configuration descriptors 162 * (set it to the device) 163 * 2) set endpoints from endpoint descriptors 164 */ 165 166 // TODO: get descriptors 167 usbkbd_get_descriptors(kbd_dev); 168 // TODO: parse descriptors and save endpoints 169 170 return kbd_dev; 171 } 172 173 static void usbkbd_process_interrupt_in(usb_hid_dev_kbd_t *kbd_dev, 174 uint8_t *buffer, size_t actual_size) 175 { 176 /* 177 * here, the parser will be called, probably with some callbacks 178 * now only take last 6 bytes and process, i.e. send to kbd 179 */ 180 181 usb_hid_report_in_callbacks_t *callbacks = 182 (usb_hid_report_in_callbacks_t *)malloc( 183 sizeof(usb_hid_report_in_callbacks_t)); 184 callbacks->keyboard = usbkbd_process_keycodes; 185 186 usb_hid_parse_report(kbd_dev->parser, buffer, actual_size, callbacks, 187 NULL); 188 } 189 190 static void usbkbd_poll_keyboard(usb_hid_dev_kbd_t *kbd_dev) 34 /* Call this periodically to check keyboard status changes. */ 35 static void poll_keyboard(device_t *dev) 191 36 { 192 37 int rc; 193 38 usb_handle_t handle; 194 uint8_tbuffer[BUFFER_SIZE];39 char buffer[BUFFER_SIZE]; 195 40 size_t actual_size; 196 //usb_endpoint_t poll_endpoint = 1;41 usb_endpoint_t poll_endpoint = 1; 197 42 198 //usb_address_t my_address = usb_drv_get_my_address(dev->parent_phone,199 //dev);200 //if (my_address < 0) {201 //return;202 //}43 usb_address_t my_address = usb_drv_get_my_address(dev->parent_phone, 44 dev); 45 if (my_address < 0) { 46 return; 47 } 203 48 204 49 usb_target_t poll_target = { 205 .address = kbd_dev->address,206 .endpoint = kbd_dev->default_ep50 .address = my_address, 51 .endpoint = poll_endpoint 207 52 }; 208 53 209 while (true) { 210 rc = usb_drv_async_interrupt_in(kbd_dev->device->parent_phone, 211 poll_target, buffer, BUFFER_SIZE, &actual_size, &handle); 212 213 if (rc != EOK) { 214 continue; 215 } 216 217 rc = usb_drv_async_wait_for(handle); 218 if (rc != EOK) { 219 continue; 220 } 221 222 /* 223 * If the keyboard answered with NAK, it returned no data. 224 * This implies that no change happened since last query. 225 */ 226 if (actual_size == 0) { 227 continue; 228 } 229 230 /* 231 * TODO: Process pressed keys. 232 */ 233 usbkbd_process_interrupt_in(kbd_dev, buffer, actual_size); 54 rc = usb_drv_async_interrupt_in(dev->parent_phone, poll_target, 55 buffer, BUFFER_SIZE, &actual_size, &handle); 56 if (rc != EOK) { 57 return; 234 58 } 235 59 236 // not reached 237 assert(0); 60 rc = usb_drv_async_wait_for(handle); 61 if (rc != EOK) { 62 return; 63 } 64 65 /* 66 * If the keyboard answered with NAK, it returned no data. 67 * This implies that no change happened since last query. 68 */ 69 if (actual_size == 0) { 70 return; 71 } 72 73 /* 74 * Process pressed keys. 75 */ 238 76 } 239 77 240 static int usbkbd_fibril_device(void *arg) 241 { 242 printf("!!! USB device fibril\n"); 243 244 if (arg == NULL) { 245 printf("No device!\n"); 246 return -1; 247 } 248 249 device_t *dev = (device_t *)arg; 250 251 // initialize device (get and process descriptors, get address, etc.) 252 usb_hid_dev_kbd_t *kbd_dev = usbkbd_init_device(dev); 253 254 usbkbd_poll_keyboard(kbd_dev); 255 256 return EOK; 257 } 258 259 static int usbkbd_add_device(device_t *dev) 78 static int add_kbd_device(device_t *dev) 260 79 { 261 80 /* For now, fail immediately. */ 262 //return ENOTSUP;81 return ENOTSUP; 263 82 264 83 /* 265 84 * When everything is okay, connect to "our" HC. 266 *267 * Not supported yet, skip..268 85 */ 269 //int phone = usb_drv_hc_connect(dev, 0);270 //if (phone < 0) {271 ///*272 //* Connecting to HC failed, roll-back and announce273 //* failure.274 //*/275 //return phone;276 //}86 int phone = usb_drv_hc_connect(dev, 0); 87 if (phone < 0) { 88 /* 89 * Connecting to HC failed, roll-back and announce 90 * failure. 91 */ 92 return phone; 93 } 277 94 278 //dev->parent_phone = phone;95 dev->parent_phone = phone; 279 96 280 97 /* 281 * Create new fibril for handling this keyboard98 * Just for fun ;-). 282 99 */ 283 fid_t fid = fibril_create(usbkbd_fibril_device, dev); 284 if (fid == 0) { 285 printf("%s: failed to start fibril for HID device\n", NAME); 286 return ENOMEM; 287 } 288 fibril_add_ready(fid); 100 poll_keyboard(dev); 289 101 290 102 /* … … 295 107 296 108 static driver_ops_t kbd_driver_ops = { 297 .add_device = usbkbd_add_device,109 .add_device = add_kbd_device, 298 110 }; 299 111 300 112 static driver_t kbd_driver = { 301 .name = NAME,113 .name = "usbkbd", 302 114 .driver_ops = &kbd_driver_ops 303 115 }; -
uspace/lib/usb/Makefile
rb666608 r94c19b8 34 34 SOURCES = \ 35 35 src/addrkeep.c \ 36 src/class.c \37 36 src/debug.c \ 38 37 src/drvpsync.c \ … … 41 40 src/hidparser.c \ 42 41 src/localdrv.c \ 43 src/recognise.c \44 42 src/remotedrv.c \ 45 43 src/usb.c \ -
uspace/lib/usb/include/usb/classes/classes.h
rb666608 r94c19b8 60 60 } usb_class_t; 61 61 62 const char *usb_str_class(usb_class_t);63 62 64 63 #endif -
uspace/lib/usb/include/usb/classes/hid.h
rb666608 r94c19b8 36 36 #define LIBUSB_HID_H_ 37 37 38 #include <usb/usb.h>39 #include <driver.h>40 #include <usb/classes/hidparser.h>41 42 38 /** USB/HID device requests. */ 43 39 typedef enum { … … 58 54 } usb_hid_protocol_t; 59 55 60 /** Part of standard USB HID descriptor specifying one class descriptor.61 *62 * (See HID Specification, p.22)63 */64 typedef struct {65 /** Type of class descriptor (Report or Physical). */66 uint8_t class_descriptor_type;67 /** Length of class descriptor. */68 uint16_t class_descriptor_length;69 } __attribute__ ((packed)) usb_standard_hid_descriptor_class_item_t;70 71 /** Standard USB HID descriptor.72 *73 * (See HID Specification, p.22)74 *75 * It is actually only the "header" of the descriptor, as it may have arbitrary76 * length if more than one class descritor is provided.77 */78 typedef struct {79 /** Size of this descriptor in bytes. */80 uint8_t length;81 /** Descriptor type (USB_DESCTYPE_HID). */82 uint8_t descriptor_type;83 /** HID Class Specification release. */84 uint16_t spec_release;85 /** Country code of localized hardware. */86 uint8_t country_code;87 /** Total number of class (i.e. Report and Physical) descriptors. */88 uint8_t class_count;89 /** First mandatory class descriptor info. */90 usb_standard_hid_descriptor_class_item_t class_descriptor;91 } __attribute__ ((packed)) usb_standard_hid_descriptor_t;92 93 94 /**95 * @brief USB/HID keyboard device type.96 *97 * Quite dummy right now.98 */99 typedef struct {100 device_t *device;101 usb_address_t address;102 usb_endpoint_t default_ep;103 usb_hid_report_parser_t *parser;104 } usb_hid_dev_kbd_t;105 106 56 #endif 107 57 /** -
uspace/lib/usb/include/usb/classes/hidparser.h
rb666608 r94c19b8 50 50 * @param arg Custom argument. 51 51 */ 52 void (*keyboard)(const uint 16_t *key_codes, size_t count, void *arg);52 void (*keyboard)(const uint32_t *key_codes, size_t count, void *arg); 53 53 } usb_hid_report_in_callbacks_t; 54 54 55 55 int usb_hid_parse_report_descriptor(usb_hid_report_parser_t *parser, 56 const uint8_t *data , size_t size);56 const uint8_t *data); 57 57 58 58 int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 59 const uint8_t *data, size_t size,59 const uint8_t *data, 60 60 const usb_hid_report_in_callbacks_t *callbacks, void *arg); 61 61 -
uspace/lib/usb/include/usb/usbdrv.h
rb666608 r94c19b8 94 94 int usb_drv_async_wait_for(usb_handle_t); 95 95 96 int usb_drv_create_device_match_ids(int, match_id_list_t *, usb_address_t);97 int usb_drv_register_child_in_devman(int, device_t *, usb_address_t,98 devman_handle_t *);99 100 96 101 97 #endif -
uspace/lib/usb/src/hidparser.c
rb666608 r94c19b8 40 40 * @param parser Opaque HID report parser structure. 41 41 * @param data Data describing the report. 42 * @param size Size of the descriptor in bytes.43 42 * @return Error code. 44 43 */ 45 44 int usb_hid_parse_report_descriptor(usb_hid_report_parser_t *parser, 46 const uint8_t *data , size_t size)45 const uint8_t *data) 47 46 { 48 47 return ENOTSUP; … … 55 54 * @param parser Opaque HID report parser structure. 56 55 * @param data Data for the report. 57 * @param size Size of the data in bytes.58 56 * @param callbacks Callbacks for report actions. 59 57 * @param arg Custom argument (passed through to the callbacks). … … 61 59 */ 62 60 int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 63 const uint8_t *data, size_t size,61 const uint8_t *data, 64 62 const usb_hid_report_in_callbacks_t *callbacks, void *arg) 65 63 { 66 int i; 67 68 // TODO: parse report 69 70 uint16_t keys[6]; 71 72 for (i = 0; i < 6; ++i) { 73 keys[i] = data[i]; 74 } 75 76 callbacks->keyboard(keys, 6, arg); 77 78 return EOK; 64 return ENOTSUP; 79 65 } 80 66 -
uspace/lib/usb/src/usbdrvreq.c
rb666608 r94c19b8 162 162 .request = USB_DEVREQ_GET_DESCRIPTOR, 163 163 .index = 0, 164 .length = sizeof(usb_standard_ configuration_descriptor_t)164 .length = sizeof(usb_standard_device_descriptor_t) 165 165 }; 166 166 setup_packet.value_high = USB_DESCTYPE_CONFIGURATION; … … 225 225 .request = USB_DEVREQ_GET_DESCRIPTOR, 226 226 .index = 0, 227 .length = buffer_size227 .length = sizeof(usb_standard_device_descriptor_t) 228 228 }; 229 229 setup_packet.value_high = USB_DESCTYPE_CONFIGURATION; -
uspace/srv/devman/devman.c
rb666608 r94c19b8 686 686 } 687 687 688 static FIBRIL_MUTEX_INITIALIZE(add_device_guard); 689 688 690 /** Pass a device to running driver. 689 691 * … … 693 695 void add_device(int phone, driver_t *drv, node_t *node, dev_tree_t *tree) 694 696 { 697 fibril_mutex_lock(&add_device_guard); 698 695 699 /* 696 700 * We do not expect to have driver's mutex locked as we do not … … 723 727 /* Wait for answer from the driver. */ 724 728 async_wait_for(req, &rc); 729 730 fibril_mutex_unlock(&add_device_guard); 725 731 726 732 switch(rc) {
Note:
See TracChangeset
for help on using the changeset viewer.