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