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