Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci Add the detach code.
details: https://anonhg.NetBSD.org/src/rev/d830de005d23
branches: trunk
changeset: 752791:d830de005d23
user: msaitoh <msaitoh%NetBSD.org@localhost>
date: Sun Mar 07 07:09:00 2010 +0000
description:
Add the detach code.
diffstat:
sys/dev/pci/if_wm.c | 114 ++++++++++++++++++++++++++++++++++++++++++---------
1 files changed, 94 insertions(+), 20 deletions(-)
diffs (228 lines):
diff -r 968ec9004eab -r d830de005d23 sys/dev/pci/if_wm.c
--- a/sys/dev/pci/if_wm.c Sun Mar 07 05:37:25 2010 +0000
+++ b/sys/dev/pci/if_wm.c Sun Mar 07 07:09:00 2010 +0000
@@ -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:
*
Home |
Main Index |
Thread Index |
Old Index