📄 scsi2lib.c
字号:
(pScsiPhysDev->lastAddSenseCode == SCSI_ADD_SENSE_NO_MEDIUM)) { pScsiPhysDev->numBlocks = 0; pScsiPhysDev->blockSize = 0; break; } else { /* if 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); } } 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); }/********************************************************************************* strIsPrintable - determine whether a string contains all printable chars** RETURNS: TRUE | FALSE.*/LOCAL BOOL strIsPrintable ( FAST char *pString /* ptr to string to be tested */ ) { FAST char ch; while ((ch = *pString++) != EOS) { if (!isprint (ch)) return (FALSE); } return (TRUE); }/********************************************************************************* scsi2Show - list the physical devices attached to a SCSI controller** This routine displays the SCSI bus ID, logical unit number (LUN), vendor ID,* product ID, firmware revision (rev.), device type, number of blocks,* block size in bytes, and a pointer to the associated SCSI_PHYS_DEV* structure for each physical SCSI device known to be attached to a specified* SCSI controller.** NOTE:* If `pScsiCtrl' is NULL, the value of the global variable `pSysScsiCtrl'* is used, unless it is also NULL.** RETURNS: OK, or ERROR if both `pScsiCtrl' and `pSysScsiCtrl' are NULL.*/LOCAL STATUS scsi2Show ( FAST SCSI_CTRL *pScsiCtrl /* ptr to SCSI controller info */ ) { FAST SCSI_PHYS_DEV *pScsiPhysDev; /* SCSI physical device info */ FAST int ix; /* loop variable */ 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 (ERROR); } } printf ("ID LUN VendorID ProductID Rev. "); printf ("Type Blocks BlkSize pScsiPhysDev \n"); printf ("-- --- -------- ---------------- ---- "); printf ("---- -------- ------- ------------\n"); for (ix = 0; ix < SCSI_MAX_PHYS_DEVS; ix++) if ((pScsiPhysDev = pScsiCtrl->physDevArr[ix]) != (SCSI_PHYS_DEV *) NULL) { printf ("%2d " , pScsiPhysDev->pScsiTarget->scsiDevBusId); printf ("%2d " , pScsiPhysDev->scsiDevLUN); printf (" %8s" , strIsPrintable (pScsiPhysDev->devVendorID) ? pScsiPhysDev->devVendorID : " "); printf (" %16s", strIsPrintable (pScsiPhysDev->devProductID) ? pScsiPhysDev->devProductID : " "); printf (" %4s ", strIsPrintable (pScsiPhysDev->devRevLevel) ? pScsiPhysDev->devRevLevel : " "); printf ("%3d" , pScsiPhysDev->scsiDevType); printf (pScsiPhysDev->removable ? "R" : " "); printf (" %8d " , pScsiPhysDev->numBlocks); printf (" %5d " , pScsiPhysDev->blockSize); printf (" 0x%08x ", (int) pScsiPhysDev); printf ("\n"); } return (OK); }/********************************************************************************* scsiThreadShow - show information for a SCSI thread** Display the role, priority, tag type (and number, if appropriate) and* state of a SCSI thread. May be called at any time, but note that the* state is a "snapshot".** RETURNS: N/A** NOMANUAL*/void scsiThreadShow ( SCSI_THREAD * pThread, /* thread to be displayed */ BOOL noHeader /* do not print title line */ ) { char * role; char * tagType; char * state; switch (pThread->role) { case SCSI_ROLE_INITIATOR: role = "init"; break; case SCSI_ROLE_TARGET: role = "targ"; break; case SCSI_ROLE_IDENT_INIT: role = "id-i"; break; case SCSI_ROLE_IDENT_TARG: role = "id-t"; break; default: role = "????"; break; } switch (pThread->tagType) { case SCSI_TAG_DEFAULT: tagType = "default"; break; case SCSI_TAG_UNTAGGED: tagType = "untagged"; break; case SCSI_TAG_SENSE_RECOVERY: tagType = "recovery"; break; case SCSI_TAG_SIMPLE: tagType = "simple"; break; case SCSI_TAG_ORDERED: tagType = "ordered"; break; case SCSI_TAG_HEAD_OF_Q: tagType = "queue hd"; break; default: tagType = "????????"; break; } switch (pThread->state) { case SCSI_THREAD_INACTIVE: state = "inact"; break; case SCSI_THREAD_WAITING: state = "wait"; break; case SCSI_THREAD_DISCONNECTED: state = "disc."; break; default: state = "conn."; break; } if (!noHeader) { printf ("Thread ID PhysDev ID Role Pri Tag Type (#) State\n"); printf ("---------- ---------- ---- --- -------------- -----\n"); } printf ("0x%08x 0x%08x %4s %3d %-8s (%3d) %5s\n", (int) pThread, (int) pThread->pScsiPhysDev, role, pThread->priority, tagType, pThread->tagNumber, state); }/********************************************************************************* scsiPhysDevShow - show status information for a physical device** This routine shows the state, the current nexus type, the current tag* number, the number of tagged commands in progress, and the number of* waiting and active threads for a SCSI physical device. Optionally, it shows* the IDs of waiting and active threads, if any. This routine may be called* at any time, but note that all of the information displayed is volatile.** RETURNS: N/A*/void scsiPhysDevShow ( SCSI_PHYS_DEV * pScsiPhysDev, /* physical device to be displayed */ BOOL showThreads, /* show IDs of associated threads */ BOOL noHeader /* do not print title line */ ) { char * nexus; char * state; int nWaiting = lstCount (&pScsiPhysDev->waitingThreads); int nActive = lstCount (&pScsiPhysDev->activeThreads); switch (pScsiPhysDev->nexus) { case SCSI_NEXUS_NONE: nexus = "none"; break; case SCSI_NEXUS_IT: nexus = "IT" ; break; case SCSI_NEXUS_ITL: nexus = "ITL" ; break; case SCSI_NEXUS_ITLQ: nexus = "ITLQ"; break; default: nexus = "????"; break; } state = pScsiPhysDev->connected ? "conn." : "disc."; if (!noHeader) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -