summaryrefslogtreecommitdiffstats
path: root/sys/dev/ata/ata-all.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/ata/ata-all.c')
-rw-r--r--sys/dev/ata/ata-all.c21
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)
{
OpenPOWER on IntegriCloud