diff options
Diffstat (limited to 'sys/dev/ata/ata-all.c')
-rw-r--r-- | sys/dev/ata/ata-all.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c index 8c0ea9d..f40dcc2 100644 --- a/sys/dev/ata/ata-all.c +++ b/sys/dev/ata/ata-all.c @@ -83,6 +83,7 @@ static void bswap(int8_t *, int); static void btrim(int8_t *, int); static void bpack(int8_t *, int8_t *, int); static void ata_interrupt_locked(void *data); +static void ata_periodic_poll(void *data); /* global vars */ MALLOC_DEFINE(M_ATA, "ata_generic", "ATA driver generic layer"); @@ -173,6 +174,7 @@ ata_attach(device_t dev) ch->curr[i] = ch->user[i]; } #endif + callout_init(&ch->poll_callout, 1); /* reset the controller HW, the channel and device(s) */ while (ATA_LOCKING(dev, ATA_LF_LOCK) != ch->unit) @@ -200,6 +202,8 @@ ata_attach(device_t dev) device_printf(dev, "unable to setup interrupt\n"); return error; } + if (ch->flags & ATA_PERIODIC_POLL) + callout_reset(&ch->poll_callout, hz, ata_periodic_poll, ch); #ifndef ATA_CAM /* probe and attach devices on this channel unless we are in early boot */ @@ -246,6 +250,8 @@ err2: err1: bus_release_resource(dev, SYS_RES_IRQ, rid, ch->r_irq); mtx_unlock(&ch->state_mtx); + if (ch->flags & ATA_PERIODIC_POLL) + callout_drain(&ch->poll_callout); return (error); #endif } @@ -267,6 +273,8 @@ ata_detach(device_t dev) mtx_lock(&ch->state_mtx); ch->state |= ATA_STALL_QUEUE; mtx_unlock(&ch->state_mtx); + if (ch->flags & ATA_PERIODIC_POLL) + callout_drain(&ch->poll_callout); #ifndef ATA_CAM /* detach & delete all children */ @@ -454,6 +462,8 @@ ata_suspend(device_t dev) if (!dev || !(ch = device_get_softc(dev))) return ENXIO; + if (ch->flags & ATA_PERIODIC_POLL) + callout_drain(&ch->poll_callout); #ifdef ATA_CAM mtx_lock(&ch->state_mtx); xpt_freeze_simq(ch->sim, 1); @@ -498,6 +508,8 @@ ata_resume(device_t dev) /* kick off requests on the queue */ ata_start(dev); #endif + if (ch->flags & ATA_PERIODIC_POLL) + callout_reset(&ch->poll_callout, hz, ata_periodic_poll, ch); return error; } @@ -564,6 +576,15 @@ ata_interrupt_locked(void *data) #endif } +static void +ata_periodic_poll(void *data) +{ + struct ata_channel *ch = (struct ata_channel *)data; + + callout_reset(&ch->poll_callout, hz, ata_periodic_poll, ch); + ata_interrupt(ch); +} + void ata_print_cable(device_t dev, u_int8_t *who) { |