From 4f58a95ce1229a3d20a787f37863fc91af9ab98a Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Fri, 6 May 2011 22:26:57 +0000 Subject: [PATCH 01/35] Set status word once instead of twice. For 3C90xB/3C90xC, frame length of status word is ignored. While here move bus_dmamap_sync() up where DMA map is loaded. --- sys/dev/xl/if_xl.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sys/dev/xl/if_xl.c b/sys/dev/xl/if_xl.c index 004b511e1129..35f0a633e6da 100644 --- a/sys/dev/xl/if_xl.c +++ b/sys/dev/xl/if_xl.c @@ -2507,6 +2507,7 @@ xl_encap(struct xl_softc *sc, struct xl_chain *c, struct mbuf **m_head) *m_head = NULL; return (EIO); } + bus_dmamap_sync(sc->xl_mtag, c->xl_map, BUS_DMASYNC_PREWRITE); total_len = 0; for (i = 0; i < nseg; i++) { @@ -2519,8 +2520,6 @@ xl_encap(struct xl_softc *sc, struct xl_chain *c, struct mbuf **m_head) total_len += sc->xl_cdata.xl_tx_segs[i].ds_len; } c->xl_ptr->xl_frag[nseg - 1].xl_len |= htole32(XL_LAST_FRAG); - c->xl_ptr->xl_status = htole32(total_len); - c->xl_ptr->xl_next = 0; if (sc->xl_type == XL_TYPE_905B) { status = XL_TXSTAT_RND_DEFEAT; @@ -2535,11 +2534,12 @@ xl_encap(struct xl_softc *sc, struct xl_chain *c, struct mbuf **m_head) status |= XL_TXSTAT_UDPCKSUM; } #endif - c->xl_ptr->xl_status = htole32(status); - } + } else + status = total_len; + c->xl_ptr->xl_status = htole32(status); + c->xl_ptr->xl_next = 0; c->xl_mbuf = *m_head; - bus_dmamap_sync(sc->xl_mtag, c->xl_map, BUS_DMASYNC_PREWRITE); return (0); } From 6ed74a0a1c069e2cc019cef82f668a7b36733ac1 Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Fri, 6 May 2011 22:31:27 +0000 Subject: [PATCH 02/35] sh: Track if the current locale's charset is UTF-8 or not. --- bin/sh/main.c | 2 ++ bin/sh/var.c | 19 +++++++++++++++++++ bin/sh/var.h | 3 +++ 3 files changed, 24 insertions(+) diff --git a/bin/sh/main.c b/bin/sh/main.c index 12a7ff2d1733..d3250eb0eaea 100644 --- a/bin/sh/main.c +++ b/bin/sh/main.c @@ -76,6 +76,7 @@ __FBSDID("$FreeBSD$"); int rootpid; int rootshell; struct jmploc main_handler; +int localeisutf8; static void read_profile(const char *); static char *find_dot_file(char *); @@ -96,6 +97,7 @@ main(int argc, char *argv[]) char *shinit; (void) setlocale(LC_ALL, ""); + updatecharset(); state = 0; if (setjmp(main_handler.loc)) { switch (exception) { diff --git a/bin/sh/var.c b/bin/sh/var.c index e14027f71575..5c87a1f63386 100644 --- a/bin/sh/var.c +++ b/bin/sh/var.c @@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$"); */ #include +#include #include "shell.h" #include "output.h" @@ -361,6 +362,7 @@ setvareq(char *s, int flags) if ((vp->flags & VEXPORT) && localevar(s)) { change_env(s, 1); (void) setlocale(LC_ALL, ""); + updatecharset(); } INTON; return; @@ -379,6 +381,7 @@ setvareq(char *s, int flags) if ((vp->flags & VEXPORT) && localevar(s)) { change_env(s, 1); (void) setlocale(LC_ALL, ""); + updatecharset(); } INTON; } @@ -480,6 +483,7 @@ bltinsetlocale(void) if (loc != NULL) { setlocale(LC_ALL, loc); INTON; + updatecharset(); return; } locdef = bltinlookup("LANG", 0); @@ -491,6 +495,7 @@ bltinsetlocale(void) setlocale(locale_categories[i], loc); } INTON; + updatecharset(); } /* @@ -505,12 +510,24 @@ bltinunsetlocale(void) for (lp = cmdenviron ; lp ; lp = lp->next) { if (localevar(lp->text)) { setlocale(LC_ALL, ""); + updatecharset(); return; } } INTON; } +/* + * Update the localeisutf8 flag. + */ +void +updatecharset(void) +{ + char *charset; + + charset = nl_langinfo(CODESET); + localeisutf8 = !strcmp(charset, "UTF-8"); +} /* * Generate a list of exported variables. This routine is used to construct @@ -656,6 +673,7 @@ exportcmd(int argc, char **argv) if ((vp->flags & VEXPORT) && localevar(vp->text)) { change_env(vp->text, 1); (void) setlocale(LC_ALL, ""); + updatecharset(); } goto found; } @@ -850,6 +868,7 @@ unsetvar(const char *s) if ((vp->flags & VEXPORT) && localevar(vp->text)) { change_env(s, 0); setlocale(LC_ALL, ""); + updatecharset(); } vp->flags &= ~VEXPORT; vp->flags |= VUNSET; diff --git a/bin/sh/var.h b/bin/sh/var.h index 775db4186e81..4336562610bf 100644 --- a/bin/sh/var.h +++ b/bin/sh/var.h @@ -81,6 +81,8 @@ extern struct var vhistsize; extern struct var vterm; #endif +extern int localeisutf8; + /* * The following macros access the values of the above variables. * They have to skip over the name. They return the null string @@ -112,6 +114,7 @@ char *lookupvar(const char *); char *bltinlookup(const char *, int); void bltinsetlocale(void); void bltinunsetlocale(void); +void updatecharset(void); char **environment(void); int showvarscmd(int, char **); int exportcmd(int, char **); From 0ecf6b16c82b7801d64bd221f566fc89482fb719 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Fri, 6 May 2011 22:36:43 +0000 Subject: [PATCH 03/35] Call bus_dmamap_sync() only after TX DPD update. --- sys/dev/xl/if_xl.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/dev/xl/if_xl.c b/sys/dev/xl/if_xl.c index 35f0a633e6da..d3d522f099f4 100644 --- a/sys/dev/xl/if_xl.c +++ b/sys/dev/xl/if_xl.c @@ -2644,8 +2644,6 @@ xl_start_locked(struct ifnet *ifp) * once for each packet. */ cur_tx->xl_ptr->xl_status |= htole32(XL_TXSTAT_DL_INTR); - bus_dmamap_sync(sc->xl_ldata.xl_tx_tag, sc->xl_ldata.xl_tx_dmamap, - BUS_DMASYNC_PREWRITE); /* * Queue the packets. If the TX channel is clear, update @@ -2666,6 +2664,8 @@ xl_start_locked(struct ifnet *ifp) sc->xl_cdata.xl_tx_head = start_tx; sc->xl_cdata.xl_tx_tail = cur_tx; } + bus_dmamap_sync(sc->xl_ldata.xl_tx_tag, sc->xl_ldata.xl_tx_dmamap, + BUS_DMASYNC_PREWRITE); if (!CSR_READ_4(sc, XL_DOWNLIST_PTR)) CSR_WRITE_4(sc, XL_DOWNLIST_PTR, start_tx->xl_phys); @@ -2765,12 +2765,12 @@ xl_start_90xB_locked(struct ifnet *ifp) * once for each packet. */ cur_tx->xl_ptr->xl_status |= htole32(XL_TXSTAT_DL_INTR); - bus_dmamap_sync(sc->xl_ldata.xl_tx_tag, sc->xl_ldata.xl_tx_dmamap, - BUS_DMASYNC_PREWRITE); /* Start transmission */ sc->xl_cdata.xl_tx_prod = idx; start_tx->xl_prev->xl_ptr->xl_next = htole32(start_tx->xl_phys); + bus_dmamap_sync(sc->xl_ldata.xl_tx_tag, sc->xl_ldata.xl_tx_dmamap, + BUS_DMASYNC_PREWRITE); /* * Set a timeout in case the chip goes out to lunch. From f321edf95a10722cc60846baf52eca61e93d4645 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Fri, 6 May 2011 22:45:13 +0000 Subject: [PATCH 04/35] Updating status word should be the last operation of UPD structure renewal. Disable instruction reordering by adding volatile to xl_list_onefrag structure. --- sys/dev/xl/if_xl.c | 2 +- sys/dev/xl/if_xlreg.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/dev/xl/if_xl.c b/sys/dev/xl/if_xl.c index d3d522f099f4..88a7ba884bc4 100644 --- a/sys/dev/xl/if_xl.c +++ b/sys/dev/xl/if_xl.c @@ -1904,8 +1904,8 @@ xl_newbuf(struct xl_softc *sc, struct xl_chain_onefrag *c) sc->xl_tmpmap = map; c->xl_mbuf = m_new; c->xl_ptr->xl_frag.xl_len = htole32(m_new->m_len | XL_LAST_FRAG); - c->xl_ptr->xl_status = 0; c->xl_ptr->xl_frag.xl_addr = htole32(segs->ds_addr); + c->xl_ptr->xl_status = 0; bus_dmamap_sync(sc->xl_mtag, c->xl_map, BUS_DMASYNC_PREREAD); return (0); } diff --git a/sys/dev/xl/if_xlreg.h b/sys/dev/xl/if_xlreg.h index 2685c44a592b..5c1c60cd6588 100644 --- a/sys/dev/xl/if_xlreg.h +++ b/sys/dev/xl/if_xlreg.h @@ -468,8 +468,8 @@ struct xl_list { struct xl_list_onefrag { u_int32_t xl_next; /* final entry has 0 nextptr */ - u_int32_t xl_status; - struct xl_frag xl_frag; + volatile u_int32_t xl_status; + volatile struct xl_frag xl_frag; }; struct xl_list_data { From 74517b0724fad85cc153119335ae40c3a2d59bc0 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Fri, 6 May 2011 22:55:53 +0000 Subject: [PATCH 05/35] Terminate interrupt handler if driver detect it's not running. Also add check for driver running state before trying to send frames. While I'm here, use for loop. --- sys/dev/xl/if_xl.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/sys/dev/xl/if_xl.c b/sys/dev/xl/if_xl.c index 88a7ba884bc4..15438a59cfc1 100644 --- a/sys/dev/xl/if_xl.c +++ b/sys/dev/xl/if_xl.c @@ -2273,10 +2273,14 @@ xl_intr(void *arg) } #endif - while ((status = CSR_READ_2(sc, XL_STATUS)) & XL_INTRS && - status != 0xFFFF) { + for (;;) { + status = CSR_READ_2(sc, XL_STATUS); + if ((status & XL_INTRS) == 0 || status == 0xFFFF) + break; CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ACK|(status & XL_INTRS)); + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + break; if (status & XL_STAT_UP_COMPLETE) { int curpkts; @@ -2304,6 +2308,7 @@ xl_intr(void *arg) if (status & XL_STAT_ADFAIL) { ifp->if_drv_flags &= ~IFF_DRV_RUNNING; xl_init_locked(sc); + break; } if (status & XL_STAT_STATSOFLOW) { @@ -2313,7 +2318,8 @@ xl_intr(void *arg) } } - if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) { + if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd) && + ifp->if_drv_flags & IFF_DRV_RUNNING) { if (sc->xl_type == XL_TYPE_905B) xl_start_90xB_locked(ifp); else From 5a13764b11a2610342ced791a997564c6c8b31a5 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Fri, 6 May 2011 23:01:29 +0000 Subject: [PATCH 06/35] Change xl_rxeof() a bit to return the number of processed frames in RX descriptor ring. Previously it returned the number of frames that were successfully passed to upper stack which in turn means it ignored frames that were discarded due to errors. The number of processed frames in RX descriptor ring is used to detect whether driver is out of sync with controller's current descriptor pointer. Returning number of processed frames reduces unnecessary (probably wrong) re-synchronization. While here, remove unnecessary local variable initialization. --- sys/dev/xl/if_xl.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/sys/dev/xl/if_xl.c b/sys/dev/xl/if_xl.c index 15438a59cfc1..e9384f886a3c 100644 --- a/sys/dev/xl/if_xl.c +++ b/sys/dev/xl/if_xl.c @@ -1944,7 +1944,7 @@ xl_rxeof(struct xl_softc *sc) struct mbuf *m; struct ifnet *ifp = sc->xl_ifp; struct xl_chain_onefrag *cur_rx; - int total_len = 0; + int total_len; int rx_npkts = 0; u_int32_t rxstat; @@ -1963,6 +1963,7 @@ again: cur_rx = sc->xl_cdata.xl_rx_head; sc->xl_cdata.xl_rx_head = cur_rx->xl_next; total_len = rxstat & XL_RXSTAT_LENMASK; + rx_npkts++; /* * Since we have told the chip to allow large frames, @@ -2047,7 +2048,6 @@ again: XL_UNLOCK(sc); (*ifp->if_input)(ifp, m); XL_LOCK(sc); - rx_npkts++; /* * If we are running from the taskqueue, the interface @@ -2283,11 +2283,7 @@ xl_intr(void *arg) break; if (status & XL_STAT_UP_COMPLETE) { - int curpkts; - - curpkts = ifp->if_ipackets; - xl_rxeof(sc); - if (curpkts == ifp->if_ipackets) { + if (xl_rxeof(sc) == 0) { while (xl_rx_resync(sc)) xl_rxeof(sc); } From 4a5c7884564b3dcbe354e594fe29a329a86af311 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Fri, 6 May 2011 23:49:10 +0000 Subject: [PATCH 07/35] Reuse the TX descriptor(DPD) if xl_encap() failed instead of just picking the next available one. This may explain why xl(4) sees TX underrun error with no queued frame. I hope this addresses a long standing xl(4) watchdog timeout issue as well. Obtained from: OpenBSD --- sys/dev/xl/if_xl.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/sys/dev/xl/if_xl.c b/sys/dev/xl/if_xl.c index e9384f886a3c..cc33caa482a3 100644 --- a/sys/dev/xl/if_xl.c +++ b/sys/dev/xl/if_xl.c @@ -2571,8 +2571,9 @@ static void xl_start_locked(struct ifnet *ifp) { struct xl_softc *sc = ifp->if_softc; - struct mbuf *m_head = NULL; + struct mbuf *m_head; struct xl_chain *prev = NULL, *cur_tx = NULL, *start_tx; + struct xl_chain *prev_tx; u_int32_t status; int error; @@ -2603,11 +2604,13 @@ xl_start_locked(struct ifnet *ifp) break; /* Pick a descriptor off the free list. */ + prev_tx = cur_tx; cur_tx = sc->xl_cdata.xl_tx_free; /* Pack the data into the descriptor. */ error = xl_encap(sc, cur_tx, &m_head); if (error) { + cur_tx = prev_tx; if (m_head == NULL) break; ifp->if_drv_flags |= IFF_DRV_OACTIVE; @@ -2702,8 +2705,9 @@ static void xl_start_90xB_locked(struct ifnet *ifp) { struct xl_softc *sc = ifp->if_softc; - struct mbuf *m_head = NULL; + struct mbuf *m_head; struct xl_chain *prev = NULL, *cur_tx = NULL, *start_tx; + struct xl_chain *prev_tx; int error, idx; XL_LOCK_ASSERT(sc); @@ -2726,11 +2730,13 @@ xl_start_90xB_locked(struct ifnet *ifp) if (m_head == NULL) break; + prev_tx = cur_tx; cur_tx = &sc->xl_cdata.xl_tx_chain[idx]; /* Pack the data into the descriptor. */ error = xl_encap(sc, cur_tx, &m_head); if (error) { + cur_tx = prev_tx; if (m_head == NULL) break; ifp->if_drv_flags |= IFF_DRV_OACTIVE; From 48dcbc3370d9f55bda3c5ba2c8b84ab92d27f741 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Sat, 7 May 2011 00:06:02 +0000 Subject: [PATCH 08/35] Rename xl_stats_update() callout handler to xl_tick() and move MII tick driving logic to xl_tick(). Now xl_tick() handles MII tick as well as periodic updating of statistics. This change removes a hack used in interrupt handler where it wanted to update statistics without driving MII tick. --- sys/dev/xl/if_xl.c | 55 ++++++++++++++++--------------------------- sys/dev/xl/if_xlreg.h | 3 +-- 2 files changed, 21 insertions(+), 37 deletions(-) diff --git a/sys/dev/xl/if_xl.c b/sys/dev/xl/if_xl.c index cc33caa482a3..a63a3149fb37 100644 --- a/sys/dev/xl/if_xl.c +++ b/sys/dev/xl/if_xl.c @@ -225,8 +225,8 @@ static int xl_attach(device_t); static int xl_detach(device_t); static int xl_newbuf(struct xl_softc *, struct xl_chain_onefrag *); -static void xl_stats_update(void *); -static void xl_stats_update_locked(struct xl_softc *); +static void xl_tick(void *); +static void xl_stats_update(struct xl_softc *); static int xl_encap(struct xl_softc *, struct xl_chain *, struct mbuf **); static int xl_rxeof(struct xl_softc *); static void xl_rxeof_task(void *, int); @@ -1330,7 +1330,7 @@ xl_attach(device_t dev) goto fail; } - callout_init_mtx(&sc->xl_stat_callout, &sc->xl_mtx, 0); + callout_init_mtx(&sc->xl_tick_callout, &sc->xl_mtx, 0); TASK_INIT(&sc->xl_task, 0, xl_rxeof_task, sc); /* @@ -1695,7 +1695,7 @@ xl_detach(device_t dev) xl_stop(sc); XL_UNLOCK(sc); taskqueue_drain(taskqueue_swi, &sc->xl_task); - callout_drain(&sc->xl_stat_callout); + callout_drain(&sc->xl_tick_callout); ether_ifdetach(ifp); } if (sc->xl_miibus) @@ -2307,11 +2307,8 @@ xl_intr(void *arg) break; } - if (status & XL_STAT_STATSOFLOW) { - sc->xl_stats_no_timeout = 1; - xl_stats_update_locked(sc); - sc->xl_stats_no_timeout = 0; - } + if (status & XL_STAT_STATSOFLOW) + xl_stats_update(sc); } if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd) && @@ -2379,49 +2376,46 @@ xl_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count) xl_init_locked(sc); } - if (status & XL_STAT_STATSOFLOW) { - sc->xl_stats_no_timeout = 1; + if (status & XL_STAT_STATSOFLOW) xl_stats_update_locked(sc); - sc->xl_stats_no_timeout = 0; - } } } return (rx_npkts); } #endif /* DEVICE_POLLING */ -/* - * XXX: This is an entry point for callout which needs to take the lock. - */ static void -xl_stats_update(void *xsc) +xl_tick(void *xsc) { struct xl_softc *sc = xsc; + struct mii_data *mii; XL_LOCK_ASSERT(sc); + if (sc->xl_miibus != NULL) { + mii = device_get_softc(sc->xl_miibus); + mii_tick(mii); + } + + xl_stats_update(sc); if (xl_watchdog(sc) == EJUSTRETURN) return; - xl_stats_update_locked(sc); + callout_reset(&sc->xl_tick_callout, hz, xl_tick, sc); } static void -xl_stats_update_locked(struct xl_softc *sc) +xl_stats_update(struct xl_softc *sc) { struct ifnet *ifp = sc->xl_ifp; struct xl_stats xl_stats; u_int8_t *p; int i; - struct mii_data *mii = NULL; XL_LOCK_ASSERT(sc); bzero((char *)&xl_stats, sizeof(struct xl_stats)); - if (sc->xl_miibus != NULL) - mii = device_get_softc(sc->xl_miibus); - p = (u_int8_t *)&xl_stats; /* Read all the stats registers. */ @@ -2443,14 +2437,7 @@ xl_stats_update_locked(struct xl_softc *sc) */ XL_SEL_WIN(4); CSR_READ_1(sc, XL_W4_BADSSD); - - if ((mii != NULL) && (!sc->xl_stats_no_timeout)) - mii_tick(mii); - XL_SEL_WIN(7); - - if (!sc->xl_stats_no_timeout) - callout_reset(&sc->xl_stat_callout, hz, xl_stats_update, sc); } /* @@ -2957,9 +2944,7 @@ xl_init_locked(struct xl_softc *sc) /* Clear out the stats counters. */ CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_STATS_DISABLE); - sc->xl_stats_no_timeout = 1; - xl_stats_update_locked(sc); - sc->xl_stats_no_timeout = 0; + xl_stats_update(sc); XL_SEL_WIN(4); CSR_WRITE_2(sc, XL_W4_NET_DIAG, XL_NETDIAG_UPPER_BYTES_ENABLE); CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_STATS_ENABLE); @@ -3000,7 +2985,7 @@ xl_init_locked(struct xl_softc *sc) ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; sc->xl_wdog_timer = 0; - callout_reset(&sc->xl_stat_callout, hz, xl_stats_update, sc); + callout_reset(&sc->xl_tick_callout, hz, xl_tick, sc); } /* @@ -3309,7 +3294,7 @@ xl_stop(struct xl_softc *sc) bus_space_write_4(sc->xl_ftag, sc->xl_fhandle, 4, 0x8000); /* Stop the stats updater. */ - callout_stop(&sc->xl_stat_callout); + callout_stop(&sc->xl_tick_callout); /* * Free data in the RX lists. diff --git a/sys/dev/xl/if_xlreg.h b/sys/dev/xl/if_xlreg.h index 5c1c60cd6588..28b956bbbc1d 100644 --- a/sys/dev/xl/if_xlreg.h +++ b/sys/dev/xl/if_xlreg.h @@ -614,13 +614,12 @@ struct xl_softc { u_int32_t xl_xcvr; u_int16_t xl_media; u_int16_t xl_caps; - u_int8_t xl_stats_no_timeout; u_int16_t xl_tx_thresh; int xl_pmcap; int xl_if_flags; struct xl_list_data xl_ldata; struct xl_chain_data xl_cdata; - struct callout xl_stat_callout; + struct callout xl_tick_callout; int xl_wdog_timer; int xl_flags; struct resource *xl_fres; From 7498e81a2df59d1b7de4fbc5283f1373a4ac6131 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Sat, 7 May 2011 00:18:58 +0000 Subject: [PATCH 09/35] Rearm watchdog timer if driver kick controller to recover from TX underrun error. While here, prepend 0x to status code to show TX status is hex number. --- sys/dev/xl/if_xl.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sys/dev/xl/if_xl.c b/sys/dev/xl/if_xl.c index a63a3149fb37..03a711459f13 100644 --- a/sys/dev/xl/if_xl.c +++ b/sys/dev/xl/if_xl.c @@ -2207,7 +2207,7 @@ xl_txeoc(struct xl_softc *sc) txstat & XL_TXSTATUS_JABBER || txstat & XL_TXSTATUS_RECLAIM) { device_printf(sc->xl_dev, - "transmission error: %x\n", txstat); + "transmission error: 0x%02x\n", txstat); CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_RESET); xl_wait(sc); if (sc->xl_type == XL_TYPE_905B) { @@ -2220,11 +2220,14 @@ xl_txeoc(struct xl_softc *sc) CSR_WRITE_4(sc, XL_DOWNLIST_PTR, c->xl_phys); CSR_WRITE_1(sc, XL_DOWN_POLL, 64); + sc->xl_wdog_timer = 5; } } else { - if (sc->xl_cdata.xl_tx_head != NULL) + if (sc->xl_cdata.xl_tx_head != NULL) { CSR_WRITE_4(sc, XL_DOWNLIST_PTR, sc->xl_cdata.xl_tx_head->xl_phys); + sc->xl_wdog_timer = 5; + } } /* * Remember to set this for the From 0b96ba12be71c56972f9c205807ec5f91236cf25 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Sat, 7 May 2011 00:25:12 +0000 Subject: [PATCH 10/35] XL_DMACTL is 32bit register, use 32bit write macro. While I'm here add more bits for the register. --- sys/dev/xl/if_xl.c | 2 +- sys/dev/xl/if_xlreg.h | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/sys/dev/xl/if_xl.c b/sys/dev/xl/if_xl.c index 03a711459f13..51e01f24575a 100644 --- a/sys/dev/xl/if_xl.c +++ b/sys/dev/xl/if_xl.c @@ -2969,7 +2969,7 @@ xl_init_locked(struct xl_softc *sc) /* Set the RX early threshold */ CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_THRESH|(XL_PACKET_SIZE >>2)); - CSR_WRITE_2(sc, XL_DMACTL, XL_DMACTL_UP_RX_EARLY); + CSR_WRITE_4(sc, XL_DMACTL, XL_DMACTL_UP_RX_EARLY); /* Enable receiver and transmitter. */ CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_ENABLE); diff --git a/sys/dev/xl/if_xlreg.h b/sys/dev/xl/if_xlreg.h index 28b956bbbc1d..f5494f55650f 100644 --- a/sys/dev/xl/if_xlreg.h +++ b/sys/dev/xl/if_xlreg.h @@ -124,6 +124,11 @@ #define XL_DMACTL_DOWN_INPROG 0x00000080 #define XL_DMACTL_COUNTER_SPEED 0x00000100 #define XL_DMACTL_DOWNDOWN_MODE 0x00000200 +#define XL_DMACTL_UP_ALTSEQ_DIS 0x00010000 /* 3c90xB/3c90xC */ +#define XL_DMACTL_DOWN_ALTSEQ_DIS 0x00020000 /* 3c90xC only */ +#define XL_DMACTL_DEFEAT_MWI 0x00100000 /* 3c90xB/3c90xC */ +#define XL_DMACTL_DEFEAT_MRL 0x00100000 /* 3c90xB/3c90xC */ +#define XL_DMACTL_UP_OVERRUN_DISC_DIS 0x00200000 /* 3c90xB/3c90xC */ #define XL_DMACTL_TARGET_ABORT 0x40000000 #define XL_DMACTL_MASTER_ABORT 0x80000000 From 9b2a96cc0410d247dbfad35cfef16351b888788a Mon Sep 17 00:00:00 2001 From: "David E. O'Brien" Date: Sat, 7 May 2011 01:05:31 +0000 Subject: [PATCH 11/35] Add the ability to search for all the inlined instances of a given function. Reviewed by: jb Obtained from: Juniper Networks --- lib/libdwarf/Makefile | 1 + lib/libdwarf/_libdwarf.h | 31 ++++++ lib/libdwarf/dwarf_func.c | 227 ++++++++++++++++++++++++++++++++++++++ lib/libdwarf/dwarf_init.c | 4 + lib/libdwarf/libdwarf.h | 14 +++ lib/libelf/Makefile | 2 +- lib/libelf/libelf_data.c | 2 + sys/sys/elf_common.h | 2 + 8 files changed, 282 insertions(+), 1 deletion(-) create mode 100644 lib/libdwarf/dwarf_func.c diff --git a/lib/libdwarf/Makefile b/lib/libdwarf/Makefile index 1375a92dd450..aa182e7d9b76 100644 --- a/lib/libdwarf/Makefile +++ b/lib/libdwarf/Makefile @@ -14,6 +14,7 @@ SRCS= \ dwarf_errno.c \ dwarf_finish.c \ dwarf_form.c \ + dwarf_func.c \ dwarf_init.c \ dwarf_loc.c diff --git a/lib/libdwarf/_libdwarf.h b/lib/libdwarf/_libdwarf.h index 697b0342219a..828250eba102 100644 --- a/lib/libdwarf/_libdwarf.h +++ b/lib/libdwarf/_libdwarf.h @@ -163,6 +163,37 @@ struct _Dwarf_Debug { dbg_cu; /* List of compilation units. */ Dwarf_CU dbg_cu_current; /* Ptr to the current compilation unit. */ + + STAILQ_HEAD(, _Dwarf_Func) dbg_func; /* List of functions */ }; +struct _Dwarf_Func { + Dwarf_Die func_die; + const char *func_name; + Dwarf_Addr func_low_pc; + Dwarf_Addr func_high_pc; + int func_is_inlined; + /* inlined instance */ + STAILQ_HEAD(, _Dwarf_Inlined_Func) func_inlined_instances; + STAILQ_ENTRY(_Dwarf_Func) func_next; +}; + +struct _Dwarf_Inlined_Func { + struct _Dwarf_Func *ifunc_origin; + Dwarf_Die ifunc_abstract; + Dwarf_Die ifunc_concrete; + Dwarf_Addr ifunc_low_pc; + Dwarf_Addr ifunc_high_pc; + STAILQ_ENTRY(_Dwarf_Inlined_Func) ifunc_next; +}; + +void dwarf_build_function_table(Dwarf_Debug dbg); + +#ifdef DWARF_DEBUG +#include +#define DWARF_ASSERT(x) assert(x) +#else +#define DWARF_ASSERT(x) +#endif + #endif /* !__LIBDWARF_H_ */ diff --git a/lib/libdwarf/dwarf_func.c b/lib/libdwarf/dwarf_func.c new file mode 100644 index 000000000000..b00d858ee601 --- /dev/null +++ b/lib/libdwarf/dwarf_func.c @@ -0,0 +1,227 @@ +/*- + * Copyright (c) 2008-2009, 2011, Juniper Networks, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * JNPR: dwarf_func.c 336441 2009-10-17 09:19:54Z deo + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include <_libdwarf.h> + +static void +dwarf_add_function(Dwarf_Debug dbg, Dwarf_Func func) +{ + + STAILQ_INSERT_TAIL(&dbg->dbg_func, func, func_next); +} + +int +dwarf_function_get_addr_range(Dwarf_Func f, Dwarf_Addr *low_pc, + Dwarf_Addr *high_pc) +{ + + *low_pc = f->func_low_pc; + *high_pc = f->func_high_pc; + return 0; +} + +int +dwarf_inlined_function_get_addr_range(Dwarf_Inlined_Func f, Dwarf_Addr *low_pc, + Dwarf_Addr *high_pc) +{ + + *low_pc = f->ifunc_low_pc; + *high_pc = f->ifunc_high_pc; + return 0; +} + +int +dwarf_function_is_inlined(Dwarf_Func f) +{ + + if (f->func_is_inlined == DW_INL_inlined || + f->func_is_inlined == DW_INL_declared_inlined) + return 1; + else + return 0; +} + +Dwarf_Func +dwarf_find_function_by_name(Dwarf_Debug dbg, const char *name) +{ + /* XXX: replace with a fast version */ + + Dwarf_Func func; + STAILQ_FOREACH(func, &dbg->dbg_func, func_next) { + if (strcmp(name, func->func_name) == 0) + return func; + } + return NULL; +} + +Dwarf_Func +dwarf_find_function_by_offset(Dwarf_Debug dbg, Dwarf_Off off) +{ + + Dwarf_Func func; + Dwarf_Die die; + /* printf("look for %llx\n", off); */ + STAILQ_FOREACH(func, &dbg->dbg_func, func_next) { + die = func->func_die; + if ((off_t)die->die_offset == off) { + return func; + } + } + return NULL; +} + +void +dwarf_build_function_table(Dwarf_Debug dbg) +{ + Dwarf_CU cu; + Dwarf_AttrValue av; + Dwarf_Die die, origin_die; + Dwarf_Func func, origin_func; + Dwarf_Inlined_Func ifunc; + unsigned long long offset; + const char *name; + Dwarf_Error error; + + /* + * find out all the functions + */ + STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) { + STAILQ_FOREACH(die, &cu->cu_die, die_next) { + if (die->die_a->a_tag == DW_TAG_subprogram) { + /* + * Some function has multiple entries, i.e. + * if a function is inlined, it has many + * abstract/concrete instances, the abstract + * instances are with DW_TAG_subprogram. + */ + dwarf_attrval_string(die, DW_AT_name, &name, + &error); + func = dwarf_find_function_by_name(dbg, name); + if (func == NULL) { + func = malloc( + sizeof(struct _Dwarf_Func)); + DWARF_ASSERT(func); + + func->func_die = die; + func->func_name = name; + STAILQ_INIT( + &func->func_inlined_instances); + + dwarf_add_function(dbg, func); + STAILQ_FOREACH(av, &die->die_attrval, + av_next) { + switch (av->av_attrib) { + case DW_AT_low_pc: + func->func_low_pc = + av->u[0].u64; + break; + case DW_AT_high_pc: + func->func_high_pc = + av->u[0].u64; + break; + case DW_AT_inline: + func->func_is_inlined = + av->u[0].u64; + break; + } + } + } + } + } + } + + /* + * Now check the concrete inlined instances. + */ + STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) { + STAILQ_FOREACH(die, &cu->cu_die, die_next) { + if (die->die_a->a_tag == DW_TAG_inlined_subroutine) { + ifunc = malloc( + sizeof(struct _Dwarf_Inlined_Func)); + DWARF_ASSERT(ifunc); + STAILQ_FOREACH(av, &die->die_attrval, av_next) { + switch (av->av_attrib) { + case DW_AT_abstract_origin: + offset = av->u[0].u64 + + die->die_cu->cu_offset; + origin_die = dwarf_die_find( + die, offset); + DWARF_ASSERT(origin_die != 0); + + /* + * the abstract origin must + * have been merged with + * another die + */ + dwarf_attrval_string( + origin_die, DW_AT_name, + &name, &error); + origin_func = + dwarf_find_function_by_name + (dbg, name); + DWARF_ASSERT(origin_func != 0); + + STAILQ_INSERT_TAIL( + &origin_func-> + func_inlined_instances, + ifunc, ifunc_next); + + break; + case DW_AT_low_pc: + ifunc->ifunc_low_pc = + av->u[0].u64; + break; + case DW_AT_high_pc: + ifunc->ifunc_high_pc = + av->u[0].u64; + break; + } + } + } + } + } +} + +void +dwarf_function_iterate_inlined_instance(Dwarf_Func func, + Dwarf_Inlined_Callback f, void *data) +{ + Dwarf_Inlined_Func ifunc; + + if (!dwarf_function_is_inlined(func)) + return; + STAILQ_FOREACH(ifunc, &func->func_inlined_instances, ifunc_next) { + f(ifunc, data); + } +} diff --git a/lib/libdwarf/dwarf_init.c b/lib/libdwarf/dwarf_init.c index 30b7b0f573d8..95642a045f93 100644 --- a/lib/libdwarf/dwarf_init.c +++ b/lib/libdwarf/dwarf_init.c @@ -578,6 +578,9 @@ dwarf_init_info(Dwarf_Debug dbg, Dwarf_Error *error) offset = next_offset; } + /* Build the function table. */ + dwarf_build_function_table(dbg); + return ret; } @@ -686,6 +689,7 @@ dwarf_elf_init(Elf *elf, int mode, Dwarf_Debug *ret_dbg, Dwarf_Error *error) dbg->dbg_mode = mode; STAILQ_INIT(&dbg->dbg_cu); + STAILQ_INIT(&dbg->dbg_func); *ret_dbg = dbg; diff --git a/lib/libdwarf/libdwarf.h b/lib/libdwarf/libdwarf.h index 6d4930d43878..04192b7ead64 100644 --- a/lib/libdwarf/libdwarf.h +++ b/lib/libdwarf/libdwarf.h @@ -51,6 +51,7 @@ typedef struct _Dwarf_Debug *Dwarf_Debug; typedef struct _Dwarf_Die *Dwarf_Die; typedef struct _Dwarf_Fde *Dwarf_Fde; typedef struct _Dwarf_Func *Dwarf_Func; +typedef struct _Dwarf_Inlined_Func *Dwarf_Inlined_Func; typedef struct _Dwarf_Global *Dwarf_Global; typedef struct _Dwarf_Line *Dwarf_Line; typedef struct _Dwarf_Type *Dwarf_Type; @@ -71,6 +72,9 @@ typedef struct { Dwarf_Loc *ld_s; } Dwarf_Locdesc; +/* receiver function for dwarf_function_iterate_inlined_instance() API */ +typedef void (*Dwarf_Inlined_Callback)(Dwarf_Inlined_Func, void *); + /* * Error numbers which are specific to this implementation. */ @@ -157,6 +161,16 @@ void dwarf_dump_strtab(Dwarf_Debug); void dwarf_dump_symtab(Dwarf_Debug); void dwarf_dump_raw(Dwarf_Debug); void dwarf_dump_tree(Dwarf_Debug); +Dwarf_Func dwarf_find_function_by_offset(Dwarf_Debug dbg, Dwarf_Off off); +Dwarf_Func dwarf_find_function_by_name(Dwarf_Debug dbg, const char *name); +int dwarf_function_get_addr_range(Dwarf_Func f, + Dwarf_Addr *low_pc, Dwarf_Addr *high_pc); +int dwarf_function_is_inlined(Dwarf_Func f); +void dwarf_function_iterate_inlined_instance(Dwarf_Func func, + Dwarf_Inlined_Callback f, void *data); +int dwarf_inlined_function_get_addr_range(Dwarf_Inlined_Func f, + Dwarf_Addr *low_pc, Dwarf_Addr *high_pc); + __END_DECLS #endif /* !_LIBDWARF_H_ */ diff --git a/lib/libelf/Makefile b/lib/libelf/Makefile index fc70d9d865c7..fe921cbe674b 100644 --- a/lib/libelf/Makefile +++ b/lib/libelf/Makefile @@ -57,7 +57,7 @@ INCS= libelf.h gelf.h GENSRCS= libelf_fsize.c libelf_msize.c libelf_convert.c CLEANFILES= ${GENSRCS} -CFLAGS+= -I. -I${.CURDIR} +CFLAGS+= -I${.CURDIR} -I${.CURDIR}/../../sys SHLIB_MAJOR= 1 diff --git a/lib/libelf/libelf_data.c b/lib/libelf/libelf_data.c index 67388b6a4a31..ee2d57a4cb79 100644 --- a/lib/libelf/libelf_data.c +++ b/lib/libelf/libelf_data.c @@ -84,6 +84,8 @@ _libelf_xlate_shtype(uint32_t sht) case SHT_SUNW_dof: return (ELF_T_BYTE); #endif + case SHT_MIPS_DWARF: + /* FALLTHROUGH */ case SHT_AMD64_UNWIND: /* == SHT_IA_64_UNWIND */ return (ELF_T_BYTE); default: diff --git a/sys/sys/elf_common.h b/sys/sys/elf_common.h index 568d15f477ba..42165ce03ad9 100644 --- a/sys/sys/elf_common.h +++ b/sys/sys/elf_common.h @@ -1,4 +1,5 @@ /*- + * Copyright (c) 2000, 2001, 2008, 2011, David E. O'Brien * Copyright (c) 1998 John D. Polstra. * All rights reserved. * @@ -295,6 +296,7 @@ typedef struct { #define SHT_HIOS 0x6fffffff /* Last of OS specific semantics */ #define SHT_LOPROC 0x70000000 /* reserved range for processor */ #define SHT_AMD64_UNWIND 0x70000001 /* unwind information */ +#define SHT_MIPS_DWARF 0x7000001e /* MIPS gcc uses MIPS_DWARF */ #define SHT_HIPROC 0x7fffffff /* specific section header types */ #define SHT_LOUSER 0x80000000 /* reserved range for application */ #define SHT_HIUSER 0xffffffff /* specific indexes */ From 3ea23f341b002d4e573cd00b546a25ee2447560a Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Sat, 7 May 2011 02:19:46 +0000 Subject: [PATCH 12/35] Remove unneeded use of variable status. This should have been done in r221557. --- sys/dev/xl/if_xl.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sys/dev/xl/if_xl.c b/sys/dev/xl/if_xl.c index 51e01f24575a..228a3caa3b85 100644 --- a/sys/dev/xl/if_xl.c +++ b/sys/dev/xl/if_xl.c @@ -2564,7 +2564,6 @@ xl_start_locked(struct ifnet *ifp) struct mbuf *m_head; struct xl_chain *prev = NULL, *cur_tx = NULL, *start_tx; struct xl_chain *prev_tx; - u_int32_t status; int error; XL_LOCK_ASSERT(sc); @@ -2651,7 +2650,6 @@ xl_start_locked(struct ifnet *ifp) sc->xl_cdata.xl_tx_tail->xl_next = start_tx; sc->xl_cdata.xl_tx_tail->xl_ptr->xl_next = htole32(start_tx->xl_phys); - status = sc->xl_cdata.xl_tx_tail->xl_ptr->xl_status; sc->xl_cdata.xl_tx_tail->xl_ptr->xl_status &= htole32(~XL_TXSTAT_DL_INTR); sc->xl_cdata.xl_tx_tail = cur_tx; From d1915e7308fbbbbfd37f2285096aa56c44e385c0 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sat, 7 May 2011 02:54:52 +0000 Subject: [PATCH 13/35] Fix the OWL revision checks. A quick story, which is partially documented in the commit. The silicon revision in Linux ath9k and the Atheros HAL use an AR_SREV_REVISION mask of 0x07. FreeBSD's HAL uses the AR5212 AR_SREV_REVISION mask of 0x0F. Thus the OWL silicon revisions were coming through as 0xA, 0xB, 0xC, rather than 0x0, 0x1 and 0x2. My ath9k-sourced AR_SREV_OWL_ macros were thus using the wrong silicon revision values and wouldn't correctly match. This commit does a few things: * Change the AR_SREV_OWL_ macros to use the AR_SREV_REVISION_OWL_* values, not AR_XSREV_REVISION_OWL macros; * Disable AR_XSREV_REVISION_OWL_* values; * Modify the IS_5416 to properly check the MAC is OWL, rather than potentially matching on non-OWL revisions (which shouldn't happen unless there's a silicon revision of higher than 0x9 in a later chip..) * Add a couple more macros from the Atheros HAL for compatibility. The main difference now is that the Atheros HAL defines AR_SREV_OWL_{20,22}_OR_LATER subtly differently - it fails on all HOWL silicon. The AR_SREV_5416_*_OR_LATER macros match on the relevant OWL version -and- all HOWL versions, along with subsequent versions. A subsequent commit is going to migrate the uses of AR_SREV_OWL_X_OR_LATER to AR_SREV_5416_X_OR_LATER to match what's going on in the Atheros HAL. There's only two uses of AR_SREV_OWL_X_OR_LATER which currently don't apply to FreeBSD but it may do in the future. Yes, it's all confusing! --- sys/dev/ath/ath_hal/ar5416/ar5416reg.h | 36 ++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416reg.h b/sys/dev/ath/ath_hal/ar5416/ar5416reg.h index 96903e45f904..e67e13a2da70 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416reg.h +++ b/sys/dev/ath/ath_hal/ar5416/ar5416reg.h @@ -580,6 +580,17 @@ #define AR_EEPROM_STATUS_DATA_PROT_ACCESS 0x00040000 #define AR_EEPROM_STATUS_DATA_ABSENT_ACCESS 0x00080000 +/* + * AR5212 defines the MAC revision mask as 0xF, but both ath9k and + * the Atheros HAL define it as 0x7. + * + * What this means however is AR5416 silicon revisions have + * changed. The below macros are for what is contained in the + * lower four bits; if the lower three bits are taken into account + * the revisions become 1.0 => 0x0, 2.0 => 0x1, 2.2 => 0x2. + */ + +/* These are the legacy revisions, with a four bit AR_SREV_REVISION mask */ #define AR_SREV_REVISION_OWL_10 0x08 #define AR_SREV_REVISION_OWL_20 0x09 #define AR_SREV_REVISION_OWL_22 0x0a @@ -590,9 +601,13 @@ #define AR_RAD2122_SREV_MAJOR 0xf0 /* Fowl: 2+5G/2x2 */ /* Test macro for owl 1.0 */ -#define IS_5416V1(_ah) ((_ah)->ah_macRev == AR_SREV_REVISION_OWL_10) -#define IS_5416V2(_ah) ((_ah)->ah_macRev >= AR_SREV_REVISION_OWL_20) -#define IS_5416V2_2(_ah) ((_ah)->ah_macRev == AR_SREV_REVISION_OWL_22) +#define IS_5416V1(_ah) (AR_SREV_OWL((ah)) && (_ah)->ah_macRev == AR_SREV_REVISION_OWL_10) +#define IS_5416V2(_ah) (AR_SREV_OWL((ah)) && (_ah)->ah_macRev >= AR_SREV_REVISION_OWL_20) +#define IS_5416V2_2(_ah) (AR_SREV_OWL((ah)) && (_ah)->ah_macRev == AR_SREV_REVISION_OWL_22) + +/* Misc; compatibility with Atheros HAL */ +#define AR_SREV_5416_V20_OR_LATER(_ah) (AR_SREV_HOWL((_ah)) || AR_SREV_OWL_20_OR_LATER(_ah)) +#define AR_SREV_5416_V22_OR_LATER(_ah) (AR_SREV_HOWL((_ah)) || AR_SREV_OWL_22_OR_LATER(_ah)) /* Expanded Mac Silicon Rev (16 bits starting with Sowl) */ #define AR_XSREV_ID 0xFFFFFFFF /* Chip ID */ @@ -609,9 +624,20 @@ #define AR_XSREV_VERSION_OWL_PCI 0x0D #define AR_XSREV_VERSION_OWL_PCIE 0x0C + + +/* + * These are from ath9k/Atheros and assume an AR_SREV version mask + * of 0x07, rather than 0x0F which is being used in the FreeBSD HAL. + * Thus, don't use these values as they're incorrect here; use + * AR_SREV_REVISION_OWL_{10,20,22}. + */ +#if 0 #define AR_XSREV_REVISION_OWL_10 0 /* Owl 1.0 */ #define AR_XSREV_REVISION_OWL_20 1 /* Owl 2.0/2.1 */ #define AR_XSREV_REVISION_OWL_22 2 /* Owl 2.2 */ +#endif + #define AR_XSREV_VERSION_HOWL 0x14 /* Howl (AR9130) */ #define AR_XSREV_VERSION_SOWL 0x40 /* Sowl (AR9160) */ #define AR_XSREV_REVISION_SOWL_10 0 /* Sowl 1.0 */ @@ -632,12 +658,12 @@ #define AR_SREV_OWL_20_OR_LATER(_ah) \ ((AR_SREV_OWL(_ah) && \ - AH_PRIVATE((_ah))->ah_macRev >= AR_XSREV_REVISION_OWL_20) || \ + AH_PRIVATE((_ah))->ah_macRev >= AR_SREV_REVISION_OWL_20) || \ AH_PRIVATE((_ah))->ah_macVersion >= AR_XSREV_VERSION_HOWL) #define AR_SREV_OWL_22_OR_LATER(_ah) \ ((AR_SREV_OWL(_ah) && \ - AH_PRIVATE((_ah))->ah_macRev >= AR_XSREV_REVISION_OWL_22) || \ + AH_PRIVATE((_ah))->ah_macRev >= AR_SREV_REVISION_OWL_22) || \ AH_PRIVATE((_ah))->ah_macVersion >= AR_XSREV_VERSION_HOWL) /* Howl (AR9130) */ From ef1901a3c9deaf1c343419e1bb9c22613dfd9ea9 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sat, 7 May 2011 02:59:24 +0000 Subject: [PATCH 14/35] Change AR_SREV_OWL_{X}_OR_LATER to AR_SREV_5416_{X}_OR_LATER. For now, these are equivalent macros. AR_SREV_OWL{X}_OR_LATER will later change to exclude Howl (AR9130) in line with what the Atheros HAL does. This should not functionally change anything. Obtained from: Atheros --- sys/dev/ath/ath_hal/ar5416/ar5416_reset.c | 33 +++++++++-------------- sys/dev/ath/ath_hal/ar5416/ar5416desc.h | 4 +-- sys/dev/ath/ath_hal/ar9002/ar9280_olc.c | 2 +- sys/dev/ath/ath_hal/ar9002/ar9285_reset.c | 4 +-- 4 files changed, 18 insertions(+), 25 deletions(-) diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c b/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c index 12f30f1c8361..c4fae1750e30 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c @@ -1465,7 +1465,7 @@ ar5416GetRegChainOffset(struct ath_hal *ah, int i) { int regChainOffset; - if (AR_SREV_OWL_20_OR_LATER(ah) && + if (AR_SREV_5416_V20_OR_LATER(ah) && (AH5416(ah)->ah_rx_chainmask == 0x5 || AH5416(ah)->ah_tx_chainmask == 0x5) && (i != 0)) { /* Regs are swapped from chain 2 to 1 for 5416 2_0 with @@ -1518,7 +1518,7 @@ ar5416SetBoardValues(struct ath_hal *ah, const struct ieee80211_channel *chan) * XXX update */ - if ((i == 0) || AR_SREV_OWL_20_OR_LATER(ah)) + if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) ar5416SetDefGainValues(ah, pModal, eep, txRxAttenLocal, regChainOffset, i); } @@ -2217,7 +2217,7 @@ ar5416SetPowerCalTable(struct ath_hal *ah, struct ar5416eeprom *pEepData, &tMinCalPower, gainBoundaries, pdadcValues, numXpdGain); - if ((i == 0) || AR_SREV_OWL_20_OR_LATER(ah)) { + if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) { ar5416SetGainBoundariesClosedLoop(ah, i, pdGainOverlap_t2, gainBoundaries); } @@ -2329,7 +2329,7 @@ ar5416GetGainBoundariesAndPdadcs(struct ath_hal *ah, pPdGainBoundaries[i] = (uint16_t)AH_MIN(AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]); /* NB: only applies to owl 1.0 */ - if ((i == 0) && !AR_SREV_OWL_20_OR_LATER(ah) ) { + if ((i == 0) && !AR_SREV_5416_V20_OR_LATER(ah) ) { /* * fix the gain delta, but get a delta that can be applied to min to * keep the upper power values accurate, don't think max needs to @@ -2500,28 +2500,21 @@ ar5416OverrideIni(struct ath_hal *ah, const struct ieee80211_channel *chan) OS_REG_WRITE(ah, AR_PCU_MISC_MODE2, val); } - /* - * The AR5416 initvals have this already set to 0x11; AR9160 has - * the register set to 0x0. Figure out whether AR9130/AR9160 needs - * this before moving forward with it. - */ -#if 0 - /* Disable BB clock gating for AR5416v2, AR9130, AR9160 */ - if (AR_SREV_OWL_20_OR_LATER(ah) || AR_SREV_HOWL(ah) || AR_SREV_SOWL(ah)) { - /* - * Disable BB clock gating - * Necessary to avoid issues on AR5416 2.0 - */ - OS_REG_WRITE(ah, 0x9800 + (651 << 2), 0x11); - } -#endif - /* * Disable RIFS search on some chips to avoid baseband * hang issues. */ if (AR_SREV_HOWL(ah) || AR_SREV_SOWL(ah)) (void) ar5416SetRifsDelay(ah, AH_FALSE); + + if (!AR_SREV_5416_V20_OR_LATER(ah) || AR_SREV_MERLIN(ah)) + return; + + /* + * Disable BB clock gating + * Necessary to avoid issues on AR5416 2.0 + */ + OS_REG_WRITE(ah, 0x9800 + (651 << 2), 0x11); } struct ini { diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416desc.h b/sys/dev/ath/ath_hal/ar5416/ar5416desc.h index e52ded63551f..76f508025e6b 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416desc.h +++ b/sys/dev/ath/ath_hal/ar5416/ar5416desc.h @@ -387,11 +387,11 @@ struct ar5416_desc { #define RXSTATUS_OFFSET(ah) 4 #define RXSTATUS_NUMWORDS(ah) 9 #define RXSTATUS_RATE(ah, ads) \ - (AR_SREV_OWL_20_OR_LATER(ah) ? \ + (AR_SREV_5416_V20_OR_LATER(ah) ? \ MS((ads)->ds_rxstatus0, AR_RxRate) : \ ((ads)->ds_rxstatus3 >> 2) & 0xFF) #define RXSTATUS_DUPLICATE(ah, ads) \ - (AR_SREV_OWL_20_OR_LATER(ah) ? \ + (AR_SREV_5416_V20_OR_LATER(ah) ? \ MS((ads)->ds_rxstatus3, AR_Parallel40) : \ ((ads)->ds_rxstatus3 >> 10) & 0x1) #endif /* _ATH_AR5416_DESC_H_ */ diff --git a/sys/dev/ath/ath_hal/ar9002/ar9280_olc.c b/sys/dev/ath/ath_hal/ar9002/ar9280_olc.c index 8f9cf1d2df8e..da5e4ed7be0c 100644 --- a/sys/dev/ath/ath_hal/ar9002/ar9280_olc.c +++ b/sys/dev/ath/ath_hal/ar9002/ar9280_olc.c @@ -368,7 +368,7 @@ ar9280SetPowerCalTable(struct ath_hal *ah, struct ar5416eeprom *pEepData, gainBoundaries, numXpdGain, pdGainOverlap_t2, pwr_table_offset, &diff); - if ((i == 0) || AR_SREV_OWL_20_OR_LATER(ah)) { + if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) { /* Set gain boundaries for either open- or closed-loop TPC */ if (AR_SREV_MERLIN_20_OR_LATER(ah) && ath_hal_eepromGetFlag(ah, AR_EEP_OL_PWRCTRL)) diff --git a/sys/dev/ath/ath_hal/ar9002/ar9285_reset.c b/sys/dev/ath/ath_hal/ar9002/ar9285_reset.c index 4a7c83e56a0a..68c8ceaeaec3 100644 --- a/sys/dev/ath/ath_hal/ar9002/ar9285_reset.c +++ b/sys/dev/ath/ath_hal/ar9002/ar9285_reset.c @@ -648,7 +648,7 @@ ar9285SetPowerCalTable(struct ath_hal *ah, struct ar5416eeprom_4k *pEepData, &tMinCalPower, gainBoundaries, pdadcValues, numXpdGain); - if ((i == 0) || AR_SREV_OWL_20_OR_LATER(ah)) { + if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) { /* * Note the pdadc table may not start at 0 dBm power, could be * negative or greater than 0. Need to offset the power @@ -762,7 +762,7 @@ ar9285GetGainBoundariesAndPdadcs(struct ath_hal *ah, pPdGainBoundaries[i] = (uint16_t)AH_MIN(AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]); /* NB: only applies to owl 1.0 */ - if ((i == 0) && !AR_SREV_OWL_20_OR_LATER(ah) ) { + if ((i == 0) && !AR_SREV_5416_V20_OR_LATER(ah) ) { /* * fix the gain delta, but get a delta that can be applied to min to * keep the upper power values accurate, don't think max needs to From de53eba037c9ea78a160d264450535ff27097a7c Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Sat, 7 May 2011 04:40:44 +0000 Subject: [PATCH 15/35] Fix build. --- sys/dev/xl/if_xl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/xl/if_xl.c b/sys/dev/xl/if_xl.c index 228a3caa3b85..f1c1d02e5d26 100644 --- a/sys/dev/xl/if_xl.c +++ b/sys/dev/xl/if_xl.c @@ -2380,7 +2380,7 @@ xl_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count) } if (status & XL_STAT_STATSOFLOW) - xl_stats_update_locked(sc); + xl_stats_update(sc); } } return (rx_npkts); From de1334e8d7d107ebba627ceace9980230a92b10d Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sat, 7 May 2011 06:45:35 +0000 Subject: [PATCH 16/35] Some BB hang changes: * Add Howl (ar9130) to the list of chips that have DFS/BB/MAC hangs * Don't treat unknown BB hangs as fatal; ath9k/Atheros HAL don't treat it as such. * Add HAL_DEBUG_DFS to the debug fields in ath_hal/ah_debug.h The BB hang check simply loops over an observation register checking for a stuck state engine, but it can happen under high traffic conditions. Ath9k and the Atheros HAL simply log a debug message and continue. Private to FreeBSD: * Add HAL_DEBUG_HANG to the debug fields * Change the hang debugging to HAL_DEBUG_HANG rather than HAL_DEBUG_DFS like in the Atheros HAL. Obtained from: Atheros --- sys/dev/ath/ath_hal/ah_debug.h | 2 ++ sys/dev/ath/ath_hal/ar5416/ar5416_misc.c | 12 ++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/sys/dev/ath/ath_hal/ah_debug.h b/sys/dev/ath/ath_hal/ah_debug.h index f31eec04acdf..14dfe38aa3cd 100644 --- a/sys/dev/ath/ath_hal/ah_debug.h +++ b/sys/dev/ath/ath_hal/ah_debug.h @@ -45,6 +45,8 @@ enum { HAL_DEBUG_GPIO = 0x00040000, /* GPIO debugging */ HAL_DEBUG_INTERRUPT = 0x00080000, /* interrupt handling */ HAL_DEBUG_DIVERSITY = 0x00100000, /* diversity debugging */ + HAL_DEBUG_DFS = 0x00200000, /* DFS debugging */ + HAL_DEBUG_HANG = 0x00400000, /* BB/MAC hang debugging */ HAL_DEBUG_ANY = 0xffffffff }; diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c b/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c index 087bf92c789f..94e0dd65a184 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c @@ -283,9 +283,9 @@ ar5416GetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type, case HAL_CAP_BB_HANG: switch (capability) { case HAL_BB_HANG_RIFS: - return AR_SREV_SOWL(ah) ? HAL_OK : HAL_ENOTSUPP; + return (AR_SREV_HOWL(ah) || AR_SREV_SOWL(ah)) ? HAL_OK : HAL_ENOTSUPP; case HAL_BB_HANG_DFS: - return AR_SREV_SOWL(ah) ? HAL_OK : HAL_ENOTSUPP; + return (AR_SREV_HOWL(ah) || AR_SREV_SOWL(ah)) ? HAL_OK : HAL_ENOTSUPP; case HAL_BB_HANG_RX_CLEAR: return AR_SREV_MERLIN(ah) ? HAL_OK : HAL_ENOTSUPP; } @@ -293,7 +293,7 @@ ar5416GetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type, case HAL_CAP_MAC_HANG: return ((ah->ah_macVersion == AR_XSREV_VERSION_OWL_PCI) || (ah->ah_macVersion == AR_XSREV_VERSION_OWL_PCIE) || - AR_SREV_SOWL(ah)) ? + AR_SREV_HOWL(ah) || AR_SREV_SOWL(ah)) ? HAL_OK : HAL_ENOTSUPP; case HAL_CAP_DIVERSITY: /* disable classic fast diversity */ return HAL_ENXIO; @@ -466,7 +466,7 @@ ar5416DetectMacHang(struct ath_hal *ah) if (ar5416CompareDbgHang(ah, &mac_dbg, &hang_sig2)) return HAL_MAC_HANG_SIG2; - HALDEBUG(ah, HAL_DEBUG_ANY, "%s Found an unknown MAC hang signature " + HALDEBUG(ah, HAL_DEBUG_HANG, "%s Found an unknown MAC hang signature " "DMADBG_3=0x%x DMADBG_4=0x%x DMADBG_5=0x%x DMADBG_6=0x%x\n", __func__, mac_dbg.dma_dbg_3, mac_dbg.dma_dbg_4, mac_dbg.dma_dbg_5, mac_dbg.dma_dbg_6); @@ -515,13 +515,13 @@ ar5416DetectBBHang(struct ath_hal *ah) } for (i = 0; i < N(hang_list); i++) if ((hang_sig & hang_list[i].mask) == hang_list[i].val) { - HALDEBUG(ah, HAL_DEBUG_ANY, + HALDEBUG(ah, HAL_DEBUG_HANG, "%s BB hang, signature 0x%x, code 0x%x\n", __func__, hang_sig, hang_list[i].code); return hang_list[i].code; } - HALDEBUG(ah, HAL_DEBUG_ANY, "%s Found an unknown BB hang signature! " + HALDEBUG(ah, HAL_DEBUG_HANG, "%s Found an unknown BB hang signature! " "<0x806c>=0x%x\n", __func__, hang_sig); return HAL_BB_HANG_UNKNOWN; From b810285f242143dad58f76cf65f366a6efd42fa4 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sat, 7 May 2011 06:47:09 +0000 Subject: [PATCH 17/35] Add some comments about which HAL capabilities are currently FreeBSD specific. The Atheros HAL and FreeBSD HAL share the same capabilities up until HAL_CAP_11D, where things begin to diverge. I'll look at tidying these up soon. Obtained from: Atheros --- sys/dev/ath/ath_hal/ah.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sys/dev/ath/ath_hal/ah.h b/sys/dev/ath/ath_hal/ah.h index e234efa1ae35..946f63bb2b5e 100644 --- a/sys/dev/ath/ath_hal/ah.h +++ b/sys/dev/ath/ath_hal/ah.h @@ -109,6 +109,8 @@ typedef enum { HAL_CAP_TPC_ACK = 26, /* ack txpower with per-packet tpc */ HAL_CAP_TPC_CTS = 27, /* cts txpower with per-packet tpc */ HAL_CAP_11D = 28, /* 11d beacon support for changing cc */ + + /* The following are currently different IDs to the Atheros HAL */ HAL_CAP_INTMIT = 29, /* interference mitigation */ HAL_CAP_RXORN_FATAL = 30, /* HAL_INT_RXORN treated as fatal */ HAL_CAP_HT = 31, /* hardware can support HT */ @@ -124,6 +126,11 @@ typedef enum { HAL_CAP_HAS_PSPOLL = 41, /* hardware has ps-poll support */ HAL_CAP_RXDESC_SELFLINK = 42, /* support a self-linked tail RX descriptor */ HAL_CAP_GTXTO = 43, /* hardware supports global tx timeout */ + + /* The following are back to normal, shared with the Atheros HAL */ + + /* The following are private to the FreeBSD HAL (224 onward) */ + } HAL_CAPABILITY_TYPE; /* From 001ac28926d0e068a5764f0d39391de19c31d68c Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sat, 7 May 2011 06:52:04 +0000 Subject: [PATCH 18/35] Instead of returning an unknown mac/bb signature, just return 0. --- sys/dev/ath/ath_hal/ar5416/ar5416_misc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c b/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c index 94e0dd65a184..c6988b8941e5 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c @@ -471,7 +471,7 @@ ar5416DetectMacHang(struct ath_hal *ah) __func__, mac_dbg.dma_dbg_3, mac_dbg.dma_dbg_4, mac_dbg.dma_dbg_5, mac_dbg.dma_dbg_6); - return HAL_MAC_HANG_UNKNOWN; + return 0; } /* @@ -524,7 +524,7 @@ ar5416DetectBBHang(struct ath_hal *ah) HALDEBUG(ah, HAL_DEBUG_HANG, "%s Found an unknown BB hang signature! " "<0x806c>=0x%x\n", __func__, hang_sig); - return HAL_BB_HANG_UNKNOWN; + return 0; #undef N } #undef NUM_STATUS_READS From 3f581c18ec9827acc206180cd74fbac46fb78eb1 Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Sat, 7 May 2011 10:06:43 +0000 Subject: [PATCH 19/35] scsi_cd: silence READ_TOC errors in CDIOREADTOCHEADER ioctl An optical disk may not have a TOC (e.g. for blank media) and userland software may legitimately try to use CDIOREADTOCHEADER to find out about the TOC. Silence from: scsi@ MFC after: 10 days --- sys/cam/scsi/scsi_cd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/cam/scsi/scsi_cd.c b/sys/cam/scsi/scsi_cd.c index 3d81800a3632..c1951ffeefa2 100644 --- a/sys/cam/scsi/scsi_cd.c +++ b/sys/cam/scsi/scsi_cd.c @@ -2138,7 +2138,7 @@ cdioctl(struct disk *dp, u_long cmd, void *addr, int flag, struct thread *td) ("trying to do CDIOREADTOCHEADER\n")); error = cdreadtoc(periph, 0, 0, (u_int8_t *)th, - sizeof (*th), /*sense_flags*/0); + sizeof (*th), /*sense_flags*/SF_NO_PRINT); if (error) { free(th, M_SCSICD); cam_periph_unlock(periph); From ff98e4c51524e01de1452b7b26f8fed64043423d Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Sat, 7 May 2011 10:40:57 +0000 Subject: [PATCH 20/35] a whitespace nit MFC after: 4 days --- sys/boot/common/interp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/boot/common/interp.c b/sys/boot/common/interp.c index a9370d982200..57eb51caf621 100644 --- a/sys/boot/common/interp.c +++ b/sys/boot/common/interp.c @@ -105,7 +105,7 @@ interact(void) /* * Read our default configuration */ - if(include("/boot/loader.rc")!=CMD_OK) + if(include("/boot/loader.rc") != CMD_OK) include("/boot/boot.conf"); printf("\n"); /* From 3860fcc7f07c2d92b5e5a99d92a2cbd3081e8acf Mon Sep 17 00:00:00 2001 From: Kai Wang Date: Sat, 7 May 2011 10:44:08 +0000 Subject: [PATCH 21/35] * Rewrite ar.5 mannual page to better document ar(1) archive format. * Use more standard BSD license. Obtained from: elftoolchain --- share/man/man5/ar.5 | 491 ++++++++++++++++++++++++++------------------ 1 file changed, 292 insertions(+), 199 deletions(-) diff --git a/share/man/man5/ar.5 b/share/man/man5/ar.5 index dc802cee79c2..81bc7e60dfa3 100644 --- a/share/man/man5/ar.5 +++ b/share/man/man5/ar.5 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2007 Joseph Koshy. All rights reserved. +.\" Copyright (c) 2010 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions @@ -9,226 +9,319 @@ .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. .\" .\" $FreeBSD$ .\" -.Dd September 7, 2007 -.Dt AR 5 +.Dd November 28, 2010 .Os +.Dt AR 5 .Sh NAME .Nm ar -.Nd format of archives managed by ar(1) and ranlib(1) -.Sh SYNOPSIS -.In ar.h -.Sh DESCRIPTION -An archive managed by the +.Nd archive file format for .Xr ar 1 and .Xr ranlib 1 -utilities is a single file that stores the individual members of the -archive along with metadata for each member. -There are two major variants of the -.Xr ar 1 -archive format, the BSD variant and the SVR4/GNU variant. -Both variants are described by this manual page. -.Pp -The header file +.Sh SYNOPSIS .In ar.h -defines constants and structures used to describe the layout -of these archives. -.Ss Archive Layout +.Sh DESCRIPTION .Xr ar 1 -archives start with a string of magic bytes -.Qq !\en -(constant -.Dv ARMAG -in header -.In ar.h ) . -The content of the archive follows the magic bytes. -Each member stored in the archive is preceded by a fixed size -archive header that stores file permissions, last modification -time, the owner, and the group of the archived file. +archives are created and managed by the +.Xr ar 1 +and +.Xr ranlib 1 +utilities. +These archives are typically used during program development to +hold libraries of program objects. +An +.Xr ar 1 +archive is contained in a single operating system file. .Pp -Archive headers start at an even byte offset in the archive -file. -If the length of the preceding archive member was odd, then an extra -newline character -.Dq "\en" -is used as padding. +This manual page documents two variants of the +.Xr ar 1 +archive format: the BSD archive format, and the SVR4/GNU archive +format. .Pp -The archive header comprises six fixed-size ASCII strings followed -by a two character trailer (see -.Vt "struct ar_hdr" -in header file -.In ar.h Ns ): -.Bd -literal -struct ar_hdr { - char ar_name[16]; /* name */ - char ar_date[12]; /* modification time */ - char ar_uid[6]; /* user id */ - char ar_gid[6]; /* group id */ - char ar_mode[8]; /* octal file permissions */ - char ar_size[10]; /* size in bytes */ - char ar_fmag[2]; /* consistency check */ -}; -.Ed +In both variants the archive file starts with an identifying byte +sequence of the seven ASCII characters +.Sq Li "!" +followed by a ASCII linefeed character +.Po +see the constant +.Dq ARMAG +in the header file +.In ar.h +.Pc . .Pp -Unused characters in the header are filled with space (ASCII 20H) -characters. -Each field of the header abuts the next without additional padding. -.Pp -The members of the archive header are as follows: -.Bl -tag -width "Va ar_name" -compact -.It Va ar_date -This field holds the decimal representation of the -modification time, in seconds since the epoch, of the archive -member. -.It Va ar_fmag -This trailer field holds the two characters -.Qq `\en -(constant -.Dv ARFMAG -defined in header file -.In ar.h Ns ), -and is used for consistency checks. -.It Va ar_gid -This field holds the decimal representation of the numeric -user id of the creator of the member. -.It Va ar_mode -This field holds octal representation of the file permissions -for the member. -.It Va ar_name -This field holds the name of an archive member. -The usage of this field depends on the format variant: -.Bl -tag -width "SVR4/GNU" -compact -.It BSD -In the BSD variant, names that are shorter than 16 characters and -without embedded spaces are stored directly in this field. -If a name has an embedded space, or if it is longer than 16 -characters, then the string -.Qq "#1/" -followed by the decimal representation of the length of the file name -is placed in this field. -The actual file name is stored immediately after the archive header. -The content of the archive member follows the file name. +Archive members follow the initial identifying byte sequence. +Each archive member is prefixed by a fixed size header describing the +file attributes associated with the member. +.Ss "Archive Headers" +An archive header describes the file attributes for the archive member that +follows it. The -.Va ar_size -field of the header (see below) will then hold the sum of the size of -the file name and the size of the member. -.It SVR4/GNU -In the SVR4/GNU variant, names up to 15 characters in length are -stored directly in this field, and are terminated by a -.Qq / -(ASCII 2FH) character. -Names larger than 15 characters in length are stored in a special -archive string table member (see -.Sx "Archive String Table" -below), and the -.Va ar_name -field holds the string -.Qq "/" -followed by the decimal representation of the offset in the archive -string table of the actual name. -.El -.It Va ar_size -In the SVR4/GNU variant, this field holds the decimal representation -of actual size in bytes of the archived file. -In the BSD variant, for member names that use the -.Va ar_name -field directly, this field holds the decimal representation of the -actual size in bytes of the archived member. -For member names that use the extension mechanism described above, the -field will hold the sum of the sizes, in bytes, of the filename and the -archive member. -.It Va ar_uid -This field holds the decimal representation of the numeric -group id of the creator of the member. -.El -.Ss Archive Symbol Table -An archive may additionally contain an archive symbol table -used by the link editor, -.Xr ld 1 . -This symbol table has the member name -.Qq __.SYMDEF -in the BSD variant of the archive format, and the name -.Qq / -in the SVR4/GNU variant. +.Xr ar 5 +format only supports a limited number of attributes: the file name, +the file creation time stamp, the uid and gid of the creator, the file +mode and the file size. .Pp -The format of the symbol table depends on the format variant: -.Bl -tag -width "SVR4/GNU" -compact +Archive headers are placed at an even byte offset in the archive file. +If the data for an archive member ends at an odd byte offset, then a +padding byte with value 0x0A is used to position the next archive +header on an even byte offset. +.Pp +An archive header comprises the following fixed sized fields: +.Bl -tag -width "Li ar_name" +.It Ar ar_name +(16 bytes) The file name of the archive member. +The format of this field varies between the BSD and SVR4/GNU formats and +is described in more detail in the section +.Sx "Representing File Names" +below. +.It Ar ar_date +(12 bytes) The file modification time for the member in seconds since the +epoch, encoded as a decimal number. +.It Ar ar_uid +(6 bytes) The uid associated with the archive member, encoded as a +decimal number. +.It Ar ar_gid +(6 bytes) The gid associated with the archive member, encoded as a +decimal number. +.It Ar ar_mode +(8 bytes) The file mode for the archive member, encoded as an octal +number. +.It Ar ar_size +(10 bytes) In the SVR4/GNU archive format this field holds the size in +bytes of the archive member, encoded as a decimal number. +In the BSD archive format, for short file names, this field +holds the size in bytes of the archive member, encoded as a decimal +number. +For long file names +.Po +see +.Sx "Representing File Names" +below +.Pc , +the field contains the combined size of the +archive member and its file name, encoded as a decimal number. +.It Ar ar_fmag +(2 bytes) This field holds 2 bytes with values 0x96 and 0x0A +respectively, marking the end of the header. +.El +.Pp +Unused bytes in the fields of an archive header are set to the value +0x20. +.Ss "Representing File Names" +The BSD and SVR4/GNU variants use different schemes for encoding file +names for members. +.Bl -tag -width "SVR4/GNU" +.It "BSD" +File names that are upto 16 bytes long and which do not contain +embedded spaces are stored directly in the +.Ar ar_name +field of the archive header. +File names that are either longer than 16 bytes or which contain +embedded spaces are stored immediately after the archive header +and the +.Ar ar_name +field of the archive header is set to the string +.Dq "#1/" +followed by a decimal representation of the number of bytes needed for +the file name. +In addition, the +.Ar ar_size +field of the archive header is set to the decimal representation of +the combined sizes of the archive member and the file name. +The file contents of the member follows the file name without further +padding. +.Pp +As an example, if the file name for a member was +.Dq "A B" +and its contents was the string +.Dq "C D" , +then the +.Ar ar_name +field of the header would contain +.Dq Li "#1/3" , +the +.Ar ar_size +field of the header would contain +.Dq Li 6 , +and the bytes immediately following the header would be 0x41, 0x20, +0x42, 0x43, 0x20 and 0x44 +.Po +ASCII +.Dq "A BC D" +.Pc . +.It "SVR4/GNU" +File names that are upto 15 characters long are stored directly in the +.Ar ar_name +field of the header, terminated by a +.Dq Li / +character. +.Pp +If the file name is larger than would fit in space for the +.Ar ar_name +field, then the actual file name is kept in the archive +string table +.Po +see +.Sx "Archive String Tables" +below +.Pc , +and the decimal offset of the file name in the string table is stored +in the +.Ar ar_name +field, prefixed by a +.Dq Li / +character. +.Pp +As an example, if the real file name has been stored at offset 768 in +the archive string table, the +.Ar ar_name +field of the header will contain the string +.Dq /768 . +.El +.Ss "Special Archive Members" +The following archive members are special. +.Bl -tag -width indent +.It Dq Li / +In the SVR4/GNU variant of the archive format, the archive member with +name +.Dq Li / +denotes an archive symbol table. +If present, this member will be the very first member in the +archive. +.It Dq Li // +In the SVR4/GNU variant of the archive format, the archive member with +name +.Dq Li // +denotes the archive string table. +This special member is used to hold filenames that do not fit in the +file name field of the header +.Po +see +.Sx "Representing File Names" +above +.Pc . +If present, this member immediately follows the archive symbol table +if an archive symbol table is present, or is the first member otherwise. +.It Dq Li "__.SYMDEF" +This special member contains the archive symbol table in the BSD +variant of the archive format. +If present, this member will be the very first member in the +archive. +.El +.Ss "Archive String Tables" +An archive string table is used in the SVR4/GNU archive format to hold +file names that are too large to fit into the constraints of the +.Ar ar_name +field of the archive header. +An archive string table contains a sequence of file names. +Each file name in the archive string table is terminated by the +byte sequence 0x2F, 0x0A +.Po +the ASCII string +.Dq "/\en" +.Pc . +No padding is used to separate adjacent file names. +.Ss "Archive Symbol Tables" +Archive symbol tables are used to speed up link editing by providing a +mapping between the program symbols defined in the archive +and the corresponding archive members. +Archive symbol tables are managed by the +.Xr ranlib 1 +utility. +.Pp +The format of archive symbol tables is as follows: +.Bl -tag -width "SVR4/GNU" .It BSD -In the BSD variant, the symbol table has 4 parts encoded in -a machine dependent manner: -.Bl -enum -compact -.It -The first part is a binary value containing size in bytes of the -second part encoded as a C -.Dq long . -.It -The second part is a list of -.Vt struct ranlib -structures (see -.In ranlib.h Ns ). -Each ranlib structure describes one symbol and comprises of -two C -.Dq long -values. -The first -.Dq long -is a zero-based offset into the string table in the fourth part -for the symbol's name. -The second -.Dq long -is an offset from the beginning of the archive to the start -of the archive header for the member that defines the symbol. -.It -The third part is a binary value denoting the length of the -string table contained in the fourth part. -.It -The fourth part is a string table containing NUL-terminated -strings. +In the BSD archive format, the archive symbol table comprises +of two parts: a part containing an array of +.Vt "struct ranlib" +descriptors, followed by a part containing a symbol string table. +The sizes and layout of the structures that make up a BSD format +archive symbol table are machine dependent. +.Pp +The part containing +.Vt "struct ranlib" +descriptors begins with a field containing the size in bytes of the +array of +.Vt "struct ranlib" +descriptors encoded as a C +.Vt long +value. +.Pp +The array of +.Vt "struct ranlib" +descriptors follows the size field. +Each +.Vt "struct ranlib" +descriptor describes one symbol. +.Pp +A +.Vt "struct ranlib" +descriptor comprises two fields: +.Bl -tag -width "Ar ran_strx" -compact +.It Ar ran_strx +.Pq C Vt long +This field contains the zero-based offset of the symbol name in the +symbol string table. +.It Ar ran_off +.Pq C Vt long +This field is the file offset to the archive header for the archive +member defining the symbol. .El +.Pp +The part containing the symbol string table begins with a field +containing the size in bytes of the string table, encoded as a C +.Vt long +value. +This string table follows the size field, and contains +NUL-terminated strings for the symbols in the symbol table. .It SVR4/GNU -In the SVR4/GNU variant, the symbol table comprises of three parts -which follow each other without padding: -.Bl -enum -compact -.It -The first part comprises of a count of entries in the symbol table, -stored a 4 byte binary value in MSB first order. -.It -The next part is an array of 4 byte file offsets within the archive -to archive header for members that define the symbol in question. -Each offset in stored in MSB first order. -.It -The third part is a string table, that contains NUL-terminated -strings for the symbols in the symbol table. +In the SVR4/GNU archive format, the archive symbol table starts with a +4-byte binary value containing the number of entries contained in the +archive symbol table. +This count of entries is stored most significant byte first. +.Pp +Next, there are +.Ar count +4-byte numbers, each stored most significant byte first. +Each number is a binary offset to the archive header for the member in +the archive file for the corresponding symbol table entry. +.Pp +After the binary offset values, there are +.Ar count +NUL-terminated strings in sequence, holding the symbol names for +the corresponding symbol table entries. .El -.El -.Ss Archive String Table -In the SVR4/GNU variant of the +.Sh STANDARDS COMPLIANCE +The .Xr ar 1 -archive format, long file names are stored in a separate -archive string table and referenced from the archive header -for each member. -Each file name is terminated by the string -.Qq /\en . -The string table itself has a name of -.Qq // . +archive format is not currently specified by a standard. +.Pp +This manual page documents the +.Xr ar 1 +archive formats used by the +.Bx 4.4 +and +.Ux SVR4 +operating system releases. .Sh SEE ALSO .Xr ar 1 , +.Xr ld 1 , .Xr ranlib 1 , -.Xr archive 3 , .Xr elf 3 , -.Xr gelf 3 , -.Xr elf 5 +.Xr elf_getarsym 3 , +.Xr elf_rand 3 From 08a7f479dd4fcded774045e1526f8b4941959a3c Mon Sep 17 00:00:00 2001 From: Kai Wang Date: Sat, 7 May 2011 11:04:36 +0000 Subject: [PATCH 22/35] For zero-sized sections, set the `d_buf` field of the `Elf_Data` descriptor returned by `elf_rawdata()` to NULL. Obtained from: elftoolchain --- lib/libelf/elf_data.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/libelf/elf_data.c b/lib/libelf/elf_data.c index b8c10de0ac20..c34c4ad358b2 100644 --- a/lib/libelf/elf_data.c +++ b/lib/libelf/elf_data.c @@ -225,7 +225,8 @@ elf_rawdata(Elf_Scn *s, Elf_Data *d) if ((d = _libelf_allocate_data(s)) == NULL) return (NULL); - d->d_buf = sh_type == SHT_NOBITS ? NULL : e->e_rawfile + sh_offset; + d->d_buf = (sh_type == SHT_NOBITS || sh_size == 0) ? NULL : + e->e_rawfile + sh_offset; d->d_off = 0; d->d_align = sh_align; d->d_size = sh_size; From f93ef5516b31a2595118c571a9537f3144317681 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sat, 7 May 2011 11:05:16 +0000 Subject: [PATCH 23/35] Read in the extended regulatory domain flags so future code can use them. These describe FCC/Japan channel and DFS behaviour. The AR9285 and later chips don't set these bits in the eeprom, the correct behaviour is to just assume all five bits are enabled. --- sys/dev/ath/ath_hal/ah_internal.h | 1 + sys/dev/ath/ath_hal/ar5416/ar5416_attach.c | 2 ++ sys/dev/ath/ath_hal/ar9001/ar9130_attach.c | 3 +++ sys/dev/ath/ath_hal/ar9001/ar9160_attach.c | 2 ++ sys/dev/ath/ath_hal/ar9002/ar9280_attach.c | 2 ++ sys/dev/ath/ath_hal/ar9002/ar9285_attach.c | 5 +++++ 6 files changed, 15 insertions(+) diff --git a/sys/dev/ath/ath_hal/ah_internal.h b/sys/dev/ath/ath_hal/ah_internal.h index cefe28a1df48..63d484e52751 100644 --- a/sys/dev/ath/ath_hal/ah_internal.h +++ b/sys/dev/ath/ath_hal/ah_internal.h @@ -298,6 +298,7 @@ struct ath_hal_private { * State for regulatory domain handling. */ HAL_REG_DOMAIN ah_currentRD; /* EEPROM regulatory domain */ + HAL_REG_DOMAIN ah_currentRDext; /* EEPROM extended regdomain flags */ HAL_CHANNEL_INTERNAL ah_channels[AH_MAXCHAN]; /* private chan state */ u_int ah_nchan; /* valid items in ah_channels */ const struct regDomain *ah_rd2GHz; /* reg state for 2G band */ diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c b/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c index 0e91e9f56824..9fa93297359a 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c @@ -371,6 +371,8 @@ ar5416Attach(uint16_t devid, HAL_SOFTC sc, /* Read Reg Domain */ AH_PRIVATE(ah)->ah_currentRD = ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, AH_NULL); + AH_PRIVATE(ah)->ah_currentRDext = + ath_hal_eepromGet(ah, AR_EEP_REGDMN_1, AH_NULL); /* * ah_miscMode is populated by ar5416FillCapabilityInfo() diff --git a/sys/dev/ath/ath_hal/ar9001/ar9130_attach.c b/sys/dev/ath/ath_hal/ar9001/ar9130_attach.c index 11c988fadd06..4d1f28aa1613 100644 --- a/sys/dev/ath/ath_hal/ar9001/ar9130_attach.c +++ b/sys/dev/ath/ath_hal/ar9001/ar9130_attach.c @@ -236,6 +236,9 @@ ar9130Attach(uint16_t devid, HAL_SOFTC sc, /* Read Reg Domain */ AH_PRIVATE(ah)->ah_currentRD = ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, AH_NULL); + AH_PRIVATE(ah)->ah_currentRDext = + ath_hal_eepromGet(ah, AR_EEP_REGDMN_1, AH_NULL); + /* * ah_miscMode is populated by ar5416FillCapabilityInfo() diff --git a/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c b/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c index 689ef7f31de9..93009defd45c 100644 --- a/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c +++ b/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c @@ -241,6 +241,8 @@ ar9160Attach(uint16_t devid, HAL_SOFTC sc, /* Read Reg Domain */ AH_PRIVATE(ah)->ah_currentRD = ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, AH_NULL); + AH_PRIVATE(ah)->ah_currentRDext = + ath_hal_eepromGet(ah, AR_EEP_REGDMN_1, AH_NULL); /* * ah_miscMode is populated by ar5416FillCapabilityInfo() diff --git a/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c b/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c index 2ea0c3d5c31b..fca380167b4c 100644 --- a/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c +++ b/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c @@ -325,6 +325,8 @@ ar9280Attach(uint16_t devid, HAL_SOFTC sc, /* Read Reg Domain */ AH_PRIVATE(ah)->ah_currentRD = ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, AH_NULL); + AH_PRIVATE(ah)->ah_currentRDext = + ath_hal_eepromGet(ah, AR_EEP_REGDMN_1, AH_NULL); /* * ah_miscMode is populated by ar5416FillCapabilityInfo() diff --git a/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c b/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c index 93406f2b0f32..9a07836e5e98 100644 --- a/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c +++ b/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c @@ -284,6 +284,11 @@ ar9285Attach(uint16_t devid, HAL_SOFTC sc, /* Read Reg Domain */ AH_PRIVATE(ah)->ah_currentRD = ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, AH_NULL); + /* + * For Kite and later chipsets, the following bits are not + * programmed in EEPROM and so are set as enabled always. + */ + AH_PRIVATE(ah)->ah_currentRDext = AR9285_RDEXT_DEFAULT; /* * ah_miscMode is populated by ar5416FillCapabilityInfo() From 816c20393743590d7e57cf1b32e9e07a1c14dcf7 Mon Sep 17 00:00:00 2001 From: Jaakko Heinonen Date: Sat, 7 May 2011 11:10:58 +0000 Subject: [PATCH 24/35] Add WITNESS_WARN() to getenv() to explicitly note that the function may sleep. This helps to expose bugs when the requested environment variable doesn't exist. --- sys/kern/kern_environment.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/kern/kern_environment.c b/sys/kern/kern_environment.c index 73551f4b00d6..ce8e778feb66 100644 --- a/sys/kern/kern_environment.c +++ b/sys/kern/kern_environment.c @@ -310,6 +310,7 @@ getenv(const char *name) int len; if (dynamic_kenv) { + WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, "getenv"); mtx_lock(&kenv_lock); cp = _getenv_dynamic(name, NULL); if (cp != NULL) { From b8331e4264c7b9fc52fd2c95cb0b2ae0d625083e Mon Sep 17 00:00:00 2001 From: Kai Wang Date: Sat, 7 May 2011 11:29:48 +0000 Subject: [PATCH 25/35] Document the behavior of `elf_getdata()` and `elf_rawdata()` with zero-sized ELF sections. Obtained from: elftoolchain --- lib/libelf/elf_getdata.3 | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/libelf/elf_getdata.3 b/lib/libelf/elf_getdata.3 index 6a5ef39ed204..59e0ef6a05ea 100644 --- a/lib/libelf/elf_getdata.3 +++ b/lib/libelf/elf_getdata.3 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2006,2008,2010 Joseph Koshy. All rights reserved. +.\" Copyright (c) 2006,2008,2010-2011 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions @@ -23,7 +23,7 @@ .\" .\" $FreeBSD$ .\" -.Dd April 30, 2010 +.Dd January 26, 2011 .Dt ELF_GETDATA 3 .Os .Sh NAME @@ -142,9 +142,10 @@ always returns .Vt Elf_Data structures of type .Dv ELF_T_BYTE . -.Ss Special handling of SHT_NOBITS sections +.Ss Special handling of zero-sized and SHT_NOBITS sections For sections of type -.Dv SHT_NOBITS , +.Dv SHT_NOBITS, +and for zero-sized sections, the functions .Fn elf_getdata and From d96fd0763765fe1f684d6ae0ab9d731786226697 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sat, 7 May 2011 12:27:25 +0000 Subject: [PATCH 26/35] Don't use MWAIT for short sleeps under XEN, as it was before r212541. This fixes panic during boot in PV mode on Xen 3.2. --- sys/i386/i386/machdep.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c index bfb96e909f12..265a5c42a1f6 100644 --- a/sys/i386/i386/machdep.c +++ b/sys/i386/i386/machdep.c @@ -1359,6 +1359,7 @@ cpu_idle(int busy) if (mp_grab_cpu_hlt()) return; #endif +#ifndef XEN /* If we are busy - try to use fast methods. */ if (busy) { if ((cpu_feature2 & CPUID2_MON) && idle_mwait) { @@ -1367,7 +1368,6 @@ cpu_idle(int busy) } } -#ifndef XEN /* If we have time - switch timers into idle mode. */ if (!busy) { critical_enter(); @@ -1395,8 +1395,8 @@ cpu_idle(int busy) cpu_activeclock(); critical_exit(); } -#endif out: +#endif CTR2(KTR_SPARE2, "cpu_idle(%d) at %d done", busy, curcpu); } From b657b11d8d64cbf2de4c0f5b4ce368f22d3e4795 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sat, 7 May 2011 13:08:48 +0000 Subject: [PATCH 27/35] Update the ext channel cycpwr threshold 1 register for the extension channel when the channel is HT/40. The new ANI code (primarily for the AR9300/AR9400) in ath9k sets this register but the ANI code for the previous 11n chips didn't set this. Unlike ath9k, only set this for HT/40 channels. Obtained From: ath9k --- sys/dev/ath/ath_hal/ar5416/ar5416_ani.c | 6 ++++++ sys/dev/ath/ath_hal/ar5416/ar5416phy.h | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c b/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c index 0ea3034ed37d..3a8f7859b43f 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c @@ -296,6 +296,12 @@ ar5416AniControl(struct ath_hal *ah, HAL_ANI_CMD cmd, int param) } OS_REG_RMW_FIELD(ah, AR_PHY_TIMING5, AR_PHY_TIMING5_CYCPWR_THR1, params->cycPwrThr1[level]); + + /* Only set the ext channel cycpwr_thr1 field for ht/40 */ + if (IEEE80211_IS_CHAN_HT40(AH_PRIVATE(ah)->ah_curchan)) + OS_REG_RMW_FIELD(ah, AR_PHY_EXT_CCA, + AR_PHY_EXT_TIMING5_CYCPWR_THR1, params->cycPwrThr1[level]); + if (level > aniState->spurImmunityLevel) ahp->ah_stats.ast_ani_spurup++; else if (level < aniState->spurImmunityLevel) diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416phy.h b/sys/dev/ath/ath_hal/ar5416/ar5416phy.h index efe509f2c85a..fc02886b9d6a 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416phy.h +++ b/sys/dev/ath/ath_hal/ar5416/ar5416phy.h @@ -100,6 +100,13 @@ #define AR_PHY_EXT_MINCCA_PWR_S 23 #define AR_PHY_EXT_CCA_THRESH62 0x007F0000 #define AR_PHY_EXT_CCA_THRESH62_S 16 +/* + * This duplicates AR_PHY_EXT_CCA_CYCPWR_THR1; it reads more like + * an ANI register this way. + */ +#define AR_PHY_EXT_TIMING5_CYCPWR_THR1 0x0000FE00 +#define AR_PHY_EXT_TIMING5_CYCPWR_THR1_S 9 + #define AR9280_PHY_EXT_MINCCA_PWR 0x01FF0000 #define AR9280_PHY_EXT_MINCCA_PWR_S 16 From 4fe5d78a0f5965ce189cb60b8ec3e992bbb95cb9 Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Sat, 7 May 2011 13:57:30 +0000 Subject: [PATCH 28/35] a whitespace nit Reminder from: kib MFC after: 4 days --- sys/boot/common/interp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/boot/common/interp.c b/sys/boot/common/interp.c index 57eb51caf621..de4bd9ab9d4e 100644 --- a/sys/boot/common/interp.c +++ b/sys/boot/common/interp.c @@ -105,7 +105,7 @@ interact(void) /* * Read our default configuration */ - if(include("/boot/loader.rc") != CMD_OK) + if (include("/boot/loader.rc") != CMD_OK) include("/boot/boot.conf"); printf("\n"); /* From 4c244ed25565cc6b4ab0939f3a4e85ac14875a7d Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Sat, 7 May 2011 14:32:16 +0000 Subject: [PATCH 29/35] sh: Add UTF-8 support to ${#var}. If the current locale uses UTF-8, ${#var} counts codepoints (more precisely, bytes b with (b & 0xc0) != 0x80). --- bin/sh/expand.c | 16 +++++++++++++--- tools/regression/bin/sh/expansion/length7.0 | 14 ++++++++++++++ tools/regression/bin/sh/expansion/length8.0 | 14 ++++++++++++++ 3 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 tools/regression/bin/sh/expansion/length7.0 create mode 100644 tools/regression/bin/sh/expansion/length8.0 diff --git a/bin/sh/expand.c b/bin/sh/expand.c index c343977eab76..dcef74ea13aa 100644 --- a/bin/sh/expand.c +++ b/bin/sh/expand.c @@ -665,6 +665,7 @@ evalvar(char *p, int flag) int special; int startloc; int varlen; + int varlenb; int easy; int quotes = flag & (EXP_FULL | EXP_CASE | EXP_REDIR); @@ -712,8 +713,15 @@ again: /* jump here after setting a variable with ${var=text} */ if (special) { varvalue(var, varflags & VSQUOTE, subtype, flag); if (subtype == VSLENGTH) { - varlen = expdest - stackblock() - startloc; - STADJUST(-varlen, expdest); + varlenb = expdest - stackblock() - startloc; + varlen = varlenb; + if (localeisutf8) { + val = stackblock() + startloc; + for (;val != expdest; val++) + if ((*val & 0xC0) == 0x80) + varlen--; + } + STADJUST(-varlenb, expdest); } } else { char const *syntax = (varflags & VSQUOTE) ? DQSYNTAX @@ -721,7 +729,9 @@ again: /* jump here after setting a variable with ${var=text} */ if (subtype == VSLENGTH) { for (;*val; val++) - varlen++; + if (!localeisutf8 || + (*val & 0xC0) != 0x80) + varlen++; } else { if (quotes) diff --git a/tools/regression/bin/sh/expansion/length7.0 b/tools/regression/bin/sh/expansion/length7.0 new file mode 100644 index 000000000000..b79b11616c15 --- /dev/null +++ b/tools/regression/bin/sh/expansion/length7.0 @@ -0,0 +1,14 @@ +# $FreeBSD$ + +unset LC_ALL +LC_CTYPE=en_US.UTF-8 +export LC_CTYPE + +# a umlaut +s=$(printf '\303\244') +# euro sign +s=$s$(printf '\342\202\254') +# some sort of 't' outside BMP +s=$s$(printf '\360\235\225\245') +set -- "$s" +[ ${#s} = 3 ] && [ ${#1} = 3 ] diff --git a/tools/regression/bin/sh/expansion/length8.0 b/tools/regression/bin/sh/expansion/length8.0 new file mode 100644 index 000000000000..3cc6c15e7ece --- /dev/null +++ b/tools/regression/bin/sh/expansion/length8.0 @@ -0,0 +1,14 @@ +# $FreeBSD$ + +unset LC_ALL +LC_CTYPE=en_US.ISO8859-1 +export LC_CTYPE + +# a umlaut +s=$(printf '\303\244') +# euro sign +s=$s$(printf '\342\202\254') +# some sort of 't' outside BMP +s=$s$(printf '\360\235\225\245') +set -- "$s" +[ ${#s} = 9 ] && [ ${#1} = 9 ] From 26e8415d1d15762bad55c33fa8985ce29c0843ff Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sat, 7 May 2011 15:30:23 +0000 Subject: [PATCH 30/35] Do a HAL capabilities sync pass based on the Atheros HAL. * Shuffle some of the capability numbers around to match the Atheros HAL capability IDs, just for consistency. * Add some new capabilities to FreeBSD from the Atheros HAL which will be be shortly used when new chipsets are added (HAL SGI-20 support is for Kiwi/AR9287 support); for TX aggregation (MBSSID aggregate support, WDS aggregation support); CST/GTT support for carrier sense/TX timeout. --- sys/dev/ath/ath_hal/ah.c | 38 ++++++++++++++--- sys/dev/ath/ath_hal/ah.h | 47 ++++++++++++++-------- sys/dev/ath/ath_hal/ah_internal.h | 3 +- sys/dev/ath/ath_hal/ar5416/ar5416_attach.c | 5 ++- sys/dev/ath/ath_hal/ar5416/ar5416_misc.c | 2 - sys/dev/ath/ath_hal/ar9001/ar9130_attach.c | 8 ++++ sys/dev/ath/ath_hal/ar9001/ar9160_attach.c | 3 ++ sys/dev/ath/ath_hal/ar9002/ar9280_attach.c | 5 ++- sys/dev/ath/ath_hal/ar9002/ar9285_attach.c | 5 ++- 9 files changed, 87 insertions(+), 29 deletions(-) diff --git a/sys/dev/ath/ath_hal/ah.c b/sys/dev/ath/ath_hal/ah.c index 11d0ee8bf7e5..2cc1e08391eb 100644 --- a/sys/dev/ath/ath_hal/ah.c +++ b/sys/dev/ath/ath_hal/ah.c @@ -585,19 +585,49 @@ ath_hal_getcapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type, return HAL_ENOTSUPP; case HAL_CAP_11D: return HAL_OK; - case HAL_CAP_RXORN_FATAL: /* HAL_INT_RXORN treated as fatal */ - return AH_PRIVATE(ah)->ah_rxornIsFatal ? HAL_OK : HAL_ENOTSUPP; + case HAL_CAP_HT: return pCap->halHTSupport ? HAL_OK : HAL_ENOTSUPP; + case HAL_CAP_GTXTO: + return pCap->halGTTSupport ? HAL_OK : HAL_ENOTSUPP; + case HAL_CAP_FAST_CC: + return pCap->halFastCCSupport ? HAL_OK : HAL_ENOTSUPP; case HAL_CAP_TX_CHAINMASK: /* mask of TX chains supported */ *result = pCap->halTxChainMask; return HAL_OK; case HAL_CAP_RX_CHAINMASK: /* mask of RX chains supported */ *result = pCap->halRxChainMask; return HAL_OK; + case HAL_CAP_NUM_GPIO_PINS: + *result = pCap->halNumGpioPins; + return HAL_OK; + case HAL_CAP_CST: + return pCap->halCSTSupport ? HAL_OK : HAL_ENOTSUPP; + case HAL_CAP_RTS_AGGR_LIMIT: + *result = pCap->halRtsAggrLimit; + return HAL_OK; + case HAL_CAP_4ADDR_AGGR: + return pCap->hal4AddrAggrSupport ? HAL_OK : HAL_ENOTSUPP; + case HAL_CAP_AUTO_SLEEP: + return pCap->halAutoSleepSupport ? HAL_OK : HAL_ENOTSUPP; + case HAL_CAP_MBSSID_AGGR_SUPPORT: + return pCap->halMbssidAggrSupport ? HAL_OK : HAL_ENOTSUPP; + case HAL_CAP_SPLIT_4KB_TRANS: /* hardware handles descriptors straddling 4k page boundary */ + return pCap->hal4kbSplitTransSupport ? HAL_OK : HAL_ENOTSUPP; + case HAL_CAP_REG_FLAG: + *result = AH_PRIVATE(ah)->ah_currentRDext; + return HAL_OK; + case HAL_CAP_BT_COEX: + return pCap->halBtCoexSupport ? HAL_OK : HAL_ENOTSUPP; + case HAL_CAP_HT20_SGI: + return pCap->halHTSGI20Support ? HAL_OK : HAL_ENOTSUPP; case HAL_CAP_RXTSTAMP_PREC: /* rx desc tstamp precision (bits) */ *result = pCap->halTstampPrecision; return HAL_OK; + + /* FreeBSD-specific entries for now */ + case HAL_CAP_RXORN_FATAL: /* HAL_INT_RXORN treated as fatal */ + return AH_PRIVATE(ah)->ah_rxornIsFatal ? HAL_OK : HAL_ENOTSUPP; case HAL_CAP_INTRMASK: /* mask of supported interrupts */ *result = pCap->halIntrMask; return HAL_OK; @@ -614,10 +644,6 @@ ath_hal_getcapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type, default: return HAL_ENOTSUPP; } - case HAL_CAP_SPLIT_4KB_TRANS: /* hardware handles descriptors straddling 4k page boundary */ - return pCap->hal4kbSplitTransSupport ? HAL_OK : HAL_ENOTSUPP; - case HAL_CAP_HAS_PSPOLL: /* hardware has ps-poll support */ - return pCap->halHasPsPollSupport ? HAL_OK : HAL_ENOTSUPP; case HAL_CAP_RXDESC_SELFLINK: /* hardware supports self-linked final RX descriptors correctly */ return pCap->halHasRxSelfLinkedTail ? HAL_OK : HAL_ENOTSUPP; default: diff --git a/sys/dev/ath/ath_hal/ah.h b/sys/dev/ath/ath_hal/ah.h index 946f63bb2b5e..85790e12101f 100644 --- a/sys/dev/ath/ath_hal/ah.h +++ b/sys/dev/ath/ath_hal/ah.h @@ -110,27 +110,40 @@ typedef enum { HAL_CAP_TPC_CTS = 27, /* cts txpower with per-packet tpc */ HAL_CAP_11D = 28, /* 11d beacon support for changing cc */ - /* The following are currently different IDs to the Atheros HAL */ - HAL_CAP_INTMIT = 29, /* interference mitigation */ - HAL_CAP_RXORN_FATAL = 30, /* HAL_INT_RXORN treated as fatal */ - HAL_CAP_HT = 31, /* hardware can support HT */ - HAL_CAP_TX_CHAINMASK = 32, /* mask of TX chains supported */ - HAL_CAP_RX_CHAINMASK = 33, /* mask of RX chains supported */ - HAL_CAP_RXTSTAMP_PREC = 34, /* rx desc tstamp precision (bits) */ - HAL_CAP_BB_HANG = 35, /* can baseband hang */ - HAL_CAP_MAC_HANG = 36, /* can MAC hang */ - HAL_CAP_INTRMASK = 37, /* bitmask of supported interrupts */ - HAL_CAP_BSSIDMATCH = 38, /* hardware has disable bssid match */ - HAL_CAP_STREAMS = 39, /* how many 802.11n spatial streams are available */ - HAL_CAP_SPLIT_4KB_TRANS = 40, /* hardware supports descriptors straddling a 4k page boundary */ - HAL_CAP_HAS_PSPOLL = 41, /* hardware has ps-poll support */ - HAL_CAP_RXDESC_SELFLINK = 42, /* support a self-linked tail RX descriptor */ - HAL_CAP_GTXTO = 43, /* hardware supports global tx timeout */ + HAL_CAP_HT = 30, /* hardware can support HT */ + HAL_CAP_GTXTO = 31, /* hardware supports global tx timeout */ + HAL_CAP_FAST_CC = 32, /* hardware supports fast channel change */ + HAL_CAP_TX_CHAINMASK = 33, /* mask of TX chains supported */ + HAL_CAP_RX_CHAINMASK = 34, /* mask of RX chains supported */ + HAL_CAP_NUM_GPIO_PINS = 36, /* number of GPIO pins */ - /* The following are back to normal, shared with the Atheros HAL */ + HAL_CAP_CST = 38, /* hardware supports carrier sense timeout */ + + HAL_CAP_RTS_AGGR_LIMIT = 42, /* aggregation limit with RTS */ + HAL_CAP_4ADDR_AGGR = 43, /* hardware is capable of 4addr aggregation */ + + HAL_CAP_AUTO_SLEEP = 48, /* hardware can go to network sleep + automatically after waking up to receive TIM */ + HAL_CAP_MBSSID_AGGR_SUPPORT = 49, /* Support for mBSSID Aggregation */ + HAL_CAP_SPLIT_4KB_TRANS = 50, /* hardware supports descriptors straddling a 4k page boundary */ + HAL_CAP_REG_FLAG = 51, /* Regulatory domain flags */ + + HAL_CAP_BT_COEX = 60, /* hardware is capable of bluetooth coexistence */ + + HAL_CAP_HT20_SGI = 96, /* hardware supports HT20 short GI */ + + HAL_CAP_RXTSTAMP_PREC = 100, /* rx desc tstamp precision (bits) */ /* The following are private to the FreeBSD HAL (224 onward) */ + HAL_CAP_INTMIT = 229, /* interference mitigation */ + HAL_CAP_RXORN_FATAL = 230, /* HAL_INT_RXORN treated as fatal */ + HAL_CAP_BB_HANG = 235, /* can baseband hang */ + HAL_CAP_MAC_HANG = 236, /* can MAC hang */ + HAL_CAP_INTRMASK = 237, /* bitmask of supported interrupts */ + HAL_CAP_BSSIDMATCH = 238, /* hardware has disable bssid match */ + HAL_CAP_STREAMS = 239, /* how many 802.11n spatial streams are available */ + HAL_CAP_RXDESC_SELFLINK = 242, /* support a self-linked tail RX descriptor */ } HAL_CAPABILITY_TYPE; /* diff --git a/sys/dev/ath/ath_hal/ah_internal.h b/sys/dev/ath/ath_hal/ah_internal.h index 63d484e52751..c4ffe745f850 100644 --- a/sys/dev/ath/ath_hal/ah_internal.h +++ b/sys/dev/ath/ath_hal/ah_internal.h @@ -184,6 +184,7 @@ typedef struct { halChanHalfRate : 1, halChanQuarterRate : 1, halHTSupport : 1, + halHTSGI20Support : 1, halRfSilentSupport : 1, halHwPhyCounterSupport : 1, halWowSupport : 1, @@ -197,13 +198,13 @@ typedef struct { halCSTSupport : 1, halRifsRxSupport : 1, halRifsTxSupport : 1, + hal4AddrAggrSupport : 1, halExtChanDfsSupport : 1, halForcePpmSupport : 1, halEnhancedPmSupport : 1, halMbssidAggrSupport : 1, halBssidMatchSupport : 1, hal4kbSplitTransSupport : 1, - halHasPsPollSupport : 1, halHasRxSelfLinkedTail : 1; uint32_t halWirelessModes; uint16_t halTotalQueues; diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c b/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c index 9fa93297359a..9ef09844bf17 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c @@ -812,6 +812,7 @@ ar5416FillCapabilityInfo(struct ath_hal *ah) pCap->halBssIdMaskSupport = AH_TRUE; pCap->halMcastKeySrchSupport = AH_FALSE; pCap->halTsfAddSupport = AH_TRUE; + pCap->hal4AddrAggrSupport = AH_FALSE; /* Broken in Owl */ if (ath_hal_eepromGet(ah, AR_EEP_MAXQCU, &val) == HAL_OK) pCap->halTotalQueues = val; @@ -862,10 +863,12 @@ ar5416FillCapabilityInfo(struct ath_hal *ah) pCap->halTxStreams = 2; pCap->halRxStreams = 2; pCap->halRtsAggrLimit = 8*1024; /* Owl 2.0 limit */ - pCap->halMbssidAggrSupport = AH_TRUE; + pCap->halMbssidAggrSupport = AH_FALSE; /* Broken on Owl */ pCap->halForcePpmSupport = AH_TRUE; pCap->halEnhancedPmSupport = AH_TRUE; pCap->halBssidMatchSupport = AH_TRUE; + pCap->halGTTSupport = AH_TRUE; + pCap->halCSTSupport = AH_TRUE; if (ath_hal_eepromGetFlag(ah, AR_EEP_RFKILL) && ath_hal_eepromGet(ah, AR_EEP_RFSILENT, &ahpriv->ah_rfsilent) == HAL_OK) { diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c b/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c index c6988b8941e5..3ed44c72c523 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c @@ -278,8 +278,6 @@ ar5416GetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type, uint32_t capability, uint32_t *result) { switch (type) { - case HAL_CAP_GTXTO: - return HAL_OK; /* All AR5416+ supports Global TX Timeout */ case HAL_CAP_BB_HANG: switch (capability) { case HAL_BB_HANG_RIFS: diff --git a/sys/dev/ath/ath_hal/ar9001/ar9130_attach.c b/sys/dev/ath/ath_hal/ar9001/ar9130_attach.c index 4d1f28aa1613..49a5f5e5f632 100644 --- a/sys/dev/ath/ath_hal/ar9001/ar9130_attach.c +++ b/sys/dev/ath/ath_hal/ar9001/ar9130_attach.c @@ -290,6 +290,14 @@ ar9130FillCapabilityInfo(struct ath_hal *ah) pCap->halRtsAggrLimit = 64*1024; /* 802.11n max */ pCap->halExtChanDfsSupport = AH_TRUE; pCap->halAutoSleepSupport = AH_FALSE; /* XXX? */ + /* + * MBSSID aggregation is broken in Howl v1.1, v1.2, v1.3 + * and works fine in v1.4. + * XXX todo, enable it for v1.4. + */ + pCap->halMbssidAggrSupport = AH_FALSE; + pCap->hal4AddrAggrSupport = AH_TRUE; + return AH_TRUE; } diff --git a/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c b/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c index 93009defd45c..0b6472b7331f 100644 --- a/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c +++ b/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c @@ -294,6 +294,9 @@ ar9160FillCapabilityInfo(struct ath_hal *ah) pCap->halRtsAggrLimit = 64*1024; /* 802.11n max */ pCap->halExtChanDfsSupport = AH_TRUE; pCap->halAutoSleepSupport = AH_FALSE; /* XXX? */ + pCap->halMbssidAggrSupport = AH_TRUE; + pCap->hal4AddrAggrSupport = AH_TRUE; + /* AR9160 is a 2x2 stream device */ pCap->halTxStreams = 2; pCap->halRxStreams = 2; diff --git a/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c b/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c index fca380167b4c..5e44cc573e11 100644 --- a/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c +++ b/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c @@ -784,8 +784,11 @@ ar9280FillCapabilityInfo(struct ath_hal *ah) pCap->hal4kbSplitTransSupport = AH_FALSE; /* Disable this so Block-ACK works correctly */ pCap->halHasRxSelfLinkedTail = AH_FALSE; + pCap->halMbssidAggrSupport = AH_TRUE; + pCap->hal4AddrAggrSupport = AH_TRUE; + if (AR_SREV_MERLIN_20_OR_LATER(ah)) - pCap->halHasPsPollSupport = AH_TRUE; + pCap->halPSPollBroken = AH_FALSE; pCap->halRxStbcSupport = 1; pCap->halTxStbcSupport = 1; diff --git a/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c b/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c index 9a07836e5e98..7aebc960a35b 100644 --- a/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c +++ b/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c @@ -395,8 +395,11 @@ ar9285FillCapabilityInfo(struct ath_hal *ah) pCap->hal4kbSplitTransSupport = AH_FALSE; /* Disable this so Block-ACK works correctly */ pCap->halHasRxSelfLinkedTail = AH_FALSE; + pCap->halMbssidAggrSupport = AH_TRUE; + pCap->hal4AddrAggrSupport = AH_TRUE; + if (AR_SREV_KITE_12_OR_LATER(ah)) - pCap->halHasPsPollSupport = AH_TRUE; + pCap->halPSPollBroken = AH_FALSE; pCap->halRxStbcSupport = 1; pCap->halTxStbcSupport = 1; From 955c139ed441c4085c608514c7d721484dcb2ca2 Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Sat, 7 May 2011 16:28:23 +0000 Subject: [PATCH 31/35] Minor usbdump update: - Use memcpy() instead of bcopy(). - Replace all asserts() by standard error messages. - Update usage(). MFC after: 7 days --- usr.sbin/usbdump/usbdump.c | 128 ++++++++++++++++++++----------------- 1 file changed, 68 insertions(+), 60 deletions(-) diff --git a/usr.sbin/usbdump/usbdump.c b/usr.sbin/usbdump/usbdump.c index 4eb709b450a5..f32104af9a68 100644 --- a/usr.sbin/usbdump/usbdump.c +++ b/usr.sbin/usbdump/usbdump.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include #include @@ -49,6 +48,8 @@ #include #include #include +#include +#include struct usbcap { int fd; /* fd for /dev/usbpf */ @@ -408,9 +409,15 @@ write_packets(struct usbcap *p, const uint8_t *data, const int datalen) int ret; ret = write(p->wfd, &len, sizeof(int)); - assert(ret == sizeof(int)); + if (ret != sizeof(int)) { + err(EXIT_FAILURE, "Could not write length " + "field of USB data payload"); + } ret = write(p->wfd, data, datalen); - assert(ret == datalen); + if (ret != datalen) { + err(EXIT_FAILURE, "Could not write " + "complete USB data payload"); + } } static void @@ -423,14 +430,16 @@ read_file(struct usbcap *p) while ((ret = read(p->rfd, &datalen, sizeof(int))) == sizeof(int)) { datalen = le32toh(datalen); data = malloc(datalen); - assert(data != NULL); + if (data == NULL) + errx(EX_SOFTWARE, "Out of memory."); ret = read(p->rfd, data, datalen); - assert(ret == datalen); + if (ret != datalen) { + err(EXIT_FAILURE, "Could not read complete " + "USB data payload"); + } print_packets(data, datalen); free(data); } - if (ret == -1) - fprintf(stderr, "read: %s\n", strerror(errno)); } static void @@ -466,14 +475,27 @@ init_rfile(struct usbcap *p) p->rfd = open(r_arg, O_RDONLY); if (p->rfd < 0) { - fprintf(stderr, "open: %s (%s)\n", r_arg, strerror(errno)); - exit(EXIT_FAILURE); + err(EXIT_FAILURE, "Could not open " + "'%s' for read", r_arg); } ret = read(p->rfd, &uf, sizeof(uf)); - assert(ret == sizeof(uf)); - assert(le32toh(uf.magic) == USBCAP_FILEHDR_MAGIC); - assert(uf.major == 0); - assert(uf.minor == 2); + if (ret != sizeof(uf)) { + err(EXIT_FAILURE, "Could not read USB capture " + "file header"); + } + if (le32toh(uf.magic) != USBCAP_FILEHDR_MAGIC) { + errx(EX_SOFTWARE, "Invalid magic field(0x%08x) " + "in USB capture file header.", + (unsigned int)le32toh(uf.magic)); + } + if (uf.major != 0) { + errx(EX_SOFTWARE, "Invalid major version(%d) " + "field in USB capture file header.", (int)uf.major); + } + if (uf.minor != 2) { + errx(EX_SOFTWARE, "Invalid minor version(%d) " + "field in USB capture file header.", (int)uf.minor); + } } static void @@ -484,15 +506,18 @@ init_wfile(struct usbcap *p) p->wfd = open(w_arg, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR); if (p->wfd < 0) { - fprintf(stderr, "open: %s (%s)\n", w_arg, strerror(errno)); - exit(EXIT_FAILURE); + err(EXIT_FAILURE, "Could not open " + "'%s' for write", r_arg); } - bzero(&uf, sizeof(uf)); + memset(&uf, 0, sizeof(uf)); uf.magic = htole32(USBCAP_FILEHDR_MAGIC); uf.major = 0; uf.minor = 2; ret = write(p->wfd, (const void *)&uf, sizeof(uf)); - assert(ret == sizeof(uf)); + if (ret != sizeof(uf)) { + err(EXIT_FAILURE, "Could not write " + "USB capture header"); + } } static void @@ -501,13 +526,13 @@ usage(void) #define FMT " %-14s %s\n" fprintf(stderr, "usage: usbdump [options]\n"); - fprintf(stderr, FMT, "-i ifname", "Listen on USB bus interface"); - fprintf(stderr, FMT, "-r file", "Read the raw packets from file"); - fprintf(stderr, FMT, "-s snaplen", "Snapshot bytes from each packet"); - fprintf(stderr, FMT, "-v", "Increases the verbose level"); - fprintf(stderr, FMT, "-w file", "Write the raw packets to file"); + fprintf(stderr, FMT, "-i ", "Listen on USB bus interface"); + fprintf(stderr, FMT, "-r ", "Read the raw packets from file"); + fprintf(stderr, FMT, "-s ", "Snapshot bytes from each packet"); + fprintf(stderr, FMT, "-v", "Increase the verbose level"); + fprintf(stderr, FMT, "-w ", "Write the raw packets to file"); #undef FMT - exit(1); + exit(EX_USAGE); } int @@ -525,7 +550,7 @@ main(int argc, char *argv[]) int fd, o; const char *optstring; - bzero(&uc, sizeof(struct usbcap)); + memset(&uc, 0, sizeof(struct usbcap)); optstring = "i:r:s:vw:"; while ((o = getopt(argc, argv, optstring)) != -1) { @@ -565,20 +590,15 @@ main(int argc, char *argv[]) } p->fd = fd = open("/dev/bpf", O_RDONLY); - if (p->fd < 0) { - fprintf(stderr, "(no devices found)\n"); - return (EXIT_FAILURE); - } + if (p->fd < 0) + err(EXIT_FAILURE, "Could not open BPF device"); + + if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0) + err(EXIT_FAILURE, "BIOCVERSION ioctl failed"); - if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0) { - fprintf(stderr, "BIOCVERSION: %s\n", strerror(errno)); - return (EXIT_FAILURE); - } if (bv.bv_major != BPF_MAJOR_VERSION || - bv.bv_minor < BPF_MINOR_VERSION) { - fprintf(stderr, "kernel bpf filter out of date"); - return (EXIT_FAILURE); - } + bv.bv_minor < BPF_MINOR_VERSION) + errx(EXIT_FAILURE, "Kernel BPF filter out of date"); /* USB transfers can be greater than 64KByte */ v = 1U << 16; @@ -592,22 +612,16 @@ main(int argc, char *argv[]) if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) >= 0) break; } - if (v == 0) { - fprintf(stderr, "BIOCSBLEN: %s: No buffer size worked", i_arg); - return (EXIT_FAILURE); - } + if (v == 0) + errx(EXIT_FAILURE, "No buffer size worked."); - if (ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) { - fprintf(stderr, "BIOCGBLEN: %s", strerror(errno)); - return (EXIT_FAILURE); - } + if (ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) + err(EXIT_FAILURE, "BIOCGBLEN ioctl failed"); p->bufsize = v; p->buffer = (uint8_t *)malloc(p->bufsize); - if (p->buffer == NULL) { - fprintf(stderr, "malloc: %s", strerror(errno)); - return (EXIT_FAILURE); - } + if (p->buffer == NULL) + errx(EX_SOFTWARE, "Out of memory."); /* XXX no read filter rules yet so at this moment accept everything */ total_insn.code = (u_short)(BPF_RET | BPF_K); @@ -617,27 +631,21 @@ main(int argc, char *argv[]) total_prog.bf_len = 1; total_prog.bf_insns = &total_insn; - if (ioctl(p->fd, BIOCSETF, (caddr_t)&total_prog) < 0) { - fprintf(stderr, "BIOCSETF: %s", strerror(errno)); - return (EXIT_FAILURE); - } + if (ioctl(p->fd, BIOCSETF, (caddr_t)&total_prog) < 0) + err(EXIT_FAILURE, "BIOCSETF ioctl failed"); /* 1 second read timeout */ tv.tv_sec = 1; tv.tv_usec = 0; - if (ioctl(p->fd, BIOCSRTIMEOUT, (caddr_t)&tv) < 0) { - fprintf(stderr, "BIOCSRTIMEOUT: %s", strerror(errno)); - return (EXIT_FAILURE); - } + if (ioctl(p->fd, BIOCSRTIMEOUT, (caddr_t)&tv) < 0) + err(EXIT_FAILURE, "BIOCSRTIMEOUT ioctl failed"); (void)signal(SIGINT, handle_sigint); do_loop(p); - if (ioctl(fd, BIOCGSTATS, (caddr_t)&us) < 0) { - fprintf(stderr, "BIOCGSTATS: %s", strerror(errno)); - return (EXIT_FAILURE); - } + if (ioctl(fd, BIOCGSTATS, (caddr_t)&us) < 0) + err(EXIT_FAILURE, "BIOCGSTATS ioctl failed"); /* XXX what's difference between pkt_captured and us.us_recv? */ printf("\n"); From 4ad5f8c23f0039b5b9135b871ee5387be35429d1 Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Sat, 7 May 2011 16:32:59 +0000 Subject: [PATCH 32/35] Add new USB ID. Submitted by: Dmitry Luhtionov MFC after: 7 days --- sys/dev/usb/usbdevs | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs index 4ff89673e1df..60d791cb0055 100644 --- a/sys/dev/usb/usbdevs +++ b/sys/dev/usb/usbdevs @@ -1565,6 +1565,7 @@ product FALCOM TWIST 0x0001 USB GSM/GPRS Modem /* FEIYA products */ product FEIYA 5IN1 0x1132 5-in-1 Card Reader +product FEIYA AC110 0x6300 AC-110 Card Reader /* Fiberline */ product FIBERLINE WL430U 0x6003 WL-430U From a63f3da5b265ab80c255c415f4df8b6591bc9580 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Sat, 7 May 2011 17:23:13 +0000 Subject: [PATCH 33/35] In pmap_kextract(), return the physical address for PBVM virtual addresses as well (incl. the PBVM page table). --- sys/ia64/ia64/pmap.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/sys/ia64/ia64/pmap.c b/sys/ia64/ia64/pmap.c index a1606422d0de..5f10ad6ff79a 100644 --- a/sys/ia64/ia64/pmap.c +++ b/sys/ia64/ia64/pmap.c @@ -65,6 +65,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -1206,6 +1207,8 @@ vm_paddr_t pmap_kextract(vm_offset_t va) { struct ia64_lpte *pte; + uint64_t *pbvm_pgtbl; + u_int idx; KASSERT(va >= VM_MAXUSER_ADDRESS, ("Must be kernel VA")); @@ -1222,6 +1225,25 @@ pmap_kextract(vm_offset_t va) return (pmap_present(pte) ? pmap_ppn(pte)|(va&PAGE_MASK) : 0); } + /* PBVM page table. */ + if (va >= IA64_PBVM_PGTBL + bootinfo->bi_pbvm_pgtblsz); + return (0); + if (va >= IA64_PBVM_PGTBL) + return (va - IA64_PBVM_PGTBL) + bootinfo->bi_pbvm_pgtbl; + + /* PBVM. */ + if (va >= IA64_PBVM_BASE) { + pbvm_pgtbl = (void *)IA64_PBVM_PGTBL; + idx = (va - IA64_PBVM_BASE) >> IA64_PBVM_PAGE_SHIFT; + if (idx >= (bootinfo->bi_pbvm_pgtblsz >> 3)) + return (0); + if ((pbvm_pgtbl[idx] & PTE_PRESENT) == 0) + return (0); + return ((pbvm_pgtbl[idx] & PTE_PPN_MASK) + + (va & IA64_PBVM_PAGE_MASK)); + } + + printf("XXX: %s: va=%#lx\n", __func__, va); return (0); } From 852bee75b7799d1d73a2e03aee637657b3dc37d2 Mon Sep 17 00:00:00 2001 From: Jaakko Heinonen Date: Sat, 7 May 2011 17:59:07 +0000 Subject: [PATCH 34/35] To avoid duplicated warning, move WITNESS_WARN() added in r221597 to the branch which doesn't call malloc(9). Suggested by: kib --- sys/kern/kern_environment.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/kern/kern_environment.c b/sys/kern/kern_environment.c index ce8e778feb66..41a9fa8e8310 100644 --- a/sys/kern/kern_environment.c +++ b/sys/kern/kern_environment.c @@ -310,7 +310,6 @@ getenv(const char *name) int len; if (dynamic_kenv) { - WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, "getenv"); mtx_lock(&kenv_lock); cp = _getenv_dynamic(name, NULL); if (cp != NULL) { @@ -322,6 +321,8 @@ getenv(const char *name) } else { mtx_unlock(&kenv_lock); ret = NULL; + WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, + "getenv"); } } else ret = _getenv_static(name); From af8223ba6d5786e1e84f0bd3ba006c83d15f035c Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sat, 7 May 2011 18:42:41 +0000 Subject: [PATCH 35/35] Fix the IS_5416 checks to actually work correctly. I've verified that my AR5416 revision 2.2 (minor revision 0x0A) now matches the correct checks. --- sys/dev/ath/ath_hal/ar5416/ar5416reg.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416reg.h b/sys/dev/ath/ath_hal/ar5416/ar5416reg.h index e67e13a2da70..983a9568c969 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416reg.h +++ b/sys/dev/ath/ath_hal/ar5416/ar5416reg.h @@ -601,9 +601,9 @@ #define AR_RAD2122_SREV_MAJOR 0xf0 /* Fowl: 2+5G/2x2 */ /* Test macro for owl 1.0 */ -#define IS_5416V1(_ah) (AR_SREV_OWL((ah)) && (_ah)->ah_macRev == AR_SREV_REVISION_OWL_10) -#define IS_5416V2(_ah) (AR_SREV_OWL((ah)) && (_ah)->ah_macRev >= AR_SREV_REVISION_OWL_20) -#define IS_5416V2_2(_ah) (AR_SREV_OWL((ah)) && (_ah)->ah_macRev == AR_SREV_REVISION_OWL_22) +#define IS_5416V1(_ah) (AR_SREV_OWL((_ah)) && AH_PRIVATE((_ah))->ah_macRev == AR_SREV_REVISION_OWL_10) +#define IS_5416V2(_ah) (AR_SREV_OWL((_ah)) && AH_PRIVATE((_ah))->ah_macRev >= AR_SREV_REVISION_OWL_20) +#define IS_5416V2_2(_ah) (AR_SREV_OWL((_ah)) && AH_PRIVATE((_ah))->ah_macRev == AR_SREV_REVISION_OWL_22) /* Misc; compatibility with Atheros HAL */ #define AR_SREV_5416_V20_OR_LATER(_ah) (AR_SREV_HOWL((_ah)) || AR_SREV_OWL_20_OR_LATER(_ah))