FreeBSD/sys/dev/mps/mps.c
/*
 * This is the routine to enqueue commands synchronously.  An error of
 * EINPROGRESS from mps_map_command() is ignored since the command will
 * be executed and enqueued automatically.  Other errors come from msleep().
 */
This is the routine to enqueue commands synchronously.  An error of
EINPROGRESS from mps_map_command() is ignored since the command will
be executed and enqueued automatically.  Other errors come from msleep().
This is the routine to enqueue commands synchronously . An error of EINPROGRESS from mps_map_command () is ignored since the command will be executed and enqueued automatically . Other errors come from msleep () .
int
mps_wait_command(struct mps_softc *sc, struct mps_command *cm, int timeout,
    int sleep_flag)
{
	int error, rc;
	struct timeval cur_time, start_time;
	if (sc->mps_flags & MPS_FLAGS_DIAGRESET) 
		return  EBUSY;
	cm->cm_complete = NULL;
	cm->cm_flags |= MPS_CM_FLAGS_POLLED;
	error = mps_map_command(sc, cm);
	if ((error != 0) && (error != EINPROGRESS))
		return (error);
	if (curthread->td_no_sleeping != 0)
		sleep_flag = NO_SLEEP;
	getmicrotime(&start_time);
	if (mtx_owned(&sc->mps_mtx) && sleep_flag == CAN_SLEEP) {
		cm->cm_flags |= MPS_CM_FLAGS_WAKEUP;
		error = msleep(cm, &sc->mps_mtx, 0, "mpswait", timeout*hz);
	} else {
		while ((cm->cm_flags & MPS_CM_FLAGS_COMPLETE) == 0) {
			mps_intr_locked(sc);
			if (sleep_flag == CAN_SLEEP)
				pause("mpswait", hz/20);
			else
				DELAY(50000);
			getmicrotime(&cur_time);
			if ((cur_time.tv_sec - start_time.tv_sec) > timeout) {
				error = EWOULDBLOCK;
				break;
			}
		}
	}
	if (error == EWOULDBLOCK) {
		mps_dprint(sc, MPS_FAULT, "Calling Reinit from %s\n", __func__);
		rc = mps_reinit(sc);
		mps_dprint(sc, MPS_FAULT, "Reinit %s\n", (rc == 0) ? "success" :
		    "failed");
		error = ETIMEDOUT;
	}
	return (error);
}
int mps_wait_command ( struct mps_softc * sc , struct mps_command * cm , int timeout , int sleep_flag ) { int error , rc ; struct timeval cur_time , start_time ; if ( sc -> mps_flags & MPS_FLAGS_DIAGRESET ) return EBUSY ; cm -> cm_complete = NULL ; cm -> cm_flags |= MPS_CM_FLAGS_POLLED ; error = mps_map_command ( sc , cm ) ; if ( ( error != 0 ) && ( error != EINPROGRESS ) ) return ( error ) ; if ( curthread -> td_no_sleeping != 0 ) sleep_flag = NO_SLEEP ; getmicrotime ( & start_time ) ; if ( mtx_owned ( & sc -> mps_mtx ) && sleep_flag == CAN_SLEEP ) { cm -> cm_flags |= MPS_CM_FLAGS_WAKEUP ; error = msleep ( cm , & sc -> mps_mtx , 0 , " " , timeout * hz ) ; } else { while ( ( cm -> cm_flags & MPS_CM_FLAGS_COMPLETE ) == 0 ) { mps_intr_locked ( sc ) ; if ( sleep_flag == CAN_SLEEP ) pause ( " " , hz / 20 ) ; else DELAY ( 50000 ) ; getmicrotime ( & cur_time ) ; if ( ( cur_time . tv_sec - start_time . tv_sec ) > timeout ) { error = EWOULDBLOCK ; break ; } } } if ( error == EWOULDBLOCK ) { mps_dprint ( sc , MPS_FAULT , " \n " , __func__ ) ; rc = mps_reinit ( sc ) ; mps_dprint ( sc , MPS_FAULT , " \n " , ( rc == 0 ) ? " " : " " ) ; error = ETIMEDOUT ; } return ( error ) ; }
This is the routine to enqueue commands synchronously.
This is the routine to enqueue commands synchronously .
/*
	 * Check for context and wait for 50 mSec at a time until time has
	 * expired or the command has finished.  If msleep can't be used, need
	 * to poll.
	 */