|
|
1.1 root 1: DMA Dequeue algorithm
2:
3: Definitions:
4:
5: * a descriptor is "completed" (as far as the kernel is concerned) if at least one byte moved between the device and the descriptor. A descriptor can be "completed" even if it was aborted because of any error. A descriptor 'n' is NOT completed if a device-level error occurred while processing data from descriptor 'n-1', even of the TE fetched one or two buffers worth of data from descriptor 'n'.
6:
7: * DMA read: transfer from device to memory
8:
9: * DMA write: transfer from memory to device
10:
11: Notes:
12:
13: * We write -1 to a descriptor's rem_byte_count field when it is enqueued.
14: * We write -1000 (or some magic number less than -(max buffer size)) to the
15: hw_count register every time we write the hw_curr_desc register.
16: * Once chan_dma_dequeue() is called with DEQUEUE_ALL, further calls specifying
17: only DEQUEUE_COMPLETED are not guaranteed to return only completed frames.
18:
19:
20: chan_dma_dequeue(dequeue_spec_t dequeue_spec) {
21:
22: desc = head of software's descriptor chain;
23: if(direction == DMA_READ) {
24: if(desc->rem_byte_count != -1) {
25: /*
26: * Easy case; TE has written the rem_byte_count field,
27: * indicating completion.
28: */
29: dequeue_ok = TRUE;
30: goto got_one;
31: }
32:
33: /*
34: * Continue - this descriptor could still be complete
35: * if EOR was not here.
36: */
37: }
38: if(desc_list_not_empty) {
39: /*
40: * Channel running; another easy case. This descriptor is
41: * complete as long as it's not the current descriptor.
42: */
43: if(desc != hw_curr_desc)
44: dequeue_ok = TRUE;
45: else
46: dequeue_ok = FALSE;
47: }
48: else {
49: /*
50: * Channel idle.
51: */
52: if(desc != hw_curr_desc) {
53: /*
54: * Not current, must be completed.
55: */
56: dequeue_ok = TRUE;
57: }
58: else {
59: /*
60: * This descriptor was either the last descriptor
61: * serviced by the TE or the next one to be serviced.
62: *
63: * We write -1000 to hw_count every time we write
64: * hw_curr_desc, so if it's still -1000, we know
65: * the TE hasn't gotten to this one yet.
66: */
67: if(hw_count == -1000) {
68: dequeue_ok = FALSE;
69: }
70: else {
71: /*
72: * Tricky case. The TE at least started to work
73: * on this descriptor, but we don't know if
74: * any data from this descriptor moved to/from
75: * the device. We have to examine the amount
76: * of data moved from memory and the state of
77: * the TE buffers...
78: */
79: if(hw_count between 0 and -(max buffer size)) {
80: /*
81: * This implies completion by the TE.
82: */
83: dequeue_ok = TRUE;
84: }
85: else {
86: bytes_moved = desc->count - hw_count;
87:
88: if(direction == DMA_READ) {
89: /*
90: * For data in, any bytes
91: * transferred
92: * means that the descriptor is
93: * complete.
94: */
95: if(bytes_moved == 0) {
96: got_a_desc = FALSE;
97: }
98: else {
99: got_a_desc = TRUE;
100: }
101: goto got_one;
102: }
103:
104: if(bytes_moved > (2 * buffer size)) {
105: /*
106: * some had to move to the
107: * device.
108: */
109: dequeue_ok = TRUE;
110: }
111: else if(bytes_moved == 0) {
112: /*
113: * We haven't touched this
114: * descriptor's data.
115: */
116: dequeue_ok = FALSE;
117: }
118: else if(bytes_moved == 1 buffer) {
119: if(either "buffer full" flag set) {
120: /*
121: * We couldn't have moved data
122: * to or from the device.
123: */
124: dequeue_ok = FALSE;
125: }
126: else {
127: dequeue_ok = TRUE;
128: }
129: }
130: else {
131: /*
132: * bytes_moved == 2 buffers.
133: */
134: if(BOTH "buffer full" flags set) {
135: dequeue_ok = FALSE;
136: }
137: else {
138: /*
139: * We moved 2 buffers from
140: * memory but at least one
141: * of the buffers is not full,
142: * so some data must have
143: * moved to the device.
144: */
145: dequeue_ok = TRUE;
146: }
147: }
148: }
149: }
150: } /* desc == hw_curr */
151: } /* channel idle */
152:
153: got_one:
154:
155: /*
156: * Even if dequeue_ok is FALSE, we can still dequeue if the channel
157: * isn't running and the caller said they wanted all descriptors.
158: */
159: if(!dequeue_ok &&
160: (channel not running) &&
161: (dequeue_spec == DEQUEUE_ALL)) {
162: dequeue_ok = TRUE;
163: }
164: if(dequeue_ok) {
165: grab this desc from s/w chain;
166: if this is the last descriptor of a frame {
167: dequeue the frame;
168: get return parameters from last descriptor;
169: unlock the VM associated with this frame;
170: free all descriptors and the frame;
171: }
172: }
173: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.