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