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

📄 scsi1lib.c

📁 VxWorks操作系统内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    int ix;			/* loop index */    /* initialize controller mutual exclusion semaphore */    if (semMInit (&pScsiCtrl->ctrlMutexSem, scsiCtrlMutexOptions) == ERROR)        {        printErr ("scsi1CtrlInit: semMInit of ctrlMutexSem failed.\n");        return (ERROR);        }    /* initialize controller interrupt waiting semaphore */    if (semBInit (&pScsiCtrl->ctrlSyncSem, scsiCtrlSemOptions,		  SEM_EMPTY) == ERROR)	{	printErr ("scsi1CtrlInit: semBInit of ctrlSyncSem failed.\n");	return (ERROR);	}    /* initialize the scsiBusReset to NULL (set by individual drivers) */    pScsiCtrl->scsiBusReset = (VOIDFUNCPTR) NULL;    /* initialize the scsiPriority to NONE (set by individual drivers) */    pScsiCtrl->scsiPriority = NONE;    /* initialize array of ptrs to SCSI_PHYS_DEV structures to NULL */    for (ix = 0; ix < MAX_SCSI_PHYS_DEVS; ix++)	{	pScsiCtrl->physDevArr [ix] = (SCSI_PHYS_DEV *) NULL;	}    return (OK);    }/********************************************************************************* scsi1PhysDevDelete - 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 scsi1PhysDevDelete    (    FAST SCSI_PHYS_DEV *pScsiPhysDev    /* ptr to SCSI physical device info */    )    {    FAST SCSI_CTRL *pScsiCtrl;    STATUS status;    if ((pScsiPhysDev == (SCSI_PHYS_DEV *) NULL) ||	(pScsiPhysDev->pScsiBlkDev != (SCSI_BLK_DEV *) NULL))	return (ERROR);    /* Reset target if the sync capacity is existing */    if ( pScsiPhysDev->syncXfer == TRUE )        {        SCSI_SYNC_AGREEMENT syncAgreement;        /* Send a sync message for async protocol */        status = scsiSyncTarget(pScsiPhysDev, pScsiPhysDev->syncXferPeriod				, 0, &syncAgreement);        /* Clear the next check status */        status = scsiTestUnitRdy(pScsiPhysDev);        }    pScsiCtrl = pScsiPhysDev->pScsiCtrl;    pScsiCtrl->physDevArr [(pScsiPhysDev->scsiDevBusId << 3) |			   pScsiPhysDev->scsiDevLUN] = (SCSI_PHYS_DEV *) NULL;    if (pScsiPhysDev->pReqSenseData != NULL)        (void) free ((char *) pScsiPhysDev->pReqSenseData);    (void) free ((char *) pScsiPhysDev);    return (OK);    }/********************************************************************************* scsi1PhysDevCreate - 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.** If `devType' is specified as NONE (-1), an INQUIRY command is issued to* determine the device type, with the added benefit of acquiring the device's* make and model number.  The scsiShow() routine displays this information.* Common values of `devType' can be found in scsiLib.h or in the SCSI* specification.** 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.*/LOCAL SCSI_PHYS_DEV *scsi1PhysDevCreate    (    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 */					/* REQ SENSE data for auto-sizing */    UINT8 reqSenseData [REQ_SENSE_ADD_LENGTH_BYTE + 1];    SCSI_PHYS_DEV *pPhysDev;    /* use to check if it's already created */         /* 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 create and if it's support sync      * capacity.     */       pPhysDev = scsiPhysDevIdGet (pScsiCtrl,devBusId,devLUN);		    if (pPhysDev != (SCSI_PHYS_DEV *)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);    /* initialize device mutual exclusion semaphore */    if (semMInit (&pScsiPhysDev->devMutexSem, scsiPhysDevMutexOptions) == ERROR)        {        SCSI_DEBUG_MSG ("scsiPhysDevCreate: semMInit of devMutexSem failed.\n",			0, 0, 0, 0, 0, 0);	(void) free ((char *) pScsiPhysDev);        return ((SCSI_PHYS_DEV *) NULL);        }    /* initialize device interrupt waiting semaphore */    if (semBInit (&pScsiPhysDev->devSyncSem, scsiPhysDevSemOptions,		  SEM_EMPTY) == ERROR)        {        SCSI_DEBUG_MSG ("scsiPhysDevCreate: semBInit of devSyncSem failed.\n",			0, 0, 0, 0, 0, 0);	(void) free ((char *) pScsiPhysDev);        return ((SCSI_PHYS_DEV *) NULL);        }    /* initialize miscellaneous fields in the SCSI_PHYS_DEV struct */    pScsiPhysDev->scsiDevBusId	= devBusId;    pScsiPhysDev->scsiDevLUN	= devLUN;    pScsiPhysDev->devStatus 	= IDLE;    (*pScsiCtrl->scsiSelTimeOutCvt) (pScsiCtrl, scsiSelectTimeout,				     &pScsiPhysDev->selTimeOut);    pScsiPhysDev->pScsiCtrl = pScsiCtrl;    pScsiCtrl->physDevArr [(devBusId << 3) | devLUN] = pScsiPhysDev;    /* initialize block device list */    semMInit (&pScsiPhysDev->blkDevList.listMutexSem, blkDevListMutexOptions);    lstInit (&pScsiPhysDev->blkDevList.blkDevNodes);    if (reqSenseLength == 0)	{        /* determine if device uses Extended Sense Data Format */        if (scsiReqSense (pScsiPhysDev, (char *) reqSenseData, 1) == ERROR)	    {	    SCSI_DEBUG_MSG ("scsiPhysDevCreate: REQUEST SENSE failed.\n",			    0, 0, 0, 0, 0, 0);            (void) scsiPhysDevDelete (pScsiPhysDev);	    return ((SCSI_PHYS_DEV *) NULL);	    }        SCSI_DEBUG_MSG ("scsiPhysDevCreate: reqSenseData[0] = %x\n",		        reqSenseData[0], 0, 0, 0, 0, 0);        if ((reqSenseData[0] & SCSI_SENSE_DATA_CLASS) != SCSI_EXT_SENSE_CLASS)	    {	    /* device uses Nonextended Sense Data Format */	    pScsiPhysDev->extendedSense      = FALSE;	    pScsiPhysDev->reqSenseDataLength = NON_EXT_SENSE_DATA_LENGTH;	    }        else if ((reqSenseData[0] & SCSI_SENSE_DATA_CODE) !=		  SCSI_EXT_SENSE_CODE)	    {	    /* device uses Unknown Sense Data Format */	    errnoSet (S_scsiLib_DEV_UNSUPPORTED);	    SCSI_DEBUG_MSG ("scsiPhysDevCreate: Unknown Sense Data Format ",			    0, 0, 0, 0, 0, 0);	    SCSI_DEBUG_MSG ("(device not supported)\n", 0, 0, 0, 0, 0, 0);            (void) scsiPhysDevDelete (pScsiPhysDev);	    return ((SCSI_PHYS_DEV *) NULL);	    }        else	    {	    /* device uses Extended Sense Data Format */	    if (scsiReqSense (pScsiPhysDev, (char *) reqSenseData,	        REQ_SENSE_ADD_LENGTH_BYTE + 1) == ERROR)	        {	        SCSI_DEBUG_MSG ("scsiPhysDevCreate: REQUEST SENSE failed.\n",				0, 0, 0, 0, 0, 0);                (void) scsiPhysDevDelete (pScsiPhysDev);	        return ((SCSI_PHYS_DEV *) NULL);	        }	    SCSI_DEBUG_MSG ("scsiPhysDevCreate: reqSenseData[7] = %x\n",			    reqSenseData[REQ_SENSE_ADD_LENGTH_BYTE],			    0, 0, 0, 0, 0);	    pScsiPhysDev->extendedSense      = TRUE;	    pScsiPhysDev->reqSenseDataLength = REQ_SENSE_ADD_LENGTH_BYTE +	        (int) reqSenseData [REQ_SENSE_ADD_LENGTH_BYTE] + 1;	    }	}    else	{	pScsiPhysDev->reqSenseDataLength = reqSenseLength;	if (reqSenseLength == 4)	    pScsiPhysDev->extendedSense = FALSE;	else	    pScsiPhysDev->extendedSense = TRUE;	}    if ((pScsiPhysDev->pReqSenseData =	(UINT8 *) calloc (pScsiPhysDev->reqSenseDataLength,			  sizeof (UINT8))) == NULL)	{        (void) scsiPhysDevDelete (pScsiPhysDev);	return ((SCSI_PHYS_DEV *) NULL);	}    /* transact an INQUIRY command if devType is unspecified */    if ((devType == NONE) || (removable == NONE))        {	UINT8 inquiryData [DEFAULT_INQUIRY_DATA_LENGTH];	int ix;        /* do an INQUIRY command */	for (ix = 0; ix < DEFAULT_INQUIRY_DATA_LENGTH; ix++)	    inquiryData[ix] = (UINT8) 0;inquiryRetry:	if ((scsiInquiry (pScsiPhysDev, (char *) inquiryData,			 sizeof (inquiryData)) == OK) &&	    (inquiryData[0] != SCSI_LUN_NOT_PRESENT))	    {	    pScsiPhysDev->scsiDevType = inquiryData[0];	    pScsiPhysDev->removable = (BOOL) (inquiryData[1] &					      INQUIRY_REMOVABLE_MED_BIT);	    bcopy ((char *) &inquiryData[8], pScsiPhysDev->devVendorID,		   VENDOR_ID_LENGTH);	    bcopy ((char *) &inquiryData[16], pScsiPhysDev->devProductID,		   PRODUCT_ID_LENGTH);	    bcopy ((char *) &inquiryData[32], pScsiPhysDev->devRevLevel,		   REV_LEVEL_LENGTH);	    pScsiPhysDev->devVendorID [VENDOR_ID_LENGTH] = EOS;	    pScsiPhysDev->devProductID [PRODUCT_ID_LENGTH] = EOS;	    pScsiPhysDev->devRevLevel [REV_LEVEL_LENGTH] = EOS;	    }	else if (pScsiPhysDev->resetFlag == TRUE)	    {	    pScsiPhysDev->resetFlag = FALSE;	    SCSI_DEBUG_MSG ("retrying scsiInquiry...\n", 0, 0, 0, 0, 0, 0);	    goto inquiryRetry;	    }	else	    {	    if (inquiryData[0] == SCSI_LUN_NOT_PRESENT)		{		SCSI_DEBUG_MSG ("scsiPhysDevCreate: LUN not present.\n",				0, 0, 0, 0, 0, 0);		errnoSet (S_scsiLib_LUN_NOT_PRESENT);		}	    (void) scsiPhysDevDelete (pScsiPhysDev);	    return ((SCSI_PHYS_DEV *) NULL);	    }        }    else        {	pScsiPhysDev->scsiDevType = (UINT8) devType;	pScsiPhysDev->removable = removable;        }    /* record numBlocks and blockSize in physical device */    if (((pScsiPhysDev->scsiDevType == SCSI_DEV_DIR_ACCESS) ||    	 (pScsiPhysDev->scsiDevType == SCSI_DEV_WORM) ||    	 (pScsiPhysDev->scsiDevType == SCSI_DEV_RO_DIR_ACCESS)) &&	((numBlocks == 0) || (blockSize == 0)))        {	int lastLogBlkAdrs;	int blkLength;        /* do a READ_CAPACITY command */readCapRetry:	if (scsiReadCapacity (pScsiPhysDev, &lastLogBlkAdrs, &blkLength) == OK)	    {	    pScsiPhysDev->numBlocks = lastLogBlkAdrs + 1;	    pScsiPhysDev->blockSize = blkLength;	    }	else if (pScsiPhysDev->resetFlag == TRUE)	    {	    pScsiPhysDev->resetFlag = FALSE;	    SCSI_DEBUG_MSG ("retrying scsiReadCapacity...\n",			    0, 0, 0, 0, 0, 0);	    goto readCapRetry;	    }	else	    {            (void) scsiPhysDevDelete (pScsiPhysDev);	    return ((SCSI_PHYS_DEV *) NULL);	    }        }    else        {	pScsiPhysDev->numBlocks = numBlocks;	pScsiPhysDev->blockSize = blockSize;        }    return (pScsiPhysDev);    }/********************************************************************************* scsi1PhysDevIdGet - return a pointer to a SCSI_PHYS_DEV structure** This routine returns a pointer to the SCSI_PHYS_DEV structure of the SCSI* physical device located at a specified bus ID (`devBusId') and logical* unit number (`devLUN') and attached to a specified SCSI controller* (`pScsiCtrl').** RETURNS: A pointer to the specified SCSI_PHYS_DEV structure, or NULL if the* structure does not exist.*/

⌨️ 快捷键说明

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