📄 aspidriver.cpp
字号:
unsigned pf : 1; //SCSI1 or standard ?
unsigned lun : 3; //logical unit number
unsigned _reserved2 : 8; //n/a
unsigned _reserved3 : 8; //n/a
*/
return RunCommand(&exec); //send it..
}
/*\
*<------------ DisplaySense ------------>
@m create a displayable string from sense data
*--> I N <-- @p
* SRB_MyExecSCSICmd *p - scsi request block
*/
void CASPIDriver::DisplaySense (SRB_MyExecSCSICmd *p)
{
if (p->SenseArea[0])
{
m_strSense.Format ("Sense Data: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X",
p->SenseArea[0], p->SenseArea[1], p->SenseArea[2], p->SenseArea[3],
p->SenseArea[4], p->SenseArea[5], p->SenseArea[6], p->SenseArea[7],
p->SenseArea[8], p->SenseArea[9], p->SenseArea[10],p->SenseArea[11],
p->SenseArea[12],p->SenseArea[13],p->SenseArea[14]);
}
}
/*\
*<------------ RequestSense ------------>
@m request sense data
*--> I N <-- @p
* BYTE adapter_id - host adapter id
* BYTE device_id - device id
* BYTE lun - lun id
*<-- OUT --> @r
* DWORD - ASPIERROR_xxx defined in AspiDriver.h
*/
DWORD CASPIDriver::RequestSense (BYTE adapter_id,BYTE device_id,BYTE lun)
{
SRB_MyExecSCSICmd exec;
ZeroMemory (&exec,sizeof(SRB_MyExecSCSICmd));
TRACE ("ASPIsnoop: requesting sense data... ");
exec.SRB_Cmd = SC_EXEC_SCSI_CMD;
exec.SRB_HaId = adapter_id;
exec.SRB_Target = device_id;
exec.SRB_Lun = lun;
exec.SRB_Flags = SRB_DIR_IN;
exec.SRB_SenseLen = SENSE_LEN;
exec.SRB_CDBLen = 6;
exec.ccb.c6.cmd = SCSI_REQ_SENSE;
exec.ccb.c6.lun = lun;
return RunCommand(&exec); //send it..
}
/*\
*<------------ GetSenseString ------------>
@m get last sense return string
*--> I N <-- @p
* CString &str -
*/
void CASPIDriver::GetSenseString (CString &str)
{
str=m_strSense;
}
/*\
*<------------ GetError ------------>
@m get an error code from our request answer
*--> I N <-- @p
* SRB_MyExecSCSICmd *srb - pointer to scsi request block
*<-- OUT --> @r
* DWORD - ASPIERROR_xxx defined in AspiDriver.h
*/
DWORD CASPIDriver::GetError (SRB_MyExecSCSICmd *srb)
{
//
// -% Advanced Sense Codes, Advance Sense Code Qualifier, My Error-Code %-
//
//SCSI2 really likes to chat ;o]
//phew.... that list took 1 day...stupid type-work... fiddle in ANSI Dox ...
const int asc[][3]=
{
{ASC_FILMRK,ASQ_FILMRK,ASPIERR_FILEMRK}, {ASC_EOM,ASQ_EOM,ASPIERR_EOM},
{ASC_SETMRK,ASQ_SETMRK,ASPIERR_SETMRK}, {ASC_BOM,ASQ_BOM,ASPIERR_BOM},
{ASC_EOD,ASQ_EOD,ASPIERR_EOD}, {ASC_IOTERM,ASQ_IOTERM,ASPIERR_IOTERM},
{ASC_PWRTFLT,ASQ_PWRTFLT,ASPIERR_PWRTFLT}, {ASC_NOWRT,ASC_NOWRT,ASPIERR_NOWRITE},
{ASC_EWRTERR,ASQ_EWRTERR,ASPIERR_EWRTERR}, {ASC_LUNNRDNC,ASQ_LUNNRDNC,ASPIERR_LUNNRDNC},
{ASC_LUNBRD,ASQ_LUNBRD,ASPIERR_LUNBRD}, {ASC_LUNNRDIR,ASQ_LUNNRDIR,ASPIERR_LUNNRDIR},
{ASC_LUNNRDMI,ASQ_LUNNRDMI,ASPIERR_LUNNRDMI}, {ASC_LUNNRDFP,ASQ_LUNNRDFP,ASPIERR_LUNNRDFP},
{ASC_LUNNSEL,ASQ_LUNNSEL,ASPIERR_LUNNSEL}, {ASC_MULTSEL,ASQ_MULTSEL,ASPIERR_MULTSEL},
{ASC_LUNCFAIL,ASQ_LUNCFAIL,ASPIERR_LUNCFAIL}, {ASC_LUNCTIME,ASQ_LUNCTIME,ASPIERR_LUNCTIME},
{ASC_LUNCPAR,ASQ_LUNCPAR,ASPIERR_LUNCPAR}, {ASC_TRKFOLOW,ASQ_TRKFOLOW,ASPIERR_TRKFOLOW},
{ASC_LOGOVER,ASQ_LOGOVER,ASPIERR_LOGOVER}, {ASC_WRITE,ASQ_WRITE,ASPIERR_WRITE},
{ASC_URREAD,ASQ_URREAD,ASPIERR_URREAD}, {ASC_RDRETRY,ASQ_RDRETRY,ASPIERR_RDRETRY},
{ASC_TOOLONG,ASQ_TOOLONG,ASPIERR_TOOLONG}, {ASC_MULREAD,ASQ_MULREAD,ASPIERR_MULREAD},
{ASC_IBLKRD,ASQ_IBLKRD,ASPIERR_IBLKRD}, {ASC_NOGAP,ASQ_NOGAP,ASPIERR_NOGAP},
{ASC_MISCORR,ASQ_MISCORR,ASPIERR_MISCORR}, {ASC_RECENTI,ASQ_RECENTI,ASPIERR_RECENTI},
{ASC_RECORD,ASQ_RECORD,ASPIERR_RECORD}, {ASC_FILESET,ASQ_FILESET,ASPIERR_FILSET},
{ASC_NOEOD,ASQ_NOEOD,ASPIERR_NOEOD}, {ASC_BLKSEQ,ASQ_BLKSEQ,ASPIERR_BLKSEQ},
{ASC_RNDPOS,ASQ_RNDPOS,ASPIERR_RNDPOS}, {ASC_MECHPOS,ASQ_MECHPOS,ASPIERR_MECHPOS},
{ASC_RDPOSE,ASQ_RDPOSE,ASPIERR_RDPOSE}, {ASC_RECDNEC,ASQ_RECDNEC,ASPIERR_RECDNEC},
{ASC_RECDRET,ASQ_RECDRET,ASPIERR_RECDRET}, {ASC_RECDPHO,ASQ_RECDPHO,ASPIERR_RECDPHO},
{ASC_RECDNHO,ASQ_RECDNHO,ASPIERR_RECDNHO}, {ASC_RECDWEC,ASQ_RECDWEC,ASPIERR_RECDWEC},
{ASC_PARLLEN,ASQ_PARLLEN,ASPIERR_PARLLEN}, {ASC_SYNCERR,ASQ_SYNCERR,ASPIERR_SYNCERR},
{ASC_INVCOC,ASQ_INVCOC,ASPIERR_INVCOC}, {ASC_LBARNG,ASQ_LBARNG,ASPIERR_LBARNG},
{ASC_INVFCDB,ASQ_INVFCDB,ASPIERR_INVFCDB}, {ASC_NOLOGUN,ASQ_NOLOGUN,ASPIERR_NOLOGUN},
{ASC_INVFPL,ASQ_INVFPL,ASPIERR_INVFPL}, {ASC_PARNSUP,ASQ_PARNSUP,ASPIERR_PARNSUP},
{ASC_PARVINV,ASQ_PARVINV,ASPIERR_PARVINV}, {ASC_NTHRPAR,ASQ_NTHRPAR,ASPIERR_NTHRPAR},
{ASC_WRTPROT,ASQ_WRTPROT,ASPIERR_WRTPROT}, {ASC_NRDYRDY,ASQ_NRDYRDY,ASPIERR_NRDYRDY},
{ASC_POWRON,ASQ_POWRON,ASPIERR_POWRON}, {ASC_PARCHN,ASQ_PARCHN,ASPIERR_PARCHN},
{ASC_MPARCHN,ASQ_MPARCHN,ASPIERR_MPARCHN}, {ASC_LPARCHN,ASQ_LPARCHN,ASPIERR_LPARCHN},
{ASC_NCPYDIS,ASQ_NCPYDIS,ASPIERR_NCPYDIS}, {ASC_CMDSEQ,ASQ_CMDSEQ,ASPIERR_CMDSEQ},
{ASC_CMDCLR,ASQ_CMDCLR,ASPIERR_CMDCLR}, {ASC_INCPMED,ASQ_INCPMED,ASPIERR_INCPMED},
{ASC_CANTRDU,ASQ_CANTRDU,ASPIERR_CANTRDU}, {ASC_CANTRDI,ASQ_CANTRDI,ASPIERR_CANTRDI},
{ASC_CLNCARD,ASQ_CLNCARD,ASPIERR_CLNCARD}, {ASC_MFRMCRP,ASQ_MFRMCRP,ASPIERR_MFRMCRP},
{ASC_TAPELEN,ASQ_TAPELEN,ASPIERR_TAPELEN}, {ASC_RNDPAR,ASQ_RNDPAR,ASPIERR_RNDPAR},
{ASC_SAVPAR,ASQ_SAVPAR,ASPIERR_SAVPAR}, {ASC_NOTAPE,ASQ_NOTAPE,ASPIERR_NOTAPE},
{ASC_SEQPOS,ASQ_SEQPOS,ASPIERR_SEQPOS}, {ASC_POSBOM,ASQ_POSBOM,ASPIERR_POSBOM},
{ASC_POSEOM,ASQ_POSEOM,ASPIERR_POSEOM}, {ASC_REPOS,ASQ_REPOS,ASPIERR_REPOS},
{ASC_INVBITS,ASQ_INVBITS,ASPIERR_INVBITS}, {ASC_LUNSCFG,ASQ_LUNSCFG,ASPIERR_LUNSCFG},
{ASC_TRGOCHG,ASQ_TRGOCHG,ASPIERR_TRGOCHG}, {ASC_CHGUC,ASQ_CHGUC,ASPIERR_CHGUC},
{ASC_CHGOD,ASQ_CHGOD,ASPIERR_CHGOD}, {ASC_CHGINQ,ASQ_CHGINQ,ASPIERR_CHGINQ},
{ASC_DGFAIL,ASQ_DGFAIL,ASPIERR_DGFAIL}, {ASC_MSGERR,ASQ_MSGERR,ASPIERR_MSGERR},
{ASC_INTTRGF,ASQ_INTTRGF,ASPIERR_INTTRGF}, {ASC_SELRESF,ASQ_SELRESF,ASPIERR_SELRESF},
{ASC_SFTRSTF,ASQ_SFTRSTF,ASPIERR_SFTRSTF}, {ASC_INDEMSG,ASQ_INDEMSG,ASPIERR_INDEMSG},
{ASC_INVMSGE,ASQ_INVMSGE,ASPIERR_INVMSGE}, {ASC_CMDPHSE,ASQ_CMDPHSE,ASPIERR_CMDPHSE},
{ASC_DATPHSE,ASQ_DATPHSE,ASPIERR_DATPHSE}, {ASC_LGUFSLF,ASQ_LGUFSLF,ASPIERR_LGUFSLF},
{ASC_OVRCMD,ASQ_OVRCMD,ASPIERR_OVRCMD}, {ASC_WRTAPE,ASQ_WRTAPE,ASPIERR_WRTAPE},
{ASC_WRTAPSE,ASQ_WRTAPSE,ASPIERR_WRTAPSE}, {ASC_POSETIM,ASQ_POSETIM,ASPIERR_POSETIM},
{ASC_ERSFAIL,ASQ_ERSFAIL,ASPIERR_ERSFAIL}, {ASC_CRDFAIL,ASQ_CRDFAIL,ASPIERR_CRDFAIL},
{ASC_MDLFAIL,ASQ_MDLFAIL,ASPIERR_MDLFAIL}, {ASC_UNTAPF,ASQ_UNTAPF,ASPIERR_UNTAPF},
{ASC_MDRMPRV,ASQ_MDRMPRV,ASPIERR_MDRMPRV}, {ASC_OPERREQ,ASQ_OPERREQ,ASPIERR_OPERREQ},
{ASC_OPERMRR,ASQ_OPERMRR,ASPIERR_OPERMRR}, {ASC_OPERSWP,ASQ_OPERSWP,ASPIERR_OPERSWP},
{ASC_OPERSWE,ASQ_OPERSWE,ASPIERR_OPERSWE}, {ASC_LOGTRAP,ASQ_LOGTRAP,ASPIERR_LOGTRAP},
{ASC_THRCND,ASQ_THRCND,ASPIERR_THRCND}, {ASC_LGCNTMX,ASQ_LGCNTMX,ASPIERR_LGCNTMX},
{ASC_LGLSCDE,ASQ_LGLSCDE,ASPIERR_LGLSCDE}, {0,0,0}
};
TRACE ("ASPIsnoop: error: %02X %02X %02X\n",srb->SRB_Status,
srb->SRB_HaStat,
srb->SRB_TargStat);
switch (srb->SRB_Status) //check normal status byte
{
case SS_COMP: return ASPIERR_OK;
case SS_PENDING: return ASPIERR_PENDING;
case SS_ABORTED: return ASPIERR_ABORTED;
case SS_ABORT_FAIL: return ASPIERR_ABORTFAILED;
case SS_ERR:
if (srb->SRB_HaStat != HASTAT_OK) //
{
switch (srb->SRB_HaStat) //check host adapter status
{
case HASTAT_SEL_TO: return ASPIERR_SELTIMEOUT;
case HASTAT_DO_DU: return ASPIERR_OVERUNDER;
case HASTAT_BUS_FREE: return ASPIERR_BUSFREE;
case HASTAT_PHASE_ERR: return ASPIERR_PHASE;
case HASTAT_TIMEOUT: return ASPIERR_TIMEOUT;
case HASTAT_COMMAND_TIMEOUT: return ASPIERR_CMDTIMEOUT;
case HASTAT_MESSAGE_REJECT: return ASPIERR_REJECT;
case HASTAT_BUS_RESET: return ASPIERR_RESET;
case HASTAT_PARITY_ERROR: return ASPIERR_PARITY;
case HASTAT_REQUEST_SENSE_FAILED: return ASPIERR_SENSE;
}
}
else if (srb->SRB_TargStat)
{
switch (srb->SRB_TargStat) //check target status
{
case STATUS_CHKCOND:
if (srb->SRB_SenseLen && srb->SenseArea[0])
{
if (!((srb->SenseArea[12] == ASC_NOINFO) & (srb->SenseArea[13] == ASQ_NOINFO)))
{
BYTE basc=srb->SenseArea[12];
BYTE bascq=srb->SenseArea[13];
int i=0;
while (asc[i][2] != 0)
{
if (asc[i][0] == basc &&
asc[i][1] == bascq)
return asc[i][2];
i++;
};
TRACE ("WARNING: additional sense code %02X %02X not identified\n",basc,bascq);
return ASPIERR_UNKNOWN;
}
else
{
switch (srb->SenseArea[2]&0x0F)
{
case KEY_NOSENSE:
if (srb->SenseArea[2] & SENSE_FILEMRK)
return ASPIERR_FILEMRK;
else if (srb->SenseArea[2] & SENSE_EOM)
return ASPIERR_EOM;
else if (srb->SenseArea[2] & SENSE_ILI)
return ASPIERR_ILI;
TRACE ("WARNING: no sense data\n");
return ASPIERR_OK;
case KEY_RECERROR: return ASPIERR_RECOVERED;
case KEY_NOTREADY: return ASPIERR_NOTREADY;
case KEY_MEDIUMERR: return ASPIERR_MEDIUMERR;
case KEY_HARDERROR: return ASPIERR_HARDERR;
case KEY_ILLGLREQ: return ASPIERR_ILLEGAL;
case KEY_UNITATT: return ASPIERR_UNITATT;
case KEY_BLANKCHK: return ASPIERR_BLANKCHK;
case KEY_VENDSPEC: return ASPIERR_VENDOR;
case KEY_COPYABORT: return ASPIERR_COPYABORT;
case KEY_EQUAL: return ASPIERR_EQUAL;
case KEY_VOLOVRFLW: return ASPIERR_TAPEFULL;
case KEY_MISCOMP: return ASPIERR_MISCOMP;
case KEY_RESERVED: return ASPIERR_RESERVED;
}
}
}
else
return ASPIERR_CHKCOND;
break;
case STATUS_CONDMET: return ASPIERR_COMDMET;
case STATUS_INTERM: return ASPIERR_INTERM;
case STATUS_INTCDMET: return ASPIERR_INTCDMET;
case STATUS_RESCONF: return ASPIERR_RESCONF;
case STATUS_COMTERM: return ASPIERR_COMTERM;
case STATUS_QFULL: return ASPIERR_QFULL;
}
}
break;
case SS_INVALID_CMD: return ASPIERR_COMMAND;
case SS_INVALID_HA: return ASPIERR_HA;
case SS_NO_DEVICE: return ASPIERR_NODEVICE;
case SS_INVALID_SRB: return ASPIERR_SRB;
case SS_BUFFER_ALIGN: return ASPIERR_ALIGN;
case SS_SECURITY_VIOLATION: return ASPIERR_SECURE;
case SS_FAILED_INIT: return ASPIERR_INIT;
case SS_BUFFER_TO_BIG: return ASPIERR_SIZE;
}
TRACE ("WARNING: no error-description found at all\n");
return ASPIERR_UNKNOWN;
}
/*\
*<------------ Copy ------------>
@m copy a tape
*--> I N <-- @p
* BYTE src_adapter_id - host adapter id
* BYTE src_id - source device id
* BYTE src_lun - source lun id
* BYTE dst_id - destination device id
* BYTE dst_lun - destination lun id
* DWORD count - number of blocks - 0=all
*/
DWORD CASPIDriver::Copy ( BYTE src_adapter_id,
BYTE src_id,
BYTE src_lun,
BYTE dst_id,
BYTE dst_lun,
DWORD count)
{
SRB_MyExecSCSICmd exec;
DWORD code;
DWORD size;
CPY_para_head *head;
CPY_segment_desc *segd;
unsigned char *buffer;
size=sizeof(CPY_para_head)+sizeof(CPY_segment_desc);
buffer=new unsigned char [size];
ASSERT (buffer);
ZeroMemory (buffer,size);
head=(CPY_para_head *)buffer;
segd=(CPY_segment_desc *)(buffer+sizeof(CPY_para_head));
head->priority=0x00; //0 - high
head->code=0x04; //image copy
segd->source_lun=src_lun; //
segd->source_id=src_id; //
segd->dest_lun=dst_lun; //
segd->dest_id=dst_id; //
segd->count=count; //0 = all !
ZeroMemory (&exec,sizeof(SRB_MyExecSCSICmd));
TRACE ("ASPIsnoop: copy %d file marks... ",count);
exec.SRB_Cmd = SC_EXEC_SCSI_CMD;
exec.SRB_HaId = src_adapter_id;
exec.SRB_Target = src_id;
exec.SRB_Lun = src_lun;
exec.SRB_Flags = SRB_DIR_OUT;
exec.SRB_BufPointer = (unsigned char *)buffer;
exec.SRB_BufLen = size;
exec.SRB_SenseLen = SENSE_LEN;
exec.SRB_CDBLen = 6;
exec.ccb.cpy.cmd = SCSI_COPY;
//exec.ccb.cpy.pad = 0;
//exec.ccb.cpy.lun = src_lun;
exec.ccb.cpy.len_0 = (size & 0xff);
exec.ccb.cpy.len_1 = ((size>>8) & 0xff);
exec.ccb.cpy.len_2 = ((size>>16) & 0xff);
code=RunCommand(&exec); //send it..
delete [] buffer;
return code;
}
/*\
*<------------ Reserve ------------>
@m create a direct SCSI device interconnection
*--> I N <-- @p
* BYTE adapter_id - host adapter id
* BYTE device_id - device id
* BYTE lun - lun id
* BYTE dest_id - destination device id
*<-- OUT --> @r
* DWORD - ASPIERROR_xxx defined in AspiDriver.h
*/
DWORD CASPIDriver::Reserve (BYTE adapter_id,BYTE device_id,BYTE lun,BYTE dest_id)
{
SRB_MyExecSCSICmd exec;
ZeroMemory (&exec,sizeof(SRB_MyExecSCSICmd));
TRACE ("ASPIsnoop: reserve... ");
exec.SRB_Cmd = SC_EXEC_SCSI_CMD;
exec.SRB_HaId = adapter_id;
exec.SRB_Target = device_id;
exec.SRB_Lun = lun;
exec.SRB_Flags = SRB_DIR_OUT;
exec.SRB_SenseLen = SENSE_LEN;
exec.SRB_CDBLen = 6;
exec.ccb.rsv.cmd = SCSI_RESERVE;
exec.ccb.rsv.lun = lun;
exec.ccb.rsv.third_party_id = dest_id;
// exec.ccb.rsv.len_0 = (size & 0xff);
// exec.ccb.rsv.len_1 = ((size>>8) & 0xff);
return RunCommand(&exec); //send it..
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -