| 1 | #include "transfer_descriptor.h"
|
|---|
| 2 |
|
|---|
| 3 | void transfer_descriptor_init(transfer_descriptor_t *instance,
|
|---|
| 4 | int error_count, size_t size, bool isochronous, usb_target_t target,
|
|---|
| 5 | int pid, void *buffer)
|
|---|
| 6 | {
|
|---|
| 7 | assert(instance);
|
|---|
| 8 |
|
|---|
| 9 | instance->next =
|
|---|
| 10 | 0 | LINK_POINTER_TERMINATE_FLAG;
|
|---|
| 11 |
|
|---|
| 12 | uhci_print_verbose("Creating link field: %x.\n", instance->next);
|
|---|
| 13 |
|
|---|
| 14 | assert(size < 1024);
|
|---|
| 15 | instance->status = 0
|
|---|
| 16 | | ((error_count & TD_STATUS_ERROR_COUNT_MASK) << TD_STATUS_ERROR_COUNT_POS)
|
|---|
| 17 | | TD_STATUS_ERROR_ACTIVE;
|
|---|
| 18 |
|
|---|
| 19 | uhci_print_verbose("Creating status field: %x.\n", instance->status);
|
|---|
| 20 |
|
|---|
| 21 | instance->device = 0
|
|---|
| 22 | | (((size - 1) & TD_DEVICE_MAXLEN_MASK) << TD_DEVICE_MAXLEN_POS)
|
|---|
| 23 | | ((target.address & TD_DEVICE_ADDRESS_MASK) << TD_DEVICE_ADDRESS_POS)
|
|---|
| 24 | | ((target.endpoint & TD_DEVICE_ENDPOINT_MASK) << TD_DEVICE_ENDPOINT_POS)
|
|---|
| 25 | | ((pid & TD_DEVICE_PID_MASK) << TD_DEVICE_PID_POS);
|
|---|
| 26 |
|
|---|
| 27 | uhci_print_verbose("Creating device field: %x.\n", instance->device);
|
|---|
| 28 |
|
|---|
| 29 | instance->buffer_ptr = (uintptr_t)addr_to_phys(buffer);
|
|---|
| 30 |
|
|---|
| 31 | uhci_print_verbose("Creating buffer field: %p(%p).\n",
|
|---|
| 32 | buffer, instance->buffer_ptr);
|
|---|
| 33 |
|
|---|
| 34 | char * buff = buffer;
|
|---|
| 35 |
|
|---|
| 36 | uhci_print_verbose("Buffer dump(8B): %x %x %x %x %x %x %x %x.\n",
|
|---|
| 37 | buff[0], buff[1], buff[2], buff[3], buff[4], buff[5], buff[6], buff[7]);
|
|---|
| 38 |
|
|---|
| 39 | instance->next_va = NULL;
|
|---|
| 40 | instance->callback = NULL;
|
|---|
| 41 | }
|
|---|
| 42 |
|
|---|
| 43 | static inline usb_transaction_outcome_t convert_outcome(uint32_t status)
|
|---|
| 44 | {
|
|---|
| 45 | /*TODO: refactor into something sane */
|
|---|
| 46 | /*TODO: add additional usb_errors to usb_outcome_t */
|
|---|
| 47 |
|
|---|
| 48 | if (status & TD_STATUS_ERROR_STALLED)
|
|---|
| 49 | return USB_OUTCOME_CRCERROR;
|
|---|
| 50 |
|
|---|
| 51 | if (status & TD_STATUS_ERROR_BUFFER)
|
|---|
| 52 | return USB_OUTCOME_CRCERROR;
|
|---|
| 53 |
|
|---|
| 54 | if (status & TD_STATUS_ERROR_BABBLE)
|
|---|
| 55 | return USB_OUTCOME_BABBLE;
|
|---|
| 56 |
|
|---|
| 57 | if (status & TD_STATUS_ERROR_NAK)
|
|---|
| 58 | return USB_OUTCOME_CRCERROR;
|
|---|
| 59 |
|
|---|
| 60 | if (status & TD_STATUS_ERROR_CRC)
|
|---|
| 61 | return USB_OUTCOME_CRCERROR;
|
|---|
| 62 |
|
|---|
| 63 | if (status & TD_STATUS_ERROR_BIT_STUFF)
|
|---|
| 64 | return USB_OUTCOME_CRCERROR;
|
|---|
| 65 |
|
|---|
| 66 | assert((((status >> TD_STATUS_ERROR_POS) & TD_STATUS_ERROR_MASK)
|
|---|
| 67 | | TD_STATUS_ERROR_RESERVED) == TD_STATUS_ERROR_RESERVED);
|
|---|
| 68 | return USB_OUTCOME_OK;
|
|---|
| 69 | }
|
|---|
| 70 |
|
|---|
| 71 | void transfer_descriptor_fini(transfer_descriptor_t *instance)
|
|---|
| 72 | {
|
|---|
| 73 | assert(instance);
|
|---|
| 74 | callback_run(instance->callback,
|
|---|
| 75 | convert_outcome(instance->status),
|
|---|
| 76 | instance->status >> TD_STATUS_ACTLEN_POS & TD_STATUS_ACTLEN_MASK
|
|---|
| 77 | );
|
|---|
| 78 | }
|
|---|