Changeset 70d72dd in mainline
- Timestamp:
- 2011-10-16T14:24:05Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- d5abaf4
- Parents:
- 9515f674
- Location:
- uspace/drv/bus/usb/ohci
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ohci/hw_struct/endpoint_descriptor.h
r9515f674 r70d72dd 109 109 110 110 /** 111 * Check for SKIP or HALTED flag being set. 112 * @param instance ED 113 * @return true if either SKIP or HALTED flag is set, false otherwise. 114 */ 115 static inline bool ed_inactive(const ed_t *instance) 116 { 117 assert(instance); 118 return (instance->td_head & ED_TDHEAD_HALTED_FLAG) 119 || (instance->status & ED_STATUS_K_FLAG); 120 } 121 122 /** 123 * Check whether this ED contains TD to be executed. 124 * @param instance ED 125 * @return true if there are pending TDs, false otherwise. 126 */ 127 static inline bool ed_transfer_pending(const ed_t *instance) 128 { 129 assert(instance); 130 return (instance->td_head & ED_TDHEAD_PTR_MASK) 131 != (instance->td_tail & ED_TDTAIL_PTR_MASK); 132 } 133 134 /** 111 135 * Set the last element of TD list 112 136 * @param instance ED -
uspace/drv/bus/usb/ohci/hw_struct/transfer_descriptor.c
r9515f674 r70d72dd 35 35 #include "transfer_descriptor.h" 36 36 37 static unsigned dp[3] = 38 { TD_STATUS_DP_IN, TD_STATUS_DP_OUT, TD_STATUS_DP_SETUP }; 39 static unsigned togg[2] = { TD_STATUS_T_0, TD_STATUS_T_1 }; 37 /** USB direction to OHCI TD values translation table */ 38 static const uint32_t dir[] = { 39 [USB_DIRECTION_IN] = TD_STATUS_DP_IN, 40 [USB_DIRECTION_OUT] = TD_STATUS_DP_OUT, 41 [USB_DIRECTION_BOTH] = TD_STATUS_DP_SETUP, 42 }; 40 43 41 void td_init(td_t *instance, 42 usb_direction_t dir, const void *buffer, size_t size, int toggle) 44 /** 45 * Initialize OHCI TD. 46 * @param instance TD structure to initialize. 47 * @param next Next TD in ED list. 48 * @param direction Used to determine PID, BOTH means setup PID. 49 * @param buffer Pointer to the first byte of transferred data. 50 * @param size Size of the buffer. 51 * @param toggle Toggle bit value, use 0/1 to set explicitly, 52 * any other value means that ED toggle will be used. 53 */ 54 void td_init(td_t *instance, const td_t *next, 55 usb_direction_t direction, const void *buffer, size_t size, int toggle) 43 56 { 44 57 assert(instance); 45 58 bzero(instance, sizeof(td_t)); 59 /* Set PID and Error code */ 46 60 instance->status = 0 47 | ((d p[dir] & TD_STATUS_DP_MASK) << TD_STATUS_DP_SHIFT)61 | ((dir[direction] & TD_STATUS_DP_MASK) << TD_STATUS_DP_SHIFT) 48 62 | ((CC_NOACCESS2 & TD_STATUS_CC_MASK) << TD_STATUS_CC_SHIFT); 63 49 64 if (toggle == 0 || toggle == 1) { 50 instance->status |= togg[toggle] << TD_STATUS_T_SHIFT; 65 /* Set explicit toggle bit */ 66 instance->status |= TD_STATUS_T_USE_TD_FLAG; 67 instance->status |= toggle ? TD_STATUS_T_FLAG : 0; 51 68 } 69 70 /* Alow less data on input. */ 52 71 if (dir == USB_DIRECTION_IN) { 53 72 instance->status |= TD_STATUS_ROUND_FLAG; 54 73 } 74 55 75 if (buffer != NULL) { 56 76 assert(size != 0); … … 58 78 instance->be = addr_to_phys(buffer + size - 1); 59 79 } 80 81 instance->next = addr_to_phys(next) & TD_NEXT_PTR_MASK; 82 60 83 } 61 84 /** -
uspace/drv/bus/usb/ohci/hw_struct/transfer_descriptor.h
r9515f674 r70d72dd 37 37 #include <bool.h> 38 38 #include <stdint.h> 39 39 40 #include "../utils/malloc32.h" 40 41 41 #include "completion_codes.h" 42 42 … … 46 46 #define OHCI_TD_MAX_TRANSFER (4 * 1024) 47 47 48 /** 49 * Transfer Descriptor representation. 50 * 51 * See OHCI spec chapter 4.3.1 General Transfer Descriptor on page 19 52 * (pdf page 33) for details. 53 */ 48 54 typedef struct td { 55 /** Status field. Do not touch on active TDs. */ 49 56 volatile uint32_t status; 50 57 #define TD_STATUS_ROUND_FLAG (1 << 18) 51 #define TD_STATUS_DP_MASK (0x3) /* direction/PID */58 #define TD_STATUS_DP_MASK (0x3) /* Direction/PID */ 52 59 #define TD_STATUS_DP_SHIFT (19) 53 60 #define TD_STATUS_DP_SETUP (0x0) 54 61 #define TD_STATUS_DP_OUT (0x1) 55 62 #define TD_STATUS_DP_IN (0x2) 56 #define TD_STATUS_DI_MASK (0x7) /* delay interrupt, wait DI frames before int*/63 #define TD_STATUS_DI_MASK (0x7) /* Delay interrupt, wait n frames before irq */ 57 64 #define TD_STATUS_DI_SHIFT (21) 58 65 #define TD_STATUS_DI_NO_INTERRUPT (0x7) 59 #define TD_STATUS_T_MASK (0x3) /* data toggle 1x = use ED toggle carry */ 60 #define TD_STATUS_T_SHIFT (24) 61 #define TD_STATUS_T_0 (0x2) 62 #define TD_STATUS_T_1 (0x3) 63 #define TD_STATUS_T_ED (0) 64 #define TD_STATUS_EC_MASK (0x3) /* error count */ 66 #define TD_STATUS_T_FLAG (1 << 24) /* Explicit toggle bit value for this TD */ 67 #define TD_STATUS_T_USE_TD_FLAG (1 << 25) /* 1 = use bit 24 as toggle bit */ 68 #define TD_STATUS_EC_MASK (0x3) /* Error count */ 65 69 #define TD_STATUS_EC_SHIFT (26) 66 #define TD_STATUS_CC_MASK (0xf) /* condition code */70 #define TD_STATUS_CC_MASK (0xf) /* Condition code */ 67 71 #define TD_STATUS_CC_SHIFT (28) 68 72 69 volatile uint32_t cbp; /* current buffer ptr, data to be transfered */ 73 /** 74 * Current buffer pointer. 75 * Phys address of the first byte to be transferred. */ 76 volatile uint32_t cbp; 77 78 /** Pointer to the next TD in chain. 16-byte aligned. */ 70 79 volatile uint32_t next; 71 80 #define TD_NEXT_PTR_MASK (0xfffffff0) 72 81 #define TD_NEXT_PTR_SHIFT (0) 73 82 74 volatile uint32_t be; /* buffer end, address of the last byte */ 83 /** 84 * Buffer end. 85 * Phys address of the last byte of the transfer. 86 * @note this does not have to be on the same page as cbp. 87 */ 88 volatile uint32_t be; 75 89 } __attribute__((packed)) td_t; 76 90 77 void td_init(td_t *instance, 91 void td_init(td_t *instance, const td_t *next, 78 92 usb_direction_t dir, const void *buffer, size_t size, int toggle); 79 93 80 inline static void td_set_next(td_t *instance, td_t *next) 94 /** 95 * Check TD for completion. 96 * @param instance TD structure. 97 * @return true if the TD was accessed and processed by hw, false otherwise. 98 */ 99 inline static bool td_is_finished(const td_t *instance) 81 100 { 82 101 assert(instance); 83 instance->next = addr_to_phys(next) & TD_NEXT_PTR_MASK; 84 } 85 86 inline static bool td_is_finished(td_t *instance) 87 { 88 assert(instance); 89 int cc = (instance->status >> TD_STATUS_CC_SHIFT) & TD_STATUS_CC_MASK; 90 /* something went wrong, error code is set */ 102 const int cc = 103 (instance->status >> TD_STATUS_CC_SHIFT) & TD_STATUS_CC_MASK; 104 /* This value is changed on transfer completion, 105 * either to CC_NOERROR or and error code. 106 * See OHCI spec 4.3.1.3.5 p. 23 (pdf 37) */ 91 107 if (cc != CC_NOACCESS1 && cc != CC_NOACCESS2) { 92 return true;93 }94 /* everything done */95 if (cc == CC_NOERROR && instance->cbp == 0) {96 108 return true; 97 109 } … … 99 111 } 100 112 101 static inline int td_error(td_t *instance) 113 /** 114 * Get error code that indicates transfer status. 115 * @param instance TD structure. 116 * @return Error code. 117 */ 118 static inline int td_error(const td_t *instance) 102 119 { 103 120 assert(instance); 104 int cc = (instance->status >> TD_STATUS_CC_SHIFT) & TD_STATUS_CC_MASK; 121 const int cc = 122 (instance->status >> TD_STATUS_CC_SHIFT) & TD_STATUS_CC_MASK; 105 123 return cc_to_rc(cc); 106 124 } 107 125 126 /** 127 * Get remaining portion of buffer to be read/written 128 * @param instance TD structure 129 * @return size of remaining buffer. 130 */ 108 131 static inline size_t td_remain_size(td_t *instance) 109 132 { 110 133 assert(instance); 134 /* Current buffer pointer is cleared on successful transfer */ 111 135 if (instance->cbp == 0) 112 136 return 0; 137 /* Buffer end points to the last byte of transfer buffer, so add 1 */ 113 138 return instance->be - instance->cbp + 1; 114 139 } -
uspace/drv/bus/usb/ohci/ohci_batch.c
r9515f674 r70d72dd 248 248 249 249 /* setup stage */ 250 td_init( ohci_batch->tds[0], USB_DIRECTION_BOTH, buffer,251 ohci_batch->usb_batch->setup_size, toggle);252 td_set_next(ohci_batch->tds[0], ohci_batch->tds[1]);250 td_init( 251 ohci_batch->tds[0], ohci_batch->tds[1], USB_DIRECTION_BOTH, 252 buffer, ohci_batch->usb_batch->setup_size, toggle); 253 253 usb_log_debug("Created CONTROL SETUP TD: %08x:%08x:%08x:%08x.\n", 254 254 ohci_batch->tds[0]->status, ohci_batch->tds[0]->cbp, … … 265 265 toggle = 1 - toggle; 266 266 267 td_init(ohci_batch->tds[td_current], data_dir, buffer, 268 transfer_size, toggle); 269 td_set_next(ohci_batch->tds[td_current], 270 ohci_batch->tds[td_current + 1]); 267 td_init(ohci_batch->tds[td_current], 268 ohci_batch->tds[td_current + 1], 269 data_dir, buffer, transfer_size, toggle); 271 270 usb_log_debug("Created CONTROL DATA TD: %08x:%08x:%08x:%08x.\n", 272 271 ohci_batch->tds[td_current]->status, … … 283 282 /* status stage */ 284 283 assert(td_current == ohci_batch->td_count - 1); 285 td_init(ohci_batch->tds[td_current], status_dir, NULL, 0, 1); 286 td_set_next(ohci_batch->tds[td_current], 287 ohci_batch->tds[td_current + 1]); 284 td_init(ohci_batch->tds[td_current], ohci_batch->tds[td_current + 1], 285 status_dir, NULL, 0, 1); 288 286 usb_log_debug("Created CONTROL STATUS TD: %08x:%08x:%08x:%08x.\n", 289 287 ohci_batch->tds[td_current]->status, … … 323 321 ? OHCI_TD_MAX_TRANSFER : remain_size; 324 322 325 td_init(ohci_batch->tds[td_current], dir, buffer, 326 transfer_size, -1); 327 td_set_next(ohci_batch->tds[td_current], 328 ohci_batch->tds[td_current + 1]); 323 td_init( 324 ohci_batch->tds[td_current], ohci_batch->tds[td_current + 1], 325 dir, buffer, transfer_size, -1); 329 326 330 327 usb_log_debug("Created DATA TD: %08x:%08x:%08x:%08x.\n",
Note:
See TracChangeset
for help on using the changeset viewer.