|
|
1.1 root 1: #include "scsi.h"
2:
3: #define DEV "/dev/scsi"
4:
5: static char *regname[][2] =
6: {
7: "??", "",
8: "sa", "mscp",
9: "csr", "per"
10: };
11:
12: int scsi_fd;
13: int scsi_id;
14: int scsi_verbose;
15: int scsi_shush;
16:
17: scsiinit(complain)
18: {
19: scsi_shush = 0;
20: if((scsi_fd = open(DEV, 2)) < 0){
21: if(complain)
22: perror(DEV);
23: return(1);
24: }
25: return(0);
26: }
27:
28: scsiid(id)
29: {
30: scsi_id = id;
31: }
32:
33: scsiclro(o)
34: register struct scsi_o *o;
35: {
36: extern char *memset();
37: memset((char *)o, 0xDD, sizeof(*o));
38: }
39:
40: tdreg(fd, sa, mscp)
41: {
42: char buf[256];
43: extern char *strcat();
44:
45: #define add(x) strcat(buf, x)
46:
47: buf[0] = 0;
48: if(mscp&0x8000) add(", host buffer access");
49: if(mscp&0x2000) add(", SCSI bus hung");
50: if(mscp&0x1000) add(", resettable bad bus phase");
51: if(mscp&0x0800) add(", select timeout");
52: if(mscp&0x0200) add(", parity error");
53: switch(mscp&0x3F)
54: {
55: case 011: add(", dma error"); break;
56: case 012: add(", controller error"); break;
57: default: add(", bad mscp error code!!"); break;
58: }
59: if(buf[0] == 0)
60: fprint(fd, "mscp: zero");
61: else {
62: fprint(fd, "mscp:%s", &buf[1]);
63: }
64: fprint(fd, "; ");
65: fprint(fd, "sa: %hux\n", sa);
66: }
67:
68: #define CSR_DONE 0x8000
69: #define CSR_ERROR 0x1000
70: #define CSR_R 0x0020
71: #define CSR_M 0x0010
72: #define CSR_I 0x0008
73: #define CSR_C 0x0004
74: #define CSR_S 0x0002
75: #define CSR_B 0x0001
76: #define CSR_BITS (CSR_DONE|CSR_ERROR|CSR_R|CSR_M|CSR_I|CSR_C|CSR_S|CSR_B)
77:
78: #define PER_CHECK 0x2000
79: #define PER_DRBUSY 0x1000
80: #define PER_SBUSY 0x0040
81: #define PER_SELECT 0x0010
82:
83: usreg(fd, csr, per)
84: {
85: char buf[256];
86: extern char *strcat();
87:
88: buf[0] = 0;
89: if(csr&CSR_DONE) add(", i/o done");
90: if(csr&CSR_ERROR) add(", error");
91: if(csr&CSR_R) add(", request active");
92: if(csr&CSR_M) add(", message active");
93: if(csr&CSR_I) add(", i/o active");
94: if(csr&CSR_C) add(", c/d active");
95: if(csr&CSR_S) add(", select active");
96: if(csr&CSR_B) add(", busy active");
97: if(buf[0] == 0)
98: fprint(fd, "CSR: zero");
99: else {
100: fprint(fd, "CSR:%s", &buf[1]);
101: if(csr&!CSR_BITS)
102: fprint(fd, " BAD BITS SET 0x%ux", csr&!CSR_BITS);
103: }
104: fprint(fd, "; ");
105: buf[0] = 0;
106: if(per&PER_CHECK) add(", check status");
107: if(per&PER_DRBUSY) add(", drive busy");
108: if(per&PER_SBUSY) add(", busy timeout");
109: if(per&PER_SELECT) add(", select timeout");
110: if(buf[0] == 0)
111: fprint(fd, "PER: zero\n");
112: else
113: fprint(fd, "PER:%s\n", &buf[1]);
114: }
115:
116: scsidump(o)
117: register struct scsi_o *o;
118: {
119: extern char *exstab[], *smsg[];
120:
121: Fprint(1, "%s=0x%uhx %s=0x%uhx status=0x%uhx(%s) message=0x%uhx\n",
122: regname[o->type][0], o->reg1, regname[o->type][1], o->reg2,
123: o->scsistatus, smsg[(o->scsistatus>>1)&0xF], o->scsimesg);
124: Fprint(1, "data=0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", o->data[0],
125: o->data[1], o->data[2], o->data[3], o->data[4], o->data[5],
126: o->data[6], o->data[7], o->data[8], o->data[9], o->data[10],
127: o->data[11]);
128: if(o->data[0] == 0x70)
129: Fprint(1, " (extended sense: %s)", exstab[o->data[2]&0xF]);
130: Fprint(1, "\n");
131: }
132:
133: prcheck(fd, o)
134: register struct scsi_o *o;
135: {
136: int ot;
137: extern char *exstab[], *smsg[];
138:
139: ot = o->type;
140: if((ot < 0) || (ot > 2)) ot = 0;
141: Fprint(fd, "%s=0x%uhx %s=0x%uhx status=0x%uhx(%s)",
142: regname[ot][0], o->reg1, regname[ot][1], o->reg2,
143: o->scsistatus, smsg[(o->scsistatus>>1)&0xF]);
144: if(o->data[0] == 0x70)
145: Fprint(fd, " (ext: %s)", exstab[o->data[2]&0xF]);
146: Fputc(fd, '\n');
147: }
148:
149: scsiio(i, icnt, o, ocnt, str)
150: struct scsi_i *i;
151: struct scsi_o *o;
152: char *str;
153: {
154: int n, loop;
155:
156: for(loop = 0; loop < 20; loop++){
157: if((n = write(scsi_fd, (char *)i, INN(icnt))) != INN(icnt)){
158: perror("write");
159: fprint(2, "%s: wrote %d, really wrote %d\n", str, INN(icnt), n);
160: return(-1);
161: }
162: scsiclro(o);
163: if((n = read(scsi_fd, (char *)o, OUTN(ocnt))) != OUTN(ocnt)){
164: if((n == 8) && (o->scsistatus == 8))
165: continue;
166: if(!scsi_shush){
167: if(n < 0)
168: perror("read");
169: fprint(2, "%s: wanted %d, got %d\n", str, OUTN(ocnt), n);
170: prcheck(2, o);
171: Fflush(2);
172: }
173: if(n < 0)
174: switch(o->type)
175: {
176: case TD_VIKING: tdreg(2, o->reg1, o->reg2); break;
177: case USD_1158: usreg(2, o->reg1, o->reg2); break;
178: default: fprint(2, "BAD board type %d\n", o->type); break;
179: }
180: return(-1);
181: }
182: if(o->scsistatus == 0)
183: break;
184: }
185: return(0);
186: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.