📄 ini910u.c
字号:
return phase;
break;
case STATUS:
if ((phase = status_msg(hcsp, scbp)) == -1)
return phase;
break;
case MSG_OUT:
if ((phase = msgout_nop(hcsp)) == -1)
return phase;
break;
case DATA_IN:
phase = xfer_pad_in(hcsp, scbp);
break;
case DATA_OUT:
phase = xfer_pad_out(hcsp, scbp);
break;
default:
return bad_seq(hcsp);
}
} /* for */
case 7: /* After xfer pad */
if ( (cnt = TUL_RD(hcsp->Base, TUL_SFifoCnt) & 0x1F) != 0) {
for (i = 0; i < cnt; i++) /* flush SCSI FIFO */
TUL_RD(hcsp->Base, TUL_SFifo);
}
phase = hcsp->Phase;
if ((phase == DATA_IN) || (phase == DATA_OUT)) {
return bad_seq(hcsp);
}
goto state_6;
case 8: /* bus device reset */
if ((hcsp->Phase) != MSG_OUT) {
return bad_seq(hcsp);
}
TUL_WR(TulSFifo, MSG_DEVRST);
TUL_WR(TulSCmd, TSC_XF_FIFO_OUT);
scbp->HaStat = 0;
scbp->Status = TULSCB_DONE; /* command done */
tcsp = hcsp->ActTcs;
tcsp->Flags &= ~(TCF_SYNC_DONE | TCF_WDTR_DONE);
tcsp->JS_PeriodOffset = 0;
tar = scbp->Target; /* target */
/* abort all SCB with same target */
pTmpScb = hcsp->FirstBusy;
while (pTmpScb != NULL) {
if (pTmpScb->Status & TULSCB_BUSY) {
if (pTmpScb->Target == tar) {
pTmpScb->HaStat = 0x1C;
pTmpScb->Status = TULSCB_DONE; /* command done */
}
}
pTmpScb = (PTULSCB)(pTmpScb->NextScb);
}
if (wait_tulip(hcsp) != -1) {
return bad_seq(hcsp);
}
return - 1;
default:
return bad_seq(hcsp);
}/* switch */
}
/****** xfer_data_in rtn **************************************/
char xfer_data_in(hcsp, scbp)
register HCS *hcsp;
register TULSCB *scbp;
{
TUL_WRLONG(hcsp->Base + TUL_SCnt0, scbp->BufLen);
if (scbp->Flags & SCF_SG) { /* S/G xfer */
TUL_WRLONG(hcsp->Base + TUL_XCntH, ((ULONG)scbp->SGLen) << 3);
TUL_WRLONG(hcsp->Base + TUL_XAddH, scbp->BufPtr);
TUL_WR(hcsp->Base + TUL_XCmd, TAX_SG_IN);
} else {
TUL_WRLONG(hcsp->Base + TUL_XCntH, scbp->BufLen);
TUL_WRLONG(hcsp->Base + TUL_XAddH, scbp->BufPtr);
TUL_WR(hcsp->Base + TUL_XCmd, TAX_X_IN);
}
TUL_WR(hcsp->Base + TUL_SCmd, TSC_XF_DMA_IN);
scbp->NxtStat = 0x5;
return 0;
}
/****************** xfer_data_out rtn *******************************/
char xfer_data_out(hcsp, scbp)
register HCS *hcsp;
register TULSCB *scbp;
{
TUL_WRLONG(hcsp->Base + TUL_SCnt0, scbp->BufLen);
if (scbp->Flags & SCF_SG) { /* S/G xfer */
TUL_WRLONG(hcsp->Base + TUL_XCntH, ((ULONG)scbp->SGLen) << 3);
TUL_WRLONG(hcsp->Base + TUL_XAddH, scbp->BufPtr);
TUL_WR(hcsp->Base + TUL_XCmd, TAX_SG_OUT);
} else {
TUL_WRLONG(hcsp->Base + TUL_XCntH, scbp->BufLen);
TUL_WRLONG(hcsp->Base + TUL_XAddH, scbp->BufPtr);
TUL_WR(hcsp->Base + TUL_XCmd, TAX_X_OUT);
}
TUL_WR(hcsp->Base + TUL_SCmd, TSC_XF_DMA_OUT);
scbp->NxtStat = 0x5;
return 0;
}
/***************** xfer_pad_in rtn **********************************/
char xfer_pad_in(hcsp, scbp)
register HCS *hcsp;
register TULSCB *scbp;
{
ULONG_PTR TulSCmd, TulSFifo;
ULONG cnt, i = 0;
char phase;
TCS * tcsp;
UCHAR readByte;
TulSCmd = hcsp->Base + TUL_SCmd;
TulSFifo = hcsp->Base + TUL_SFifo;
tcsp = &hcsp->Tcs[scbp->Target];
phase = TUL_RD(hcsp->Base, TUL_SSignal) & 0x07;
while (phase == DATA_IN) {
if ((scbp->Flags & SCF_DIR) != SCF_NO_DCHK) {
scbp->HaStat = HOST_DO_DU; /* over run */
}
cnt = 1;
if (tcsp->JS_PeriodOffset & TSC_WIDE_SCSI)
cnt = cnt << 1;
TUL_WRLONG(hcsp->Base + TUL_SCnt0, cnt );
TUL_WR(TulSCmd, TSC_XF_FIFO_IN);
if ((phase = wait_tulip(hcsp)) == -1)
return phase;
readByte = TUL_RD(hcsp->Base, TUL_SFifo);
phase = TUL_RD(hcsp->Base, TUL_SSignal) & 0x07;
} /* while (phase == DATA_IN)) */
TUL_WR(hcsp->Base + TUL_SCtrl0, TSC_FLUSH_FIFO); /* flush SCSI FIFO */
return phase;
}
/***************** xfer_pad_out rtn **********************************/
char xfer_pad_out(hcsp, scbp)
register HCS *hcsp;
register TULSCB *scbp;
{
ULONG_PTR TulSCmd, TulSFifo;
TCS * tcsp;
char phase;
int i;
phase = TUL_RD(hcsp->Base, TUL_SSignal) & 0x07;
while (phase == DATA_OUT) {
TulSCmd = hcsp->Base + TUL_SCmd;
TulSFifo = hcsp->Base + TUL_SFifo;
if ((scbp->Flags & SCF_DIR) != SCF_NO_DCHK) {
scbp->HaStat = HOST_DO_DU; /* over run */
}
tcsp = &hcsp->Tcs[scbp->Target];
if (tcsp->JS_PeriodOffset & TSC_WIDE_SCSI) {
TUL_WRLONG(hcsp->Base + TUL_SCnt0, 0x2 );
} else {
TUL_WRLONG(hcsp->Base + TUL_SCnt0, 0x1);
}
TUL_WR(TulSFifo, 0);
TUL_WR(TulSCmd, TSC_XF_FIFO_OUT);
if ((phase = wait_tulip(hcsp)) == -1)
return phase;
/* wait xfer_pad done or phase change */
phase = TUL_RD(hcsp->Base, TUL_SSignal) & 0x07;
} /* if (phase == DATA_OUT) */
TUL_WR(hcsp->Base + TUL_SCtrl1, TSC_HW_RESELECT ) ;/* Enable HW reselect */
TUL_WR(hcsp->Base + TUL_SCtrl0, TSC_FLUSH_FIFO); /* flush SCSI FIFO */
return phase;
}
/**************** status_msg rtn ***************************/
char status_msg(hcsp, scbp) /* status & MSG_IN */
register HCS *hcsp;
register TULSCB *scbp;
{
char phase;
UBYTE msg;
ULONG_PTR TulSCmd;
UCHAR readByte;
TulSCmd = hcsp->Base + TUL_SCmd;
TUL_WR(TulSCmd, TSC_CMD_COMP);
if ((phase = wait_tulip(hcsp)) == -1) {
return - 1;
}
/* get status */
scbp->TaStat = TUL_RD(hcsp->Base, TUL_SFifo);
hcsp->JSStatus0 = TUL_RD(hcsp->Base, TUL_SStatus0);
hcsp->Phase = hcsp->JSStatus0 & TSS_PH_MASK;
if (hcsp->Phase == MSG_IN) {
/* handle MSG_IN phase */
if (hcsp->JSStatus0 & TSS_PAR_ERROR) {
/*------------------ parity_err: ------------------*/
if ((phase = msg_accept(hcsp)) == -1) {
return phase;
}
if (phase != MSG_OUT) {
return bad_seq(hcsp);
} else {
TUL_WR(hcsp->Base + TUL_SFifo, MSG_PARITY);
TUL_WR(TulSCmd, TSC_XF_FIFO_OUT);
return wait_tulip(hcsp);
}
}
if ( (msg = TUL_RD(hcsp->Base, TUL_SFifo)) == 0) {/* command complete */
if (( scbp->TaStat & 0x18) == 0x10 ) {
return bad_seq(hcsp); /* no link support */
}
hcsp->Flags |= HCF_EXPECT_DISC;
if ((phase = msg_accept(hcsp)) != -1)
return bad_seq(hcsp);
ll_unlink_busy_scb(hcsp, scbp);
scbp->Status = TULSCB_DONE;
ll_append_done_scb(hcsp, scbp);
return - 1;
} else {
/*--------------------- chk_link_msg: ---------------*/
if ((msg != MSG_LINK_COMP) && (msg != MSG_LINK_FLAG)) {
return bad_seq(hcsp);
} else { /* link_msg */
if (( scbp->TaStat & 0x18) != 0x10 )
return bad_seq(hcsp); /* bad link msg */
return msg_accept(hcsp);
}
}
} else {
if (hcsp->Phase != MSG_OUT) {
return bad_seq(hcsp);
}
if (hcsp->JSStatus0 & TSS_PAR_ERROR) {
TUL_WR(hcsp->Base + TUL_SFifo, MSG_PARITY);
} else {
TUL_WR(hcsp->Base + TUL_SFifo, MSG_NOP);
}
TUL_WR(TulSCmd, TSC_XF_FIFO_OUT);
return wait_tulip(hcsp);
}
}
/******************* int_resel rtn *************************/
/* scsi reselection */
int int_resel(hcsp)
register HCS *hcsp;
{
int phase = 0;
UWORD tar, lun;
UBYTE msg;
UWORD tarlun, scbp_tarlun;
register TULSCB *scbp;
TCS * tcsp;
ULONG_PTR TulSCmd;
UBYTE readByte;
TulSCmd = hcsp->Base + TUL_SCmd;
if ((scbp = hcsp->ActScb) != NULL) {
if (scbp->Status & TULSCB_SELECT) {
scbp->Status &= ~TULSCB_SELECT;
}
hcsp->ActScb = NULL;
}
/* ------------no active SCB, get target id-------- */
tar = TUL_RD(hcsp->Base, TUL_SBusId);
tar &= 0x0F;
/* ---------- check if parity err ---------------- */
if (hcsp->JSStatus0 & TSS_PAR_ERROR) {
if ((phase = msgin_par_err(hcsp, scbp)) == -1)
return - 1;
}
/*--------------- get ident ---------------------*/
/* get LUN from Identify message */
msg = TUL_RD(hcsp->Base, TUL_SIdent);
lun = msg & 0x1F; /* 10/21/97 & 0x7; */
tarlun = tar | lun << 8;
tcsp = &hcsp->Tcs[tar];
mod_ALTPD(hcsp, tcsp);
TUL_WR(hcsp->Base + TUL_SPeriodOffset, tcsp->JS_PeriodOffset);
/* ------------- tag queueing ? ------------------- */
msg = 0;
if (tcsp->Flags & TCF_EN_TAG) {
/*------------ get Tag msg ------------------------*/
if ((phase = msg_accept(hcsp)) == -1)
return phase;
if (phase == MSG_IN) {
TUL_WRLONG(hcsp->Base + TUL_SCnt0, 1);
TUL_WR(TulSCmd, TSC_XF_FIFO_IN);
if ((phase = wait_tulip(hcsp)) == -1)
return phase;
msg = TUL_RD(hcsp->Base, TUL_SFifo);
if ((phase = msg_accept(hcsp)) == -1)
return phase;
}
}
if (( MSG_STAG <= msg <= MSG_OTAG) && (phase == MSG_IN)) {
UBYTE tag;
/*------------ get Tag ID ------------------------*/
TUL_WRLONG(hcsp->Base + TUL_SCnt0, 1);
TUL_WR(TulSCmd, TSC_XF_FIFO_IN);
if ((phase = wait_tulip(hcsp)) == -1)
return phase;
tag = TUL_RD(hcsp->Base, TUL_SFifo);
/* accept tagId */
if ((phase = msg_accept(hcsp)) == -1)
return phase;
if ( (scbp = ll_find_tagid_busy_scb(hcsp, tarlun, tag)) == NULL) {
TulPanic("bug??");
}
scbp_tarlun = (scbp->Lun << 8) | scbp->Target;
if ( scbp_tarlun != tarlun) {
msgout_abort_tag(hcsp);
return - 1;
}
if ( scbp->Status != TULSCB_BUSY) { /* 3/24/95 */
msgout_abort_tag(hcsp);
return - 1;
}
} else /* no tag */
{
scbp = ll_find_busy_scb(hcsp, tarlun);
if (scbp == NULL) {
msgout_abort(hcsp);
return - 1;
}
if (!(tcsp->Flags & TCF_EN_TAG)) {
if ((phase = msg_accept(hcsp)) == -1)
return phase;
}
}
hcsp->ActTcs = tcsp;
hcsp->ActScb = scbp;
next_state(hcsp, scbp);
return phase;
}
/***************************************************************************/
int msgin_par_err(hcsp, scbp)
register HCS *hcsp;
register TULSCB *scbp;
{
ULONG_PTR TulSCmd;
char phase = 0;
TulSCmd = hcsp->Base + TUL_SCmd;
TUL_WR(hcsp->Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
if ((phase = msg_accept(hcsp)) == -1)
return phase;
if (phase == MSG_OUT) {
TUL_WR(hcsp->Base + TUL_SFifo, MSG_PARITY);
TUL_WR(TulSCmd, TSC_XF_FIFO_OUT);
if ((phase = wait_tulip(hcsp)) == -1)
return phase;
if (phase == MSG_IN) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -