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

📄 scsiseqlib.c

📁 VxWorks操作系统内核源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	    	    if ((scsiSpace (pScsiSeqDev, -1, SPACE_CODE_FILEMARK)) == ERROR)	        {		printf ("Backward space unsuccessful\n");	        return (ERROR);		}  	    }	return (unitsRead);	}    return (numDataUnits);    }/********************************************************************************* scsiWrtTape - write data to a SCSI tape device** This routine writes data to the current block on a specified physical* device.  If the boolean <fixedSize> is true, then <numBytes>* represents the number of blocks of size <blockSize>,  * defined in the `pScsiPhysDev' structure.  If variable block sizes are used* (<fixedSize> = FALSE), then <numBytes> represents the actual number of bytes* to be written.  If <numBytes> is greater than the `maxBytesLimit' field* defined in the `pScsiPhysDev' structure, then more than one SCSI transaction* is used to transfer the data.** RETURNS: OK, or ERROR if the data cannot be written or zero bytes are * written.*/STATUS scsiWrtTape    (    SCSI_SEQ_DEV *pScsiSeqDev,    /* ptr to SCSI sequential device info  */    int numBytes,                 /* total bytes or blocks to be written */    char *buffer,                 /* ptr to input data buffer            */    BOOL fixedSize		  /* if variable size blocks             */    )    {    SCSI_COMMAND scsiCommand;	  /* SCSI command byte array          */    SCSI_TRANSACTION scsiXaction; /* info on a SCSI transaction       */    SCSI_PHYS_DEV *pScsiPhysDev;  /* ptr to SCSI physical device info */    STATUS status = ERROR;	  /* status of transaction            */    UINT8 * bufPtr;               /*  ptr to input data buffer        */    UINT timeout;                 /* scsi command timeout             */    int  xferLength;              /* transfer length                  */    int  numBlocks;    int  maxVarBlockLimit;    int  writeBytes;    int  xferBlocks;    SCSI_DEBUG_MSG ("scsiWrtTape:\n", 0, 0, 0, 0, 0, 0);    pScsiPhysDev = pScsiSeqDev->pScsiPhysDev;    /*     * Fixed block size transfer. The block size must be defined in      * pScsiPhysDev prior to calling this function      */    if (fixedSize)        {	numBlocks = numBytes; /* numBytes means numBlocks for fixed blk size */		if (numBlocks > SCSI_MAX_XFER_BLOCKS)	    return (ERROR);	/*	 * Check if the number of blocks to be transferred	 * is less than the max permissible size 	 */	if (numBlocks <= (pScsiPhysDev->pScsiCtrl->maxBytesPerXfer / 			  pScsiSeqDev->seqDev.sd_blkSize))   	    {	    scsiCmdFill (pScsiSeqDev, scsiCommand, SCSI_WRITE, TRUE, 			 numBlocks);	    bufPtr = (UINT8 *) buffer;	    xferLength = numBlocks * pScsiSeqDev->seqDev.sd_blkSize;	    /* 	     * timeout value is based on 100kB/sec xfer and a 5 	     * sec threshold 	     */	    timeout = SCSI_TIMEOUT_5SEC * 50 + (10 * numBlocks *						pScsiPhysDev->blockSize);	    scsiXactionFill (&scsiXaction, scsiCommand, SCSI_WRITE,			     SCSI_GROUP_0_CMD_LENGTH, timeout, xferLength,			     bufPtr);	    	    status = (*pScsiPhysDev->pScsiCtrl->scsiTransact)		     (pScsiPhysDev, &scsiXaction);	    return (status);	    }	else	    {	    /* determine the max number of blocks that can be transferred */            xferBlocks = (pScsiPhysDev->pScsiCtrl->maxBytesPerXfer) /	                 (pScsiSeqDev->seqDev.sd_blkSize);	    while (numBlocks > 0)                {   		scsiCmdFill (pScsiSeqDev, scsiCommand, SCSI_WRITE, TRUE, 			     xferBlocks);		bufPtr = (UINT8 *) buffer;		xferLength = xferBlocks * pScsiSeqDev->seqDev.sd_blkSize;				/* 		 * timeout value is based on 100kB/sec xfer and a 5 		 * sec threshold 		 */		timeout = SCSI_TIMEOUT_5SEC * 50 + (10 * xferBlocks *						    pScsiPhysDev->blockSize);		scsiXactionFill (&scsiXaction, scsiCommand, SCSI_WRITE,				 SCSI_GROUP_0_CMD_LENGTH, timeout, xferLength,				 bufPtr);		status = (*pScsiPhysDev->pScsiCtrl->scsiTransact)		  (pScsiPhysDev, &scsiXaction);		if (status == OK )		    {		     numBlocks -= xferBlocks;		     buffer += (xferBlocks * pScsiSeqDev->seqDev.sd_blkSize);		     if (numBlocks <= 			 (pScsiPhysDev->pScsiCtrl->maxBytesPerXfer /			  pScsiSeqDev->seqDev.sd_blkSize))		       xferBlocks = numBlocks; 		    }		else		    return (status);   		}	    return (status);	    }	}    /* get the maximum variable block size for the device */            maxVarBlockLimit = pScsiPhysDev->maxVarBlockLimit;    if ( maxVarBlockLimit > pScsiPhysDev->pScsiCtrl->maxBytesPerXfer)	maxVarBlockLimit = pScsiPhysDev->pScsiCtrl->maxBytesPerXfer;    /* multiple transactions needed if numBytes > maxVarBlockLimit */    for (writeBytes=0; numBytes > maxVarBlockLimit;	        numBytes -= maxVarBlockLimit, writeBytes += maxVarBlockLimit)        {	scsiCmdFill (pScsiSeqDev, scsiCommand, SCSI_WRITE, FALSE, 		     maxVarBlockLimit);	bufPtr = (UINT8 *) buffer + writeBytes;	xferLength = maxVarBlockLimit;	timeout = SCSI_TIMEOUT_5SEC * 50 + (maxVarBlockLimit * 10);	scsiXactionFill (&scsiXaction, scsiCommand, SCSI_WRITE,			 SCSI_GROUP_0_CMD_LENGTH, timeout, xferLength,			 bufPtr);        status = (*pScsiPhysDev->pScsiCtrl->scsiTransact)    	           (pScsiPhysDev, &scsiXaction);        if (status == ERROR)	    return (status);        }    if (numBytes > 0)	{	scsiCmdFill (pScsiSeqDev, scsiCommand, SCSI_WRITE, FALSE, numBytes);	bufPtr = (UINT8 *) buffer + writeBytes;	xferLength = numBytes;	timeout = SCSI_TIMEOUT_5SEC * 50 + (numBytes * 10);	scsiXactionFill (&scsiXaction, scsiCommand, SCSI_WRITE,			 SCSI_GROUP_0_CMD_LENGTH, timeout, xferLength,			 bufPtr);        status = (*pScsiPhysDev->pScsiCtrl->scsiTransact)    	           (pScsiPhysDev, &scsiXaction);        }    return (status);    }/********************************************************************************* scsiRewind - issue a REWIND command to a SCSI device** This routine issues a REWIND command to a specified SCSI device.** RETURNS: OK, or ERROR if the command fails.*/STATUS scsiRewind    (    SCSI_SEQ_DEV *pScsiSeqDev	/* ptr to SCSI Sequential device */    )    {    SCSI_COMMAND rewindCommand;		/* SCSI command byte array     */    SCSI_TRANSACTION scsiXaction;	/* info on a SCSI transaction  */    SCSI_PHYS_DEV * pScsiPhysDev;    	/* ptr to SCSI physical device */    STATUS status;			/* holds status of transaction */    SCSI_DEBUG_MSG ("scsiRewind:\n", 0, 0, 0, 0, 0, 0);    pScsiPhysDev = pScsiSeqDev->pScsiPhysDev;    rewindCommand[0] = SCSI_OPCODE_REWIND;    rewindCommand[1] = (UINT8) ((pScsiPhysDev->scsiDevLUN & 0x7) << 5);    rewindCommand[2] = (UINT8) 0;    rewindCommand[3] = (UINT8) 0;    rewindCommand[4] = (UINT8) 0;    rewindCommand[5] = (UINT8) 0;    scsiXaction.cmdAddress    = rewindCommand;    scsiXaction.cmdLength     = SCSI_GROUP_0_CMD_LENGTH;    scsiXaction.dataAddress   = (UINT8 *) NULL;    scsiXaction.dataDirection = O_WRONLY;    scsiXaction.dataLength    = 0;    scsiXaction.addLengthByte = NULL;    scsiXaction.cmdTimeout    = SCSI_TIMEOUT_FULL;    scsiXaction.tagType       = SCSI_TAG_DEFAULT;    scsiXaction.priority      = SCSI_THREAD_TASK_PRIORITY;    status = (*pScsiPhysDev->pScsiCtrl->scsiTransact)	      (pScsiPhysDev, &scsiXaction);    return (status);    }/********************************************************************************* scsiReserveUnit - issue a RESERVE UNIT command to a SCSI device** This routine issues a RESERVE UNIT command to a specified SCSI device.** RETURNS: OK, or ERROR if the command fails.*/STATUS scsiReserveUnit    (    SCSI_SEQ_DEV *pScsiSeqDev	/* ptr to SCSI sequential device */    )    {    SCSI_COMMAND reserveUnitCommand;	/* SCSI command byte array     */    SCSI_TRANSACTION scsiXaction;	/* info on a SCSI transaction  */    SCSI_PHYS_DEV *pScsiPhysDev;        /* ptr to SCSI physical device */    STATUS status;			/* status of transaction       */    SCSI_DEBUG_MSG ("scsiReserveUnit:\n", 0, 0, 0, 0, 0, 0);    pScsiPhysDev = pScsiSeqDev->pScsiPhysDev;    reserveUnitCommand[0] = SCSI_OPCODE_RESERVE;    reserveUnitCommand[1] = (UINT8) 0;    reserveUnitCommand[2] = (UINT8) 0;    reserveUnitCommand[3] = (UINT8) 0;    reserveUnitCommand[4] = (UINT8) 0;    reserveUnitCommand[5] = (UINT8) 0;    scsiXaction.cmdAddress    = reserveUnitCommand;    scsiXaction.cmdLength     = SCSI_GROUP_0_CMD_LENGTH;    scsiXaction.dataAddress   = (UINT8 *) NULL;    scsiXaction.dataDirection = O_WRONLY;    scsiXaction.dataLength    = 0;    scsiXaction.addLengthByte = NULL;    scsiXaction.cmdTimeout    = SCSI_TIMEOUT_5SEC;    scsiXaction.tagType       = SCSI_TAG_DEFAULT;    scsiXaction.priority      = SCSI_THREAD_TASK_PRIORITY;    status = (*pScsiPhysDev->pScsiCtrl->scsiTransact)	      (pScsiPhysDev, &scsiXaction);    return (status);    }/********************************************************************************* scsiReleaseUnit - issue a RELEASE UNIT command to a SCSI device** This routine issues a RELEASE UNIT command to a specified SCSI device.** RETURNS: OK, or ERROR if the command fails.*/STATUS scsiReleaseUnit    (    SCSI_SEQ_DEV *pScsiSeqDev	/* ptr to SCSI sequential device */    )    {    SCSI_COMMAND releaseUnitCommand;	/* SCSI command byte array     */    SCSI_TRANSACTION scsiXaction;	/* info on a SCSI transaction  */    SCSI_PHYS_DEV *pScsiPhysDev;        /* ptr to SCSI physical device */    STATUS status;			/* status of transaction       */    SCSI_DEBUG_MSG ("scsiReleaseUnit:\n", 0, 0, 0, 0, 0, 0);    pScsiPhysDev = pScsiSeqDev->pScsiPhysDev;    releaseUnitCommand[0] = SCSI_OPCODE_RELEASE;    releaseUnitCommand[1] = (UINT8) 0;    releaseUnitCommand[2] = (UINT8) 0;    releaseUnitCommand[3] = (UINT8) 0;    releaseUnitCommand[4] = (UINT8) 0;    releaseUnitCommand[5] = (UINT8) 0;    scsiXaction.cmdAddress    = releaseUnitCommand;    scsiXaction.cmdLength     = SCSI_GROUP_0_CMD_LENGTH;    scsiXaction.dataAddress   = (UINT8 *) NULL;    scsiXaction.dataDirection = O_WRONLY;    scsiXaction.dataLength    = 0;    scsiXaction.addLengthByte = NULL;    scsiXaction.cmdTimeout    = SCSI_TIMEOUT_5SEC;    scsiXaction.tagType       = SCSI_TAG_DEFAULT;    scsiXaction.priority      = SCSI_THREAD_TASK_PRIORITY;    status = (*pScsiPhysDev->pScsiCtrl->scsiTransact)	      (pScsiPhysDev, &scsiXaction);    return (status);    }/********************************************************************************* scsiLoadUnit - issue a LOAD/UNLOAD command to a SCSI device** This routine issues a LOAD/UNLOAD command to a specified SCSI device.** RETURNS: OK, or ERROR if the command fails.*/STATUS scsiLoadUnit    (    SCSI_SEQ_DEV * pScsiSeqDev,	        /* ptr to SCSI physical device */    BOOL           load,		/* TRUE=load, FALSE=unload     */    BOOL	   reten,		/* TRUE=retention and unload   */    BOOL	   eot			/* TRUE=end of tape and unload */    )    {    SCSI_COMMAND loadCommand;		/* SCSI command byte array     */    SCSI_TRANSACTION scsiXaction;	/* info on a SCSI transaction  */    SCSI_PHYS_DEV *pScsiPhysDev;	/* ptr to SCSI physical device */    STATUS status;			/* status of transaction       */    SCSI_DEBUG_MSG ("scsiLoadUnit:\n", 0, 0, 0, 0, 0, 0);    pScsiPhysDev = pScsiSeqDev->pScsiPhysDev;    loadCommand[0] = SCSI_OPCODE_LOAD_UNLOAD;    loadCommand[1] = (UINT8) 0;    loadCommand[2] = (UINT8) 0;    loadCommand[3] = (UINT8) 0;    /*      * Check for load, retension and eot (TRUE/FALSE) conditions.     * Byte4 bit2 of CDB: eot     * Byte4 bit1 of CDB: reten     * Byte4 bit0 of CDB: load     */    if (load && eot) 		/* invalid condition */	return (ERROR);    if (load)        loadCommand[4] = (UINT8) 1;    else /* unload */	{        loadCommand[4] = (UINT8) 0;        if (eot)	    loadCommand[4] |= (0x1 << 2);        }    if (reten)    	loadCommand[4] |= (0x1 << 1);    loadCommand[5] = (UINT8) 0;    scsiXaction.cmdAddress    = loadCommand;    scsiXaction.cmdLength     = SCSI_GROUP_0_CMD_LENGTH;    scsiXaction.dataAddress   = (UINT8 *) NULL;    scsiXaction.dataDirection = O_WRONLY;    scsiXaction.dataLength    = 0;    scsiXaction.addLengthByte = NULL;    scsiXaction.cmdTimeout    = SCSI_TIMEOUT_5SEC * 10;    scsiXaction.tagType       = SCSI_TAG_DEFAULT;    scsiXaction.priority      = SCSI_THREAD_TASK_PRIORITY;    status = (*pScsiPhysDev->pScsiCtrl->scsiTransact)	      (pScsiPhysDev, &scsiXaction);    return (status);    }/********************************************************************************* scsiWrtFileMarks - write file marks to a SCSI sequential device** This routine writes file marks to a specified physical device.** RETURNS: OK, or ERROR if the file mark cannot be written.*/

⌨️ 快捷键说明

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