📄 scsi2lib.c
字号:
lstInit (&pScsiPhysDev->blkDevList); /* initialize sequential dev ptr */ pScsiPhysDev->pScsiSeqDev = NULL; /* initialize lists of active and waiting threads */ lstInit (&pScsiPhysDev->activeThreads); lstInit (&pScsiPhysDev->waitingThreads); /* initialize state variables */ pScsiPhysDev->connected = FALSE; pScsiPhysDev->pendingCA = FALSE; pScsiPhysDev->curTag = SCSI_TAG_NONE; pScsiPhysDev->nexus = SCSI_NEXUS_NONE; pScsiPhysDev->savedNexus = SCSI_NEXUS_NONE; pScsiPhysDev->nTaggedNexus = 0; /* initialise tags: do not use tags until after the INQUIRY command ! */ pScsiPhysDev->tagType = SCSI_TAG_UNTAGGED; pScsiPhysDev->nTags = 0; pScsiPhysDev->pTagInfo = 0; scsiMgrPhysDevTagInit (pScsiPhysDev); /* * Issue a Request Sense command to establish length of sense data, * if not specified by caller. */ if (reqSenseLength != 0) { pScsiPhysDev->reqSenseDataLength = reqSenseLength; if (reqSenseLength <= NON_EXT_SENSE_DATA_LENGTH) pScsiPhysDev->extendedSense = FALSE; else pScsiPhysDev->extendedSense = TRUE; } else { /* determine if 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); goto failed; } 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); goto failed; } else { /* device uses Extended Sense Data Format */ 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; } } if ((pScsiPhysDev->pReqSenseData = (UINT8 *) calloc (pScsiPhysDev->reqSenseDataLength, sizeof (UINT8))) == NULL) { goto failed; } /* * Issue an INQUIRY command: retry while a reset condition persists */ bzero ((char *) inquiryData, sizeof (inquiryData)); while (scsiInquiry (pScsiPhysDev, (char *) inquiryData, sizeof (inquiryData)) != OK) { if (!pScsiPhysDev->resetFlag) goto failed; pScsiPhysDev->resetFlag = FALSE; SCSI_DEBUG_MSG ("retrying scsiInquiry...\n", 0, 0, 0, 0, 0, 0); } /* * The INQUIRY command was successful: is there a device on this LUN ? */ if (inquiryData[SCSI_INQUIRY_DEV_TYPE] == SCSI_LUN_NOT_PRESENT) { SCSI_DEBUG_MSG ("scsiPhysDevCreate: LUN not present.\n", 0, 0, 0, 0, 0, 0); errnoSet (S_scsiLib_LUN_NOT_PRESENT); goto failed; } /* * There is a supported device on this LUN */ { int devType = inquiryData[SCSI_INQUIRY_DEV_TYPE] & SCSI_INQUIRY_DEV_TYPE_MASK; BOOL removable = inquiryData[SCSI_INQUIRY_DEV_MODIFIER] & SCSI_INQUIRY_REMOVABLE_MASK; int ansiVersion = inquiryData[SCSI_INQUIRY_VERSION] & SCSI_INQUIRY_ANSI_VSN_MASK; BOOL supportsTags = inquiryData[SCSI_INQUIRY_FLAGS] & SCSI_INQUIRY_CMD_QUEUE_MASK; BOOL syncSupport = inquiryData[SCSI_INQUIRY_FLAGS] & 0x10; BOOL wideSupport = (inquiryData[SCSI_INQUIRY_FLAGS] & SCSI_INQUIRY_WIDE_16_MASK) | (inquiryData[SCSI_INQUIRY_FLAGS] & SCSI_INQUIRY_WIDE_32_MASK); /* * set the appropriate fields to indicate if the target * supports wide / synchronous transfers. */ pScsiTarget->wideSupport = wideSupport; pScsiTarget->syncSupport = syncSupport; pScsiPhysDev->scsiDevType = devType; pScsiPhysDev->removable = removable; pScsiPhysDev->tagType = (ansiVersion >= 2) && supportsTags ? pScsiTarget->tagType : SCSI_TAG_UNTAGGED; pScsiPhysDev->nTags = (pScsiPhysDev->tagType != SCSI_TAG_UNTAGGED) ? pScsiTarget->maxTags : 0; if (pScsiPhysDev->nTags != 0) { /* * Allocate tag info. table; re-initialise tag system */ if ((pScsiPhysDev->pTagInfo = malloc (pScsiPhysDev->nTags * sizeof (SCSI_TAG_INFO))) == 0) { SCSI_DEBUG_MSG ("scsiPhysDevCreate: can't allocate tag info.\n", 0, 0, 0, 0, 0, 0); goto failed; } scsiMgrPhysDevTagInit (pScsiPhysDev); } /* * Save product info. strings in physical device structure */ bcopy ((char *) &inquiryData[SCSI_INQUIRY_VENDOR_ID], pScsiPhysDev->devVendorID, SCSI_INQUIRY_VENDOR_ID_LENGTH); bcopy ((char *) &inquiryData[SCSI_INQUIRY_PRODUCT_ID], pScsiPhysDev->devProductID, SCSI_INQUIRY_PRODUCT_ID_LENGTH); bcopy ((char *) &inquiryData[SCSI_INQUIRY_REV_LEVEL], pScsiPhysDev->devRevLevel, SCSI_INQUIRY_REV_LEVEL_LENGTH); pScsiPhysDev->devVendorID [SCSI_INQUIRY_VENDOR_ID_LENGTH] = EOS; pScsiPhysDev->devProductID [SCSI_INQUIRY_PRODUCT_ID_LENGTH] = EOS; pScsiPhysDev->devRevLevel [SCSI_INQUIRY_REV_LEVEL_LENGTH] = EOS; } /* 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; /* * Issue a READ_CAPACITY command: retry while a reset condition occurs */ while (scsiReadCapacity (pScsiPhysDev, &lastLogBlkAdrs, &blkLength) != OK) { /* if the command failed, then the device must have been reset */ if (!pScsiPhysDev->resetFlag) goto failed; pScsiPhysDev->resetFlag = FALSE; SCSI_DEBUG_MSG ("retrying scsiReadCapacity...\n", 0, 0, 0, 0, 0, 0); } /* * The READ CAPCITY command was successful */ pScsiPhysDev->numBlocks = lastLogBlkAdrs + 1; pScsiPhysDev->blockSize = blkLength; } else if (pScsiPhysDev->scsiDevType == SCSI_DEV_SEQ_ACCESS) { int pMaxBlockLength; /* where to return maximum block length */ UINT16 pMinBlockLength; while (scsiReadBlockLimits (pScsiPhysDev, &pMaxBlockLength, &pMinBlockLength) != OK) { /* if the command failed, then the device must have been reset */ if (!pScsiPhysDev->resetFlag) goto failed; pScsiPhysDev->resetFlag = FALSE; SCSI_DEBUG_MSG ("retrying scsiReadBlockLimits...\n", 0, 0, 0, 0, 0, 0); } pScsiPhysDev->maxVarBlockLimit = pMaxBlockLength; /* for sequential access devices, these fields are not used */ pScsiPhysDev->numBlocks = numBlocks; pScsiPhysDev->blockSize = blockSize; } return (pScsiPhysDev);failed: if (pScsiPhysDev->mutexSem != 0) (void) semDelete (pScsiPhysDev->mutexSem); if (pScsiPhysDev->pTagInfo != 0) (void) free ((char *) pScsiPhysDev->pTagInfo); if (pScsiPhysDev->pReqSenseData != 0) (void) free ((char *) pScsiPhysDev->pReqSenseData); (void) free ((char *) pScsiPhysDev); pScsiCtrl->physDevArr [(devBusId << 3) | devLUN] = NULL; return (NULL); }/********************************************************************************* scsi2PhysDevIdGet - 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.*/LOCAL SCSI_PHYS_DEV * scsi2PhysDevIdGet ( SCSI_CTRL *pScsiCtrl, /* ptr to SCSI controller info */ int devBusId, /* device's SCSI bus ID */ int devLUN /* device's logical unit number */ ) { /* check for valid ptr to SCSI_CTRL */ if (pScsiCtrl == NULL) { if (pSysScsiCtrl != NULL) pScsiCtrl = pSysScsiCtrl; else { errnoSet (S_scsiLib_NO_CONTROLLER); SCSI_DEBUG_MSG ("No SCSI controller specified.\n", 0, 0, 0, 0, 0, 0); return ((SCSI_PHYS_DEV *) NULL); } } return (pScsiCtrl->physDevArr [(devBusId << 3) | devLUN]); }/********************************************************************************* scsi2AutoConfig - configure all devices connected to a SCSI controller** This routine cycles through all legal SCSI bus IDs (and logical unit* numbers (LUNs)), attempting a scsiPhysDevCreate() with default parameters* on each. All devices which support the INQUIRY routine are* configured. The scsiShow() routine can be used to find the system's table* of SCSI physical devices attached to a specified SCSI controller. In* addition, scsiPhysDevIdGet() can be used programmatically to get a* pointer to the SCSI_PHYS_DEV structure associated with the device at a* specified SCSI bus ID and LUN.** RETURNS: OK, or ERROR if `pScsiCtrl' and `pSysScsiCtrl' are both NULL.*/LOCAL STATUS scsi2AutoConfig ( SCSI_CTRL *pScsiCtrl /* ptr to SCSI controller info */ ) { int busId, lun; /* loop indices */ SCSI_PHYS_DEV *pScsiPhysDev; /* ptr to SCSI physical device info */ /* check for valid input parameters */ if (pScsiCtrl == (SCSI_CTRL *) NULL) { if (pSysScsiCtrl == (SCSI_CTRL *) NULL) { errnoSet (S_scsiLib_NO_CONTROLLER); printErr ("No SCSI controller specified.\n"); return (ERROR); } pScsiCtrl = pSysScsiCtrl; } /* loop through all SCSI bus ID's and LUN's (logical units); if a given * bus ID times out during selection, do not test for other LUN's at * that bus ID, since there cannot be any. */ for (busId = SCSI_MIN_BUS_ID; busId <= SCSI_MAX_BUS_ID; busId++) { if (busId != pScsiCtrl->scsiCtrlBusId) { for (lun = SCSI_MIN_LUN; lun <= SCSI_MAX_LUN; lun++) { SCSI_DEBUG_MSG ("scsiAutoConfig: bus ID = %d, LUN = %d\n", busId, lun, 0, 0, 0, 0); if ((pScsiPhysDev = scsiPhysDevCreate (pScsiCtrl, busId, lun, 0, NONE, 0, 0, 0)) == (SCSI_PHYS_DEV *) NULL) { if (errnoGet () == S_scsiLib_SELECT_TIMEOUT) break; } } } } return (OK); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -