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

📄 ini910u.c

📁 This directory contains the miniport driver for INI-9100U/UW PCI_UltraSCSI Bus Master Controllers. T
💻 C
📖 第 1 页 / 共 5 页
字号:
char    mod_ALTPD(hcsp, tcsp)
register HCS    *hcsp;
register TCS    *tcsp;
{
    TUL_WR(hcsp->Base + TUL_SConfig, tcsp->sConfig);
    return 1;
}


/**************** tulip_scsi rtn *************************************/
char    tulip_scsi(hcsp)
register HCS    *hcsp;
{
    register TULSCB    *scbp;
    register TCS    *tcsp;
    UBYTE readByte;
    int    rtn;
    hcsp->JSStatus0 = TUL_RD(hcsp->Base, TUL_SStatus0);
    if (hcsp->JSStatus0 & TSS_INT_PENDING) {
        if (hcsp->JSInt = (TUL_RD(hcsp->Base, TUL_SInt)) ) {
            hcsp->Phase = hcsp->JSStatus0 & TSS_PH_MASK;
            hcsp->JSStatus1 = TUL_RD(hcsp->Base, TUL_SStatus1);
            if (hcsp->JSInt & TSS_SCSIRST_INT) {
                /* if SCSI bus reset detected */
                int_scsi_rst(hcsp);
                return 0;
            }
            /* Happens when msg_accept SCSI cmd 0xF find out bus free */
            if (hcsp->JSInt & TSS_DISC_INT) {
                return 0;
            }
            if (hcsp->JSInt & TSS_RESEL_INT) {
                /* if selected/reselected interrupt */
                int_resel(hcsp);
                return 0;
            }
            if (hcsp->JSInt & TSS_SEL_TIMEOUT) {
                /* if selected/reselected timeout interrupt */
                int_busfree(hcsp);
                return 0;
            }
            if (hcsp->JSInt & (TSS_FUNC_COMP | TSS_BUS_SERV)) {

                if ( (scbp = hcsp->ActScb)  != 0) {
                    next_state(hcsp, scbp);
                }
                return 1;
            }
            /* if selected  or scam selected*/
            TUL_WR( hcsp->Base + TUL_SSignal, 0);
        }
    }


    if (hcsp->ActScb != 0) {
        return 1;
    }

    if ( (scbp = hcsp->FirstPend) == NULL) {
        return 1;
    }

    tcsp = &hcsp->Tcs[scbp->Target];
    /* program HBA's SCSI ID & target SCSI ID */
    TUL_WR( hcsp->Base + TUL_SScsiId,
        (hcsp->HaId << 4) | (scbp->Target & 0x0F) );

    if (scbp->Opcode == ExecSCSI) {


        mod_ALTPD(hcsp, tcsp);
        TUL_WR(hcsp->Base + TUL_SPeriodOffset, tcsp->JS_PeriodOffset);

        if ( (tcsp->Flags & (TCF_WDTR_DONE | TCF_NO_WDTR)) == 0) {
            /* do wdtr negotiation */
            select_atn_stop(hcsp, scbp);
        } else if ( (tcsp->Flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) == 0) {
            /* do sync negotiation */
            select_atn_stop(hcsp, scbp);
        } else {
            if (scbp->TagMsg) {
                select_atn3(hcsp, scbp);
            } else {
                select_atn(hcsp, scbp);
            }
        }

        if (scbp->Flags & SCF_POLL) {
            while (wait_tulip(hcsp) != -1) {
                if ( next_state(hcsp, scbp) == -1)
                    break;
            }
        }
    } else if (scbp->Opcode == BusDevRst) {
        select_atn_stop(hcsp, scbp);
        scbp->NxtStat = 8;
        if (scbp->Flags & SCF_POLL) {
            while (wait_tulip(hcsp) != -1) {
                if (next_state(hcsp, scbp) == -1)
                    break;
            }
        }
    } else if (scbp->Opcode == AbortCmd ) {
        select_atn_stop(hcsp, scbp);
        if (scbp->Flags & SCF_POLL) {
            while (wait_tulip(hcsp) != -1) {
                if (next_state(hcsp, scbp) == -1)
                    break;
            }
        }
    } else {
        ll_pop_pend_scb(hcsp);
        scbp->Status = TULSCB_DONE;        /* done */
        scbp->HaStat = 0x16;    /* bad command */
        ll_append_done_scb(hcsp, scbp);
    }
    return 0;
}



/***************** next_state rtn *****************************/
char    next_state(hcsp, scbp)
register HCS    *hcsp;
register TULSCB *scbp;
{
UCHAR     xfrPeriod[8] = {   /* fast 20 */
    /* nanosecond devide by 4 */
    12,              /* 50ns,  20M       */
    18,              /* 75ns,  13.3M */
    25,              /* 100ns, 10M   */
    31,              /* 125ns, 8M    */
    37,              /* 150ns, 6.6M  */
    43,              /* 175ns, 5.7M  */
    50,              /* 200ns, 5M    */
    62               /* 250ns, 4M    */
};

    TCS     * tcsp;
    UBYTE   tar;
    ULONG_PTR   TulSCmd, TulSFifo;
    long    i, cnt, xcnt, fifoCnt;
    char    phase;
    UCHAR   sta, ctrl;
    UCHAR readByte;
    TULSCB  * pTmpScb;


    tcsp = hcsp->ActTcs;
    TulSCmd =  hcsp->Base + TUL_SCmd;
    TulSFifo = hcsp->Base + TUL_SFifo;

    switch (scbp->NxtStat) {
    case 1:
        if (scbp != ll_pop_pend_scb(hcsp)) {
            TulPanic("case1: scbp != ll_pop_pend_scb(hcsp)\n");
        }
        scbp->Status = TULSCB_BUSY;
        ll_append_busy_scb(hcsp, scbp);
        if (hcsp->Phase == MSG_OUT) {
            if (scbp->Opcode == AbortCmd) {
                if (scbp->TagMsg == 0) {
                    msgout_abort(hcsp);
                } else
                 {
                    msgout_abort_tag(hcsp);
                }
                return 3;
            } else
             {
                /* enable BUS */
                TUL_WR(hcsp->Base + TUL_SCtrl1, TSC_EN_BUS_IN);

                /* send out identify message */
                TUL_WR(hcsp->Base + TUL_SFifo, scbp->Ident);
                if (scbp->TagMsg != 0) {
                    TUL_WR(TulSFifo, scbp->TagMsg);
                    TUL_WR(TulSFifo, scbp->TagId);
                }

                if ((tcsp->Flags & (TCF_WDTR_DONE | TCF_NO_WDTR)) == 0) {
                    tcsp->Flags |= TCF_WDTR_DONE;
                    TUL_WR(TulSFifo, MSG_EXTEND);
                    TUL_WR(TulSFifo, 2); /* extended msg length */
                    TUL_WR(TulSFifo, 3);     /* sync request */
                    TUL_WR(TulSFifo, 1);     /* start from 16bit xfer */
                } else
                 {
                    if ((tcsp->Flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) == 0 ) {
                        tcsp->Flags |= TCF_SYNC_DONE;
                        TUL_WR(TulSFifo, MSG_EXTEND);
                        TUL_WR(TulSFifo, 3); /* extended msg length */
                        TUL_WR(TulSFifo, 1); /* sync request */

                        TUL_WR(TulSFifo, xfrPeriod[tcsp->xfrPeriodIdx]);
                        TUL_WR(TulSFifo, MAX_OFFSET); /* REQ/ACK offset */
                    }
                }
                TUL_WR(TulSCmd, TSC_XF_FIFO_OUT);
                if (wait_tulip(hcsp) == -1)
                    return - 1;
                TUL_WR(hcsp->Base + TUL_SCtrl0,  TSC_FLUSH_FIFO);
                readByte = TUL_RD(hcsp->Base, TUL_SSignal);
                TUL_WR( hcsp->Base + TUL_SSignal, readByte & 0x47);
                goto state_3;
            }
        } else
         {
            /* not MSG_OUT phase, ATN on */
            TUL_WR( hcsp->Base + TUL_SCtrl0,  TSC_FLUSH_FIFO);
            readByte = TUL_RD(hcsp->Base, TUL_SSignal);
            TUL_WR( hcsp->Base + TUL_SSignal, readByte & 0x47);
            goto state_3;
        }
        break;
    case 2:
        if (scbp != ll_pop_pend_scb(hcsp)) {
            TulPanic("case2: scbp != ll_pop_pend_scb(hcsp)\n");
        }
        scbp->Status = TULSCB_BUSY;

        ll_append_busy_scb(hcsp, scbp);

        hcsp->JSStatus1 = TUL_RD( hcsp->Base, TUL_SStatus1);
        if (hcsp->JSStatus1 & TSS_CMD_PH_CMP) {
            goto state_4;
        }
        TUL_WR(hcsp->Base + TUL_SCtrl0,  TSC_FLUSH_FIFO);
        readByte = TUL_RD(hcsp->Base, TUL_SSignal);
        TUL_WR( hcsp->Base + TUL_SSignal, readByte & 0x47);
        goto state_3;

    case 3:
state_3:
        phase = hcsp->Phase;
        for (; ; ) {
            switch (phase) {
            case CMD_OUT:       /* Command phase                */
                for ( i = 0; i < (int)scbp->CDBLen; i++) {
                    TUL_WR( TulSFifo, scbp->CDB[i]);
                }
                TUL_WR(TulSCmd, TSC_XF_FIFO_OUT);
                if ((phase = wait_tulip(hcsp)) == -1)
                    return phase;
                if (phase == CMD_OUT) {
                    return  bad_seq(hcsp);
                }
                goto state_4;
            case MSG_IN:        /* Message in phase             */
                scbp->NxtStat = 0x3;
                if ((phase =  msgin(hcsp, scbp)) == -1)
                    return - 1;
                break;
            case STATUS:        /* Status phase                 */
                if ((phase =  status_msg(hcsp, scbp)) == -1) {
                    return - 1;
                }
                break;
            case MSG_OUT:       /* Message out phase            */
                if ((tcsp->Flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) == 0 ) {
                    tcsp->Flags |= TCF_SYNC_DONE;
                    TUL_WR(TulSFifo, MSG_EXTEND);
                    TUL_WR(TulSFifo, 3); /* extended msg length */
                    TUL_WR(TulSFifo, 1); /* sync request */

                    TUL_WR(TulSFifo, xfrPeriod[tcsp->xfrPeriodIdx]);
                    TUL_WR(TulSFifo, MAX_OFFSET); /* REQ/ACK offset */

                    TUL_WR(TulSCmd, TSC_XF_FIFO_OUT);
                    if ((phase = wait_tulip(hcsp)) == -1)
                        return - 1;
                    TUL_WR(hcsp->Base + TUL_SCtrl0,  TSC_FLUSH_FIFO);
                    readByte = TUL_RD(hcsp->Base, TUL_SSignal);
                    TUL_WR( hcsp->Base + TUL_SSignal, readByte & 0x47);
                } else {
                    if ((phase =  msgout_nop(hcsp)) == -1)
                        return - 1;
                }
                break;
            default:
                return  bad_seq(hcsp);
            }
        } /* for */

    case 4:
state_4:
        if ((scbp->Flags & SCF_DIR) == SCF_NO_XF) {
            goto state_6;
        }

        phase = hcsp->Phase;
        for (; ; ) {
            if (scbp->BufLen == 0) {
                goto state_6;
            }
            switch (phase) {
            case DATA_IN:       /* Data in phase                */
                return  xfer_data_in(hcsp, scbp);
            case DATA_OUT:      /* Data out phase               */
                return  xfer_data_out(hcsp, scbp);
            case MSG_IN:        /* Message in phase             */
                scbp->NxtStat = 0x4;
                if ((phase =  msgin(hcsp, scbp)) == -1)
                    return phase;
                break;
            case STATUS:        /* Status phase                 */
                if ((phase = status_msg(hcsp, scbp)) == -1) {
                    if ( (!(scbp->Mode & SCM_RSENS)) &&
                        (!(scbp->TaStat == TARGET_BUSY)) ) {
                        /* not in auto req sense modeand target not busy*/
                        if (scbp->Srb->DataTransferLength -= scbp->BufLen)
                            if ((scbp->Flags & SCF_DIR) != SCF_NO_DCHK)
                                scbp->HaStat = HOST_DO_DU;    /* 10/21/97    */
                    }

                    return phase;
                }
                break;
            case MSG_OUT:       /* Message out phase            */
                if ( hcsp->JSStatus0 & TSS_PAR_ERROR ) {
                    scbp->BufLen = 0;
                    scbp->HaStat = HOST_DO_DU;
                    if ((phase =  msgout_ide(hcsp)) == -1)
                        return phase;
                    goto state_6;
                } else
                 {
                    if ((phase =  msgout_nop(hcsp)) == -1)
                        return phase;
                }
                break;
            default:
                return  bad_seq(hcsp);
            }
        }

    case 5:
        cnt = TUL_RDLONG(hcsp->Base, TUL_SCnt0) & 0xffffff;

        /************** DMA direction == DATA_IN **************************/
        if (TUL_RD(hcsp->Base, TUL_XCmd) & 0x20) { /* check direction */
            if ( hcsp->JSStatus0 & TSS_PAR_ERROR ) {
                scbp->HaStat = HOST_DO_DU;
            }
            /*data underrun: when mode
            sense cmd (0x1A) request 192 byte, but target drive xfer
            146 byte then change phase to STATUS, in this case, we need
            to clean up the DMA xfer  */
            sta = TUL_RD(hcsp->Base, TUL_XStatus);
            if ((sta & XPEND)) {               /* DMA xfer pending */

                /* force DMA xfer the left over bytes */
                ctrl = TUL_RD(hcsp->Base, TUL_XCtrl);
                TUL_WR(hcsp->Base + TUL_XCtrl, ctrl | 0x80 );  /* set bit 7 */
                /* wait until DMA xfer not pending */
                while ( (sta = TUL_RD(hcsp->Base, TUL_XStatus)) & XPEND ) {
                }
                TUL_WR(hcsp->Base + TUL_XCtrl, ctrl);  /* clear bit 7*/

            }       /* if (sta & XPEND) : DMA xfer pending */

        } else
         {
            /************** DMA direction == DATA OUT *******************/
            if (!(TUL_RD(hcsp->Base, TUL_SStatus1) & TSS_XFER_CMP)) {
                fifoCnt = TUL_RD(hcsp->Base, TUL_SFifoCnt) & 0x1f;
                if (tcsp->JS_PeriodOffset & TSC_WIDE_SCSI)
                    fifoCnt = fifoCnt << 1;
                cnt += fifoCnt;
                TUL_WR(hcsp->Base + TUL_SCtrl0,   TSC_FLUSH_FIFO);
            }

            /* st5_xfer_done: */
            /* if DMA xfer is pending, abort DMA xfer */
            if (TUL_RD(hcsp->Base, TUL_XStatus) & XPEND) {
                ULONG countdown = 500;
                /* ----------- ABORT ----------------------*/
/*                TUL_WR(hcsp->Base + TUL_XCmd, TAX_X_ABT | TAX_X_CLR_FIFO);*/
                TUL_WR(hcsp->Base + TUL_XCmd, TAX_X_ABT); /* 02/26/98 */
                /* wait Abort DMA xfer done */
                while (((TUL_RD(hcsp->Base, TUL_Int) & XABT) == 0) &&
                       (countdown != 0)) {
                    ScsiPortStallExecution(1);
                    countdown--;
                }
                if(countdown == 0) {
                    DebugPrint((0, "initio::nextstate - XABT bit was never set\n"));
                }
            }
        } /* DMA direction == DATA_OUT */

        xcnt = scbp->BufLen - cnt;
        scbp->BufLen = cnt;/* left byte cnt to be xfer */

        if (scbp->BufLen == 0) {
            goto state_6;
        }
        if (scbp->Flags & SCF_SG) {
            register SG *sgp;
            ULONG       i;

            sgp = &scbp->SGList[scbp->SGIdx];
            for (i = scbp->SGIdx; i < scbp->SGMax; sgp++, i++) {
                xcnt -= sgp->Len;
                if (xcnt < 0) {
                    xcnt += sgp->Len;
                    sgp->Ptr += (ULONG)xcnt;
                    sgp->Len -= (ULONG)xcnt;
                    scbp->BufPtr += ((ULONG)(i - scbp->SGIdx) << 3);
                    scbp->SGLen = (UBYTE)(scbp->SGMax - i);
                    scbp->SGIdx = (UWORD)i;
                    goto state_4;
                }
            } /* for */

            goto state_6;
        } else
         {
            scbp->BufPtr += xcnt;
        }
        goto state_4;

    case 6:
state_6:
        phase = hcsp->Phase;
        for (; ; ) {
            switch (phase) {
            case MSG_IN:
                scbp->NxtStat = 0x6;
                if ((phase  =  msgin(hcsp, scbp)) == -1)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -