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