|
|
1.1 root 1: #include <stdio.h>
2: #include "../scsi.h"
3: #include "../scsish.h"
4: #include "fns.h"
5:
6: #define SHORT(n) ((ret.data[n]<<8)|(ret.data[n+1]))
7:
8: static int
9: er_w6(int pcf, char *err)
10: {
11: struct scsi_cmd cmd;
12: struct scsi_return ret;
13: int n;
14: static char *bit[8] = { "DCR", "DTE", "PER", "EEC", "RC", "TB", "ARRE", "AWRE" };
15:
16: set6(cmd, 0x1A, 0, (pcf<<6)|0x01, 0, 20, 0);
17: if(n = s_io(0, &cmd, 0, &ret, 20, err))
18: return(n);
19: printf("error recovery:\n\t");
20: for(n = 7; n >= 0; n--)
21: printf(" %s%s", (ret.data[14]&(1<<n))? "":"~", bit[n]);
22: printf("\n\t%d retries, max ecc span=%d, recov tlimit=%d\n",
23: ret.data[15], ret.data[16], ret.data[17]);
24: return(0);
25: }
26:
27: static int
28: dr_w6(int pcf, char *err)
29: {
30: struct scsi_cmd cmd;
31: struct scsi_return ret;
32: int n;
33:
34: set6(cmd, 0x1A, 0, (pcf<<6)|0x02, 0, 24, 0);
35: if(n = s_io(0, &cmd, 0, &ret, 24, err))
36: return(n);
37: printf("disconnect/reconnect:\n");
38: printf("\tread reconnect=%d/256 full,", ret.data[14]);
39: printf(" write reconnect=%d/256 empty\n", ret.data[15]);
40: return(0);
41: }
42:
43: static int
44: fp_w6(int pcf, char *err)
45: {
46: struct scsi_cmd cmd;
47: struct scsi_return ret;
48: int n;
49: static char *bit[8] = { "", "", "", "INS", "SURF", "Remove", "HardSec", "SoftSec" };
50:
51: set6(cmd, 0x1A, 0, (pcf<<6)|0x03, 0, 36, 0);
52: if(n = s_io(0, &cmd, 0, &ret, 36, err))
53: return(n);
54: printf("format parameters:\n");
55: printf("\tsec=%d B, trk=%d secs, interleave=%d, trk_skew=%d, cyl_skew=%d\n",
56: SHORT(24), SHORT(22), SHORT(26), SHORT(28), SHORT(30));
57: printf("\t%d alt_sec/%d alt_trk per zone(=%d trks), %d alt_trk per vol\n",
58: SHORT(16), SHORT(18), SHORT(14), SHORT(20));
59: printf("\tdrive type:");
60: for(n = 7; n >= 3; n--)
61: printf(" %s%s", (ret.data[32]&(1<<n))? "":"~", bit[n]);
62: printf("\n");
63: return(0);
64: }
65:
66: static int
67: geom_w6(int pcf, char *err)
68: {
69: struct scsi_cmd cmd;
70: struct scsi_return ret;
71: int n;
72:
73: set6(cmd, 0x1A, 0, (pcf<<6)|0x04, 0, 32, 0);
74: if(n = s_io(0, &cmd, 0, &ret, 32, err))
75: return(n);
76: printf("drive geometry:\n\t%d cyls, %d heads\n",
77: (ret.data[14]<<16)|SHORT(15), ret.data[17]);
78: return(0);
79: }
80:
81: static int
82: cc_w6(int pcf, char *err)
83: {
84: struct scsi_cmd cmd;
85: struct scsi_return ret;
86: int n;
87: static char *bit[8] = { "", "", "", "", "CacheEnable", "RSVD", "WIE", "RSVD" };
88:
89: set6(cmd, 0x1A, 0, (pcf<<6)|0x38, 0, 28, 0);
90: if(n = s_io(0, &cmd, 0, &ret, 28, err))
91: return(n);
92: printf("cache control:\n\t");
93: for(n = 7; n >= 4; n--)
94: printf(" %s%s", (ret.data[14]&(1<<n))? "":"~", bit[n]);
95: printf(", cache size=%d\n", ret.data[14]&0xF);
96: printf("\tprefetch: thr=%d max=%d(mult %d) min=%d(mult %d)\n",
97: ret.data[15], ret.data[16], ret.data[17], ret.data[18], ret.data[19]);
98: return(0);
99: }
100:
101: static int
102: er_wr2(int pcf, char *err)
103: {
104: struct scsi_cmd cmd;
105: struct scsi_return ret;
106: int n;
107: static char *bit[8] = { "DCR", "DTE", "PER", "EEC", "RC", "TB", "ARRE", "AWRE" };
108:
109: set6(cmd, 0x1A, 0, (pcf<<6)|0x01, 0, 20, 0);
110: if(n = s_io(0, &cmd, 0, &ret, 20, err))
111: return(n);
112: printf("error recovery:\n\t");
113: for(n = 7; n >= 0; n--)
114: printf(" %s%s", (ret.data[14]&(1<<n))? "":"~", bit[n]);
115: printf("\n\t%d retries, max ecc span=%d, %d wr retries, recov tlimit=%d\n",
116: ret.data[15], ret.data[16], ret.data[20], SHORT(22));
117: return(0);
118: }
119:
120: static int
121: geom_wr2(int pcf, char *err)
122: {
123: struct scsi_cmd cmd;
124: struct scsi_return ret;
125: int n;
126: static char *sspin[4] = {
127: "no spindle synch",
128: "synch-spindle slave",
129: "synch-spindle master",
130: "synch-spindle master control",
131: };
132:
133: set6(cmd, 0x1A, 0, (pcf<<6)|0x04, 0, 32, 0);
134: if(n = s_io(0, &cmd, 0, &ret, 32, err))
135: return(n);
136: printf("drive geometry:\n\t%d cyls, %d heads, %s, rotation rate %d\n",
137: (ret.data[14]<<16)|SHORT(15), ret.data[17],
138: sspin[ret.data[29]&3], SHORT(32));
139: return(0);
140: }
141:
142: static int
143: cp_wr2(int pcf, char *err)
144: {
145: struct scsi_cmd cmd;
146: struct scsi_return ret;
147: int n;
148: static char *bit[8] = { "ReadCacheDisable", "", "WriteCacheEnable", "", "", "", "", "" };
149:
150: set6(cmd, 0x1A, 0, (pcf<<6)|0x38, 0, 28, 0);
151: if(n = s_io(0, &cmd, 0, &ret, 28, err))
152: return(n);
153: printf("caching parameters:\n\t");
154: for(n = 2; n >= 0; n -= 2)
155: printf(" %s%s", (ret.data[14]&(1<<n))? "":"~", bit[n]);
156: printf("\n\tprefetch: min=%d, max=%d, ceiling=%d\n",
157: SHORT(18), SHORT(20), SHORT(22));
158: return(0);
159: }
160:
161: static int
162: cc_wr2(int pcf, char *err)
163: {
164: struct scsi_cmd cmd;
165: struct scsi_return ret;
166: int n;
167: static char *bit[8] = { "", "", "", "", "CacheEnable", "SSM", "WIE", "CCEN" };
168:
169: set6(cmd, 0x1A, 0, (pcf<<6)|0x38, 0, 28, 0);
170: if(n = s_io(0, &cmd, 0, &ret, 28, err))
171: return(n);
172: printf("cache control:\n\t");
173: for(n = 7; n >= 4; n--)
174: printf(" %s%s", (ret.data[14]&(1<<n))? "":"~", bit[n]);
175: printf(", cache size=%d\n", ret.data[14]&0xF);
176: printf("\tprefetch: thr=%d max=%d(mult %d) min=%d(mult %d)\n",
177: ret.data[15], ret.data[16], ret.data[17], ret.data[18], ret.data[19]);
178: return(0);
179: }
180:
181: typedef (*Fn)(int, char *);
182: static struct Drive
183: {
184: char *type; /* match inq field */
185: char *desc; /* print at the user */
186: Fn fns[10];
187: } drive[] = { /* first one is default when none match */
188: { "94181-15", "Wren VI", er_w6, dr_w6, fp_w6, geom_w6, cc_w6, 0 },
189: { "ST4767", "Wren Runner-2", er_wr2, dr_w6, fp_w6, geom_wr2, cp_wr2, cc_wr2, 0 },
190: { 0 }
191: };
192:
193: int
194: wr_modesense(int niargs, int *iargs, int ncargs, char **cargs, char *err)
195: {
196: int n, i, retv;
197: char product[17];
198: int found;
199: struct scsi_cmd cmd;
200: struct scsi_return ret;
201:
202: #pragma ref ncargs
203: #pragma ref cargs
204: #pragma ref niargs
205: #pragma ref iargs
206:
207: #define PCF 0 /* current values */
208:
209: /* find drive type */
210: set6(cmd, 0x12, 0, 0, 0, 32, 0);
211: if(n = s_io(0, &cmd, 0, &ret, 32, err))
212: return(n);
213: fixedstr(&ret.data[16], 16, product);
214: for(n = 0, found = 0; drive[n].type; n++)
215: if(strcmp(product, drive[n].type) == 0){
216: found = 1;
217: break;
218: }
219: if(!found)
220: n = 0;
221:
222: if(found)
223: printf("mode sense(%d,0)[%s(%s)]:\n", s_id, drive[n].desc, product);
224: else
225: printf("mode sense(%d,0)[using %s, found '%s']:\n", s_id, drive[n].desc, product);
226: for(i = 0; drive[n].fns[i]; i++)
227: if(retv = (*drive[n].fns[i])(PCF, err))
228: return(retv);
229: return(0);
230: }
231: #include <stdio.h>
232: #include "../scsi.h"
233: #include "../scsish.h"
234: #include "fns.h"
235:
236: int
237: wr_modeselect(int niargs, int *iargs, int ncargs, char **cargs, char *err)
238: {
239: struct scsi_cmd cmd;
240: struct scsi_return ret;
241: int n;
242:
243: #pragma ref niargs
244: #pragma ref ncargs
245: #pragma ref cargs
246:
247: printf("changing modes to ");
248: if((iargs[0] < 256) && (iargs[0] >= 0))
249: printf("er-param=%d(=#%x), ", iargs[0], iargs[0]);
250: if((iargs[1] < 256) && (iargs[1] >= 0))
251: printf("er-retries=%d, ", iargs[1]);
252: if((iargs[2] < 256) && (iargs[2] >= 0))
253: printf("read-recon=%d/256, ", iargs[2]);
254: if((iargs[3] < 256) && (iargs[3] >= 0))
255: printf("write-recon=%d/256, ", iargs[3]);
256: if((iargs[4] < 256) && (iargs[4] >= 0))
257: printf("cache %sable, ", iargs[4]?"en":"dis");
258: if((iargs[5] < 256) && (iargs[5] >= 0))
259: printf("cache threshold=%d, ", iargs[5]);
260: if((iargs[6] < 256) && (iargs[6] >= 0))
261: printf("cache max prefetch=%d, ", iargs[6]);
262: if((iargs[7] < 256) && (iargs[7] >= 0))
263: printf("cache size=%d, ", iargs[7]);
264: printf("\nsleep(10); kill me if you disagree\n");
265: fflush(stdout);
266: sleep(10);
267: /* do error recovery */
268: if(((iargs[0] < 256) && (iargs[0] >= 0)) || ((iargs[1] < 256) && (iargs[1] >= 0))){
269: set6(cmd, 0x1A, 0, (0<<6)|0x01, 0, 20, 0);
270: if(n = s_io(0, &cmd, 0, &ret, 20, err))
271: return(n);
272: memcpy(cmd.data, ret.data, 20);
273: cmd.data[14] &= ~0x10;
274: if((iargs[0] < 256) && (iargs[0] >= 0))
275: cmd.data[14] = iargs[0];
276: if((iargs[1] < 256) && (iargs[1] >= 0))
277: cmd.data[15] = iargs[1];
278: set6(cmd, 0x15, 0x11, 0, 0, 20, 0);
279: if(n = s_io(0, &cmd, 20, &ret, 0, err))
280: return(n);
281: }
282: /* reconnect */
283: if(((iargs[2] < 256) && (iargs[2] >= 0)) || ((iargs[3] < 256) && (iargs[3] >= 0))){
284: set6(cmd, 0x1A, 0, (0<<6)|0x02, 0, 24, 0);
285: if(n = s_io(0, &cmd, 0, &ret, 24, err))
286: return(n);
287: memcpy(cmd.data, ret.data, 24);
288: if((iargs[3] < 256) && (iargs[3] >= 0))
289: cmd.data[14] = iargs[3];
290: if((iargs[4] < 256) && (iargs[4] >= 0))
291: cmd.data[15] = iargs[4];
292: set6(cmd, 0x15, 0x11, 0, 0, 24, 0);
293: if(n = s_io(0, &cmd, 24, &ret, 0, err))
294: return(n);
295: }
296: /* do cache control */
297: if(((iargs[4] < 256) && (iargs[4] >= 0))
298: || ((iargs[5] < 256) && (iargs[5] >= 0))
299: || ((iargs[6] < 256) && (iargs[6] >= 0))
300: || ((iargs[7] < 256) && (iargs[7] >= 0))){
301: set6(cmd, 0x1A, 0, (0<<6)|0x38, 0, 28, 0);
302: if(n = s_io(0, &cmd, 0, &ret, 28, err))
303: return(n);
304: memcpy(cmd.data, ret.data, 28);
305: cmd.data[14] &= ~0x10;
306: if(iargs[4])
307: cmd.data[14] |= 0x10;
308: if((iargs[7] < 256) && (iargs[7] >= 0)){
309: cmd.data[14] &= 0xF0;
310: cmd.data[14] |= iargs[7]&0xF;
311: }
312: if((iargs[5] < 256) && (iargs[5] >= 0))
313: cmd.data[15] = iargs[5];
314: if((iargs[6] < 256) && (iargs[6] >= 0))
315: cmd.data[16] = iargs[6];
316: set6(cmd, 0x15, 0x11, 0, 0, 28, 0);
317: if(n = s_io(0, &cmd, 28, &ret, 0, err))
318: return(n);
319: }
320: return(0);
321: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.