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

📄 atadrv.c

📁 promise20265的驱动源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	    {
	    if (++retryRW0 > ataRetry)
		{
	        (void)ataCmd (pDev->ctrl, pDev->drive, ATA_CMD_RECALIB, NULL,
			      NULL);
	        if (++retryRW1 > ataRetry)
		    goto done;
	        retrySeek = 0;
	        while (ataCmd (pDev->ctrl, pDev->drive, ATA_CMD_SEEK, cylinder,
			       head) != OK)
	            if (++retrySeek > ataRetry)
		        goto done;
	        retryRW0 = 0;
		}
	    }

        startBlk += nSecs;
        pBuf += pBlkDev->bd_bytesPerBlk * nSecs;
	}

    status = OK;

done:
#ifndef BUILD_BOOTROM
    if (status == ERROR)
        (void)errnoSet (S_ioLib_DEVICE_ERROR);
#endif
    semGive (&ataCtrl[0].muteSem);
    return (status);
    } /* ataBlkRW */

/*******************************************************************************
*
* ataIntr - ATA/IDE controller interrupt handler.
*
* RETURNS: N/A
*/

LOCAL void ataIntr
(
 int ctrl
)
{
  ATA_CTRL *pCtrl;
  
  

  pCtrl = &ataCtrl[0];
  
  if (pCtrl->installed) {
    ATA_INTR_MSG ("ataIntr %d miriam\n", 0, 0, 0, 0, 0, 0);	
    pCtrl->intCount++;
    pCtrl->intStatus = ATA_IO_BYTE_READ (pCtrl->status);
  }    
  pCtrl = &ataCtrl[1];
  if (pCtrl->installed) {
    ATA_INTR_MSG ("ataIntr %d miriam\n", 1, 0, 0, 0, 0, 0);
    pCtrl->intCount++;
    pCtrl->intStatus = ATA_IO_BYTE_READ (pCtrl->status);
  }
  semGive (&ataCtrl[0].syncSem);    
      
} /* ataIntr */

/*******************************************************************************
*
* ataWdog - ATA/IDE controller watchdog handler.
*
* RETURNS: N/A
*/

LOCAL void ataWdog
    (
    int ctrl
    )
    {
    ATA_CTRL *pCtrl	= &ataCtrl[ctrl];

    pCtrl->wdgOkay = FALSE;
    } /* ataWdog */

/*******************************************************************************
*
* ataWait - wait the drive ready
*
* Wait the drive ready
*
* RETURNS: OK, ERROR if the drive didn't become ready in certain period of time.
*/

LOCAL STATUS ataWait
    (
    int 	ctrl,
    int         drive,
    int 	request,
    BOOL	reset
    )
    {
    ATA_CTRL *	pCtrl	= &ataCtrl[ctrl];
    ATA_DRIVE *	pDrive;
 

    ATA_DEBUG_MSG (3, "ataWait: ctrl=%d  request=0x%x\n", ctrl, request, 0, 0, 
                   0, 0);

    pDrive = &pCtrl->drive[drive];

    switch (request)
	{
	case ATA_STAT_READY:
    ATA_DEBUG_MSG (3, "ataWait:0x%x - case ATA_STAT_READY-wdStart\n",hmpv_read_fcnt(), 0, 0, 0, 0, 0);
	    wdStart (pCtrl->wdgId, (sysClkRateGet() * pCtrl->wdgTimeout), 
		     (FUNCPTR)ataWdog, ctrl);
    ATA_DEBUG_MSG (3, "ataWait:0x%x - ATA_STAT_BUSY\n",hmpv_read_fcnt(), 0, 0, 0, 0, 0);
            while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_BUSY) && 
		   (pCtrl->wdgOkay))
	        ;
    ATA_DEBUG_MSG (3, "ataWait:0x%x - ATA_STAT_READY\n",hmpv_read_fcnt(), 0, 0, 0, 0, 0);
            while (((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_READY) == 0)
                   && (pCtrl->wdgOkay))
	        ;
    ATA_DEBUG_MSG (3, "ataWait:0x%x - ATA_STAT_DRQ\n",hmpv_read_fcnt(), 0, 0, 0, 0, 0);
            while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_DRQ) &&
		   (pCtrl->wdgOkay))
                ;
    ATA_DEBUG_MSG (3, "ataWait:0x%x - wdCancel\n",hmpv_read_fcnt(), 0, 0, 0, 0, 0);
	    wdCancel (pCtrl->wdgId);

            if (!pCtrl->wdgOkay)
	        {
	        pCtrl->wdgOkay = TRUE;
                if (reset == TRUE)
	            (void) pDrive->Reset (ctrl, drive);
                return (ERROR);
	        }
	    break;

	case ATA_STAT_ACCESS:
	    wdStart (pCtrl->wdgId, (sysClkRateGet() * pCtrl->wdgTimeout), 
		     (FUNCPTR)ataWdog, ctrl);
            while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_BUSY) && 
		   (pCtrl->wdgOkay))
	        ;
            while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_DRQ) &&
		   (pCtrl->wdgOkay))
                ;
	    wdCancel (pCtrl->wdgId);

            if (!pCtrl->wdgOkay)
	        {
	        pCtrl->wdgOkay = TRUE;
                if (reset == TRUE)
	            (void) pDrive->Reset (ctrl, drive);
                return (ERROR);
	        }
	    break;

	case ATA_STAT_BUSY:
            while (ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_BUSY)
		;
	    break;

	case ATA_STAT_DRQ:
            while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_DRQ) == 0)
	        ;
	    break;

	case ATA_STAT_SEEKCMPLT:
            while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_SEEKCMPLT) 
                   == 0)
	        ;
	    break;
        case ATA_STAT_DMRD:
            while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_DMRD) 
                   == 0)
	        ;
            break;
	}

    ATA_DEBUG_MSG (3, "ataWait end:\n", 0, 0, 0, 0, 0, 0);

    return (OK);
    } /* ataWait */

/*******************************************************************************
*
* ataInit - init a ATA/IDE disk controller
*
* This routine initializes a ATA/IDE disk controller.
*
* RETURNS: OK, ERROR if the command didn't succeed.
*/

LOCAL STATUS ataInit
    (
    int ctrl,
    int drive
    )
    {
    u_long retaddr = hmpv_return_address();
    ATA_CTRL *pCtrl	= &ataCtrl[ctrl];
    int ix;

    ATA_DEBUG_MSG (1, "ataInit:%d/%d from %p\n", ctrl, drive, retaddr, 0, 0, 0);

    /* Set reset bit */
#if 1
    ATA_IO_BYTE_WRITE (pCtrl->dControl, ATA_CTL_4BIT | ATA_CTL_RST);
#else
     ATA_IO_BYTE_WRITE (pCtrl->dControl,ATA_CTL_RST);
#endif
//    for (ix = 0; ix < 20; ix++)		/* >= 5 mks */
//
//    ATA_WAIT_STATUS;

     /*wait 5usec */
     ataWaitStatus(5000);
    /* Clear reset bit */
#if 1
    ATA_IO_BYTE_WRITE (pCtrl->dControl, ATA_CTL_4BIT);
#else
    ATA_IO_BYTE_WRITE (pCtrl->dControl, 0);
#endif

//    for (ix = 0; ix < 5000; ix++)	/* 2 ms */
//        ATA_WAIT_STATUS;

    ataWaitStatus(2000000);
    pCtrl->wdgOkay = TRUE;

    /* Start the ATA  watchdog */

    wdStart (pCtrl->wdgId, (sysClkRateGet() * pCtrl->wdgTimeout),
	     (FUNCPTR)ataWdog, ctrl);

    /* Wait for BUSY bit to be cleared */

    while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_BUSY) &&
           (pCtrl->wdgOkay))
	;

    /* Stop the ATA watchdog */

    wdCancel (pCtrl->wdgId);

    if (!pCtrl->wdgOkay)
        {
	ATA_DEBUG_MSG (1, "ataInit error:\n", 0, 0, 0, 0, 0, 0);
        pCtrl->wdgOkay = TRUE;
        return (ERROR);
        }

    /* The following allow to recover after accidental interrupt */

    if (semTake (&ataCtrl[0].syncSem, NO_WAIT) == OK)
        {
        ATA_DEBUG_MSG (1, "ataInit%d/%d: WARNING: interrupt cleared\n",  
                       ctrl, drive, 0, 0, 0, 0);
        }
    else
        {
        ATA_DEBUG_MSG (2, "ataInit%d/%d: Ok\n", ctrl, drive, 0, 0, 0, 0);
        }


    //ATA_DEBUG_MSG (3, "ataInit Calling sysAtaInit (if present):\n", 0, 0, 0, 0, 0, 0);

        /* Call out to bsp specific setup routine */
        //SYS_ATA_INIT_RTN (ctrl);                

	//ATA_DEBUG_MSG (3, "ataInit sysAtaInit returned\n", 0, 0, 0, 0, 0, 0);

	ATA_DEBUG_MSG (2, "ataInit end\n", 0, 0, 0, 0, 0, 0);

    return (OK);
    } /* ataInit */

/*******************************************************************************
*
* ataCmd - issue non data command
*
* Issue a non data command.  Non data commands have the same protocol.
*
* RETURNS: OK, ERROR if the command didn't succeed.
*/

LOCAL STATUS ataCmd
    (
    int ctrl,
    int drive,
    int cmd,
    int arg0,
    int arg1
    )
    {
    ATA_CTRL *pCtrl	= &ataCtrl[ctrl];
    ATA_TYPE *pType	= &ataTypes[ctrl][drive];
    BOOL retry		= TRUE;
    int retryCount	= 0;
    int semStatus;

    ATA_DEBUG_MSG (1, "ataCmd%d/%d: cmd=0x%x 0x%x 0x%x\n", ctrl, drive, cmd, arg0, arg1, 
                   0);

    while (retry)
	{
        ataWait (ctrl,drive, ATA_STAT_READY, TRUE);

	switch (cmd)
	    {
	    case ATA_CMD_INITP:
		ATA_IO_BYTE_WRITE (pCtrl->cylLo, pType->cylinders);
		ATA_IO_BYTE_WRITE (pCtrl->cylHi, pType->cylinders >> 8);
		ATA_IO_BYTE_WRITE (pCtrl->seccnt, pType->sectors);
		ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (drive << 4) | 
			    ((pType->heads - 1) & 0x0f));
		break;
	    case ATA_CMD_RECALIB:
		ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (drive << 4));
		break;
	    case ATA_CMD_SEEK:
		ATA_IO_BYTE_WRITE (pCtrl->cylLo, arg0);
		ATA_IO_BYTE_WRITE (pCtrl->cylHi, arg0>>8);
		ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (drive << 4) |
			    (arg1 & 0xf));
		break;
	    case ATA_CMD_SET_FEATURE:
        	ATA_IO_BYTE_WRITE (pCtrl->seccnt, arg1);
        	ATA_IO_BYTE_WRITE (pCtrl->feature, arg0);
        	ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (drive << 4));
		break;
	    case ATA_CMD_SET_MULTI:
        	ATA_IO_BYTE_WRITE (pCtrl->seccnt, arg0);
        	ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (drive << 4));
		break;
	    }

        ATA_IO_BYTE_WRITE (pCtrl->command, cmd);
        semStatus = semTake (&ataCtrl[0].syncSem, 
			     sysClkRateGet() * pCtrl->semTimeout);

        if ((pCtrl->intStatus & ATA_STAT_ERR) || (semStatus == ERROR))
	    {
	    ATA_DEBUG_MSG (1, "ataCmd%d/%d: ERROR: cmd=0x%x status=0x%x "
                           "semStatus=%d err=0x%x\n", ctrl, drive, cmd, 
                           pCtrl->intStatus, semStatus, 
                           ATA_IO_BYTE_READ(pCtrl->error));
	    if (++retryCount > ataRetry)
	        return (ERROR);
	    }
	else
	    retry = FALSE;
	}

	switch (cmd)
	    {
	    case ATA_CMD_SEEK:
		ataWait (ctrl,drive, ATA_STAT_SEEKCMPLT, FALSE);
		break;
	    }

    ATA_DEBUG_MSG (2, "ataCmd%d/%d: Ok\n", ctrl, drive, 0, 0, 0, 0);

    return (OK);
    } /* ataCmd */

/*******************************************************************************
*
* ataPread - Read drive parameters
*
* Read drive parameters.
*
* RETURNS: OK, ERROR if the command didn't succeed.
*/

LOCAL STATUS ataPread
    (
    int ctrl,
    int drive,
    void *buffer
    )
    {
    ATA_CTRL *pCtrl	= &ataCtrl[ctrl];
    BOOL retry		= TRUE;
    int retryCount	= 0;
    int semStatus;

    ATA_DEBUG_MSG (2, "ataPread: ctrl=%d drive=%d\n", ctrl, drive, 0, 0, 0, 0);

    while (retry)
	{
	
        ataWait (ctrl,drive, ATA_STAT_READY, TRUE);

    ATA_DEBUG_MSG (2, "ataPread: ctrl=%d drive=%d mark 1\n", ctrl, drive, 0, 0, 0, 0);
        ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (drive << 4));
    ATA_DEBUG_MSG (2, "ataPread: ctrl=%d drive=%d mark 2\n", ctrl, drive, 0, 0, 0, 0);
        ATA_IO_BYTE_WRITE (pCtrl->command, ATA_CMD_READP);
        semStatus = semTake (&ataCtrl[0].syncSem, 
			     sysClkRateGet() * pCtrl->semTimeout);

        if ((pCtrl->intStatus & ATA_STAT_ERR) || (semStatus == ERROR))
	    {
            ATA_DEBUG_MSG (1, "ataPread%d/%d - err: status=0x%x intStatus=0x%x "
                          "error=0x%x semStatus=%d\n", ctrl, drive, 
                          ATA_IO_BYTE_READ (pCtrl->aStatus), pCtrl->intStatus, 
                          ATA_IO_BYTE_READ (pCtrl->error), semStatus);

	    if (++retryCount > ataRetry)
	        return (ERROR);
	    }
        else
	    retry = FALSE;
        }

    ATA_DEBUG_MSG (2, "ataPread: ctrl=%d drive=%d mark 3\n", ctrl, drive, 0, 0, 0, 0);

⌨️ 快捷键说明

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