scsitransp.c
来自「刻录光盘的程序」· C语言 代码 · 共 866 行 · 第 1/2 页
C
866 行
long maxdma; maxdma = scsi_maxdma(scgp); if (amt <= 0 || amt > maxdma) return (maxdma); return (amt);}EXPORT voidscsi_setnonstderrs(scgp, vec) SCSI *scgp; const char **vec;{ scgp->nonstderrs = vec;}EXPORTBOOL scsi_yes(msg) char *msg;{ char okbuf[10]; printf("%s", msg); flush(); if (getline(okbuf, sizeof(okbuf)) == EOF) exit(EX_BAD); if(streql(okbuf, "y") || streql(okbuf, "yes") || streql(okbuf, "Y") || streql(okbuf, "YES")) return(TRUE); else return(FALSE);}#ifdef nononoLOCAL voidscsi_sighandler(sig) int sig;{ printf("\n"); if (scsi_running) { printf("Running command: %s\n", scsi_command); printf("Resetting SCSI - Bus.\n"); if (scsireset(scgp) < 0) errmsg("Cannot reset SCSI - Bus.\n"); } if (scsi_yes("EXIT ? ")) exit(sig);}#endifEXPORTint scsicmd(scgp) SCSI *scgp;{ int f; int ret; register struct scg_cmd *scmd = scgp->scmd; f = scsi_fileno(scgp, scgp->scsibus, scgp->target, scgp->lun); scmd->kdebug = scgp->kdebug; if (scmd->timeout == 0 || scmd->timeout < scgp->deftimeout) scmd->timeout = scgp->deftimeout; if (scgp->disre_disable) scmd->flags &= ~SCG_DISRE_ENA; if (scgp->noparity) scmd->flags |= SCG_NOPARITY; scmd->u_sense.cmd_sense[0] = 0; /* Paranioa */ if (scgp->verbose) { printf("\nExecuting '%s' command on Bus %d Target %d, Lun %d timeout %ds\n", scgp->cmdname, scgp->scsibus, scgp->target, scmd->cdb.g0_cdb.lun, scmd->timeout); scsiprintcdb(scgp); if (scgp->verbose > 1) scsiprintwdata(scgp); flush(); } if (scgp->running) { if (scgp->curcmdname) { error("Currently running '%s' command.\n", scgp->curcmdname); } raisecond("SCSI ALREADY RUNNING !!", 0L); } gettimeofday(scgp->cmdstart, (struct timezone *)0); scgp->curcmdname = scgp->cmdname; scgp->running = TRUE; ret = scsi_send(scgp, f, scmd); scgp->running = FALSE; scsitimes(scgp); if (ret < 0) { /* * Old /dev/scg versions will not allow to access targets > 7. * Include a workaround to make this non fatal. */ if (scgp->target < 8 || geterrno() != EINVAL) comerr("Cannot send SCSI cmd via ioctl\n"); if (scmd->ux_errno == 0) scmd->ux_errno = geterrno(); if (scmd->error == SCG_NO_ERROR) scmd->error = SCG_FATAL; if (scgp->debug) { errmsg("ret < 0 errno: %d ux_errno: %d error: %d\n", geterrno(), scmd->ux_errno, scmd->error); } } ret = scsicheckerr(scgp); if (scgp->verbose || (ret && scgp->silent <= 0)) { scsiprintresult(scgp); } return (ret);}EXPORTint scsigetresid(scgp) SCSI *scgp;{ return (scgp->scmd->resid);}LOCALvoid scsitimes(scgp) SCSI *scgp;{ struct timeval *stp = scgp->cmdstop; gettimeofday(stp, (struct timezone *)0); stp->tv_sec -= scgp->cmdstart->tv_sec; stp->tv_usec -= scgp->cmdstart->tv_usec; while (stp->tv_usec < 0) { stp->tv_sec -= 1; stp->tv_usec += 1000000; }}LOCAL BOOLscsierr(scgp) SCSI *scgp;{ register struct scg_cmd *cp = scgp->scmd; if(cp->error != SCG_NO_ERROR || cp->ux_errno != 0 || *(u_char *)&cp->scb != 0 || cp->u_sense.cmd_sense[0] != 0) /* Paranioa */ return (TRUE); return (FALSE);}LOCAL intscsicheckerr(scgp) SCSI *scgp;{ register int ret; ret = 0; if(scsierr(scgp)) { if (!scgp->silent || scgp->verbose) scsiprinterr(scgp); ret = -1; } if ((!scgp->silent || scgp->verbose) && scgp->scmd->resid) { printf("resid: %d\n", scgp->scmd->resid); flush(); } return (ret);}EXPORT voidscsiprinterr(scgp) SCSI *scgp;{ register struct scg_cmd *cp = scgp->scmd; register char *err; char errbuf[64]; switch (cp->error) { case SCG_NO_ERROR : err = "no error"; break; case SCG_RETRYABLE: err = "retryable error"; break; case SCG_FATAL : err = "fatal error"; break; /* * We need to cast timeval->* to long because * of the broken sys/time.h in Linux. */ case SCG_TIMEOUT : sprintf(errbuf, "cmd timeout after %ld.%03ld (%d) s", (long)scgp->cmdstop->tv_sec, (long)scgp->cmdstop->tv_usec/1000, cp->timeout); err = errbuf; break; default: sprintf(errbuf, "error: %d", cp->error); err = errbuf; } errmsgno(cp->ux_errno, "%s: scsi sendcmd: %s\n", scgp->cmdname, err); scsiprintcdb(scgp); if (cp->error <= SCG_RETRYABLE) scsiprintstatus(scgp); if (cp->scb.chk) { scsiprsense((u_char *)&cp->sense, cp->sense_count); scsierrmsg(scgp, &cp->sense, &cp->scb, -1, scgp->nonstderrs); } flush();}EXPORT voidscsiprintcdb(scgp) SCSI *scgp;{ scsiprbytes("CDB: ", scgp->scmd->cdb.cmd_cdb, scgp->scmd->cdb_len);}EXPORT voidscsiprintwdata(scgp) SCSI *scgp;{ register struct scg_cmd *scmd = scgp->scmd; if (scmd->size > 0 && (scmd->flags & SCG_RECV_DATA) == 0) { printf("Sending %d (0x%X) bytes of data.\n", scmd->size, scmd->size); scsiprbytes("Write Data: ", (Uchar *)scmd->addr, scmd->size > 100 ? 100 : scmd->size); }}EXPORT voidscsiprintrdata(scgp) SCSI *scgp;{ register struct scg_cmd *scmd = scgp->scmd; if (scmd->size > 0 && (scmd->flags & SCG_RECV_DATA) != 0) { printf("Got %d (0x%X), expecting %d (0x%X) bytes of data.\n", scmd->size-scmd->resid, scmd->size-scmd->resid, scmd->size, scmd->size); scsiprbytes("Received Data: ", (Uchar *)scmd->addr, (scmd->size-scmd->resid) > 100 ? 100 : (scmd->size-scmd->resid)); }}EXPORT voidscsiprintresult(scgp) SCSI *scgp;{ printf("cmd finished after %ld.%03lds timeout %ds\n", (long)scgp->cmdstop->tv_sec, (long)scgp->cmdstop->tv_usec/1000, scgp->scmd->timeout); if (scgp->verbose > 1) scsiprintrdata(scgp); flush();}EXPORTvoid scsiprintstatus(scgp) SCSI *scgp;{ register struct scg_cmd *cp = scgp->scmd; error("status: 0x%x ", *(u_char *)&cp->scb);#ifdef SCSI_EXTENDED_STATUS if (cp->scb.ext_st1) error("0x%x ", ((u_char *)&cp->scb)[1]); if (cp->scb.ext_st2) error("0x%x ", ((u_char *)&cp->scb)[2]);#endif error("("); switch (*(u_char *)&cp->scb & 036) { case 0 : error("GOOD STATUS"); break; case 02 : error("CHECK CONDITION"); break; case 04 : error("CONDITION MET/GOOD"); break; case 010: error("BUSY"); break; case 020: error("INTERMEDIATE GOOD STATUS"); break; case 024: error("INTERMEDIATE CONDITION MET/GOOD"); break; case 030: error("RESERVATION CONFLICT"); break; default : error("Reserved"); break; }#ifdef SCSI_EXTENDED_STATUS if (cp->scb.ext_st1 && cp->scb.ha_er) error(" host adapter detected error");#endif error(")\n");}EXPORT voidscsiprbytes(s, cp, n) char *s; register u_char *cp; register int n;{ printf(s); while (--n >= 0) printf(" %02X", *cp++); printf("\n");}EXPORT voidscsiprsense(cp, n) u_char *cp; int n;{ scsiprbytes("Sense Bytes:", cp, n);}EXPORT intscsi_sense_key(scgp) SCSI *scgp;{ register struct scg_cmd *cp = scgp->scmd; int key = -1; if(!scsierr(scgp)) return (0); if (cp->sense.code >= 0x70) key = ((struct scsi_ext_sense*)&(cp->sense))->key; return(key);}EXPORT intscsi_sense_code(scgp) SCSI *scgp;{ register struct scg_cmd *cp = scgp->scmd; int code = -1; if(!scsierr(scgp)) return (0); if (cp->sense.code >= 0x70) code = ((struct scsi_ext_sense*)&(cp->sense))->sense_code; else code = cp->sense.code; return(code);}EXPORT intscsi_sense_qual(scgp) SCSI *scgp;{ register struct scg_cmd *cp = scgp->scmd; if(!scsierr(scgp)) return (0); if (cp->sense.code >= 0x70) return (((struct scsi_ext_sense*)&(cp->sense))->qual_code); else return (0);}EXPORTvoid scsiprintdev(ip) struct scsi_inquiry *ip;{ if (ip->removable) printf("Removable "); if (ip->data_format >= 2) { switch (ip->qualifier) { case INQ_DEV_PRESENT: break; case INQ_DEV_NOTPR: printf("not present "); break; case INQ_DEV_RES: printf("reserved "); break; case INQ_DEV_NOTSUP: if (ip->type == INQ_NODEV) { printf("unsupported\n"); return; } printf("unsupported "); break; default: printf("vendor specific %d ", ip->qualifier); } } switch (ip->type) { case INQ_DASD: printf("Disk"); break; case INQ_SEQD: printf("Tape"); break; case INQ_PRTD: printf("Printer"); break; case INQ_PROCD: printf("Processor"); break; case INQ_WORM: printf("WORM"); break; case INQ_ROMD: printf("CD-ROM"); break; case INQ_SCAN: printf("Scanner"); break; case INQ_OMEM: printf("Optical Storage"); break; case INQ_JUKE: printf("Juke Box"); break; case INQ_COMM: printf("Communication"); break; case INQ_IT8_1: printf("IT8 1"); break; case INQ_IT8_2: printf("IT8 2"); break; case INQ_STARR: printf("Storage array"); break; case INQ_ENCL: printf("Enclosure services"); break; case INQ_NODEV: if (ip->data_format >= 2) { printf("unknown/no device"); break; } else if (ip->qualifier == INQ_DEV_NOTSUP) { printf("unit not present"); break; } default: printf("unknown device type 0x%x", ip->type); } printf("\n");}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?