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

📄 scsi2lib.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* initialize wide / sync support for each target to be FALSE */    pScsiTarget->wideSupport   = FALSE;    pScsiTarget->syncSupport   = FALSE;    scsiTargetReset (pScsiCtrl, busId);    }/********************************************************************************* scsiTargetReset - reset the state of a SCSI target** Reset the target's state variables, but do not change its configurable* parameters.  Typically called when a target is initialised, and when a* SCSI bus reset occurs.** RETURNS: N/A** NOMANUAL*/VOID scsiTargetReset    (    FAST SCSI_CTRL *pScsiCtrl,		/* ptr to SCSI controller info    */    UINT busId				/* SCSI bus ID of target to reset */    )    {    FAST SCSI_TARGET *pScsiTarget = &pScsiCtrl->targetArr [busId];        /* intialise synchronous transfer fsm */    scsiSyncXferNegotiate (pScsiCtrl, pScsiTarget, SYNC_XFER_RESET);    /* similarly, intialise the wide data transfer fsm */    scsiWideXferNegotiate (pScsiCtrl, pScsiTarget, WIDE_XFER_RESET);    }/********************************************************************************* scsiTargetOptionsSet - set options for one or all SCSI targets** This routine sets the options defined by the bitmask `which' for the* specified target (or all targets if `devBusId' is SCSI_SET_OPT_ALL_TARGETS).** The bitmask `which' can be any combination of the following, bitwise* OR'd together (corresponding fields in the SCSI_OPTIONS structure are* shown in parentheses):** .TS* tab(|);* l l l.* SCSI_SET_OPT_TIMEOUT    | 'selTimeOut' | select timeout period, microseconds* * SCSI_SET_OPT_MESSAGES   | 'messages'   | FALSE to disable SCSI messages** SCSI_SET_OPT_DISCONNECT | 'disconnect' | FALSE to disable discon/recon** SCSI_SET_OPT_XFER_PARAMS| 'maxOffset,' | max sync xfer offset, 0=>async*                         |  'minPeriod' | min sync xfer period, x 4 nsec.** SCSI_SET_OPT_TAG_PARAMS | 'tagType,'   | default tag type (SCSI_TAG_*)*                         |  'maxTags'   | max cmd tags available** SCSI_SET_OPT_WIDE_PARAMS| 'xferWidth'  | data transfer width in bits** .TE** NOTE* This routine can be used after the target device has already been used; * in this case, however, it is not possible to change the tag parameters. * This routine must not be used while there is any SCSI activity on the * specified target(s).** RETURNS: OK, or ERROR if the bus ID or options are invalid.*/STATUS scsiTargetOptionsSet    (    SCSI_CTRL    *pScsiCtrl,		/* ptr to SCSI controller info   */    int           devBusId,		/* target to affect, or all      */    SCSI_OPTIONS *pOptions,		/* buffer containing new options */    UINT          which			/* which options to change       */    )    {    int i;    /* verify bus ID of target, and validity of "which" bitmask */        if (((devBusId < SCSI_MIN_BUS_ID) || (devBusId > SCSI_MAX_BUS_ID)) &&	(devBusId != SCSI_SET_OPT_ALL_TARGETS))	{	errnoSet (S_scsiLib_ILLEGAL_BUS_ID);	return (ERROR);	}    if ((which & SCSI_SET_OPT_BITMASK) != which)	{	errnoSet (S_scsiLib_ILLEGAL_PARAMETER);	return (ERROR);	}    /* set options for one or all targets (loop is easiest approach) */        for (i = 0; i < SCSI_MAX_TARGETS; ++i)	{	if ((devBusId == i) || (devBusId == SCSI_SET_OPT_ALL_TARGETS))	    {	    SCSI_TARGET *pScsiTarget = &pScsiCtrl->targetArr [i];	    /* support for variable select timeout period (us) */	    	    if (which & SCSI_SET_OPT_TIMEOUT)		pScsiTarget->selTimeOut = pOptions->selTimeOut;	    /* support for messages (other than COMMAND COMPLETE) */	    	    if (which & SCSI_SET_OPT_MESSAGES)		pScsiTarget->messages = pOptions->messages;	    /* support for disconnect / reconnect (requires messages) */	    	    if (which & SCSI_SET_OPT_DISCONNECT)		{		if (pOptions->disconnect &&		    (!pScsiCtrl->disconnect || !pScsiTarget->messages))		    {		    errnoSet (S_scsiLib_ILLEGAL_PARAMETER);		    return (ERROR);		    }		pScsiTarget->disconnect = pOptions->disconnect;		}	    /* support for synchronous data transfer (requires messages) */	    	    if (which & SCSI_SET_OPT_XFER_PARAMS)		{		if ((pOptions->maxOffset != SCSI_SYNC_XFER_ASYNC_OFFSET) &&		    (!pScsiCtrl->syncXfer || !pScsiTarget->messages))		    {		    errnoSet (S_scsiLib_ILLEGAL_PARAMETER);		    return (ERROR);		    }				pScsiTarget->maxOffset = pOptions->maxOffset;		pScsiTarget->minPeriod = pOptions->minPeriod;    	    	/* re-intialise synchronous transfer fsm */    	    	scsiSyncXferNegotiate (pScsiCtrl, pScsiTarget, SYNC_XFER_RESET);		}	    /* support for tagged commands (requires messages) */	    	    if (which & SCSI_SET_OPT_TAG_PARAMS)		{		BOOL valid;				switch (pOptions->tagType)		    {		    case SCSI_TAG_UNTAGGED:		    	valid = (pOptions->maxTags == 0);			break;		    case SCSI_TAG_SIMPLE:		    case SCSI_TAG_ORDERED:		    case SCSI_TAG_HEAD_OF_Q:			valid = pScsiTarget->messages    &&			    	(pOptions->maxTags >  0) &&			        (pOptions->maxTags <= SCSI_MAX_TAGS);			break;					    default:		    	valid = FALSE;			break;		    }		if (!valid)		    {		    errnoSet (S_scsiLib_ILLEGAL_PARAMETER);		    return (ERROR);		    }    	    	pScsiTarget->tagType = pOptions->tagType;		pScsiTarget->maxTags = pOptions->maxTags;		}            /* support for wide data transfer */            if (which & SCSI_SET_OPT_WIDE_PARAMS)	        {		if (!pScsiCtrl->wideXfer || 		       ( pOptions->xferWidth != SCSI_WIDE_XFER_SIZE_NARROW &&		         pOptions->xferWidth != SCSI_WIDE_XFER_SIZE_DEFAULT                       ) )		    {		    errnoSet (S_scsiLib_ILLEGAL_PARAMETER);		    return (ERROR);		    }                pScsiTarget->xferWidth = pOptions->xferWidth;                /* re-initialise wide data xfer fsm */    	    	scsiWideXferNegotiate (pScsiCtrl, pScsiTarget, WIDE_XFER_RESET);		}	    }	}        return (OK);    }/********************************************************************************* scsiTargetOptionsGet - get options for one or all SCSI targets** This routine copies the current options for the specified target into the* caller's buffer.** RETURNS: OK, or ERROR if the bus ID is invalid.*/STATUS scsiTargetOptionsGet    (    SCSI_CTRL    *pScsiCtrl,		/* ptr to SCSI controller info */    int           devBusId,		/* target to interrogate       */    SCSI_OPTIONS *pOptions		/* buffer to return options    */    )    {    SCSI_TARGET *pScsiTarget;    if ((devBusId < SCSI_MIN_BUS_ID) || (devBusId > SCSI_MAX_BUS_ID))	{	errnoSet (S_scsiLib_ILLEGAL_BUS_ID);	return (ERROR);	}    pScsiTarget = &pScsiCtrl->targetArr [devBusId];    pOptions->selTimeOut = pScsiTarget->selTimeOut;    pOptions->messages   = pScsiTarget->messages;    pOptions->disconnect = pScsiTarget->disconnect;    pOptions->maxOffset  = pScsiTarget->maxOffset;    pOptions->minPeriod  = pScsiTarget->minPeriod;    pOptions->tagType    = pScsiTarget->tagType;    pOptions->maxTags    = pScsiTarget->maxTags;    pOptions->xferWidth  =  pScsiTarget->xferWidth;    return (OK);    }/********************************************************************************* scsi2PhysDevDelete - delete a SCSI physical device structure** This routine deletes a specified SCSI physical device structure.** RETURNS: OK, or ERROR if `pScsiPhysDev' is NULL or SCSI_BLK_DEVs have* been created on the device.*/LOCAL STATUS scsi2PhysDevDelete    (    FAST SCSI_PHYS_DEV *pScsiPhysDev    /* ptr to SCSI physical device info */    )    {    FAST SCSI_CTRL *pScsiCtrl;    if ((pScsiPhysDev == (SCSI_PHYS_DEV *) NULL)        ||	(lstCount (&pScsiPhysDev->blkDevList)     != 0) ||	(lstCount (&pScsiPhysDev->activeThreads)  != 0) ||	(lstCount (&pScsiPhysDev->waitingThreads) != 0))	return (ERROR);    pScsiCtrl = pScsiPhysDev->pScsiCtrl;    pScsiCtrl->physDevArr [(pScsiPhysDev->pScsiTarget->scsiDevBusId << 3) |			   pScsiPhysDev->scsiDevLUN] = (SCSI_PHYS_DEV *) NULL;    if (pScsiPhysDev->pReqSenseData != NULL)        (void) free ((char *) pScsiPhysDev->pReqSenseData);    if (pScsiPhysDev->pTagInfo != 0)	(void) free ((char *) pScsiPhysDev->pTagInfo);    if (pScsiPhysDev->mutexSem != 0)	(void) semDelete (pScsiPhysDev->mutexSem);    (void) free ((char *) pScsiPhysDev);    return (OK);    }/********************************************************************************* scsi2PhysDevCreate - create a SCSI physical device structure** This routine enables access to a SCSI device and must be invoked first.* It should be called once for each physical device on the SCSI bus.** If `reqSenseLength' is specified as NULL (0), one or more REQUEST_SENSE* commands are issued to the device to determine the number of bytes of* sense data it typically returns.  Note that if the device returns variable* amounts of sense data depending on its state, consult the device manual * to determine the maximum amount of sense data that can be returned.** An INQUIRY command is issued to determine information about the device* including its type, make and model number, and its ability to accept* SCSI-2 features such as tagged commands.  The scsiShow() routine displays* this information.** If `numBlocks' or `blockSize' are specified as NULL (0), a READ_CAPACITY* command is issued to determine those values.  This will occur* only for device types which support READ_CAPACITY.** RETURNS: A pointer to the created SCSI_PHYS_DEV structure, or NULL if the* routine is unable to create the physical device structure.** NOTE: the `devType' and `removable' arguments are ignored.*/LOCAL SCSI_PHYS_DEV *scsi2PhysDevCreate    (    SCSI_CTRL *pScsiCtrl,       /* ptr to SCSI controller info */    int devBusId,               /* device's SCSI bus ID */    int devLUN,                 /* device's logical unit number */    int reqSenseLength,         /* length of REQUEST SENSE data dev returns */    int devType,                /* type of SCSI device */    BOOL removable,             /* whether medium is removable */    int numBlocks,              /* number of blocks on device */    int blockSize               /* size of a block in bytes */    )    {    SCSI_PHYS_DEV *pScsiPhysDev;	/* ptr to SCSI physical dev. struct */    SCSI_TARGET   *pScsiTarget;	    	/* ptr to SCSI target structure */					/* REQ SENSE data for auto-sizing */    UINT8 reqSenseData [REQ_SENSE_ADD_LENGTH_BYTE + 1];    UINT8 inquiryData  [DEFAULT_INQUIRY_DATA_LENGTH];    /* check bus ID and LUN are within limits */    if ((devBusId < SCSI_MIN_BUS_ID) ||	(devBusId > SCSI_MAX_BUS_ID) ||	(devLUN < SCSI_MIN_LUN) ||	(devLUN > SCSI_MAX_LUN))	{	errnoSet (S_scsiLib_ILLEGAL_PARAMETER);	return ((SCSI_PHYS_DEV *) NULL);	}    /* Check if this device was already created */    if (scsiPhysDevIdGet (pScsiCtrl, devBusId, devLUN) != NULL)        {        errnoSet (S_scsiLib_DEVICE_EXIST);        return ((SCSI_PHYS_DEV *) NULL);	}    /* create a SCSI physical device structure */    pScsiPhysDev = (SCSI_PHYS_DEV *) calloc (1, sizeof (*pScsiPhysDev));    if (pScsiPhysDev == NULL)        return ((SCSI_PHYS_DEV *) NULL);    /* create device mutual exclusion semaphore */    if ((pScsiPhysDev->mutexSem = semMCreate (scsiPhysDevMutexOptions)) == NULL)        {        SCSI_DEBUG_MSG ("scsiPhysDevCreate: semMCreate of mutexSem failed.\n",			0, 0, 0, 0, 0, 0);	goto failed;        }    /* initialize miscellaneous fields in the SCSI_PHYS_DEV struct */    pScsiTarget = &pScsiCtrl->targetArr [devBusId];        pScsiPhysDev->pScsiCtrl   = pScsiCtrl;    pScsiPhysDev->pScsiTarget = pScsiTarget;    pScsiPhysDev->scsiDevLUN  = devLUN;        pScsiCtrl->physDevArr [(devBusId << 3) | devLUN] = pScsiPhysDev;    /* initialize block device list */

⌨️ 快捷键说明

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