source: mainline/uspace/drv/uhci/uhci_struct/transfer_descriptor.c@ 245b56b5

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 245b56b5 was 44d8853, checked in by Jan Vesely <jano.vesely@…>, 14 years ago

Fixed: Do not crash on zero buffers

  • Property mode set to 100644
File size: 2.3 KB
Line 
1#include "transfer_descriptor.h"
2
3void 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 if (size) {
30 instance->buffer_ptr = (uintptr_t)addr_to_phys(buffer);
31
32 uhci_print_verbose("Creating buffer field: %p(%p).\n",
33 buffer, instance->buffer_ptr);
34
35 if (size >= 8) {
36 char * buff = buffer;
37
38 uhci_print_verbose("Buffer dump(8B): %x %x %x %x %x %x %x %x.\n",
39 buff[0], buff[1], buff[2], buff[3], buff[4], buff[5], buff[6], buff[7]);
40 }
41 } else {
42 instance->buffer_ptr = 0;
43 }
44
45 instance->next_va = NULL;
46 instance->callback = NULL;
47 uhci_print_info("Created a new TD.\n");
48}
49
50static inline usb_transaction_outcome_t convert_outcome(uint32_t status)
51{
52 /*TODO: refactor into something sane */
53 /*TODO: add additional usb_errors to usb_outcome_t */
54
55 if (status & TD_STATUS_ERROR_STALLED)
56 return USB_OUTCOME_CRCERROR;
57
58 if (status & TD_STATUS_ERROR_BUFFER)
59 return USB_OUTCOME_CRCERROR;
60
61 if (status & TD_STATUS_ERROR_BABBLE)
62 return USB_OUTCOME_BABBLE;
63
64 if (status & TD_STATUS_ERROR_NAK)
65 return USB_OUTCOME_CRCERROR;
66
67 if (status & TD_STATUS_ERROR_CRC)
68 return USB_OUTCOME_CRCERROR;
69
70 if (status & TD_STATUS_ERROR_BIT_STUFF)
71 return USB_OUTCOME_CRCERROR;
72
73 assert((((status >> TD_STATUS_ERROR_POS) & TD_STATUS_ERROR_MASK)
74 | TD_STATUS_ERROR_RESERVED) == TD_STATUS_ERROR_RESERVED);
75 return USB_OUTCOME_OK;
76}
77
78void transfer_descriptor_fini(transfer_descriptor_t *instance)
79{
80 assert(instance);
81 callback_run(instance->callback,
82 convert_outcome(instance->status),
83 ((instance->status >> TD_STATUS_ACTLEN_POS) + 1) & TD_STATUS_ACTLEN_MASK
84 );
85}
Note: See TracBrowser for help on using the repository browser.