Exemple #1
0
/* Wait for transfer to complete, optionally check RXAK. */
static int
wait_for_xfer(struct i2c_softc *sc, int checkack)
{
	int retry, sr;

	/*
	 * Sleep for about the time it takes to transfer a byte (with precision
	 * set to tolerate 5% oversleep).  We calculate the approximate byte
	 * transfer time when we set the bus speed divisor.  Slaves are allowed
	 * to do clock-stretching so the actual transfer time can be larger, but
	 * this gets the bulk of the waiting out of the way without tying up the
	 * processor the whole time.
	 */
	pause_sbt("imxi2c", sc->byte_time_sbt, sc->byte_time_sbt / 20, 0);

	retry = 10000;
	while (retry --) {
		sr = i2c_read_reg(sc, I2C_STATUS_REG);
		if (sr & I2CSR_MIF) {
                        if (sr & I2CSR_MAL) 
				return (IIC_EBUSERR);
			else if (checkack && (sr & I2CSR_RXAK))
				return (IIC_ENOACK);
			else
				return (IIC_NOERR);
		}
		DELAY(1);
	}
	return (IIC_ETIMEOUT);
}
Exemple #2
0
int
vmbus_msghc_exec_noresult(struct vmbus_msghc *mh)
{
	sbintime_t time = SBT_1MS;
	int i;

	/*
	 * Save the input parameter so that we could restore the input
	 * parameter if the Hypercall failed.
	 *
	 * XXX
	 * Is this really necessary?!  i.e. Will the Hypercall ever
	 * overwrite the input parameter?
	 */
	memcpy(&mh->mh_inprm_save, mh->mh_inprm, HYPERCALL_POSTMSGIN_SIZE);

	/*
	 * In order to cope with transient failures, e.g. insufficient
	 * resources on host side, we retry the post message Hypercall
	 * several times.  20 retries seem sufficient.
	 */
#define HC_RETRY_MAX	20

	for (i = 0; i < HC_RETRY_MAX; ++i) {
		uint64_t status;

		status = hypercall_post_message(mh->mh_inprm_dma.hv_paddr);
		if (status == HYPERCALL_STATUS_SUCCESS)
			return 0;

		pause_sbt("hcpmsg", time, 0, C_HARDCLOCK);
		if (time < SBT_1S * 2)
			time *= 2;

		/* Restore input parameter and try again */
		memcpy(mh->mh_inprm, &mh->mh_inprm_save,
		    HYPERCALL_POSTMSGIN_SIZE);
	}

#undef HC_RETRY_MAX

	return EIO;
}