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