|
|
1.1 root 1: #include <stdio.h>
2: #include "../scsi.h"
3: #include "../scsish.h"
4: #include "../tcl.h"
5: #include "fns.h"
6: #include "wren.h"
7:
8: static int msense(ClientData, int, char **);
9: static int mselect(ClientData, int, char **);
10: Wren wr_wren5 =
11: {
12: "94181-15",
13: "Wren V",
14: msense,
15: mselect,
16: 0,
17: 0,
18: 0
19: };
20:
21: #define SHORT(n) ((ret.data[n]<<8)|(ret.data[n+1]))
22: #define LONG(n) ((((long)SHORT(n))<<16) | SHORT(n+2))
23: #define GETPAGE(page, pcf, ndata)\
24: {\
25: set6(cmd, 0x1A, 0, (pcf<<6)|page, 0, 12+ndata, 0);\
26: if(s_io(0, &cmd, 0, &ret, 12+ndata, err)) return(-1);\
27: if(((ret.data[12]&0x3F) != page) || (ret.data[13]+2!= ndata))\
28: printf("pg=#%x(#%x) data=#%x(#%x)\n",\
29: ret.data[12], page, ret.data[13], ndata);\
30: }
31: #define GETLPAGE(page, ppc, pc, pp, ndata)\
32: {\
33: set10(cmd, 0x4D, ppc<<1, (pc<<6)|page, 0, 0, pp>>8, pp, (ndata+4)>>8, (ndata+4), 0);\
34: if(s_io(0, &cmd, 0, &ret, 4+ndata, err)) return(-1);\
35: if(((ret.data[0]&0x3F) != page) || (SHORT(2)!= ndata))\
36: printf("pg=#%x(#%x) data=#%x(#%x)\n",\
37: ret.data[0], page, SHORT(2), ndata);\
38: }
39:
40: static int
41: er(int pcf, char *err)
42: {
43: struct scsi_cmd cmd;
44: struct scsi_return ret;
45: int n;
46: static char *bit[8] = { "DCR", "DTE", "PER", "EER", "RC", "TB", "ARRE", "AWRE" };
47:
48: GETPAGE(0x01, pcf, 8)
49: printf("error recovery:\n\t");
50: for(n = 7; n >= 0; n--)
51: printf(" %s=%d", bit[n], !!(ret.data[14]&(1<<n)));
52: printf("\n\t%d retries, max ecc span=%d, recov tlimit=%d\n",
53: ret.data[15], ret.data[16], ret.data[19]);
54: return(0);
55: }
56:
57: static int
58: dr(int pcf, char *err)
59: {
60: struct scsi_cmd cmd;
61: struct scsi_return ret;
62:
63: GETPAGE(0x02, pcf, 12)
64: printf("disconnect/reconnect:\n");
65: printf("\tread reconnect=%d/256 full,", ret.data[14]);
66: printf(" write reconnect=%d/256 empty\n", ret.data[15]);
67: return(0);
68: }
69:
70: static int
71: fp(int pcf, char *err)
72: {
73: struct scsi_cmd cmd;
74: struct scsi_return ret;
75: int n;
76: static char *bit[8] = { "", "", "", "INS", "SURF", "Remove", "HardSec", "SoftSec" };
77:
78: GETPAGE(0x03, pcf, 24);
79: printf("format parameters:\n");
80: printf("\tdrive type:");
81: for(n = 7; n >= 3; n--)
82: printf(" %s=%d", bit[n], !!(ret.data[32]&(1<<n)));
83: printf("\n");
84: printf("\tsec=%d B, trk=%d secs, interleave=%d, trk_skew=%d, cyl_skew=%d\n",
85: SHORT(24), SHORT(22), SHORT(26), SHORT(28), SHORT(30));
86: printf("\t%d alt_sec/%d alt_trk per zone(=%d trks), %d alt_trk per vol\n",
87: SHORT(16), SHORT(18), SHORT(14), SHORT(20));
88: return(0);
89: }
90:
91: static int
92: geom(int pcf, char *err)
93: {
94: struct scsi_cmd cmd;
95: struct scsi_return ret;
96:
97: GETPAGE(0x04, pcf, 20);
98: printf("drive geometry:\n\t%d cyls, %d heads\n",
99: (((long)ret.data[14])<<16)|SHORT(15), ret.data[17]);
100: return(0);
101: }
102:
103: static int
104: vc(int pcf, char *err)
105: {
106: struct scsi_cmd cmd;
107: struct scsi_return ret;
108: int n;
109: static char *bit[8] = { "", "", "", "", "CE", 0, "WIE", 0 };
110:
111: GETPAGE(0x38, pcf, 16)
112: printf("vendor caching parameters:\n\t");
113: for(n = 7; n >= 4; n--)
114: if(bit[n])
115: printf(" %s=%d", bit[n], !!(ret.data[14]&(1<<n)));
116: printf(", cache size=%d\n", ret.data[14]&0xF);
117: printf("\tprefetch: thr=%d max=%d(mult %d) min=%d(mult %d)\n",
118: ret.data[15], ret.data[16], ret.data[17], ret.data[18], ret.data[19]);
119: return(0);
120: }
121:
122: static char *pcfval[4] = { "current", "changeable", "default", "saved" };
123:
124: static int
125: msense(ClientData cd, int argc, char **argv)
126: {
127: int pcf;
128:
129: if(argc > 2){
130: usage:
131: sprintf(cd->err, "usage: modesense [%s|%s|%s|%s]", pcfval[0], pcfval[1], pcfval[2], pcfval[3]);
132: return(TCL_ERROR);
133: }
134: if(argc == 2){
135: for(pcf = 3; pcf >= 0; pcf--)
136: if(strcmp(pcfval[pcf], argv[1]) == 0)
137: break;
138: if(pcf < 0)
139: goto usage;
140: } else
141: pcf = 0;
142: printf("modesense(id=%d,%s values):\n", s_id, pcfval[pcf]);
143: if(er(pcf, cd->err))
144: return(1);
145: if(dr(pcf, cd->err))
146: return(1);
147: if(fp(pcf, cd->err))
148: return(1);
149: if(geom(pcf, cd->err))
150: return(1);
151: if(vc(pcf, cd->err))
152: return(1);
153: return(0);
154: }
155:
156: static Page pages[] =
157: {
158: { "er", 0x1, {
159: { "dcr", 2, 0, 1 },
160: { "dte", 2, 1, 1 },
161: { "per", 2, 2, 1 },
162: { "eer", 2, 3, 1 },
163: { "rc", 2, 4, 1 },
164: { "tb", 2, 5, 1 },
165: { "arre", 2, 6, 1 },
166: { "awre", 2, 7, 1 },
167: { "read retries", 3, 0, 8 },
168: { (char *)0 },
169: }},
170: { "dr", 0x2, {
171: { "buffer full", 2, 0, 8 },
172: { "buffer empty", 3, 0, 8 },
173: { (char *)0 },
174: }},
175: { "vc", 0x38, {
176: { "ce", 2, 4, 1 },
177: { (char *)0 },
178: }},
179: { (char *)0 }
180: };
181:
182: static int
183: mselect(ClientData cd, int argc, char **argv)
184: {
185: int page, i;
186: int pcf = 0;
187: Field *f, *todo[64], **fp = todo;
188:
189: #pragma ref argc
190:
191: argv++;
192: if(*argv){
193: for(i = 0; i < 4; i++)
194: if(strcmp(pcfval[i], *argv) == 0){
195: pcf = i;
196: argv++;
197: }
198: }
199: if(*argv == 0){
200: usage:
201: printf("Usage: modeselect ");
202: for(i = 0; i < 4; i++)
203: printf("%c%s", i?'|':'[', pcfval[i]);
204: printf("]");
205: for(i = 0; pages[i].name; i++)
206: printf("%c%s", i?'|':' ', pages[i].name);
207: printf(" fields ...\n");
208: return(TCL_OK);
209: }
210: for(i = 0; pages[i].name; i++)
211: if(strcmp(pages[i].name, *argv) == 0)
212: break;
213: if(pages[i].name == 0)
214: goto usage;
215: page = i;
216: if(*++argv == 0){
217: fusage:
218: printf("fields for page %s:", pages[page].name);
219: for(i = 0; pages[page].fields[i].name; i++)
220: printf(" '%s'", pages[page].fields[i].name);
221: printf("\n");
222: return(TCL_OK);
223: }
224: while(*argv){
225: for(f = pages[page].fields; f->name; f++)
226: if(strcmp(f->name, *argv) == 0)
227: break;
228: if(f->name == 0)
229: goto fusage;
230: if(*++argv == 0){
231: sprintf(cd->err, "expected val for field %s", f->name);
232: return(-1);
233: }
234: f->nval = atol(*argv++);
235: *fp++ = f;
236: }
237: *fp = 0;
238: return(wr_mpage(pcf, pages[page].page, todo, cd->err));
239: }
240:
241: #ifdef NO
242: #include <stdio.h>
243: #include "../scsi.h"
244: #include "../scsish.h"
245: #include "fns.h"
246:
247: int
248: wr_modeselect(int niargs, int *iargs, int ncargs, char **cargs, char *err)
249: {
250: struct scsi_cmd cmd;
251: struct scsi_return ret;
252: int n;
253:
254: #pragma ref niargs
255: #pragma ref ncargs
256: #pragma ref cargs
257:
258: printf("changing modes to ");
259: if((iargs[0] < 256) && (iargs[0] >= 0))
260: printf("er-param=%d(=#%x), ", iargs[0], iargs[0]);
261: if((iargs[1] < 256) && (iargs[1] >= 0))
262: printf("er-retries=%d, ", iargs[1]);
263: if((iargs[2] < 256) && (iargs[2] >= 0))
264: printf("read-recon=%d/256, ", iargs[2]);
265: if((iargs[3] < 256) && (iargs[3] >= 0))
266: printf("write-recon=%d/256, ", iargs[3]);
267: if((iargs[4] < 256) && (iargs[4] >= 0))
268: printf("cache %sable, ", iargs[4]?"en":"dis");
269: if((iargs[5] < 256) && (iargs[5] >= 0))
270: printf("cache threshold=%d, ", iargs[5]);
271: if((iargs[6] < 256) && (iargs[6] >= 0))
272: printf("cache max prefetch=%d, ", iargs[6]);
273: if((iargs[7] < 256) && (iargs[7] >= 0))
274: printf("cache size=%d, ", iargs[7]);
275: printf("\nsleep(10); kill me if you disagree\n");
276: fflush(stdout);
277: sleep(10);
278: /* do error recovery */
279: if(((iargs[0] < 256) && (iargs[0] >= 0)) || ((iargs[1] < 256) && (iargs[1] >= 0))){
280: set6(cmd, 0x1A, 0, (0<<6)|0x01, 0, 20, 0);
281: if(n = s_io(0, &cmd, 0, &ret, 20, err))
282: return(n);
283: memcpy(cmd.data, ret.data, 20);
284: cmd.data[14] &= ~0x10;
285: if((iargs[0] < 256) && (iargs[0] >= 0))
286: cmd.data[14] = iargs[0];
287: if((iargs[1] < 256) && (iargs[1] >= 0))
288: cmd.data[15] = iargs[1];
289: set6(cmd, 0x15, 0x11, 0, 0, 20, 0);
290: if(n = s_io(0, &cmd, 20, &ret, 0, err))
291: return(n);
292: }
293: /* reconnect */
294: if(((iargs[2] < 256) && (iargs[2] >= 0)) || ((iargs[3] < 256) && (iargs[3] >= 0))){
295: set6(cmd, 0x1A, 0, (0<<6)|0x02, 0, 24, 0);
296: if(n = s_io(0, &cmd, 0, &ret, 24, err))
297: return(n);
298: memcpy(cmd.data, ret.data, 24);
299: if((iargs[3] < 256) && (iargs[3] >= 0))
300: cmd.data[14] = iargs[3];
301: if((iargs[4] < 256) && (iargs[4] >= 0))
302: cmd.data[15] = iargs[4];
303: set6(cmd, 0x15, 0x11, 0, 0, 24, 0);
304: if(n = s_io(0, &cmd, 24, &ret, 0, err))
305: return(n);
306: }
307: /* do cache control */
308: if(((iargs[4] < 256) && (iargs[4] >= 0))
309: || ((iargs[5] < 256) && (iargs[5] >= 0))
310: || ((iargs[6] < 256) && (iargs[6] >= 0))
311: || ((iargs[7] < 256) && (iargs[7] >= 0))){
312: set6(cmd, 0x1A, 0, (0<<6)|0x38, 0, 28, 0);
313: if(n = s_io(0, &cmd, 0, &ret, 28, err))
314: return(n);
315: memcpy(cmd.data, ret.data, 28);
316: cmd.data[14] &= ~0x10;
317: if(iargs[4])
318: cmd.data[14] |= 0x10;
319: if((iargs[7] < 256) && (iargs[7] >= 0)){
320: cmd.data[14] &= 0xF0;
321: cmd.data[14] |= iargs[7]&0xF;
322: }
323: if((iargs[5] < 256) && (iargs[5] >= 0))
324: cmd.data[15] = iargs[5];
325: if((iargs[6] < 256) && (iargs[6] >= 0))
326: cmd.data[16] = iargs[6];
327: set6(cmd, 0x15, 0x11, 0, 0, 28, 0);
328: if(n = s_io(0, &cmd, 28, &ret, 0, err))
329: return(n);
330: }
331: return(0);
332: }
333: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.