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

📄 atadrv.c

📁 promise20265的驱动源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
        if (pParam->advancedPio & 0x02)
            pDrive->pioMode = 4;
        }

    /* find out supported max DMA mode */

    if (pDrive->okDma)
        {

        if (pParam->multiDma & 0x04)
            pDrive->multiDmaMode = 2;
        else if (pParam->multiDma & 0x02)
            pDrive->multiDmaMode = 1;
        else if (pParam->multiDma & 0x01)
            pDrive->multiDmaMode = 0;
        }

        /* Is Ultra DMA supported */
        

        if (pParam->valid & 0x04) {
	   if (pParam->ultraDma & 0x20)
	      pDrive->ultraDmaMode = 5;
	   else if (pParam->ultraDma & 0x10)
	      pDrive->ultraDmaMode = 4;
	   else if (pParam->ultraDma & 0x08)
	      pDrive->ultraDmaMode = 3;
	   else if (pParam->ultraDma & 0x04)
	      pDrive->ultraDmaMode = 2;
	   else if (pParam->ultraDma & 0x02)
	      pDrive->ultraDmaMode = 1;
	   else if (pParam->ultraDma & 0x01)
	      pDrive->ultraDmaMode = 0;
        } else
           pDrive->ultraDmaMode = -1;



    /* find out transfer mode to use */

    pDrive->rwBits = configType & ATA_BITS_MASK;
    pDrive->rwPio  = configType & ATA_PIO_MASK;
    //    pDrive->rwDma  = configType & ATA_DMA_MASK;
    pDrive->rwMode = ATA_PIO_DEF_W;

    switch (configType & ATA_MODE_MASK)
    {
        case ATA_PIO_0:
        case ATA_PIO_1:
        case ATA_PIO_2:
        case ATA_PIO_3:
        case ATA_PIO_4:
        case ATA_PIO_DEF_0:
        case ATA_PIO_DEF_1:
            pDrive->rwMode = configType & ATA_MODE_MASK;
            break;
        case ATA_PIO_AUTO:
            pDrive->rwMode = ATA_PIO_W_0 + pDrive->pioMode;
	    logMsg("setting pio mode to PIO_%d\n",pDrive->pioMode, 0,0,0,0,0);
            break;
     }


     if(pDrive->okDma)
        switch (configType & ATA_DMA_MODE_MASK)
	{
	case ATA_DMA_MULTI_0:
           pDrive->rwDma = ATA_DMA_MULTI_W_0;
           break;
	case ATA_DMA_MULTI_1:
           pDrive->rwDma = ATA_DMA_MULTI_W_1;
           break;
	case ATA_DMA_MULTI_2:
           pDrive->rwDma = ATA_DMA_MULTI_W_2;
           break;
	case ATA_DMA_ULTRA_0:
           pDrive->rwDma = ATA_DMA_ULTRA_W_0;
           break;
	case ATA_DMA_ULTRA_1:
           pDrive->rwDma = ATA_DMA_ULTRA_W_1;
           break;
	case ATA_DMA_ULTRA_2:
           pDrive->rwDma = ATA_DMA_ULTRA_W_2;
           break;
	case ATA_DMA_ULTRA_3:
           pDrive->rwDma = ATA_DMA_ULTRA_W_3;
           break;
	case ATA_DMA_ULTRA_4:
           pDrive->rwDma = ATA_DMA_ULTRA_W_4;
           break;
	case ATA_DMA_ULTRA_5:
           pDrive->rwDma = ATA_DMA_ULTRA_W_5;
           break;
	case ATA_DMA_AUTO:
//	  if (pDrive->type == ATA_TYPE_ATA) {
	   if (pDrive->ultraDmaMode != -1)
	      pDrive->rwDma = ATA_DMA_ULTRA_W_0 + pDrive->ultraDmaMode;
	   else
	      pDrive->rwDma = ATA_DMA_MULTI_W_0 + pDrive->multiDmaMode;
//	  }
          /* bugbug don't know why cdrom drive reports ultraDmaMode but only 
             works if multidma mode */
//          else if (pDrive->type == ATA_TYPE_ATAPI)
//              pDrive->rwDma = ATA_DMA_MULTI_W_0 + pDrive->multiDmaMode;
	   break;
	default:
           //
           // Turn off dma
           //
            
           pDrive->okDma = FALSE;   
	   break;
	} //end switch


    /* Set the transfer mode */

    (void) ataCmd (ctrl, drive, ATA_CMD_SET_FEATURE, ATA_SUB_SET_RWMODE,
                   pDrive->rwMode);

    /* Disable reverting to power on defaults */
#if 1
    (void) ataCmd (ctrl, drive, ATA_CMD_SET_FEATURE, 0x5, 0xFE);
#endif
    /* Set multiple mode (multisector read/write) */

    if ((pDrive->rwPio == ATA_PIO_MULTI) && 
        (pDrive->type == ATA_TYPE_ATA))
        {
        if (pDrive->okMulti)
            (void) ataCmd (ctrl, drive, ATA_CMD_SET_MULTI,
                           pDrive->multiSecs, NULL);
        else
            pDrive->rwPio = ATA_PIO_SINGLE;
        }

    pDrive->state = ATA_DEV_OK;

    config_chipset_for_dma (ctrl,drive);

driveInitExit:

    semGive (&ataCtrl[0].muteSem);

    if (pDrive->state != ATA_DEV_OK)
        {
        ATA_DEBUG_MSG (1, "ataDriveInit%d/%d: ERROR: state=%d dev=0x%x "
                       "status=0x%x error=0x%x\n", ctrl, drive, pDrive->state, 
                       ATA_IO_BYTE_READ (pCtrl->sdh), 
                       ATA_IO_BYTE_READ (pCtrl->status), 
                       ATA_IO_BYTE_READ (pCtrl->error));
        return (ERROR);
        }

    return (OK);
    } /* ataDriveInit */

void    sysInWordString
    (
    ULONG port,
    UINT16 *pData,
    int count
    ) 
    {
    UINT32 volatile_noncached *x;
    UINT32 volatile_noncached *y;
    int    status;
    int     i;

    x = (UINT32 volatile_noncached *)PCIA_PIO_CMD;
    y = (((UINT32)port & 0x4) == 0) ? 
          (UINT32 volatile_noncached *)PCIA_PIO_DATA_E : 
          (UINT32 volatile_noncached *)PCIA_PIO_DATA_O;
    
    status = intLock();
    
    *x = PCI_CMD_IO_READ;
    *(x+1) = (UINT32)port;
    for (i=0;i<count;i++) {

   

       *(pData + i) = *((UINT16 volatile_noncached *)(((UINT32)y) | ((UINT32)port & 0x3)));
    }
   
    intUnlock(status);
    return; 

    }


void    sysInLongString
    (
    ULONG port,
    ULONG *pData,
    int count
    )
    {
    int i;

    /*logMsg("params to sysInLongString: port:0x%x pData:0x%x count:0x%x\n",port,pData,count,0,0,0);
    taskDelay(5);*/
    if ((unsigned int)pData & 3) {
	 /*logMsg("Not aligned sysInLongString: breaking into sysInWordString()\n",0,0,0,0,0,0); */
      /* wkc -- hack, if not aligned, then do words... */
      //sysInWordString(port,(short *)pData,count*2);
      for(i=0;i<count*2;i++) {
          sysInWordString(port,((UINT16 *)pData)+i,2);
      }
      return;
    } 
    for(i=0;i<count;i++)
        *(pData + i) = sysInLong(port);
    }

void    sysOutWordString
    (
    ULONG port,
    UINT16 *pData,
    int count
    )
{
     int i;
     UINT32 volatile_noncached *x;
     UINT32 volatile_noncached *y;
     int    status;

     x = (UINT32 volatile_noncached *)PCIA_PIO_CMD;
     y = (((UINT32)port & 0x4) == 0) ? 
          (UINT32 volatile_noncached *)PCIA_PIO_DATA_E : 
          (UINT32 volatile_noncached *)PCIA_PIO_DATA_O;

     status = intLock();



     for(i=0;i<count;i++) {
        *x = PCI_CMD_IO_WRITE;
        *(x+1) = (UINT32)port;
        *((UINT16 volatile_noncached *)(((UINT32)y) | ((UINT32)port & 0x3))) = *(pData + i);
    }
    intUnlock(status);

    return;
}



void    sysOutLongString
    (
    ULONG port,
    ULONG *pData, 
    int count
    )
    {
    int i;
    for(i=0;i<count;i++)
       sysOutLong(port,*(pData+i));
    }


/*******************************************************************************
*
* 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 */
    int 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;
    int ix;
    ATA_DRIVE *pDrive;
    int drive;
    STATUS status;

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



    if (!ataDrvInstalled)
	{

	  
	  for (ix = 0; ix < ATA_MAX_CTRLS; ix++) {
	    memset(&ataCtrl[ix],0,sizeof(ATA_CTRL));
	    ataCtrl[ix].wdgId = wdCreate ();
	  }
	  semBInit (&ataCtrl[0].syncSem, SEM_Q_FIFO, SEM_EMPTY);
	  semMInit (&ataCtrl[0].muteSem, SEM_Q_PRIORITY | SEM_DELETE_SAFE |
		    SEM_INVERSION_SAFE);

	  /* clear any unexpected pci interrupts */
	  ATA_IO_BYTE_READ (ATA_STATUS	(ataResources[0].resource.ioStart[0]));
	  ATA_IO_BYTE_READ (ATA_STATUS	(ataResources[1].resource.ioStart[0]));

          status = pciIntConnect((VOIDFUNCPTR *)INUM_TO_IVEC (ataResources[ctrl].intVector),(VOIDFUNCPTR)ataIntr, 0);
	  
	  if (status != OK) {
#ifdef  ATA_DEBUG
	       printErr ("ERROR: pciIntConnect\n");
#endif  /* ATA_DEBUG */
	       return status;
	  }	  

	  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->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]);


	  
#ifdef INCLUDE_VCON_MODULE
(void) VCIOintConnect ((VOIDFUNCPTR *)INUM_TO_IVEC(ataResources[ctrl].intVector),(VOIDFUNCPTR)ataIntr, ctrl);
#endif

#ifdef  INCLUDE_VT82C686B

(void) SuperIOintConnect ((VOIDFUNCPTR *)INUM_TO_IVEC(ataResources[ctrl].intVector),(VOIDFUNCPTR)ataIntr, ctrl);

    
#else


#endif 

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

	  pCtrl->installed = TRUE;
        
	  status = ataInit (ctrl,0);

	  if (status != OK)
	       return status;
          for (drive = 0; drive < ATA_MAX_DRIVES; drive++)
              ataDevIdentify (ctrl, drive);
 		
	  for (drive = 0; drive < drives; drive++) {
	        pDrive = &pCtrl->drive[drive];//only one drive on each chain
		pDrive->state	= ATA_DEV_INIT;
		//pDrive->type	= ATA_TYPE_INIT;
		pDrive->diagCode	= 0;
		pDrive->Reset	= ataInit;
		dllInit(&pDrive->ataDevList);
                if (pDrive->type != ATA_TYPE_NONE) {
                    status = ataDriveInit(ctrl,drive);
                    if (status == OK) {
                        pCtrl->drives++;
                    }
		}
	  }
 
	  /* Call system INIT routine to allow proper PIO mode setup and mount drives */
         
	  SYS_ATA_INIT_RTN (ctrl);

	}


    return (OK);
    } /* ataDrv */

/*******************************************************************************
*
* ataDevCreate - create a device for a ATA/IDE disk
*
* This routine creates a device for a specified ATA/IDE disk.
*
* <drive> is a drive number for the hard drive; it must be 0 or 1.
*
* The <nBlocks> parameter specifies the size of the device in blocks.
* If <nBlocks> is zero, the whole disk is used.

⌨️ 快捷键说明

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