|
|
1.1 root 1: #include <stdio.h>
2: #include "../scsi.h"
3: #include "../scsish.h"
4: #include <scsi.h>
5:
6: #define DEV "/dev/scsi"
7:
8: static fd = -1;
9: int s_id;
10: int s_ignua = 1;
11: void (*ss_extsense)(uchar *, char *, int);
12:
13: ss_io(int preserve, struct scsi_cmd *cmd, int ncmd, struct scsi_return *ret, int nret, char *err)
14: {
15: int n;
16: int retv;
17:
18: err[0] = 0;
19: retv = -1;
20: if(fd < 0){
21: if((fd = open(DEV, 2)) < 0){
22: pperror(err, DEV);
23: return(-1);
24: }
25: }
26: cmd->flags |= (ncmd == 0)? SCSI_RD:SCSI_WR;
27: if((n = write(fd, cmd, 16+ncmd)) != 16+ncmd){
28: pperror(err, "scsiio write");
29: err_ret:
30: close(fd);
31: fd = -1;
32: return(retv);
33: }
34: if(nret >= 0){
35: if((n = read(fd, ret, 36+nret)) != 36+nret){
36: if(n == 36)
37: retv = 1;
38: else
39: pperror(err, "scsiio read");
40: goto err_ret;
41: }
42: } else {
43: if((n = read(fd, ret, 36-nret)) < 0){
44: pperror(err, "scsiio read");
45: goto err_ret;
46: }
47: ret->nread = n-36;
48: }
49: if(!preserve){
50: close(fd);
51: fd = -1;
52: }
53: return(0);
54: }
55:
56: static char *smsg[16] =
57: {
58: "good", "check condition", "met/good", "reserved",
59: "busy", "reserved", "reserved", "reserved",
60: "intermediate good", "reserved", "intermediate good/met", "reserved",
61: "reservation conflict", "reserved", "reserved", "reserved",
62: };
63:
64: s_io(int preserve, struct scsi_cmd *cmd, int ncmd, struct scsi_return *ret, int nret, char *err)
65: {
66: int n;
67: int status;
68: char buf[512];
69: char ioerr[512];
70: struct scsi_cmd mycmd;
71: int ignoredua = 0;
72:
73: cmd->bus_id = s_id;
74: again:
75: if(n = ss_io(preserve, cmd, ncmd, ret, nret, err)){
76: if(n < 0)
77: return(n);
78: strcpy(ioerr, err);
79: err[0] = 0;
80: } else
81: ioerr[0] = 0;
82: if(status = ret->scsi_stat){
83: mycmd.bus_id = s_id;
84: set6(mycmd, 0x03, cmd->cmd[1]&0xE0, 0, 0, 100, 0);
85: if(n = ss_io(0, &mycmd, 0, ret, -100, err))
86: return(n);
87: if(s_ignua){ /* ignore unit attention ?? */
88: if((ret->data[2]&0xF) == 6){ /* it is */
89: if(ignoredua++ == 0){ /* but only ignore once */
90: mycmd.bus_id = s_id;
91: set6(mycmd, 0x12, cmd->cmd[1]&0xE0, 0, 0, 5, 0);
92: if(n = ss_io(0, &mycmd, 0, ret, 5, err))
93: return(n);
94: goto again;
95: }
96: }
97: }
98: if(ss_extsense == 0)
99: ss_extsense = gen_extsense;
100: (*ss_extsense)(ret->data, buf, sizeof buf);
101: sprintf(err, "%s; %s", ioerr[0]? ioerr : smsg[(status>>1)&0xF], buf);
102: return(1);
103: }
104: return(0);
105: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.