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

📄 scsi1lib.c

📁 VxWorks操作系统内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    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;    return ((*pScsiPhysDev->pScsiCtrl->scsiTransact)	    (pScsiPhysDev, &scsiXaction));    }/********************************************************************************* scsi1ReadCapacity - 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 scsi1ReadCapacity    (    SCSI_PHYS_DEV *pScsiPhysDev,/* ptr to SCSI physical device */    int *pLastLBA,              /* where to return last logical block address */    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;    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);	}    }/********************************************************************************* scsi1RdSecs - 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 scsi1RdSecs    (    SCSI_BLK_DEV *pScsiBlkDev,  /* ptr to SCSI block device info */    int sector,                 /* sector number to read */    int numSecs,                /* total sectors to 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 <= 0x1FFFFF && numSecs <= 256)        {        /* build a 21 bit logical block address 'O_RDONLY' 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;    if (numSecs < 2000)	scsiXaction.cmdTimeout = SCSI_TIMEOUT_5SEC +				 (SCSI_TIMEOUT_1SEC * numSecs);    else	scsiXaction.cmdTimeout = SCSI_TIMEOUT_FULL;    return ((*pScsiPhysDev->pScsiCtrl->scsiTransact)	    (pScsiPhysDev, &scsiXaction));    }/********************************************************************************* scsi1WrtSecs - 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 scsi1WrtSecs    (    SCSI_BLK_DEV *pScsiBlkDev,  /* ptr to SCSI block device info */    int sector,                 /* sector number to write */    int numSecs,                /* total sectors to write */    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 <= 0x1FFFFF && numSecs <= 256)        {        /* build a 21 bit logical block address 'O_WRONLY' 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;    if (numSecs < 2000)	scsiXaction.cmdTimeout = SCSI_TIMEOUT_5SEC +				 (SCSI_TIMEOUT_1SEC * numSecs);    else	scsiXaction.cmdTimeout = SCSI_TIMEOUT_FULL;    return ((*pScsiPhysDev->pScsiCtrl->scsiTransact)	    (pScsiPhysDev, &scsiXaction));    }/********************************************************************************* scsi1ReqSense - issue a REQUEST_SENSE command to a device and read the results** This routine issues a REQUEST_SENSE command to a specified SCSI device and* read the results.** RETURNS: OK, or ERROR if the command fails.*/LOCAL STATUS scsi1ReqSense    (    SCSI_PHYS_DEV *pScsiPhysDev,/* ptr to SCSI physical device */    char *buffer,               /* ptr to input data buffer */    int bufLength               /* length of buffer in bytes */    )    {    SCSI_COMMAND reqSenseCommand;	/* SCSI command byte array */    SCSI_TRANSACTION scsiXaction;	/* info on a SCSI transaction */    SCSI_DEBUG_MSG ("scsiReqSense:\n", 0, 0, 0, 0, 0, 0);    if (scsiCmdBuild (reqSenseCommand, &scsiXaction.cmdLength,		      SCSI_OPCODE_REQUEST_SENSE, pScsiPhysDev->scsiDevLUN,		      FALSE, 0, bufLength, (UINT8) 0)        == ERROR)        return (ERROR);    scsiXaction.cmdAddress    = reqSenseCommand;    scsiXaction.dataAddress   = (UINT8 *) buffer;    scsiXaction.dataDirection = O_RDONLY;    scsiXaction.dataLength    = bufLength;    scsiXaction.addLengthByte = REQ_SENSE_ADD_LENGTH_BYTE;    scsiXaction.cmdTimeout    = SCSI_TIMEOUT_5SEC;    return ((*pScsiPhysDev->pScsiCtrl->scsiTransact)	    (pScsiPhysDev, &scsiXaction));    }/********************************************************************************* scsiPhaseSequence - manage all phases of a single SCSI bus sequence** This routine is called by scsiTransact after a device has been successfully* selected.  It repeated calls the appropriate routine to detect the current* SCSI bus phase.  It takes whatever action is specified in the supplied* SCSI_TRANSACTION structure, usually calling the appropiate routines to* input or output bytes to the device.** RETURNS: OK, or ERROR if not successful for any reason.*/LOCAL STATUS scsiPhaseSequence    (    SCSI_PHYS_DEV *pScsiPhysDev,        /* ptr to the target device */    SCSI_TRANSACTION *pScsiXaction      /* ptr to the transaction info */    )    {    SCSI_CTRL *pScsiCtrl;	/* SCSI controller info for device */    STATUS status;		/* routine return status */    int scsiPhase;		/* passed to scsiBusPhaseGet routine */    UINT8 msgIn [MAX_MSG_IN_BYTES]; /* message returned from the SCSI device */    UINT8 *pMsgIn;		/* ptr to next dest. for a message in */    BOOL transactionComplete;	/* set TRUE upon 'disconn' or 'comm complete' */    pScsiCtrl = pScsiPhysDev->pScsiCtrl;    /* save current command context requested */    pScsiPhysDev->pScsiXaction = pScsiXaction;    transactionComplete = FALSE;    if ((status = scsiDevSelect (pScsiPhysDev, pScsiXaction)) == ERROR)	{	SCSI_DEBUG_MSG ("scsiPhaseSequence: Unable to select device.\n",			0, 0, 0, 0, 0, 0);	return (ERROR);	}    do	{	if ((*pScsiCtrl->scsiBusPhaseGet) (pScsiCtrl, pScsiXaction->cmdTimeout,					   &scsiPhase) != OK)	    {	    SCSI_DEBUG_MSG ("scsiBusPhaseGet returned ERROR.\n",			    0, 0, 0, 0, 0, 0);	    return (ERROR);	    }	phaseSwitch:        switch (scsiPhase)	    {	    case SCSI_DATA_OUT_PHASE:	        status = (*pScsiCtrl->scsiBytesOut)			     (pScsiPhysDev, pScsiXaction->dataAddress,			      pScsiXaction->dataLength, scsiPhase);		if (status == ERROR)		    {		    return (ERROR);		    }	        break;	    case SCSI_DATA_IN_PHASE:		{		int addLengthByte = pScsiXaction->addLengthByte;		int dataLength = pScsiXaction->dataLength;		UINT8 *dataAddress = pScsiXaction->dataAddress;		if ((addLengthByte == NONE) ||		    (dataLength <= (addLengthByte + 1)))		    {	            status = (*pScsiCtrl->scsiBytesIn)			         (pScsiPhysDev, dataAddress,			          dataLength, scsiPhase);		    if (status == ERROR)		        {		        return (ERROR);		        }		    }		else		    {	            status = (*pScsiCtrl->scsiBytesIn)			         (pScsiPhysDev, dataAddress,			          addLengthByte + 1, scsiPhase);		    if (status == ERROR)		        {		        return (ERROR);		        }	    if ((*pScsiCtrl->scsiBusPhaseGet) (pScsiCtrl, 0, &scsiPhase) != OK)	        {		SCSI_DEBUG_MSG ("scsiBusPhaseGet returned ERROR.\n",				0, 0, 0, 0, 0, 0);	        return (ERROR);	        }		if (scsiPhase != SCSI_DATA_IN_PHASE)		    goto phaseSwitch;	            status = (*pScsiCtrl->scsiBytesIn)			         (pScsiPhysDev,				  dataAddress + addLengthByte + 1,				  min (dataAddress [addLengthByte],				       dataLength - (addLengthByte + 1)),				  scsiPhase);		    if (status == ERROR)		        {		        return (ERROR);		        }		    }	        break;		}	    case SCSI_COMMAND_PHASE:		status = (*pScsiCtrl->scsiBytesOut)			     (pScsiPhysDev, pScsiXaction->cmdAddress,			      pScsiXaction->cmdLength, scsiPhase);		if (status != OK)		    {		    return (ERROR);		    }		break;	    case SCSI_STATUS_PHASE:	        status = (*pScsiCtrl->scsiBytesIn)			     (pScsiPhysDev, &pScsiXaction->statusByte,			      sizeof (pScsiXaction->statusByte), scsiPhase);		if (status == ERROR)		    {		    return (ERROR);		    }	        break;	    case SCSI_MSG_OUT_PHASE:	        status = (*pScsiCtrl->scsiBytesOut)			     (pScsiPhysDev, pScsiPhysDev->msgOutArray,			      pScsiPhysDev->msgLength, scsiPhase);		if (status == ERROR)		    {		    return (ERROR);		    }		else		    pScsiPhysDev->msgLength = 0;	        break;	    case SCSI_MSG_IN_PHASE:		pMsgIn = msgIn;	        status = (*pScsiCtrl->scsiBytesIn)			     (p

⌨️ 快捷键说明

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