diff options
author | mav <mav@FreeBSD.org> | 2009-02-19 00:32:55 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2009-02-19 00:32:55 +0000 |
commit | 049011f572eea1020696967e53537c23d04c613d (patch) | |
tree | d0db707a28184efa663d8a1c183d38fc63966fb2 /sys/dev/ata | |
parent | b25019649c73794eeefae1f2ac382ead9d51ebff (diff) | |
download | FreeBSD-src-049011f572eea1020696967e53537c23d04c613d.zip FreeBSD-src-049011f572eea1020696967e53537c23d04c613d.tar.gz |
Quite mechanical ch_detach implementations for all atapci subdrivers.
Some dmainit call fixes for previous commit.
Diffstat (limited to 'sys/dev/ata')
-rw-r--r-- | sys/dev/ata/ata-dma.c | 1 | ||||
-rw-r--r-- | sys/dev/ata/ata-pci.c | 22 | ||||
-rw-r--r-- | sys/dev/ata/ata-pci.h | 5 | ||||
-rw-r--r-- | sys/dev/ata/chipsets/ata-acard.c | 1 | ||||
-rw-r--r-- | sys/dev/ata/chipsets/ata-acerlabs.c | 2 | ||||
-rw-r--r-- | sys/dev/ata/chipsets/ata-ahci.c | 12 | ||||
-rw-r--r-- | sys/dev/ata/chipsets/ata-highpoint.c | 1 | ||||
-rw-r--r-- | sys/dev/ata/chipsets/ata-intel.c | 14 | ||||
-rw-r--r-- | sys/dev/ata/chipsets/ata-jmicron.c | 29 | ||||
-rw-r--r-- | sys/dev/ata/chipsets/ata-marvell.c | 11 | ||||
-rw-r--r-- | sys/dev/ata/chipsets/ata-netcell.c | 1 | ||||
-rw-r--r-- | sys/dev/ata/chipsets/ata-nvidia.c | 1 | ||||
-rw-r--r-- | sys/dev/ata/chipsets/ata-promise.c | 34 | ||||
-rw-r--r-- | sys/dev/ata/chipsets/ata-serverworks.c | 12 | ||||
-rw-r--r-- | sys/dev/ata/chipsets/ata-siliconimage.c | 26 | ||||
-rw-r--r-- | sys/dev/ata/chipsets/ata-sis.c | 1 | ||||
-rw-r--r-- | sys/dev/ata/chipsets/ata-via.c | 29 |
17 files changed, 171 insertions, 31 deletions
diff --git a/sys/dev/ata/ata-dma.c b/sys/dev/ata/ata-dma.c index f0c207b..a9a4e5b 100644 --- a/sys/dev/ata/ata-dma.c +++ b/sys/dev/ata/ata-dma.c @@ -45,7 +45,6 @@ __FBSDID("$FreeBSD$"); #include <dev/ata/ata-pci.h> /* prototypes */ -static void ata_dmafini(device_t dev); static void ata_dmasetupc_cb(void *xsc, bus_dma_segment_t *segs, int nsegs, int error); static void ata_dmaalloc(device_t dev); static void ata_dmafree(device_t dev); diff --git a/sys/dev/ata/ata-pci.c b/sys/dev/ata/ata-pci.c index d05d0b5..ebba094 100644 --- a/sys/dev/ata/ata-pci.c +++ b/sys/dev/ata/ata-pci.c @@ -100,6 +100,7 @@ ata_pci_attach(device_t dev) ctlr->channels = 1; ctlr->ichannels = -1; ctlr->ch_attach = ata_pci_ch_attach; + ctlr->ch_detach = ata_pci_ch_detach; ctlr->dev = dev; /* if needed try to enable busmastering */ @@ -382,6 +383,21 @@ ata_pci_ch_attach(device_t dev) } int +ata_pci_ch_detach(device_t dev) +{ + struct ata_channel *ch = device_get_softc(dev); + + ata_pci_dmafini(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 (0); +} + +int ata_pci_status(device_t dev) { struct ata_pci_controller *controller = @@ -477,6 +493,12 @@ ata_pci_dmainit(device_t dev) ch->dma.reset = ata_pci_dmareset; } +void +ata_pci_dmafini(device_t dev) +{ + + ata_dmafini(dev); +} static device_method_t ata_pci_methods[] = { /* device interface */ diff --git a/sys/dev/ata/ata-pci.h b/sys/dev/ata/ata-pci.h index 0ed0169..26a4798 100644 --- a/sys/dev/ata/ata-pci.h +++ b/sys/dev/ata/ata-pci.h @@ -410,9 +410,11 @@ int ata_pci_release_resource(device_t dev, device_t child, int type, int rid, st int ata_pci_setup_intr(device_t dev, device_t child, struct resource *irq, int flags, driver_filter_t *filter, driver_intr_t *function, void *argument, void **cookiep); int ata_pci_teardown_intr(device_t dev, device_t child, struct resource *irq, void *cookie); int ata_pci_ch_attach(device_t dev); +int ata_pci_ch_detach(device_t dev); int ata_pci_status(device_t dev); void ata_pci_hw(device_t dev); void ata_pci_dmainit(device_t dev); +void ata_pci_dmafini(device_t dev); char *ata_pcivendor2str(device_t dev); int ata_legacy(device_t); void ata_generic_intr(void *data); @@ -435,13 +437,14 @@ void ata_pm_identify(device_t dev); /* global prototypes from chipsets/ata-*.c */ int ata_ahci_chipinit(device_t); int ata_ahci_ch_attach(device_t dev); +int ata_ahci_ch_detach(device_t dev); void ata_ahci_reset(device_t dev); -void ata_ahci_dmainit(device_t dev); int ata_marvell_edma_chipinit(device_t); int ata_sii_chipinit(device_t); /* global prototypes ata-dma.c */ void ata_dmainit(device_t); +void ata_dmafini(device_t dev); /* externs */ extern devclass_t ata_pci_devclass; diff --git a/sys/dev/ata/chipsets/ata-acard.c b/sys/dev/ata/chipsets/ata-acard.c index 4fa7f9c..be60438 100644 --- a/sys/dev/ata/chipsets/ata-acard.c +++ b/sys/dev/ata/chipsets/ata-acard.c @@ -98,6 +98,7 @@ ata_acard_chipinit(device_t dev) return ENXIO; ctlr->ch_attach = ata_acard_ch_attach; + ctlr->ch_detach = ata_pci_ch_detach; if (ctlr->chip->cfg1 == ATP_OLD) { ctlr->setmode = ata_acard_850_setmode; ctlr->locking = ata_serialize; diff --git a/sys/dev/ata/chipsets/ata-acerlabs.c b/sys/dev/ata/chipsets/ata-acerlabs.c index 9c326c1..89e2b01 100644 --- a/sys/dev/ata/chipsets/ata-acerlabs.c +++ b/sys/dev/ata/chipsets/ata-acerlabs.c @@ -106,6 +106,7 @@ ata_ali_chipinit(device_t dev) case ALI_SATA: ctlr->channels = ctlr->chip->cfg1; ctlr->ch_attach = ata_ali_sata_ch_attach; + ctlr->ch_detach = ata_pci_ch_detach; ctlr->setmode = ata_sata_setmode; /* AHCI mode is correctly supported only on the ALi 5288. */ @@ -134,6 +135,7 @@ ata_ali_chipinit(device_t dev) "using PIO transfers above 137GB as workaround for " "48bit DMA access bug, expect reduced performance\n"); ctlr->ch_attach = ata_ali_ch_attach; + ctlr->ch_detach = ata_pci_ch_detach; ctlr->reset = ata_ali_reset; ctlr->setmode = ata_ali_setmode; break; diff --git a/sys/dev/ata/chipsets/ata-ahci.c b/sys/dev/ata/chipsets/ata-ahci.c index 1221151..f77f3d8 100644 --- a/sys/dev/ata/chipsets/ata-ahci.c +++ b/sys/dev/ata/chipsets/ata-ahci.c @@ -62,6 +62,7 @@ static int ata_ahci_pm_write(device_t dev, int port, int reg, u_int32_t result); static u_int32_t ata_ahci_softreset(device_t dev, int port); static void ata_ahci_dmasetprd(void *xsc, bus_dma_segment_t *segs, int nsegs, int error); static int ata_ahci_setup_fis(struct ata_ahci_cmd_tab *ctp, struct ata_request *equest); +static void ata_ahci_dmainit(device_t dev); /* * AHCI v1.x compliant SATA chipset support functions @@ -129,6 +130,7 @@ ata_ahci_chipinit(device_t dev) ctlr->reset = ata_ahci_reset; ctlr->ch_attach = ata_ahci_ch_attach; + ctlr->ch_detach = ata_ahci_ch_detach; ctlr->setmode = ata_sata_setmode; ctlr->suspend = ata_ahci_suspend; ctlr->resume = ata_ahci_ctlr_reset; @@ -225,6 +227,14 @@ ata_ahci_ch_attach(device_t dev) return 0; } +int +ata_ahci_ch_detach(device_t dev) +{ + + ata_dmafini(dev); + return (0); +} + static int ata_ahci_status(device_t dev) { @@ -763,7 +773,7 @@ ata_ahci_dmasetprd(void *xsc, bus_dma_segment_t *segs, int nsegs, int error) args->nsegs = nsegs; } -void +static void ata_ahci_dmainit(device_t dev) { struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); diff --git a/sys/dev/ata/chipsets/ata-highpoint.c b/sys/dev/ata/chipsets/ata-highpoint.c index d0bafbd..7ee7e92 100644 --- a/sys/dev/ata/chipsets/ata-highpoint.c +++ b/sys/dev/ata/chipsets/ata-highpoint.c @@ -135,6 +135,7 @@ ata_highpoint_chipinit(device_t dev) (pci_read_config(dev, 0x5b, 1) & 0x01) | 0x20, 1); } ctlr->ch_attach = ata_highpoint_ch_attach; + ctlr->ch_detach = ata_pci_ch_detach; ctlr->setmode = ata_highpoint_setmode; return 0; } diff --git a/sys/dev/ata/chipsets/ata-intel.c b/sys/dev/ata/chipsets/ata-intel.c index c7b18a3..b9cc6a2 100644 --- a/sys/dev/ata/chipsets/ata-intel.c +++ b/sys/dev/ata/chipsets/ata-intel.c @@ -59,6 +59,7 @@ static void ata_intel_old_setmode(device_t dev, int mode); static void ata_intel_new_setmode(device_t dev, int mode); static void ata_intel_sata_setmode(device_t dev, int mode); static int ata_intel_31244_ch_attach(device_t dev); +static int ata_intel_31244_ch_detach(device_t dev); static int ata_intel_31244_status(device_t dev); static void ata_intel_31244_tf_write(struct ata_request *request); static void ata_intel_31244_reset(device_t dev); @@ -172,6 +173,7 @@ ata_intel_chipinit(device_t dev) return ENXIO; ctlr->channels = 4; ctlr->ch_attach = ata_intel_31244_ch_attach; + ctlr->ch_detach = ata_intel_31244_ch_detach; ctlr->reset = ata_intel_31244_reset; } ctlr->setmode = ata_sata_setmode; @@ -181,6 +183,7 @@ ata_intel_chipinit(device_t dev) else if (ctlr->chip->max_dma < ATA_SA150) { ctlr->channels = ctlr->chip->cfg2; ctlr->ch_attach = ata_intel_ch_attach; + ctlr->ch_detach = ata_pci_ch_detach; ctlr->setmode = ata_intel_new_setmode; } @@ -190,6 +193,7 @@ ata_intel_chipinit(device_t dev) pci_write_config(dev, 0x92, pci_read_config(dev, 0x92, 2) | 0x0f, 2); ctlr->ch_attach = ata_intel_ch_attach; + ctlr->ch_detach = ata_pci_ch_detach; ctlr->reset = ata_intel_reset; /* @@ -403,6 +407,8 @@ ata_intel_31244_ch_attach(device_t dev) int i; int ch_offset; + ata_pci_dmainit(dev); + ch_offset = 0x200 + ch->unit * 0x200; for (i = ATA_DATA; i < ATA_MAX_RES; i++) @@ -444,6 +450,14 @@ ata_intel_31244_ch_attach(device_t dev) } static int +ata_intel_31244_ch_detach(device_t dev) +{ + + ata_pci_dmafini(dev); + return (0); +} + +static int ata_intel_31244_status(device_t dev) { /* do we have any PHY events ? */ diff --git a/sys/dev/ata/chipsets/ata-jmicron.c b/sys/dev/ata/chipsets/ata-jmicron.c index 30e334f..583ddae 100644 --- a/sys/dev/ata/chipsets/ata-jmicron.c +++ b/sys/dev/ata/chipsets/ata-jmicron.c @@ -54,11 +54,10 @@ __FBSDID("$FreeBSD$"); /* local prototypes */ static int ata_jmicron_chipinit(device_t dev); static int ata_jmicron_ch_attach(device_t dev); +static int ata_jmicron_ch_detach(device_t dev); static void ata_jmicron_reset(device_t dev); -static void ata_jmicron_dmainit(device_t dev); static void ata_jmicron_setmode(device_t dev, int mode); - /* * JMicron chipset support functions */ @@ -113,6 +112,7 @@ ata_jmicron_chipinit(device_t dev) /* otherwise we are on the PATA part */ ctlr->ch_attach = ata_pci_ch_attach; + ctlr->ch_detach = ata_pci_ch_detach; ctlr->reset = ata_generic_reset; ctlr->setmode = ata_jmicron_setmode; ctlr->channels = ctlr->chip->cfg2; @@ -126,6 +126,7 @@ ata_jmicron_chipinit(device_t dev) return error; ctlr->ch_attach = ata_jmicron_ch_attach; + ctlr->ch_detach = ata_jmicron_ch_detach; ctlr->reset = ata_jmicron_reset; ctlr->setmode = ata_jmicron_setmode; @@ -142,8 +143,6 @@ ata_jmicron_ch_attach(device_t dev) struct ata_channel *ch = device_get_softc(dev); int error; - ata_jmicron_dmainit(dev); - if (ch->unit >= ctlr->chip->cfg1) { ch->unit -= ctlr->chip->cfg1; error = ata_pci_ch_attach(dev); @@ -154,28 +153,34 @@ ata_jmicron_ch_attach(device_t dev) return error; } -static void -ata_jmicron_reset(device_t dev) +static int +ata_jmicron_ch_detach(device_t dev) { struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); struct ata_channel *ch = device_get_softc(dev); + int error; - if (ch->unit >= ctlr->chip->cfg1) - ata_generic_reset(dev); + if (ch->unit >= ctlr->chip->cfg1) { + ch->unit -= ctlr->chip->cfg1; + error = ata_pci_ch_detach(dev); + ch->unit += ctlr->chip->cfg1; + } else - ata_ahci_reset(dev); + error = ata_ahci_ch_detach(dev); + + return (error); } static void -ata_jmicron_dmainit(device_t dev) +ata_jmicron_reset(device_t dev) { struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); struct ata_channel *ch = device_get_softc(dev); if (ch->unit >= ctlr->chip->cfg1) - ata_pci_dmainit(dev); + ata_generic_reset(dev); else - ata_ahci_dmainit(dev); + ata_ahci_reset(dev); } static void diff --git a/sys/dev/ata/chipsets/ata-marvell.c b/sys/dev/ata/chipsets/ata-marvell.c index 1184a7b..24d30ed 100644 --- a/sys/dev/ata/chipsets/ata-marvell.c +++ b/sys/dev/ata/chipsets/ata-marvell.c @@ -56,6 +56,7 @@ static int ata_marvell_pata_chipinit(device_t dev); static int ata_marvell_pata_ch_attach(device_t dev); static void ata_marvell_pata_setmode(device_t dev, int mode); static int ata_marvell_edma_ch_attach(device_t dev); +static int ata_marvell_edma_ch_detach(device_t dev); static int ata_marvell_edma_status(device_t dev); static int ata_marvell_edma_begin_transaction(struct ata_request *request); static int ata_marvell_edma_end_transaction(struct ata_request *request); @@ -136,6 +137,7 @@ ata_marvell_pata_chipinit(device_t dev) return ENXIO; ctlr->ch_attach = ata_marvell_pata_ch_attach; + ctlr->ch_detach = ata_pci_ch_detach; ctlr->setmode = ata_marvell_pata_setmode; ctlr->channels = ctlr->chip->cfg1; return 0; @@ -190,6 +192,7 @@ ata_marvell_edma_chipinit(device_t dev) ATA_OUTL(ctlr->r_res1, 0x01d5c, 0x00000000); ctlr->ch_attach = ata_marvell_edma_ch_attach; + ctlr->ch_detach = ata_marvell_edma_ch_detach; ctlr->reset = ata_marvell_edma_reset; ctlr->setmode = ata_sata_setmode; ctlr->channels = ctlr->chip->cfg1; @@ -308,6 +311,14 @@ ata_marvell_edma_ch_attach(device_t dev) } static int +ata_marvell_edma_ch_detach(device_t dev) +{ + + ata_dmafini(dev); + return (0); +} + +static int ata_marvell_edma_status(device_t dev) { struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); diff --git a/sys/dev/ata/chipsets/ata-netcell.c b/sys/dev/ata/chipsets/ata-netcell.c index a87458e..8c19af8 100644 --- a/sys/dev/ata/chipsets/ata-netcell.c +++ b/sys/dev/ata/chipsets/ata-netcell.c @@ -82,6 +82,7 @@ ata_netcell_chipinit(device_t dev) return ENXIO; ctlr->ch_attach = ata_netcell_ch_attach; + ctlr->ch_detach = ata_pci_ch_detach; ctlr->setmode = ata_netcell_setmode; return 0; } diff --git a/sys/dev/ata/chipsets/ata-nvidia.c b/sys/dev/ata/chipsets/ata-nvidia.c index f8207f7..bc2e11a 100644 --- a/sys/dev/ata/chipsets/ata-nvidia.c +++ b/sys/dev/ata/chipsets/ata-nvidia.c @@ -131,6 +131,7 @@ ata_nvidia_chipinit(device_t dev) int offset = ctlr->chip->cfg1 & NV4 ? 0x0440 : 0x0010; ctlr->ch_attach = ata_nvidia_ch_attach; + ctlr->ch_detach = ata_pci_ch_detach; ctlr->reset = ata_nvidia_reset; /* enable control access */ diff --git a/sys/dev/ata/chipsets/ata-promise.c b/sys/dev/ata/chipsets/ata-promise.c index 080123d..0913df1 100644 --- a/sys/dev/ata/chipsets/ata-promise.c +++ b/sys/dev/ata/chipsets/ata-promise.c @@ -58,11 +58,11 @@ static int ata_promise_status(device_t dev); static int ata_promise_dmastart(struct ata_request *request); static int ata_promise_dmastop(struct ata_request *request); static void ata_promise_dmareset(device_t dev); -static void ata_promise_dmainit(device_t dev); static void ata_promise_setmode(device_t dev, int mode); static int ata_promise_tx2_ch_attach(device_t dev); static int ata_promise_tx2_status(device_t dev); static int ata_promise_mio_ch_attach(device_t dev); +static int ata_promise_mio_ch_detach(device_t dev); static void ata_promise_mio_intr(void *data); static int ata_promise_mio_status(device_t dev); static int ata_promise_mio_command(struct ata_request *request); @@ -232,11 +232,13 @@ ata_promise_chipinit(device_t dev) /* enable burst mode */ ATA_OUTB(ctlr->r_res1, 0x1f, ATA_INB(ctlr->r_res1, 0x1f) | 0x01); ctlr->ch_attach = ata_promise_ch_attach; + ctlr->ch_detach = ata_pci_ch_detach; ctlr->setmode = ata_promise_setmode; return 0; case PR_TX: ctlr->ch_attach = ata_promise_tx2_ch_attach; + ctlr->ch_detach = ata_pci_ch_detach; ctlr->setmode = ata_promise_setmode; return 0; @@ -283,6 +285,7 @@ ata_promise_chipinit(device_t dev) hpkt->busy = 0; device_set_ivars(dev, hpkt); ctlr->ch_attach = ata_promise_mio_ch_attach; + ctlr->ch_detach = ata_promise_mio_ch_detach; ctlr->reset = ata_promise_mio_reset; ctlr->setmode = ata_promise_setmode; ctlr->channels = 4; @@ -335,6 +338,7 @@ sataii: ATA_OUTL(ctlr->r_res2, 0x44, ATA_INL(ctlr->r_res2, 0x44) | 0x2000); ctlr->ch_attach = ata_promise_mio_ch_attach; + ctlr->ch_detach = ata_promise_mio_ch_detach; ctlr->reset = ata_promise_mio_reset; ctlr->setmode = ata_promise_mio_setmode; @@ -355,12 +359,15 @@ ata_promise_ch_attach(device_t dev) struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); struct ata_channel *ch = device_get_softc(dev); - if (ctlr->chip->cfg1 == PR_NEW) - ata_promise_dmainit(dev); - if (ata_pci_ch_attach(dev)) return ENXIO; + if (ctlr->chip->cfg1 == PR_NEW) { + ch->dma.start = ata_promise_dmastart; + ch->dma.stop = ata_promise_dmastop; + ch->dma.reset = ata_promise_dmareset; + } + ch->hw.status = ata_promise_status; return 0; } @@ -434,17 +441,6 @@ ata_promise_dmareset(device_t dev) } static void -ata_promise_dmainit(device_t dev) -{ - struct ata_channel *ch = device_get_softc(dev); - - ata_dmainit(dev); - ch->dma.start = ata_promise_dmastart; - ch->dma.stop = ata_promise_dmastop; - ch->dma.reset = ata_promise_dmareset; -} - -static void ata_promise_setmode(device_t dev, int mode) { device_t gparent = GRANDPARENT(dev); @@ -588,6 +584,14 @@ ata_promise_mio_ch_attach(device_t dev) return 0; } +static int +ata_promise_mio_ch_detach(device_t dev) +{ + + ata_dmafini(dev); + return (0); +} + static void ata_promise_mio_intr(void *data) { diff --git a/sys/dev/ata/chipsets/ata-serverworks.c b/sys/dev/ata/chipsets/ata-serverworks.c index 2bd426d..366f9a1 100644 --- a/sys/dev/ata/chipsets/ata-serverworks.c +++ b/sys/dev/ata/chipsets/ata-serverworks.c @@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$"); /* local prototypes */ static int ata_serverworks_chipinit(device_t dev); static int ata_serverworks_ch_attach(device_t dev); +static int ata_serverworks_ch_detach(device_t dev); static void ata_serverworks_tf_read(struct ata_request *request); static void ata_serverworks_tf_write(struct ata_request *request); static void ata_serverworks_setmode(device_t dev, int mode); @@ -114,6 +115,7 @@ ata_serverworks_chipinit(device_t dev) ctlr->channels = ctlr->chip->cfg2; ctlr->ch_attach = ata_serverworks_ch_attach; + ctlr->ch_detach = ata_serverworks_ch_detach; ctlr->setmode = ata_sata_setmode; return 0; } @@ -151,6 +153,8 @@ ata_serverworks_ch_attach(device_t dev) int ch_offset; int i; + ata_pci_dmainit(dev); + ch_offset = ch->unit * 0x100; for (i = ATA_DATA; i < ATA_MAX_RES; i++) @@ -189,6 +193,14 @@ ata_serverworks_ch_attach(device_t dev) return 0; } +static int +ata_serverworks_ch_detach(device_t dev) +{ + + ata_pci_dmafini(dev); + return (0); +} + static void ata_serverworks_tf_read(struct ata_request *request) { diff --git a/sys/dev/ata/chipsets/ata-siliconimage.c b/sys/dev/ata/chipsets/ata-siliconimage.c index c13af95..5fe08be 100644 --- a/sys/dev/ata/chipsets/ata-siliconimage.c +++ b/sys/dev/ata/chipsets/ata-siliconimage.c @@ -56,10 +56,12 @@ static int ata_cmd_ch_attach(device_t dev); static int ata_cmd_status(device_t dev); static void ata_cmd_setmode(device_t dev, int mode); static int ata_sii_ch_attach(device_t dev); +static int ata_sii_ch_detach(device_t dev); static int ata_sii_status(device_t dev); static void ata_sii_reset(device_t dev); static void ata_sii_setmode(device_t dev, int mode); static int ata_siiprb_ch_attach(device_t dev); +static int ata_siiprb_ch_detach(device_t dev); static int ata_siiprb_status(device_t dev); static int ata_siiprb_begin_transaction(struct ata_request *request); static int ata_siiprb_end_transaction(struct ata_request *request); @@ -139,6 +141,7 @@ ata_sii_chipinit(device_t dev) return ENXIO; } ctlr->ch_attach = ata_siiprb_ch_attach; + ctlr->ch_detach = ata_siiprb_ch_detach; ctlr->reset = ata_siiprb_reset; ctlr->setmode = ata_sata_setmode; ctlr->channels = (ctlr->chip->cfg2 == SII_4CH) ? 4 : 2; @@ -185,8 +188,10 @@ ata_sii_chipinit(device_t dev) /* enable PCI interrupt as BIOS might not */ pci_write_config(dev, 0x8a, (pci_read_config(dev, 0x8a, 1) & 0x3f), 1); - if (ctlr->r_res2) + if (ctlr->r_res2) { ctlr->ch_attach = ata_sii_ch_attach; + ctlr->ch_detach = ata_sii_ch_detach; + } if (ctlr->chip->max_dma >= ATA_SA150) { ctlr->reset = ata_sii_reset; @@ -206,6 +211,7 @@ ata_sii_chipinit(device_t dev) pci_write_config(dev, 0x71, 0x01, 1); ctlr->ch_attach = ata_cmd_ch_attach; + ctlr->ch_detach = ata_pci_ch_detach; ctlr->setmode = ata_cmd_setmode; break; } @@ -306,6 +312,8 @@ ata_sii_ch_attach(device_t dev) int unit01 = (ch->unit & 1), unit10 = (ch->unit & 2); int i; + ata_pci_dmainit(dev); + for (i = ATA_DATA; i <= ATA_COMMAND; i++) { ch->r_io[i].res = ctlr->r_res2; ch->r_io[i].offset = 0x80 + i + (unit01 << 6) + (unit10 << 8); @@ -347,6 +355,14 @@ ata_sii_ch_attach(device_t dev) } static int +ata_sii_ch_detach(device_t dev) +{ + + ata_pci_dmafini(dev); + return (0); +} + +static int ata_sii_status(device_t dev) { struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); @@ -496,6 +512,14 @@ ata_siiprb_ch_attach(device_t dev) } static int +ata_siiprb_ch_detach(device_t dev) +{ + + ata_dmafini(dev); + return 0; +} + +static int ata_siiprb_status(device_t dev) { struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); diff --git a/sys/dev/ata/chipsets/ata-sis.c b/sys/dev/ata/chipsets/ata-sis.c index de84c05..b3c86f5 100644 --- a/sys/dev/ata/chipsets/ata-sis.c +++ b/sys/dev/ata/chipsets/ata-sis.c @@ -187,6 +187,7 @@ ata_sis_chipinit(device_t dev) if ((ctlr->r_res2 = bus_alloc_resource_any(dev, ctlr->r_type2, &ctlr->r_rid2, RF_ACTIVE))) { ctlr->ch_attach = ata_sis_ch_attach; + ctlr->ch_detach = ata_pci_ch_detach; ctlr->reset = ata_sis_reset; /* enable PCI interrupt */ diff --git a/sys/dev/ata/chipsets/ata-via.c b/sys/dev/ata/chipsets/ata-via.c index 29146ef..632f17d 100644 --- a/sys/dev/ata/chipsets/ata-via.c +++ b/sys/dev/ata/chipsets/ata-via.c @@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$"); /* local prototypes */ static int ata_via_chipinit(device_t dev); static int ata_via_ch_attach(device_t dev); +static int ata_via_ch_detach(device_t dev); static void ata_via_reset(device_t dev); static void ata_via_old_setmode(device_t dev, int mode); static void ata_via_southbridge_fixup(device_t dev); @@ -140,6 +141,7 @@ ata_via_chipinit(device_t dev) if ((ctlr->r_res2 = bus_alloc_resource_any(dev, ctlr->r_type2, &ctlr->r_rid2, RF_ACTIVE))) { ctlr->ch_attach = ata_via_ch_attach; + ctlr->ch_detach = ata_via_ch_detach; ctlr->reset = ata_via_reset; /* enable PCI interrupt */ @@ -194,6 +196,8 @@ ata_via_ch_attach(device_t dev) struct resource *r_io; int i, rid; + ata_pci_dmainit(dev); + rid = PCIR_BAR(ch->unit); if (!(r_io = bus_alloc_resource_any(device_get_parent(dev), SYS_RES_IOPORT, @@ -235,6 +239,31 @@ ata_via_ch_attach(device_t dev) return 0; } +static int +ata_via_ch_detach(device_t dev) +{ + struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); + struct ata_channel *ch = device_get_softc(dev); + + /* newer SATA chips has resources in one BAR for each channel */ + if (ctlr->chip->cfg2 & VIABAR) { + int rid; + + rid = PCIR_BAR(ch->unit); + bus_release_resource(device_get_parent(dev), + SYS_RES_IOPORT, rid, ch->r_io[ATA_CONTROL].res); + + ata_pci_dmafini(dev); + } + else { + /* setup the usual register normal pci style */ + if (ata_pci_ch_detach(dev)) + return ENXIO; + } + + return 0; +} + static void ata_via_reset(device_t dev) { |