svn commit: r188769 - in head/sys/dev/ata: . chipsets

Alexander Motin mav at FreeBSD.org
Wed Feb 18 16:32:56 PST 2009


Author: mav
Date: Thu Feb 19 00:32:55 2009
New Revision: 188769
URL: http://svn.freebsd.org/changeset/base/188769

Log:
  Quite mechanical ch_detach implementations for all atapci subdrivers.
  Some dmainit call fixes for previous commit.

Modified:
  head/sys/dev/ata/ata-dma.c
  head/sys/dev/ata/ata-pci.c
  head/sys/dev/ata/ata-pci.h
  head/sys/dev/ata/chipsets/ata-acard.c
  head/sys/dev/ata/chipsets/ata-acerlabs.c
  head/sys/dev/ata/chipsets/ata-ahci.c
  head/sys/dev/ata/chipsets/ata-highpoint.c
  head/sys/dev/ata/chipsets/ata-intel.c
  head/sys/dev/ata/chipsets/ata-jmicron.c
  head/sys/dev/ata/chipsets/ata-marvell.c
  head/sys/dev/ata/chipsets/ata-netcell.c
  head/sys/dev/ata/chipsets/ata-nvidia.c
  head/sys/dev/ata/chipsets/ata-promise.c
  head/sys/dev/ata/chipsets/ata-serverworks.c
  head/sys/dev/ata/chipsets/ata-siliconimage.c
  head/sys/dev/ata/chipsets/ata-sis.c
  head/sys/dev/ata/chipsets/ata-via.c

Modified: head/sys/dev/ata/ata-dma.c
==============================================================================
--- head/sys/dev/ata/ata-dma.c	Thu Feb 19 00:06:01 2009	(r188768)
+++ head/sys/dev/ata/ata-dma.c	Thu Feb 19 00:32:55 2009	(r188769)
@@ -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);

Modified: head/sys/dev/ata/ata-pci.c
==============================================================================
--- head/sys/dev/ata/ata-pci.c	Thu Feb 19 00:06:01 2009	(r188768)
+++ head/sys/dev/ata/ata-pci.c	Thu Feb 19 00:32:55 2009	(r188769)
@@ -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 */

Modified: head/sys/dev/ata/ata-pci.h
==============================================================================
--- head/sys/dev/ata/ata-pci.h	Thu Feb 19 00:06:01 2009	(r188768)
+++ head/sys/dev/ata/ata-pci.h	Thu Feb 19 00:32:55 2009	(r188769)
@@ -410,9 +410,11 @@ int ata_pci_release_resource(device_t de
 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;

Modified: head/sys/dev/ata/chipsets/ata-acard.c
==============================================================================
--- head/sys/dev/ata/chipsets/ata-acard.c	Thu Feb 19 00:06:01 2009	(r188768)
+++ head/sys/dev/ata/chipsets/ata-acard.c	Thu Feb 19 00:32:55 2009	(r188769)
@@ -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;

Modified: head/sys/dev/ata/chipsets/ata-acerlabs.c
==============================================================================
--- head/sys/dev/ata/chipsets/ata-acerlabs.c	Thu Feb 19 00:06:01 2009	(r188768)
+++ head/sys/dev/ata/chipsets/ata-acerlabs.c	Thu Feb 19 00:32:55 2009	(r188769)
@@ -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;

Modified: head/sys/dev/ata/chipsets/ata-ahci.c
==============================================================================
--- head/sys/dev/ata/chipsets/ata-ahci.c	Thu Feb 19 00:06:01 2009	(r188768)
+++ head/sys/dev/ata/chipsets/ata-ahci.c	Thu Feb 19 00:32:55 2009	(r188769)
@@ -62,6 +62,7 @@ static int ata_ahci_pm_write(device_t de
 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_se
     args->nsegs = nsegs;
 }
 
-void
+static void
 ata_ahci_dmainit(device_t dev)
 {
     struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));

Modified: head/sys/dev/ata/chipsets/ata-highpoint.c
==============================================================================
--- head/sys/dev/ata/chipsets/ata-highpoint.c	Thu Feb 19 00:06:01 2009	(r188768)
+++ head/sys/dev/ata/chipsets/ata-highpoint.c	Thu Feb 19 00:32:55 2009	(r188769)
@@ -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;
 }

Modified: head/sys/dev/ata/chipsets/ata-intel.c
==============================================================================
--- head/sys/dev/ata/chipsets/ata-intel.c	Thu Feb 19 00:06:01 2009	(r188768)
+++ head/sys/dev/ata/chipsets/ata-intel.c	Thu Feb 19 00:32:55 2009	(r188769)
@@ -59,6 +59,7 @@ static void ata_intel_old_setmode(device
 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 ? */

Modified: head/sys/dev/ata/chipsets/ata-jmicron.c
==============================================================================
--- head/sys/dev/ata/chipsets/ata-jmicron.c	Thu Feb 19 00:06:01 2009	(r188768)
+++ head/sys/dev/ata/chipsets/ata-jmicron.c	Thu Feb 19 00:32:55 2009	(r188769)
@@ -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

Modified: head/sys/dev/ata/chipsets/ata-marvell.c
==============================================================================
--- head/sys/dev/ata/chipsets/ata-marvell.c	Thu Feb 19 00:06:01 2009	(r188768)
+++ head/sys/dev/ata/chipsets/ata-marvell.c	Thu Feb 19 00:32:55 2009	(r188769)
@@ -56,6 +56,7 @@ static int ata_marvell_pata_chipinit(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));

Modified: head/sys/dev/ata/chipsets/ata-netcell.c
==============================================================================
--- head/sys/dev/ata/chipsets/ata-netcell.c	Thu Feb 19 00:06:01 2009	(r188768)
+++ head/sys/dev/ata/chipsets/ata-netcell.c	Thu Feb 19 00:32:55 2009	(r188769)
@@ -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;
 }

Modified: head/sys/dev/ata/chipsets/ata-nvidia.c
==============================================================================
--- head/sys/dev/ata/chipsets/ata-nvidia.c	Thu Feb 19 00:06:01 2009	(r188768)
+++ head/sys/dev/ata/chipsets/ata-nvidia.c	Thu Feb 19 00:32:55 2009	(r188769)
@@ -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 */

Modified: head/sys/dev/ata/chipsets/ata-promise.c
==============================================================================
--- head/sys/dev/ata/chipsets/ata-promise.c	Thu Feb 19 00:06:01 2009	(r188768)
+++ head/sys/dev/ata/chipsets/ata-promise.c	Thu Feb 19 00:32:55 2009	(r188769)
@@ -58,11 +58,11 @@ static int ata_promise_status(device_t d
 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)
 {

Modified: head/sys/dev/ata/chipsets/ata-serverworks.c
==============================================================================
--- head/sys/dev/ata/chipsets/ata-serverworks.c	Thu Feb 19 00:06:01 2009	(r188768)
+++ head/sys/dev/ata/chipsets/ata-serverworks.c	Thu Feb 19 00:32:55 2009	(r188769)
@@ -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)
 {

Modified: head/sys/dev/ata/chipsets/ata-siliconimage.c
==============================================================================
--- head/sys/dev/ata/chipsets/ata-siliconimage.c	Thu Feb 19 00:06:01 2009	(r188768)
+++ head/sys/dev/ata/chipsets/ata-siliconimage.c	Thu Feb 19 00:32:55 2009	(r188769)
@@ -56,10 +56,12 @@ static int ata_cmd_ch_attach(device_t de
 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));

Modified: head/sys/dev/ata/chipsets/ata-sis.c
==============================================================================
--- head/sys/dev/ata/chipsets/ata-sis.c	Thu Feb 19 00:06:01 2009	(r188768)
+++ head/sys/dev/ata/chipsets/ata-sis.c	Thu Feb 19 00:32:55 2009	(r188769)
@@ -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 */

Modified: head/sys/dev/ata/chipsets/ata-via.c
==============================================================================
--- head/sys/dev/ata/chipsets/ata-via.c	Thu Feb 19 00:06:01 2009	(r188768)
+++ head/sys/dev/ata/chipsets/ata-via.c	Thu Feb 19 00:32:55 2009	(r188769)
@@ -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)
 {


More information about the svn-src-head mailing list