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