aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorBrandon Bergren <bdragon@FreeBSD.org>2020-06-14 16:47:16 +0000
committerBrandon Bergren <bdragon@FreeBSD.org>2020-06-14 16:47:16 +0000
commita4ec123c569adc860c69827bc54c306b333c924b (patch)
treefc4051a3b089119af8f0ae19db0403625b009a84 /sys
parentb231bff8b263f40dee4018677afdd4c766a8e0aa (diff)
downloadsrc-a4ec123c569adc860c69827bc54c306b333c924b.tar.gz
src-a4ec123c569adc860c69827bc54c306b333c924b.zip
[PowerPC] Fix scc z8530 driver
Parts of the z8530 driver were still using the SUN channel spacing. This was invalid on PowerMac and QEMU, where the attachment was to escc, not escc-legacy. This means the driver has apparently NEVER worked properly on Macintosh hardware. Add documentation for the channel spacing details, and change to using driver-specific initialization instead of hardcoded spacing so either spacing can be used. Fixes boot hang in QEMU when using the serial console, and fixes use on Xserve serial (and presumably PowerMacs that have a Stealth Serial port or similar) Reviewed by: jhibbits Sponsored by: Tag1 Consulting, Inc. Differential Revision: https://reviews.freebsd.org/D24661
Notes
Notes: svn path=/head/; revision=362179
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/ic/z8530.h15
-rw-r--r--sys/dev/scc/scc_bfe.h3
-rw-r--r--sys/dev/scc/scc_bfe_macio.c3
-rw-r--r--sys/dev/scc/scc_dev_z8530.c28
4 files changed, 36 insertions, 13 deletions
diff --git a/sys/dev/ic/z8530.h b/sys/dev/ic/z8530.h
index 115f9a689bc5..61dce69a718f 100644
--- a/sys/dev/ic/z8530.h
+++ b/sys/dev/ic/z8530.h
@@ -32,16 +32,15 @@
#define _DEV_IC_Z8530_H_
/*
- * Channel B control: 0
- * Channel B data: 1
- * Channel A control: 2
- * Channel A data: 3
+ * legacy: SUN compatible
+ * escc: Macintosh
+ * legacy escc
+ * Channel B control: 0 0
+ * Channel B data: 1 1
+ * Channel A control: 2 16
+ * Channel A data: 3 17
*/
-/* The following apply when using a device-scoped bus handle */
-#define CHAN_A 2
-#define CHAN_B 0
-
#define REG_CTRL 0
#define REG_DATA 1
diff --git a/sys/dev/scc/scc_bfe.h b/sys/dev/scc/scc_bfe.h
index d6ddd6775a3c..0b7f91f83f99 100644
--- a/sys/dev/scc/scc_bfe.h
+++ b/sys/dev/scc/scc_bfe.h
@@ -114,7 +114,8 @@ struct scc_class {
extern struct scc_class scc_quicc_class;
extern struct scc_class scc_sab82532_class;
-extern struct scc_class scc_z8530_class;
+extern struct scc_class scc_z8530_escc_class;
+extern struct scc_class scc_z8530_legacy_class;
struct scc_softc {
KOBJ_FIELDS;
diff --git a/sys/dev/scc/scc_bfe_macio.c b/sys/dev/scc/scc_bfe_macio.c
index 51a8ed61f0f5..241f6c072a2c 100644
--- a/sys/dev/scc/scc_bfe_macio.c
+++ b/sys/dev/scc/scc_bfe_macio.c
@@ -55,9 +55,10 @@ scc_macio_probe(device_t dev)
sc = device_get_softc(dev);
nm = ofw_bus_get_name(dev);
+ /* Attach to modern escc (channel shift 4 bits) */
if (!strcmp(nm, "escc")) {
device_set_desc(dev, "Zilog Z8530 dual channel SCC");
- sc->sc_class = &scc_z8530_class;
+ sc->sc_class = &scc_z8530_escc_class;
return (scc_bfe_probe(dev, MACIO_REGSHFT, MACIO_RCLK, 0));
}
return (ENXIO);
diff --git a/sys/dev/scc/scc_dev_z8530.c b/sys/dev/scc/scc_dev_z8530.c
index 193ed7184e86..6255ebd06c7c 100644
--- a/sys/dev/scc/scc_dev_z8530.c
+++ b/sys/dev/scc/scc_dev_z8530.c
@@ -51,6 +51,10 @@ static int z8530_bfe_iclear(struct scc_softc *, struct scc_chan *);
static int z8530_bfe_ipend(struct scc_softc *);
static int z8530_bfe_probe(struct scc_softc *);
+/* Channel B is always at 0 offset. */
+#define CHAN_A (-(sc->sc_class->cl_range))
+#define CHAN_B 0
+
static kobj_method_t z8530_methods[] = {
KOBJMETHOD(scc_attach, z8530_bfe_attach),
KOBJMETHOD(scc_iclear, z8530_bfe_iclear),
@@ -59,14 +63,32 @@ static kobj_method_t z8530_methods[] = {
KOBJMETHOD_END
};
-struct scc_class scc_z8530_class = {
- "z8530 class",
+/*
+ * escc (macio) spacing.
+ */
+struct scc_class scc_z8530_escc_class = {
+ "z8530 escc class",
+ z8530_methods,
+ sizeof(struct scc_softc),
+ .cl_channels = 2,
+ .cl_class = SCC_CLASS_Z8530,
+ .cl_modes = SCC_MODE_ASYNC | SCC_MODE_BISYNC | SCC_MODE_HDLC,
+ /* Negative .cl_range signifies this is channel spacing. */
+ .cl_range = (CHAN_B - 16),
+};
+
+/*
+ * SUN compatible channel spacing.
+ */
+struct scc_class scc_z8530_legacy_class = {
+ "z8530 legacy class",
z8530_methods,
sizeof(struct scc_softc),
.cl_channels = 2,
.cl_class = SCC_CLASS_Z8530,
.cl_modes = SCC_MODE_ASYNC | SCC_MODE_BISYNC | SCC_MODE_HDLC,
- .cl_range = CHAN_B - CHAN_A,
+ /* Negative .cl_range signifies this is channel spacing. */
+ .cl_range = (CHAN_B - 2),
};
/* Multiplexed I/O. */