summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/cxgbe/t4_main.c7
-rw-r--r--sys/dev/ic/ns16550.h2
-rw-r--r--sys/dev/iscsi/iscsi.c99
-rw-r--r--sys/dev/iscsi/iscsi.h3
-rw-r--r--sys/dev/puc/pucdata.c154
-rw-r--r--sys/dev/rtwn/if_rtwn.c2
-rw-r--r--sys/dev/sfxge/common/efsys.h1
-rw-r--r--sys/dev/ti/if_ti.c4
-rw-r--r--sys/dev/vt/hw/ofwfb/ofwfb.c25
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);
OpenPOWER on IntegriCloud