Changeset 7dd3318 in mainline
- Timestamp:
- 2011-02-12T02:00:54Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 83c439c
- Parents:
- f6309b6
- Location:
- uspace/drv/uhci-hcd
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/uhci-hcd/iface.c
rf6309b6 r7dd3318 110 110 111 111 tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_INTERRUPT, 112 max_packet_size, speed, data, size, NULL, callback, arg);112 max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg); 113 113 if (!tracker) 114 114 return ENOMEM; … … 125 125 126 126 tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_INTERRUPT, 127 max_packet_size, speed, data, size, callback, NULL, arg);127 max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg); 128 128 if (!tracker) 129 129 return ENOMEM; … … 140 140 141 141 tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL, 142 max_packet_size, speed, data, size, NULL, callback, arg); 143 if (!tracker) 144 return ENOMEM; 145 tracker_control_write(tracker, setup_data, setup_size); 142 max_packet_size, speed, data, size, setup_data, setup_size, 143 NULL, callback, arg); 144 if (!tracker) 145 return ENOMEM; 146 tracker_control_write(tracker); 146 147 return EOK; 147 148 } … … 155 156 156 157 tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL, 157 max_packet_size, speed, data, size, callback, NULL, arg); 158 if (!tracker) 159 return ENOMEM; 160 tracker_control_read(tracker, setup_data, setup_size); 158 max_packet_size, speed, data, size, setup_data, setup_size, callback, 159 NULL, arg); 160 if (!tracker) 161 return ENOMEM; 162 tracker_control_read(tracker); 161 163 return EOK; 162 164 } … … 166 168 usbhc_iface_transfer_out_callback_t callback, void *arg) 167 169 { 168 usb_log_warning("Using deprecated API %s.\n", __FUNCTION__); 169 tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL, 170 8, FULL_SPEED, data, size, NULL, callback, arg); 170 size_t max_packet_size = 8; 171 dev_speed_t speed = FULL_SPEED; 172 173 usb_log_warning("Using deprecated API %s.\n", __FUNCTION__); 174 tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL, 175 max_packet_size, speed, NULL, 0, data, size, NULL, callback, arg); 171 176 if (!tracker) 172 177 return ENOMEM; … … 179 184 usbhc_iface_transfer_out_callback_t callback, void *arg) 180 185 { 181 usb_log_warning("Using deprecated API %s.\n", __FUNCTION__); 182 tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL, 183 size, FULL_SPEED, data, size, NULL, callback, arg); 186 size_t max_packet_size = 8; 187 dev_speed_t speed = FULL_SPEED; 188 189 usb_log_warning("Using deprecated API %s.\n", __FUNCTION__); 190 tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL, 191 max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg); 184 192 if (!tracker) 185 193 return ENOMEM; … … 191 199 usbhc_iface_transfer_in_callback_t callback, void *arg) 192 200 { 193 usb_log_warning("Using deprecated API %s.\n", __FUNCTION__); 194 tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL, 195 0, FULL_SPEED, NULL, 0, callback, NULL, arg); 201 size_t max_packet_size = 8; 202 dev_speed_t speed = FULL_SPEED; 203 204 usb_log_warning("Using deprecated API %s.\n", __FUNCTION__); 205 tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL, 206 max_packet_size, speed, NULL, 0, NULL, 0, callback, NULL, arg); 196 207 if (!tracker) 197 208 return ENOMEM; … … 204 215 usbhc_iface_transfer_out_callback_t callback, void *arg) 205 216 { 206 usb_log_warning("Using deprecated API %s.\n", __FUNCTION__); 207 tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL, 208 8, FULL_SPEED, data, size, NULL, callback, arg); 217 size_t max_packet_size = 8; 218 dev_speed_t speed = FULL_SPEED; 219 220 usb_log_warning("Using deprecated API %s.\n", __FUNCTION__); 221 tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL, 222 max_packet_size, speed, NULL, 0, data, size, NULL, callback, arg); 209 223 if (!tracker) 210 224 return ENOMEM; … … 217 231 usbhc_iface_transfer_in_callback_t callback, void *arg) 218 232 { 219 usb_log_warning("Using deprecated API %s.\n", __FUNCTION__); 220 tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL, 221 size, FULL_SPEED, data, size, callback, NULL, arg); 233 size_t max_packet_size = 8; 234 dev_speed_t speed = FULL_SPEED; 235 236 usb_log_warning("Using deprecated API %s.\n", __FUNCTION__); 237 tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL, 238 max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg); 222 239 if (!tracker) 223 240 return ENOMEM; … … 229 246 usbhc_iface_transfer_out_callback_t callback, void *arg) 230 247 { 231 usb_log_warning("Using deprecated API %s.\n", __FUNCTION__); 232 tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL, 233 0, FULL_SPEED, NULL, 0, NULL, callback, arg); 248 size_t max_packet_size = 8; 249 dev_speed_t speed = FULL_SPEED; 250 251 usb_log_warning("Using deprecated API %s.\n", __FUNCTION__); 252 tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL, 253 max_packet_size, speed, NULL, 0, NULL, 0, NULL, callback, arg); 234 254 if (!tracker) 235 255 return ENOMEM; -
uspace/drv/uhci-hcd/main.c
rf6309b6 r7dd3318 134 134 */ 135 135 sleep(5); 136 usb_log_enable(USB_LOG_LEVEL_ INFO, NAME);136 usb_log_enable(USB_LOG_LEVEL_DEBUG2, NAME); 137 137 138 138 return driver_main(&uhci_driver); -
uspace/drv/uhci-hcd/tracker.c
rf6309b6 r7dd3318 41 41 #include "utils/malloc32.h" 42 42 43 #define SETUP_PACKET_DATA_SIZE 844 43 #define DEFAULT_ERROR_COUNT 3 45 #define MAX(a,b) ((a > b) ? a : b)46 #define MIN(a,b) ((a < b) ? a : b)47 44 48 45 static int tracker_schedule(tracker_t *instance); 49 50 static void tracker_control_read_data(tracker_t *instance);51 static void tracker_control_write_data(tracker_t *instance);52 static void tracker_control_read_status(tracker_t *instance);53 static void tracker_control_write_status(tracker_t *instance);54 46 55 47 static void tracker_call_in(tracker_t *instance); … … 62 54 usb_transfer_type_t transfer_type, size_t max_packet_size, 63 55 dev_speed_t speed, char *buffer, size_t size, 56 char* setup_buffer, size_t setup_size, 64 57 usbhc_iface_transfer_in_callback_t func_in, 65 58 usbhc_iface_transfer_out_callback_t func_out, void *arg) … … 69 62 70 63 tracker_t *instance = malloc(sizeof(tracker_t)); 71 if ( !instance) {72 usb_log_error("Failed to allocate tracker i sntance.\n");73 return NULL; 74 } 75 76 instance-> td = malloc32(sizeof(transfer_descriptor_t));77 if ( !instance->td) {78 usb_log_error("Failed to allocate transfer descriptor.\n");64 if (instance == NULL) { 65 usb_log_error("Failed to allocate tracker instance.\n"); 66 return NULL; 67 } 68 69 instance->qh = queue_head_get(); 70 if (instance->qh == NULL) { 71 usb_log_error("Failed to allocate queue head.\n"); 79 72 free(instance); 80 73 return NULL; 81 74 } 82 bzero(instance->td, sizeof(transfer_descriptor_t)); 83 84 instance->packet = max_packet_size ? malloc32(max_packet_size) : NULL; 85 if (max_packet_size && !instance->packet) { 86 usb_log_error("Failed to allocate device acessible buffer.\n"); 87 free32(instance->td); 75 76 instance->packets = (size + max_packet_size - 1) / max_packet_size; 77 if (transfer_type == USB_TRANSFER_CONTROL) { 78 instance->packets += 2; 79 } 80 81 instance->tds = malloc32(sizeof(transfer_descriptor_t) * instance->packets); 82 if (instance->tds == NULL) { 83 usb_log_error("Failed to allocate transfer descriptors.\n"); 84 queue_head_dispose(instance->qh); 88 85 free(instance); 89 86 return NULL; 90 87 } 88 bzero(instance->tds, sizeof(transfer_descriptor_t) * instance->packets); 89 90 const size_t transport_size = max_packet_size * instance->packets; 91 92 instance->transport_buffer = 93 (size > 0) ? malloc32(transport_size) : NULL; 94 if ((size > 0) && (instance->transport_buffer == NULL)) { 95 usb_log_error("Failed to allocate device accessible buffer.\n"); 96 queue_head_dispose(instance->qh); 97 free32(instance->tds); 98 free(instance); 99 return NULL; 100 } 101 102 instance->setup_buffer = setup_buffer ? malloc32(setup_size) : NULL; 103 if ((setup_size > 0) && (instance->setup_buffer == NULL)) { 104 usb_log_error("Failed to allocate device accessible setup buffer.\n"); 105 queue_head_dispose(instance->qh); 106 free32(instance->tds); 107 free32(instance->transport_buffer); 108 free(instance); 109 return NULL; 110 } 111 if (instance->setup_buffer) { 112 memcpy(instance->setup_buffer, setup_buffer, setup_size); 113 } 114 91 115 instance->max_packet_size = max_packet_size; 92 instance->packet_size = 0;93 instance->buffer_offset = 0;94 116 95 117 link_initialize(&instance->link); 118 96 119 instance->target = target; 97 120 instance->transfer_type = transfer_type; … … 101 124 if (func_in) 102 125 instance->callback_in = func_in; 126 103 127 instance->buffer = buffer; 104 128 instance->buffer_size = size; 129 instance->setup_size = setup_size; 105 130 instance->dev = dev; 106 131 instance->arg = arg; 107 instance->toggle = 0;108 132 instance->speed = speed; 109 133 134 queue_head_element_td(instance->qh, addr_to_phys(instance->tds)); 110 135 return instance; 111 136 } 112 137 /*----------------------------------------------------------------------------*/ 113 void tracker_control_write( 114 tracker_t *instance, char* setup_buffer, size_t setup_size) 115 { 116 assert(instance); 117 assert(instance->buffer_offset == 0); 118 assert(setup_size == 8); 119 120 instance->packet_size = 0; 121 memcpy(instance->packet, setup_buffer, setup_size); 122 123 transfer_descriptor_init(instance->td, DEFAULT_ERROR_COUNT, 124 setup_size, instance->toggle++, false, instance->target, 125 USB_PID_SETUP, instance->packet); 126 127 instance->next_step = tracker_control_write_data; 128 129 tracker_schedule(instance); 130 } 131 /*----------------------------------------------------------------------------*/ 132 void tracker_control_read( 133 tracker_t *instance, char* setup_buffer, size_t setup_size) 134 { 135 assert(instance); 136 assert(instance->buffer_offset == 0); 137 assert(setup_size == 8); 138 139 memcpy(instance->packet, setup_buffer, setup_size); 140 141 transfer_descriptor_init(instance->td, DEFAULT_ERROR_COUNT, 142 setup_size, instance->toggle++, false, instance->target, 143 USB_PID_SETUP, instance->packet); 144 145 instance->next_step = tracker_control_read_data; 146 147 tracker_schedule(instance); 148 } 149 /*----------------------------------------------------------------------------*/ 150 void tracker_control_read_data(tracker_t *instance) 151 { 152 assert(instance); 153 154 /* check for errors */ 155 int err = transfer_descriptor_status(instance->td); 156 if (err != EOK) { 157 tracker_call_in_and_dispose(instance); 158 return; 159 } 160 161 /* we are data in, we want data from our device */ 162 if (instance->packet_size) { 163 memcpy(instance->buffer + instance->buffer_offset, instance->packet, 164 instance->packet_size); 165 } 166 instance->buffer_offset += instance->packet_size; 167 168 /* prepare next packet, no copy, we are receiving data */ 169 instance->packet_size = MIN(instance->max_packet_size, 170 instance->buffer_size - instance->buffer_offset); 171 172 transfer_descriptor_init(instance->td, DEFAULT_ERROR_COUNT, 173 instance->packet_size, instance->toggle++, false, instance->target, 174 USB_PID_IN, instance->packet); 175 176 tracker_schedule(instance); 177 178 /* set next step */ 179 if ((instance->buffer_offset + instance->packet_size) 180 >= instance->buffer_size) { 181 /* that's all, end coomunication */ 182 instance->next_step = tracker_control_read_status; 183 } 184 } 185 /*----------------------------------------------------------------------------*/ 186 void tracker_control_write_data(tracker_t *instance) 187 { 188 assert(instance); 189 190 /* check for errors */ 191 int err = transfer_descriptor_status(instance->td); 192 if (err != EOK) { 193 tracker_call_out_and_dispose(instance); 194 return; 195 } 196 197 /* we are data out, we don't want data from our device */ 198 instance->buffer_offset += instance->packet_size; 199 200 /* prepare next packet, copy data to packet */ 201 instance->packet_size = MIN(instance->max_packet_size, 202 instance->buffer_size - instance->buffer_offset); 203 memcpy(instance->packet, instance->buffer + instance->buffer_offset, 204 instance->packet_size); 205 206 transfer_descriptor_init(instance->td, DEFAULT_ERROR_COUNT, 207 instance->packet_size, instance->toggle++, false, instance->target, 208 USB_PID_OUT, instance->packet); 209 210 tracker_schedule(instance); 211 212 /* set next step */ 213 if ((instance->buffer_offset + instance->packet_size) 214 >= instance->buffer_size) { 215 /* that's all, end coomunication */ 216 instance->next_step = tracker_control_write_status; 217 } 218 } 219 /*----------------------------------------------------------------------------*/ 220 void tracker_control_read_status(tracker_t *instance) 221 { 222 assert(instance); 223 224 /* check for errors */ 225 int err = transfer_descriptor_status(instance->td); 226 if (err != EOK) { 227 tracker_call_in_and_dispose(instance); 228 return; 229 } 230 231 /* we are data in, we want data from our device */ 232 memcpy(instance->buffer + instance->buffer_offset, instance->packet, 233 instance->packet_size); 234 instance->buffer_offset += instance->packet_size; 235 assert(instance->buffer_offset = instance->buffer_size); 236 237 /* prepare next packet, no nothing, just an empty packet */ 238 instance->packet_size = 0; 239 transfer_descriptor_init(instance->td, DEFAULT_ERROR_COUNT, 240 instance->packet_size, 1, false, instance->target, USB_PID_OUT, NULL); 241 242 tracker_schedule(instance); 243 244 /* set next step, callback and cleanup */ 138 bool tracker_is_complete(tracker_t *instance) 139 { 140 assert(instance); 141 usb_log_debug("Checking(%p) %d packet for completion.\n", 142 instance, instance->packets); 143 /* This is just an ugly trick to support the old API */ 144 instance->transfered_size = -instance->setup_size; 145 size_t i = 0; 146 for (;i < instance->packets; ++i) { 147 if (transfer_descriptor_is_active(&instance->tds[i])) 148 return false; 149 instance->error = transfer_descriptor_status(&instance->tds[i]); 150 if (instance->error != EOK) { 151 return true; 152 } 153 instance->transfered_size += 154 transfer_descriptor_actual_size(&instance->tds[i]); 155 } 156 return true; 157 } 158 /*----------------------------------------------------------------------------*/ 159 void tracker_control_write(tracker_t *instance) 160 { 161 assert(instance); 162 163 /* we are data out, we are supposed to provide data */ 164 memcpy(instance->transport_buffer, instance->buffer, instance->buffer_size); 165 166 int toggle = 0; 167 /* setup stage */ 168 transfer_descriptor_init(instance->tds, DEFAULT_ERROR_COUNT, 169 instance->setup_size, toggle, false, instance->target, 170 USB_PID_SETUP, instance->setup_buffer, &instance->tds[1]); 171 172 /* data stage */ 173 size_t i = 1; 174 for (;i < instance->packets - 1; ++i) { 175 char *data = 176 instance->transport_buffer + ((i - 1) * instance->max_packet_size); 177 toggle = 1 - toggle; 178 179 transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT, 180 instance->max_packet_size, toggle++, false, instance->target, 181 USB_PID_OUT, data, &instance->tds[i + 1]); 182 } 183 184 /* status stage */ 185 i = instance->packets - 1; 186 transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT, 187 0, 1, false, instance->target, USB_PID_IN, NULL, NULL); 188 189 instance->next_step = tracker_call_out_and_dispose; 190 tracker_schedule(instance); 191 } 192 /*----------------------------------------------------------------------------*/ 193 void tracker_control_read(tracker_t *instance) 194 { 195 assert(instance); 196 197 int toggle = 0; 198 /* setup stage */ 199 transfer_descriptor_init(instance->tds, DEFAULT_ERROR_COUNT, 200 instance->setup_size, toggle, false, instance->target, 201 USB_PID_SETUP, instance->setup_buffer, &instance->tds[1]); 202 203 /* data stage */ 204 size_t i = 1; 205 for (;i < instance->packets - 1; ++i) { 206 char *data = 207 instance->transport_buffer + ((i - 1) * instance->max_packet_size); 208 toggle = 1 - toggle; 209 210 transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT, 211 instance->max_packet_size, toggle, false, instance->target, 212 USB_PID_IN, data, &instance->tds[i + 1]); 213 } 214 215 /* status stage */ 216 i = instance->packets - 1; 217 transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT, 218 0, 1, false, instance->target, USB_PID_OUT, NULL, NULL); 219 245 220 instance->next_step = tracker_call_in_and_dispose; 246 } 247 /*----------------------------------------------------------------------------*/ 248 void tracker_control_write_status(tracker_t *instance) 249 { 250 assert(instance); 251 252 /* check for errors */ 253 int err = transfer_descriptor_status(instance->td); 254 if (err != EOK) { 255 tracker_call_out_and_dispose(instance); 256 return; 257 } 258 259 /* we are data in, we want data from our device */ 260 assert( 261 instance->buffer_offset + instance->packet_size <= instance->buffer_size); 262 memcpy(instance->buffer + instance->buffer_offset, instance->packet, 263 instance->packet_size); 264 instance->buffer_offset += instance->packet_size; 265 assert(instance->buffer_offset = instance->buffer_size); 266 267 /* prepare next packet, no nothing, just an empty packet */ 268 instance->packet_size = 0; 269 transfer_descriptor_init(instance->td, DEFAULT_ERROR_COUNT, 270 instance->packet_size, 1, false, instance->target, USB_PID_IN, NULL); 271 272 tracker_schedule(instance); 273 274 /* set next step, callback and cleanup */ 221 tracker_schedule(instance); 222 } 223 /*----------------------------------------------------------------------------*/ 224 void tracker_interrupt_in(tracker_t *instance) 225 { 226 assert(instance); 227 228 int toggle = 1; 229 size_t i = 0; 230 for (;i < instance->packets; ++i) { 231 char *data = 232 instance->transport_buffer + (i * instance->max_packet_size); 233 transfer_descriptor_t *next = (i + 1) < instance->packets ? 234 &instance->tds[i + 1] : NULL; 235 toggle = 1 - toggle; 236 237 transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT, 238 instance->max_packet_size, toggle, false, instance->target, 239 USB_PID_IN, data, next); 240 } 241 242 instance->next_step = tracker_call_in_and_dispose; 243 tracker_schedule(instance); 244 } 245 /*----------------------------------------------------------------------------*/ 246 void tracker_interrupt_out(tracker_t *instance) 247 { 248 assert(instance); 249 250 memcpy(instance->transport_buffer, instance->buffer, instance->buffer_size); 251 252 int toggle = 1; 253 size_t i = 0; 254 for (;i < instance->packets; ++i) { 255 char *data = 256 instance->transport_buffer + (i * instance->max_packet_size); 257 transfer_descriptor_t *next = (i + 1) < instance->packets ? 258 &instance->tds[i + 1] : NULL; 259 toggle = 1 - toggle; 260 261 transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT, 262 instance->max_packet_size, toggle++, false, instance->target, 263 USB_PID_OUT, data, next); 264 } 265 275 266 instance->next_step = tracker_call_out_and_dispose; 276 } 277 /*----------------------------------------------------------------------------*/ 278 void tracker_interrupt_in(tracker_t *instance) 279 { 280 assert(instance); 281 282 /* check for errors */ 283 int err = transfer_descriptor_status(instance->td); 284 if (err != EOK) { 285 tracker_call_in_and_dispose(instance); 286 return; 287 } 288 289 assert(instance->packet_size <= instance->max_packet_size); 290 if (instance->packet_size) { 291 /* we are data in, we want data from our device. if there is data */ 292 memcpy(instance->buffer + instance->buffer_offset, instance->packet, 293 instance->packet_size); 294 instance->buffer_offset += instance->packet_size; 295 } 296 297 /* prepare next packet, no copy, we are receiving data */ 298 instance->packet_size = MIN(instance->max_packet_size, 299 instance->buffer_size - instance->buffer_offset); 300 assert(instance->packet_size <= instance->max_packet_size); 301 302 transfer_descriptor_init(instance->td, DEFAULT_ERROR_COUNT, 303 instance->packet_size, instance->toggle++, false, instance->target, 304 USB_PID_IN, instance->packet); 305 306 tracker_schedule(instance); 307 308 /* set next step */ 309 if ((instance->buffer_offset + instance->packet_size) 310 >= instance->buffer_size) { 311 /* that's all, end coomunication */ 312 instance->next_step = tracker_call_in_and_dispose; 313 } else { 314 instance->next_step = tracker_interrupt_in; 315 } 316 } 317 /*----------------------------------------------------------------------------*/ 318 void tracker_interrupt_out(tracker_t *instance) 319 { 320 assert(instance); 321 322 /* check for errors */ 323 int err = transfer_descriptor_status(instance->td); 324 if (err != EOK) { 325 tracker_call_out_and_dispose(instance); 326 return; 327 } 328 329 /* we are data out, we don't want data from our device */ 330 instance->buffer_offset += instance->packet_size; 331 332 /* prepare next packet, copy data to packet */ 333 instance->packet_size = MIN(instance->max_packet_size, 334 instance->buffer_size - instance->buffer_offset); 335 memcpy(instance->packet, instance->buffer + instance->buffer_offset, 336 instance->packet_size); 337 338 transfer_descriptor_init(instance->td, DEFAULT_ERROR_COUNT, 339 instance->packet_size, instance->toggle++, false, instance->target, 340 USB_PID_OUT, instance->packet); 341 342 tracker_schedule(instance); 343 344 /* set next step */ 345 if ((instance->buffer_offset + instance->packet_size) 346 >= instance->buffer_size) { 347 /* that's all, end coomunication */ 348 instance->next_step = tracker_call_out_and_dispose; 349 } else { 350 instance->next_step = tracker_interrupt_out; 351 } 267 tracker_schedule(instance); 352 268 } 353 269 /*----------------------------------------------------------------------------*/ … … 357 273 assert(instance->callback_in); 358 274 359 /* check for errors */ 360 int err = transfer_descriptor_status(instance->td); 361 if (err == EOK && instance->packet_size) { 362 memcpy(instance->buffer + instance->buffer_offset, instance->packet, 363 instance->packet_size); 364 instance->buffer_offset += instance->packet_size; 365 } 366 usb_log_debug("Callback IN(%d): %d, %zu.\n", instance->transfer_type, 367 err, instance->buffer_offset); 275 memcpy(instance->buffer, instance->transport_buffer, instance->buffer_size); 276 277 int err = instance->error; 278 usb_log_info("Callback IN(%d): %d, %zu.\n", instance->transfer_type, 279 err, instance->transfered_size); 280 368 281 instance->callback_in(instance->dev, 369 err ? USB_OUTCOME_CRCERROR : USB_OUTCOME_OK, instance->buffer_offset,282 err, instance->transfered_size, 370 283 instance->arg); 371 284 } … … 376 289 assert(instance->callback_out); 377 290 378 /* check for errors */ 379 int err = transfer_descriptor_status(instance->td); 380 usb_log_debug("Callback OUT(%d): %d, %zu.\n", instance->transfer_type, 381 err, instance->buffer_offset); 291 int err = instance->error; 292 usb_log_info("Callback OUT(%d): %d.\n", instance->transfer_type, err); 382 293 instance->callback_out(instance->dev, 383 err ? USB_OUTCOME_CRCERROR : USB_OUTCOME_OK, instance->arg);294 err, instance->arg); 384 295 } 385 296 /*----------------------------------------------------------------------------*/ … … 388 299 assert(instance); 389 300 tracker_call_in(instance); 390 transfer_list_remove_tracker(instance->scheduled_list, instance); 391 free32(instance->td); 392 free32(instance->packet); 301 usb_log_debug("Disposing tracker: %p.\n", instance); 302 free32(instance->tds); 303 free32(instance->qh); 304 free32(instance->setup_buffer); 305 free32(instance->transport_buffer); 393 306 free(instance); 394 307 } … … 398 311 assert(instance); 399 312 tracker_call_out(instance); 400 assert(instance->scheduled_list); 401 transfer_list_remove_tracker(instance->scheduled_list, instance); 402 free32(instance->td); 403 free32(instance->packet); 313 usb_log_debug("Disposing tracker: %p.\n", instance); 314 free32(instance->tds); 315 free32(instance->qh); 316 free32(instance->setup_buffer); 317 free32(instance->transport_buffer); 404 318 free(instance); 405 319 } … … 417 331 { 418 332 assert(instance); 419 assert(instance->buffer_offset == 0); 420 421 instance->packet_size = SETUP_PACKET_DATA_SIZE; 422 memcpy(instance->packet, instance->buffer, SETUP_PACKET_DATA_SIZE); 423 424 transfer_descriptor_init(instance->td, DEFAULT_ERROR_COUNT, 425 SETUP_PACKET_DATA_SIZE, 0, false, instance->target, USB_PID_SETUP, 426 instance->packet); 427 428 instance->buffer_offset += SETUP_PACKET_DATA_SIZE; 333 instance->packets = 1; 334 335 /* setup stage */ 336 transfer_descriptor_init(instance->tds, DEFAULT_ERROR_COUNT, 337 instance->setup_size, 0, false, instance->target, 338 USB_PID_SETUP, instance->setup_buffer, NULL); 339 429 340 instance->next_step = tracker_call_out_and_dispose; 430 431 tracker_schedule(instance); 432 } 433 341 tracker_schedule(instance); 342 } 343 /*----------------------------------------------------------------------------*/ 434 344 void tracker_control_write_data_old(tracker_t *instance) 435 345 { 436 346 assert(instance); 437 assert(instance->max_packet_size == instance->buffer_size); 438 439 memcpy(instance->packet, instance->buffer, instance->max_packet_size); 440 instance->packet_size = instance->max_packet_size; 441 442 transfer_descriptor_init(instance->td, DEFAULT_ERROR_COUNT, 443 instance->packet_size, 1, false, instance->target, USB_PID_OUT, 444 instance->packet); 347 instance->packets -= 2; 348 tracker_interrupt_out(instance); 349 } 350 /*----------------------------------------------------------------------------*/ 351 void tracker_control_read_data_old(tracker_t *instance) 352 { 353 assert(instance); 354 instance->packets -= 2; 355 tracker_interrupt_in(instance); 356 } 357 /*----------------------------------------------------------------------------*/ 358 void tracker_control_write_status_old(tracker_t *instance) 359 { 360 assert(instance); 361 instance->packets = 1; 362 transfer_descriptor_init(instance->tds, DEFAULT_ERROR_COUNT, 363 0, 1, false, instance->target, USB_PID_IN, NULL, NULL); 364 instance->next_step = tracker_call_in_and_dispose; 365 tracker_schedule(instance); 366 } 367 /*----------------------------------------------------------------------------*/ 368 void tracker_control_read_status_old(tracker_t *instance) 369 { 370 assert(instance); 371 instance->packets = 1; 372 transfer_descriptor_init(instance->tds, DEFAULT_ERROR_COUNT, 373 0, 1, false, instance->target, USB_PID_OUT, NULL, NULL); 445 374 instance->next_step = tracker_call_out_and_dispose; 446 447 tracker_schedule(instance);448 }449 450 void tracker_control_read_data_old(tracker_t *instance)451 {452 assert(instance);453 assert(instance->max_packet_size == instance->buffer_size);454 455 instance->packet_size = instance->max_packet_size;456 457 transfer_descriptor_init(instance->td, DEFAULT_ERROR_COUNT,458 instance->packet_size, 1, false, instance->target, USB_PID_IN,459 instance->packet);460 461 instance->next_step = tracker_call_in_and_dispose;462 463 tracker_schedule(instance);464 }465 466 void tracker_control_write_status_old(tracker_t *instance)467 {468 assert(instance);469 assert(instance->max_packet_size == 0);470 assert(instance->buffer_size == 0);471 assert(instance->packet == NULL);472 473 instance->packet_size = instance->max_packet_size;474 instance->next_step = tracker_call_in_and_dispose;475 476 transfer_descriptor_init(instance->td, DEFAULT_ERROR_COUNT,477 instance->packet_size, 1, false, instance->target, USB_PID_IN,478 instance->packet);479 480 tracker_schedule(instance);481 }482 483 void tracker_control_read_status_old(tracker_t *instance)484 {485 assert(instance);486 assert(instance->max_packet_size == 0);487 assert(instance->buffer_size == 0);488 assert(instance->packet == NULL);489 490 instance->packet_size = instance->max_packet_size;491 instance->next_step = tracker_call_out_and_dispose;492 493 transfer_descriptor_init(instance->td, DEFAULT_ERROR_COUNT,494 instance->packet_size, 1, false, instance->target, USB_PID_OUT,495 instance->packet);496 497 375 tracker_schedule(instance); 498 376 } -
uspace/drv/uhci-hcd/tracker.h
rf6309b6 r7dd3318 41 41 42 42 #include "uhci_struct/transfer_descriptor.h" 43 #include "uhci_struct/queue_head.h" 43 44 44 45 typedef enum { … … 47 48 } dev_speed_t; 48 49 49 struct transfer_list;50 51 50 typedef struct tracker 52 51 { 53 52 link_t link; 53 dev_speed_t speed; 54 54 usb_target_t target; 55 55 usb_transfer_type_t transfer_type; … … 59 59 }; 60 60 void *arg; 61 char *transport_buffer; 62 char *setup_buffer; 63 size_t setup_size; 61 64 char *buffer; 62 char *packet;63 65 size_t buffer_size; 64 66 size_t max_packet_size; 65 size_t packet _size;66 size_t buffer_offset;67 dev_speed_t speed;67 size_t packets; 68 size_t transfered_size; 69 int error; 68 70 device_t *dev; 69 transfer_descriptor_t *td; 71 queue_head_t *qh; 72 transfer_descriptor_t *tds; 70 73 void (*next_step)(struct tracker*); 71 unsigned toggle:1;72 73 struct transfer_list *scheduled_list;74 74 } tracker_t; 75 76 75 77 76 tracker_t * tracker_get(device_t *dev, usb_target_t target, 78 77 usb_transfer_type_t transfer_type, size_t max_packet_size, 79 78 dev_speed_t speed, char *buffer, size_t size, 79 char *setup_buffer, size_t setup_size, 80 80 usbhc_iface_transfer_in_callback_t func_in, 81 81 usbhc_iface_transfer_out_callback_t func_out, void *arg); 82 82 83 void tracker_control_write( 84 tracker_t *instance, char* setup_buffer, size_t setup_size); 83 bool tracker_is_complete(tracker_t *instance); 85 84 86 void tracker_control_read( 87 tracker_t *instance, char* setup_buffer, size_t setup_size); 85 void tracker_control_write(tracker_t *instance); 86 87 void tracker_control_read(tracker_t *instance); 88 88 89 89 void tracker_interrupt_in(tracker_t *instance); -
uspace/drv/uhci-hcd/transfer_list.c
rf6309b6 r7dd3318 51 51 52 52 queue_head_init(instance->queue_head); 53 list_initialize(&instance->tracker_list); 53 54 return EOK; 54 55 } … … 58 59 assert(instance); 59 60 assert(next); 60 instance->next = next;61 61 if (!instance->queue_head) 62 62 return; 63 queue_head_a dd_next(instance->queue_head, next->queue_head_pa);63 queue_head_append_qh(instance->queue_head, next->queue_head_pa); 64 64 } 65 65 /*----------------------------------------------------------------------------*/ … … 69 69 assert(tracker); 70 70 71 uint32_t pa = (uintptr_t)addr_to_phys(tracker-> td);71 uint32_t pa = (uintptr_t)addr_to_phys(tracker->qh); 72 72 assert((pa & LINK_POINTER_ADDRESS_MASK) == pa); 73 pa |= LINK_POINTER_QUEUE_HEAD_FLAG; 73 74 74 75 75 if (instance->queue_head->element & LINK_POINTER_TERMINATE_FLAG) { 76 usb_log_debug2("Adding td(%X:%X) to queue %s first.\n", 77 tracker->td->status, tracker->td->device, instance->name); 76 if ((instance->queue_head->element & LINK_POINTER_TERMINATE_FLAG) != 0) { 78 77 /* there is nothing scheduled */ 79 instance->last_tracker = tracker;78 list_append(&tracker->link, &instance->tracker_list); 80 79 instance->queue_head->element = pa; 81 usb_log_debug2("Added t d(%X:%X) to queue %s first.\n",82 tracker ->td->status, tracker->td->device, instance->name);80 usb_log_debug2("Added tracker(%p) to queue %s first.\n", 81 tracker, instance->name); 83 82 return; 84 83 } 85 usb_log_debug2("Adding td(%X:%X) to queue %s last.%p\n", 86 tracker->td->status, tracker->td->device, instance->name, 87 instance->last_tracker); 88 /* now we can be sure that last_tracker is a valid pointer */ 89 instance->last_tracker->td->next = pa; 90 instance->last_tracker = tracker; 91 92 usb_log_debug2("Added td(%X:%X) to queue %s last.\n", 93 tracker->td->status, tracker->td->device, instance->name); 94 95 /* check again, may be use atomic compare and swap */ 96 if (instance->queue_head->element & LINK_POINTER_TERMINATE_FLAG) { 97 instance->queue_head->element = pa; 98 usb_log_debug2("Added td(%X:%X) to queue first2 %s.\n", 99 tracker->td->status, tracker->td->device, instance->name); 100 } 84 /* now we can be sure that there is someting scheduled */ 85 assert(!list_empty(&instance->tracker_list)); 86 tracker_t *first = list_get_instance( 87 instance->tracker_list.next, tracker_t, link); 88 tracker_t *last = list_get_instance( 89 instance->tracker_list.prev, tracker_t, link); 90 queue_head_append_qh(last->qh, pa); 91 list_append(&tracker->link, &instance->tracker_list); 92 usb_log_debug2("Added tracker(%p) to queue %s last, first is %p.\n", 93 tracker, instance->name, first ); 101 94 } 102 95 /*----------------------------------------------------------------------------*/ 103 void transfer_list_remove_tracker(transfer_list_t *instance, tracker_t *tracker) 96 static void transfer_list_remove_tracker( 97 transfer_list_t *instance, tracker_t *tracker) 104 98 { 105 99 assert(instance); 106 100 assert(tracker); 107 101 assert(instance->queue_head); 108 assert(tracker-> td);102 assert(tracker->qh); 109 103 110 uint32_t pa = (uintptr_t)addr_to_phys(tracker->td); 111 if ((instance->queue_head->element & LINK_POINTER_ADDRESS_MASK) == pa) { 112 instance->queue_head->element = tracker->td->next; 104 /* I'm the first one here */ 105 if (tracker->link.next == &instance->tracker_list) { 106 usb_log_debug("Removing tracer %p was first, next element %x.\n", 107 tracker, tracker->qh->next_queue); 108 instance->queue_head->element = tracker->qh->next_queue; 109 } else { 110 usb_log_debug("Removing tracer %p was NOT first, next element %x.\n", 111 tracker, tracker->qh->next_queue); 112 tracker_t *prev = list_get_instance(tracker->link.prev, tracker_t, link); 113 prev->qh->next_queue = tracker->qh->next_queue; 114 } 115 list_remove(&tracker->link); 116 } 117 /*----------------------------------------------------------------------------*/ 118 void transfer_list_check(transfer_list_t *instance) 119 { 120 assert(instance); 121 link_t *current = instance->tracker_list.next; 122 while (current != &instance->tracker_list) { 123 link_t *next = current->next; 124 tracker_t *tracker = list_get_instance(current, tracker_t, link); 125 126 if (tracker_is_complete(tracker)) { 127 transfer_list_remove_tracker(instance, tracker); 128 tracker->next_step(tracker); 129 } 130 current = next; 113 131 } 114 132 } -
uspace/drv/uhci-hcd/transfer_list.h
rf6309b6 r7dd3318 41 41 typedef struct transfer_list 42 42 { 43 tracker_t *last_tracker;44 45 43 queue_head_t *queue_head; 46 44 uint32_t queue_head_pa; 47 45 struct transfer_list *next; 48 46 const char *name; 47 link_t tracker_list; 49 48 } transfer_list_t; 50 49 … … 59 58 queue_head_dispose(instance->queue_head); 60 59 } 60 void transfer_list_check(transfer_list_t *instance); 61 61 62 62 void transfer_list_add_tracker(transfer_list_t *instance, tracker_t *tracker); 63 64 void transfer_list_remove_tracker(transfer_list_t *instance, tracker_t *track);65 66 63 #endif 67 64 /** -
uspace/drv/uhci-hcd/uhci.c
rf6309b6 r7dd3318 158 158 const int low_speed = (tracker->speed == LOW_SPEED); 159 159 if (!allowed_usb_packet( 160 low_speed, tracker->transfer_type, tracker-> packet_size)) {160 low_speed, tracker->transfer_type, tracker->max_packet_size)) { 161 161 usb_log_warning("Invalid USB packet specified %s SPEED %d %zu.\n", 162 162 low_speed ? "LOW" : "FULL" , tracker->transfer_type, 163 tracker-> packet_size);163 tracker->max_packet_size); 164 164 return ENOTSUP; 165 165 } 166 166 /* TODO: check available bandwith here */ 167 168 usb_log_debug2("Scheduler(%d) acquiring tracker list mutex.\n",169 fibril_get_id());170 fibril_mutex_lock(&instance->tracker_list_mutex);171 usb_log_debug2("Scheduler(%d) acquired tracker list mutex.\n",172 fibril_get_id());173 167 174 168 transfer_list_t *list = … … 176 170 assert(list); 177 171 transfer_list_add_tracker(list, tracker); 178 list_append(&tracker->link, &instance->tracker_list);179 180 tracker->scheduled_list = list;181 182 usb_log_debug2("Scheduler(%d) releasing tracker list mutex.\n",183 fibril_get_id());184 fibril_mutex_unlock(&instance->tracker_list_mutex);185 usb_log_debug2("Scheduler(%d) released tracker list mutex.\n",186 fibril_get_id());187 172 188 173 return EOK; … … 196 181 197 182 while(1) { 198 LIST_INITIALIZE(done_trackers); 199 /* tracker iteration */ 200 201 usb_log_debug2("Cleaner(%d) acquiring tracker list mutex.\n", 202 fibril_get_id()); 203 fibril_mutex_lock(&instance->tracker_list_mutex); 204 usb_log_debug2("Cleaner(%d) acquired tracker list mutex.\n", 205 fibril_get_id()); 206 207 link_t *current = instance->tracker_list.next; 208 while (current != &instance->tracker_list) 209 { 210 211 link_t *next = current->next; 212 tracker_t *tracker = list_get_instance(current, tracker_t, link); 213 214 assert(current == &tracker->link); 215 assert(tracker); 216 assert(tracker->next_step); 217 assert(tracker->td); 218 219 if (!transfer_descriptor_is_active(tracker->td)) { 220 usb_log_info("Found inactive tracker with status: %x:%x.\n", 221 tracker->td->status, tracker->td->device); 222 list_remove(current); 223 list_append(current, &done_trackers); 224 } 225 current = next; 226 } 227 228 usb_log_debug2("Cleaner(%d) releasing tracker list mutex.\n", 229 fibril_get_id()); 230 fibril_mutex_unlock(&instance->tracker_list_mutex); 231 usb_log_debug2("Cleaner(%d) released tracker list mutex.\n", 232 fibril_get_id()); 233 234 while (!list_empty(&done_trackers)) { 235 tracker_t *tracker = list_get_instance( 236 done_trackers.next, tracker_t, link); 237 list_remove(&tracker->link); 238 tracker->next_step(tracker); 239 } 183 transfer_list_check(&instance->transfers_interrupt); 184 transfer_list_check(&instance->transfers_control_slow); 185 transfer_list_check(&instance->transfers_control_full); 186 transfer_list_check(&instance->transfers_bulk_full); 240 187 async_usleep(UHCI_CLEANER_TIMEOUT); 241 188 } -
uspace/drv/uhci-hcd/uhci.h
rf6309b6 r7dd3318 72 72 73 73 #define UHCI_FRAME_LIST_COUNT 1024 74 #define UHCI_CLEANER_TIMEOUT 1000 74 #define UHCI_CLEANER_TIMEOUT 1000000 75 75 #define UHCI_DEBUGER_TIMEOUT 5000000 76 76 -
uspace/drv/uhci-hcd/uhci_struct/queue_head.h
rf6309b6 r7dd3318 55 55 } 56 56 57 static inline void queue_head_a dd_next(queue_head_t *instance, uint32_t next_queue_pa)57 static inline void queue_head_append_qh(queue_head_t *instance, uint32_t pa) 58 58 { 59 if ( next_queue_pa) {60 instance->next_queue = ( next_queue_pa & LINK_POINTER_ADDRESS_MASK)61 | LINK_POINTER_QUEUE_HEAD_FLAG;59 if (pa) { 60 instance->next_queue = (pa & LINK_POINTER_ADDRESS_MASK) 61 | LINK_POINTER_QUEUE_HEAD_FLAG; 62 62 } 63 63 } 64 64 65 static inline queue_head_t * queue_head_get() 66 { return malloc32(sizeof(queue_head_t)); } 65 static inline void queue_head_element_qh(queue_head_t *instance, uint32_t pa) 66 { 67 if (pa) { 68 instance->next_queue = (pa & LINK_POINTER_ADDRESS_MASK) 69 | LINK_POINTER_QUEUE_HEAD_FLAG; 70 } 71 } 72 73 static inline void queue_head_element_td(queue_head_t *instance, uint32_t pa) 74 { 75 if (pa) { 76 instance->element = (pa & LINK_POINTER_ADDRESS_MASK); 77 } 78 } 79 80 static inline queue_head_t * queue_head_get() { 81 queue_head_t *ret = malloc32(sizeof(queue_head_t)); 82 if (ret) 83 queue_head_init(ret); 84 return ret; 85 } 67 86 68 87 static inline void queue_head_dispose(queue_head_t *head) -
uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.c
rf6309b6 r7dd3318 40 40 void transfer_descriptor_init(transfer_descriptor_t *instance, 41 41 int error_count, size_t size, bool toggle, bool isochronous, 42 usb_target_t target, int pid, void *buffer )42 usb_target_t target, int pid, void *buffer, transfer_descriptor_t *next) 43 43 { 44 44 assert(instance); 45 45 46 instance->next = 0 | LINK_POINTER_TERMINATE_FLAG; 46 instance->next = 47 (next != NULL) ? addr_to_phys(next) : LINK_POINTER_TERMINATE_FLAG; 47 48 48 49 instance->status = 0 -
uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.h
rf6309b6 r7dd3318 93 93 void transfer_descriptor_init(transfer_descriptor_t *instance, 94 94 int error_count, size_t size, bool toggle, bool isochronous, 95 usb_target_t target, int pid, void *buffer );95 usb_target_t target, int pid, void *buffer, transfer_descriptor_t * next); 96 96 97 97 int transfer_descriptor_status(transfer_descriptor_t *instance); 98 99 static inline size_t transfer_descriptor_actual_size( 100 transfer_descriptor_t *instance) 101 { 102 assert(instance); 103 return 104 ((instance->status >> TD_STATUS_ACTLEN_POS) + 1) & TD_STATUS_ACTLEN_MASK; 105 } 98 106 99 107 static inline bool transfer_descriptor_is_active( -
uspace/drv/uhci-hcd/utils/malloc32.h
rf6309b6 r7dd3318 45 45 #define UHCI_REQUIRED_PAGE_SIZE 4096 46 46 47 static inline void *addr_to_phys(void *addr)47 static inline uintptr_t addr_to_phys(void *addr) 48 48 { 49 49 uintptr_t result; … … 51 51 52 52 assert(ret == 0); 53 return ( void*)(result | ((uintptr_t)addr & 0xfff));53 return (result | ((uintptr_t)addr & 0xfff)); 54 54 } 55 55
Note:
See TracChangeset
for help on using the changeset viewer.