Пример #1
0
int
wdactivate(struct device *self, int act)
{
	struct wd_softc *wd = (void *)self;
	int rv = 0;

	switch (act) {
	case DVACT_SUSPEND:
		break;
	case DVACT_POWERDOWN:
		wd_flushcache(wd, AT_POLL);
		if (boothowto & RB_POWERDOWN)
			wd_standby(wd, AT_POLL);
		break;
	case DVACT_RESUME:
		/*
		 * Do two resets separated by a small delay. The
		 * first wakes the controller, the second resets
		 * the channel.
		 */
		wdc_disable_intr(wd->drvp->chnl_softc);
		wdc_reset_channel(wd->drvp, 1);
		delay(10000);
		wdc_reset_channel(wd->drvp, 0);
		wdc_enable_intr(wd->drvp->chnl_softc);
		wd_get_params(wd, at_poll, &wd->sc_params);
		break;
	}
	return (rv);
}
Пример #2
0
int
atapiscsi_activate(struct device *self, int act)
{
	struct atapiscsi_softc *as = (void *)self;
 	struct channel_softc *chp = as->chp;
	struct ata_drive_datas *drvp = &chp->ch_drive[as->drive];

	switch (act) {
	case DVACT_SUSPEND:
		break;
	case DVACT_RESUME:
		/*
		 * Do two resets separated by a small delay. The
		 * first wakes the controller, the second resets
		 * the channel
		 */
		wdc_disable_intr(chp);
		wdc_reset_channel(drvp, 1);
		delay(10000);
		wdc_reset_channel(drvp, 0);
		wdc_enable_intr(chp);
		break;
	}
	return (0);
}
Пример #3
0
void
wdc_atapi_the_machine(struct channel_softc *chp, struct wdc_xfer *xfer,
    enum atapi_context ctxt)
{
	int idx = 0;
	extern int ticks;
	int timeout_delay = hz / 10;

	if (xfer->c_flags & C_POLL) {
		wdc_disable_intr(chp);

		if (ctxt != ctxt_process) {
			if (ctxt == ctxt_interrupt)
				xfer->endticks = 1;

			return;
		}

		wdc_atapi_the_poll_machine(chp, xfer);
		return;
	}

	/* Don't go through more than 50 state machine steps
	   before yielding. This tries to limit the amount of time
	   spent at high SPL */
	for (idx = 0; idx < 50; idx++) {
		struct atapi_return_args retargs = ARGS_INIT;

		(xfer->next)(chp, xfer,
		    xfer->endticks && (ticks - xfer->endticks >= 0),
		    &retargs);

		if (retargs.timeout != -1)
			/*
			 * Add 1 tick to compensate for the fact that we
			 * can be just microseconds before the tick changes.
			 */
			xfer->endticks =
			    max((retargs.timeout * hz) / 1000, 1) + 1 + ticks;

		if (xfer->next == NULL) {
			if (xfer->c_flags & C_POLL_MACHINE)
				timeout_del(&xfer->atapi_poll_to);

			wdc_free_xfer(chp, xfer);
			wdcstart(chp);

			return;
		}

		if (retargs.expect_irq) {
			int timeout_period;
			chp->ch_flags |= WDCF_IRQ_WAIT;
			timeout_period =  xfer->endticks - ticks;
			if (timeout_period < 1)
				timeout_period = 1;
			timeout_add(&chp->ch_timo, timeout_period);
			return;
		}

		if (retargs.delay != 0) {
			timeout_delay = max(retargs.delay * hz / 1000, 1);
			break;
		}

		DELAY(1);
	}

	timeout_add(&xfer->atapi_poll_to, timeout_delay);
	xfer->c_flags |= C_POLL_MACHINE;

	return;
}