summaryrefslogtreecommitdiffstats
path: root/sys/dev/ata
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2009-02-19 00:32:55 +0000
committermav <mav@FreeBSD.org>2009-02-19 00:32:55 +0000
commit049011f572eea1020696967e53537c23d04c613d (patch)
treed0db707a28184efa663d8a1c183d38fc63966fb2 /sys/dev/ata
parentb25019649c73794eeefae1f2ac382ead9d51ebff (diff)
downloadFreeBSD-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.c1
-rw-r--r--sys/dev/ata/ata-pci.c22
-rw-r--r--sys/dev/ata/ata-pci.h5
-rw-r--r--sys/dev/ata/chipsets/ata-acard.c1
-rw-r--r--sys/dev/ata/chipsets/ata-acerlabs.c2
-rw-r--r--sys/dev/ata/chipsets/ata-ahci.c12
-rw-r--r--sys/dev/ata/chipsets/ata-highpoint.c1
-rw-r--r--sys/dev/ata/chipsets/ata-intel.c14
-rw-r--r--sys/dev/ata/chipsets/ata-jmicron.c29
-rw-r--r--sys/dev/ata/chipsets/ata-marvell.c11
-rw-r--r--sys/dev/ata/chipsets/ata-netcell.c1
-rw-r--r--sys/dev/ata/chipsets/ata-nvidia.c1
-rw-r--r--sys/dev/ata/chipsets/ata-promise.c34
-rw-r--r--sys/dev/ata/chipsets/ata-serverworks.c12
-rw-r--r--sys/dev/ata/chipsets/ata-siliconimage.c26
-rw-r--r--sys/dev/ata/chipsets/ata-sis.c1
-rw-r--r--sys/dev/ata/chipsets/ata-via.c29
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)
{
OpenPOWER on IntegriCloud