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