|
|
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.