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

📄 scsiseqlib.c

📁 VxWorks操作系统内核源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    scsiXaction.cmdTimeout    = SCSI_TIMEOUT_5SEC;    scsiXaction.tagType       = SCSI_TAG_DEFAULT;    scsiXaction.priority      = SCSI_THREAD_TASK_PRIORITY;    status = (*pScsiPhysDev->pScsiCtrl->scsiTransact)	      (pScsiPhysDev, &scsiXaction);    if (status == ERROR)	return (ERROR);    *pMaxBlockLength = readBlkLimitData.maxBlockLength;    *pMinBlockLength = readBlkLimitData.minBlockLength;    SCSI_SWAB (pMaxBlockLength, sizeof (*pMaxBlockLength));    SCSI_SWAB (pMinBlockLength, sizeof (*pMinBlockLength));    return (OK);    }/********************************************************************************* scsiSeqReadBlockLimits - issue a READ_BLOCK_LIMITS command to a SCSI device** This routine issues a READ_BLOCK_LIMITS command to a specified SCSI device.** RETURNS: OK, or ERROR if the command fails.*/STATUS scsiSeqReadBlockLimits    (    SCSI_SEQ_DEV * pScsiSeqDev,  /* ptr to SCSI sequential device        */    int    *pMaxBlockLength,     /* where to return maximum block length */    UINT16 *pMinBlockLength      /* where to return minimum block length */    )    {    SCSI_PHYS_DEV * pScsiPhysDev = pScsiSeqDev->pScsiPhysDev;    return (scsiReadBlockLimits (pScsiPhysDev, pMaxBlockLength, 							pMinBlockLength));    }/********************************************************************************* scsiCmdFill - fill the SCSI_COMMAND structure.** RETURNS: N/A.*/LOCAL VOID scsiCmdFill     (     SCSI_SEQ_DEV * pScsiSeqDev,    SCSI_COMMAND   scsiCommand,  /* scsi command structure to be filled */    BOOL           commandType,  /* read or write command               */    BOOL           fixed,        /* variable or fixed                   */    int            xferLength    /* total bytes or blocks to xfer       */    )    {    SCSI_PHYS_DEV *pScsiPhysDev; /* ptr to SCSI physical device info */    pScsiPhysDev = pScsiSeqDev->pScsiPhysDev;    if ( commandType == SCSI_READ )	scsiCommand[0] = SCSI_OPCODE_READ;    else	scsiCommand[0] = SCSI_OPCODE_WRITE;    scsiCommand[1] = (UINT8) ((pScsiPhysDev->scsiDevLUN & 0x7) << 5);    if (fixed)	scsiCommand[1] |= 0x01;	/* set for fixed block size */    scsiCommand[2] = (UINT8) ((xferLength >> 16) & 0xff);    scsiCommand[3] = (UINT8) ((xferLength >>  8) & 0xff);    scsiCommand[4] = (UINT8) (xferLength & 0xff);    scsiCommand[5] = (UINT8) 0;    }/********************************************************************************* scsiXactionFill - fill the SCSI_TRANSACTION structure.** RETURNS: N/A.*/LOCAL VOID scsiXactionFill     (     SCSI_TRANSACTION * scsiXaction, /* scsi Transaction structure */    SCSI_COMMAND   scsiCommand,     /* scsi command structure     */    BOOL           commandType,     /* read or write command      */    int            cmdLength,       /* scsi command length        */    UINT           cmdTimeout,      /* scsi command timeout       */    int            dataXferLen,     /* data transfer length       */    UINT8 *        bufAdrs          /* scsi data address          */    )    {    if ( commandType == SCSI_READ )	scsiXaction->dataDirection = O_RDONLY;    else	scsiXaction->dataDirection = O_WRONLY;    scsiXaction->cmdAddress  = scsiCommand;    scsiXaction->cmdLength   = cmdLength;    scsiXaction->dataAddress = bufAdrs;    scsiXaction->dataLength  = dataXferLen;    scsiXaction->addLengthByte = NULL;    scsiXaction->cmdTimeout = cmdTimeout;    scsiXaction->tagType = SCSI_TAG_DEFAULT;    scsiXaction->priority = SCSI_THREAD_TASK_PRIORITY;    }/********************************************************************************* scsiRdTapeFixedBlocks - reads the number of blocks specified** This routine reads the specified number of blocks from a specified* physical device.  If `numBlocks' is greater than the `maxBytesLimit' field* defined in the `pScsiPhysDev' structure, then more than one SCSI transaction* is used to transfer the data.** RETURNS: Number of blocks actually read, 0 if EOF, or ERROR.*/LOCAL int scsiRdTapeFixedBlocks    (    SCSI_SEQ_DEV *pScsiSeqDev,    /* ptr to SCSI sequential device info */    UINT numBlocks,                /* total # of blocks to be read       */    char * buffer                 /* ptr to iput data buffer            */        )    {    SCSI_PHYS_DEV *pScsiPhysDev;  /* ptr to SCSI physical device info   */    SCSI_COMMAND readCommand;	  /* SCSI command byte array            */    SCSI_TRANSACTION scsiXaction; /* info on a SCSI transaction         */    UINT8 * bufPtr;               /* ptr to input data buffer           */    UINT timeout;                 /* scsi command timeout               */    int  xferLength;              /* transfer length                    */    int  nBlocks = 0;             /* number of blocks read              */    int  xferBlocks;              /* number of blocks to be xferred     */    UINT blocksRead = 0;          /* actual number of blocks read       */    pScsiPhysDev = pScsiSeqDev->pScsiPhysDev;        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, readCommand, SCSI_READ, 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, readCommand, SCSI_READ,			 SCSI_GROUP_0_CMD_LENGTH, timeout, xferLength,			 bufPtr);        if (((*pScsiPhysDev->pScsiCtrl->scsiTransact) 	     (pScsiPhysDev, &scsiXaction)) == ERROR)	    return (ERROR);		if ((blocksRead = scsiCalcDataRead (pScsiSeqDev, numBlocks)) == ERROR)	    return (ERROR);		return (blocksRead);	}    else	{	/* determine the max number of blocks that can be transferred */		xferBlocks = (pScsiPhysDev->pScsiCtrl->maxBytesPerXfer) /		     (pScsiSeqDev->seqDev.sd_blkSize);	while (numBlocks > 0)	    {	    scsiCmdFill (pScsiSeqDev, readCommand, SCSI_READ, 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, readCommand, SCSI_READ,			     SCSI_GROUP_0_CMD_LENGTH, timeout, xferLength,			     bufPtr);	    if (((*pScsiPhysDev->pScsiCtrl->scsiTransact) 		 (pScsiPhysDev, &scsiXaction)) == ERROR)  	        return (ERROR);	    	    if ((nBlocks = scsiCalcDataRead (pScsiSeqDev, numBlocks)) == ERROR)	        return (ERROR);	    	    numBlocks -= xferBlocks;	    buffer += (xferBlocks * pScsiSeqDev->seqDev.sd_blkSize);	    	    if (numBlocks <= 		(pScsiPhysDev->pScsiCtrl->maxBytesPerXfer /		 pScsiSeqDev->seqDev.sd_blkSize))		xferBlocks = numBlocks;	    	    blocksRead += nBlocks;	    }	return (blocksRead);	}    }/********************************************************************************* scsiRdTapeVariableBlocks - reads the number of bytes specified** This routine reads the specified number of bytes from a specified* physical device.  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: Number of bytes actually read, 0 if EOF, or ERROR.*/LOCAL int scsiRdTapeVariableBlocks    (    SCSI_SEQ_DEV *pScsiSeqDev,    /* ptr to SCSI sequential device info */    UINT numBytes,                 /* total # of bytes to be read        */    char * buffer                 /* ptr to input data buffer           */        )    {    SCSI_PHYS_DEV *pScsiPhysDev;  /* ptr to SCSI physical device info   */    SCSI_COMMAND readCommand;	  /* SCSI command byte array            */    SCSI_TRANSACTION scsiXaction; /* info on a SCSI transaction         */    UINT8 * bufPtr;               /* ptr to input data buffer           */    UINT timeout;                 /* scsi command timeout               */    int  xferLength;              /* transfer length                    */    int  nBytes;                  /* number of bytes read               */    int  maxVarBlockLimit;        /* maximum variable block limit       */    UINT bytesRead = 0;           /* actual number of bytes read        */    int  readBytes;               /* for multiple read transactions     */            pScsiPhysDev = pScsiSeqDev->pScsiPhysDev;        /* 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 (readBytes=0; numBytes > maxVarBlockLimit; 	 numBytes -= maxVarBlockLimit, readBytes += maxVarBlockLimit)        {	scsiCmdFill (pScsiSeqDev, readCommand, SCSI_READ, FALSE, 		     maxVarBlockLimit);		bufPtr = (UINT8 *) buffer + readBytes;	xferLength = maxVarBlockLimit;	timeout = SCSI_TIMEOUT_5SEC * 50 + (maxVarBlockLimit * 10);		scsiXactionFill (&scsiXaction, readCommand, SCSI_READ,			 SCSI_GROUP_0_CMD_LENGTH, timeout, xferLength,			 bufPtr);	        if (((*pScsiPhysDev->pScsiCtrl->scsiTransact) 	     (pScsiPhysDev, &scsiXaction)) == ERROR)	    return (ERROR);		if ((nBytes = scsiCalcDataRead (pScsiSeqDev, xferLength)) == ERROR)	    return (ERROR);		bytesRead += nBytes;        }        if (numBytes > 0)	{	scsiCmdFill (pScsiSeqDev, readCommand, SCSI_READ, FALSE, numBytes);	bufPtr = (UINT8 *) buffer + readBytes;	timeout = SCSI_TIMEOUT_5SEC * 50 + (numBytes * 10);		scsiXactionFill (&scsiXaction, readCommand, SCSI_READ,			 SCSI_GROUP_0_CMD_LENGTH, timeout, numBytes,			 bufPtr);	        if (((*pScsiPhysDev->pScsiCtrl->scsiTransact)	     (pScsiPhysDev, &scsiXaction)) == ERROR)            return (ERROR);		if ((nBytes = scsiCalcDataRead (pScsiSeqDev, numBytes)) == ERROR) 	    return (ERROR);		bytesRead  += nBytes;	}    return (bytesRead);    }/********************************************************************************* scsiRdTape - read bytes or blocks from a SCSI tape device** This routine reads the specified number of bytes or blocks from 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 read. ** RETURNS: Number of bytes or blocks actually read, 0 if EOF, or ERROR.*/int scsiRdTape    (    SCSI_SEQ_DEV *pScsiSeqDev,    /* ptr to SCSI sequential device info */    UINT count,                   /* total bytes or blocks to be read   */    char *buffer,                 /* ptr to input data buffer           */    BOOL fixedSize		  /* if variable size blocks            */    )    {    SCSI_PHYS_DEV *pScsiPhysDev;  /* ptr to SCSI physical device info   */    int            dataCount;     /* blocks or bytes read               */        pScsiPhysDev = pScsiSeqDev->pScsiPhysDev;        SCSI_DEBUG_MSG ("scsiRdTape:\n", 0, 0, 0, 0, 0, 0);        /* Invalidate the request sense data */        pScsiPhysDev->pReqSenseData[0] &= 0x7f;        if (fixedSize)	dataCount = scsiRdTapeFixedBlocks (pScsiSeqDev, count, buffer);    else	dataCount = scsiRdTapeVariableBlocks (pScsiSeqDev, count, buffer);        return (dataCount);    }/********************************************************************************* scsiCalcDataRead - calculates the actual # of bytes read** This routine calculates the actual number of bytes or blocks read after* a read operation, by examining the request sense data if it is valid.** RETURNS: bytes or blocks read, 0 if EOF or ERROR if tape move was * unsuccessful.*          * NOMANUAL*/LOCAL int scsiCalcDataRead     (    SCSI_SEQ_DEV *pScsiSeqDev,    /* ptr to SCSI sequential device info */    UINT numDataUnits              /* total bytes or blocks to be read   */    )    {    SCSI_PHYS_DEV *pScsiPhysDev;  /* ptr to SCSI physical device info */    int  residue;                 /* diff between requested & xfered data */    UINT unitsRead = 0;           /* actual number of bytes read          */        pScsiPhysDev = pScsiSeqDev->pScsiPhysDev;        /* if request sense data is valid */        if (pScsiPhysDev->pReqSenseData[0] & 0x80)	{	residue = (pScsiPhysDev->pReqSenseData[3] << 24) +		  (pScsiPhysDev->pReqSenseData[4] << 16) +		  (pScsiPhysDev->pReqSenseData[5] <<  8) +		  (pScsiPhysDev->pReqSenseData[6]);		if (residue < 0)	    unitsRead = numDataUnits;	else	    unitsRead = numDataUnits - residue;		/* Invalidate the request sense data */		pScsiPhysDev->pReqSenseData[0] = pScsiPhysDev->pReqSenseData[0] & 0x7f;	        /*	 * Check the request sense data to see if End of Filemark	 * or End of Medium was encountered.	 */		if ((pScsiPhysDev->pReqSenseData[2] & 0x40) ||	    (pScsiPhysDev->pReqSenseData[2] & 0x80))	    {            /* move tape head to the beginning of filemark */

⌨️ 快捷键说明

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