|
|
1.1 root 1: #include <stdio.h>
2: #include <stddef.h>
3: #include "../scsi.h"
4: #include "../scsish.h"
5: #include "../tcl.h"
6: #include "fns.h"
7:
8: static int cnts[256];
9: static char *cmsg[256];
10:
11: sony_media1(int drive, long lbn, int lower, struct scsi_return *ret, char *err)
12: {
13: struct scsi_cmd cmd;
14: int n;
15:
16: set6(cmd, 0x1D, drive<<5, 0, 0, 10, 0);
17: cmd.data[0] = 0x0A; /* error margin check */
18: cmd.data[1] = lower? 2:1;
19: cmd.data[2] = 0;
20: cmd.data[3] = 0;
21: cmd.data[4] = drive;
22: cmd.data[5] = lbn;
23: cmd.data[6] = lbn>>8;
24: cmd.data[7] = lbn>>16;
25: cmd.data[8] = 0;
26: cmd.data[9] = 0;
27: if(n = s_io(0, &cmd, 10, ret, 0, err))
28: return(n);
29: setdiag(cmd, drive, 256);
30: if(n = s_io(0, &cmd, 0, ret, 256, err))
31: return(n);
32: return(0);
33: }
34:
35: int
36: sony_media(ClientData cd, Tcl_Interp *it, int argc, char **argv)
37: {
38: struct scsi_return ret;
39: uchar *d;
40: int bn, c;
41: char buf[256];
42: int lower;
43: int nline;
44: int cur, curb;
45: int drive;
46: long lbn;
47: int count;
48: extern char *strdup(char *);
49: int verbose = 0;
50: FILE *fp = 0;
51: char *fout = 0;
52: extern char *optarg;
53: extern int optind;
54:
55: #pragma ref niargs
56:
57: while((c = getopt(argc, argv, "vf:")) != -1)
58: switch(c)
59: {
60: case 'v': verbose = 1; break;
61: case 'f': fout = optarg; break;
62: default: USAGE_RETURN
63: }
64: if(optind+3 != argc)
65: USAGE_RETURN
66: drive = atoi(argv[optind]);
67: lbn = atol(argv[optind+1]);
68: count = atoi(argv[optind+2]);
69: if(fout){
70: if((fp = fopen(fout, "w")) == NULL){
71: pperror(cd->err, fout);
72: ERR_RETURN
73: }
74: }
75: if(sony_istatus(&ret, cd->err))
76: ERR_RETURN
77: if((ret.data[100]&0x80) && (drive == (ret.data[100]&7)))
78: lower = 0;
79: else if((ret.data[101]&0x80) && (drive == (ret.data[101]&7)))
80: lower = 1;
81: else {
82: sprintf(cd->err, "drive %d not occupied and ready\n", drive);
83: ERR_RETURN
84: }
85: printf("media margin check for %d blocks [%d-%d] on %s drive (%d,%d):",
86: count, lbn, lbn+count-1, lower? "lower":"upper", s_id, drive);
87: if(fp)
88: printf(" stored in '%s'", fout);
89: putchar('\n');
90: if(cmsg[0] == 0){
91: for(bn = 0; bn < 256; bn++){
92: sprintf(buf, "rare error 0x%x", bn);
93: cmsg[bn] = strdup(buf);
94: }
95: cmsg[0] = "good";
96: cmsg[0x40] = "seek error 1 (alternated)";
97: cmsg[0x41] = "seek error 2 (alternated)";
98: cmsg[0x42] = "seek error 3 (alternated)";
99: cmsg[0x44] = "read error 1 (alternated)";
100: cmsg[0x45] = "unwritten";
101: cmsg[0x46] = "read error 3 (alternated)";
102: cmsg[0x81] = "<50% burst";
103: cmsg[0x82] = "50-96% burst (alternated)";
104: cmsg[0x83] = ">96% burst (alternated)";
105: cmsg[0x84] = "uncorrectable (alternated)";
106: }
107: #define DO(ch,cp) if(fp) putc(ch,fp); else if(ch != cur){\
108: int newb = bn+cp-ret.data;\
109: if(verbose && (curb>=0)){\
110: printf("%d %s@%d, ", newb-curb, cmsg[cur], curb);\
111: if(++nline == 5){nline = 0; putchar('\n');}\
112: }\
113: cur = ch;\
114: curb = newb;\
115: }
116: cur = 256;
117: curb = -1;
118: nline = 0;
119: for(bn = 0; bn < 256; bn++)
120: cnts[bn] = 0;
121: for(bn = lbn, c = count; c >= 256; c -= 256, bn += 256){
122: if(sony_media1(drive, bn, lower, &ret, cd->err))
123: ERR_RETURN
124: for(d = ret.data; d < &ret.data[256];){
125: DO(*d, d);
126: cnts[*d++]++;
127: }
128: }
129: if(c){
130: if(sony_media1(drive, bn, lower, &ret, cd->err))
131: ERR_RETURN
132: for(d = ret.data; c; c--){
133: DO(*d, d);
134: cnts[*d++]++;
135: }
136: }
137: DO(256, d);
138: if(nline)
139: putchar('\n');
140: printf("\t");
141: for(c = 0; c < 256; c++)
142: if(cnts[c])
143: printf("%d %s, ", cnts[c], cmsg[c]);
144: printf("\n");
145: return(TCL_OK);
146: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.