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