summaryrefslogtreecommitdiffstats
path: root/sys/dev/ata
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2009-02-18 20:42:42 +0000
committermav <mav@FreeBSD.org>2009-02-18 20:42:42 +0000
commit06c33a48b84173fe2b0b5f18a3505bf0f0d9ec04 (patch)
tree2575c45f67e2f44475a4b1cb181830d8c4bd3eb0 /sys/dev/ata
parentad4207874a036d6fc4159706062117d0b9509ae5 (diff)
downloadFreeBSD-src-06c33a48b84173fe2b0b5f18a3505bf0f0d9ec04.zip
FreeBSD-src-06c33a48b84173fe2b0b5f18a3505bf0f0d9ec04.tar.gz
Implement proper attach/detach routines for ISA driver.
Diffstat (limited to 'sys/dev/ata')
-rw-r--r--sys/dev/ata/ata-isa.c60
1 files changed, 55 insertions, 5 deletions
diff --git a/sys/dev/ata/ata-isa.c b/sys/dev/ata/ata-isa.c
index 3b7d86d..bad2c4e 100644
--- a/sys/dev/ata/ata-isa.c
+++ b/sys/dev/ata/ata-isa.c
@@ -60,15 +60,49 @@ static struct isa_pnp_id ata_ids[] = {
static int
ata_isa_probe(device_t dev)
{
- struct ata_channel *ch = device_get_softc(dev);
struct resource *io = NULL, *ctlio = NULL;
u_long tmp;
- int i, rid;
+ int rid;
/* check isapnp ids */
if (ISA_PNP_PROBE(device_get_parent(dev), dev, ata_ids) == ENXIO)
return ENXIO;
-
+
+ /* allocate the io port range */
+ rid = ATA_IOADDR_RID;
+ if (!(io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0,
+ ATA_IOSIZE, RF_ACTIVE)))
+ return ENXIO;
+
+ /* set the altport range */
+ if (bus_get_resource(dev, SYS_RES_IOPORT, ATA_CTLADDR_RID, &tmp, &tmp)) {
+ bus_set_resource(dev, SYS_RES_IOPORT, ATA_CTLADDR_RID,
+ rman_get_start(io) + ATA_CTLOFFSET, ATA_CTLIOSIZE);
+ }
+
+ /* allocate the altport range */
+ rid = ATA_CTLADDR_RID;
+ if (!(ctlio = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0,
+ ATA_CTLIOSIZE, RF_ACTIVE))) {
+ bus_release_resource(dev, SYS_RES_IOPORT, ATA_IOADDR_RID, io);
+ return ENXIO;
+ }
+
+ /* Release resources to reallocate on attach. */
+ bus_release_resource(dev, SYS_RES_IOPORT, ATA_CTLADDR_RID, ctlio);
+ bus_release_resource(dev, SYS_RES_IOPORT, ATA_IOADDR_RID, io);
+
+ return (ata_probe(dev));
+}
+
+static int
+ata_isa_attach(device_t dev)
+{
+ struct ata_channel *ch = device_get_softc(dev);
+ struct resource *io = NULL, *ctlio = NULL;
+ u_long tmp;
+ int i, rid;
+
/* allocate the io port range */
rid = ATA_IOADDR_RID;
if (!(io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0,
@@ -103,13 +137,29 @@ ata_isa_probe(device_t dev)
ch->unit = 0;
ch->flags |= ATA_USE_16BIT;
ata_generic_hw(dev);
- return ata_probe(dev);
+ return ata_attach(dev);
+}
+
+static int
+ata_isa_detach(device_t dev)
+{
+ struct ata_channel *ch = device_get_softc(dev);
+ int error;
+
+ error = ata_detach(dev);
+
+ bus_release_resource(dev, SYS_RES_IOPORT, ATA_CTLADDR_RID,
+ ch->r_io[ATA_CONTROL].res);
+ bus_release_resource(dev, SYS_RES_IOPORT, ATA_IOADDR_RID,
+ ch->r_io[ATA_IDX_ADDR].res);
+ return (error);
}
static device_method_t ata_isa_methods[] = {
/* device interface */
DEVMETHOD(device_probe, ata_isa_probe),
- DEVMETHOD(device_attach, ata_attach),
+ DEVMETHOD(device_attach, ata_isa_attach),
+ DEVMETHOD(device_detach, ata_isa_detach),
DEVMETHOD(device_suspend, ata_suspend),
DEVMETHOD(device_resume, ata_resume),
OpenPOWER on IntegriCloud