[PATCH 3/3] change bwi driver to use wlan_serialize_enter/exit and fix some small bugs

Jost Tobias Springenberg k-gee at wrfl.de
Wed Jan 5 07:10:59 PST 2011


---
 sys/dev/netif/bwi/Makefile     |    5 +-
 sys/dev/netif/bwi/bwimac.c     |   10 ++--
 sys/dev/netif/bwi/if_bwi.c     |   90 ++++++++++++++++++----------------------
 sys/dev/netif/bwi/if_bwi_pci.c |   23 +++++++++-
 sys/dev/netif/bwi/if_bwivar.h  |   11 -----
 5 files changed, 69 insertions(+), 70 deletions(-)

diff --git a/sys/dev/netif/bwi/Makefile b/sys/dev/netif/bwi/Makefile
index acaf2d9..71c8f75 100644
--- a/sys/dev/netif/bwi/Makefile
+++ b/sys/dev/netif/bwi/Makefile
@@ -1,7 +1,8 @@
 # $DragonFly: src/sys/dev/netif/bwi/Makefile,v 1.2 2007/09/30 12:32:20 sephe Exp $
 KMOD	= if_bwi
 
-SRCS	= if_bwi.c bwimac.c bwiphy.c bwirf.c
-SRCS	+= device_if.h bus_if.h pci_if.h
+SRCS	= if_bwi.c bwimac.c bwiphy.c bwirf.c if_bwi_pci.c
+SRCS	+= bitops.h bus_if.h bwimac.h bwiphy.h bwirf.h device_if.h if_bwireg.h if_bwivar.h pci_if.h
+
 
 .include <bsd.kmod.mk>
diff --git a/sys/dev/netif/bwi/bwimac.c b/sys/dev/netif/bwi/bwimac.c
index 288a41a..144dffb 100644
--- a/sys/dev/netif/bwi/bwimac.c
+++ b/sys/dev/netif/bwi/bwimac.c
@@ -883,7 +883,7 @@ bwi_mac_fw_alloc(struct bwi_mac *mac)
 	 * module would be loaded automatically
 	 */
 	if (mac->mac_stub == NULL) {
-		snprintf(fwname, sizeof(fwname), BWI_FW_STUB_PATH,
+		ksnprintf(fwname, sizeof(fwname), BWI_FW_STUB_PATH,
 			 sc->sc_fw_version);
 		mac->mac_stub = firmware_get(fwname);
 		if (mac->mac_stub == NULL) {
@@ -893,7 +893,7 @@ bwi_mac_fw_alloc(struct bwi_mac *mac)
 	}
 
 	if (mac->mac_ucode == NULL) {
-		snprintf(fwname, sizeof(fwname), BWI_FW_UCODE_PATH,
+		ksnprintf(fwname, sizeof(fwname), BWI_FW_UCODE_PATH,
 			  sc->sc_fw_version,
 			  mac->mac_rev >= 5 ? 5 : mac->mac_rev);
 
@@ -908,7 +908,7 @@ bwi_mac_fw_alloc(struct bwi_mac *mac)
 	}
 
 	if (mac->mac_pcm == NULL) {
-		snprintf(fwname, sizeof(fwname), BWI_FW_PCM_PATH,
+		ksnprintf(fwname, sizeof(fwname), BWI_FW_PCM_PATH,
 			  sc->sc_fw_version,
 			  mac->mac_rev < 5 ? 4 : 5);
 
@@ -934,7 +934,7 @@ bwi_mac_fw_alloc(struct bwi_mac *mac)
 			return ENODEV;
 		}
 
-		snprintf(fwname, sizeof(fwname), BWI_FW_IV_PATH,
+		ksnprintf(fwname, sizeof(fwname), BWI_FW_IV_PATH,
 			  sc->sc_fw_version, idx);
 
 		mac->mac_iv = firmware_get(fwname);
@@ -960,7 +960,7 @@ bwi_mac_fw_alloc(struct bwi_mac *mac)
 			return ENODEV;
 		}
 
-		snprintf(fwname, sizeof(fwname), BWI_FW_IV_EXT_PATH,
+		ksnprintf(fwname, sizeof(fwname), BWI_FW_IV_EXT_PATH,
 			  sc->sc_fw_version, idx);
 
 		mac->mac_iv_ext = firmware_get(fwname);
diff --git a/sys/dev/netif/bwi/if_bwi.c b/sys/dev/netif/bwi/if_bwi.c
index 902fa01..c887684 100644
--- a/sys/dev/netif/bwi/if_bwi.c
+++ b/sys/dev/netif/bwi/if_bwi.c
@@ -349,7 +349,7 @@ bwi_attach(struct bwi_softc *sc)
         struct sysctl_ctx_list *ctx;
         struct sysctl_oid *tree;
  
-	BWI_LOCK_INIT(sc);
+	wlan_serialize_enter();
 
 	/*
 	 * Initialize taskq and various tasks
@@ -360,6 +360,7 @@ bwi_attach(struct bwi_softc *sc)
 		device_get_nameunit(dev));
 	TASK_INIT(&sc->sc_restart_task, 0, bwi_restart, sc);
 
+	callout_init(&sc->sc_calib_ch);
 	/*
 	 * Initialize sysctl variables
 	 */
@@ -451,7 +452,7 @@ bwi_attach(struct bwi_softc *sc)
 	ifq_set_maxlen(&ifp->if_snd, ifqmaxlen);
 	ifp->if_snd.ifq_maxlen = ifqmaxlen;
 	ifq_set_ready(&ifp->if_snd);
-	//callout_init_mtx(&sc->sc_watchdog_timer, &sc->sc_mtx, 0);
+	callout_init(&sc->sc_watchdog_timer);
 
 	/*
 	 * Setup ratesets, phytype, channels and get MAC address
@@ -560,10 +561,11 @@ bwi_attach(struct bwi_softc *sc)
 #endif
 	if (bootverbose)
 		ieee80211_announce(ic);
-
+	
+	wlan_serialize_exit();
 	return (0);
 fail:
-	BWI_LOCK_DESTROY(sc);
+	wlan_serialize_exit();
 	return (error);
 }
 
@@ -575,6 +577,8 @@ bwi_detach(struct bwi_softc *sc)
 	int i;
 
 	bwi_stop(sc, 1);
+	
+	wlan_serialize_enter();
 	callout_stop(&sc->sc_led_blink_ch);
 	callout_stop(&sc->sc_calib_ch);
 	callout_stop(&sc->sc_watchdog_timer);
@@ -588,7 +592,7 @@ bwi_detach(struct bwi_softc *sc)
 	if_free(ifp);
 	taskqueue_free(sc->sc_tq);
 
-	BWI_LOCK_DESTROY(sc);
+	wlan_serialize_exit();
 
 	return (0);
 }
@@ -604,7 +608,7 @@ bwi_vap_create(struct ieee80211com *ic,
 
 	if (!TAILQ_EMPTY(&ic->ic_vaps))		/* only one at a time */
 		return NULL;
-	bvp = (struct bwi_vap *) malloc(sizeof(struct bwi_vap),
+	bvp = (struct bwi_vap *) kmalloc(sizeof(struct bwi_vap),
 	    M_80211_VAP, M_WAITOK | M_ZERO);
 	if (bvp == NULL)
 		return NULL;
@@ -634,7 +638,7 @@ bwi_vap_delete(struct ieee80211vap *vap)
 
 	ieee80211_ratectl_deinit(vap);
 	ieee80211_vap_detach(vap);
-	free(bvp, M_80211_VAP);
+	kfree(bvp, M_80211_VAP);
 }
 
 void
@@ -1218,9 +1222,9 @@ bwi_init(void *xsc)
 	struct ifnet *ifp = sc->sc_ifp;
 	struct ieee80211com *ic = ifp->if_l2com;
 
-	BWI_LOCK(sc);
+	wlan_serialize_enter();
 	bwi_init_statechg(sc, 1);
-	BWI_UNLOCK(sc);
+	wlan_serialize_exit();
 
 	if (ifp->if_flags & IFF_RUNNING)
 		ieee80211_start_all(ic);		/* start all vap's */
@@ -1312,7 +1316,7 @@ bwi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data, struct ucred *ucred)
 
 	switch (cmd) {
 	case SIOCSIFFLAGS:
-		BWI_LOCK(sc);
+		wlan_serialize_enter();
 		if (IS_RUNNING(ifp)) {
 			struct bwi_mac *mac;
 			int promisc = -1;
@@ -1345,7 +1349,7 @@ bwi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data, struct ucred *ucred)
 			if (ifp->if_flags & IFF_RUNNING)
 				bwi_stop_locked(sc, 1);
 		}
-		BWI_UNLOCK(sc);
+		wlan_serialize_exit();
 		if (startall)
 			ieee80211_start_all(ic);
 		break;
@@ -1366,11 +1370,11 @@ bwi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data, struct ucred *ucred)
 static void
 bwi_start(struct ifnet *ifp)
 {
-	struct bwi_softc *sc = ifp->if_softc;
-
-	BWI_LOCK(sc);
+	//struct bwi_softc *sc = ifp->if_softc;
+	
+	wlan_serialize_enter();
 	bwi_start_locked(ifp);
-	BWI_UNLOCK(sc);
+	wlan_serialize_exit();
 }
 
 static void
@@ -1450,7 +1454,7 @@ bwi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
 		return ENETDOWN;
 	}
 
-	BWI_LOCK(sc);
+	wlan_serialize_enter();
 	idx = tbd->tbd_idx;
 	KASSERT(tbd->tbd_buf[idx].tb_mbuf == NULL, ("slot %d not empty", idx));
 	if (params == NULL) {
@@ -1477,7 +1481,7 @@ bwi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
 		ieee80211_free_node(ni);
 		ifp->if_oerrors++;
 	}
-	BWI_UNLOCK(sc);
+	wlan_serialize_exit();
 	return error;
 }
 
@@ -1489,7 +1493,6 @@ bwi_watchdog(void *arg)
 
 	sc = arg;
 	ifp = sc->sc_ifp;
-	BWI_ASSERT_LOCKED(sc);
 	if (sc->sc_tx_timer != 0 && --sc->sc_tx_timer == 0) {
 		if_printf(ifp, "watchdog timeout\n");
 		ifp->if_oerrors++;
@@ -1501,9 +1504,9 @@ bwi_watchdog(void *arg)
 static void
 bwi_stop(struct bwi_softc *sc, int statechg)
 {
-	BWI_LOCK(sc);
+	wlan_serialize_enter();
 	bwi_stop_locked(sc, statechg);
-	BWI_UNLOCK(sc);
+	wlan_serialize_exit();
 }
 
 static void
@@ -1513,8 +1516,6 @@ bwi_stop_locked(struct bwi_softc *sc, int statechg)
 	struct bwi_mac *mac;
 	int i, error, pwr_off = 0;
 
-	BWI_ASSERT_LOCKED(sc);
-
 	callout_stop(&sc->sc_calib_ch);
 	callout_stop(&sc->sc_led_blink_ch);
 	sc->sc_led_blinking = 0;
@@ -1565,11 +1566,8 @@ bwi_intr(void *xsc)
 	uint32_t txrx_intr_status[BWI_TXRX_NRING];
 	int i, txrx_error, tx = 0, rx_data = -1;
 
-	BWI_LOCK(sc);
-
 	if ((ifp->if_flags & IFF_RUNNING) == 0 ||
 	    (sc->sc_flags & BWI_F_STOP)) {
-		BWI_UNLOCK(sc);
 		return;
 	}
 	/*
@@ -1577,7 +1575,6 @@ bwi_intr(void *xsc)
 	 */
 	intr_status = CSR_READ_4(sc, BWI_MAC_INTR_STATUS);
 	if (intr_status == 0xffffffff) {	/* Not for us */
-		BWI_UNLOCK(sc);
 		return;
 	}
 
@@ -1585,7 +1582,6 @@ bwi_intr(void *xsc)
 
 	intr_status &= CSR_READ_4(sc, BWI_MAC_INTR_MASK);
 	if (intr_status == 0) {		/* Nothing is interesting */
-		BWI_UNLOCK(sc);
 		return;
 	}
 
@@ -1650,7 +1646,6 @@ bwi_intr(void *xsc)
 		if (mac->mac_flags & BWI_MAC_F_PHYE_RESET) {
 			if_printf(ifp, "%s: intr PHY TX error\n", __func__);
 			taskqueue_enqueue(sc->sc_tq, &sc->sc_restart_task);
-			BWI_UNLOCK(sc);
 			return;
 		}
 	}
@@ -1679,7 +1674,6 @@ bwi_intr(void *xsc)
 	if (txrx_intr_status[0] & BWI_TXRX_INTR_RX) {
 		rx_data = sc->sc_rxeof(sc);
 		if (sc->sc_flags & BWI_F_STOP) {
-			BWI_UNLOCK(sc);
 			return;
 		}
 	}
@@ -1717,7 +1711,6 @@ bwi_intr(void *xsc)
 			bwi_led_event(sc, evt);
 	}
 
-	BWI_UNLOCK(sc);
 }
 
 static void
@@ -1725,10 +1718,10 @@ bwi_scan_start(struct ieee80211com *ic)
 {
 	struct bwi_softc *sc = ic->ic_ifp->if_softc;
 
-	BWI_LOCK(sc);
+	wlan_serialize_enter();
 	/* Enable MAC beacon promiscuity */
 	CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_PASS_BCN);
-	BWI_UNLOCK(sc);
+	wlan_serialize_exit();
 }
 
 static void
@@ -1738,7 +1731,7 @@ bwi_set_channel(struct ieee80211com *ic)
 	struct ieee80211_channel *c = ic->ic_curchan;
 	struct bwi_mac *mac;
 
-	BWI_LOCK(sc);
+	wlan_serialize_enter();
 	KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC,
 	    ("current regwin type %d", sc->sc_cur_regwin->rw_type));
 	mac = (struct bwi_mac *)sc->sc_cur_regwin;
@@ -1754,7 +1747,7 @@ bwi_set_channel(struct ieee80211com *ic)
 	sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags =
 		htole16(c->ic_flags & 0xffff);
 
-	BWI_UNLOCK(sc);
+	wlan_serialize_exit();
 }
 
 static void
@@ -1762,9 +1755,9 @@ bwi_scan_end(struct ieee80211com *ic)
 {
 	struct bwi_softc *sc = ic->ic_ifp->if_softc;
 
-	BWI_LOCK(sc);
+	wlan_serialize_enter();
 	CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_PASS_BCN);
-	BWI_UNLOCK(sc);
+	wlan_serialize_exit();
 }
 
 static int
@@ -1779,7 +1772,7 @@ bwi_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
 	struct bwi_mac *mac;
 	int error;
 
-	BWI_LOCK(sc);
+	wlan_serialize_enter();
 
 	callout_stop(&sc->sc_calib_ch);
 
@@ -1833,7 +1826,7 @@ bwi_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
 		callout_reset(&sc->sc_calib_ch, hz, bwi_calibrate, sc);
 	}
 back:
-	BWI_UNLOCK(sc);
+	wlan_serialize_exit();
 
 	return error;
 }
@@ -2078,7 +2071,7 @@ bwi_dma_txstats_alloc(struct bwi_softc *sc, uint32_t ctrl_base,
 	bus_size_t dma_size;
 	int error;
 
-	st = malloc(sizeof(*st), M_DEVBUF, M_NOWAIT | M_ZERO);
+	st = kmalloc(sizeof(*st), M_DEVBUF, M_NOWAIT | M_ZERO);
 	if (st == NULL) {
 		device_printf(sc->sc_dev, "can't allocate txstats data\n");
 		return ENOMEM;
@@ -2200,7 +2193,7 @@ bwi_dma_txstats_free(struct bwi_softc *sc)
 		bus_dma_tag_destroy(st->stats_dtag);
 	}
 
-	free(st, M_DEVBUF);
+	kfree(st, M_DEVBUF);
 }
 
 static void
@@ -2625,6 +2618,7 @@ bwi_rxeof(struct bwi_softc *sc, int end_idx)
 	int idx, rx_data = 0;
 
 	idx = rbd->rbd_idx;
+	//wlan_serialize_enter();
 	while (idx != end_idx) {
 		struct bwi_rxbuf *rb = &rbd->rbd_buf[idx];
 		struct bwi_rxbuf_hdr *hdr;
@@ -2680,7 +2674,7 @@ bwi_rxeof(struct bwi_softc *sc, int end_idx)
 
 		m_adj(m, -IEEE80211_CRC_LEN);
 
-		BWI_UNLOCK(sc);
+		wlan_serialize_exit();
 
 		wh = mtod(m, struct ieee80211_frame_min *);
 		ni = ieee80211_find_rxnode(ic, wh);
@@ -2694,7 +2688,7 @@ bwi_rxeof(struct bwi_softc *sc, int end_idx)
 			sc->sc_rx_rate = rate;
 		}
 
-		BWI_LOCK(sc);
+		wlan_serialize_enter();
 next:
 		idx = (idx + 1) % BWI_RX_NDESC;
 
@@ -3740,7 +3734,7 @@ bwi_updateslot(struct ifnet *ifp)
 	struct ieee80211com *ic = ifp->if_l2com;
 	struct bwi_mac *mac;
 
-	BWI_LOCK(sc);
+	wlan_serialize_enter();
 	if (ifp->if_flags & IFF_RUNNING) {
 		DPRINTF(sc, BWI_DBG_80211, "%s\n", __func__);
 
@@ -3750,7 +3744,7 @@ bwi_updateslot(struct ifnet *ifp)
 
 		bwi_mac_updateslot(mac, (ic->ic_flags & IEEE80211_F_SHSLOT));
 	}
-	BWI_UNLOCK(sc);
+	wlan_serialize_exit();
 }
 
 static void
@@ -3763,8 +3757,6 @@ bwi_calibrate(void *xsc)
 #endif
 	struct bwi_mac *mac;
 
-	BWI_ASSERT_LOCKED(sc);
-
 	KASSERT(ic->ic_opmode != IEEE80211_M_MONITOR,
 	    ("opmode %d", ic->ic_opmode));
 
@@ -3900,7 +3892,7 @@ bwi_led_attach(struct bwi_softc *sc)
 			"%dth led, act %d, lowact %d\n", i,
 			led->l_act, led->l_flags & BWI_LED_F_ACTLOW);
 	}
-	/*callout_init_mtx(&sc->sc_led_blink_ch, &sc->sc_mtx, 0);*/
+	callout_init(&sc->sc_led_blink_ch);
 }
 
 static __inline uint16_t
@@ -4059,10 +4051,10 @@ bwi_restart(void *xsc, int pending)
 	struct ifnet *ifp = sc->sc_ifp;
 
 	if_printf(ifp, "%s begin, help!\n", __func__);
-	BWI_LOCK(sc);
+	wlan_serialize_enter();
 	bwi_init_statechg(xsc, 0);
 #if 0
 	bwi_start_locked(ifp);
 #endif
-	BWI_UNLOCK(sc);
+	wlan_serialize_exit();
 }
diff --git a/sys/dev/netif/bwi/if_bwi_pci.c b/sys/dev/netif/bwi/if_bwi_pci.c
index 973e01d..0c1130a 100644
--- a/sys/dev/netif/bwi/if_bwi_pci.c
+++ b/sys/dev/netif/bwi/if_bwi_pci.c
@@ -100,16 +100,19 @@ bwi_pci_probe(device_t dev)
 {
 	const struct bwi_dev *b;
 	uint16_t did, vid;
-
+	
+	wlan_serialize_enter();
 	did = pci_get_device(dev);
 	vid = pci_get_vendor(dev);
 
 	for (b = bwi_devices; b->desc != NULL; ++b) {
 		if (b->did == did && b->vid == vid) {
 			device_set_desc(dev, b->desc);
+			wlan_serialize_exit();
 			return BUS_PROBE_DEFAULT;
 		}
 	}
+	wlan_serialize_exit();
 	return ENXIO;
 }
 
@@ -117,9 +120,12 @@ static int
 bwi_pci_attach(device_t dev)
 {
 	struct bwi_pci_softc *psc = device_get_softc(dev);
-	struct bwi_softc *sc = &psc->sc_sc;
+	struct bwi_softc *sc;
 	int error = ENXIO;
 
+	wlan_serialize_enter();
+
+	sc = &psc->sc_sc;
 	sc->sc_dev = dev;
 
 	/*
@@ -169,8 +175,9 @@ bwi_pci_attach(device_t dev)
 	sc->sc_pci_subvid = pci_get_subvendor(dev);
 	sc->sc_pci_subdid = pci_get_subdevice(dev);
 
+        wlan_serialize_exit();
 	error = bwi_attach(sc);
-	if (error == 0)					/* success */
+	if (error == 0)  /* success */
 		return 0;
 
 	bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_irq_handle);
@@ -179,6 +186,7 @@ bad2:
 bad1:
 	bus_release_resource(dev, SYS_RES_MEMORY, BS_BAR, sc->sc_mem_res);
 bad:
+        wlan_serialize_exit();
 	return (error);
 }
 
@@ -188,16 +196,22 @@ bwi_pci_detach(device_t dev)
 	struct bwi_pci_softc *psc = device_get_softc(dev);
 	struct bwi_softc *sc = &psc->sc_sc;
 
+        wlan_serialize_enter();
+
 	/* check if device was removed */
 	sc->sc_invalid = !bus_child_present(dev);
+	wlan_serialize_exit();
 
 	bwi_detach(sc);
 
+        wlan_serialize_enter();
 	bus_generic_detach(dev);
 	bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_irq_handle);
 	bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
 
 	bus_release_resource(dev, SYS_RES_MEMORY, BS_BAR, sc->sc_mem_res);
+        
+	wlan_serialize_exit();
 
 	return (0);
 }
@@ -208,6 +222,7 @@ bwi_pci_shutdown(device_t dev)
 	struct bwi_pci_softc *psc = device_get_softc(dev);
 
 	bwi_shutdown(&psc->sc_sc);
+	
 	return (0);
 }
 
@@ -251,4 +266,6 @@ static	devclass_t bwi_devclass;
 DRIVER_MODULE(bwi, pci, bwi_driver, bwi_devclass, 0, 0);
 MODULE_DEPEND(bwi, wlan, 1, 1, 1);		/* 802.11 media layer */
 MODULE_DEPEND(bwi, firmware, 1, 1, 1);		/* firmware support */
+#if 0
 MODULE_DEPEND(bwi, wlan_amrr, 1, 1, 1);
+#endif 
diff --git a/sys/dev/netif/bwi/if_bwivar.h b/sys/dev/netif/bwi/if_bwivar.h
index 49a07a9..a15f1b6 100644
--- a/sys/dev/netif/bwi/if_bwivar.h
+++ b/sys/dev/netif/bwi/if_bwivar.h
@@ -666,17 +666,6 @@ struct bwi_softc {
 #define BWI_DBG_TXEOF		0x00001000
 #define BWI_DBG_LED		0x00002000
 
-#define BWI_LOCK_INIT(sc) \
-        lockinit(&(sc)->sc_lock, \
-            __DECONST(char *, device_get_nameunit((sc)->sc_dev)), \
-            0, LK_CANRECURSE)
- 
-#define BWI_LOCK_DESTROY(sc)    lockuninit(&(sc)->sc_lock)
-#define BWI_ASSERT_LOCKED(sc)     \
-        KKASSERT(lockstatus(&(sc)->sc_lock, curthread) == LK_EXCLUSIVE)
-#define BWI_LOCK(sc)            lockmgr(&(sc)->sc_lock, LK_EXCLUSIVE)
-#define BWI_UNLOCK(sc)          lockmgr(&(sc)->sc_lock, LK_RELEASE)
-
 int		bwi_attach(struct bwi_softc *);
 int		bwi_detach(struct bwi_softc *);
 void		bwi_suspend(struct bwi_softc *);
-- 
1.7.3.4


--MP_/7kLc1vNOi9uTUCh+2Y3IB1x--






More information about the Kernel mailing list