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

📄 pdma3min.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 4 页
字号:
/*  blddattbl - Builds a table of DMA buffers suitable for use with		the 3min.  Users buffer address is broken up both at		page boundaries and, when buffer areas are less than 8		bytes in length, fixed buffer areas allocated by the		driver are used instead.    Inputs:	int controller - controller number                DTENT *table -	A pointer to the table to be filled in.		long count -	Length of the user's buffer.		char *addr -	Pointer to the user's buffer.    Return:	PDMA_FAIL on failure*/blddattbl( controller, pd, count, addr, dir ) int controller; PDMA *pd;			/* pointer for the DMA control struct */unsigned long count; char *addr;int dir;    {    DTENT *table;     char *frag;    int index = 0;    unsigned ecount;	    int rem;    char *eaddr, *uadr;    table = (DTENT *) pd->dat_addr;    frag = pd->frag_bufp;    /* build null 0th entry */    if ( blddatent( &table[index++], NULL, NULL, NULL, NULL ) == PDMA_FAIL )        return( PDMA_FAIL );    while( count )        {        if ( !(ecount = caldatent( addr, count )) )            {            printf( "blddattbl: Illegal return value (0) from caldatent().\n" );            return( PDMA_FAIL );            }        if ( ecount < 8 )            {            eaddr = frag;            uadr = addr;            }        else             {            eaddr = addr;            uadr = 0;            }	if ( blddatent( &(table[index++]), ecount, eaddr, uadr, dir ) ) 	    {            printstate |= PANICPRINT;	    printf("eaddr=0x%x ecount=%d\n ", eaddr, ecount);	    dumptbl( table );            panic("blddatbl:  Invalid IOASIC physical address .\n");	    }        count -= ecount;        addr += ecount;        }    if ( blddatent( &table[index++], NULL, NULL, NULL, NULL ) == PDMA_FAIL )        return( PDMA_FAIL );    return( PDMA_SUCCESS );    }/* rps - original 4K page params - should use other kernel defines */#define STRPW  0xfffffff8#define PAGS   0x00001000#define SEGMSK 0x00000fff#define	FRAGSZ 0x00000008#define FRAGM  0x00000007int caldatent( addr, count )char *addr;long count;    {    unsigned long rem, rem2;    unsigned long ecount;    rem = ((unsigned long)addr) & FRAGM;    rem2 = ((unsigned long)addr) & SEGMSK;    if ( count < FRAGSZ )        ecount = count;    else if ( rem ) /* not octabyte aligned? */        ecount = FRAGSZ - rem;    else if ( rem2 )	/* not page aligned? */        {        ecount = PAGS - rem2;        if ( count < ecount )	            ecount = ( ( ((unsigned long)addr) + count ) & STRPW ) - ((unsigned long)addr);        }    else				/* a 4k page */        {        ecount = PAGS;        if ( count < ecount )            ecount = ( ( ((unsigned long)addr) + count ) & STRPW ) - ((unsigned long)addr);        }    return( ecount );    }flush_fragbuf( pd, lcount )PDMA *pd;unsigned long lcount;    {    DTENT *datp, *datep;    /* pointer to DAT table and individual entry */    char *tp;    if ( lcount > 7 )        printf("flush_fragbuf: pd=0x%x, lcount=%d\n", pd, lcount );  /* First pull out the DAT table entry corresponding to this xfer */    datp = (DTENT *)pd->dat_addr;    datep = (DTENT *)&(datp[pd->dat_index]);    if( lcount > 0 )	/* don't bother if no data */        {        bcopy( datep->addr, datep->uadr, lcount );        pd->targcnt += lcount;	/* update target count */        datep->length -= lcount;	/* adjust DAT entry length */          datep->uadr += lcount;        if ( datep->length == 0 )            pd->dat_index++;        wbflush();        }    }dmapload( sc, targid, addr )struct sz_softc *sc;int targid;unsigned int *addr;    {    unsigned **dmap;         /* pointer to IOASIC DMA Ptr. reg. */    DMA_AR *ioasicp;		/* pointer for the SCSI DMA engine register */        PDMA *pd;    DTENT *datp, *datep;    /* pointer to DAT table and individual entry */    pd = &sc->pdma_ctrl[ targid ];		/* assign the pointer */    datp = (DTENT *)pd->dat_addr;    datep = (DTENT *)&(datp[pd->dat_index]);    ioasicp = (DMAAR *)sc->ioasicp;	/* engine address */    dmap = (unsigned **) ( ( (unsigned) ioasicp ) + IOA_S_DMAP_O );    if ( addr == 0 )        {        printstate |= PANICPRINT;        dumptbl( (DTENT *)pd->dat_addr );        printf("dat_index = %d\n", pd->dat_index );        dumpent( datep );        printf( "dmapload:  Null IOASIC (SCSI) DMA address pointer.\n" );	return PDMA_FAIL;        }    *dmap = addr;    return PDMA_SUCCESS;    }ssrdmaon( sc, dir )struct sz_softc *sc;int dir;    {    unsigned *ssrp;          /* pointer to IOASIC SSR */    DMA_AR *ioasicp;		/* pointer for the SCSI DMA engine register */    ioasicp = (DMAAR *)sc->ioasicp;	/* engine address */    ssrp = (unsigned *)((unsigned)ioasicp + SSR_O);    if ( dir )		/* read */	*ssrp |= ( SSR_DMADIR | SSR_DMAENB );    else        {        *ssrp &= ( ~SSR_DMADIR );        *ssrp |= SSR_DMAENB;        }    wbflush();    }ssrdmaoff( sc )struct sz_softc *sc;    {    unsigned *ssrp;          /* pointer to IOASIC SSR */    DMA_AR *ioasicp;		/* pointer for the SCSI DMA engine register */    unsigned int ssr;    ioasicp = (DMAAR *)sc->ioasicp;	/* engine address */    ssrp = (unsigned *)((unsigned)ioasicp + SSR_O);#ifdef PDMADEBUG    if ( scsidebug & PASS2 && targtmp == targmatch )        {        ssr = *ssrp;        if ( ssr & SSR_DMAENB )	    	    printf("ssrdmaoff:  DMA enabled\n");        else            printf("ssrdmaoff:  DMA disabled\n");        }#endif    *ssrp &= ( ~SSR_DMAENB );    wbflush();    }dumphex( ptr, len )char *ptr;unsigned len;    {    int i,j,index;    printf("\nDump of 0x%x, length %d\n\n", ptr, len );    for( i=0; i<len; i+=16 )        {        printf("  %05x: ", i );        for( j=0; j<16; j++ )            {            index = i+j;            if (index >= len )                break;            printf( "%2x ", ptr[index] );            }        printf( "\n" );        }    }/* ------------------------------------------------------------------------ *//*	getdbuffer( sc, bufp )		Copies the IOASIC data buffers into *//*					a user buffer.  User buffer must be *//*					at least 8 bytes long!              *//*	Inputs:                                                             *//*	    sc				Pointer to soft_c structure         *//*	    bufp			Pointer to user buffer.             *//*                                                                          *//*	Return value:			Number of valid data bytes or -1 on *//*					error.                              *//* ------------------------------------------------------------------------ */int getdbuffer( sc, bufp )struct sz_softc *sc;void *bufp;    {    unsigned long *dbufp, *ubufp;    unsigned int *cregp, creg;    DMA_AR *ioasicp;		/* pointer for the SCSI DMA engine register */    if ( !bufp )			/* check for invalid user address */	return -1;    ubufp = (unsigned long *)bufp;	/* address user buffer using 32's */    ioasicp = (DMAAR *)sc->ioasicp;	/* engine address */    dbufp = (unsigned long *)((unsigned)ioasicp + SCSI_DATA0_O );    *ubufp++ = *dbufp;			/* Copy word 1 */    dbufp = (unsigned long *)((unsigned)ioasicp + SCSI_DATA1_O );    *ubufp = *dbufp;			/* Copy word 2 */    cregp = (unsigned int *)((unsigned)ioasicp + SCSI_CTRL_O );    creg = *cregp;			/* grab the scsi control register */    if ( creg & CREG_DMA_M )		/* DMA operation in progress? */	return 0;			/* nothing to read if a write */    creg &= CREG_BUSG_M;		/* mask of to byte usage count */#ifdef PDMADEBUGif ( scsidebug & ENTRYEXIT && targtmp == targmatch )    printf( "getdbuffer:  exit(%x)\n", creg<<1 );#endif    return creg<<1;			/* multiply hword's to get bytes */    }/* ------------------------------------------------------------------------ *//*	getdbcount( sc, dir )		Returns the number of bytes filled  *//*					in the IOASIC data buffers.         *//*	Inputs:                                                             *//*	    sc				Pointer to soft_c structure         *//*	    dir				IO Direction (IOASIC_READ or _WRITE)*//*                                                                          *//*	Return value:			Number of valid data bytes or -1 on *//*					error.                              *//* ------------------------------------------------------------------------ */int getdbcount( sc, dir )struct sz_softc *sc;int dir;    {    unsigned int *cregp, creg;		/* Control pointer and content.    */    DMA_AR *ioasicp;			/* SCSI DMA engine register        */    int bcnt;				    ioasicp = (DMAAR *)sc->ioasicp;	/* Engine address                  */    cregp = (unsigned int *)((unsigned)ioasicp + SCSI_CTRL_O );    creg = *cregp;			/* Grab the scsi control register. */    bcnt = creg & CREG_BUSG_M;		/* Mask off to byte usage count.   */    if ( dir == IOASIC_WRITE )		/* During writes, the sense of the */        {				/* DMA bit is inverted.            */        if ( creg & CREG_DMA_M )	/* Buffer not empty?               */	    return (4-bcnt)<<1;		/* IOASIC counts in half-words (16)*/	return 0;			/* bcnt is invalid                 */        }				/* We've handled all WRITE cases.  */    if ( creg & CREG_DMA_M )		/* DMA in progress?                */        return 0;#ifdef PDMADEBUGif ( scsidebug & ENTRYEXIT && targtmp == targmatch )    printf( "getdbcount:  exit(%x)\n", bcnt<<1 );#endif    return bcnt<<1;			/* Multiply hword's to get bytes.  */    }voidsetscsictrl( sc, val )struct sz_softc *sc;int val;    {    unsigned int *cregp, creg;		/* Control pointer and content.    */    DMA_AR *ioasicp;			/* SCSI DMA engine register        */    int bcnt;				    ssrdmaoff( sc );			/* JIC, turn DMA OFF */    ioasicp = (DMAAR *)sc->ioasicp;	/* Engine address                  */    cregp = (unsigned int *)((unsigned)ioasicp + SCSI_CTRL_O );    *cregp = val;    wbflush();    }int flushdb( sc, cnt )struct sz_softc *sc;int cnt;    {    unsigned int *cregp, creg;		/* Control pointer and content.    */    DMA_AR *ioasicp;			/* SCSI DMA engine register        */    unsigned int *dmap;	                /* pointer to IOASIC DMA Ptr. reg. */    char *padr;                         /* physical address of user buffer */    char lbuf[32];			/* Local data buffer               */    int bcnt;				    ioasicp = (DMAAR *)sc->ioasicp;	/* Engine address                  */    dmap = (unsigned int *) ( (unsigned) ioasicp + IOA_S_DMAP_O );    padr = (char *) backcvt( (void *)*dmap ); /* Calc. the user buf address */    bcnt = getdbuffer( sc, lbuf );	/* grab data bytes */    if ( cnt != bcnt )        {        printf("flushdb: input count (%d) doesn't match buffer count (%d)\n",            cnt, bcnt );        }    bcopy( lbuf, padr, cnt );    return cnt;    }

⌨️ 快捷键说明

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