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