diff options
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/cxgbe/t4_main.c | 7 | ||||
-rw-r--r-- | sys/dev/ic/ns16550.h | 2 | ||||
-rw-r--r-- | sys/dev/iscsi/iscsi.c | 99 | ||||
-rw-r--r-- | sys/dev/iscsi/iscsi.h | 3 | ||||
-rw-r--r-- | sys/dev/puc/pucdata.c | 154 | ||||
-rw-r--r-- | sys/dev/rtwn/if_rtwn.c | 2 | ||||
-rw-r--r-- | sys/dev/sfxge/common/efsys.h | 1 | ||||
-rw-r--r-- | sys/dev/ti/if_ti.c | 4 | ||||
-rw-r--r-- | sys/dev/vt/hw/ofwfb/ofwfb.c | 25 |
9 files changed, 235 insertions, 62 deletions
diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c index 0d00a77..21d0cb8 100644 --- a/sys/dev/cxgbe/t4_main.c +++ b/sys/dev/cxgbe/t4_main.c @@ -3642,6 +3642,9 @@ setup_intr_handlers(struct adapter *sc) #ifdef DEV_NETMAP struct sge_nm_rxq *nm_rxq; #endif +#ifdef RSS + int nbuckets = rss_getnumbuckets(); +#endif /* * Setup interrupts. @@ -3700,6 +3703,10 @@ setup_intr_handlers(struct adapter *sc) t4_intr, rxq, s); if (rc != 0) return (rc); +#ifdef RSS + bus_bind_intr(sc->dev, irq->res, + rss_getcpu(q % nbuckets)); +#endif irq++; rid++; vi->nintr++; diff --git a/sys/dev/ic/ns16550.h b/sys/dev/ic/ns16550.h index 33a7dd1..e4c714f 100644 --- a/sys/dev/ic/ns16550.h +++ b/sys/dev/ic/ns16550.h @@ -205,6 +205,7 @@ * requires ACR[6]. */ #define com_icr 5 /* index control register (R/W) */ +#define REG_ICR com_icr /* * 16950 register #7. It is the same as com_scr except it has a different @@ -220,6 +221,7 @@ */ #define com_acr 0 /* additional control register (R/W) */ +#define REG_ACR com_acr #define ACR_ASE 0x80 /* ASR/RFL/TFL enable */ #define ACR_ICRE 0x40 /* ICR enable */ #define ACR_TLE 0x20 /* TTL/RTL enable */ diff --git a/sys/dev/iscsi/iscsi.c b/sys/dev/iscsi/iscsi.c index d792746..a9bdaf7 100644 --- a/sys/dev/iscsi/iscsi.c +++ b/sys/dev/iscsi/iscsi.c @@ -98,6 +98,9 @@ SYSCTL_INT(_kern_iscsi, OID_AUTO, maxtags, CTLFLAG_RWTUN, &maxtags, static int fail_on_disconnection = 0; SYSCTL_INT(_kern_iscsi, OID_AUTO, fail_on_disconnection, CTLFLAG_RWTUN, &fail_on_disconnection, 0, "Destroy CAM SIM on connection failure"); +static int fail_on_shutdown = 1; +SYSCTL_INT(_kern_iscsi, OID_AUTO, fail_on_shutdown, CTLFLAG_RWTUN, + &fail_on_shutdown, 0, "Fail disconnected sessions on shutdown"); static MALLOC_DEFINE(M_ISCSI, "iSCSI", "iSCSI initiator"); static uma_zone_t iscsi_outstanding_zone; @@ -417,8 +420,6 @@ iscsi_maintenance_thread_terminate(struct iscsi_session *is) sc = is->is_softc; sx_xlock(&sc->sc_lock); - TAILQ_REMOVE(&sc->sc_sessions, is, is_next); - sx_xunlock(&sc->sc_lock); icl_conn_close(is->is_conn); callout_drain(&is->is_callout); @@ -450,6 +451,9 @@ iscsi_maintenance_thread_terminate(struct iscsi_session *is) #ifdef ICL_KERNEL_PROXY cv_destroy(&is->is_login_cv); #endif + TAILQ_REMOVE(&sc->sc_sessions, is, is_next); + sx_xunlock(&sc->sc_lock); + ISCSI_SESSION_DEBUG(is, "terminated"); free(is, M_ISCSI); @@ -473,12 +477,7 @@ iscsi_maintenance_thread(void *arg) STAILQ_EMPTY(&is->is_postponed)) cv_wait(&is->is_maintenance_cv, &is->is_lock); - if (is->is_reconnecting) { - ISCSI_SESSION_UNLOCK(is); - iscsi_maintenance_thread_reconnect(is); - continue; - } - + /* Terminate supersedes reconnect. */ if (is->is_terminating) { ISCSI_SESSION_UNLOCK(is); iscsi_maintenance_thread_terminate(is); @@ -486,6 +485,12 @@ iscsi_maintenance_thread(void *arg) return; } + if (is->is_reconnecting) { + ISCSI_SESSION_UNLOCK(is); + iscsi_maintenance_thread_reconnect(is); + continue; + } + iscsi_session_send_postponed(is); ISCSI_SESSION_UNLOCK(is); } @@ -605,6 +610,11 @@ iscsi_callout(void *context) return; out: + if (is->is_terminating) { + ISCSI_SESSION_UNLOCK(is); + return; + } + ISCSI_SESSION_UNLOCK(is); if (reconnect_needed) @@ -2326,30 +2336,62 @@ iscsi_poll(struct cam_sim *sim) } static void -iscsi_shutdown(struct iscsi_softc *sc) +iscsi_terminate_sessions(struct iscsi_softc *sc) { struct iscsi_session *is; - /* - * Trying to reconnect during system shutdown would lead to hang. - */ - fail_on_disconnection = 1; + sx_slock(&sc->sc_lock); + TAILQ_FOREACH(is, &sc->sc_sessions, is_next) + iscsi_session_terminate(is); + while(!TAILQ_EMPTY(&sc->sc_sessions)) { + ISCSI_DEBUG("waiting for sessions to terminate"); + cv_wait(&sc->sc_cv, &sc->sc_lock); + } + ISCSI_DEBUG("all sessions terminated"); + sx_sunlock(&sc->sc_lock); +} + +static void +iscsi_shutdown_pre(struct iscsi_softc *sc) +{ + struct iscsi_session *is; + + if (!fail_on_shutdown) + return; /* * If we have any sessions waiting for reconnection, request * maintenance thread to fail them immediately instead of waiting * for reconnect timeout. + * + * This prevents LUNs with mounted filesystems that are supported + * by disconnected iSCSI sessions from hanging, however it will + * fail all queued BIOs. */ + ISCSI_DEBUG("forcing failing all disconnected sessions due to shutdown"); + + fail_on_disconnection = 1; + sx_slock(&sc->sc_lock); TAILQ_FOREACH(is, &sc->sc_sessions, is_next) { ISCSI_SESSION_LOCK(is); - if (is->is_waiting_for_iscsid) + if (!is->is_connected) { + ISCSI_SESSION_DEBUG(is, "force failing disconnected session early"); iscsi_session_reconnect(is); + } ISCSI_SESSION_UNLOCK(is); } sx_sunlock(&sc->sc_lock); } +static void +iscsi_shutdown_post(struct iscsi_softc *sc) +{ + + ISCSI_DEBUG("removing all sessions due to shutdown"); + iscsi_terminate_sessions(sc); +} + static int iscsi_load(void) { @@ -2372,8 +2414,16 @@ iscsi_load(void) } sc->sc_cdev->si_drv1 = sc; - sc->sc_shutdown_eh = EVENTHANDLER_REGISTER(shutdown_pre_sync, - iscsi_shutdown, sc, SHUTDOWN_PRI_DEFAULT-1); + sc->sc_shutdown_pre_eh = EVENTHANDLER_REGISTER(shutdown_pre_sync, + iscsi_shutdown_pre, sc, SHUTDOWN_PRI_FIRST); + /* + * shutdown_post_sync needs to run after filesystem shutdown and before + * CAM shutdown - otherwise when rebooting with an iSCSI session that is + * disconnected but has outstanding requests, dashutdown() will hang on + * cam_periph_runccb(). + */ + sc->sc_shutdown_post_eh = EVENTHANDLER_REGISTER(shutdown_post_sync, + iscsi_shutdown_post, sc, SHUTDOWN_PRI_DEFAULT - 1); return (0); } @@ -2381,7 +2431,6 @@ iscsi_load(void) static int iscsi_unload(void) { - struct iscsi_session *is, *tmp; if (sc->sc_cdev != NULL) { ISCSI_DEBUG("removing device node"); @@ -2389,18 +2438,12 @@ iscsi_unload(void) ISCSI_DEBUG("device node removed"); } - if (sc->sc_shutdown_eh != NULL) - EVENTHANDLER_DEREGISTER(shutdown_pre_sync, sc->sc_shutdown_eh); + if (sc->sc_shutdown_pre_eh != NULL) + EVENTHANDLER_DEREGISTER(shutdown_pre_sync, sc->sc_shutdown_pre_eh); + if (sc->sc_shutdown_post_eh != NULL) + EVENTHANDLER_DEREGISTER(shutdown_post_sync, sc->sc_shutdown_post_eh); - sx_slock(&sc->sc_lock); - TAILQ_FOREACH_SAFE(is, &sc->sc_sessions, is_next, tmp) - iscsi_session_terminate(is); - while(!TAILQ_EMPTY(&sc->sc_sessions)) { - ISCSI_DEBUG("waiting for sessions to terminate"); - cv_wait(&sc->sc_cv, &sc->sc_lock); - } - ISCSI_DEBUG("all sessions terminated"); - sx_sunlock(&sc->sc_lock); + iscsi_terminate_sessions(sc); uma_zdestroy(iscsi_outstanding_zone); sx_destroy(&sc->sc_lock); diff --git a/sys/dev/iscsi/iscsi.h b/sys/dev/iscsi/iscsi.h index fd52fa8..a2475f4 100644 --- a/sys/dev/iscsi/iscsi.h +++ b/sys/dev/iscsi/iscsi.h @@ -131,7 +131,8 @@ struct iscsi_softc { TAILQ_HEAD(, iscsi_session) sc_sessions; struct cv sc_cv; unsigned int sc_last_session_id; - eventhandler_tag sc_shutdown_eh; + eventhandler_tag sc_shutdown_pre_eh; + eventhandler_tag sc_shutdown_post_eh; }; #endif /* !ISCSI_H */ diff --git a/sys/dev/puc/pucdata.c b/sys/dev/puc/pucdata.c index b953146..d8ca258 100644 --- a/sys/dev/puc/pucdata.c +++ b/sys/dev/puc/pucdata.c @@ -42,12 +42,16 @@ __FBSDID("$FreeBSD$"); #include <machine/bus.h> #include <sys/rman.h> +#include <dev/ic/ns16550.h> + +#include <dev/pci/pcireg.h> #include <dev/pci/pcivar.h> #include <dev/puc/puc_bus.h> #include <dev/puc/puc_cfg.h> #include <dev/puc/puc_bfe.h> +static puc_config_f puc_config_advantech; static puc_config_f puc_config_amc; static puc_config_f puc_config_diva; static puc_config_f puc_config_exar; @@ -691,10 +695,25 @@ const struct puc_cfg puc_pci_devices[] = { .config_function = puc_config_exar_pcie }, + /* + * The Advantech PCI-1602 Rev. A use the first two ports of an Oxford + * Semiconductor OXuPCI954. Note these boards have a hardware bug in + * that they drive the RS-422/485 transmitters after power-on until a + * driver initalizes the UARTs. + */ { 0x13fe, 0x1600, 0x1602, 0x0002, - "Advantech PCI-1602", + "Advantech PCI-1602 Rev. A", DEFAULT_RCLK * 8, PUC_PORT_2S, 0x10, 0, 8, + .config_function = puc_config_advantech + }, + + /* Advantech PCI-1602 Rev. B1/PCI-1603 are also based on OXuPCI952. */ + { 0x13fe, 0xa102, 0x13fe, 0xa102, + "Advantech 2-port PCI (PCI-1602 Rev. B1/PCI-1603)", + DEFAULT_RCLK * 8, + PUC_PORT_2S, 0x10, 4, 0, + .config_function = puc_config_advantech }, { 0x1407, 0x0100, 0xffff, 0, @@ -1256,6 +1275,92 @@ const struct puc_cfg puc_pci_devices[] = { }; static int +puc_config_advantech(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port, + intptr_t *res __unused) +{ + const struct puc_cfg *cfg; + struct resource *cres; + struct puc_bar *bar; + device_t cdev, dev; + bus_size_t off; + int base, crtype, fixed, high, i, oxpcie; + uint8_t acr, func, mask; + + if (cmd != PUC_CFG_SETUP) + return (ENXIO); + + base = fixed = oxpcie = 0; + crtype = SYS_RES_IOPORT; + acr = mask = 0x0; + func = high = 1; + off = 0x60; + + cfg = sc->sc_cfg; + switch (cfg->subvendor) { + case 0x13fe: + switch (cfg->device) { + case 0xa102: + high = 0; + break; + default: + break; + } + default: + break; + } + if (fixed == 1) + goto setup; + + dev = sc->sc_dev; + cdev = pci_find_dbsf(pci_get_domain(dev), pci_get_bus(dev), + pci_get_slot(dev), func); + if (cdev == NULL) { + device_printf(dev, "could not find config function\n"); + return (ENXIO); + } + + i = PCIR_BAR(0); + cres = bus_alloc_resource_any(cdev, crtype, &i, RF_ACTIVE); + if (cres == NULL) { + device_printf(dev, "could not allocate config resource\n"); + return (ENXIO); + } + + if (oxpcie == 0) { + mask = bus_read_1(cres, off); + if (pci_get_function(dev) == 1) + base = 4; + } + + setup: + for (i = 0; i < sc->sc_nports; ++i) { + device_printf(dev, "port %d: ", i); + bar = puc_get_bar(sc, cfg->rid + i * cfg->d_rid); + if (bar == NULL) { + printf("could not get BAR\n"); + continue; + } + + if (fixed == 0) { + if ((mask & (1 << (base + i))) == 0) { + acr = 0; + printf("RS-232\n"); + } else { + acr = (high == 1 ? 0x18 : 0x10); + printf("RS-422/RS-485, active-%s auto-DTR\n", + high == 1 ? "high" : "low"); + } + } + + bus_write_1(bar->b_res, REG_SPR, REG_ACR); + bus_write_1(bar->b_res, REG_ICR, acr); + } + + bus_release_resource(cdev, crtype, rman_get_rid(cres), cres); + return (0); +} + +static int puc_config_amc(struct puc_softc *sc __unused, enum puc_cfg_cmd cmd, int port, intptr_t *res) { @@ -1360,24 +1465,17 @@ puc_config_quatech(struct puc_softc *sc, enum puc_cfg_cmd cmd, bar = puc_get_bar(sc, cfg->rid); if (bar == NULL) return (ENXIO); - /* Set DLAB in the LCR register of UART 0. */ - bus_write_1(bar->b_res, 3, 0x80); - /* Write 0 to the SPR register of UART 0. */ - bus_write_1(bar->b_res, 7, 0); - /* Read back the contents of the SPR register of UART 0. */ - v0 = bus_read_1(bar->b_res, 7); - /* Write a specific value to the SPR register of UART 0. */ - bus_write_1(bar->b_res, 7, 0x80 + -cfg->clock); - /* Read back the contents of the SPR register of UART 0. */ - v1 = bus_read_1(bar->b_res, 7); - /* Clear DLAB in the LCR register of UART 0. */ - bus_write_1(bar->b_res, 3, 0); - /* Save the two values read-back from the SPR register. */ + bus_write_1(bar->b_res, REG_LCR, LCR_DLAB); + bus_write_1(bar->b_res, REG_SPR, 0); + v0 = bus_read_1(bar->b_res, REG_SPR); + bus_write_1(bar->b_res, REG_SPR, 0x80 + -cfg->clock); + v1 = bus_read_1(bar->b_res, REG_SPR); + bus_write_1(bar->b_res, REG_LCR, 0); sc->sc_cfg_data = (v0 << 8) | v1; if (v0 == 0 && v1 == 0x80 + -cfg->clock) { /* * The SPR register echoed the two values written - * by us. This means that the SPAD jumper is set. + * by us. This means that the SPAD jumper is set. */ device_printf(sc->sc_dev, "warning: extra features " "not usable -- SPAD compatibility enabled\n"); @@ -1385,7 +1483,7 @@ puc_config_quatech(struct puc_softc *sc, enum puc_cfg_cmd cmd, } if (v0 != 0) { /* - * The first value doesn't match. This can only mean + * The first value doesn't match. This can only mean * that the SPAD jumper is not set and that a non- * standard fixed clock multiplier jumper is set. */ @@ -1399,8 +1497,8 @@ puc_config_quatech(struct puc_softc *sc, enum puc_cfg_cmd cmd, return (0); } /* - * The first value matched, but the second didn't. We know - * that the SPAD jumper is not set. We also know that the + * The first value matched, but the second didn't. We know + * that the SPAD jumper is not set. We also know that the * clock rate multiplier is software controlled *and* that * we just programmed it to the maximum allowed. */ @@ -1415,8 +1513,8 @@ puc_config_quatech(struct puc_softc *sc, enum puc_cfg_cmd cmd, /* * XXX With the SPAD jumper applied, there's no * easy way of knowing if there's also a clock - * rate multiplier jumper installed. Let's hope - * not... + * rate multiplier jumper installed. Let's hope + * not ... */ *res = DEFAULT_RCLK; } else if (v0 == 0) { @@ -1678,15 +1776,15 @@ puc_config_oxford_pcie(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port, case PUC_CFG_GET_NPORTS: /* * Check if we are being called from puc_bfe_attach() - * or puc_bfe_probe(). If puc_bfe_probe(), we cannot - * puc_get_bar(), so we return a value of 16. This has cosmetic - * side-effects at worst; in PUC_CFG_GET_DESC, - * (int)sc->sc_cfg_data will not contain the true number of - * ports in PUC_CFG_GET_DESC, but we are not implementing that - * call for this device family anyway. + * or puc_bfe_probe(). If puc_bfe_probe(), we cannot + * puc_get_bar(), so we return a value of 16. This has + * cosmetic side-effects at worst; in PUC_CFG_GET_DESC, + * sc->sc_cfg_data will not contain the true number of + * ports in PUC_CFG_GET_DESC, but we are not implementing + * that call for this device family anyway. * - * The check is for initialisation of sc->sc_bar[idx], which is - * only done in puc_bfe_attach(). + * The check is for initialization of sc->sc_bar[idx], + * which is only done in puc_bfe_attach(). */ idx = 0; do { diff --git a/sys/dev/rtwn/if_rtwn.c b/sys/dev/rtwn/if_rtwn.c index ec17cdc..927a8c8 100644 --- a/sys/dev/rtwn/if_rtwn.c +++ b/sys/dev/rtwn/if_rtwn.c @@ -1683,7 +1683,7 @@ rtwn_tx(struct rtwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni) txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, 0)); } /* Set sequence number (already little endian). */ - txd->txdseq = *(uint16_t *)wh->i_seq; + txd->txdseq = htole16(M_SEQNO_GET(m) % IEEE80211_SEQ_RANGE); if (!qos) { /* Use HW sequence numbering for non-QoS frames. */ diff --git a/sys/dev/sfxge/common/efsys.h b/sys/dev/sfxge/common/efsys.h index 10dc04d..a3980ff 100644 --- a/sys/dev/sfxge/common/efsys.h +++ b/sys/dev/sfxge/common/efsys.h @@ -238,6 +238,7 @@ sfxge_map_mbuf_fast(bus_dma_tag_t tag, bus_dmamap_t map, #define EFSYS_OPT_FALCON_NIC_CFG_OVERRIDE 0 #define EFSYS_OPT_SIENA 1 #define EFSYS_OPT_HUNTINGTON 1 +#define EFSYS_OPT_MEDFORD 0 #ifdef DEBUG #define EFSYS_OPT_CHECK_REG 1 #else diff --git a/sys/dev/ti/if_ti.c b/sys/dev/ti/if_ti.c index 9b9c4a1..eba7f7b 100644 --- a/sys/dev/ti/if_ti.c +++ b/sys/dev/ti/if_ti.c @@ -1634,7 +1634,7 @@ ti_newbuf_jumbo(struct ti_softc *sc, int idx, struct mbuf *m_old) m[i]->m_data = (void *)sf_buf_kva(sf[i]); m[i]->m_len = PAGE_SIZE; MEXTADD(m[i], sf_buf_kva(sf[i]), PAGE_SIZE, - sf_buf_mext, (void*)sf_buf_kva(sf[i]), sf[i], + sf_mext_free, (void*)sf_buf_kva(sf[i]), sf[i], 0, EXT_DISPOSABLE); m[i]->m_next = m[i+1]; } @@ -1699,7 +1699,7 @@ nobufs: if (m[i]) m_freem(m[i]); if (sf[i]) - sf_buf_mext((void *)sf_buf_kva(sf[i]), sf[i]); + sf_mext_free((void *)sf_buf_kva(sf[i]), sf[i]); } return (ENOBUFS); } diff --git a/sys/dev/vt/hw/ofwfb/ofwfb.c b/sys/dev/vt/hw/ofwfb/ofwfb.c index acad5d4..c3ac185 100644 --- a/sys/dev/vt/hw/ofwfb/ofwfb.c +++ b/sys/dev/vt/hw/ofwfb/ofwfb.c @@ -57,6 +57,7 @@ struct ofwfb_softc { int iso_palette; }; +static void ofwfb_initialize(struct vt_device *vd); static vd_probe_t ofwfb_probe; static vd_init_t ofwfb_init; static vd_bitblt_text_t ofwfb_bitblt_text; @@ -124,6 +125,18 @@ ofwfb_bitblt_bitmap(struct vt_device *vd, const struct vt_window *vw, uint8_t c[4]; } ch1, ch2; +#ifdef __powerpc__ + /* Deal with unmapped framebuffers */ + if (sc->fb_flags & FB_FLAG_NOWRITE) { + if (pmap_bootstrapped) { + sc->fb_flags &= ~FB_FLAG_NOWRITE; + ofwfb_initialize(vd); + } else { + return; + } + } +#endif + fgc = sc->fb_cmap[fg]; bgc = sc->fb_cmap[bg]; b = m = 0; @@ -271,6 +284,11 @@ ofwfb_initialize(struct vt_device *vd) cell_t retval; uint32_t oldpix; + sc->fb.fb_cmsize = 16; + + if (sc->fb.fb_flags & FB_FLAG_NOWRITE) + return; + /* * Set up the color map */ @@ -318,8 +336,6 @@ ofwfb_initialize(struct vt_device *vd) panic("Unknown color space depth %d", sc->fb.fb_bpp); break; } - - sc->fb.fb_cmsize = 16; } static int @@ -466,6 +482,11 @@ ofwfb_init(struct vt_device *vd) #if defined(__powerpc__) OF_decode_addr(node, fb_phys, &sc->sc_memt, &sc->fb.fb_vbase); sc->fb.fb_pbase = sc->fb.fb_vbase; /* 1:1 mapped */ + #ifdef __powerpc64__ + /* Real mode under a hypervisor probably doesn't cover FB */ + if (!(mfmsr() & (PSL_HV | PSL_DR))) + sc->fb.fb_flags |= FB_FLAG_NOWRITE; + #endif #else /* No ability to interpret assigned-addresses otherwise */ return (CN_DEAD); |