|
|
1.1 ! root 1: /* ! 2: * aha_dsl.c - routines for manipulating AHA-154x Data Segment Lists. ! 3: * Part of the Adaptec SCSI driver. ! 4: */ ! 5: ! 6: #include <sys/coherent.h> ! 7: #include <sys/buf.h> ! 8: #include <sys/scsiwork.h> ! 9: #include <sys/aha154x.h> ! 10: #include <sys/errno.h> ! 11: ! 12: #ifndef LESSER ! 13: #define LESSER(a, b) (((a)<(b))?(a):(b)) ! 14: #endif /* LESSER */ ! 15: ! 16: extern unsigned long aha_p3_to_l(); ! 17: ! 18: /* ! 19: * void ! 20: * dsl_free( P3 dsl_ptr ) ! 21: * ! 22: * Free a DSL generated by dsl_gen(). ! 23: */ ! 24: void ! 25: dsl_free( dsl_ptr ) ! 26: P3 dsl_ptr; ! 27: { ! 28: caddr_t dsl_vaddr; /* Virtual address of DSL. */ ! 29: ! 30: T_PIGGY(0x4000, printf("dsl_free(%x:%x:%x)", ! 31: dsl_ptr[0], dsl_ptr[1], dsl_ptr[2] )); ! 32: ! 33: dsl_vaddr = mem_recall( aha_p3_to_l( dsl_ptr ) ); ! 34: ! 35: T_PIGGY(0x4000, printf(":%x, ", dsl_vaddr) ); ! 36: ! 37: pfree( dsl_vaddr ); ! 38: mem_forget( dsl_vaddr ); ! 39: ! 40: } /* dsl_free() */ ! 41: ! 42: #if 1 ! 43: #define MAX_ENTRIES 16 /* At most 16 DSL entries are allowed. */ ! 44: /* ! 45: * void ! 46: * dsl_gen(P3 new_dsl, paddr_t buffer, unsigned len) ! 47: * ! 48: * Generate a Data Segment List for virtual-physical buffer 'buffer' with ! 49: * length 'len'. Return a P3 pointer to this DSL in new_dsl. ! 50: */ ! 51: void ! 52: dsl_gen( new_dsl, new_len, buffer, len) ! 53: P3 new_dsl, new_len; ! 54: paddr_t buffer; ! 55: unsigned long len; ! 56: { ! 57: unsigned first; /* Size of first chunk in bytes. */ ! 58: unsigned rest; /* len - first */ ! 59: unsigned middle; /* Size of middle (aligned) chunk in bytes. */ ! 60: unsigned middle_clicks; /* middle/NBPC */ ! 61: unsigned last; /* Size of last chunk in bytes. */ ! 62: ! 63: unsigned total_entries; /* Total number of entries in DSL. */ ! 64: unsigned table_len; /* total_entries * sizeof(DSL_ENTRY) */ ! 65: ! 66: DSL_ENTRY *tmp_dsl; /* Build DSL here. */ ! 67: ! 68: unsigned len_to_stuff; /* How much buffer left to stuff into DSL? */ ! 69: unsigned addr_to_stuff; /* What address goes in the current DSL entry? */ ! 70: ! 71: int i; /* Handy counter/index. */ ! 72: ! 73: T_PIGGY( 0x4000, ! 74: printf("dsl_gen(dsl: %x, new_len: %x, buf: %x, len: %x)", ! 75: new_dsl, new_len, buffer, len)); ! 76: ! 77: /* ! 78: * The buffer can have up to three sections: ! 79: * first -- from the start of the buffer ! 80: * to the start of the next click. ! 81: * middle -- all full sized clicks ! 82: * last -- the final partial click. ! 83: * ! 84: * A buffer must have at least a first section, may have only ! 85: * a first and last, first and middle, or may have all three. ! 86: */ ! 87: ! 88: /* ! 89: * Calculate the sizes for all three sections in bytes. ! 90: */ ! 91: ! 92: /* ! 93: * The first chunk is either the entire buffer, or up to then ! 94: * end of the first click. ! 95: */ ! 96: first = LESSER(len, ctob(btocrd(buffer + NBPC)) - buffer); ! 97: ! 98: rest = len - first; ! 99: middle_clicks = rest / NBPC; /* First calculate length in clicks. */ ! 100: middle = middle_clicks * NBPC; /* Convert to bytes. */ ! 101: ! 102: last = rest % NBPC; ! 103: ! 104: /* How many entries do we need in the DSL? */ ! 105: total_entries = ((first > 0)?1:0) + middle_clicks + ((last > 0)?1:0); ! 106: ! 107: /* The AHA-154xB permits no more than MAX_ENTRIES DSL entries. */ ! 108: if ( total_entries > MAX_ENTRIES ) { ! 109: u.u_error = EINVAL; ! 110: return; ! 111: } ! 112: ! 113: /* How big a table do we need? */ ! 114: table_len = total_entries * sizeof(DSL_ENTRY); ! 115: ! 116: /* Allocate the DSL. */ ! 117: if (NULL == (tmp_dsl = (DSL_ENTRY *) palloc(table_len))) { ! 118: u.u_error = ENOMEM; ! 119: return; ! 120: } ! 121: ! 122: /* Fill in the DSL. */ ! 123: len_to_stuff = len; ! 124: addr_to_stuff = buffer; ! 125: ! 126: /* First Part */ ! 127: aha_l_to_p3( first, tmp_dsl[0].size ); ! 128: aha_l_to_p3( vptop( addr_to_stuff ), tmp_dsl[0].addr ); ! 129: ! 130: T_PIGGY(0x4000, ! 131: printf("DSL first(size: %x:%x:%x, addr: %x:%x:%x)", ! 132: tmp_dsl[0].size[0], tmp_dsl[0].size[1], tmp_dsl[0].size[2], ! 133: tmp_dsl[0].addr[0], tmp_dsl[0].addr[1], tmp_dsl[0].addr[2])); ! 134: len_to_stuff -= first; ! 135: addr_to_stuff += first; ! 136: ! 137: /* Middle Part */ ! 138: i = 1; ! 139: while (len_to_stuff > NBPC) { ! 140: aha_l_to_p3( NBPC, tmp_dsl[i].size ); ! 141: aha_l_to_p3( vptop( addr_to_stuff ), tmp_dsl[i].addr ); ! 142: ! 143: T_PIGGY(0x4000, ! 144: printf("DSL middle:%x(size: %x:%x:%x, addr: %x:%x:%x)", i, ! 145: tmp_dsl[i].size[0], tmp_dsl[i].size[1], tmp_dsl[i].size[2], ! 146: tmp_dsl[i].addr[0], tmp_dsl[i].addr[1], tmp_dsl[i].addr[2])); ! 147: len_to_stuff -= NBPC; ! 148: addr_to_stuff += NBPC; ! 149: ++i; ! 150: } ! 151: ! 152: /* Last Part */ ! 153: if (len_to_stuff > 0) { ! 154: aha_l_to_p3( last, tmp_dsl[i].size ); ! 155: aha_l_to_p3( vptop( addr_to_stuff ), tmp_dsl[i].addr ); ! 156: ! 157: T_PIGGY(0x4000, ! 158: printf("DSL last:%x(size: %x:%x:%x, addr: %x:%x:%x)", i, ! 159: tmp_dsl[i].size[0], tmp_dsl[i].size[1], tmp_dsl[i].size[2], ! 160: tmp_dsl[i].addr[0], tmp_dsl[i].addr[1], tmp_dsl[i].addr[2])); ! 161: ! 162: len_to_stuff -= last; ! 163: addr_to_stuff += last; ! 164: ++i; ! 165: } ! 166: ! 167: #if 0 ! 168: /* ! 169: * NIGEL: Trace macros must now be given expressions... this one ! 170: * wasn't worth cleaning up. ! 171: */ ! 172: ! 173: T_PIGGY(0x4000, { ! 174: /* Sanity Check. */ ! 175: if ( i != total_entries ) { ! 176: printf( ! 177: "\ndsl_gen() insane: i: %x != total_entries: %x\n", ! 178: i, total_entries ); ! 179: } ! 180: if ( len_to_stuff != 0 ) { ! 181: printf( ! 182: "\ndsl_gen() insane: len_to_stuff: %x != 0\n", ! 183: len_to_stuff); ! 184: } ! 185: if ( addr_to_stuff != (buffer + len) ) { ! 186: printf( ! 187: "\ndsl_gen() insane: addr_to_stuff: %x != (buffer + len): %x\n", ! 188: addr_to_stuff, (buffer + len)); ! 189: } ! 190: } ); /* T_PIGGY() */ ! 191: #endif ! 192: ! 193: /* Fill in return values. */ ! 194: aha_l_to_p3( table_len, new_len ); ! 195: aha_l_to_p3( vtop(tmp_dsl), new_dsl ); ! 196: mem_remember( tmp_dsl, aha_p3_to_l( new_dsl )); ! 197: ! 198: ! 199: T_PIGGY( 0x4000, printf("new_dsl: %x:%x:%x, new_len: %x:%x:%x, ", ! 200: new_dsl[0], new_dsl[1], new_dsl[2], ! 201: new_len[0], new_len[1], new_len[2])); ! 202: } /* dsl_gen() */ ! 203: #endif /* 1 */ ! 204:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.