⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ini910u.c

📁 This directory contains the miniport driver for INI-9100U/UW PCI_UltraSCSI Bus Master Controllers. T
💻 C
📖 第 1 页 / 共 5 页
字号:
                    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 + -