|
|
1.1 root 1: #include <stdio.h>
2: #include "../scsi.h"
3: #include "../scsish.h"
4: #include <sys/types.h>
5: #include <sys/dsreq.h>
6:
7: #define DEV(buf, target, lun) sprintf(buf, "/dev/scsi/sc0d%dl%d", target, lun)
8:
9: static fd = -1;
10: int s_id;
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 retv;
16: dsreq_t ds;
17: char dev[512];
18:
19: err[0] = 0;
20: retv = -1;
21: if(ncmd && nret){
22: sprintf(err, "both input (%d bytes) and output (%d bytes) expected", ncmd, nret);
23: return(retv);
24: }
25: if(cmd->bus_id & 0x8000){
26: sprintf(err, "reset not supported");
27: return(retv);
28: }
29: if(fd < 0){
30: DEV(dev, cmd->bus_id, ((cmd->cmd[1]>>5)&7));
31: if((fd = open(dev, 2)) < 0){
32: pperror(err, dev);
33: return(-1);
34: }
35: }
36: ds.ds_flags = DSRQ_SENSE;
37: ds.ds_time = 30000;
38: ds.ds_cmdbuf = (char *)cmd->cmd;
39: ds.ds_cmdlen = 10;
40: if(ncmd){
41: ds.ds_databuf = (char *)cmd->data;
42: ds.ds_datalen = ncmd;
43: ds.ds_flags |= DSRQ_WRITE;
44: } else {
45: ds.ds_databuf = (char *)ret->data;
46: ds.ds_datalen = nret;
47: ds.ds_flags |= DSRQ_READ;
48: }
49: ds.ds_sensebuf = (char *)ret->sense;
50: ds.ds_senselen = sizeof ret->sense;
51: ds.ds_iovbuf = 0;
52: ds.ds_link = 0;
53: if(ioctl(fd, DS_ENTER, &ds) < 0){
54: pperror(err, "DS_ENTER ioctl");
55: err_ret:
56: close(fd);
57: fd = -1;
58: return(retv);
59: }
60: if(ds.ds_ret
61: && (ds.ds_ret != DSRT_SHORT)
62: && (ds.ds_ret != DSRT_OK)
63: ) /* an error */
64: fprintf(stderr, "ds_ret = #%x\n", ds.ds_ret);
65: ret->type = 3;
66: ret->scsi_stat = ds.ds_status;
67: ret->scsi_msg = ds.ds_msg;
68: ret->reg1 = ret->reg2 = 0;
69: if(nret >= 0){
70: if(ds.ds_datasent != nret){
71: if(ds.ds_datasent == 0)
72: retv = 1;
73: else
74: sprintf(err, "data transfer error; wanted %d, got %d", nret, ds.ds_datasent);
75: goto err_ret;
76: }
77: } else {
78: ret->nread = ds.ds_datasent;
79: }
80: if(!preserve){
81: close(fd);
82: fd = -1;
83: }
84: return(0);
85: }
86:
87: static char *smsg[16] =
88: {
89: "good", "check condition", "met/good", "reserved",
90: "busy", "reserved", "reserved", "reserved",
91: "intermediate good", "reserved", "intermediate good/met", "reserved",
92: "reservation conflict", "reserved", "reserved", "reserved",
93: };
94:
95: s_io(int preserve, struct scsi_cmd *cmd, int ncmd, struct scsi_return *ret, int nret, char *err)
96: {
97: int n;
98: int status;
99: char buf[512];
100: char ioerr[512];
101:
102: cmd->bus_id = s_id;
103: if(n = ss_io(preserve, cmd, ncmd, ret, nret, err)){
104: if(n < 0)
105: return(n);
106: strcpy(ioerr, err);
107: err[0] = 0;
108: } else
109: ioerr[0] = 0;
110: if(status = ret->scsi_stat){
111: (*ss_extsense)(ret->data, buf, sizeof buf);
112: sprintf(err, "%s; %s", ioerr[0]? ioerr : smsg[(status>>1)&0xF], buf);
113: return(1);
114: }
115: return(0);
116: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.