📄 scsi2lib.c
字号:
/********************************************************************************* 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) { printf ("PhysDev ID State Nexus Tag # Tags # Threads (w/a)\n"); printf ("---------- ----- ----- --- ------ ---------------\n"); } printf ("0x%08x %-5s %-4s %3d %3d %3d %3d\n", (int) pScsiPhysDev, state, nexus, pScsiPhysDev->curTag, pScsiPhysDev->nTaggedNexus, nWaiting, nActive); if (showThreads && (nWaiting != 0)) { printf ("\nWaiting threads:\n"); scsiThreadListIdShow (&pScsiPhysDev->waitingThreads); } if (showThreads && (nActive != 0)) { printf ("\nActive threads:\n"); scsiThreadListIdShow (&pScsiPhysDev->activeThreads); } }/********************************************************************************* scsiThreadListIdShow - show IDs of all threads in a list** Step through a list of threads, printing IDs of all threads in the list.* A maximum of 6 IDs are printed per line of output.** NOTE: this routine is naive about the list being updated while it is* traversed, so is best used when there is no SCSI activity.** RETURNS: N/A** NOMANUAL*/VOID scsiThreadListIdShow ( LIST * pList ) { NODE * pThread; int n; n = 0; for (pThread = lstFirst (pList); pThread != 0; pThread = lstNext (pThread)) { printf ("0x%08x ", (int) pThread); if ((++n % 6) == 0) { printf ("\n"); n = 0; } } if (n != 0) printf ("\n"); }/********************************************************************************* scsiThreadListShow - show info for all threads in a list** Step through a list of threads, showing details of all threads in the list.** NOTE: this routine is naive about the list being updated while it is* traversed, so is best used when there is no SCSI activity.** RETURNS: N/A** NOMANUAL*/void scsiThreadListShow ( LIST * pList ) { NODE * pThread; BOOL noHeader; noHeader = FALSE; for (pThread = lstFirst (pList); pThread != 0; pThread = lstNext (pThread)) { scsiThreadShow ((SCSI_THREAD *) pThread, noHeader); noHeader = TRUE; } }/********************************************************************************* scsi2BusReset - pulse the reset signal on the SCSI bus** This routine calls a controller-specific routine to reset a specified* controller's SCSI bus. If no controller is specified (`pScsiCtrl' is 0),* the value in `pSysScsiCtrl' is used.** RETURNS: OK, or ERROR if there is no controller or controller-specific* routine.** INTERNAL** The SCSI manager must be notified that a SCSI bus reset has occurred. This* is normally done by the ISR for the SCSI controller hardware, assuming it* can detect a bus reset. If this is not the case "scsiBusResetNotify ()"* must be called explicitly, perhaps by a board-specific ISR.*/LOCAL STATUS scsi2BusReset ( SCSI_CTRL *pScsiCtrl /* ptr to SCSI controller info */ ) { if (pScsiCtrl == (SCSI_CTRL *) NULL) { if (pSysScsiCtrl != (SCSI_CTRL *) NULL) pScsiCtrl = pSysScsiCtrl; else { errnoSet (S_scsiLib_NO_CONTROLLER); printErr ("No SCSI controller specified.\n"); return (ERROR); } } (pScsiCtrl->scsiBusControl) (pScsiCtrl, SCSI_BUS_RESET); return (OK); }/********************************************************************************* scsiBusResetNotify - notify the SCSI library that a bus reset has occurred.** This function should not normally be called by application code. It may be* called from interrupt service routines (typically in the controller- or* BSP-specific code which handles a SCSI bus reset interrupt).** INTERNAL* SCSI controller interrupts must be disabled while the synthesised* bus reset event is posted to the controller, to ensure that the posting* operation (which is not inherently atomic) is not interrupted by the ISR.** NOMANUAL*/void scsiBusResetNotify ( SCSI_CTRL *pScsiCtrl /* ctrlr for bus which was reset */ ) { SCSI_EVENT event; int key; event.type = SCSI_EVENT_BUS_RESET; key = intLock (); scsiMgrEventNotify (pScsiCtrl, &event, sizeof (event)); intUnlock (key); }/********************************************************************************* scsi2PhaseNameGet - get the name of a specified SCSI phase** This routine returns a pointer to a string which is the name of the SCSI* phase input as an integer. It's primarily used to improve readability of* debugging messages.** RETURNS: A pointer to a string naming the SCSI phase input*/LOCAL char *scsi2PhaseNameGet ( int scsiPhase /* phase whose name
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -