📄 scsidirectlib.c
字号:
int defListFormat, /* defect list format */ int vendorUnique, /* vendor unique byte */ int interleave, /* interleave factor */ char *buffer, /* ptr to input data buffer */ int bufLength /* length of buffer in bytes */ ) { SCSI_COMMAND formatUnitCommand; /* SCSI command byte array */ SCSI_TRANSACTION scsiXaction; /* info on a SCSI transaction */ SCSI_DEBUG_MSG ("scsiFormatUnit:\n", 0, 0, 0, 0, 0, 0); formatUnitCommand[0] = SCSI_OPCODE_FORMAT_UNIT; formatUnitCommand[1] = (UINT8) ((pScsiPhysDev->scsiDevLUN & 0x7) << 5); if (buffer != (char *) NULL) { formatUnitCommand[1] |= SCSI_FORMAT_DATA_BIT; if (cmpDefectList) formatUnitCommand[1] |= SCSI_COMPLETE_LIST_BIT; formatUnitCommand[1] |= (defListFormat & 0x07); } formatUnitCommand[2] = (UINT8) vendorUnique; formatUnitCommand[3] = (UINT8) ((interleave >> 8) & 0xff); formatUnitCommand[4] = (UINT8) ((interleave ) & 0xff); formatUnitCommand[5] = (UINT8) 0; scsiXaction.cmdAddress = formatUnitCommand; scsiXaction.cmdLength = SCSI_GROUP_0_CMD_LENGTH; scsiXaction.dataAddress = (UINT8 *) buffer; scsiXaction.dataDirection = O_WRONLY; scsiXaction.dataLength = bufLength; scsiXaction.addLengthByte = NONE; scsiXaction.cmdTimeout = WAIT_FOREVER; scsiXaction.tagType = SCSI_TAG_DEFAULT; scsiXaction.priority = SCSI_THREAD_TASK_PRIORITY; return ((*pScsiPhysDev->pScsiCtrl->scsiTransact) (pScsiPhysDev, &scsiXaction)); }/********************************************************************************* scsi2ModeSelect - issue a MODE_SELECT command to a SCSI device** This routine issues a MODE_SELECT command to a specified SCSI device.** RETURNS: OK, or ERROR if the command fails.*/LOCAL STATUS scsi2ModeSelect ( SCSI_PHYS_DEV *pScsiPhysDev,/* ptr to SCSI physical device */ int pageFormat, /* value of the page format bit (0-1) */ int saveParams, /* value of the save parameters bit (0-1) */ char *buffer, /* ptr to output data buffer */ int bufLength /* length of buffer in bytes */ ) { SCSI_COMMAND modeSelectCommand; /* SCSI command byte array */ SCSI_TRANSACTION scsiXaction; /* info on a SCSI transaction */ int tempLBAField; /* "logical block address" field */ SCSI_DEBUG_MSG ("scsiModeSelect:\n", 0, 0, 0, 0, 0, 0); tempLBAField = (pageFormat ? (1 << 20) : 0) | (saveParams ? (1 << 16) : 0); if (scsiCmdBuild (modeSelectCommand, &scsiXaction.cmdLength, SCSI_OPCODE_MODE_SELECT, pScsiPhysDev->scsiDevLUN, FALSE, tempLBAField, min (0xff, bufLength), (UINT8) 0) == ERROR) return (ERROR); scsiXaction.cmdAddress = modeSelectCommand; scsiXaction.dataAddress = (UINT8 *) buffer; scsiXaction.dataDirection = O_WRONLY; scsiXaction.dataLength = min (0xff, bufLength); 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)); }/********************************************************************************* scsi2ModeSense - issue a MODE_SENSE command to a SCSI device** This routine issues a MODE_SENSE command to a specified SCSI device.** RETURNS: OK, or ERROR if the command fails.*/LOCAL STATUS scsi2ModeSense ( SCSI_PHYS_DEV *pScsiPhysDev,/* ptr to SCSI physical device */ int pageControl, /* value of the page control field (0-3) */ int pageCode, /* value of the page code field (0-0x3f) */ char *buffer, /* ptr to input data buffer */ int bufLength /* length of buffer in bytes */ ) { SCSI_COMMAND modeSenseCommand; /* SCSI command byte array */ SCSI_TRANSACTION scsiXaction; /* info on a SCSI transaction */ SCSI_DEBUG_MSG ("scsiModeSense:\n", 0, 0, 0, 0, 0, 0); if (scsiCmdBuild (modeSenseCommand, &scsiXaction.cmdLength, SCSI_OPCODE_MODE_SENSE, pScsiPhysDev->scsiDevLUN, FALSE, 0, min (0xff, bufLength), (UINT8) 0) == ERROR) return (ERROR); modeSenseCommand [2] = (UINT8) ((pageControl << 6) | pageCode); scsiXaction.cmdAddress = modeSenseCommand; scsiXaction.dataAddress = (UINT8 *) buffer; scsiXaction.dataDirection = O_RDONLY; scsiXaction.dataLength = min (0xff, bufLength); scsiXaction.addLengthByte = MODE_SENSE_ADD_LENGTH_BYTE; scsiXaction.cmdTimeout = SCSI_TIMEOUT_5SEC; scsiXaction.tagType = SCSI_TAG_DEFAULT; scsiXaction.priority = SCSI_THREAD_TASK_PRIORITY; return ((*pScsiPhysDev->pScsiCtrl->scsiTransact) (pScsiPhysDev, &scsiXaction)); }/********************************************************************************* scsi2ReadCapacity - issue a READ_CAPACITY command to a SCSI device** This routine issues a READ_CAPACITY command to a specified SCSI device.** RETURNS: OK, or ERROR if the command fails.*/LOCAL STATUS scsi2ReadCapacity ( SCSI_PHYS_DEV *pScsiPhysDev,/* ptr to SCSI physical device */ int *pLastLBA, /* where to return last logical block adrs */ int *pBlkLength /* where to return block length */ ) { SCSI_COMMAND readCapCommand; /* SCSI command byte array */ RD_CAP_DATA readCapData; /* data structure for results */ SCSI_TRANSACTION scsiXaction; /* info on a SCSI transaction */ SCSI_DEBUG_MSG ("scsiReadCapacity:\n", 0, 0, 0, 0, 0, 0); if (scsiCmdBuild (readCapCommand, &scsiXaction.cmdLength, SCSI_OPCODE_READ_CAPACITY, pScsiPhysDev->scsiDevLUN, FALSE, 0, 0, (UINT8) 0) == ERROR) return (ERROR); scsiXaction.cmdAddress = readCapCommand; scsiXaction.dataAddress = (UINT8 *) &readCapData; scsiXaction.dataDirection = O_RDONLY; scsiXaction.dataLength = sizeof (readCapData); scsiXaction.addLengthByte = NONE; scsiXaction.cmdTimeout = SCSI_TIMEOUT_5SEC; scsiXaction.tagType = SCSI_TAG_DEFAULT; scsiXaction.priority = SCSI_THREAD_TASK_PRIORITY; if ((*pScsiPhysDev->pScsiCtrl->scsiTransact) (pScsiPhysDev, &scsiXaction) == ERROR) return (ERROR); else { *pLastLBA = readCapData.lastLogBlkAdrs; *pBlkLength = readCapData.blkLength; SCSI_SWAB (pLastLBA, sizeof (*pLastLBA)); SCSI_SWAB (pBlkLength, sizeof (*pBlkLength)); return (OK); } }/******************************************************************************** scsi2RdSecs - write sector(s) to a SCSI block device** This routine checks if the data to be transferred is greater than the* maximum transfer length permitted by the device. If the data to be * 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 numSecs* is zero.*/LOCAL STATUS scsi2RdSecs ( 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 read */ int numbSecs; /* total sectors to be read */ 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 = scsiSectorRead (pScsiBlkDev,sector,numSecs,buffer); else { while (dataToXfer > 0) { /* determine the number of sectors to read */ if (dataToXfer > (pScsiPhysDev->pScsiCtrl->maxBytesPerXfer)) numbSecs = (pScsiPhysDev->pScsiCtrl->maxBytesPerXfer) / pScsiPhysDev->blockSize; else numbSecs = dataToXfer / pScsiPhysDev->blockSize; /* read the sectors */ xferStatus = scsiSectorRead (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); }/********************************************************************************* scsiSectorRead - read sector(s) from a SCSI block device** This routine reads the specified physical sector(s) from a specified* physical device.** RETURNS: OK, or ERROR if the sector cannot be read.*/LOCAL STATUS scsiSectorRead ( 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 readCommand; /* 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 ("scsiRdSecs:\n", 0, 0, 0, 0, 0, 0); if (startSec <= SCSI_BLOCK_ADDRESS_SIZE && numSecs <= 256) { /* build a 21 bit logical block address 'READ' command */ if (scsiCmdBuild (readCommand, &scsiXaction.cmdLength, SCSI_OPCODE_READ, pScsiPhysDev->scsiDevLUN, FALSE, startSec, (numSecs == 256 ? 0 : numSecs), (UINT8) 0) == ERROR) return (ERROR); } else { /* build a 32 bit logical block address 'READ_EXTENDED' command */ if (scsiCmdBuild (readCommand, &scsiXaction.cmdLength, SCSI_OPCODE_READ_EXT, pScsiPhysDev->scsiDevLUN, FALSE, startSec, numSecs, (UINT8) 0) == ERROR) return (ERROR); } scsiXaction.cmdAddress = readCommand; scsiXaction.dataAddress = (UINT8 *) buffer; scsiXaction.dataDirection = O_RDONLY; 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)); }/********************************************************************************* scsi2WrtSecs - write sector(s) to a SCSI block device** This routine checks if the data to be transferred is greater than the* maximum transfer length permitted by the device. If the data to be
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -