📄 scsidirectlib.c
字号:
* transferred is greater than the maximum transfer length it breaks the* data into permissible sizes and loops until the transfer is done.** RETURNS: OK, or ERROR if the sector cannot be written, or if the numSecs* is zero.*/LOCAL STATUS scsi2WrtSecs ( SCSI_BLK_DEV *pScsiBlkDev, /* ptr to SCSI block device info */ int sector, /* sector number to be read */ int numSecs, /* total sectors to be read */ char *buffer /* ptr to input data buffer */ ) { SCSI_PHYS_DEV *pScsiPhysDev = pScsiBlkDev->pScsiPhysDev; int dataToXfer; /* Total Transfer size */ int sectorNum; /* sector number to be written */ int numbSecs; /* total sectors to be written */ char *xferBuf; /* ptr to input data buffer */ STATUS xferStatus = OK; dataToXfer = numSecs * pScsiPhysDev->blockSize; xferBuf = buffer; sectorNum = sector; if (numSecs == 0) return ERROR; if (dataToXfer <= (pScsiPhysDev->pScsiCtrl->maxBytesPerXfer)) xferStatus = scsiSectorWrite (pScsiBlkDev,sector,numSecs,buffer); else { while (dataToXfer > 0) { /* determine the number of sectors to written */ if (dataToXfer > (pScsiPhysDev->pScsiCtrl->maxBytesPerXfer)) numbSecs = (pScsiPhysDev->pScsiCtrl->maxBytesPerXfer) / pScsiPhysDev->blockSize; else numbSecs = dataToXfer / pScsiPhysDev->blockSize; /* write the sectors */ xferStatus = scsiSectorWrite (pScsiBlkDev,sectorNum,numbSecs, xferBuf); if (xferStatus == OK) { /* * increment the sector no, buffer pointers & update the * bytes left to be transferred */ sectorNum += numbSecs; xferBuf += (numbSecs * pScsiPhysDev->blockSize); dataToXfer -= (numbSecs * pScsiPhysDev->blockSize); } else return (xferStatus); } } return (xferStatus); }/********************************************************************************* scsiSectorWrite - write sector(s) to a SCSI block device** This routine writes the specified physical sector(s) to a specified physical* device.** RETURNS: OK, or ERROR if the sector cannot be written.*/LOCAL STATUS scsiSectorWrite ( SCSI_BLK_DEV *pScsiBlkDev, /* ptr to SCSI block device info */ int sector, /* sector number to be read */ int numSecs, /* total sectors to be read */ char *buffer /* ptr to input data buffer */ ) { SCSI_COMMAND writeCommand; /* SCSI command byte array */ SCSI_TRANSACTION scsiXaction; /* info on a SCSI transaction */ SCSI_PHYS_DEV *pScsiPhysDev = pScsiBlkDev->pScsiPhysDev; int startSec = sector + pScsiBlkDev->blockOffset; SCSI_DEBUG_MSG ("scsiWrtSecs:\n", 0, 0, 0, 0, 0, 0); if (startSec <= SCSI_BLOCK_ADDRESS_SIZE && numSecs <= 256) { /* build a 21 bit logical block address 'WRITE' command */ if (scsiCmdBuild (writeCommand, &scsiXaction.cmdLength, SCSI_OPCODE_WRITE, pScsiPhysDev->scsiDevLUN, FALSE, startSec, (numSecs == 256 ? 0 : numSecs), (UINT8) 0) == ERROR) { return (ERROR); } } else { /* build a 32 bit logical block address 'WRITE_EXTENDED' command */ if (scsiCmdBuild (writeCommand, &scsiXaction.cmdLength, SCSI_OPCODE_WRITE_EXT, pScsiPhysDev->scsiDevLUN, FALSE, startSec, numSecs, (UINT8) 0) == ERROR) return (ERROR); } scsiXaction.cmdAddress = writeCommand; scsiXaction.dataAddress = (UINT8 *) buffer; scsiXaction.dataDirection = O_WRONLY; scsiXaction.dataLength = numSecs * pScsiPhysDev->blockSize; scsiXaction.addLengthByte = NONE; scsiXaction.tagType = SCSI_TAG_DEFAULT; scsiXaction.priority = SCSI_THREAD_TASK_PRIORITY; if (numSecs < 2000) scsiXaction.cmdTimeout = SCSI_TIMEOUT_5SEC + (SCSI_TIMEOUT_1SEC * numSecs); else scsiXaction.cmdTimeout = SCSI_TIMEOUT_FULL; return ((*pScsiPhysDev->pScsiCtrl->scsiTransact) (pScsiPhysDev, &scsiXaction)); }/********************************************************************************* scsiStatusCheck - called by filesystems before doing open()'s or creat()'s** This routine issues a TEST_UNIT_READY command to a SCSI device to detect a* medium change.** RETURNS: OK or ERROR.*/LOCAL STATUS scsiStatusCheck ( BLK_DEV *pBlkDev /* ptr to a block dev */ ) { SCSI_PHYS_DEV *pScsiPhysDev; /* ptr to SCSI physical device */ SCSI_COMMAND testUnitRdyCommand; /* SCSI command byte array */ SCSI_TRANSACTION scsiXaction; /* info on a SCSI transaction */ pScsiPhysDev = ((SCSI_BLK_DEV *) pBlkDev)->pScsiPhysDev; if (scsiCmdBuild (testUnitRdyCommand, &scsiXaction.cmdLength, SCSI_OPCODE_TEST_UNIT_READY, pScsiPhysDev->scsiDevLUN, FALSE, 0, 0, (UINT8) 0) == ERROR) { return (ERROR); } scsiXaction.cmdAddress = testUnitRdyCommand; scsiXaction.dataAddress = NULL; scsiXaction.dataDirection = NONE; scsiXaction.dataLength = 0; scsiXaction.addLengthByte = NONE; scsiXaction.cmdTimeout = SCSI_TIMEOUT_5SEC; scsiXaction.tagType = SCSI_TAG_DEFAULT; scsiXaction.priority = SCSI_THREAD_TASK_PRIORITY; (*pScsiPhysDev->pScsiCtrl->scsiTransact) (pScsiPhysDev, &scsiXaction); if ((pScsiPhysDev->lastSenseKey != SCSI_SENSE_KEY_NO_SENSE) && (pScsiPhysDev->lastSenseKey != SCSI_SENSE_KEY_UNIT_ATTENTION)) { SCSI_DEBUG_MSG ("scsiStatusCheck returning ERROR, last Sense = %x\n", pScsiPhysDev->lastSenseKey, 0, 0, 0, 0, 0); return (ERROR); } else return (OK); }/********************************************************************************* scsiBlkDevIoctl - call scsiIoctl() with pointer to SCSI physical device* associated with the specified SCSI block device** RETURNS: Status of scsiIoctl call.*/LOCAL STATUS scsiBlkDevIoctl ( SCSI_BLK_DEV *pScsiBlkDev, /* ptr to SCSI block device info */ int function, /* function code */ int arg /* argument to pass called function */ ) { return (scsiIoctl (pScsiBlkDev->pScsiPhysDev, function, arg)); }/********************************************************************************* scsiStartStopUnit - issue a START_STOP_UNIT command to a SCSI device** This routine issues a START_STOP_UNIT command to a specified SCSI device.** RETURNS: OK, or ERROR if the command fails.*/STATUS scsiStartStopUnit ( SCSI_PHYS_DEV *pScsiPhysDev, /* ptr to SCSI physical device */ BOOL start /* TRUE == start, FALSE == stop */ ) { SCSI_COMMAND startStopCommand; /* SCSI command byte array */ SCSI_TRANSACTION scsiXaction; /* info on a SCSI transaction */ SCSI_DEBUG_MSG ("scsiStartStopUnit:\n", 0, 0, 0, 0, 0, 0); if (scsiCmdBuild (startStopCommand, &scsiXaction.cmdLength, SCSI_OPCODE_START_STOP_UNIT, pScsiPhysDev->scsiDevLUN, FALSE, 0, 1, (UINT8) 0) == ERROR) { return (ERROR); } scsiXaction.cmdAddress = startStopCommand; scsiXaction.dataDirection = O_RDONLY; scsiXaction.dataLength = 0; scsiXaction.addLengthByte = NONE; scsiXaction.cmdTimeout = SCSI_TIMEOUT_5SEC; scsiXaction.tagType = SCSI_TAG_DEFAULT; scsiXaction.priority = SCSI_THREAD_TASK_PRIORITY; return ((*pScsiPhysDev->pScsiCtrl->scsiTransact) (pScsiPhysDev, &scsiXaction)); }/********************************************************************************* scsiReserve - issue a RESERVE command to a SCSI device** This routine issues a RESERVE command to a specified SCSI device.** RETURNS: OK, or ERROR if the command fails.*/STATUS scsiReserve ( SCSI_PHYS_DEV *pScsiPhysDev /* ptr to SCSI physical device */ ) { SCSI_COMMAND reserveCommand; /* SCSI command byte array */ SCSI_TRANSACTION scsiXaction; /* info on a SCSI transaction */ SCSI_DEBUG_MSG ("scsiReserve:\n", 0, 0, 0, 0, 0, 0); if (scsiCmdBuild (reserveCommand, &scsiXaction.cmdLength, SCSI_OPCODE_RESERVE, pScsiPhysDev->scsiDevLUN, FALSE, 0, 0, (UINT8) 0) == ERROR) { return (ERROR); } scsiXaction.cmdAddress = reserveCommand; scsiXaction.dataDirection = O_RDONLY; scsiXaction.dataLength = 0; scsiXaction.addLengthByte = NONE; scsiXaction.cmdTimeout = SCSI_TIMEOUT_5SEC; scsiXaction.tagType = SCSI_TAG_DEFAULT; scsiXaction.priority = SCSI_THREAD_TASK_PRIORITY; return ((*pScsiPhysDev->pScsiCtrl->scsiTransact) (pScsiPhysDev, &scsiXaction)); }/********************************************************************************* scsiRelease - issue a RELEASE command to a SCSI device** This routine issues a RELEASE command to a specified SCSI device.** RETURNS: OK, or ERROR if the command fails.*/STATUS scsiRelease ( SCSI_PHYS_DEV *pScsiPhysDev /* ptr to SCSI physical device */ ) { SCSI_COMMAND releaseCommand; /* SCSI command byte array */ SCSI_TRANSACTION scsiXaction; /* info on a SCSI transaction */ SCSI_DEBUG_MSG ("scsiRelease:\n", 0, 0, 0, 0, 0, 0); if (scsiCmdBuild (releaseCommand, &scsiXaction.cmdLength, SCSI_OPCODE_RELEASE, pScsiPhysDev->scsiDevLUN, FALSE, 0, 0, (UINT8) 0) == ERROR) { return (ERROR); } scsiXaction.cmdAddress = releaseCommand; scsiXaction.dataDirection = O_RDONLY; scsiXaction.dataLength = 0; scsiXaction.addLengthByte = NONE; scsiXaction.cmdTimeout = SCSI_TIMEOUT_5SEC; scsiXaction.tagType = SCSI_TAG_DEFAULT; scsiXaction.priority = SCSI_THREAD_TASK_PRIORITY; return ((*pScsiPhysDev->pScsiCtrl->scsiTransact) (pScsiPhysDev, &scsiXaction)); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -