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

📄 pdma3min.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 4 页
字号:
	The SZ_DID_DMA flag in the softc structure will be set.  This informs	the driver that data xfers are taking place.	    NOTE: An opcode argument is passed to this routine mostly for the	    NCR 53c94.  Return:	PDMA_SUCCESS		 all is ready and ok 	PDMA_FAIL		 a fatal(?) problem has occured */int pmaz_ba_start( sc, targid, opcode )struct sz_softc *sc;	/* pointer to the softc structure */int targid;			/* current target ID */int opcode;			/* value to start the dma oper in the chip */    {    PDMA *pd;			/* pointer for the DMA control struct */    ASC_REG *ascaddr; 		/* pointer for the SCSI chip registers */    DMA_AR *ioasicp;		/* pointer for the SCSI DMA engine register */    DTENT *datp, *datep;	/* pointer to DAT table and individual entry */#ifdef PDMADEBUG    PRINTD( targid, ENTRYEXIT,         ("pmaz_ba_start: entry sc=0x%x targ=%d op=0x%x, ",sc, targid, opcode ));#endif  /* Initialize local variables. */    pd = &sc->pdma_ctrl[ targid ];		/* assign the pointer */#ifdef PDMADEBUG    PRINTD( targid, DETAILDAT, ("    dat_index=%d\n", pd->dat_index ));#endif    ascaddr = (ASCREG *)sc->sc_scsiaddr;	/* get the chip addr */    ioasicp = (DMA_AR *)sc->ioasicp;	/* engine address */    pd->opcode = opcode;		/* save for later use */  /* Load the information from the dma control structure for buffer 0 into    the SCSI chip and DMA engine. */    datp = (DTENT *)pd->dat_addr;    datep = (DTENT *)&(datp[pd->dat_index]);#ifdef PDMADEBUG    if ( scsidebug & DETAILDAT && ( targid==targmatch ) )         dumpent( datep );#endif    if ( datep->length==0 )	/* handle special case of padded xfer */	{        ASC_LOADCNTR(ascaddr, sc->sc_siidmacount[targid]);	/* load counter */        wbflush();				/* clear write buffer */        sc->sc_asccmd = ASC_DMA | ASC_XPAD ;         ascaddr->asc_cmd = sc->sc_asccmd;        sc->sc_szflags[ targid ] |= SZ_DID_DMA;        wbflush();				/* clear write buffer */        return PDMA_SUCCESS;	}    if ( datep->addr == 0 )        {        printf( "start: Invalid DAT entry.\n" );        dumpent( datep );        }    if ( is_local_xfer( pd ) && datep->dir == IOASIC_WRITE )        {        pd->pstate = PDMA_ACTIVE;        sc->sc_szflags[ targid ] |= SZ_DID_DMA | SZ_PIO_INTR;        asc_FIFOsenddata (sc, ASC_XINFO, datep->uadr, datep->length );        }    else        {	setscsictrl( sc, 0 );        if ( dmapload( sc, targid, datep->iadr ) == PDMA_FAIL )            {            printf( "pdma_start: Failure return from dmapload\n" );            return PDMA_FAIL;            }        ssrdmaon( sc, datep->dir );    #ifdef PDMADEBUG        PRINTD( targid, REGLOAD,             ("    start: loading ASC counter (base 0x%x) with length (%d)\n",            ascaddr, datep->length ));#endif        ASC_LOADCNTR(ascaddr, datep->length);	            wbflush();        sc->sc_asccmd = pd->opcode;           ascaddr->asc_cmd = pd->opcode;        wbflush();				/* clear write buffer */        }  /* Set the pstate to inform the driver that DMA is in progress. */    pd->pstate = PDMA_ACTIVE;    sc->sc_szflags[ targid ] |= SZ_DID_DMA;#ifdef PDMADEBUG    PRINTD( targid, ENTRYEXIT, ("pdma_start: exit\n"));#endif    return PDMA_SUCCESS;    }/* ---------------------------------------------------------------------- *//*int pdma_cont( sc, targid )Inputs:	sz_softc *sc;		 pointer to the softc structure 	int targid;		 current target ID Function:	Handle intermediate DMA functions during the transfer.  Return:	The number of bytes transfered sofar for this DMA operation.*/int pmaz_ba_cont( sc, targid )struct sz_softc *sc;	/* pointer to the softc structure */int targid;			/* current target ID */    {    PDMA *pd;			/* pointer for the DMA control struct */    ASC_REG *ascaddr; 		/* pointer for the SCSI chip registers */    DMA_AR *ioasicp;		/* pointer for the SCSI DMA engine register */    DTENT *datp, *datep;	/* pointer to DAT table and individual entry */    char *newbufp;		/* buffer pointer for use in DAT table adj.  */    int ecount;			/* used in DAT table rebuilding */    int tidx;			/* temporary index variable in DAT rebuild */    int	ffr;			/* value for the FIFO flags */    int dbcount;		/* number of bytes in IOASIC data buffer */    int	tcount;			/* corrected count for the ASC counters */    int lcount;			/* local count from the transfers */    int tmp1;    pd = &sc->pdma_ctrl[ targid ];	/* assign the pointer */#ifdef PDMADEBUG    PRINTD( targid, ENTRYEXIT,         ("pmaz_ba_cont: entry sc:%x targ:%d\n", sc, targid));    PRINTD( targid, ENTRYEXIT, ("    dat_index:%d\n", pd->dat_index ));#endif    ascaddr = (ASCREG *)sc->sc_scsiaddr;/* get the chip addr */    ioasicp = (DMAAR *)sc->ioasicp;	/* engine address */  /* First pull out the DAT table entry corresponding to this xfer */    datp = (DTENT *)pd->dat_addr;    datep = (DTENT *)&(datp[pd->dat_index]);#ifdef PDMADEBUG    if ( scsidebug & DETAILDAT && ( targid==targmatch ) )         dumpent( datep );#endif    if ( !(datep->length) )	/* handle special case of padded xfer */	{        sc->sc_szflags[ targid ] |= SZ_DID_DMA;        PRINTD( targid, PADTRACK, ("    cont:  padded xfer return: %d bytes\n",                pd->targcnt + sc->sc_siidmacount[targid] ));        return pd->targcnt + sc->sc_siidmacount[targid];	}  /* From the active buffers count and the SCSI chips actual xfer counter    register value, calc how much data was transfered.  Update the working    counter(s) for the return xfer count.  So far the SCSI chip counters    are all down counters, making the xfer count calc a simple subtaction.    The counters in the ASC have to be corrected for the # of bytes    left in the FIFO but not transferred when the target changed phase.    It should be noted that the 3min system (or possibly the softc struct)    exhibits a situation which should not occur; the TC bit in the status    register is set but the dma xfer counter is non-zero.  */    ssrdmaoff( sc );			/* turn off DMA */    ffr =  (int)ascaddr->asc_ffss;	/* get the fifo flags count */    ffr &= ASC_FIFO_MSK;		/* mask off sequ step bits */    ASC_GETCNTR(ascaddr, tcount);	/* get the counter value */    ASC_LOADCNTR(ascaddr, 0);	             /* JAG - force TC bit off */    wbflush();    dbcount = getdbcount( sc, datep->dir );  /* bytes stuck in IOASIC? */    if ( datep->dir==IOASIC_WRITE )  /* for RDAT bug */        lcount = datep->length - ffr;    else        lcount = datep->length;    if ( (lcount & 1) && dbcount )	/* if odd, then dbcount is off by 1 */        dbcount--;			/* RPS 03/28/91 */    if ( is_local_xfer( pd ) )        newbufp = datep->uadr + lcount;    else        newbufp = datep->addr + lcount;    if( pd->iodir == SZ_DMA_READ )        {        if ( dbcount )			/* data was left in the IOASIC     */            flushdb( sc, dbcount );#ifdef PDMADEBUG        if ( scsidebug & DUMPHEX && targid == targmatch )            {            if ( lcount > 0x40 )                {                dumphex(datep->addr, 0x20 );                dumphex(datep->addr+lcount-0x20, 0x20 );                }            else                 dumphex( datep->addr, lcount );            }#endif      /* If the operation is a DMA_IN: check for fragment buffer usage,         clean out that data if necessary, then determine if new DAT table         entries must be built or modified before continuing */        if ( is_local_xfer( pd ))	/* a local buffer was in addr?     */            {            flush_fragbuf( pd, lcount );            }        else				/* completed normally */            {            if ( IS_KUSEG( datep->addr ) )                panic("pdmacont(2): KUSEG address passwd in!\n" );            else                clean_dcache( PHYS_TO_K0( svtophy( datep->addr ) ),                     datep->length );            datep->completed = 1;	/* tag the entry complete */            pd->targcnt += datep->length;  /* bump transfer counter */            pd->dat_index++;            }      /* Load up the IOASIC chip with the address and '94 with the count          for the next buffer. */        datep = (DTENT *)&(datp[pd->dat_index]);#ifdef PDMADEBUG        if ( scsidebug & DETAILDAT && ( targid==targmatch ) )             {            PRINTD( targid, DETAILDAT,                 ("    cont: dat index=%d\n", pd->dat_index ));            dumpent( datep );            }#endif        if ( datep->length != 0 )            {	    setscsictrl( sc, 0 );            if ( dmapload( sc, targid, datep->iadr ) == PDMA_FAIL )                {                printf( "pdma_start: Failure return from dmapload\n" );                return PDMA_FAIL;                }            ssrdmaon( sc, datep->dir );#ifdef PDMADEBUG            PRINTD( targid, REGLOAD,                 ("    cont: loading ASC counter (base 0x%x) with length (%d)\n",                ascaddr, datep->length ));#endif            ASC_LOADCNTR(ascaddr, datep->length);	/* load counter */            wbflush();      /* Start the DMA operation in the ASC. */            sc->sc_asccmd = pd->opcode;               ascaddr->asc_cmd = pd->opcode;            wbflush();				/* clear write buffer */      /* Set the flag to inform the driver that DMA is in progress. */            sc->sc_szflags[ targid ] |= SZ_DID_DMA;            } /* end of (datep->length != 0 ) */        else            {  /* time to pad out an xfer */            ASC_LOADCNTR(ascaddr, sc->sc_siidmacount[targid]);	/* load counter */            wbflush();				/* clear write buffer */            sc->sc_asccmd = ASC_DMA | ASC_XPAD ;             ascaddr->asc_cmd = sc->sc_asccmd;            sc->sc_szflags[ targid ] |= SZ_DID_DMA;            wbflush();				/* clear write buffer */            }        } /* end of (pd->iodir == SZ_DMA_READ) */    else        {                              /* Write case now */        datep->completed = 1;          /* tag the entry complete */        pd->targcnt += datep->length;  /* bump transfer counter */        pd->dat_index++;        datep = (DTENT *)&(datp[pd->dat_index]);        if ( is_local_xfer( pd ) )	/* is this a fragment? */            {            if ( frag_buf_load( pd ) == PDMA_FAIL )                {                printf( "pmaz_ba_cont(3min)(12): (WRITE(2)) frag buffer load, dat_addr=0x%x index= %d\n",                    pd->dat_addr, pd->dat_index );                return( PDMA_FAIL );                }            }#ifdef PDMADEBUG        if ( scsidebug & DETAILDAT && ( targid==targmatch ) )             {            PRINTD( targid, DETAILDAT,                 ("    cont: dat index=%d\n", pd->dat_index ));            dumpent( datep );            }#endif        if ( is_local_xfer( pd ) && datep->dir == IOASIC_WRITE )            {            sc->sc_szflags[ targid ] |= SZ_DID_DMA | SZ_PIO_INTR;            asc_FIFOsenddata (sc, ASC_XINFO, datep->uadr, datep->length );            }        else            {            if ( datep->length != 0 )                {                /* Load addr reg, set the write direction bit. */        	    setscsictrl( sc, 0 );                if ( dmapload( sc, targid, datep->iadr ) == PDMA_FAIL )                    {                    printf( "pdma_start: Failure return from dmapload\n" );                    return PDMA_FAIL;                    }                ssrdmaon( sc, datep->dir );#ifdef PDMADEBUG                PRINTD( targid, REGLOAD,                     ("    cont: loading ASC counter (base 0x%x) with length (%d)\n",                    ascaddr, datep->length ));#endif                ASC_LOADCNTR(ascaddr, datep->length);	/* load counter */                wbflush();              /* Start the DMA operation in the ASC. */                sc->sc_asccmd = pd->opcode;                   ascaddr->asc_cmd = pd->opcode;                wbflush();				/* clear write buffer */          /* Set the flag to inform the driver that DMA is in progress. */                    sc->sc_szflags[ targid ] |= SZ_DID_DMA;                } /* end of if ( datep->length != 0 ) */            else                {  /* time to pad out an xfer */                ASC_LOADCNTR(ascaddr, sc->sc_siidmacount[targid]);	/* load counter */                wbflush();				/* clear write buffer */                sc->sc_asccmd = ASC_DMA | ASC_XPAD ;                 ascaddr->asc_cmd = sc->sc_asccmd;                sc->sc_szflags[ targid ] |= SZ_DID_DMA;                wbflush();				/* clear write buffer */                }            }        } /* end of else on (pd->iodir == SZ_DMA_READ) */#ifdef PDMADEBUG    PRINTD( targid, ENTRYEXIT, ("pmaz_ba_cont:  exit\n" ));#endif    return pd->targcnt;	/* return current progress */    }/* ---------------------------------------------------------------------- *//*int pdma_end( sc, targid )Inputs:	sz_softc *sc;		 pointer to the softc structure 	int targid;		 current target ID Function:	Handle the completion of the DMA operation.  Free up the necessary	DMA resources that were allocated in dma_setup().  Handle the final	move of the data to user space if the operation was a read.

⌨️ 快捷键说明

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