📄 scsi2lib.c
字号:
if (pScsiCtrl->timeoutQ != 0) (void) rngDelete (pScsiCtrl->timeoutQ); if (pScsiCtrl->requestQ != 0) (void) rngDelete (pScsiCtrl->requestQ); return (ERROR); }/********************************************************************************* scsiTargetInit - initialise a SCSI target structure** Set all per-target configurable parameters to their default values.* Initialise all the target's state variables.** RETURNS: N/A** NOMANUAL*/LOCAL void scsiTargetInit ( FAST SCSI_CTRL *pScsiCtrl, /* ptr to SCSI controller info */ UINT busId /* SCSI bus ID of target to init */ ) { FAST SCSI_TARGET *pScsiTarget = &pScsiCtrl->targetArr [busId]; /* initialise options (also see "scsiTargetOptionsSet()") */ pScsiTarget->selTimeOut = SCSI_DEF_SELECT_TIMEOUT; pScsiTarget->messages = TRUE; pScsiTarget->disconnect = TRUE; pScsiTarget->xferOffset = SCSI_SYNC_XFER_ASYNC_OFFSET; pScsiTarget->xferPeriod = SCSI_SYNC_XFER_ASYNC_PERIOD; pScsiTarget->maxOffset = SCSI_SYNC_XFER_MAX_OFFSET; pScsiTarget->minPeriod = SCSI_SYNC_XFER_MIN_PERIOD; pScsiTarget->tagType = SCSI_DEF_TAG_TYPE; pScsiTarget->maxTags = SCSI_MAX_TAGS; if (pScsiCtrl->wideXfer) pScsiTarget->xferWidth = SCSI_WIDE_XFER_SIZE_DEFAULT; else pScsiTarget->xferWidth = SCSI_WIDE_XFER_SIZE_NARROW; /* 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 setting.* xferWidth = 0 ; 8 bits wide * xferWidth = 1 ; 16 bits wide** .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; /* if messages are off, force options to SCSI-1 defaults */ if (!pScsiTarget->messages) { pScsiTarget->disconnect = FALSE; pScsiTarget->maxOffset = 0; pScsiTarget->xferWidth = SCSI_WIDE_XFER_SIZE_NARROW; } /* 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); } if (pOptions->minPeriod < 1) { 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 (requires messages) */ if (which & SCSI_SET_OPT_WIDE_PARAMS) { if (pOptions->xferWidth != SCSI_WIDE_XFER_SIZE_NARROW && pOptions->xferWidth != SCSI_WIDE_XFER_SIZE_DEFAULT) { errnoSet (S_scsiLib_ILLEGAL_PARAMETER); return (ERROR); } if (pScsiTarget->messages) { pScsiTarget->xferWidth = pOptions->xferWidth; /* re-initialise wide data xfer fsm */ scsiWideXferNegotiate (pScsiCtrl, pScsiTarget, WIDE_XFER_RESET); } else { /* if messages off, only accept NARROW */ if (pOptions->xferWidth != SCSI_WIDE_XFER_SIZE_NARROW) { errnoSet (S_scsiLib_ILLEGAL_PARAMETER); return (ERROR); } } } } } 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->xferOffset; pOptions->minPeriod = pScsiTarget->xferPeriod; pOptions->tagType = pScsiTarget->tagType; pOptions->maxTags = pScsiTarget->maxTags; pOptions->xferWidth = pScsiTarget->xferWidth; return (OK); }/********************************************************************************* scsiTargetOptionsShow - display options for specified SCSI target** This routine displays the current target options for the specified target in* the following format:* * Target Options (id <scsi bus ID>): * selection TimeOut: <timeout> nano secs* messages allowed: TRUE or FALSE* disconnect allowed: TRUE or FALSE* REQ/ACK offset: <negotiated offset> * transfer period: <negotiated period> * transfer width: 8 or 16 bits* maximum transfer rate: <peak transfer rate> MB/sec* tag type: <tag type>* maximum tags: <max tags>** RETURNS: OK, or ERROR if the bus ID is invalid.*/STATUS scsiTargetOptionsShow ( SCSI_CTRL *pScsiCtrl, /* ptr to SCSI controller info */ int devBusId /* target to interrogate */ ) { SCSI_OPTIONS options; /* buffer for returned options */ if ((devBusId < SCSI_MIN_BUS_ID) || (devBusId > SCSI_MAX_BUS_ID)) { errnoSet (S_scsiLib_ILLEGAL_BUS_ID); return (ERROR); } if (scsiTargetOptionsGet (pScsiCtrl, devBusId, &options) == ERROR) { return (ERROR); } printf("Target Options (id %d):\n", devBusId); printf(" selection TimeOut: %d nano secs\n", options.selTimeOut); printf(" messages allowed: %s\n", (options.messages ? "TRUE" : "FALSE")); printf(" disconnect allowed: %s\n", (options.disconnect ? "TRUE" : "FALSE")); printf(" REQ/ACK offset: %d\n", options.maxOffset);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -