Changeset b666608 in mainline
- Timestamp:
- 2010-12-12T13:49:35Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 4c74ac3
- Parents:
- 94c19b8 (diff), 0c05496 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Files:
-
- 2 added
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/include/ipc/ipc.h
r94c19b8 rb666608 43 43 #define IPC_CALL_LEN 6 44 44 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 45 /** Maximum active async calls per phone */ 46 #define IPC_MAX_ASYNC_CALLS 4 51 47 52 48 /* Flags for calls */ -
kernel/generic/include/proc/task.h
r94c19b8 rb666608 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 to97 * certain extent.98 */99 atomic_t active_calls;100 95 /** List of synchronous answerboxes. */ 101 96 link_t sync_box_head; -
kernel/generic/src/ipc/ipc.c
r94c19b8 rb666608 655 655 (call->flags & IPC_CALL_NOTIF)); 656 656 657 /*658 * Record the receipt of this call in the current task's counter659 * of active calls. IPC_M_PHONE_HUNGUP calls do not contribute660 * 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 665 657 ipc_call_free(call); 666 658 } -
kernel/generic/src/ipc/sysipc.c
r94c19b8 rb666608 644 644 } 645 645 646 /** Check that the task did not exceed the allowed limit of asynchronous calls. 647 * 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. 648 650 * @return 0 if limit not reached or -1 if limit exceeded. 649 651 * 650 652 */ 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); 653 static int check_call_limit(phone_t *phone) 654 { 655 if (atomic_get(&phone->active_calls) >= IPC_MAX_ASYNC_CALLS) 655 656 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 685 682 phone_t *phone; 686 683 if (phone_get(phoneid, &phone) != EOK) 687 684 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 725 722 phone_t *phone; 726 723 if (phone_get(phoneid, &phone) != EOK) 727 724 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 the1051 * 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);1055 1048 } 1056 1049 -
kernel/generic/src/proc/task.c
r94c19b8 rb666608 151 151 atomic_set(&task->refcount, 0); 152 152 atomic_set(&task->lifecount, 0); 153 atomic_set(&task->active_calls, 0);154 153 155 154 irq_spinlock_initialize(&task->lock, "task_t_lock"); … … 478 477 #ifdef __32_BITS__ 479 478 if (*additional) 480 printf("%-8" PRIu64 " %9" PRIua " %7" PRIua, task->taskid,481 atomic_get(&task->refcount) , atomic_get(&task->active_calls));479 printf("%-8" PRIu64 " %9" PRIua, task->taskid, 480 atomic_get(&task->refcount)); 482 481 else 483 482 printf("%-8" PRIu64 " %-14s %-5" PRIu32 " %10p %10p" … … 490 489 if (*additional) 491 490 printf("%-8" PRIu64 " %9" PRIu64 "%c %9" PRIu64 "%c " 492 "%9" PRIua " %7" PRIua, 493 task->taskid, ucycles, usuffix, kcycles, ksuffix, 494 atomic_get(&task->refcount), atomic_get(&task->active_calls)); 491 "%9" PRIua, task->taskid, ucycles, usuffix, kcycles, 492 ksuffix, atomic_get(&task->refcount)); 495 493 else 496 494 printf("%-8" PRIu64 " %-14s %-5" PRIu32 " %18p %18p\n", -
uspace/app/usbinfo/dump.c
r94c19b8 rb666608 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 71 84 void dump_standard_device_descriptor(usb_standard_device_descriptor_t *d) 72 85 { -
uspace/app/usbinfo/main.c
r94c19b8 rb666608 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 /* 114 128 * Get device descriptor and dump it. 115 129 */ -
uspace/app/usbinfo/usbinfo.h
r94c19b8 rb666608 39 39 #include <usb/descriptor.h> 40 40 #include <usb/debug.h> 41 #include <ipc/devman.h> 41 42 42 43 … … 44 45 45 46 void dump_buffer(const char *, const uint8_t *, size_t); 47 void dump_match_ids(match_id_list_t *matches); 46 48 void dump_standard_device_descriptor(usb_standard_device_descriptor_t *); 47 49 void dump_standard_configuration_descriptor(int, -
uspace/app/virtusbkbd/Makefile
r94c19b8 rb666608 33 33 34 34 LIBS = $(LIBUSB_PREFIX)/libusb.a $(LIBUSBVIRT_PREFIX)/libusbvirt.a 35 EXTRA_CFLAGS = -I$(LIBUSB_PREFIX)/include -I$(LIB_PREFIX) 35 EXTRA_CFLAGS = -I$(LIBUSB_PREFIX)/include -I$(LIB_PREFIX) -I$(LIBDRV_PREFIX)/include 36 36 37 37 SOURCES = \ -
uspace/drv/usbkbd/main.c
r94c19b8 rb666608 28 28 #include <usb/usbdrv.h> 29 29 #include <driver.h> 30 #include <ipc/driver.h> 30 31 #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> 31 37 32 38 #define BUFFER_SIZE 32 33 34 /* Call this periodically to check keyboard status changes. */ 35 static void poll_keyboard(device_t *dev) 39 #define NAME "usbkbd" 40 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) 36 191 { 37 192 int rc; 38 193 usb_handle_t handle; 39 charbuffer[BUFFER_SIZE];194 uint8_t buffer[BUFFER_SIZE]; 40 195 size_t actual_size; 41 usb_endpoint_t poll_endpoint = 1;42 43 usb_address_t my_address = usb_drv_get_my_address(dev->parent_phone,44 dev);45 if (my_address < 0) {46 return;47 }196 //usb_endpoint_t poll_endpoint = 1; 197 198 // usb_address_t my_address = usb_drv_get_my_address(dev->parent_phone, 199 // dev); 200 // if (my_address < 0) { 201 // return; 202 // } 48 203 49 204 usb_target_t poll_target = { 50 .address = my_address,51 .endpoint = poll_endpoint205 .address = kbd_dev->address, 206 .endpoint = kbd_dev->default_ep 52 207 }; 53 208 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; 58 } 59 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 */ 76 } 77 78 static int add_kbd_device(device_t *dev) 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); 234 } 235 236 // not reached 237 assert(0); 238 } 239 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) 79 260 { 80 261 /* For now, fail immediately. */ 81 return ENOTSUP;262 //return ENOTSUP; 82 263 83 264 /* 84 265 * When everything is okay, connect to "our" HC. 85 */ 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 } 94 95 dev->parent_phone = phone; 96 97 /* 98 * Just for fun ;-). 99 */ 100 poll_keyboard(dev); 266 * 267 * Not supported yet, skip.. 268 */ 269 // int phone = usb_drv_hc_connect(dev, 0); 270 // if (phone < 0) { 271 // /* 272 // * Connecting to HC failed, roll-back and announce 273 // * failure. 274 // */ 275 // return phone; 276 // } 277 278 // dev->parent_phone = phone; 279 280 /* 281 * Create new fibril for handling this keyboard 282 */ 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); 101 289 102 290 /* … … 107 295 108 296 static driver_ops_t kbd_driver_ops = { 109 .add_device = add_kbd_device,297 .add_device = usbkbd_add_device, 110 298 }; 111 299 112 300 static driver_t kbd_driver = { 113 .name = "usbkbd",301 .name = NAME, 114 302 .driver_ops = &kbd_driver_ops 115 303 }; -
uspace/lib/usb/Makefile
r94c19b8 rb666608 34 34 SOURCES = \ 35 35 src/addrkeep.c \ 36 src/class.c \ 36 37 src/debug.c \ 37 38 src/drvpsync.c \ … … 40 41 src/hidparser.c \ 41 42 src/localdrv.c \ 43 src/recognise.c \ 42 44 src/remotedrv.c \ 43 45 src/usb.c \ -
uspace/lib/usb/include/usb/classes/classes.h
r94c19b8 rb666608 60 60 } usb_class_t; 61 61 62 const char *usb_str_class(usb_class_t); 62 63 63 64 #endif -
uspace/lib/usb/include/usb/classes/hid.h
r94c19b8 rb666608 36 36 #define LIBUSB_HID_H_ 37 37 38 #include <usb/usb.h> 39 #include <driver.h> 40 #include <usb/classes/hidparser.h> 41 38 42 /** USB/HID device requests. */ 39 43 typedef enum { … … 54 58 } usb_hid_protocol_t; 55 59 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 arbitrary 76 * 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 56 106 #endif 57 107 /** -
uspace/lib/usb/include/usb/classes/hidparser.h
r94c19b8 rb666608 50 50 * @param arg Custom argument. 51 51 */ 52 void (*keyboard)(const uint 32_t *key_codes, size_t count, void *arg);52 void (*keyboard)(const uint16_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 );56 const uint8_t *data, size_t size); 57 57 58 58 int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 59 const uint8_t *data, 59 const uint8_t *data, size_t size, 60 60 const usb_hid_report_in_callbacks_t *callbacks, void *arg); 61 61 -
uspace/lib/usb/include/usb/usbdrv.h
r94c19b8 rb666608 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 96 100 97 101 #endif -
uspace/lib/usb/src/hidparser.c
r94c19b8 rb666608 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. 42 43 * @return Error code. 43 44 */ 44 45 int usb_hid_parse_report_descriptor(usb_hid_report_parser_t *parser, 45 const uint8_t *data )46 const uint8_t *data, size_t size) 46 47 { 47 48 return ENOTSUP; … … 54 55 * @param parser Opaque HID report parser structure. 55 56 * @param data Data for the report. 57 * @param size Size of the data in bytes. 56 58 * @param callbacks Callbacks for report actions. 57 59 * @param arg Custom argument (passed through to the callbacks). … … 59 61 */ 60 62 int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 61 const uint8_t *data, 63 const uint8_t *data, size_t size, 62 64 const usb_hid_report_in_callbacks_t *callbacks, void *arg) 63 65 { 64 return ENOTSUP; 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; 65 79 } 66 80 -
uspace/lib/usb/src/usbdrvreq.c
r94c19b8 rb666608 162 162 .request = USB_DEVREQ_GET_DESCRIPTOR, 163 163 .index = 0, 164 .length = sizeof(usb_standard_ device_descriptor_t)164 .length = sizeof(usb_standard_configuration_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 = sizeof(usb_standard_device_descriptor_t)227 .length = buffer_size 228 228 }; 229 229 setup_packet.value_high = USB_DESCTYPE_CONFIGURATION; -
uspace/srv/devman/devman.c
r94c19b8 rb666608 686 686 } 687 687 688 static FIBRIL_MUTEX_INITIALIZE(add_device_guard);689 690 688 /** Pass a device to running driver. 691 689 * … … 695 693 void add_device(int phone, driver_t *drv, node_t *node, dev_tree_t *tree) 696 694 { 697 fibril_mutex_lock(&add_device_guard);698 699 695 /* 700 696 * We do not expect to have driver's mutex locked as we do not … … 727 723 /* Wait for answer from the driver. */ 728 724 async_wait_for(req, &rc); 729 730 fibril_mutex_unlock(&add_device_guard);731 725 732 726 switch(rc) {
Note:
See TracChangeset
for help on using the changeset viewer.