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

📄 nwatadrv.c

📁 ks8695的ide硬盘程序
💻 C
📖 第 1 页 / 共 5 页
字号:
/* ataDrv.c - ATA/IDE (LOCAL and PCMCIA) disk device driver */


/* Copyright 1989-1998 Wind River Systems, Inc. */
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <asm/ioctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include "nwAtaDrv.h"
#include "ks8695p.h"
#include "../Vxworks2Linux/Vxworks2Linux.h"

#define VXDOS                           "VXDOS"
#define VXEXT                           "VXEXT"

#undef  ATA_MAX_CTRLS
#define ATA_MAX_CTRLS 1

#define ATA0_IO_START0		(EXT_IO_BANK_2 | 0x00)	/* io for ATA0 */
#define ATA0_IO_STOP0		(EXT_IO_BANK_2 | 0x1c)
#define ATA0_IO_START1		(EXT_IO_BANK_2 | 0x20)
#define ATA0_IO_STOP1		(EXT_IO_BANK_2 | 0x2c)
#define ATA0_INT_LVL        INT_LVL_EXTI1S
#define ATA0_INT_VEC        INT_VEC_EXTI1S
#define ATA0_CONFIG         (ATA_GEO_PHYSICAL | ATA_PIO_AUTO \
								| ATA_BITS_16 | ATA_PIO_MULTI)
/*
#define ATA1_IO_START0		(EXT_IO_BANK_2 | 0x00)	// io for ATA1
#define ATA1_IO_STOP0		(EXT_IO_BANK_2 | 0x0e)
#define ATA1_IO_START1		(EXT_IO_BANK_2 | 0x10)
#define ATA1_IO_STOP1		(EXT_IO_BANK_2 | 0x1e)
#define ATA1_INT_LVL		INT_LVL_EXTI1S
#define ATA1_INT_VEC        INT_VEC_EXTI1S
#define ATA1_CONFIG		(ATA_GEO_PHYSICAL | ATA_PIO_AUTO | \
				 				ATA_BITS_16 | ATA_PIO_MULTI)*/
#define ATA_SEM_TIMEOUT		1       /* timeout for ATA sync sem */
#define ATA_WDG_TIMEOUT		2       /* timeout for ATA watch dog */
/* imports */
ATA_TYPE ataTypes[ATA_MAX_CTRLS][ATA_MAX_DRIVES] =
    {
    {{761, 8, 39, 512, 0xff},		/* ctrl 0 drive 0 */
     {761, 8, 39, 512, 0xff}}		/* ctrl 0 drive 1 */
    };

ATA_RESOURCE ataResources[ATA_MAX_CTRLS] =
    {
    {
     {
     5, 0,
     {ATA0_IO_START0, ATA0_IO_START1}, {ATA0_IO_STOP0, ATA0_IO_STOP1}, 0,
     0, 0, 0, 0, 0
     },
     IDE_LOCAL, 1, 0/*ATA0_INT_VEC*/, ATA0_INT_LVL, ATA0_CONFIG,
     ATA_SEM_TIMEOUT, ATA_WDG_TIMEOUT, 0, 0
    }	/* ctrl 0 */
   };
/*IMPORT ATA_TYPE		ataTypes [ATA_MAX_CTRLS][ATA_MAX_DRIVES];
IMPORT ATA_RESOURCE	ataResources [ATA_MAX_CTRLS];*/

/* add by wangb for ultra dma mode 2005-11-2 14:17*/

// first entry bytes before 64K boundry
#define MAX_TRANSFER    (0x10000)
#define MAX_PRD_ENTRIES (4)

/* DMA */
static unsigned int busMasterRegs[2] = {0,0}; // address bus master regs

#define BM_COMMAND_REG    0            // offset to command reg
#define BM_CR_MASK_READ    0x08           // read from memory
#define BM_CR_MASK_WRITE   0x00           // write to memory
#define BM_CR_MASK_START   0x01           // start transfer
#define BM_CR_MASK_STOP    0x00           // stop transfer

#define BM_STATUS_REG     2            // offset to status reg
#define BM_SR_MASK_SIMPLEX 0x80           // simplex only
#define BM_SR_MASK_DRV1    0x40           // drive 1 can do dma
#define BM_SR_MASK_DRV0    0x20           // drive 0 can do dma
#define BM_SR_MASK_INT     0x04           // INTRQ signal asserted
#define BM_SR_MASK_ERR     0x02           // error
#define BM_SR_MASK_ACT     0x01           // active

#define BM_PRD_ADDR  4                // offset to prd addr reg low 16 bits

/* gloab */
UINT32 g_dwAtaCbio[2][2] = { {0,0}, {0,0} };
UINT32 g_dwAtaHDAllBlocks[2][2] = { {0,0}, {0,0} };

static unsigned char statReg[2];          // save BM status reg bits
static unsigned char rwControl[2];        // read/write control bit setting


#define ATA_DEBUG
#undef ATA_DEBUG
//***********************************************************
//
// pci bus master control macros
//
//***********************************************************

typedef struct {
   char *  address;
   struct {
     unsigned long count:16;
     unsigned long reserved:15;
     unsigned long EOT:1;
   }bits;             
} PRD_ENTRY,*PPRD_ENTRY;

static  PRD_ENTRY prdTable[2][MAX_PRD_ENTRIES];

STATUS ataDmaSetupXfer(int ctrl, int dir, char *buffer, int count);
int  ataDmaConfig(int ctrl, UINT32 regAddr );
unsigned char atpRDByt(UINT32 ioAdrs);
void atpWRByt(UINT32 ioAdrs, UINT8  byte);
/* end by wangb for ultra dma mode 2005-11-2 14:17 */




/* Byte swapping version of sysInWordString(), big-endian CPUs only */

/*IMPORT void	sysInWordStringRev (int port, short *pData, int count);*/
void sysInWordString( ULONG	ioAddr, UINT16 *	bufPtr,int nWords);
void sysOutWordString(ULONG	ioAddr,UINT16 *	bufPtr,int nWords);
void sysInLongString(ULONG    ioAddr,ULONG *  bufPtr,int nLongs);
void sysOutLongString(ULONG	ioAddr,ULONG *	bufPtr,int nLongs);
/* defines */

/* Read a BYTE from IO port, `ioAdrs' */

#ifndef ATA_IO_BYTE_READ
#define ATA_IO_BYTE_READ(ioAdrs)	atpRDByt (ioAdrs)
#endif	/* ATA_IO_BYTE_READ */

/* Write a BYTE `byte' to IO port, `ioAdrs' */

#ifndef ATA_IO_BYTE_WRITE
#define ATA_IO_BYTE_WRITE(ioAdrs, byte)	atpWRByt (ioAdrs, byte)
#endif	/* ATA_IO_BYTE_WRITE */

/* Read 16-bit little-endian `nWords' into `pData' from IO port, `ioAdrs' */

#ifndef ATA_IO_NWORD_READ
#define ATA_IO_NWORD_READ(ioAdrs, pData, nWords)                        \
	sysInWordString (ioAdrs, pData, nWords)
#endif	/* ATA_IO_NWORD_READ */

/* Write 16-bit little-endian `nWords' from `pData' into IO port, `ioAdrs' */

#ifndef ATA_IO_NWORD_WRITE
#define ATA_IO_NWORD_WRITE(ioAdrs, pData, nWords)                       \
	sysOutWordString (ioAdrs, pData, nWords)
#endif /* ATA_IO_NWORD_WRITE */
    
/* Read 32-bit little-endian `nLongs' into `pData' from IO port, `ioAdrs' */

#ifndef ATA_IO_NLONG_READ
#define ATA_IO_NLONG_READ(ioAdrs, pData, nLongs)                        \
	sysInLongString (ioAdrs, pData, nLongs)
#endif	/* ATA_IO_NLONG_READ */

/* Write 32-bit little-endian `nLongs' from `pData' into IO port, `ioAdrs' */

#ifndef ATA_IO_NLONG_WRITE
#define ATA_IO_NLONG_WRITE(ioAdrs, pData, nLongs)                       \
	sysOutLongString (ioAdrs, pData, nLongs)
#endif	/* ATA_IO_NLONG_WRITE */

/* Read 32-bit CPU-endian `nWords' into `pData' from IO port, `ioAdrs' */

#ifndef	ATA_IO_NWORD_READ_SWAP
#define ATA_IO_NWORD_READ_SWAP(ioAdrs, pData, nWords)                 \
	ATA_IO_NWORD_READ (ioAdrs, pData, nWords)
#endif	/* ATA_IO_NLONG_READ_SWAP */

/* Special BSP INIT After ATA Reset */

/* Special BSP INIT After ATA Reset */
#ifndef SYS_ATA_INIT_RTN
#define SYS_ATA_INIT_RTN(ctrl)  if (_func_sysAtaInit != NULL)    \
                                    {                            \
                                    ((*_func_sysAtaInit)(ctrl)); \
                                    }
#endif

/* globals */

BOOL	  ataDrvInstalled = FALSE;	/* TRUE if installed */
ATA_CTRL  ataCtrl [ATA_MAX_CTRLS];

/* BSP specific ATA Init/Reset routine */
VOIDFUNCPTR _func_sysAtaInit = NULL;


/* locals */

LOCAL int       ataRetry = 3;		/* max retry count */

/* Used to hold LBA information, if larger than calculated CHS value */

LOCAL UINT32 ataLbaTotalSecs [ATA_MAX_CTRLS][ATA_MAX_DRIVES];


/* function prototypes */

LOCAL STATUS ataBlkRd	(ATA_DEV *pDev, int startBlk, int nBlks, char *p);
LOCAL STATUS ataBlkWrt	(ATA_DEV *pDev, int startBlk, int nBlks, char *p);
LOCAL STATUS ataReset	(ATA_DEV *pDev);
LOCAL STATUS ataStatus	(ATA_DEV *pDev);
LOCAL STATUS ataIoctl	(ATA_DEV *pDev, int function, int arg);
LOCAL STATUS ataBlkRW	(ATA_DEV *pDev, int startBlk, int nBlks, char *p,
			 int direction);
LOCAL void   ataWdog	(int ctrl);
LOCAL void   ataIntr	(int ctrl);
LOCAL STATUS ataInit	(int ctrl);
LOCAL void   ataWait	(int ctrl, int request);
LOCAL STATUS ataCmd	(int ctrl, int drive, int cmd, int arg0, int arg1);
LOCAL STATUS ataPread	(int ctrl, int drive, void *p);
STATUS ataRW	(int ctrl, int drive, int cylinder, int head, int sec, 
	 		 void *p, int nSecs, int direction);

STATUS sysAtaDevIdGet(void)
{
	printf("sysAtaDevIdGet\n");
	return 1;
}

/* add by wangb 2005-10-18 14:10 */
void enableChan(int ctrl)
{
  if(ctrl > ATA_MAX_CTRLS)
    return;
  atpWRByt(busMasterRegs[ctrl] + BM_COMMAND_REG,rwControl[ctrl] | BM_CR_MASK_START);
  return;
}
void disableChan(int ctrl)
{
  if(ctrl > ATA_MAX_CTRLS)
    return;
  atpWRByt( busMasterRegs[ctrl] + BM_COMMAND_REG,BM_CR_MASK_STOP);
  return;
}

void clearChan(int ctrl)
{
  if(ctrl > ATA_MAX_CTRLS)
    return;
  atpWRByt( busMasterRegs[ctrl] + BM_STATUS_REG,statReg[ctrl] | BM_SR_MASK_INT | BM_SR_MASK_ERR );
  return;
}

/***********************************************************************
*
* ideDelayFun - ide delay function
*
************************************************************************/
LOCAL ideDelayFun()
{
	volatile unsigned int i =0;
	volatile unsigned int j =0;
	for(i =0; i< 2000; i++)
	{
		j++;	
	}
}

int min(int a,int b)
{
	if(a>b)
		return b;
	else
		return a;
}
/*******************************************************************************
*
* ataDrv - initialize the ATA driver
*
* This routine initializes the ATA/IDE driver, sets up interrupt vectors,
* and performs hardware initialization of the ATA/IDE chip.
*
* This routine must be called exactly once, before any reads, writes,
* or calls to ataDevCreate().  Normally, it is called by usrRoot()
* in usrConfig.c.
*
* RETURNS: OK, or ERROR if initialization fails.
*
* SEE ALSO: ataDevCreate()
*/

STATUS ataDrv(
    int  ctrl,			/* controller no. */
    int  drives,		/* number of drives */
    int  vector,		/* interrupt vector */
    int  level,			/* interrupt level */
    BOOL configType,		/* configuration type */
    int  semTimeout,		/* timeout seconds for sync semaphore */
    int  wdgTimeout		/* timeout seconds for watch dog */
    )
    {
    ATA_CTRL *pCtrl		= &ataCtrl[ctrl];
    ATA_RESOURCE *pAta		= &ataResources[ctrl];
    PCCARD_RESOURCE *pResource	= &pAta->resource;
    ATA_DRIVE *pDrive;
    ATA_PARAM *pParam;
    ATA_TYPE *pType;
    int drive;
    int ix;

    if ((ctrl >= ATA_MAX_CTRLS) || (drives > ATA_MAX_DRIVES))
	    return (ERROR);

    if (!ataDrvInstalled)
	  {
	    for (ix = 0; ix < ATA_MAX_CTRLS; ix++)
	    {
        ataCtrl[ix].wdgId = wdCreate ();
	    }
    	ataDrvInstalled = TRUE;
	  }

    if (!pCtrl->installed)
	  {
	    if (semTimeout == 0)
	      pCtrl->semTimeout = ATA_SEM_TIMEOUT_DEF;
	    else
	      pCtrl->semTimeout = semTimeout;

	    if (wdgTimeout == 0)
	      pCtrl->wdgTimeout = ATA_WDG_TIMEOUT_DEF;
	    else
	      pCtrl->wdgTimeout = wdgTimeout;

        pCtrl->syncSem=semBCreate(SEM_Q_FIFO, SEM_EMPTY);
        pCtrl->muteSem=semMCreate(SEM_Q_PRIORITY | SEM_DELETE_SAFE |
	          SEM_INVERSION_SAFE);

	    pCtrl->data	= ATA_DATA	(pResource->ioStart[0]);
	    pCtrl->error	= ATA_ERROR	(pResource->ioStart[0]);
	    pCtrl->feature	= ATA_FEATURE	(pResource->ioStart[0]);
	    pCtrl->seccnt	= ATA_SECCNT	(pResource->ioStart[0]);
	    pCtrl->sector	= ATA_SECTOR	(pResource->ioStart[0]);
	    pCtrl->cylLo	= ATA_CYL_LO	(pResource->ioStart[0]);
	    pCtrl->cylHi	= ATA_CYL_HI	(pResource->ioStart[0]);
    	pCtrl->sdh	= ATA_SDH	(pResource->ioStart[0]);
	    pCtrl->command	= ATA_COMMAND	(pResource->ioStart[0]);
	    pCtrl->status	= ATA_STATUS	(pResource->ioStart[0]);
	    pCtrl->aStatus	= ATA_A_STATUS	(pResource->ioStart[1]);
	    pCtrl->dControl	= ATA_D_CONTROL (pResource->ioStart[1]);
	    pCtrl->dAddress	= ATA_D_ADDRESS (pResource->ioStart[1]);
#if 0
	    (void) sysAtaIntConnect ((VOIDFUNCPTR *)INUM_TO_IVEC (vector),
				  (VOIDFUNCPTR)ataIntr, ctrl);

#if     (CPU_FAMILY==I80X86)
      sysIntEnablePIC (level);	/* unmask the interrupt level */
#elif   (CPU_FAMILY==PPC)
      sysAtaIntEnable (level);	/* unmask the interrupt level */
#else
      #err
#endif
#endif
	    /*intConnect((VOIDFUNCPTR *)INUM_TO_IVEC (INT_LVL_EXTI1S), (VOIDFUNCPTR )ataIntr, ctrl);quy del int 2006-3-24 8:32*/
	    /*intEnable(INT_LVL_EXTI1S);quy del int 2006-3-24 8:31*/

	    pCtrl->intLevel = level;
	    pCtrl->wdgOkay  = TRUE;

	    semTake (&pCtrl->muteSem, WAIT_FOREVER);

      if (ataInit (ctrl) != OK)
	    {
	      semGive (&pCtrl->muteSem);
	      return (ERROR);
	    }

   	  /*added by youyan 2005-11-19 10:58*/
	    ataLbaTotalSecs[ctrl][0]=0;
	    ataLbaTotalSecs[ctrl][1]=0;
	    /*end of added by youyan 2005-11-19 10:59*/
      for (drive = 0; drive < drives; drive++)
	    {
	      pType  = &ataTypes[ctrl][drive];
	      pDrive = &pCtrl->drive[drive];
	      pParam = &pDrive->param;
	      if (pType->cylinders == 0)
	        return ERROR;

	      if ((pCtrl->ctrlType == ATA_PCMCIA) ||
		        ((pCtrl->ctrlType != ATA_PCMCIA) && (drive == 0)))
		    {
          if (ataCmd (ctrl, drive, ATA_CMD_DIAGNOSE, 0, 0) != OK)
		      {
	          semGive (&pCtrl->muteSem);
	          return (ERROR);
		      }
		    }

	      /* find out geometry */

	      if ((configType & ATA_GEO_MASK) == ATA_GEO_FORCE)
	      {
	        if(ataCmd (ctrl, drive, ATA_CMD_INITP, 0, 0) != OK)
				    break;
          if(ataPread (ctrl, drive, (char *)pParam) != OK)
				    break;
	      }
	      else if ((configType & ATA_GEO_MASK) == ATA_GEO_PHYSICAL)
	      { 
          if(ataPread (ctrl, drive, (char *)pParam) != OK)
				    break;
		      pType->cylinders = pParam->cylinders - 1;
		      pType->heads	 = pParam->heads;
		      pType->sectors   = pParam->sectors;
	  //          pType->bytes     = pParam->bytesSec;
	  /*modify start by wb 2005-6-20 10:20*/
	  			if(pParam->capabilities & 0x0200)  /* if (drive supports LBA) */
				  {
				    if (((pParam->feature & 0x0400 ) >> 10) == 0)
				    {
				      ataLbaTotalSecs[ctrl][drive] =  (unsigned int)((unsigned int)pParam->sectors0 | (((unsigned int)pParam->sectors1) << 16));
				        /*printf("ataLbaTotalSecs is %d \n", ataLbaTotalSecs[ctrl][drive]);
				        printf("sectors0 is %d \n", pParam->sectors0);
				        printf("sectors1 is %d \n", pParam->sectors1);*/
				    }
				    else
				    {
						  ataLbaTotalSecs[ctrl][drive] =	(unsigned int)(pParam->sectorsExt0	   |	 \
											((unsigned int)(pParam->sectorsExt1) << 16)| \
											((unsigned int)(pParam->sectorsExt2) << 24));
					  }
					  pDrive->lba48bit = (ataLbaTotalSecs[ctrl][drive] > 268435455);
				  }
				  /*end by wb 2005-6-20 10:20*/
	      }
	      else if ((configType & ATA_GEO_MASK) == ATA_GEO_CURRENT)
	      {
          if(ataPread (ctrl, drive, (char *)pParam) != OK)
					  break;
				  if ((pParam->currentCylinders != 0) &&
				      (pParam->currentHeads != 0) &&
				      (pParam->currentSectors != 0))
				  {
			      pType->cylinders = pParam->currentCylinders - 1;
			      pType->heads     = pParam->currentHeads;
			      pType->sectors   = pParam->currentSectors;
				  }
				  else
				  {
			      pType->cylinders = pParam->cylinders - 1;
			      pType->heads     = pParam->heads;
			      pType->sectors   = pParam->sectors;
				  }
	      } 
            /* 
  	    * reinitialize the controller with parameters read from the
  	    * controller.
            */

        (void) ataCmd (ctrl, drive, ATA_CMD_INITP, 0, 0);

        /* recalibrate */

⌨️ 快捷键说明

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