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

📄 scsiseqlib.c

📁 VxWorks操作系统内核源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
STATUS scsiWrtFileMarks    (    SCSI_SEQ_DEV * pScsiSeqDev,   /* ptr to SCSI sequential device info */    int            numMarks,      /* number of file marks to write      */    BOOL           shortMark	  /* TRUE to write short file mark      */    )    {    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;		/* status of transactions           */    SCSI_DEBUG_MSG ("scsiWrtFileMarks:\n", 0, 0, 0, 0, 0, 0);    pScsiPhysDev = pScsiSeqDev->pScsiPhysDev;    scsiCommand[0] = SCSI_OPCODE_WRITE_FILEMARKS;    scsiCommand[1] = (UINT8) ((pScsiPhysDev->scsiDevLUN & 0x7) << 5);    scsiCommand[2] = (UINT8) ((numMarks >> 16) & 0xff);    scsiCommand[3] = (UINT8) ((numMarks >>  8) & 0xff);    scsiCommand[4] = (UINT8) (numMarks & 0xff);    if (shortMark)	scsiCommand [5] = 0x80;    else        scsiCommand[5] = (UINT8) 0;    scsiXaction.cmdAddress    = scsiCommand;    scsiXaction.cmdLength     = SCSI_GROUP_0_CMD_LENGTH;    scsiXaction.dataAddress   = NULL;    scsiXaction.dataDirection = O_WRONLY;    scsiXaction.dataLength    = NULL;    scsiXaction.addLengthByte = NULL;    if (numMarks < 500)        scsiXaction.cmdTimeout = SCSI_TIMEOUT_5SEC * (numMarks + 10);    else	scsiXaction.cmdTimeout = SCSI_TIMEOUT_FULL;    scsiXaction.tagType       = SCSI_TAG_DEFAULT;    scsiXaction.priority      = SCSI_THREAD_TASK_PRIORITY;    status = (*pScsiPhysDev->pScsiCtrl->scsiTransact)	      (pScsiPhysDev, &scsiXaction);    return (status);    }/********************************************************************************* scsiSpace - move the tape on a specified physical SCSI device** This routine moves the tape on a specified SCSI physical device.* There are two types of space code that are mandatory in SCSI; currently* these are the only two supported:** .TS* tab(|);* lf3 lf3 cf3* l l c.* Code | Description | Support* _* 000 | Blocks		      | Yes* 001 | File marks            | Yes* 010 | Sequential file marks | No* 011 | End-of-data           | No* 100 | Set marks             | No* 101 | Sequential set marks  | No* .TE	** RETURNS: OK, or ERROR if an error is returned by the device.** ERRNO: S_scsiLib_ILLEGAL_REQUEST*/STATUS scsiSpace    (    SCSI_SEQ_DEV * pScsiSeqDev,  /* ptr to SCSI sequential device info */    int count,                   /* count for space command            */    int spaceCode		 /* code for the type of space command */    )    {    SCSI_PHYS_DEV *pScsiPhysDev;	/* ptr to SCSI physical device info */    SCSI_COMMAND scsiCommand;		/* SCSI command byte array          */    SCSI_TRANSACTION scsiXaction;	/* info on a SCSI transaction       */    STATUS status;			/* status of transaction            */    SCSI_DEBUG_MSG ("scsiSpace:\n", 0, 0, 0, 0, 0, 0);    pScsiPhysDev = pScsiSeqDev->pScsiPhysDev;    if ((count == 0) || ((spaceCode != SPACE_CODE_DATABLK) && 			 (spaceCode != SPACE_CODE_FILEMARK)))        {	errno = S_scsiLib_ILLEGAL_REQUEST;	return (ERROR);	}    scsiCommand[0] = SCSI_OPCODE_SPACE;    scsiCommand[1] = (UINT8) (((pScsiPhysDev->scsiDevLUN & 0x7) << 5) |			      (spaceCode));    scsiCommand[2] = (UINT8) ((count >> 16) & 0xff);    scsiCommand[3] = (UINT8) ((count >>  8) & 0xff);    scsiCommand[4] = (UINT8) (count & 0xff);    scsiCommand[5] = (UINT8) 0;    scsiXaction.cmdAddress    = scsiCommand;    scsiXaction.cmdLength     = SCSI_GROUP_0_CMD_LENGTH;    scsiXaction.dataAddress   = NULL;    scsiXaction.dataDirection = O_RDONLY;    scsiXaction.dataLength    = NULL;    scsiXaction.addLengthByte = NULL;    if (count < 500)        scsiXaction.cmdTimeout = SCSI_TIMEOUT_5SEC * count * 10;    else	scsiXaction.cmdTimeout = SCSI_TIMEOUT_FULL;    scsiXaction.tagType       = SCSI_TAG_DEFAULT;    scsiXaction.priority      = SCSI_THREAD_TASK_PRIORITY;    status = (*pScsiPhysDev->pScsiCtrl->scsiTransact)	      (pScsiPhysDev, &scsiXaction);    return (status);    }/********************************************************************************* scsiSeqStatusCheck - detect a change in media** This routine issues a TEST_UNIT_READY command to a SCSI device to detect a* change in media. It is called by file systems before executing open() or* creat().** INTERNAL* This function is a duplicate of that in scsiDirectLib, except for the fact* that this function operates on a SEQ_DEV.* * RETURNS: OK or ERROR.*/STATUS scsiSeqStatusCheck    (    SCSI_SEQ_DEV *pScsiSeqDev          /* ptr to a sequential 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  */    char             modeBuf[0xff];     /* get mode sense data array   */    int		     modeBufLen;    int 	     pageControl;    int              pageCode;    pScsiPhysDev =  pScsiSeqDev->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;    scsiXaction.tagType       = SCSI_TAG_DEFAULT;    scsiXaction.priority      = SCSI_THREAD_TASK_PRIORITY;    if ((*pScsiPhysDev->pScsiCtrl->scsiTransact) (pScsiPhysDev, &scsiXaction)							             == ERROR)	{        SCSI_DEBUG_MSG ("scsiSeqStatusCheck returning ERROR, last Sense = %x\n",                        pScsiPhysDev->lastSenseKey, 0, 0, 0, 0, 0);        return (ERROR);	}    pageControl = 0x0;  /* current values     */    pageCode    = 0x0;  /* no page formatting */    /* (Mode param hdr len) + (mode param block descriptor len) */    modeBufLen  = 4 + 8;    if (scsiModeSense (pScsiPhysDev, pageControl, pageCode, modeBuf,		       modeBufLen		       ) == ERROR)        return (ERROR);    /* Set the mode of the device */    pScsiSeqDev->seqDev.sd_mode =	( modeBuf [SCSI_MODE_DEV_SPECIFIC_PARAM] &	  (UINT8) SCSI_DEV_SPECIFIC_WP_MASK        ) ? O_RDONLY : O_RDWR;    return (OK);       }/********************************************************************************* scsiSeqIoctl - perform an I/O control function for sequential access devices** This routine issues scsiSeqLib commands to perform sequential* device-specific I/O control operations.** RETURNS: OK or ERROR.** ERRNO: S_scsiLib_INVALID_BLOCK_SIZE*/int scsiSeqIoctl    (    SCSI_SEQ_DEV *  pScsiSeqDev,    /* ptr to SCSI sequential device */    int		    function,	    /* ioctl function code */    int		    arg 	    /* argument to pass to called function */    )    {    char modeBuf[MODE_BUF_LENGTH];    int  modeBufLen;    int  pageControl;    int  pageCode;    int  pageFormat;    int  savePages;    int  blkSize;    SCSI_PHYS_DEV * pScsiPhysDev;	/* ptr to SCSI physical device struct */    if ((pScsiPhysDev = pScsiSeqDev->pScsiPhysDev) == NULL)	{	/* XXX errno */	SCSI_DEBUG_MSG ("scsiSeqIoctl: pScsiSeqDev ptr NULL\n",0,0,0,0,0,0);	return (ERROR);	}    switch (function)	{    	case FIODENSITYSET:            /* Execute a MODE SENSE to get the right buffer values */	    pageControl = 0x0;  /* current values     */	    pageCode    = 0x0; 	/* no page formatting */            /* (Mode param hdr len) + (mode param block descriptor len) */    	    modeBufLen  = 4 + 8;	    if (scsiModeSense (pScsiPhysDev, pageControl, pageCode, modeBuf,			       modeBufLen			      ) == ERROR)		return (ERROR);            	    /* Execute a MODE SELECT to set the density value */	    modeBuf[0] = 0x0;	/* mode data len not valid for mode select   */	    /* modeBuf[1] is reserved; medium type not valid for seq devices */	    modeBuf[2] = 0x0;   /* dev-specific param not defined for md sel */	    modeBuf[4] = arg;   /* set density code                          */            pageFormat = 0x0;   /* no formatted pages                        */	    savePages  = 0x1;   /* save page values                          */	    if (scsiModeSelect (pScsiPhysDev, pageFormat, savePages, modeBuf,				modeBufLen) == ERROR)	        return (ERROR);            /* Check that the density was set correctly by issuing MODE SENSE */            	    if (scsiModeSense (pScsiPhysDev, pageControl, pageCode, modeBuf,			       modeBufLen			      ) == ERROR)		return (ERROR);            if (modeBuf[4] != arg)		{		/* XXX set errno */		return (ERROR);		}	    pScsiSeqDev->seqDev.sd_density = arg;	    return (OK);        case FIODENSITYGET:            /* Execute a MODE SENSE to get the right buffer values */                        pageControl = 0x0;  /* current values     */            pageCode    = 0x0;  /* no page formatting */            /* (Mode param hdr len) + (mode param block descriptor len) */            modeBufLen  = 4 + 8;            if (scsiModeSense (pScsiPhysDev, pageControl, pageCode, modeBuf,                               modeBufLen                              ) == ERROR)                return (ERROR);            * ((int *) arg) = modeBuf[4];	/* density */	    return (OK);        case FIOBLKSIZESET:            /* Execute a MODE SENSE to get the right buffer values */                        pageControl = 0x0;  /* current values     */            pageCode    = 0x0;  /* no page formatting */            /* (Mode param hdr len) + (mode param block descriptor len) */            modeBufLen  = 4 + 8;            if (scsiModeSense (pScsiPhysDev, pageControl, pageCode, modeBuf,                               modeBufLen                              ) == ERROR)                return (ERROR);            /* Execute a MODE SELECT to set the blkSize value */            modeBuf[0]  = 0x0;   /* mode data len not valid for mode select   */            /* modeBuf[1] is reserved; medium type not valid for seq devices  */	    modeBuf[1] = 0x0;            modeBuf[2] = 0x0;    /* dev-specific param not defined for md sel */            /* Set the block size */            modeBuf[9]  = (UINT8) ((arg >> 16) & 0xff);            modeBuf[10] = (UINT8) ((arg >>  8) & 0xff);            modeBuf[11] = (UINT8) ( arg & 0xff);             pageFormat = 0x1;   /* no formatted pages                        */            savePages  = 0x0;   /* save page values                          */            if (scsiModeSelect (pScsiPhysDev, pageFormat, savePages, modeBuf,                                modeBufLen) == ERROR)                return (ERROR);            /* Check that the block size was set correctly */            blkSize = scsiSeqIoctl (pScsiSeqDev, FIOBLKSIZEGET, 0);            if (blkSize != arg)                {                errno = S_scsiLib_INVALID_BLOCK_SIZE;                return (ERROR);                }            pScsiSeqDev->seqDev.sd_blkSize = blkSize;            return (OK);        case FIOBLKSIZEGET:            /* Execute a MODE SENSE to get the right buffer values */                        pageControl = 0x0;  /* current values     */            pageCode    = 0x0;  /* no page formatting */            /* (Mode param hdr len) + (mode param block descriptor len) */            modeBufLen  = 4 + 8;            if (scsiModeSense (pScsiPhysDev, pageControl, pageCode, modeBuf,                               modeBufLen                              ) == ERROR)                return (ERROR);            /* Construct the block size from the buffer */            blkSize  = 0;            blkSize  = (modeBuf[9]  << 16);            blkSize |= (modeBuf[10] <<  8);            blkSize |=  modeBuf[11];            return (blkSize);        default:	    SCSI_DEBUG_MSG ("scsiSeqIoctl: bad IOCTL function\n",0,0,0,0,0,0);            return (ERROR);        } /* switch */    }

⌨️ 快捷键说明

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