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

📄 atadrv.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 3 页
字号:
	    if (pDrive->pioMode > 2)	        pDrive->pioMode = 0;	    if ((pDrive->okIordy) && (pParam->valid & 0x02))	/* PIO 3,4 */		{		if (pParam->advancedPio & 0x01)		    pDrive->pioMode = 3;		if (pParam->advancedPio & 0x02)		    pDrive->pioMode = 4;		}	    /* find out supported max DMA mode */	    if ((pDrive->okDma) && (pParam->valid & 0x02))		{	        pDrive->singleDmaMode = (pParam->dmaMode >> 8) & 0x03;		if (pDrive->singleDmaMode >= 2)	            pDrive->singleDmaMode = 0;		pDrive->multiDmaMode  = 0;		if (pParam->singleDma & 0x04)		    pDrive->singleDmaMode = 2;		else if (pParam->singleDma & 0x02)		    pDrive->singleDmaMode = 1;		else if (pParam->singleDma & 0x01)		    pDrive->singleDmaMode = 0;		if (pParam->multiDma & 0x04)		    pDrive->multiDmaMode = 2;		else if (pParam->multiDma & 0x02)		    pDrive->multiDmaMode = 1;		else if (pParam->multiDma & 0x01)		    pDrive->multiDmaMode = 0;		}	    /* 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;		    break;		case ATA_DMA_0:		case ATA_DMA_1:		case ATA_DMA_2:	            if (pDrive->okDma)		        {		        if (pDrive->rwDma == ATA_DMA_SINGLE)	                    pDrive->rwMode |= ATA_DMA_SINGLE_0;		        if (pDrive->rwDma == ATA_DMA_MULTI)	                    pDrive->rwMode |= ATA_DMA_MULTI_0;		        }		    break;		case ATA_DMA_AUTO:	            if (pDrive->okDma)		        {		        if (pDrive->rwDma == ATA_DMA_SINGLE)	                    pDrive->rwMode = ATA_DMA_SINGLE_0 + 					     pDrive->singleDmaMode;		        if (pDrive->rwDma == ATA_DMA_MULTI)	                    pDrive->rwMode = ATA_DMA_MULTI_0 + 					     pDrive->multiDmaMode;		        }		    break;		default:		    break;		}	    	    /* set the transfer mode */	    (void) ataCmd (ctrl, drive, ATA_CMD_SET_FEATURE, ATA_SUB_SET_RWMODE,			   pDrive->rwMode);	    if (pDrive->rwPio == ATA_PIO_MULTI)		{	        if (pDrive->okMulti)	            (void) ataCmd (ctrl, drive, ATA_CMD_SET_MULTI,			           pDrive->multiSecs, NULL);		else		    pDrive->rwPio = ATA_PIO_SINGLE;		}	    }	pCtrl->installed = TRUE;#ifdef  ATA_DEBUG        printErr ("ataDrv Calling sysAtaInit (if present):\n");#endif  /* ATA_DEBUG */ 	/* Call system INIT routine to allow proper PIO mode setup */        SYS_ATA_INIT_RTN (ctrl); #ifdef  ATA_DEBUG        printErr ("ataDrv sysAtaInit returned:\n");#endif  /* ATA_DEBUG */	semGive (&pCtrl->muteSem);	}    return (OK);    }/********************************************************************************* 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.** 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_TYPE *pType	= &ataTypes[ctrl][drive];    ATA_DRIVE *pDrive	= &pCtrl->drive[drive];    ATA_DEV *pDev;    BLK_DEV *pBlkdev;    int	    maxBlks;    if ((ctrl >= ATA_MAX_CTRLS) || (drive >= ATA_MAX_DRIVES) ||        !ataDrvInstalled || !pCtrl->installed)	return (NULL);    if ((pDev = (ATA_DEV *)malloc(sizeof (ATA_DEV))) == NULL)	return (NULL);    pBlkdev = &pDev->blkDev;    /*      * 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)))   	{	maxBlks = (ataLbaTotalSecs[ctrl][drive]) - blkOffset;	}    else /* just use CHS */	{        maxBlks = ((pType->cylinders * pType->heads * pType->sectors) 			- blkOffset);	}    if (nBlocks == 0)	nBlocks = maxBlks;        if (nBlocks > maxBlks)	nBlocks = maxBlks;    pBlkdev->bd_nBlocks		= nBlocks;    pBlkdev->bd_bytesPerBlk	= pType->bytes;    pBlkdev->bd_blksPerTrack	= pType->sectors;    pBlkdev->bd_nHeads		= pType->heads;    pBlkdev->bd_removable	= TRUE;    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;    pBlkdev->bd_reset		= NULL;    pBlkdev->bd_statusChk	= NULL;    pDev->ctrl			= ctrl;    pDev->drive			= drive;    pDev->blkOffset		= blkOffset;    return (&pDev->blkDev);    }/********************************************************************************* 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 ((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));    }/********************************************************************************* 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    )    {    return (ataBlkRW (pDev, startBlk, nBlks, pBuf, O_RDONLY));    }/********************************************************************************* 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    )    {    return (ataBlkRW (pDev, startBlk, nBlks, pBuf, O_WRONLY));    }/********************************************************************************* 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];        if (!pCtrl->installed)	return (ERROR);    semTake (&pCtrl->muteSem, WAIT_FOREVER);    (void) ataInit (pDev->ctrl);    semGive (&pCtrl->muteSem);    return (OK);    }/********************************************************************************* 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];    BLK_DEV *pBlkdev	= &pDev->blkDev;        if (!pCtrl->installed)	return (ERROR);    if (pCtrl->changed)	{	pBlkdev->bd_readyChanged = TRUE;	pCtrl->changed		 = FALSE;	}    return (OK);    }/********************************************************************************* 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];    FAST int status	= ERROR;    if (!pCtrl->installed)        return (ERROR);    semTake (&pCtrl->muteSem, WAIT_FOREVER);    switch (function)	{	case FIODISKFORMAT:	    (void) errnoSet (S_ioLib_UNKNOWN_REQUEST);	    break;	default:	    (void) errnoSet (S_ioLib_UNKNOWN_REQUEST);	}    semGive (&pCtrl->muteSem);    return (status);    }/********************************************************************************* 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);    nSecs = pBlkdev->bd_nBlocks;    if ((startBlk + nBlks) > nSecs)	{#ifdef	ATA_DEBUG	printErr ("startBlk=%d nBlks=%d: 0 - %d\n", startBlk, nBlks, nSecs);#endif	/* ATA_DEBUG */	return (ERROR);	}    startBlk += pDev->blkOffset;    semTake (&pCtrl->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;	    }

⌨️ 快捷键说明

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