Changeset 64ce0c1 in mainline
- Timestamp:
- 2018-02-02T10:13:55Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 961a5ee
- Parents:
- e67c50a (diff), 290338b (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. - Location:
- uspace
- Files:
-
- 1 added
- 1 deleted
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/tmon/Makefile
re67c50a r64ce0c1 30 30 BINARY = tmon 31 31 32 LIBS = drv 32 LIBS = drv usb 33 33 34 34 SOURCES = \ … … 36 36 list.c\ 37 37 tf.c\ 38 burst_tests.c\38 tests.c\ 39 39 resolve.c 40 40 -
uspace/app/tmon/commands.h
re67c50a r64ce0c1 42 42 int tmon_list(int, char **); 43 43 44 /* Burst tests read/write into endpoints as fast as possible. */45 int tmon_ burst_intr_in(int, char **);46 int tmon_ burst_intr_out(int, char **);47 int tmon_ burst_bulk_in(int, char **);48 int tmon_ burst_bulk_out(int, char **);49 int tmon_ burst_isoch_in(int, char **);50 int tmon_ burst_isoch_out(int, char **);44 /* Tests commands differ by endpoint types. */ 45 int tmon_test_intr_in(int, char **); 46 int tmon_test_intr_out(int, char **); 47 int tmon_test_bulk_in(int, char **); 48 int tmon_test_bulk_out(int, char **); 49 int tmon_test_isoch_in(int, char **); 50 int tmon_test_isoch_out(int, char **); 51 51 52 52 #endif /* TMON_COMMANDS_H_ */ -
uspace/app/tmon/main.c
re67c50a r64ce0c1 64 64 .name = "test-intr-in", 65 65 .description = "Read from interrupt endpoint as fast as possible.", 66 .action = tmon_ burst_intr_in,66 .action = tmon_test_intr_in, 67 67 }, 68 68 { 69 69 .name = "test-intr-out", 70 70 .description = "Write to interrupt endpoint as fast as possible.", 71 .action = tmon_ burst_intr_out,71 .action = tmon_test_intr_out, 72 72 }, 73 73 { 74 74 .name = "test-bulk-in", 75 75 .description = "Read from bulk endpoint as fast as possible.", 76 .action = tmon_ burst_bulk_in,76 .action = tmon_test_bulk_in, 77 77 }, 78 78 { 79 79 .name = "test-bulk-out", 80 80 .description = "Write to bulk endpoint as fast as possible.", 81 .action = tmon_ burst_bulk_out,81 .action = tmon_test_bulk_out, 82 82 }, 83 83 { 84 84 .name = "test-isoch-in", 85 85 .description = "Read from isochronous endpoint as fast as possible.", 86 .action = tmon_ burst_isoch_in,86 .action = tmon_test_isoch_in, 87 87 }, 88 88 { 89 89 .name = "test-isoch-out", 90 90 .description = "Write to isochronous endpoint as fast as possible.", 91 .action = tmon_ burst_isoch_out,92 } 91 .action = tmon_test_isoch_out, 92 }, 93 93 }; 94 94 … … 106 106 static tmon_opt_t options[] = { 107 107 { 108 .long_name = " cycles",109 .short_name = ' n',110 .description = "Set the number of read/write cycles."108 .long_name = "duration", 109 .short_name = 't', 110 .description = "Set the minimum test duration (in seconds)." 111 111 }, 112 112 { 113 113 .long_name = "size", 114 114 .short_name = 's', 115 .description = "Set the data size transferred in a single cycle." 116 } 115 .description = "Set the data size (in bytes) transferred in a single cycle." 116 }, 117 { 118 .long_name = "validate", 119 .short_name = 'v', 120 .description = "Validate the correctness of transferred data (impacts performance)." 121 }, 117 122 }; 118 123 -
uspace/app/tmon/tf.c
re67c50a r64ce0c1 36 36 37 37 #include <stdio.h> 38 #include <macros.h> 38 39 #include <devman.h> 39 40 #include <str_error.h> … … 74 75 } 75 76 76 printf(" Using device: %s\n", path);77 printf("Device: %s\n", path); 77 78 78 79 // Read test parameters from options. 79 tmon_test_params_t*params = NULL;80 void *params = NULL; 80 81 if ((rc = ops->read_params(argc, argv, ¶ms))) { 81 82 printf(NAME ": Reading test parameters failed. %s\n", str_error(rc)); 83 return 1; 84 } 85 86 if ((rc = ops->pre_run(params))) { 87 printf(NAME ": Pre-run hook failed. %s\n", str_error(rc)); 82 88 return 1; 83 89 } … … 106 112 } 107 113 114 /** Unit of quantity used for pretty formatting. */ 115 typedef struct tmon_unit { 116 /** Prefix letter, which is printed before the actual unit. */ 117 const char *unit; 118 /** Factor of the unit. */ 119 double factor; 120 } tmon_unit_t; 121 122 /** Format a value for human reading. 123 * @param[in] val The value to format. 124 * @param[in] fmt Format string. Must include one double and char. 125 * 126 * @return Heap-allocated string if successful (caller becomes its owner), NULL otherwise. 127 */ 128 static char *format_unit(double val, const char *fmt, const tmon_unit_t *units, size_t len) 129 { 130 // Figure out the "tightest" unit. 131 unsigned i; 132 for (i = 0; i < len; ++i) { 133 if (units[i].factor <= val) 134 break; 135 } 136 137 if (i == len) --i; 138 const char *unit = units[i].unit; 139 double factor = units[i].factor; 140 141 // Format the size. 142 const double div_size = val / factor; 143 144 char *out = NULL; 145 asprintf(&out, fmt, div_size, unit); 146 147 return out; 148 } 149 150 /** Static array of size units with decreasing factors. */ 151 static const tmon_unit_t size_units[] = { 152 { .unit = "EB", .factor = 1ULL << 60 }, 153 { .unit = "PB", .factor = 1ULL << 50 }, 154 { .unit = "TB", .factor = 1ULL << 40 }, 155 { .unit = "GB", .factor = 1ULL << 30 }, 156 { .unit = "MB", .factor = 1ULL << 20 }, 157 { .unit = "kB", .factor = 1ULL << 10 }, 158 { .unit = "B", .factor = 1ULL }, 159 }; 160 161 char *tmon_format_size(double val, const char *fmt) 162 { 163 return format_unit(val, fmt, size_units, ARRAY_SIZE(size_units)); 164 } 165 166 /** Static array of duration units with decreasing factors. */ 167 static const tmon_unit_t dur_units[] = { 168 { .unit = "d", .factor = 60 * 60 * 24 }, 169 { .unit = "h", .factor = 60 * 60 }, 170 { .unit = "min", .factor = 60 }, 171 { .unit = "s", .factor = 1 }, 172 { .unit = "ms", .factor = 1e-3 }, 173 { .unit = "us", .factor = 1e-6 }, 174 { .unit = "ns", .factor = 1e-9 }, 175 { .unit = "ps", .factor = 1e-12 }, 176 }; 177 178 char *tmon_format_duration(usbdiag_dur_t val, const char *fmt) 179 { 180 return format_unit(val / 1000.0, fmt, dur_units, ARRAY_SIZE(dur_units)); 181 } 182 108 183 /** @} 109 184 */ -
uspace/app/tmon/tf.h
re67c50a r64ce0c1 38 38 39 39 #include <async.h> 40 41 /** Parameters common for all tests. */ 42 typedef struct tmon_test_params { 43 /* Nothing here. */ 44 } tmon_test_params_t; 40 #include <usbdiag_iface.h> 45 41 46 42 /** Operations to implement by all tests. */ 47 43 typedef struct tmon_test_ops { 48 int (*run)(async_exch_t *, const tmon_test_params_t *); 49 int (*read_params)(int, char **, tmon_test_params_t **); 44 int (*pre_run)(void *); 45 int (*run)(async_exch_t *, const void *); 46 int (*read_params)(int, char **, void **); 50 47 } tmon_test_ops_t; 51 48 52 49 int tmon_test_main(int, char **, const tmon_test_ops_t *); 50 51 char *tmon_format_size(double, const char *); 52 char *tmon_format_duration(usbdiag_dur_t, const char *); 53 53 54 54 #endif /* TMON_TF_H_ */ -
uspace/drv/bus/usb/usbdiag/device.c
re67c50a r64ce0c1 46 46 47 47 static usbdiag_iface_t diag_interface = { 48 .burst_intr_in = usbdiag_burst_test_intr_in, 49 .burst_intr_out = usbdiag_burst_test_intr_out, 50 .burst_bulk_in = usbdiag_burst_test_bulk_in, 51 .burst_bulk_out = usbdiag_burst_test_bulk_out, 52 .burst_isoch_in = usbdiag_burst_test_isoch_in, 53 .burst_isoch_out = usbdiag_burst_test_isoch_out, 54 .data_intr_in = usbdiag_data_test_intr_in, 55 .data_intr_out = usbdiag_data_test_intr_out, 56 .data_bulk_in = usbdiag_data_test_bulk_in, 57 .data_bulk_out = usbdiag_data_test_bulk_out, 58 .data_isoch_in = usbdiag_data_test_isoch_in, 59 .data_isoch_out = usbdiag_data_test_isoch_out 48 .test_in = usbdiag_dev_test_in, 49 .test_out = usbdiag_dev_test_out, 60 50 }; 61 51 … … 86 76 } while (0); 87 77 88 _MAP_EP(dev->intr_in, INTR_IN); 89 _MAP_EP(dev->intr_out, INTR_OUT); 90 _MAP_EP(dev->bulk_in, BULK_IN); 91 _MAP_EP(dev->bulk_out, BULK_OUT); 92 _MAP_EP(dev->isoch_in, ISOCH_IN); 93 _MAP_EP(dev->isoch_out, ISOCH_OUT); 78 _MAP_EP(dev->burst_intr_in, BURST_INTR_IN); 79 _MAP_EP(dev->burst_intr_out, BURST_INTR_OUT); 80 _MAP_EP(dev->burst_bulk_in, BURST_BULK_IN); 81 _MAP_EP(dev->burst_bulk_out, BURST_BULK_OUT); 82 _MAP_EP(dev->burst_isoch_in, BURST_ISOCH_IN); 83 _MAP_EP(dev->burst_isoch_out, BURST_ISOCH_OUT); 84 _MAP_EP(dev->data_intr_in, DATA_INTR_IN); 85 _MAP_EP(dev->data_intr_out, DATA_INTR_OUT); 86 _MAP_EP(dev->data_bulk_in, DATA_BULK_IN); 87 _MAP_EP(dev->data_bulk_out, DATA_BULK_OUT); 88 _MAP_EP(dev->data_isoch_in, DATA_ISOCH_IN); 89 _MAP_EP(dev->data_isoch_out, DATA_ISOCH_OUT); 94 90 95 91 #undef _MAP_EP -
uspace/drv/bus/usb/usbdiag/device.h
re67c50a r64ce0c1 40 40 #include <usb/dev/driver.h> 41 41 42 #define USBDIAG_EP_INTR_IN 1 43 #define USBDIAG_EP_INTR_OUT 2 44 #define USBDIAG_EP_BULK_IN 3 45 #define USBDIAG_EP_BULK_OUT 4 46 #define USBDIAG_EP_ISOCH_IN 5 47 #define USBDIAG_EP_ISOCH_OUT 6 42 #define USBDIAG_EP_BURST_INTR_IN 1 43 #define USBDIAG_EP_BURST_INTR_OUT 2 44 #define USBDIAG_EP_BURST_BULK_IN 3 45 #define USBDIAG_EP_BURST_BULK_OUT 4 46 #define USBDIAG_EP_BURST_ISOCH_IN 5 47 #define USBDIAG_EP_BURST_ISOCH_OUT 6 48 49 #define USBDIAG_EP_DATA_INTR_IN 7 50 #define USBDIAG_EP_DATA_INTR_OUT 8 51 #define USBDIAG_EP_DATA_BULK_IN 9 52 #define USBDIAG_EP_DATA_BULK_OUT 10 53 #define USBDIAG_EP_DATA_ISOCH_IN 11 54 #define USBDIAG_EP_DATA_ISOCH_OUT 12 48 55 49 56 /** … … 53 60 usb_device_t *usb_dev; 54 61 ddf_fun_t *fun; 55 usb_pipe_t *intr_in; 56 usb_pipe_t *intr_out; 57 usb_pipe_t *bulk_in; 58 usb_pipe_t *bulk_out; 59 usb_pipe_t *isoch_in; 60 usb_pipe_t *isoch_out; 62 63 usb_pipe_t *burst_intr_in; 64 usb_pipe_t *burst_intr_out; 65 usb_pipe_t *burst_bulk_in; 66 usb_pipe_t *burst_bulk_out; 67 usb_pipe_t *burst_isoch_in; 68 usb_pipe_t *burst_isoch_out; 69 70 usb_pipe_t *data_intr_in; 71 usb_pipe_t *data_intr_out; 72 usb_pipe_t *data_bulk_in; 73 usb_pipe_t *data_bulk_out; 74 usb_pipe_t *data_isoch_in; 75 usb_pipe_t *data_isoch_out; 76 61 77 } usbdiag_dev_t; 62 78 -
uspace/drv/bus/usb/usbdiag/main.c
re67c50a r64ce0c1 139 139 } 140 140 141 static const usb_endpoint_description_t intr_in_ep = { 142 .transfer_type = USB_TRANSFER_INTERRUPT, 143 .direction = USB_DIRECTION_IN, 144 .interface_class = USB_CLASS_DIAGNOSTIC, 145 .interface_subclass = 0x00, 146 .interface_protocol = 0x01, 147 .flags = 0 148 }; 149 static const usb_endpoint_description_t intr_out_ep = { 150 .transfer_type = USB_TRANSFER_INTERRUPT, 151 .direction = USB_DIRECTION_OUT, 152 .interface_class = USB_CLASS_DIAGNOSTIC, 153 .interface_subclass = 0x00, 154 .interface_protocol = 0x01, 155 .flags = 0 156 }; 157 static const usb_endpoint_description_t bulk_in_ep = { 158 .transfer_type = USB_TRANSFER_BULK, 159 .direction = USB_DIRECTION_IN, 160 .interface_class = USB_CLASS_DIAGNOSTIC, 161 .interface_subclass = 0x00, 162 .interface_protocol = 0x01, 163 .flags = 0 164 }; 165 static const usb_endpoint_description_t bulk_out_ep = { 166 .transfer_type = USB_TRANSFER_BULK, 167 .direction = USB_DIRECTION_OUT, 168 .interface_class = USB_CLASS_DIAGNOSTIC, 169 .interface_subclass = 0x00, 170 .interface_protocol = 0x01, 171 .flags = 0 172 }; 173 static const usb_endpoint_description_t isoch_in_ep = { 174 .transfer_type = USB_TRANSFER_ISOCHRONOUS, 175 .direction = USB_DIRECTION_IN, 176 .interface_class = USB_CLASS_DIAGNOSTIC, 177 .interface_subclass = 0x00, 178 .interface_protocol = 0x01, 179 .flags = 0 180 }; 181 static const usb_endpoint_description_t isoch_out_ep = { 141 static const usb_endpoint_description_t burst_intr_in_ep = { 142 .transfer_type = USB_TRANSFER_INTERRUPT, 143 .direction = USB_DIRECTION_IN, 144 .interface_class = USB_CLASS_DIAGNOSTIC, 145 .interface_subclass = 0x00, 146 .interface_protocol = 0x01, 147 .flags = 0 148 }; 149 static const usb_endpoint_description_t burst_intr_out_ep = { 150 .transfer_type = USB_TRANSFER_INTERRUPT, 151 .direction = USB_DIRECTION_OUT, 152 .interface_class = USB_CLASS_DIAGNOSTIC, 153 .interface_subclass = 0x00, 154 .interface_protocol = 0x01, 155 .flags = 0 156 }; 157 static const usb_endpoint_description_t burst_bulk_in_ep = { 158 .transfer_type = USB_TRANSFER_BULK, 159 .direction = USB_DIRECTION_IN, 160 .interface_class = USB_CLASS_DIAGNOSTIC, 161 .interface_subclass = 0x00, 162 .interface_protocol = 0x01, 163 .flags = 0 164 }; 165 static const usb_endpoint_description_t burst_bulk_out_ep = { 166 .transfer_type = USB_TRANSFER_BULK, 167 .direction = USB_DIRECTION_OUT, 168 .interface_class = USB_CLASS_DIAGNOSTIC, 169 .interface_subclass = 0x00, 170 .interface_protocol = 0x01, 171 .flags = 0 172 }; 173 static const usb_endpoint_description_t burst_isoch_in_ep = { 174 .transfer_type = USB_TRANSFER_ISOCHRONOUS, 175 .direction = USB_DIRECTION_IN, 176 .interface_class = USB_CLASS_DIAGNOSTIC, 177 .interface_subclass = 0x00, 178 .interface_protocol = 0x01, 179 .flags = 0 180 }; 181 static const usb_endpoint_description_t burst_isoch_out_ep = { 182 .transfer_type = USB_TRANSFER_ISOCHRONOUS, 183 .direction = USB_DIRECTION_OUT, 184 .interface_class = USB_CLASS_DIAGNOSTIC, 185 .interface_subclass = 0x00, 186 .interface_protocol = 0x01, 187 .flags = 0 188 }; 189 static const usb_endpoint_description_t data_intr_in_ep = { 190 .transfer_type = USB_TRANSFER_INTERRUPT, 191 .direction = USB_DIRECTION_IN, 192 .interface_class = USB_CLASS_DIAGNOSTIC, 193 .interface_subclass = 0x00, 194 .interface_protocol = 0x01, 195 .flags = 0 196 }; 197 static const usb_endpoint_description_t data_intr_out_ep = { 198 .transfer_type = USB_TRANSFER_INTERRUPT, 199 .direction = USB_DIRECTION_OUT, 200 .interface_class = USB_CLASS_DIAGNOSTIC, 201 .interface_subclass = 0x00, 202 .interface_protocol = 0x01, 203 .flags = 0 204 }; 205 static const usb_endpoint_description_t data_bulk_in_ep = { 206 .transfer_type = USB_TRANSFER_BULK, 207 .direction = USB_DIRECTION_IN, 208 .interface_class = USB_CLASS_DIAGNOSTIC, 209 .interface_subclass = 0x00, 210 .interface_protocol = 0x01, 211 .flags = 0 212 }; 213 static const usb_endpoint_description_t data_bulk_out_ep = { 214 .transfer_type = USB_TRANSFER_BULK, 215 .direction = USB_DIRECTION_OUT, 216 .interface_class = USB_CLASS_DIAGNOSTIC, 217 .interface_subclass = 0x00, 218 .interface_protocol = 0x01, 219 .flags = 0 220 }; 221 static const usb_endpoint_description_t data_isoch_in_ep = { 222 .transfer_type = USB_TRANSFER_ISOCHRONOUS, 223 .direction = USB_DIRECTION_IN, 224 .interface_class = USB_CLASS_DIAGNOSTIC, 225 .interface_subclass = 0x00, 226 .interface_protocol = 0x01, 227 .flags = 0 228 }; 229 static const usb_endpoint_description_t data_isoch_out_ep = { 182 230 .transfer_type = USB_TRANSFER_ISOCHRONOUS, 183 231 .direction = USB_DIRECTION_OUT, … … 189 237 190 238 static const usb_endpoint_description_t *diag_endpoints[] = { 191 [USBDIAG_EP_INTR_IN] = &intr_in_ep, 192 [USBDIAG_EP_INTR_OUT] = &intr_out_ep, 193 [USBDIAG_EP_BULK_IN] = &bulk_in_ep, 194 [USBDIAG_EP_BULK_OUT] = &bulk_out_ep, 195 [USBDIAG_EP_ISOCH_IN] = &isoch_in_ep, 196 [USBDIAG_EP_ISOCH_OUT] = &isoch_out_ep, 239 [USBDIAG_EP_BURST_INTR_IN] = &burst_intr_in_ep, 240 [USBDIAG_EP_BURST_INTR_OUT] = &burst_intr_out_ep, 241 [USBDIAG_EP_BURST_BULK_IN] = &burst_bulk_in_ep, 242 [USBDIAG_EP_BURST_BULK_OUT] = &burst_bulk_out_ep, 243 [USBDIAG_EP_BURST_ISOCH_IN] = &burst_isoch_in_ep, 244 [USBDIAG_EP_BURST_ISOCH_OUT] = &burst_isoch_out_ep, 245 [USBDIAG_EP_DATA_INTR_IN] = &data_intr_in_ep, 246 [USBDIAG_EP_DATA_INTR_OUT] = &data_intr_out_ep, 247 [USBDIAG_EP_DATA_BULK_IN] = &data_bulk_in_ep, 248 [USBDIAG_EP_DATA_BULK_OUT] = &data_bulk_out_ep, 249 [USBDIAG_EP_DATA_ISOCH_IN] = &data_isoch_in_ep, 250 [USBDIAG_EP_DATA_ISOCH_OUT] = &data_isoch_out_ep, 197 251 NULL 198 252 }; -
uspace/drv/bus/usb/usbdiag/tests.c
re67c50a r64ce0c1 44 44 #define NAME "usbdiag" 45 45 46 static int burst_in_test(usb_pipe_t *pipe, int cycles, size_t size, usbdiag_dur_t *duration) 46 static const uint32_t test_data_src = 0xDEADBEEF; 47 48 static int test_in(usb_pipe_t *pipe, const usbdiag_test_params_t *params, usbdiag_test_results_t *results) 47 49 { 48 50 if (!pipe) 49 51 return EBADMEM; 50 52 51 char *buffer = usb_pipe_alloc_buffer(pipe, size); 53 bool validate = params->validate_data; 54 size_t size = params->transfer_size; 55 if (!size) 56 size = pipe->desc.max_transfer_size; 57 58 const uint32_t test_data = uint32_host2usb(test_data_src); 59 if (validate && size % sizeof(test_data)) 60 return EINVAL; 61 62 size_t test_data_size = size / sizeof(test_data); 63 char *buffer = (char *) malloc(size); 52 64 if (!buffer) 53 65 return ENOMEM; … … 55 67 // TODO: Are we sure that no other test is running on this endpoint? 56 68 57 usb_log_info("Performing %s IN burst test.", usb_str_transfer_type(pipe->desc.transfer_type));69 usb_log_info("Performing %s IN test with duration %ld ms.", usb_str_transfer_type(pipe->desc.transfer_type), params->min_duration); 58 70 59 71 int rc = EOK; 60 struct timeval start_time; 72 uint32_t transfer_count = 0; 73 74 struct timeval start_time, final_time, stop_time; 61 75 gettimeofday(&start_time, NULL); 62 63 for (int i = 0; i < cycles; ++i) { 76 gettimeofday(&stop_time, NULL); 77 78 tv_add_diff(&stop_time, params->min_duration * 1000); 79 gettimeofday(&final_time, NULL); 80 81 while (!tv_gt(&final_time, &stop_time)) { 82 ++transfer_count; 83 64 84 // Read device's response. 65 85 size_t remaining = size; … … 83 103 if (rc) 84 104 break; 85 } 86 87 struct timeval final_time; 88 gettimeofday(&final_time, NULL); 105 106 if (validate) { 107 uint32_t *beef_buffer = (uint32_t *) buffer; 108 109 /* Check if the beef is really dead. */ 110 for (size_t i = 0; i < test_data_size; ++i) { 111 if (beef_buffer[i] != test_data) { 112 usb_log_error("Read of %s IN endpoint returned " 113 "invalid data at address %zu. [ 0x%X != 0x%X ]", 114 usb_str_transfer_type(pipe->desc.transfer_type), i * sizeof(test_data), beef_buffer[i], test_data); 115 rc = EINVAL; 116 } 117 } 118 119 if (rc) 120 break; 121 } 122 123 gettimeofday(&final_time, NULL); 124 } 125 89 126 usbdiag_dur_t in_duration = ((final_time.tv_usec - start_time.tv_usec) / 1000) + 90 127 ((final_time.tv_sec - start_time.tv_sec) * 1000); 91 128 92 usb_log_info("Burst test on %s IN endpoint completed in %lu ms.", usb_str_transfer_type(pipe->desc.transfer_type), in_duration); 93 94 usb_pipe_free_buffer(pipe, buffer); 95 if (duration) 96 *duration = in_duration; 129 usb_log_info("Test on %s IN endpoint completed in %lu ms.", usb_str_transfer_type(pipe->desc.transfer_type), in_duration); 130 131 results->act_duration = in_duration; 132 results->transfer_count = transfer_count; 133 results->transfer_size = size; 134 135 free(buffer); 97 136 98 137 return rc; 99 138 } 100 139 101 static int burst_out_test(usb_pipe_t *pipe, int cycles, size_t size, usbdiag_dur_t *duration)140 static int test_out(usb_pipe_t *pipe, const usbdiag_test_params_t *params, usbdiag_test_results_t *results) 102 141 { 103 142 if (!pipe) 104 143 return EBADMEM; 144 145 bool validate = params->validate_data; 146 size_t size = params->transfer_size; 147 if (!size) 148 size = pipe->desc.max_transfer_size; 149 150 const uint32_t test_data = uint32_host2usb(test_data_src); 151 152 if (validate && size % sizeof(test_data)) 153 return EINVAL; 105 154 106 155 char *buffer = usb_pipe_alloc_buffer(pipe, size); … … 108 157 return ENOMEM; 109 158 110 memset(buffer, 42, size); 159 if (validate) { 160 for (size_t i = 0; i < size; i += sizeof(test_data)) { 161 memcpy(buffer + i, &test_data, sizeof(test_data)); 162 } 163 } 111 164 112 165 // TODO: Are we sure that no other test is running on this endpoint? 113 166 114 usb_log_info("Performing %s OUT bursttest.", usb_str_transfer_type(pipe->desc.transfer_type));167 usb_log_info("Performing %s OUT test.", usb_str_transfer_type(pipe->desc.transfer_type)); 115 168 116 169 int rc = EOK; 117 struct timeval start_time; 170 uint32_t transfer_count = 0; 171 172 struct timeval start_time, final_time, stop_time; 118 173 gettimeofday(&start_time, NULL); 119 120 for (int i = 0; i < cycles; ++i) { 174 gettimeofday(&stop_time, NULL); 175 176 tv_add_diff(&stop_time, params->min_duration * 1000); 177 gettimeofday(&final_time, NULL); 178 179 while (!tv_gt(&final_time, &stop_time)) { 180 ++transfer_count; 181 121 182 // Write buffer to device. 122 183 if ((rc = usb_pipe_write_dma(pipe, buffer, size))) { … … 124 185 break; 125 186 } 126 } 127 128 struct timeval final_time;129 gettimeofday(&final_time, NULL); 187 188 gettimeofday(&final_time, NULL); 189 } 190 130 191 usbdiag_dur_t in_duration = ((final_time.tv_usec - start_time.tv_usec) / 1000) + 131 192 ((final_time.tv_sec - start_time.tv_sec) * 1000); 132 193 133 usb_log_info("Burst test on %s OUT endpoint completed in %ld ms.", usb_str_transfer_type(pipe->desc.transfer_type), in_duration); 134 135 usb_pipe_free_buffer(pipe, buffer); 136 if (duration) 137 *duration = in_duration; 194 usb_log_info("Test on %s OUT endpoint completed in %ld ms.", usb_str_transfer_type(pipe->desc.transfer_type), in_duration); 195 196 results->act_duration = in_duration; 197 results->transfer_count = transfer_count; 198 results->transfer_size = size; 199 200 free(buffer); 138 201 139 202 return rc; 140 203 } 141 204 142 static const uint32_t test_data_src = 0xDEADBEEF; 143 144 static int data_in_test(usb_pipe_t *pipe, int cycles, size_t size, usbdiag_dur_t *duration) 145 { 146 if (!pipe) 147 return EBADMEM; 148 149 const uint32_t test_data = uint32_host2usb(test_data_src); 150 151 if (size % sizeof(test_data)) 152 return EINVAL; 153 154 char *buffer = usb_pipe_alloc_buffer(pipe, size); 155 if (!buffer) 156 return ENOMEM; 157 158 // TODO: Are we sure that no other test is running on this endpoint? 159 160 usb_log_info("Performing %s IN data test.", usb_str_transfer_type(pipe->desc.transfer_type)); 161 162 int rc = EOK; 163 struct timeval start_time; 164 gettimeofday(&start_time, NULL); 165 166 for (int i = 0; i < cycles; ++i) { 167 // Read device's response. 168 size_t remaining = size; 169 size_t transferred; 170 171 while (remaining > 0) { 172 if ((rc = usb_pipe_read_dma(pipe, buffer + size - remaining, remaining, &transferred))) { 173 usb_log_error("Read of %s IN endpoint failed with error: %s", usb_str_transfer_type(pipe->desc.transfer_type), str_error(rc)); 174 break; 175 } 176 177 if (transferred > remaining) { 178 usb_log_error("Read of %s IN endpoint returned more data than expected.", usb_str_transfer_type(pipe->desc.transfer_type)); 179 rc = EINVAL; 180 break; 181 } 182 183 remaining -= transferred; 184 } 185 186 if (rc) 187 break; 188 189 for (size_t i = 0; i < size; i += sizeof(test_data)) { 190 if (*(uint32_t *)(buffer + i) != test_data) { 191 usb_log_error("Read of %s IN endpoint returned " 192 "invald data at address %zu.", 193 usb_str_transfer_type(pipe->desc.transfer_type), i); 194 rc = EINVAL; 195 break; 196 } 197 } 198 199 if (rc) 200 break; 201 } 202 203 struct timeval final_time; 204 gettimeofday(&final_time, NULL); 205 usbdiag_dur_t in_duration = ((final_time.tv_usec - start_time.tv_usec) / 1000) + 206 ((final_time.tv_sec - start_time.tv_sec) * 1000); 207 208 usb_log_info("Data test on %s IN endpoint completed in %lu ms.", usb_str_transfer_type(pipe->desc.transfer_type), in_duration); 209 210 usb_pipe_free_buffer(pipe, buffer); 211 if (duration) 212 *duration = in_duration; 213 214 return rc; 215 } 216 217 static int data_out_test(usb_pipe_t *pipe, int cycles, size_t size, usbdiag_dur_t *duration) 218 { 219 if (!pipe) 220 return EBADMEM; 221 222 const uint32_t test_data = uint32_host2usb(test_data_src); 223 224 if (size % sizeof(test_data)) 225 return EINVAL; 226 227 char *buffer = usb_pipe_alloc_buffer(pipe, size); 228 if (!buffer) 229 return ENOMEM; 230 231 for (size_t i = 0; i < size; i += sizeof(test_data)) { 232 memcpy(buffer + i, &test_data, sizeof(test_data)); 233 } 234 235 // TODO: Are we sure that no other test is running on this endpoint? 236 237 usb_log_info("Performing %s OUT data test.", usb_str_transfer_type(pipe->desc.transfer_type)); 238 239 int rc = EOK; 240 struct timeval start_time; 241 gettimeofday(&start_time, NULL); 242 243 for (int i = 0; i < cycles; ++i) { 244 // Write buffer to device. 245 if ((rc = usb_pipe_write_dma(pipe, buffer, size))) { 246 usb_log_error("Write to %s OUT endpoint failed with error: %s", usb_str_transfer_type(pipe->desc.transfer_type), str_error(rc)); 247 break; 248 } 249 } 250 251 struct timeval final_time; 252 gettimeofday(&final_time, NULL); 253 usbdiag_dur_t in_duration = ((final_time.tv_usec - start_time.tv_usec) / 1000) + 254 ((final_time.tv_sec - start_time.tv_sec) * 1000); 255 256 usb_log_info("Data test on %s OUT endpoint completed in %ld ms.", usb_str_transfer_type(pipe->desc.transfer_type), in_duration); 257 258 usb_pipe_free_buffer(pipe, buffer); 259 if (duration) 260 *duration = in_duration; 261 262 return rc; 263 } 264 265 int usbdiag_burst_test_intr_in(ddf_fun_t *fun, int cycles, size_t size, usbdiag_dur_t *duration) 205 int usbdiag_dev_test_in(ddf_fun_t *fun, const usbdiag_test_params_t *params, usbdiag_test_results_t *results) 266 206 { 267 207 usbdiag_dev_t *dev = ddf_fun_to_usbdiag_dev(fun); … … 269 209 return EBADMEM; 270 210 271 return burst_in_test(dev->intr_in, cycles, size, duration); 272 } 273 274 int usbdiag_burst_test_intr_out(ddf_fun_t *fun, int cycles, size_t size, usbdiag_dur_t *duration) 211 usb_pipe_t *pipe; 212 213 switch (params->transfer_type) { 214 case USB_TRANSFER_INTERRUPT: 215 pipe = params->validate_data ? dev->data_intr_in : dev->burst_intr_in; 216 break; 217 case USB_TRANSFER_BULK: 218 pipe = params->validate_data ? dev->data_bulk_in : dev->burst_bulk_in; 219 break; 220 case USB_TRANSFER_ISOCHRONOUS: 221 pipe = params->validate_data ? dev->data_isoch_in : dev->burst_isoch_in; 222 break; 223 default: 224 return ENOTSUP; 225 } 226 227 return test_in(pipe, params, results); 228 } 229 230 int usbdiag_dev_test_out(ddf_fun_t *fun, const usbdiag_test_params_t *params, usbdiag_test_results_t *results) 275 231 { 276 232 usbdiag_dev_t *dev = ddf_fun_to_usbdiag_dev(fun); … … 278 234 return EBADMEM; 279 235 280 return burst_out_test(dev->intr_out, cycles, size, duration); 281 } 282 283 int usbdiag_burst_test_bulk_in(ddf_fun_t *fun, int cycles, size_t size, usbdiag_dur_t *duration) 284 { 285 usbdiag_dev_t *dev = ddf_fun_to_usbdiag_dev(fun); 286 if (!dev) 287 return EBADMEM; 288 289 return burst_in_test(dev->bulk_in, cycles, size, duration); 290 } 291 292 int usbdiag_burst_test_bulk_out(ddf_fun_t *fun, int cycles, size_t size, usbdiag_dur_t *duration) 293 { 294 usbdiag_dev_t *dev = ddf_fun_to_usbdiag_dev(fun); 295 if (!dev) 296 return EBADMEM; 297 298 return burst_out_test(dev->bulk_out, cycles, size, duration); 299 } 300 301 int usbdiag_burst_test_isoch_in(ddf_fun_t *fun, int cycles, size_t size, usbdiag_dur_t *duration) 302 { 303 usbdiag_dev_t *dev = ddf_fun_to_usbdiag_dev(fun); 304 if (!dev) 305 return EBADMEM; 306 307 return burst_in_test(dev->isoch_in, cycles, size, duration); 308 } 309 310 int usbdiag_burst_test_isoch_out(ddf_fun_t *fun, int cycles, size_t size, usbdiag_dur_t *duration) 311 { 312 usbdiag_dev_t *dev = ddf_fun_to_usbdiag_dev(fun); 313 if (!dev) 314 return EBADMEM; 315 316 return burst_out_test(dev->isoch_out, cycles, size, duration); 317 } 318 319 int usbdiag_data_test_intr_in(ddf_fun_t *fun, int cycles, size_t size, usbdiag_dur_t *duration) 320 { 321 usbdiag_dev_t *dev = ddf_fun_to_usbdiag_dev(fun); 322 if (!dev) 323 return EBADMEM; 324 325 return data_in_test(dev->intr_in, cycles, size, duration); 326 } 327 328 int usbdiag_data_test_intr_out(ddf_fun_t *fun, int cycles, size_t size, usbdiag_dur_t *duration) 329 { 330 usbdiag_dev_t *dev = ddf_fun_to_usbdiag_dev(fun); 331 if (!dev) 332 return EBADMEM; 333 334 return data_out_test(dev->intr_out, cycles, size, duration); 335 } 336 337 int usbdiag_data_test_bulk_in(ddf_fun_t *fun, int cycles, size_t size, usbdiag_dur_t *duration) 338 { 339 usbdiag_dev_t *dev = ddf_fun_to_usbdiag_dev(fun); 340 if (!dev) 341 return EBADMEM; 342 343 return data_in_test(dev->bulk_in, cycles, size, duration); 344 } 345 346 int usbdiag_data_test_bulk_out(ddf_fun_t *fun, int cycles, size_t size, usbdiag_dur_t *duration) 347 { 348 usbdiag_dev_t *dev = ddf_fun_to_usbdiag_dev(fun); 349 if (!dev) 350 return EBADMEM; 351 352 return data_out_test(dev->bulk_out, cycles, size, duration); 353 } 354 355 int usbdiag_data_test_isoch_in(ddf_fun_t *fun, int cycles, size_t size, usbdiag_dur_t *duration) 356 { 357 usbdiag_dev_t *dev = ddf_fun_to_usbdiag_dev(fun); 358 if (!dev) 359 return EBADMEM; 360 361 return data_in_test(dev->isoch_in, cycles, size, duration); 362 } 363 364 int usbdiag_data_test_isoch_out(ddf_fun_t *fun, int cycles, size_t size, usbdiag_dur_t *duration) 365 { 366 usbdiag_dev_t *dev = ddf_fun_to_usbdiag_dev(fun); 367 if (!dev) 368 return EBADMEM; 369 370 return data_out_test(dev->isoch_out, cycles, size, duration); 236 usb_pipe_t *pipe; 237 238 switch (params->transfer_type) { 239 case USB_TRANSFER_INTERRUPT: 240 pipe = params->validate_data ? dev->data_intr_out : dev->burst_intr_out; 241 break; 242 case USB_TRANSFER_BULK: 243 pipe = params->validate_data ? dev->data_bulk_out : dev->burst_bulk_out; 244 break; 245 case USB_TRANSFER_ISOCHRONOUS: 246 pipe = params->validate_data ? dev->data_isoch_out : dev->burst_isoch_out; 247 break; 248 default: 249 return ENOTSUP; 250 } 251 252 return test_out(pipe, params, results); 371 253 } 372 254 -
uspace/drv/bus/usb/usbdiag/tests.h
re67c50a r64ce0c1 39 39 #include <ddf/driver.h> 40 40 41 int usbdiag_burst_test_intr_in(ddf_fun_t *, int, size_t, usbdiag_dur_t *); 42 int usbdiag_burst_test_intr_out(ddf_fun_t *, int, size_t, usbdiag_dur_t *); 43 int usbdiag_burst_test_bulk_in(ddf_fun_t *, int, size_t, usbdiag_dur_t *); 44 int usbdiag_burst_test_bulk_out(ddf_fun_t *, int, size_t, usbdiag_dur_t *); 45 int usbdiag_burst_test_isoch_in(ddf_fun_t *, int, size_t, usbdiag_dur_t *); 46 int usbdiag_burst_test_isoch_out(ddf_fun_t *, int, size_t, usbdiag_dur_t *); 47 48 int usbdiag_data_test_intr_in(ddf_fun_t *, int, size_t, usbdiag_dur_t *); 49 int usbdiag_data_test_intr_out(ddf_fun_t *, int, size_t, usbdiag_dur_t *); 50 int usbdiag_data_test_bulk_in(ddf_fun_t *, int, size_t, usbdiag_dur_t *); 51 int usbdiag_data_test_bulk_out(ddf_fun_t *, int, size_t, usbdiag_dur_t *); 52 int usbdiag_data_test_isoch_in(ddf_fun_t *, int, size_t, usbdiag_dur_t *); 53 int usbdiag_data_test_isoch_out(ddf_fun_t *, int, size_t, usbdiag_dur_t *); 41 int usbdiag_dev_test_in(ddf_fun_t *, const usbdiag_test_params_t *, usbdiag_test_results_t *); 42 int usbdiag_dev_test_out(ddf_fun_t *, const usbdiag_test_params_t *, usbdiag_test_results_t *); 54 43 55 44 #endif /* USBDIAG_TESTS_H_ */ -
uspace/drv/bus/usb/xhci/endpoint.c
re67c50a r64ce0c1 88 88 if (dev->speed >= USB_SPEED_SUPER) { 89 89 ep->packets_per_uframe = xhci_ep->max_burst * xhci_ep->mult; 90 ep->max_transfer_size = ep->max_packet_size * ep->packets_per_uframe; 90 if (ep->transfer_type == USB_TRANSFER_ISOCHRONOUS 91 || ep->transfer_type == USB_TRANSFER_INTERRUPT) { 92 ep->max_transfer_size = ep->max_packet_size * ep->packets_per_uframe; 93 } 94 else { 95 ep->max_transfer_size = 200 * PAGE_SIZE; 96 } 91 97 } 92 98 -
uspace/drv/bus/usb/xhci/transfers.c
re67c50a r64ce0c1 126 126 } 127 127 128 static int calculate_trb_count(xhci_transfer_t *transfer) 129 { 130 const size_t size = transfer->batch.buffer_size; 131 return (size + PAGE_SIZE - 1 )/ PAGE_SIZE; 132 } 133 134 static void trb_set_buffer(xhci_transfer_t *transfer, xhci_trb_t *trb, 135 size_t i, size_t total, size_t *remaining) 136 { 137 const uintptr_t ptr = dma_buffer_phys(&transfer->hc_buffer, 138 transfer->hc_buffer.virt + i * PAGE_SIZE); 139 140 trb->parameter = host2xhci(64, ptr); 141 TRB_CTRL_SET_TD_SIZE(*trb, max(31, total - i - 1)); 142 if (*remaining > PAGE_SIZE) { 143 TRB_CTRL_SET_XFER_LEN(*trb, PAGE_SIZE); 144 *remaining -= PAGE_SIZE; 145 } 146 else { 147 TRB_CTRL_SET_XFER_LEN(*trb, *remaining); 148 *remaining = 0; 149 } 150 } 151 128 152 static int schedule_control(xhci_hc_t* hc, xhci_transfer_t* transfer) 129 153 { … … 133 157 usb_device_request_setup_packet_t* setup = &batch->setup.packet; 134 158 135 xhci_trb_t trbs[3]; 136 int trbs_used = 0; 137 138 xhci_trb_t *trb_setup = trbs + trbs_used++; 159 size_t buffer_count = 0; 160 if (setup->length > 0) { 161 buffer_count = calculate_trb_count(transfer); 162 } 163 164 xhci_trb_t trbs[buffer_count + 2]; 165 166 xhci_trb_t *trb_setup = trbs; 139 167 xhci_trb_clean(trb_setup); 140 168 … … 155 183 156 184 /* Data stage */ 157 xhci_trb_t *trb_data = NULL;158 185 if (setup->length > 0) { 159 trb_data = trbs + trbs_used++;160 xhci_trb_clean(trb_data);161 162 trb_data->parameter = host2xhci(64, transfer->hc_buffer.phys);163 164 // data size (sent for OUT, or buffer size)165 TRB_CTRL_SET_XFER_LEN(*trb_data, batch->buffer_size);166 // FIXME: TD size 4.11.2.4167 TRB_CTRL_SET_TD_SIZE(*trb_data, 1);168 169 // Some more fields here, no idea what they mean170 TRB_CTRL_SET_TRB_TYPE(*trb_data, XHCI_TRB_TYPE_DATA_STAGE);171 172 186 int stage_dir = REQUEST_TYPE_IS_DEVICE_TO_HOST(setup->request_type) 173 187 ? STAGE_IN : STAGE_OUT; 174 TRB_CTRL_SET_DIR(*trb_data, stage_dir); 188 size_t remaining = transfer->batch.buffer_size; 189 190 for (size_t i = 0; i < buffer_count; ++i) { 191 xhci_trb_clean(&trbs[i + 1]); 192 trb_set_buffer(transfer, &trbs[i + 1], i, buffer_count, &remaining); 193 194 TRB_CTRL_SET_DIR(trbs[i + 1], stage_dir); 195 TRB_CTRL_SET_TRB_TYPE(trbs[i + 1], XHCI_TRB_TYPE_DATA_STAGE); 196 197 if (i == buffer_count - 1) break; 198 199 /* Set the chain bit as this is not the last TRB */ 200 TRB_CTRL_SET_CHAIN(trbs[i], 1); 201 } 175 202 } 176 203 177 204 /* Status stage */ 178 xhci_trb_t *trb_status = trbs + trbs_used++;205 xhci_trb_t *trb_status = trbs + buffer_count + 1; 179 206 xhci_trb_clean(trb_status); 180 207 … … 192 219 193 220 return xhci_trb_ring_enqueue_multiple(get_ring(transfer), trbs, 194 trbs_used, &transfer->interrupt_trb_phys);221 buffer_count + 2, &transfer->interrupt_trb_phys); 195 222 } 196 223 197 224 static int schedule_bulk(xhci_hc_t* hc, xhci_transfer_t *transfer) 198 225 { 199 xhci_trb_t trb;200 xhci_trb_clean(&trb);201 trb.parameter = host2xhci(64, transfer->hc_buffer.phys);202 203 // data size (sent for OUT, or buffer size)204 TRB_CTRL_SET_XFER_LEN(trb, transfer->batch.buffer_size);205 206 226 /* The stream-enabled endpoints need to chain ED trb */ 207 227 xhci_endpoint_t *ep = xhci_endpoint_get(transfer->batch.ep); 208 228 if (!ep->primary_stream_data_size) { 209 // FIXME: TD size 4.11.2.4 210 TRB_CTRL_SET_TD_SIZE(trb, 1); 211 212 // we want an interrupt after this td is done 213 TRB_CTRL_SET_IOC(trb, 1); 214 TRB_CTRL_SET_TRB_TYPE(trb, XHCI_TRB_TYPE_NORMAL); 229 const size_t buffer_count = calculate_trb_count(transfer); 230 xhci_trb_t trbs[buffer_count]; 231 size_t remaining = transfer->batch.buffer_size; 232 233 for (size_t i = 0; i < buffer_count; ++i) { 234 xhci_trb_clean(&trbs[i]); 235 trb_set_buffer(transfer, &trbs[i], i, buffer_count, &remaining); 236 TRB_CTRL_SET_TRB_TYPE(trbs[i], XHCI_TRB_TYPE_NORMAL); 237 238 if (i == buffer_count - 1) break; 239 240 /* Set the chain bit as this is not the last TRB */ 241 TRB_CTRL_SET_CHAIN(trbs[i], 1); 242 } 243 /* Set the interrupt bit for last TRB */ 244 TRB_CTRL_SET_IOC(trbs[buffer_count - 1], 1); 215 245 216 246 xhci_trb_ring_t* ring = get_ring(transfer); 217 return xhci_trb_ring_enqueue(ring, &trb, &transfer->interrupt_trb_phys); 247 return xhci_trb_ring_enqueue_multiple(ring, &trbs[0], buffer_count, 248 &transfer->interrupt_trb_phys); 218 249 } 219 250 else { 220 TRB_CTRL_SET_TD_SIZE(trb, 2);221 TRB_CTRL_SET_TRB_TYPE(trb, XHCI_TRB_TYPE_NORMAL);222 TRB_CTRL_SET_CHAIN(trb, 1);223 TRB_CTRL_SET_ENT(trb, 1);224 225 251 xhci_trb_ring_t* ring = get_ring(transfer); 226 252 if (!ring) { … … 228 254 } 229 255 230 int err = xhci_trb_ring_enqueue(ring, &trb, &transfer->interrupt_trb_phys); 231 232 if (err) { 233 return err; 234 } 235 236 xhci_trb_clean(&trb); 237 trb.parameter = host2xhci(64, (uintptr_t) transfer); 238 TRB_CTRL_SET_TRB_TYPE(trb, XHCI_TRB_TYPE_EVENT_DATA); 239 TRB_CTRL_SET_IOC(trb, 1); 240 241 return xhci_trb_ring_enqueue(ring, &trb, &transfer->interrupt_trb_phys); 256 const size_t buffer_count = calculate_trb_count(transfer); 257 xhci_trb_t trbs[buffer_count + 1]; 258 size_t remaining = transfer->batch.buffer_size; 259 260 for (size_t i = 0; i < buffer_count; ++i) { 261 xhci_trb_clean(&trbs[i]); 262 trb_set_buffer(transfer, &trbs[i], i, buffer_count + 1, &remaining); 263 TRB_CTRL_SET_TRB_TYPE(trbs[i], XHCI_TRB_TYPE_NORMAL); 264 TRB_CTRL_SET_CHAIN(trbs[i], 1); 265 } 266 TRB_CTRL_SET_ENT(trbs[buffer_count - 1], 1); 267 268 xhci_trb_clean(&trbs[buffer_count]); 269 trbs[buffer_count].parameter = host2xhci(64, (uintptr_t) transfer); 270 TRB_CTRL_SET_TRB_TYPE(trbs[buffer_count], XHCI_TRB_TYPE_EVENT_DATA); 271 TRB_CTRL_SET_IOC(trbs[buffer_count], 1); 272 273 return xhci_trb_ring_enqueue_multiple(ring, &trbs[0], buffer_count + 1, 274 &transfer->interrupt_trb_phys); 242 275 } 243 276 } … … 245 278 static int schedule_interrupt(xhci_hc_t* hc, xhci_transfer_t* transfer) 246 279 { 247 xhci_trb_t trb; 248 xhci_trb_clean(&trb); 249 trb.parameter = host2xhci(64, transfer->hc_buffer.phys); 250 251 // data size (sent for OUT, or buffer size) 252 TRB_CTRL_SET_XFER_LEN(trb, transfer->batch.buffer_size); 253 // FIXME: TD size 4.11.2.4 254 TRB_CTRL_SET_TD_SIZE(trb, 1); 255 256 // we want an interrupt after this td is done 257 TRB_CTRL_SET_IOC(trb, 1); 258 259 TRB_CTRL_SET_TRB_TYPE(trb, XHCI_TRB_TYPE_NORMAL); 280 const size_t buffer_count = calculate_trb_count(transfer); 281 xhci_trb_t trbs[buffer_count]; 282 size_t remaining = transfer->batch.buffer_size; 283 284 for (size_t i = 0; i < buffer_count; ++i) { 285 xhci_trb_clean(&trbs[i]); 286 trb_set_buffer(transfer, &trbs[i], i, buffer_count, &remaining); 287 TRB_CTRL_SET_TRB_TYPE(trbs[i], XHCI_TRB_TYPE_NORMAL); 288 289 if (i == buffer_count - 1) break; 290 291 /* Set the chain bit as this is not the last TRB */ 292 TRB_CTRL_SET_CHAIN(trbs[i], 1); 293 } 294 /* Set the interrupt bit for last TRB */ 295 TRB_CTRL_SET_IOC(trbs[buffer_count - 1], 1); 260 296 261 297 xhci_trb_ring_t* ring = get_ring(transfer); 262 263 return xhci_trb_ring_enqueue(ring, &trb,&transfer->interrupt_trb_phys);298 return xhci_trb_ring_enqueue_multiple(ring, &trbs[0], buffer_count, 299 &transfer->interrupt_trb_phys); 264 300 } 265 301 -
uspace/lib/drv/generic/remote_usbdiag.c
re67c50a r64ce0c1 43 43 44 44 typedef enum { 45 IPC_M_USBDIAG_BURST_INTR_IN, 46 IPC_M_USBDIAG_BURST_INTR_OUT, 47 IPC_M_USBDIAG_BURST_BULK_IN, 48 IPC_M_USBDIAG_BURST_BULK_OUT, 49 IPC_M_USBDIAG_BURST_ISOCH_IN, 50 IPC_M_USBDIAG_BURST_ISOCH_OUT, 51 IPC_M_USBDIAG_DATA_INTR_IN, 52 IPC_M_USBDIAG_DATA_INTR_OUT, 53 IPC_M_USBDIAG_DATA_BULK_IN, 54 IPC_M_USBDIAG_DATA_BULK_OUT, 55 IPC_M_USBDIAG_DATA_ISOCH_IN, 56 IPC_M_USBDIAG_DATA_ISOCH_OUT 45 IPC_M_USBDIAG_TEST_IN, 46 IPC_M_USBDIAG_TEST_OUT, 57 47 } usb_iface_funcs_t; 58 48 … … 68 58 } 69 59 70 int usbdiag_ burst_intr_in(async_exch_t *exch, int cycles, size_t size, usbdiag_dur_t *duration)60 int usbdiag_test_in(async_exch_t *exch, const usbdiag_test_params_t *params, usbdiag_test_results_t *results) 71 61 { 72 62 if (!exch) 73 63 return EBADMEM; 74 64 75 sysarg_t duration_; 76 const int rc = async_req_3_1(exch, DEV_IFACE_ID(USBDIAG_DEV_IFACE), IPC_M_USBDIAG_BURST_INTR_IN, cycles, size, &duration_); 77 78 if (rc == EOK && duration) 79 *duration = duration_; 80 81 return rc; 82 } 83 84 int usbdiag_burst_intr_out(async_exch_t *exch, int cycles, size_t size, usbdiag_dur_t *duration) 65 ipc_call_t answer; 66 aid_t req = async_send_1(exch, DEV_IFACE_ID(USBDIAG_DEV_IFACE), IPC_M_USBDIAG_TEST_IN, &answer); 67 68 int rc = async_data_write_start(exch, params, sizeof(usbdiag_test_params_t)); 69 if (rc != EOK) { 70 async_exchange_end(exch); 71 async_forget(req); 72 return rc; 73 } 74 75 rc = async_data_read_start(exch, results, sizeof(usbdiag_test_results_t)); 76 if (rc != EOK) { 77 async_exchange_end(exch); 78 async_forget(req); 79 return rc; 80 } 81 82 async_exchange_end(exch); 83 84 errno_t retval; 85 async_wait_for(req, &retval); 86 87 return (int) retval; 88 } 89 90 int usbdiag_test_out(async_exch_t *exch, const usbdiag_test_params_t *params, usbdiag_test_results_t *results) 85 91 { 86 92 if (!exch) 87 93 return EBADMEM; 88 94 89 sysarg_t duration_; 90 const int rc = async_req_3_1(exch, DEV_IFACE_ID(USBDIAG_DEV_IFACE), IPC_M_USBDIAG_BURST_INTR_OUT, cycles, size, &duration_); 91 92 if (rc == EOK && duration) 93 *duration = duration_; 94 95 return rc; 96 } 97 98 int usbdiag_burst_bulk_in(async_exch_t *exch, int cycles, size_t size, usbdiag_dur_t *duration) 99 { 100 if (!exch) 101 return EBADMEM; 102 103 sysarg_t duration_; 104 const int rc = async_req_3_1(exch, DEV_IFACE_ID(USBDIAG_DEV_IFACE), IPC_M_USBDIAG_BURST_BULK_IN, cycles, size, &duration_); 105 106 if (rc == EOK && duration) 107 *duration = duration_; 108 109 return rc; 110 } 111 112 int usbdiag_burst_bulk_out(async_exch_t *exch, int cycles, size_t size, usbdiag_dur_t *duration) 113 { 114 if (!exch) 115 return EBADMEM; 116 117 sysarg_t duration_; 118 const int rc = async_req_3_1(exch, DEV_IFACE_ID(USBDIAG_DEV_IFACE), IPC_M_USBDIAG_BURST_BULK_OUT, cycles, size, &duration_); 119 120 if (rc == EOK && duration) 121 *duration = duration_; 122 123 return rc; 124 } 125 126 int usbdiag_burst_isoch_in(async_exch_t *exch, int cycles, size_t size, usbdiag_dur_t *duration) 127 { 128 if (!exch) 129 return EBADMEM; 130 131 sysarg_t duration_; 132 const int rc = async_req_3_1(exch, DEV_IFACE_ID(USBDIAG_DEV_IFACE), IPC_M_USBDIAG_BURST_ISOCH_IN, cycles, size, &duration_); 133 134 if (rc == EOK && duration) 135 *duration = duration_; 136 137 return rc; 138 } 139 140 int usbdiag_burst_isoch_out(async_exch_t *exch, int cycles, size_t size, usbdiag_dur_t *duration) 141 { 142 if (!exch) 143 return EBADMEM; 144 145 sysarg_t duration_; 146 const int rc = async_req_3_1(exch, DEV_IFACE_ID(USBDIAG_DEV_IFACE), IPC_M_USBDIAG_BURST_ISOCH_OUT, cycles, size, &duration_); 147 148 if (rc == EOK && duration) 149 *duration = duration_; 150 151 return rc; 152 } 153 154 int usbdiag_data_intr_in(async_exch_t *exch, int cycles, size_t size, usbdiag_dur_t *duration) 155 { 156 if (!exch) 157 return EBADMEM; 158 159 sysarg_t duration_; 160 const int rc = async_req_3_1(exch, DEV_IFACE_ID(USBDIAG_DEV_IFACE), IPC_M_USBDIAG_DATA_INTR_IN, cycles, size, &duration_); 161 162 if (rc == EOK && duration) 163 *duration = duration_; 164 165 return rc; 166 } 167 168 int usbdiag_data_intr_out(async_exch_t *exch, int cycles, size_t size, usbdiag_dur_t *duration) 169 { 170 if (!exch) 171 return EBADMEM; 172 173 sysarg_t duration_; 174 const int rc = async_req_3_1(exch, DEV_IFACE_ID(USBDIAG_DEV_IFACE), IPC_M_USBDIAG_DATA_INTR_OUT, cycles, size, &duration_); 175 176 if (rc == EOK && duration) 177 *duration = duration_; 178 179 return rc; 180 } 181 182 int usbdiag_data_bulk_in(async_exch_t *exch, int cycles, size_t size, usbdiag_dur_t *duration) 183 { 184 if (!exch) 185 return EBADMEM; 186 187 sysarg_t duration_; 188 const int rc = async_req_3_1(exch, DEV_IFACE_ID(USBDIAG_DEV_IFACE), IPC_M_USBDIAG_DATA_BULK_IN, cycles, size, &duration_); 189 190 if (rc == EOK && duration) 191 *duration = duration_; 192 193 return rc; 194 } 195 196 int usbdiag_data_bulk_out(async_exch_t *exch, int cycles, size_t size, usbdiag_dur_t *duration) 197 { 198 if (!exch) 199 return EBADMEM; 200 201 sysarg_t duration_; 202 const int rc = async_req_3_1(exch, DEV_IFACE_ID(USBDIAG_DEV_IFACE), IPC_M_USBDIAG_DATA_BULK_OUT, cycles, size, &duration_); 203 204 if (rc == EOK && duration) 205 *duration = duration_; 206 207 return rc; 208 } 209 210 int usbdiag_data_isoch_in(async_exch_t *exch, int cycles, size_t size, usbdiag_dur_t *duration) 211 { 212 if (!exch) 213 return EBADMEM; 214 215 sysarg_t duration_; 216 const int rc = async_req_3_1(exch, DEV_IFACE_ID(USBDIAG_DEV_IFACE), IPC_M_USBDIAG_DATA_ISOCH_IN, cycles, size, &duration_); 217 218 if (rc == EOK && duration) 219 *duration = duration_; 220 221 return rc; 222 } 223 224 int usbdiag_data_isoch_out(async_exch_t *exch, int cycles, size_t size, usbdiag_dur_t *duration) 225 { 226 if (!exch) 227 return EBADMEM; 228 229 sysarg_t duration_; 230 const int rc = async_req_3_1(exch, DEV_IFACE_ID(USBDIAG_DEV_IFACE), IPC_M_USBDIAG_DATA_ISOCH_OUT, cycles, size, &duration_); 231 232 if (rc == EOK && duration) 233 *duration = duration_; 234 235 return rc; 236 } 237 238 static void remote_usbdiag_burst_intr_in(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 239 static void remote_usbdiag_burst_intr_out(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 240 static void remote_usbdiag_burst_bulk_in(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 241 static void remote_usbdiag_burst_bulk_out(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 242 static void remote_usbdiag_burst_isoch_in(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 243 static void remote_usbdiag_burst_isoch_out(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 244 245 static void remote_usbdiag_data_intr_in(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 246 static void remote_usbdiag_data_intr_out(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 247 static void remote_usbdiag_data_bulk_in(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 248 static void remote_usbdiag_data_bulk_out(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 249 static void remote_usbdiag_data_isoch_in(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 250 static void remote_usbdiag_data_isoch_out(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 95 ipc_call_t answer; 96 aid_t req = async_send_1(exch, DEV_IFACE_ID(USBDIAG_DEV_IFACE), IPC_M_USBDIAG_TEST_OUT, &answer); 97 98 int rc = async_data_write_start(exch, params, sizeof(usbdiag_test_params_t)); 99 if (rc != EOK) { 100 async_exchange_end(exch); 101 async_forget(req); 102 return rc; 103 } 104 105 rc = async_data_read_start(exch, results, sizeof(usbdiag_test_results_t)); 106 if (rc != EOK) { 107 async_exchange_end(exch); 108 async_forget(req); 109 return rc; 110 } 111 112 async_exchange_end(exch); 113 114 errno_t retval; 115 async_wait_for(req, &retval); 116 117 return (int) retval; 118 } 119 120 static void remote_usbdiag_test_in(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 121 static void remote_usbdiag_test_out(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 251 122 252 123 /** Remote USB diagnostic interface operations. */ 253 124 static const remote_iface_func_ptr_t remote_usbdiag_iface_ops [] = { 254 [IPC_M_USBDIAG_BURST_INTR_IN] = remote_usbdiag_burst_intr_in, 255 [IPC_M_USBDIAG_BURST_INTR_OUT] = remote_usbdiag_burst_intr_out, 256 [IPC_M_USBDIAG_BURST_BULK_IN] = remote_usbdiag_burst_bulk_in, 257 [IPC_M_USBDIAG_BURST_BULK_OUT] = remote_usbdiag_burst_bulk_out, 258 [IPC_M_USBDIAG_BURST_ISOCH_IN] = remote_usbdiag_burst_isoch_in, 259 [IPC_M_USBDIAG_BURST_ISOCH_OUT] = remote_usbdiag_burst_isoch_out, 260 [IPC_M_USBDIAG_DATA_INTR_IN] = remote_usbdiag_data_intr_in, 261 [IPC_M_USBDIAG_DATA_INTR_OUT] = remote_usbdiag_data_intr_out, 262 [IPC_M_USBDIAG_DATA_BULK_IN] = remote_usbdiag_data_bulk_in, 263 [IPC_M_USBDIAG_DATA_BULK_OUT] = remote_usbdiag_data_bulk_out, 264 [IPC_M_USBDIAG_DATA_ISOCH_IN] = remote_usbdiag_data_isoch_in, 265 [IPC_M_USBDIAG_DATA_ISOCH_OUT] = remote_usbdiag_data_isoch_out 125 [IPC_M_USBDIAG_TEST_IN] = remote_usbdiag_test_in, 126 [IPC_M_USBDIAG_TEST_OUT] = remote_usbdiag_test_out 266 127 }; 267 128 … … 272 133 }; 273 134 274 void remote_usbdiag_ burst_intr_in(ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call)135 void remote_usbdiag_test_in(ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call) 275 136 { 276 137 const usbdiag_iface_t *diag_iface = (usbdiag_iface_t *) iface; 277 138 278 if (diag_iface->burst_bulk_in == NULL) { 279 async_answer_0(callid, ENOTSUP); 280 return; 281 } 282 283 int cycles = DEV_IPC_GET_ARG1(*call); 284 size_t size = DEV_IPC_GET_ARG2(*call); 285 usbdiag_dur_t duration; 286 const int ret = diag_iface->burst_intr_in(fun, cycles, size, &duration); 139 size_t size; 140 ipc_callid_t data_callid; 141 if (!async_data_write_receive(&data_callid, &size)) { 142 async_answer_0(data_callid, EINVAL); 143 async_answer_0(callid, EINVAL); 144 return; 145 } 146 147 if (size != sizeof(usbdiag_test_params_t)) { 148 async_answer_0(data_callid, EINVAL); 149 async_answer_0(callid, EINVAL); 150 return; 151 } 152 153 usbdiag_test_params_t params; 154 if (async_data_write_finalize(data_callid, ¶ms, size) != EOK) { 155 async_answer_0(callid, EINVAL); 156 return; 157 } 158 159 usbdiag_test_results_t results; 160 const int ret = !diag_iface->test_in ? ENOTSUP : diag_iface->test_in(fun, ¶ms, &results); 287 161 288 162 if (ret != EOK) { 289 163 async_answer_0(callid, ret); 290 } else { 291 async_answer_1(callid, EOK, duration); 292 } 293 } 294 295 void remote_usbdiag_burst_intr_out(ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call) 164 return; 165 } 166 167 if (!async_data_read_receive(&data_callid, &size)) { 168 async_answer_0(data_callid, EINVAL); 169 async_answer_0(callid, EINVAL); 170 return; 171 } 172 173 if (size != sizeof(usbdiag_test_results_t)) { 174 async_answer_0(data_callid, EINVAL); 175 async_answer_0(callid, EINVAL); 176 return; 177 } 178 179 if (async_data_read_finalize(data_callid, &results, size) != EOK) { 180 async_answer_0(callid, EINVAL); 181 return; 182 } 183 184 async_answer_0(callid, ret); 185 } 186 187 void remote_usbdiag_test_out(ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call) 296 188 { 297 189 const usbdiag_iface_t *diag_iface = (usbdiag_iface_t *) iface; 298 190 299 if (diag_iface->burst_bulk_out == NULL) { 300 async_answer_0(callid, ENOTSUP); 301 return; 302 } 303 304 int cycles = DEV_IPC_GET_ARG1(*call); 305 size_t size = DEV_IPC_GET_ARG2(*call); 306 usbdiag_dur_t duration; 307 const int ret = diag_iface->burst_intr_out(fun, cycles, size, &duration); 191 size_t size; 192 ipc_callid_t data_callid; 193 if (!async_data_write_receive(&data_callid, &size)) { 194 async_answer_0(data_callid, EINVAL); 195 async_answer_0(callid, EINVAL); 196 return; 197 } 198 199 if (size != sizeof(usbdiag_test_params_t)) { 200 async_answer_0(data_callid, EINVAL); 201 async_answer_0(callid, EINVAL); 202 return; 203 } 204 205 usbdiag_test_params_t params; 206 if (async_data_write_finalize(data_callid, ¶ms, size) != EOK) { 207 async_answer_0(callid, EINVAL); 208 return; 209 } 210 211 usbdiag_test_results_t results; 212 const int ret = !diag_iface->test_out ? ENOTSUP : diag_iface->test_out(fun, ¶ms, &results); 308 213 309 214 if (ret != EOK) { 310 215 async_answer_0(callid, ret); 311 } else { 312 async_answer_1(callid, EOK, duration); 313 } 314 } 315 316 void remote_usbdiag_burst_bulk_in(ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call) 317 { 318 const usbdiag_iface_t *diag_iface = (usbdiag_iface_t *) iface; 319 320 if (diag_iface->burst_bulk_in == NULL) { 321 async_answer_0(callid, ENOTSUP); 322 return; 323 } 324 325 int cycles = DEV_IPC_GET_ARG1(*call); 326 size_t size = DEV_IPC_GET_ARG2(*call); 327 usbdiag_dur_t duration; 328 const int ret = diag_iface->burst_bulk_in(fun, cycles, size, &duration); 329 330 if (ret != EOK) { 331 async_answer_0(callid, ret); 332 } else { 333 async_answer_1(callid, EOK, duration); 334 } 335 } 336 337 void remote_usbdiag_burst_bulk_out(ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call) 338 { 339 const usbdiag_iface_t *diag_iface = (usbdiag_iface_t *) iface; 340 341 if (diag_iface->burst_bulk_out == NULL) { 342 async_answer_0(callid, ENOTSUP); 343 return; 344 } 345 346 int cycles = DEV_IPC_GET_ARG1(*call); 347 size_t size = DEV_IPC_GET_ARG2(*call); 348 usbdiag_dur_t duration; 349 const int ret = diag_iface->burst_bulk_out(fun, cycles, size, &duration); 350 351 if (ret != EOK) { 352 async_answer_0(callid, ret); 353 } else { 354 async_answer_1(callid, EOK, duration); 355 } 356 } 357 358 void remote_usbdiag_burst_isoch_in(ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call) 359 { 360 const usbdiag_iface_t *diag_iface = (usbdiag_iface_t *) iface; 361 362 if (diag_iface->burst_isoch_in == NULL) { 363 async_answer_0(callid, ENOTSUP); 364 return; 365 } 366 367 int cycles = DEV_IPC_GET_ARG1(*call); 368 size_t size = DEV_IPC_GET_ARG2(*call); 369 usbdiag_dur_t duration; 370 const int ret = diag_iface->burst_isoch_in(fun, cycles, size, &duration); 371 372 if (ret != EOK) { 373 async_answer_0(callid, ret); 374 } else { 375 async_answer_1(callid, EOK, duration); 376 } 377 } 378 379 void remote_usbdiag_burst_isoch_out(ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call) 380 { 381 const usbdiag_iface_t *diag_iface = (usbdiag_iface_t *) iface; 382 383 if (diag_iface->burst_isoch_out == NULL) { 384 async_answer_0(callid, ENOTSUP); 385 return; 386 } 387 388 int cycles = DEV_IPC_GET_ARG1(*call); 389 size_t size = DEV_IPC_GET_ARG2(*call); 390 usbdiag_dur_t duration; 391 const int ret = diag_iface->burst_isoch_out(fun, cycles, size, &duration); 392 393 if (ret != EOK) { 394 async_answer_0(callid, ret); 395 } else { 396 async_answer_1(callid, EOK, duration); 397 } 398 } 399 400 void remote_usbdiag_data_intr_in(ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call) 401 { 402 const usbdiag_iface_t *diag_iface = (usbdiag_iface_t *) iface; 403 404 if (diag_iface->data_bulk_in == NULL) { 405 async_answer_0(callid, ENOTSUP); 406 return; 407 } 408 409 int cycles = DEV_IPC_GET_ARG1(*call); 410 size_t size = DEV_IPC_GET_ARG2(*call); 411 usbdiag_dur_t duration; 412 const int ret = diag_iface->data_intr_in(fun, cycles, size, &duration); 413 414 if (ret != EOK) { 415 async_answer_0(callid, ret); 416 } else { 417 async_answer_1(callid, EOK, duration); 418 } 419 } 420 421 void remote_usbdiag_data_intr_out(ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call) 422 { 423 const usbdiag_iface_t *diag_iface = (usbdiag_iface_t *) iface; 424 425 if (diag_iface->data_bulk_out == NULL) { 426 async_answer_0(callid, ENOTSUP); 427 return; 428 } 429 430 int cycles = DEV_IPC_GET_ARG1(*call); 431 size_t size = DEV_IPC_GET_ARG2(*call); 432 usbdiag_dur_t duration; 433 const int ret = diag_iface->data_intr_out(fun, cycles, size, &duration); 434 435 if (ret != EOK) { 436 async_answer_0(callid, ret); 437 } else { 438 async_answer_1(callid, EOK, duration); 439 } 440 } 441 442 void remote_usbdiag_data_bulk_in(ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call) 443 { 444 const usbdiag_iface_t *diag_iface = (usbdiag_iface_t *) iface; 445 446 if (diag_iface->data_bulk_in == NULL) { 447 async_answer_0(callid, ENOTSUP); 448 return; 449 } 450 451 int cycles = DEV_IPC_GET_ARG1(*call); 452 size_t size = DEV_IPC_GET_ARG2(*call); 453 usbdiag_dur_t duration; 454 const int ret = diag_iface->data_bulk_in(fun, cycles, size, &duration); 455 456 if (ret != EOK) { 457 async_answer_0(callid, ret); 458 } else { 459 async_answer_1(callid, EOK, duration); 460 } 461 } 462 463 void remote_usbdiag_data_bulk_out(ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call) 464 { 465 const usbdiag_iface_t *diag_iface = (usbdiag_iface_t *) iface; 466 467 if (diag_iface->data_bulk_out == NULL) { 468 async_answer_0(callid, ENOTSUP); 469 return; 470 } 471 472 int cycles = DEV_IPC_GET_ARG1(*call); 473 size_t size = DEV_IPC_GET_ARG2(*call); 474 usbdiag_dur_t duration; 475 const int ret = diag_iface->data_bulk_out(fun, cycles, size, &duration); 476 477 if (ret != EOK) { 478 async_answer_0(callid, ret); 479 } else { 480 async_answer_1(callid, EOK, duration); 481 } 482 } 483 484 void remote_usbdiag_data_isoch_in(ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call) 485 { 486 const usbdiag_iface_t *diag_iface = (usbdiag_iface_t *) iface; 487 488 if (diag_iface->data_isoch_in == NULL) { 489 async_answer_0(callid, ENOTSUP); 490 return; 491 } 492 493 int cycles = DEV_IPC_GET_ARG1(*call); 494 size_t size = DEV_IPC_GET_ARG2(*call); 495 usbdiag_dur_t duration; 496 const int ret = diag_iface->data_isoch_in(fun, cycles, size, &duration); 497 498 if (ret != EOK) { 499 async_answer_0(callid, ret); 500 } else { 501 async_answer_1(callid, EOK, duration); 502 } 503 } 504 505 void remote_usbdiag_data_isoch_out(ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call) 506 { 507 const usbdiag_iface_t *diag_iface = (usbdiag_iface_t *) iface; 508 509 if (diag_iface->data_isoch_out == NULL) { 510 async_answer_0(callid, ENOTSUP); 511 return; 512 } 513 514 int cycles = DEV_IPC_GET_ARG1(*call); 515 size_t size = DEV_IPC_GET_ARG2(*call); 516 usbdiag_dur_t duration; 517 const int ret = diag_iface->data_isoch_out(fun, cycles, size, &duration); 518 519 if (ret != EOK) { 520 async_answer_0(callid, ret); 521 } else { 522 async_answer_1(callid, EOK, duration); 523 } 216 return; 217 } 218 219 if (!async_data_read_receive(&data_callid, &size)) { 220 async_answer_0(data_callid, EINVAL); 221 async_answer_0(callid, EINVAL); 222 return; 223 } 224 225 if (size != sizeof(usbdiag_test_results_t)) { 226 async_answer_0(data_callid, EINVAL); 227 async_answer_0(callid, EINVAL); 228 return; 229 } 230 231 if (async_data_read_finalize(data_callid, &results, size) != EOK) { 232 async_answer_0(callid, EINVAL); 233 return; 234 } 235 236 async_answer_0(callid, ret); 524 237 } 525 238 -
uspace/lib/drv/include/usbdiag_iface.h
re67c50a r64ce0c1 39 39 40 40 #include <async.h> 41 #include <usbhc_iface.h> 41 42 #include "ddf/driver.h" 42 43 … … 46 47 typedef unsigned long usbdiag_dur_t; 47 48 49 /** Test parameters. */ 50 typedef struct usbdiag_test_params { 51 usb_transfer_type_t transfer_type; 52 size_t transfer_size; 53 usbdiag_dur_t min_duration; 54 bool validate_data; 55 } usbdiag_test_params_t; 56 57 /** Test results. */ 58 typedef struct usbdiag_test_results { 59 usbdiag_dur_t act_duration; 60 uint32_t transfer_count; 61 size_t transfer_size; 62 } usbdiag_test_results_t; 63 48 64 async_sess_t *usbdiag_connect(devman_handle_t); 49 65 void usbdiag_disconnect(async_sess_t*); 50 66 51 int usbdiag_burst_intr_in(async_exch_t*, int, size_t, usbdiag_dur_t*); 52 int usbdiag_burst_intr_out(async_exch_t*, int, size_t, usbdiag_dur_t*); 53 int usbdiag_burst_bulk_in(async_exch_t*, int, size_t, usbdiag_dur_t*); 54 int usbdiag_burst_bulk_out(async_exch_t*, int, size_t, usbdiag_dur_t*); 55 int usbdiag_burst_isoch_in(async_exch_t*, int, size_t, usbdiag_dur_t*); 56 int usbdiag_burst_isoch_out(async_exch_t*, int, size_t, usbdiag_dur_t*); 57 58 int usbdiag_data_intr_in(async_exch_t*, int, size_t, usbdiag_dur_t*); 59 int usbdiag_data_intr_out(async_exch_t*, int, size_t, usbdiag_dur_t*); 60 int usbdiag_data_bulk_in(async_exch_t*, int, size_t, usbdiag_dur_t*); 61 int usbdiag_data_bulk_out(async_exch_t*, int, size_t, usbdiag_dur_t*); 62 int usbdiag_data_isoch_in(async_exch_t*, int, size_t, usbdiag_dur_t*); 63 int usbdiag_data_isoch_out(async_exch_t*, int, size_t, usbdiag_dur_t*); 67 int usbdiag_test_in(async_exch_t*, const usbdiag_test_params_t *, usbdiag_test_results_t *); 68 int usbdiag_test_out(async_exch_t*, const usbdiag_test_params_t *, usbdiag_test_results_t *); 64 69 65 70 /** USB diagnostic device communication interface. */ 66 71 typedef struct { 67 int (*burst_intr_in)(ddf_fun_t*, int, size_t, usbdiag_dur_t*); 68 int (*burst_intr_out)(ddf_fun_t*, int, size_t, usbdiag_dur_t*); 69 int (*burst_bulk_in)(ddf_fun_t*, int, size_t, usbdiag_dur_t*); 70 int (*burst_bulk_out)(ddf_fun_t*, int, size_t, usbdiag_dur_t*); 71 int (*burst_isoch_in)(ddf_fun_t*, int, size_t, usbdiag_dur_t*); 72 int (*burst_isoch_out)(ddf_fun_t*, int, size_t, usbdiag_dur_t*); 73 int (*data_intr_in)(ddf_fun_t*, int, size_t, usbdiag_dur_t*); 74 int (*data_intr_out)(ddf_fun_t*, int, size_t, usbdiag_dur_t*); 75 int (*data_bulk_in)(ddf_fun_t*, int, size_t, usbdiag_dur_t*); 76 int (*data_bulk_out)(ddf_fun_t*, int, size_t, usbdiag_dur_t*); 77 int (*data_isoch_in)(ddf_fun_t*, int, size_t, usbdiag_dur_t*); 78 int (*data_isoch_out)(ddf_fun_t*, int, size_t, usbdiag_dur_t*); 72 int (*test_in)(ddf_fun_t*, const usbdiag_test_params_t *, usbdiag_test_results_t *); 73 int (*test_out)(ddf_fun_t*, const usbdiag_test_params_t *, usbdiag_test_results_t *); 79 74 } usbdiag_iface_t; 80 75 -
uspace/lib/usbdev/src/pipesinit.c
re67c50a r64ce0c1 146 146 if (interface_number_fits 147 147 && interface_setting_fits 148 && endpoint_descriptions_fits) { 148 && endpoint_descriptions_fits 149 && !mapping->present) { 149 150 return mapping; 150 151 } … … 153 154 mapping_count--; 154 155 } 156 155 157 return NULL; 156 158 } -
uspace/lib/usbhost/src/endpoint.c
re67c50a r64ce0c1 244 244 245 245 /** Limit transfers with reserved bandwidth to the amount reserved */ 246 if ((ep->transfer_type == USB_TRANSFER_INTERRUPT 247 || ep->transfer_type == USB_TRANSFER_ISOCHRONOUS) 248 && size > ep->max_transfer_size) 246 if (ep->direction == USB_DIRECTION_OUT && size > ep->max_transfer_size) 249 247 return ENOSPC; 250 248
Note:
See TracChangeset
for help on using the changeset viewer.