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

📄 scsi1lib.c

📁 VxWorks操作系统内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		{	        errnoSet (S_scsiLib_NO_CONTROLLER);	        printErr ("No SCSI controller specified.\n");		return (ERROR);		}	    }	(pScsiCtrl->scsiBusReset) (pScsiCtrl);	return (OK);	}    }/********************************************************************************* scsiDevSelect - call the scsiDevSelect routine in the SCSI_CTRL structure** This routine is not intended to be called directly by users, but rather* by other routines in scsiLib.  It merely calls a driver-specific routine* to select the desired SCSI physical device.** RETURNS: OK if device was successfully selected, otherwise ERROR.*/LOCAL STATUS scsiDevSelect    (    SCSI_PHYS_DEV *pScsiPhysDev,        /* ptr to SCSI physical device */    SCSI_TRANSACTION *pScsiXaction      /* ptr to SCSI transaction info */    )    {    return ((*pScsiPhysDev->pScsiCtrl->scsiDevSelect)	        (pScsiPhysDev, pScsiXaction));    }/********************************************************************************* scsi1PhaseNameGet - get the name of a specified SCSI phase** This routine returns a pointer to a string which is the name of the SCSI* phase input as an integer.  It's primarily used to improve readability of* debugging messages.** RETURNS: A pointer to a string naming the SCSI phase input** NOMANUAL*/LOCAL char *scsi1PhaseNameGet    (    int scsiPhase               /* phase whose name to look up */    )    {    static char *phaseNameArray [] =	{	"DATA_OUT",	"DATA_IN ",	"COMMAND ",	"STATUS  ",	"UNDEF(4)",	"UNDEF(5)",	"MSG_OUT ",	"MSG_IN  "	};    return ((scsiPhase < SCSI_DATA_OUT_PHASE ||	     scsiPhase > SCSI_MSG_IN_PHASE) ?	     "UNKNOWN " : phaseNameArray [scsiPhase]);    }/********************************************************************************* scsi1CmdBuild - fills in the fields of a SCSI command descriptor block** Typically, this routine is not called directly by the user, but by other* routines in scsiLib.  It fills in fields of a SCSI-command descriptor block* based on the input parameters.  The field layouts vary based on the command* group, which is determined from the `opCode'.** RETURNS: ERROR if vendor-unique command group or out-of-bounds parameter,* otherwise OK.** NOMANUAL*/LOCAL STATUS scsi1CmdBuild    (    SCSI_COMMAND scsiCmd,       /* command to be built */    int *pCmdLength,            /* ptr to command length variable */    UINT8 opCode,               /* SCSI opCode for command */    int LUN,                    /* logical unit number for command */    BOOL relAdrs,               /* whether to set relative address bit */    int logBlockAdrs,           /* logical block address */    int xferLength,             /* number of blocks or bytes to xfer */    UINT8 controlByte           /* control byte for command */    )    {    FAST int groupCode = (int) (opCode >> 5);    FAST int cmdLength;    /* array with the length of a SCSI command indexed by its group code     * (NONE == vendor unique)     */    LOCAL int scsiCmdLength [8] =        {        SCSI_GROUP_0_CMD_LENGTH,        SCSI_GROUP_1_CMD_LENGTH,        NONE,        NONE,        NONE,        SCSI_GROUP_5_CMD_LENGTH,        NONE,        NONE        };    if ((*pCmdLength = cmdLength = scsiCmdLength [groupCode]) == NONE)	return (ERROR);    if ((groupCode == 0) && (logBlockAdrs > 0x1fffff || xferLength > 0xff))	return (ERROR);    else if (xferLength > 0xffff)	return (ERROR);    scsiCmd[0] = opCode;    scsiCmd[1] = (UINT8) ((LUN & 0x7) << 5);    switch (groupCode)	{	case 0:	    scsiCmd[1] |= (UINT8) ((logBlockAdrs >> 16) & 0x1f);	    scsiCmd[2]  = (UINT8) ((logBlockAdrs >>  8) & 0xff);	    scsiCmd[3]  = (UINT8) ((logBlockAdrs      ) & 0xff);	    scsiCmd[4]  = (UINT8) xferLength;	    scsiCmd[5]  = controlByte;	    break;	case 1:	case 5:	    scsiCmd[1] |= (UINT8) (relAdrs ? 1 : 0);	    scsiCmd[2]  = (UINT8) ((logBlockAdrs >> 24) & 0xff);	    scsiCmd[3]  = (UINT8) ((logBlockAdrs >> 16) & 0xff);	    scsiCmd[4]  = (UINT8) ((logBlockAdrs >>  8) & 0xff);	    scsiCmd[5]  = (UINT8) ((logBlockAdrs      ) & 0xff);	    scsiCmd[6]  = (UINT8) 0;	    if (groupCode == 5)		{	        scsiCmd[7]  = (UINT8) 0;	        scsiCmd[8]  = (UINT8) 0;		}	    scsiCmd [cmdLength - 3] = (UINT8) ((xferLength >> 8) & 0xff);	    scsiCmd [cmdLength - 2] = (UINT8) ((xferLength     ) & 0xff);	    scsiCmd [cmdLength - 1] = controlByte;	    break;	}    return (OK);    }/********************************************************************************* scsi1TestUnitRdy - issue a TEST_UNIT_READY command to a SCSI device** This routine issues a TEST_UNIT_READY command to a specified SCSI device.** RETURNS: OK, or ERROR if the command fails.*/LOCAL STATUS scsi1TestUnitRdy    (    SCSI_PHYS_DEV *pScsiPhysDev         /* ptr to SCSI physical device */    )    {    SCSI_COMMAND testUnitRdyCommand;	/* SCSI command byte array */    SCSI_TRANSACTION scsiXaction;	/* info on a SCSI transaction */    SCSI_DEBUG_MSG ("scsiTestUnitRdy:\n", 0, 0, 0, 0, 0, 0);    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;    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;    (*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);    }/********************************************************************************* scsi1FormatUnit - issue a FORMAT_UNIT command to a SCSI device** This routine issues a FORMAT_UNIT command to a specified SCSI device.** RETURNS: OK, or ERROR if the command fails.*/LOCAL STATUS scsi1FormatUnit    (    SCSI_PHYS_DEV *pScsiPhysDev,/* ptr to SCSI physical device */    BOOL cmpDefectList,         /* whether defect list is complete */    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    = SCSI_TIMEOUT_FULL;    return ((*pScsiPhysDev->pScsiCtrl->scsiTransact)	    (pScsiPhysDev, &scsiXaction));    }/********************************************************************************* scsi1Inquiry - issue an INQUIRY command to a SCSI device** This routine issues an INQUIRY command to a specified SCSI device.** RETURNS: OK, or ERROR if the command fails.*/LOCAL STATUS scsi1Inquiry    (    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 inquiryCommand;	/* SCSI command byte array */    SCSI_TRANSACTION scsiXaction;	/* info on a SCSI transaction */    SCSI_DEBUG_MSG ("scsiInquiry:\n", 0, 0, 0, 0, 0, 0);    if (scsiCmdBuild (inquiryCommand, &scsiXaction.cmdLength,	SCSI_OPCODE_INQUIRY, pScsiPhysDev->scsiDevLUN, FALSE,	0, bufLength, (UINT8) 0)	== ERROR)    return (ERROR);    scsiXaction.cmdAddress    = inquiryCommand;    scsiXaction.dataAddress   = (UINT8 *) buffer;    scsiXaction.dataDirection = O_RDONLY;    scsiXaction.dataLength    = bufLength;    scsiXaction.addLengthByte = INQUIRY_ADD_LENGTH_BYTE;    scsiXaction.cmdTimeout    = SCSI_TIMEOUT_5SEC;    return ((*pScsiPhysDev->pScsiCtrl->scsiTransact)	    (pScsiPhysDev, &scsiXaction));    }/********************************************************************************* scsi1ModeSelect - 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 scsi1ModeSelect    (    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;    return ((*pScsiPhysDev->pScsiCtrl->scsiTransact)	    (pScsiPhysDev, &scsiXaction));    }/********************************************************************************* scsi1ModeSense - 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 scsi1ModeSense    (    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 */

⌨️ 快捷键说明

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