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

📄 pdma3min.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 4 页
字号:
#ifndef lintstatic char *sccsid = "@(#)pdma3min.c	4.6      (ULTRIX)  4/4/91";#endif lint/************************************************************************ *									* *			Copyright (c) 1988 by				* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any	other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or	reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//************************************************************************ * * pdma_3min.c * * Pseudo DMA routines for the PMAZ-BA a.k.a. 3min. * * Modification history: * * 15 Aug 1990  Robert Scott * Created this file to implement PDMA code for 3min hardware.  Based upon * 3max PDMA code. * ************************************************************************//* ---------------------------------------------------------------------- */#define ENTRYEXIT	0x00010000#define REGLOAD		0x00020000#define DETAILDAT	0x00040000#define INTTRACE	0x00080000#define	PADTRACK	0x00100000	#define DUMPHEX		0x00200000#define PASS2		0x00400000#define FRAG		0x00800000#include "../data/scsi_data.c"#include "../io/tc/tc.h"#include "scsi_debug.h"#include "pdma3min.h"/* ---------------------------------------------------------------------- *//* External functions and variables. */extern int scsidebug;extern PDMA_ENTRY pdma_entry[];		/* the entry array *//* ---------------------------------------------------------------------- *//* Local Data area. *//* Entry structure for the pseudo DMA routines for the PMAZBA.  The externaldeclarations are needed for the forward reference. */extern int pmaz_ba_init();extern int pmaz_ba_setup();extern int pmaz_ba_start();extern int pmaz_ba_cont();extern int pmaz_ba_end();extern int pmaz_ba_flush();extern int bcopy();extern int bzero();PDMA_ENTRY pdma_ds5000_100 ={    DS_5000_100,				/* cpu type value */    ( 0 ),				/* MISC control flags */    pmaz_ba_init,    pmaz_ba_setup,    pmaz_ba_start,    pmaz_ba_cont,    pmaz_ba_end,    bcopy,				/* kernel routines can be used */    bcopy,    bzero,    pmaz_ba_flush};int targmatch = 9;int targtmp;/* ---------------------------------------------------------------------- *//*unsigned *ioa_addrcvt( addr )Inputs:	char *addr;		 K2SEG address for the data Function: 	Convert input virtual address to physical which, in turn, must        be modified to meet IOASIC format requirements.Return:	Physical memory address in IOASIC format.*/unsigned *ioa_addrcvt ( addr )char *addr;    {    unsigned long a = (unsigned long) addr;    unsigned long p;    if ( IS_KUSEG( a ) )        {        printf( "ioa_addrcvt: KUSEG address passwd in!\n" );        p = a;	return 0;        }    p = svtophy( a );    if ( p == 0 )        {        printstate |= PANICPRINT;        printf(  "ioa_addrcvt: Invalid return from svtophy().\n" );        printf( "ioa_addrcvt: Address 0x%x maps to physical address 0.\n",a );	return 0;        }    a = ( p & 0x1ffffffc ) << 3;     return (unsigned *) a;     }/* ---------------------------------------------------------------------- *//*void *backcvt( addr )Inputs:	void *addr;		 IOASIC format physical address Function:        Convert an IOASIC format physical address into normal physical        address format.Return:	Physical memory address in standard format.*/void *backcvt( void *addr )    {    unsigned long a = (unsigned long) addr;    unsigned long p;    p = a >> 3;    return (void *)( PHYS_TO_K0( p ));    }/* ---------------------------------------------------------------------- *//*int pdma_init( sc )Inputs:	sz_softc pointerFunction:	Initialize all that is necessary for the DMA engine/code to run 	for the particular system.  For the 3min, DAT table space and        fragment buffer space must be allocated.	The PDMA related fields will be cleared/initialized and one of the	pipe buffers will be set to READY.Return:	PDMA_SUCCESS		 all is ready and ok 	PDMA_FAIL		 a fatal(?) problem has occured */int pmaz_ba_init( sc )struct sz_softc *sc;    {    int targid;			/* loop counter for targets */    PDMA *pd;			/* pointer for the DMA control struct */    int *slotp;			/* IOASIC SCSI DMA slot register pointer */    static char *fbp=0;                /* Fragment buffer pool pointer *//*  Setup the DMA engine address pointers in the softc.  The    base address for these and the SCSI chip should have already been     set in the softc by the particular driver's probe code. *//*  In contradiction with the previous comment, this line should be done     somewhere in scsi_asc.c? */    sc->ioasicp =  (char *) PHYS_TO_K1( BASE_IOASIC );  /* The IOASIC SCSI DMA slot register MUST be initialized before any    communication with the '94 is attempted.  */    slotp = (int *) ( (unsigned)sc->ioasicp + SCSI_DMASLOT_O);      *slotp = SCSI_SLOT_DATA;	/* magic cookie as found in v1.6 of spec */                           /* FIX: This may change with PMAZ-BA's */  /* For each of the target slots on a SCSI bus, this is one of the valid    magic #'s of 8.  Setup and assign the pointers/offsets for each of the    DMA control structures. */  /* Allocate a chunk of memory for the fragment buffers and DAT table      for each target */    if ( !fbp )        KM_ALLOC( fbp, char *, (sizeof( FRAGBUF )+DATTBL_SIZ)*8, KM_DEVBUF,            KM_NOW_CL_CO_CA|KM_NOCACHE );    for( targid = 0; targid < NDPS; targid++ )        {	pd = &sc->pdma_ctrl[ targid ];	/* assign the pointer */      /* Clear the per call elements. */	pd->pstate = PDMA_IDLE;		/* clear out misc flags */	pd->iodir = 0;			/* clear direction */	pd->count = 0;			/* clear total count */	pd->data_addr = (char *)NULL;	/* clear data address */     /* The DAT table and fragment buffer for a given target must be        extracted from the large buffer kmalloc'ed above.  One might        think of the large buffer as being an array (of length 8) of        structures containing a DAT table followed by a fragment         buffer for each target.  Then again, one might not.     */        pd->dat_addr = (char *) ( fbp +            targid * ( DATTBL_SIZ + sizeof( FRAGBUF ) ) );        pd->frag_bufp = (char *) ( fbp +             targid * ( DATTBL_SIZ + sizeof( FRAGBUF ) ) +            DATTBL_SIZ );#ifdef PDMADEBUG        PRINTD( targid, DETAILDAT,             ("init:  pd->dat_addr = 0x%x\n", pd->dat_addr ));        PRINTD( targid, DETAILDAT,             ("init:  pd->frag_bufp = 0x%x\n", pd->frag_bufp ));#endif	pd->usercnt = 0;		/* user space count */	pd->targcnt = 0;		/* target count */	}    return( PDMA_SUCCESS );    }/* ---------------------------------------------------------------------- *//*int pdma_setup( sc, targid, dir, count, addr )Inputs:	sz_softc *sc;		 pointer to the softc structure 	int targid;		 current target ID 	int dir;		 direction for I/O xfer 	long count;		 number of bytes to xfer 	char *addr;		 address for the data Function:Return:	PDMA_SUCCESS		 all is ready and ok 	PDMA_FAIL		 a fatal(?) problem has occured 	PDMA_RETRY(?)		 unable to setup, try again later */int pmaz_ba_setup( sc, targid, dir, count, addr )struct sz_softc *sc;	/* pointer to the softc structure */int targid;			/* current target ID */int dir;			/* direction for I/O xfer */long count;			/* number of bytes to xfer */char *addr;			/* address for the data */    {    PDMA *pd;			/* pointer for the DMA control struct */    int i;			/* loop counter */#ifdef PDMADEBUG    PRINTD( targid, ENTRYEXIT,        ("pmaz_ba_setup: entry sc=0x%x targ=%d dir=%d cnt=%d addr=0x%x\n  bcount=%d dmaxfer=%d\n",        sc, targid, dir, count, addr, sc->sc_b_bcount[targid],         sc->sc_dmaxfer[targid] ));#endif  /* Setup the DMA control structure for this target. */    pd = &sc->pdma_ctrl[ targid ];	/* assign the pointer */    targtmp = targid;			/* used for debugging purposes only */  /* If this pipe is not IDLE return PDMA_RETRY. */    if( pd->pstate != PDMA_IDLE )        {        PRINTD( targid, ENTRYEXIT, ("pmaz_ba_setup: exit - PDMA_RETRY\n"));	return( PDMA_RETRY );        }        pd->pstate = PDMA_SETUP;		/* setup is being done */    pd->iodir = dir;			/* load direction */    /* must save difference between requested xfer count and real count */    /* in order to pad out the xfer with the '94 */    pd->count = sc->sc_b_bcount[targid] - sc->sc_dmaxfer[targid];    /* OK, so this doesn't have anything to do with the sii, we don't        need another counter in the softc structure and I don't like       using #defines to mask things.      */    sc->sc_siidmacount[targid] = count - pd->count;#ifdef PDMADEBUG    if ( scsidebug & PADTRACK && targmatch == targid )        {        if ( sc->sc_siidmacount[targid] )        cprintf("setup: Padding %d -> %d : %d\n", count, pd->count,            sc->sc_siidmacount[targid] );        }#endif    pd->data_addr = addr;		/* load data address */    pd->usercnt = 0;			/* clear working count */    pd->targcnt = 0;			/* clear working count */  /* Build the DAT table for this transfer. */    if ( blddattbl( targid, pd, pd->count, addr, dir ) == PDMA_FAIL )        {        printf( "setup: dat table build failure\n" );        printf( "  target=%d dat_addr=0x%x pd->count=%d addr=0x%x dir=%d\n",             targid, pd->dat_addr, pd->count, addr, dir );        dumptbl( (DTENT *)pd->dat_addr );        return( PDMA_FAIL );        }  /* The DAT indexing scheme always begins with 1 as entry 0 is reserved     in case 'backing-up' is necessary.  This could occur due to a     disconnect which leaves a segment of less than a double word in     length to be transferred.  In such a case, the remainder of the      segment interrupted would be broken into two portions:  A transfer of     less than a double word into a local buffer followed by a normal DMA     transfer.  */    pd->dat_index = 1;#ifdef PDMADEBUG    if ( scsidebug & DETAILDAT && ( targid==targmatch ) )         dumptbl( (DTENT *)pd->dat_addr );#endif  /* If the setup is for a write and there the table begins with a 'special     case' transfer from a local buffer, fill that buffer right now.  */    if ( ( dir == SZ_DMA_WRITE ) && is_local_xfer( pd ) )        frag_buf_load( pd );#ifdef PDMADEBUG    PRINTD( targid, ENTRYEXIT, ("pmaz_ba_setup: exit\n"));#endif    return( PDMA_SUCCESS );		/* ready */    }/* ---------------------------------------------------------------------- *//* int pdma_start( sc, targid, opcode )Inputs:	sz_softc *sc;		 pointer to the softc structure 	int targid;		 current target ID 	int opcode;		 value to start the dma oper in the chip Function:	This routine is fairly straight forward.  It is responsible for loading	what ever is necessary into the DMA engine and the SCSI chip.  The 	dma control structure for the target should contain all the information.

⌨️ 快捷键说明

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