|
|
1.1 root 1: descriptorList_t *head, *tail; // software's list of descriptors
2:
3: /*
4: * Returns CHAN_RUNNING/ CHAN_NOT_RUNNING. CHAN_NOT_RUNNING implies that
5: * a 'load descriptor' operation is required to start the channel.
6: */
7: emptyIndication_t enqueueDescriptors(descriptorList_t *descFrame)
8: {
9: if (channel's DNLE == 0) {
10: /*
11: * hw out of descriptors, channel MUST be stopped.
12: * Set-up hardware to start with this descriptor if
13: * current list is empty, else enqueue on end of
14: * (non-running) list.
15: */
16: if (tail == NULL)
17: head = descFrame;
18: else
19: tail->next = descFrame;
20: tail = tailOf(descFrame);
21: hw_current_desc = descFrame;
22: hw_count = -1;
23: return CHAN_NOT_RUNNING;
24: } else {
25: /*
26: * Channel has descriptors to process.
27: * It may, or may not be currently running.
28: *
29: * First, just do what's necessary to enqueue descriptors
30: * in memory.
31: *
32: * Software queue CAN'T be empty....
33: */
34: tail->next = descFrame;
35: tail = tailOf(descFrame);
36:
37: /*
38: * Now, need to check to see if the memory enqueue "made it".
39: *
40: * The first test is to check the hw_next_desc.
41: *
42: * If the channel is running and hw_next_desc is non-null,
43: * then the update must have been in time (channel is running
44: * with more descriptors ready).
45: *
46: * Of course, if the channel is not running, there's no race
47: * (we wouldn't be here...??)
48: */
49: if (hw_next_desc != NULL)
50: return CHAN_RUNNING;
51: /*
52: * At this point, the channel MUST have been running since
53: * the last time this routine was called because that's the
54: * only way that hw_next_desc can become null.
55: *
56: * Race to update hw_next_desc before the transfer engine
57: * needs to advance.
58: */
59: hw_next_desc = descFrame;
60:
61: /*
62: * Have to do an implementation-dependent test for desc list
63: * not empty - updates to TE registers are atomic, but the
64: * update of the channel status register is not. Current
65: * desc_list_not_empty() test is to read channel's DNLE bit
66: * 'n' times here; any read of 0 is a failure (i.e., it's
67: * empty).
68: */
69: if (desc_list_not_empty() == 1)
70: return CHAN_RUNNING;
71:
72: /*
73: * Lost the race. The channel MUST be stopped.
74: *
75: * Set-up the channel so that a driver ENABLE will restart
76: * it with descFrame.
77: */
78: hw_current_desc = descFrame;
79: hw_count = -1;
80: return CHAN_NOT_RUNNING;
81: }
82: }
83:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.