Module Name:    src
Committed By:   msaitoh
Date:           Sun Mar  7 07:09:00 UTC 2010

Modified Files:
        src/sys/dev/pci: if_wm.c

Log Message:
Add the detach code.


To generate a diff of this commit:
cvs rdiff -u -r1.200 -r1.201 src/sys/dev/pci/if_wm.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/pci/if_wm.c
diff -u src/sys/dev/pci/if_wm.c:1.200 src/sys/dev/pci/if_wm.c:1.201
--- src/sys/dev/pci/if_wm.c:1.200	Thu Feb 25 15:07:06 2010
+++ src/sys/dev/pci/if_wm.c	Sun Mar  7 07:09:00 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_wm.c,v 1.200 2010/02/25 15:07:06 msaitoh Exp $	*/
+/*	$NetBSD: if_wm.c,v 1.201 2010/03/07 07:09:00 msaitoh Exp $	*/
 
 /*
  * Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc.
@@ -76,7 +76,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.200 2010/02/25 15:07:06 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.201 2010/03/07 07:09:00 msaitoh Exp $");
 
 #include "rnd.h"
 
@@ -245,13 +245,12 @@
 	device_t sc_dev;		/* generic device information */
 	bus_space_tag_t sc_st;		/* bus space tag */
 	bus_space_handle_t sc_sh;	/* bus space handle */
+	bus_space_handle_t sc_ss;	/* bus space size */
 	bus_space_tag_t sc_iot;		/* I/O space tag */
 	bus_space_handle_t sc_ioh;	/* I/O space handle */
 	bus_space_tag_t sc_flasht;	/* flash registers space tag */
 	bus_space_handle_t sc_flashh;	/* flash registers space handle */
 	bus_dma_tag_t sc_dmat;		/* bus DMA tag */
-	bus_dmamap_t sc_cddmamap;	/* control data DMA map */
-#define	sc_cddma	sc_cddmamap->dm_segs[0].ds_addr
 
 	struct ethercom sc_ethercom;	/* ethernet common data */
 	struct mii_data sc_mii;		/* MII/media information */
@@ -288,8 +287,13 @@
 	/*
 	 * Control data structures.
 	 */
-	int			sc_ntxdesc;	/* must be a power of two */
+	int sc_ntxdesc;			/* must be a power of two */
 	struct wm_control_data_82544 *sc_control_data;
+	bus_dmamap_t sc_cddmamap;	/* control data DMA map */
+	bus_dma_segment_t sc_cd_seg;	/* control data segment */
+	int sc_cd_rseg;			/* real number of control segment */
+	size_t sc_cd_size;		/* control data size */
+#define	sc_cddma	sc_cddmamap->dm_segs[0].ds_addr
 #define	sc_txdescs	sc_control_data->wcd_txdescs
 #define	sc_rxdescs	sc_control_data->wcd_rxdescs
 
@@ -544,6 +548,7 @@
 static void	wm_set_spiaddrbits(struct wm_softc *);
 static int	wm_match(device_t, cfdata_t, void *);
 static void	wm_attach(device_t, device_t, void *);
+static int	wm_detach(device_t, int);
 static int	wm_is_onboard_nvm_eeprom(struct wm_softc *);
 static void	wm_get_auto_rd_done(struct wm_softc *);
 static void	wm_lan_init_done(struct wm_softc *);
@@ -577,8 +582,8 @@
 static void	wm_set_pcie_completion_timeout(struct wm_softc *);
 static void	wm_reset_init_script_82575(struct wm_softc *);
 
-CFATTACH_DECL_NEW(wm, sizeof(struct wm_softc),
-    wm_match, wm_attach, NULL, NULL);
+CFATTACH_DECL3_NEW(wm, sizeof(struct wm_softc),
+    wm_match, wm_attach, wm_detach, NULL, NULL, NULL, DVF_DETACH_SHUTDOWN);
 
 /*
  * Devices supported by this driver.
@@ -1060,14 +1065,13 @@
 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
 	pci_chipset_tag_t pc = pa->pa_pc;
 	pci_intr_handle_t ih;
-	size_t cdata_size;
 	const char *intrstr = NULL;
 	const char *eetype, *xname;
 	bus_space_tag_t memt;
 	bus_space_handle_t memh;
-	bus_dma_segment_t seg;
+	bus_size_t memsize;
 	int memh_valid;
-	int i, rseg, error;
+	int i, error;
 	const struct wm_product *wmp;
 	prop_data_t ea;
 	prop_number_t pn;
@@ -1125,7 +1129,7 @@
 	case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
 	case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
 		memh_valid = (pci_mapreg_map(pa, WM_PCI_MMBA,
-		    memtype, 0, &memt, &memh, NULL, NULL) == 0);
+		    memtype, 0, &memt, &memh, NULL, &memsize) == 0);
 		break;
 	default:
 		memh_valid = 0;
@@ -1135,6 +1139,7 @@
 	if (memh_valid) {
 		sc->sc_st = memt;
 		sc->sc_sh = memh;
+		sc->sc_ss = memsize;
 	} else {
 		aprint_error_dev(sc->sc_dev,
 		    "unable to map device registers\n");
@@ -1344,26 +1349,28 @@
 	 */
 	WM_NTXDESC(sc) = sc->sc_type < WM_T_82544 ?
 	    WM_NTXDESC_82542 : WM_NTXDESC_82544;
-	cdata_size = sc->sc_type < WM_T_82544 ?
+	sc->sc_cd_size = sc->sc_type < WM_T_82544 ?
 	    sizeof(struct wm_control_data_82542) :
 	    sizeof(struct wm_control_data_82544);
-	if ((error = bus_dmamem_alloc(sc->sc_dmat, cdata_size, PAGE_SIZE,
-		    (bus_size_t) 0x100000000ULL, &seg, 1, &rseg, 0)) != 0) {
+	if ((error = bus_dmamem_alloc(sc->sc_dmat, sc->sc_cd_size, PAGE_SIZE,
+		    (bus_size_t) 0x100000000ULL, &sc->sc_cd_seg, 1,
+		    &sc->sc_cd_rseg, 0)) != 0) {
 		aprint_error_dev(sc->sc_dev,
 		    "unable to allocate control data, error = %d\n",
 		    error);
 		goto fail_0;
 	}
 
-	if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, cdata_size,
+	if ((error = bus_dmamem_map(sc->sc_dmat, &sc->sc_cd_seg,
+		    sc->sc_cd_rseg, sc->sc_cd_size,
 		    (void **)&sc->sc_control_data, BUS_DMA_COHERENT)) != 0) {
 		aprint_error_dev(sc->sc_dev,
 		    "unable to map control data, error = %d\n", error);
 		goto fail_1;
 	}
 
-	if ((error = bus_dmamap_create(sc->sc_dmat, cdata_size, 1, cdata_size,
-		    0, 0, &sc->sc_cddmamap)) != 0) {
+	if ((error = bus_dmamap_create(sc->sc_dmat, sc->sc_cd_size, 1,
+		    sc->sc_cd_size, 0, 0, &sc->sc_cddmamap)) != 0) {
 		aprint_error_dev(sc->sc_dev,
 		    "unable to create control data DMA map, error = %d\n",
 		    error);
@@ -1371,7 +1378,7 @@
 	}
 
 	if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_cddmamap,
-		    sc->sc_control_data, cdata_size, NULL, 0)) != 0) {
+		    sc->sc_control_data, sc->sc_cd_size, NULL, 0)) != 0) {
 		aprint_error_dev(sc->sc_dev,
 		    "unable to load control data DMA map, error = %d\n",
 		    error);
@@ -1947,13 +1954,80 @@
 	bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap);
  fail_2:
 	bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_control_data,
-	    cdata_size);
+	    sc->sc_cd_size);
  fail_1:
-	bus_dmamem_free(sc->sc_dmat, &seg, rseg);
+	bus_dmamem_free(sc->sc_dmat, &sc->sc_cd_seg, sc->sc_cd_rseg);
  fail_0:
 	return;
 }
 
+static int
+wm_detach(device_t self, int flags __unused)
+{
+	struct wm_softc *sc = device_private(self);
+	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
+	int i, s;
+
+	s = splnet();
+	/* Stop the interface. Callouts are stopped in it. */
+	wm_stop(ifp, 1);
+	splx(s);
+
+	pmf_device_deregister(self);
+
+	/* Tell the firmware about the release */
+#if 0
+	wm_release_manageability(sc);
+#endif
+
+	mii_detach(&sc->sc_mii, MII_PHY_ANY, MII_OFFSET_ANY);
+
+	/* Delete all remaining media. */
+	ifmedia_delete_instance(&sc->sc_mii.mii_media, IFM_INST_ANY);
+
+	ether_ifdetach(ifp);
+	if_detach(ifp);
+
+
+	/* Unload RX dmamaps and free mbufs */ 
+	wm_rxdrain(sc);
+
+	/* Free dmamap. It's the same as the end of the wm_attach() function */
+	for (i = 0; i < WM_NRXDESC; i++) {
+		if (sc->sc_rxsoft[i].rxs_dmamap != NULL)
+			bus_dmamap_destroy(sc->sc_dmat,
+			    sc->sc_rxsoft[i].rxs_dmamap);
+	}
+	for (i = 0; i < WM_TXQUEUELEN(sc); i++) {
+		if (sc->sc_txsoft[i].txs_dmamap != NULL)
+			bus_dmamap_destroy(sc->sc_dmat,
+			    sc->sc_txsoft[i].txs_dmamap);
+	}
+	bus_dmamap_unload(sc->sc_dmat, sc->sc_cddmamap);
+	bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap);
+	bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_control_data,
+	    sc->sc_cd_size);
+	bus_dmamem_free(sc->sc_dmat, &sc->sc_cd_seg, sc->sc_cd_rseg);
+
+	/* Disestablish the interrupt handler */
+	if (sc->sc_ih != NULL) {
+		pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
+		sc->sc_ih = NULL;
+	}
+
+	/* Unmap the register */
+	if (sc->sc_ss) {
+		bus_space_unmap(sc->sc_st, sc->sc_sh, sc->sc_ss);
+		sc->sc_ss = 0;
+	}
+
+#if 0
+	wm_release_hw_control(sc);
+#endif
+
+	return 0;
+}
+
 /*
  * wm_tx_offload:
  *

Reply via email to