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

📄 atadrv.c

📁 promise20265的驱动源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
*
* The <blkOffset> parameter specifies an offset, in blocks, from the start
* of the device to be used when writing or reading the hard disk.  This
* offset is added to the block numbers passed by the file system during
* disk accesses.  (VxWorks file systems always use block numbers beginning
* at zero for the start of a device.)
*
*
* RETURNS:
* A pointer to a block device structure (BLK_DEV) or NULL if memory cannot
* be allocated for the device structure.
*
* SEE ALSO: dosFsMkfs(), dosFsDevInit(), rt11FsDevInit(), rt11FsMkfs(),
* rawFsDevInit()
*/

BLK_DEV *ataDevCreate
    (
    int ctrl,
    int drive,
    int nBlocks,
    int blkOffset
    )
    {
    ATA_CTRL *	pCtrl	= &ataCtrl[ctrl];
    ATA_DRIVE *	pDrive	= &pCtrl->drive[drive];
    ATA_DEV *	pDev;


    if ((ctrl >= ATA_MAX_CTRLS) || (drive >= ATA_MAX_DRIVES) ||
        !ataDrvInstalled || !pCtrl->installed)
	return (NULL);
#define HARRIET
#ifndef HARRIET
    /* If no drive then return an error */
    if (pDrive->state == ATA_DEV_NONE)
	 return (NULL);
#endif

    ATA_DEBUG_MSG (1, "ataDevCreate entry%d/%d: entry:  nBlocks %d blkOffset %d\n  "
		   ,ctrl,drive,nBlocks,blkOffset,0,0);
#if FALSE /* To forbid creation of some block devices for the same physycal 
           * device change FALSE to TRUE.  Also freeing of BLK_DEV structure
           * must be removed from PCMCIA code in this case.
           */
    if (pDrive->pAtaDev != 0)
        return (NULL);	/* avoid creation of another block device */
#endif

    if ((pDev = (ATA_DEV *)memalign(32,sizeof (ATA_DEV))) == NULL)
        return (NULL);

    memset(pDev,0,sizeof(ATA_DEV));

    pDrive->pAtaDev = pDev;
    dllAdd (&pDrive->ataDevList, &pDev->node);
    pDev->ctrl			= ctrl;
    pDev->drive			= drive;
    pDev->blkOffset		= blkOffset;
    pDev->nBlocks		= nBlocks;

    ataBlkDevFill(pDrive->pAtaDev);

    if (pDrive->type == ATA_TYPE_ATAPI) {
       ataPiTestUnitRdy(&pDev->blkDev);
       ataPiGetConfiguration(&pDev->blkDev);
    }
 
#if 0
    ataDriveInit( ctrl, drive );
#endif

#ifdef ATA_DEBUG
    pgDevice[ctrl][drive] = &pDev->blkDev;
#endif
  
    return (&pDev->blkDev);
    } /* ataDevCreate */

/*******************************************************************************
*
* ataRawio - do raw I/O access
*
* This routine is called to perform raw I/O access.
*
* <drive> is a drive number for the hard drive: it must be 0 or 1.
*
* The <pAtaRaw> is a pointer to the structure ATA_RAW which is defined in 
* ataDrv.h.
*
* RETURNS:
* OK, or ERROR if the parameters are not valid.
*
*/

STATUS ataRawio
    (
    int ctrl,
    int drive,
    ATA_RAW *pAtaRaw
    )
    {
    ATA_CTRL *pCtrl	= &ataCtrl[ctrl];
    ATA_DRIVE *	pDrive	= &pCtrl->drive[drive];
    ATA_TYPE *pType	= &ataTypes[ctrl][drive];
    ATA_DEV ataDev;
    BLK_DEV *pBlkDev	= &ataDev.blkDev;
    UINT startBlk;

    if ((ctrl >= ATA_MAX_CTRLS) || (drive >= ATA_MAX_DRIVES) ||
        !ataDrvInstalled || !pCtrl->installed)
        return (ERROR);

    if ( (pDrive->state != ATA_DEV_OK) && (pDrive->state != ATA_DEV_MED_CH) )
        return (ERROR);

    if ((pAtaRaw->cylinder	>= pType->cylinders)	||
        (pAtaRaw->head		>= pType->heads)	||
        (pAtaRaw->sector	>  pType->sectors)	||
        (pAtaRaw->sector	== 0))
	return (ERROR);


	/*
	 * if LBA is supported and ataLbaTotalSecs is not zero
	 * and ataLbaTotalSecs is greater than the product of
	 * CHS, then we should use the LBA value.
	 */

    if ((pDrive->okLba == TRUE)             && 
		(ataLbaTotalSecs[ctrl][drive] != 0) &&
		(ataForceCHSonLBA != TRUE)		    &&
		(ataLbaTotalSecs[ctrl][drive] > 
		 (pType->cylinders * pType->heads * pType->sectors)))   
	{
	  pBlkDev->bd_nBlocks = ataLbaTotalSecs[ctrl][drive];
	}
    else /* just use CHS value */
	{
	  pBlkDev->bd_nBlocks	= pType->cylinders * pType->heads * 
		pType->sectors;
	}

    pBlkDev->bd_bytesPerBlk	= pType->bytes;
    pBlkDev->bd_blksPerTrack	= pType->sectors;
    pBlkDev->bd_nHeads		= pType->heads;
    pBlkDev->bd_removable	= FALSE;
    pBlkDev->bd_retry		= 1;
    pBlkDev->bd_mode		= O_RDWR;
    pBlkDev->bd_readyChanged	= TRUE;
    pBlkDev->bd_blkRd		= ataBlkRd;
    pBlkDev->bd_blkWrt		= ataBlkWrt;
    pBlkDev->bd_ioctl		= ataIoctl;
    pBlkDev->bd_reset		= ataReset;
    pBlkDev->bd_statusChk	= ataStatus;

    ataDev.ctrl			= ctrl;
    ataDev.drive		= drive;
    ataDev.blkOffset		= 0;

    startBlk = pAtaRaw->cylinder * (pType->sectors * pType->heads) +
	       pAtaRaw->head * pType->sectors + pAtaRaw->sector - 1;

    return (ataBlkRW (&ataDev, startBlk, pAtaRaw->nSecs, pAtaRaw->pBuf,
		     pAtaRaw->direction));
    } /* ataRawio */

/*******************************************************************************
*
* ataBlkRd - read one or more blocks from a ATA/IDE disk
*
* This routine reads one or more blocks from the specified device,
* starting with the specified block number.
*
* If any block offset was specified during ataDevCreate(), it is added
* to <startBlk> before the transfer takes place.
*
* RETURNS: OK, ERROR if the read command didn't succeed.
*/

LOCAL STATUS ataBlkRd
    (
    ATA_DEV *pDev,
    int startBlk,
    int nBlks,
    char *pBuf
    )
    {
	ATA_DEBUG_MSG (2, "**********ataBlkRd:0x%lx: readonly - startblk is 0x%x, nBlks=0x%x\n", hmpv_read_fcnt(),startBlk, nBlks, 0, 0, 0);

    return (ataBlkRW (pDev, startBlk, nBlks, pBuf, O_RDONLY));
    } /* ataBlkRd */

/*******************************************************************************
*
* ataBlkWrt - write one or more blocks to a ATA/IDE disk
*
* This routine writes one or more blocks to the specified device,
* starting with the specified block number.
*
* If any block offset was specified during ataDevCreate(), it is added
* to <startBlk> before the transfer takes place.
*
* RETURNS: OK, ERROR if the write command didn't succeed.
*/

LOCAL STATUS ataBlkWrt
    (
    ATA_DEV *pDev,
    int startBlk,
    int nBlks,
    char *pBuf
    )
    {
	ATA_DEBUG_MSG (2, "**********ataBlkWrt:0x%lx: readonly - startblk is 0x%x, nBlks=0x%x\n", hmpv_read_fcnt(),startBlk, nBlks, 0, 0, 0);
      
    return (ataBlkRW (pDev, startBlk, nBlks, pBuf, O_WRONLY));
    } /* ataBlkWrt */

/*******************************************************************************
*
* ataReset - reset a ATA/IDE disk controller
*
* This routine resets a ATA/IDE disk controller.
*
* RETURNS: OK, always.
*/

LOCAL STATUS ataReset
    (
    ATA_DEV *pDev
    )
    {
    ATA_CTRL *	pCtrl	= &ataCtrl[pDev->ctrl];
    ATA_DRIVE *	pDrive	= &pCtrl->drive[pDev->drive];

    if (!pCtrl->installed)
        return (ERROR);

    if (pDrive->state != ATA_DEV_MED_CH)
        {	/* power on, entire drive changed, or failure recovering */
        semTake (&ataCtrl[0].muteSem, WAIT_FOREVER);
      
        if (pDrive->state != ATA_DEV_INIT)
            {	/* higher level tried to recover after failure */
            if (pDrive->Reset (pDev->ctrl, pDev->drive) != OK)
                {
                semGive (&ataCtrl[0].muteSem);
                return (ERROR);
                }
            }
#if 0
        if (ataDriveInit (pDev->ctrl, pDev->drive) != OK)
            {
            semGive (&ataCtrl[0].muteSem);
            return (ERROR);
            }
#endif
        semGive (&ataCtrl[0].muteSem);
        }

    /* Identify medium */

    pDrive->state = ATA_DEV_OK;

    return (OK);
    } /* ataReset */

/*******************************************************************************
*
* ataStatus - check status of a ATA/IDE disk controller
*
* This routine check status of a ATA/IDE disk controller.
*
* RETURNS: OK, ERROR if the card is removed.
*/

LOCAL STATUS ataStatus
    (
    ATA_DEV *pDev
    )
    {

    ATA_CTRL *pCtrl	= &ataCtrl[pDev->ctrl];
    ATA_DRIVE *pDrive	= &pCtrl->drive[pDev->drive];
    BLK_DEV *pBlkDev	= &pDev->blkDev;

    if (!pCtrl->installed)
        return (ERROR);

    if (pDrive->state != ATA_DEV_OK)
	return (ERROR);

    if (pCtrl->changed)
	{
	     /*pBlkDev->bd_readyChanged = TRUE; */
	     ataSetbd_readyChanged(pDev);
	     pCtrl->changed		 = FALSE;
	}

    return (OK);
    } /* ataStatus */

/*******************************************************************************
*
* ataIoctl - do device specific control function
*
* This routine is called when the file system cannot handle an ioctl()
* function.
*
* RETURNS:  OK or ERROR.
*/

LOCAL STATUS ataIoctl
    (
    ATA_DEV *pDev,
    int function,
    int arg
    )
    {
    ATA_CTRL *pCtrl	= &ataCtrl[pDev->ctrl];
    ATA_DRIVE *pDrive	= &pCtrl->drive[pDev->drive];
    FAST int status	= ERROR;

    if (!pCtrl->installed)
        return (ERROR);

    if (pDrive->state != ATA_DEV_OK)
        return (ERROR);

    semTake (&ataCtrl[0].muteSem, WAIT_FOREVER);
#ifndef BUILD_BOOTROM
    switch (function)
	{
	case FIODISKFORMAT:
	    (void) errnoSet (S_ioLib_UNKNOWN_REQUEST);
	    break;

	default:
	    (void) errnoSet (S_ioLib_UNKNOWN_REQUEST);
	}
#endif

    semGive (&ataCtrl[0].muteSem);
    return (status);
    } /* ataIoctl */

/*******************************************************************************
*
* ataBlkRW - read or write sectors to a ATA/IDE disk.
*
* Read or write sectors to a ATA/IDE disk.
*
* RETURNS: OK, ERROR if the command didn't succeed.
*/

LOCAL STATUS ataBlkRW
    (
    ATA_DEV *pDev,
    int startBlk,
    int nBlks,
    char *pBuf,
    int direction
    )
    {
    ATA_CTRL *pCtrl	= &ataCtrl[pDev->ctrl];
    ATA_DRIVE *pDrive	= &pCtrl->drive[pDev->drive];
    BLK_DEV *pBlkDev	= &pDev->blkDev;
    ATA_TYPE *pType	= &ataTypes[pDev->ctrl][pDev->drive];
    int status		= ERROR;
    int retryRW0	= 0;
    int retryRW1	= 0;
    int retrySeek	= 0;
    int cylinder;
    int head;
    int sector;
    int nSecs;
    int ix;

    /* sanity check */

    if (!pCtrl->installed)
        return (ERROR);

    if (pDrive->state != ATA_DEV_OK)
        return (ERROR);

    nSecs = pBlkDev->bd_nBlocks;
    if ((startBlk + nBlks) > nSecs)
	{
	ATA_DEBUG_MSG (1, "startBlk=%d nBlks=%d: 0 - %d\n", startBlk, nBlks, 
                       nSecs, 0, 0, 0);
	return (ERROR);
	}

    startBlk += pDev->blkOffset;

    semTake (&ataCtrl[0].muteSem, WAIT_FOREVER);

    for (ix = 0; ix < nBlks; ix += nSecs)
	{
	if (pDrive->okLba)
	    {
	    head     = (startBlk & 0x0f000000) >> 24;
	    cylinder = (startBlk & 0x00ffff00) >> 8;
	    sector   = (startBlk & 0x000000ff);
	    }
	else
	    {
	    cylinder = startBlk / (pType->sectors * pType->heads);
	    sector   = startBlk % (pType->sectors * pType->heads);
	    head     = sector / pType->sectors;
	    sector   = sector % pType->sectors + 1;
	    }
	nSecs    = min (nBlks - ix, ATA_MAX_RW_SECTORS);

	retryRW1 = 0;
	retryRW0 = 0;
	while (ataRW(pDev->ctrl, pDev->drive, cylinder, head, sector, 
	       pBuf, nSecs, direction) != OK)

⌨️ 快捷键说明

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