📄 atadrv.c
字号:
pCtrl->intLevel = level; pCtrl->wdgOkay = TRUE; pCtrl->configType = configType; semTake (&pCtrl->muteSem, WAIT_FOREVER); pCtrl->changed = FALSE; pCtrl->installed = TRUE; for (drive = 0; drive < drives; drive++) { pType = &ataTypes[ctrl][drive]; pDrive = &pCtrl->drive[drive]; pParam = &pDrive->param; pDrive->state = ATA_DEV_INIT; pDrive->type = ATA_TYPE_INIT; pDrive->diagCode = 0; pDrive->Reset = ataInit; ataDriveInit (ctrl, drive); } ATA_DEBUG_MSG (3, "ataDrv Calling sysAtaInit (if present):\n", 0, 0, 0, 0, 0, 0); /* Call system INIT routine to allow proper PIO mode setup */ SYS_ATA_INIT_RTN (ctrl); ATA_DEBUG_MSG (3, "ataDrv sysAtaInit returned:\n", 0, 0, 0, 0, 0, 0); semGive (&pCtrl->muteSem); } return (OK); }/********************************************************************************* ataDevCreate - create a device for a ATA/IDE disk** This routine creates a device for a specified ATA/IDE or ATAPI CDROM disk.** <ctrl> is a controller number for the ATA controller; the primary controller* is 0. The maximum is specified via ATA_MAX_CTRLS.** <drive> is the drive number for the ATA hard drive; the master drive* is 0. The maximum is specified via ATA_MAX_DRIVES.** 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, /* ATA controller number, 0 is the primary controller */ int drive, /* ATA drive number, 0 is the master drive */ int nBlocks, /* number of blocks on device, 0 = use entire disc */ int blkOffset /* offset BLK_DEV nBlocks from the start of the drive */ ){ ATA_CTRL *pCtrl = &ataCtrl[ctrl]; ATA_TYPE *pType = &ataTypes[ctrl][drive]; ATA_DRIVE *pDrive = &pCtrl->drive[drive]; ATA_PARAM *pParam = &pDrive->param; /* move * */ ATA_DEV *pDev; BLK_DEV *pBlkdev; int maxBlks; ATA_DEBUG_MSG (3, "Enter into ataDevCreate\n", 0, 0, 0, 0, 0, 0); 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 ((pDrive->state == ATA_DEV_OK) || (pDrive->state == ATA_DEV_MED_CH)) { pDrive->state = ATA_DEV_MED_CH; if (pDrive->type == ATA_TYPE_ATA) { /* * 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 = FALSE; pBlkdev->bd_retry = 0; 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; pDev->ctrl = ctrl; pDev->drive = drive; pDev->blkOffset = blkOffset; } else if (pDrive->type == ATA_TYPE_ATAPI) { pBlkdev->bd_nBlocks = 100; pBlkdev->bd_bytesPerBlk = 2048; pBlkdev->bd_blksPerTrack = pBlkdev->bd_nBlocks; pBlkdev->bd_nHeads = 1; if (pParam->config & CONFIG_REMOVABLE) pBlkdev->bd_removable = TRUE; else pBlkdev->bd_removable = FALSE; pBlkdev->bd_retry = 0; pBlkdev->bd_mode = O_RDONLY; pBlkdev->bd_readyChanged = TRUE; pBlkdev->bd_blkRd = ataPiBlkRd; pBlkdev->bd_blkWrt = ataStub; pBlkdev->bd_ioctl = ataPiIoctl; pBlkdev->bd_reset = ataPiReset; pBlkdev->bd_statusChk = ataPiStatusChk; pDev->ctrl = ctrl; pDev->drive = drive; pDev->blkOffset = blkOffset; pDev->nBlocks = nBlocks; } ataDriveInit (ctrl, drive); pDrive->state = ATA_DEV_OK; } 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; ATA_DEBUG_MSG (3, "Enter into ataRawio\n", 0, 0, 0, 0, 0, 0); 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 = 0; pBlkdev->bd_mode = O_RDWR; pBlkdev->bd_readyChanged = TRUE; pBlkdev->bd_blkRd = ataBlkRd; pBlkdev->bd_blkWrt = ataBlkWrt; pBlkdev->bd_ioctl = ataIoctl; pBlkdev->bd_reset = NULL; pBlkdev->bd_statusChk = NULL; 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 ) { ATA_DEBUG_MSG (1, "Enter into ataBlkRd: nBlks=%d\n", nBlks, 0, 0, 0, 0, 0); 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 ) { ATA_DEBUG_MSG (1, "Enter into ataBlkWrt: nBlks=%d\n", nBlks, 0, 0, 0, 0, 0); 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]; ATA_DEBUG_MSG (3, "Enter into ataReset\n", 0, 0, 0, 0, 0, 0); if (!pCtrl->installed) return (ERROR); semTake (&pCtrl->muteSem, WAIT_FOREVER); (void) ataInit (pDev->ctrl, 0); 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; ATA_DEBUG_MSG (3, "Enter into ataStatus\n", 0, 0, 0, 0, 0, 0); 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]; register UINT localStatus; /* local status variable */ ATA_DEBUG_MSG (3, "Enter into ataIoctl\n", 0, 0, 0, 0, 0, 0); if (!pCtrl->installed) return (ERROR); semTake (&pCtrl->muteSem, WAIT_FOREVER); switch (function) { case FIODISKFORMAT: /*(void) errnoSet (S_ioLib_UNKNOWN_REQUEST); localStatus = ERROR;*/ pDev->blkDev.bd_readyChanged = TRUE; break; default: (void) errnoSet (S_ioLib_UNKNOWN_REQUEST); localStatus = ERROR; break; } semGive (&pCtrl->muteSem); return ((localStatus ? ERROR : OK)); }/********************************************************************************* 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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -