summaryrefslogtreecommitdiffstats
path: root/sys/dev/ppbus
diff options
context:
space:
mode:
authornsouch <nsouch@FreeBSD.org>2000-01-14 00:18:06 +0000
committernsouch <nsouch@FreeBSD.org>2000-01-14 00:18:06 +0000
commit59fc142474158cbbfbae06872a4e3efaa40e777f (patch)
tree3dd5303c8a8a1e20337965402c872462f141a217 /sys/dev/ppbus
parent83719ce7419aa6d99e02f397ba20a42d7406963b (diff)
downloadFreeBSD-src-59fc142474158cbbfbae06872a4e3efaa40e777f.zip
FreeBSD-src-59fc142474158cbbfbae06872a4e3efaa40e777f.tar.gz
Port of ppbus standalone framework to the newbus system.
Note1: the correct interrupt level is invoked correctly for each driver. For this purpose, drivers request the bus before being able to call BUS_SETUP_INTR and BUS_TEARDOWN_INTR call is forced by the ppbus core when drivers release it. Thus, when BUS_SETUP_INTR is called at ppbus driver level, ppbus checks that the caller owns the bus and stores the interrupt handler cookie (in order to unregister it later). Printing is impossible while plip link is up is still TRUE. vpo (ZIP driver) and lpt are make in such a way that using the ZIP and printing concurrently is permitted is also TRUE. Note2: specific chipset detection is not done by default. PPC_PROBE_CHIPSET is now needed to force chipset detection. If set, the flags 0x40 still avoid detection at boot. Port of the pcf(4) driver to the newbus system (was previously directly connected to the rootbus and attached by a bogus pcf_isa_probe function).
Diffstat (limited to 'sys/dev/ppbus')
-rw-r--r--sys/dev/ppbus/if_plip.c281
-rw-r--r--sys/dev/ppbus/immio.c146
-rw-r--r--sys/dev/ppbus/lpbb.c162
-rw-r--r--sys/dev/ppbus/lpt.c351
-rw-r--r--sys/dev/ppbus/ppb_1284.c325
-rw-r--r--sys/dev/ppbus/ppb_1284.h24
-rw-r--r--sys/dev/ppbus/ppb_base.c137
-rw-r--r--sys/dev/ppbus/ppb_msq.c51
-rw-r--r--sys/dev/ppbus/ppb_msq.h16
-rw-r--r--sys/dev/ppbus/ppbconf.c429
-rw-r--r--sys/dev/ppbus/ppbconf.h231
-rw-r--r--sys/dev/ppbus/ppbio.h83
-rw-r--r--sys/dev/ppbus/ppbus_if.m92
-rw-r--r--sys/dev/ppbus/ppi.c248
-rw-r--r--sys/dev/ppbus/pps.c144
-rw-r--r--sys/dev/ppbus/vpo.c117
-rw-r--r--sys/dev/ppbus/vpoio.c170
-rw-r--r--sys/dev/ppbus/vpoio.h6
18 files changed, 1607 insertions, 1406 deletions
diff --git a/sys/dev/ppbus/if_plip.c b/sys/dev/ppbus/if_plip.c
index f2085e4..033889e 100644
--- a/sys/dev/ppbus/if_plip.c
+++ b/sys/dev/ppbus/if_plip.c
@@ -77,15 +77,28 @@
/*
* Update for ppbus, PLIP support only - Nicolas Souchu
*/
+#include "plip.h"
+
+#if NPLIP > 0
+
+#include "opt_plip.h"
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
+#include <machine/clock.h>
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/rman.h>
+
#include <net/if.h>
#include <net/if_types.h>
#include <net/netisr.h>
@@ -96,8 +109,8 @@
#include <net/bpf.h>
#include <dev/ppbus/ppbconf.h>
-
-#include "opt_plip.h"
+#include "ppbus_if.h"
+#include <dev/ppbus/ppbio.h>
#ifndef LPMTU /* MTU for the lp# interfaces */
#define LPMTU 1500
@@ -135,20 +148,15 @@ static int volatile lptflag = 1;
static int volatile lptflag = 0;
#endif
-struct lpt_softc {
+struct lp_data {
unsigned short lp_unit;
- struct ppb_device lp_dev;
-
struct ifnet sc_if;
u_char *sc_ifbuf;
int sc_iferrs;
-};
-
-static int nlp = 0;
-#define MAXPLIP 8 /* XXX not much better! */
-static struct lpt_softc *lpdata[MAXPLIP];
+ struct resource *res_irq;
+};
/* Tables for the lp# interface */
static u_char *txmith;
@@ -162,87 +170,87 @@ static u_char *ctxmith;
#define ctrecvl (ctxmith+(3*LPIPTBLSIZE))
/* Functions for the lp# interface */
-static struct ppb_device *lpprobe(struct ppb_data *);
-static int lpattach(struct ppb_device *);
+static int lp_probe(device_t dev);
+static int lp_attach(device_t dev);
static int lpinittables(void);
static int lpioctl(struct ifnet *, u_long, caddr_t);
static int lpoutput(struct ifnet *, struct mbuf *, struct sockaddr *,
struct rtentry *);
-static void lpintr(int);
+static void lp_intr(void *);
-/*
- * Make ourselves visible as a ppbus driver
- */
+#define DEVTOSOFTC(dev) \
+ ((struct lp_data *)device_get_softc(dev))
+#define UNITOSOFTC(unit) \
+ ((struct lp_data *)devclass_get_softc(lp_devclass, (unit)))
+#define UNITODEVICE(unit) \
+ (devclass_get_device(lp_devclass, (unit)))
-static struct ppb_driver lpdriver = {
- lpprobe, lpattach, "lp"
+static devclass_t lp_devclass;
+
+static device_method_t lp_methods[] = {
+ /* device interface */
+ DEVMETHOD(device_probe, lp_probe),
+ DEVMETHOD(device_attach, lp_attach),
+
+ { 0, 0 }
};
-DATA_SET(ppbdriver_set, lpdriver);
+static driver_t lp_driver = {
+ "plip",
+ lp_methods,
+ sizeof(struct lp_data),
+};
/*
* lpprobe()
*/
-static struct ppb_device *
-lpprobe(struct ppb_data *ppb)
+static int
+lp_probe(device_t dev)
{
- struct lpt_softc *lp;
+ device_t ppbus = device_get_parent(dev);
+ struct lp_data *lp;
+ int irq, zero = 0;
+
+ lp = DEVTOSOFTC(dev);
+ bzero(lp, sizeof(struct lp_data));
+
+ /* retrieve the ppbus irq */
+ BUS_READ_IVAR(ppbus, dev, PPBUS_IVAR_IRQ, &irq);
/* if we haven't interrupts, the probe fails */
- if (!ppb->ppb_link->id_irq) {
- printf("plip: not an interrupt driven port, failed.\n");
- return (0);
+ if (irq == -1) {
+ device_printf(dev, "not an interrupt driven port, failed.\n");
+ return (ENXIO);
}
- lp = (struct lpt_softc *) malloc(sizeof(struct lpt_softc),
- M_TEMP, M_NOWAIT);
- if (!lp) {
- printf("lp: cannot malloc!\n");
- return (0);
+ /* reserve the interrupt resource, expecting irq is available to continue */
+ lp->res_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &zero, irq, irq, 1,
+ RF_SHAREABLE);
+ if (lp->res_irq == 0) {
+ device_printf(dev, "cannot reserve interrupt, failed.\n");
+ return (ENXIO);
}
- bzero(lp, sizeof(struct lpt_softc));
-
- lpdata[nlp] = lp;
/*
* lp dependent initialisation.
*/
- lp->lp_unit = nlp;
-
- if (bootverbose)
- printf("plip: irq %d\n", ppb->ppb_link->id_irq);
-
- /*
- * ppbus dependent initialisation.
- */
- lp->lp_dev.id_unit = lp->lp_unit;
- lp->lp_dev.name = lpdriver.name;
- lp->lp_dev.ppb = ppb;
- lp->lp_dev.intr = lpintr;
+ lp->lp_unit = device_get_unit(dev);
- /* Ok, go to next device on next probe */
- nlp ++;
+ device_set_desc(dev, "PLIP network interface");
- return (&lp->lp_dev);
+ return (0);
}
static int
-lpattach (struct ppb_device *dev)
+lp_attach (device_t dev)
{
- int unit = dev->id_unit;
- struct lpt_softc *sc = lpdata[unit];
- struct ifnet *ifp = &sc->sc_if;
+ struct lp_data *lp = DEVTOSOFTC(dev);
+ struct ifnet *ifp = &lp->sc_if;
- /*
- * Report ourselves
- */
- printf("plip%d: <PLIP network interface> on ppbus %d\n",
- dev->id_unit, dev->ppb->ppb_link->adapter_unit);
-
- ifp->if_softc = sc;
+ ifp->if_softc = lp;
ifp->if_name = "lp";
- ifp->if_unit = unit;
+ ifp->if_unit = device_get_unit(dev);
ifp->if_mtu = LPMTU;
ifp->if_flags = IFF_SIMPLEX | IFF_POINTOPOINT | IFF_MULTICAST;
ifp->if_ioctl = lpioctl;
@@ -255,7 +263,7 @@ lpattach (struct ppb_device *dev)
bpfattach(ifp, DLT_NULL, sizeof(u_int32_t));
- return (1);
+ return (0);
}
/*
* Build the translation tables for the LPIP (BSD unix) protocol.
@@ -303,10 +311,13 @@ lpinittables (void)
static int
lpioctl (struct ifnet *ifp, u_long cmd, caddr_t data)
{
- struct lpt_softc *sc = lpdata[ifp->if_unit];
+ device_t dev = UNITODEVICE(ifp->if_unit);
+ device_t ppbus = device_get_parent(dev);
+ struct lp_data *sc = DEVTOSOFTC(dev);
struct ifaddr *ifa = (struct ifaddr *)data;
struct ifreq *ifr = (struct ifreq *)data;
u_char *ptr;
+ void *ih;
int error;
switch (cmd) {
@@ -322,11 +333,11 @@ lpioctl (struct ifnet *ifp, u_long cmd, caddr_t data)
case SIOCSIFFLAGS:
if ((!(ifp->if_flags & IFF_UP)) && (ifp->if_flags & IFF_RUNNING)) {
- ppb_wctr(&sc->lp_dev, 0x00);
+ ppb_wctr(ppbus, 0x00);
ifp->if_flags &= ~IFF_RUNNING;
/* IFF_UP is not set, try to release the bus anyway */
- ppb_release_bus(&sc->lp_dev);
+ ppb_release_bus(ppbus, dev);
break;
}
if (((ifp->if_flags & IFF_UP)) && (!(ifp->if_flags & IFF_RUNNING))) {
@@ -334,26 +345,33 @@ lpioctl (struct ifnet *ifp, u_long cmd, caddr_t data)
/* XXX
* Should the request be interruptible?
*/
- if ((error = ppb_request_bus(&sc->lp_dev, PPB_WAIT|PPB_INTR)))
+ if ((error = ppb_request_bus(ppbus, dev, PPB_WAIT|PPB_INTR)))
return (error);
/* Now IFF_UP means that we own the bus */
- ppb_set_mode(&sc->lp_dev, PPB_COMPATIBLE);
+ ppb_set_mode(ppbus, PPB_COMPATIBLE);
if (lpinittables()) {
- ppb_release_bus(&sc->lp_dev);
+ ppb_release_bus(ppbus, dev);
return ENOBUFS;
}
sc->sc_ifbuf = malloc(sc->sc_if.if_mtu + MLPIPHDRLEN,
M_DEVBUF, M_WAITOK);
if (!sc->sc_ifbuf) {
- ppb_release_bus(&sc->lp_dev);
+ ppb_release_bus(ppbus, dev);
return ENOBUFS;
}
- ppb_wctr(&sc->lp_dev, IRQENABLE);
+ /* attach our interrupt handler, later detached when the bus is released */
+ if ((error = BUS_SETUP_INTR(ppbus, dev, sc->res_irq,
+ INTR_TYPE_NET, lp_intr, dev, &ih))) {
+ ppb_release_bus(ppbus, dev);
+ return (error);
+ }
+
+ ppb_wctr(ppbus, IRQENABLE);
ifp->if_flags |= IFF_RUNNING;
}
break;
@@ -404,15 +422,15 @@ lpioctl (struct ifnet *ifp, u_long cmd, caddr_t data)
}
static __inline int
-clpoutbyte (u_char byte, int spin, struct ppb_device *dev)
+clpoutbyte (u_char byte, int spin, device_t ppbus)
{
- ppb_wdtr(dev, ctxmitl[byte]);
- while (ppb_rstr(dev) & CLPIP_SHAKE)
+ ppb_wdtr(ppbus, ctxmitl[byte]);
+ while (ppb_rstr(ppbus) & CLPIP_SHAKE)
if (--spin == 0) {
return 1;
}
- ppb_wdtr(dev, ctxmith[byte]);
- while (!(ppb_rstr(dev) & CLPIP_SHAKE))
+ ppb_wdtr(ppbus, ctxmith[byte]);
+ while (!(ppb_rstr(ppbus) & CLPIP_SHAKE))
if (--spin == 0) {
return 1;
}
@@ -420,23 +438,23 @@ clpoutbyte (u_char byte, int spin, struct ppb_device *dev)
}
static __inline int
-clpinbyte (int spin, struct ppb_device *dev)
+clpinbyte (int spin, device_t ppbus)
{
u_char c, cl;
- while((ppb_rstr(dev) & CLPIP_SHAKE))
+ while((ppb_rstr(ppbus) & CLPIP_SHAKE))
if(!--spin) {
return -1;
}
- cl = ppb_rstr(dev);
- ppb_wdtr(dev, 0x10);
+ cl = ppb_rstr(ppbus);
+ ppb_wdtr(ppbus, 0x10);
- while(!(ppb_rstr(dev) & CLPIP_SHAKE))
+ while(!(ppb_rstr(ppbus) & CLPIP_SHAKE))
if(!--spin) {
return -1;
}
- c = ppb_rstr(dev);
- ppb_wdtr(dev, 0x00);
+ c = ppb_rstr(ppbus);
+ ppb_wdtr(ppbus, 0x00);
return (ctrecvl[cl] | ctrecvh[c]);
}
@@ -460,9 +478,11 @@ lptap(struct ifnet *ifp, struct mbuf *m)
}
static void
-lpintr (int unit)
+lp_intr (void *arg)
{
- struct lpt_softc *sc = lpdata[unit];
+ device_t dev = (device_t)arg;
+ device_t ppbus = device_get_parent(dev);
+ struct lp_data *sc = DEVTOSOFTC(dev);
int len, s, j;
u_char *bp;
u_char c, cl;
@@ -473,14 +493,14 @@ lpintr (int unit)
if (sc->sc_if.if_flags & IFF_LINK0) {
/* Ack. the request */
- ppb_wdtr(&sc->lp_dev, 0x01);
+ ppb_wdtr(ppbus, 0x01);
/* Get the packet length */
- j = clpinbyte(LPMAXSPIN2, &sc->lp_dev);
+ j = clpinbyte(LPMAXSPIN2, ppbus);
if (j == -1)
goto err;
len = j;
- j = clpinbyte(LPMAXSPIN2, &sc->lp_dev);
+ j = clpinbyte(LPMAXSPIN2, ppbus);
if (j == -1)
goto err;
len = len + (j << 8);
@@ -490,14 +510,14 @@ lpintr (int unit)
bp = sc->sc_ifbuf;
while (len--) {
- j = clpinbyte(LPMAXSPIN2, &sc->lp_dev);
+ j = clpinbyte(LPMAXSPIN2, ppbus);
if (j == -1) {
goto err;
}
*bp++ = j;
}
/* Get and ignore checksum */
- j = clpinbyte(LPMAXSPIN2, &sc->lp_dev);
+ j = clpinbyte(LPMAXSPIN2, ppbus);
if (j == -1) {
goto err;
}
@@ -525,27 +545,27 @@ lpintr (int unit)
}
goto done;
}
- while ((ppb_rstr(&sc->lp_dev) & LPIP_SHAKE)) {
+ while ((ppb_rstr(ppbus) & LPIP_SHAKE)) {
len = sc->sc_if.if_mtu + LPIPHDRLEN;
bp = sc->sc_ifbuf;
while (len--) {
- cl = ppb_rstr(&sc->lp_dev);
- ppb_wdtr(&sc->lp_dev, 8);
+ cl = ppb_rstr(ppbus);
+ ppb_wdtr(ppbus, 8);
j = LPMAXSPIN2;
- while((ppb_rstr(&sc->lp_dev) & LPIP_SHAKE))
+ while((ppb_rstr(ppbus) & LPIP_SHAKE))
if(!--j) goto err;
- c = ppb_rstr(&sc->lp_dev);
- ppb_wdtr(&sc->lp_dev, 0);
+ c = ppb_rstr(ppbus);
+ ppb_wdtr(ppbus, 0);
*bp++= trecvh[cl] | trecvl[c];
j = LPMAXSPIN2;
- while (!((cl=ppb_rstr(&sc->lp_dev)) & LPIP_SHAKE)) {
+ while (!((cl=ppb_rstr(ppbus)) & LPIP_SHAKE)) {
if (cl != c &&
- (((cl = ppb_rstr(&sc->lp_dev)) ^ 0xb8) & 0xf8) ==
+ (((cl = ppb_rstr(ppbus)) ^ 0xb8) & 0xf8) ==
(c & 0xf8))
goto end;
if (!--j) goto err;
@@ -578,7 +598,7 @@ lpintr (int unit)
goto done;
err:
- ppb_wdtr(&sc->lp_dev, 0);
+ ppb_wdtr(ppbus, 0);
lprintf("R");
sc->sc_if.if_ierrors++;
sc->sc_iferrs++;
@@ -588,8 +608,8 @@ lpintr (int unit)
* so stop wasting our time
*/
if (sc->sc_iferrs > LPMAXERRS) {
- printf("lp%d: Too many errors, Going off-line.\n", unit);
- ppb_wctr(&sc->lp_dev, 0x00);
+ printf("lp%d: Too many errors, Going off-line.\n", device_get_unit(dev));
+ ppb_wctr(ppbus, 0x00);
sc->sc_if.if_flags &= ~IFF_RUNNING;
sc->sc_iferrs=0;
}
@@ -600,14 +620,14 @@ lpintr (int unit)
}
static __inline int
-lpoutbyte (u_char byte, int spin, struct ppb_device *dev)
+lpoutbyte (u_char byte, int spin, device_t ppbus)
{
- ppb_wdtr(dev, txmith[byte]);
- while (!(ppb_rstr(dev) & LPIP_SHAKE))
+ ppb_wdtr(ppbus, txmith[byte]);
+ while (!(ppb_rstr(ppbus) & LPIP_SHAKE))
if (--spin == 0)
return 1;
- ppb_wdtr(dev, txmitl[byte]);
- while (ppb_rstr(dev) & LPIP_SHAKE)
+ ppb_wdtr(ppbus, txmitl[byte]);
+ while (ppb_rstr(ppbus) & LPIP_SHAKE)
if (--spin == 0)
return 1;
return 0;
@@ -617,7 +637,8 @@ static int
lpoutput (struct ifnet *ifp, struct mbuf *m,
struct sockaddr *dst, struct rtentry *rt)
{
- struct lpt_softc *sc = lpdata[ifp->if_unit];
+ device_t dev = UNITODEVICE(ifp->if_unit);
+ device_t ppbus = device_get_parent(dev);
int s, err;
struct mbuf *mm;
u_char *cp = "\0\0";
@@ -634,19 +655,19 @@ lpoutput (struct ifnet *ifp, struct mbuf *m,
s = splhigh();
/* Suspend (on laptops) or receive-errors might have taken us offline */
- ppb_wctr(&sc->lp_dev, IRQENABLE);
+ ppb_wctr(ppbus, IRQENABLE);
if (ifp->if_flags & IFF_LINK0) {
- if (!(ppb_rstr(&sc->lp_dev) & CLPIP_SHAKE)) {
+ if (!(ppb_rstr(ppbus) & CLPIP_SHAKE)) {
lprintf("&");
- lpintr(ifp->if_unit);
+ lp_intr(dev);
}
/* Alert other end to pending packet */
spin = LPMAXSPIN1;
- ppb_wdtr(&sc->lp_dev, 0x08);
- while ((ppb_rstr(&sc->lp_dev) & 0x08) == 0)
+ ppb_wdtr(ppbus, 0x08);
+ while ((ppb_rstr(ppbus) & 0x08) == 0)
if (--spin == 0) {
goto nend;
}
@@ -659,21 +680,21 @@ lpoutput (struct ifnet *ifp, struct mbuf *m,
for (mm = m; mm; mm = mm->m_next) {
count += mm->m_len;
}
- if (clpoutbyte(count & 0xFF, LPMAXSPIN1, &sc->lp_dev))
+ if (clpoutbyte(count & 0xFF, LPMAXSPIN1, ppbus))
goto nend;
- if (clpoutbyte((count >> 8) & 0xFF, LPMAXSPIN1, &sc->lp_dev))
+ if (clpoutbyte((count >> 8) & 0xFF, LPMAXSPIN1, ppbus))
goto nend;
/* Send dummy ethernet header */
for (i = 0; i < 12; i++) {
- if (clpoutbyte(i, LPMAXSPIN1, &sc->lp_dev))
+ if (clpoutbyte(i, LPMAXSPIN1, ppbus))
goto nend;
chksum += i;
}
- if (clpoutbyte(0x08, LPMAXSPIN1, &sc->lp_dev))
+ if (clpoutbyte(0x08, LPMAXSPIN1, ppbus))
goto nend;
- if (clpoutbyte(0x00, LPMAXSPIN1, &sc->lp_dev))
+ if (clpoutbyte(0x00, LPMAXSPIN1, ppbus))
goto nend;
chksum += 0x08 + 0x00; /* Add into checksum */
@@ -683,17 +704,17 @@ lpoutput (struct ifnet *ifp, struct mbuf *m,
len = mm->m_len;
while (len--) {
chksum += *cp;
- if (clpoutbyte(*cp++, LPMAXSPIN2, &sc->lp_dev))
+ if (clpoutbyte(*cp++, LPMAXSPIN2, ppbus))
goto nend;
}
} while ((mm = mm->m_next));
/* Send checksum */
- if (clpoutbyte(chksum, LPMAXSPIN2, &sc->lp_dev))
+ if (clpoutbyte(chksum, LPMAXSPIN2, ppbus))
goto nend;
/* Go quiescent */
- ppb_wdtr(&sc->lp_dev, 0);
+ ppb_wdtr(ppbus, 0);
err = 0; /* No errors */
@@ -710,22 +731,22 @@ lpoutput (struct ifnet *ifp, struct mbuf *m,
m_freem(m);
- if (!(ppb_rstr(&sc->lp_dev) & CLPIP_SHAKE)) {
+ if (!(ppb_rstr(ppbus) & CLPIP_SHAKE)) {
lprintf("^");
- lpintr(ifp->if_unit);
+ lp_intr(dev);
}
(void) splx(s);
return 0;
}
- if (ppb_rstr(&sc->lp_dev) & LPIP_SHAKE) {
+ if (ppb_rstr(ppbus) & LPIP_SHAKE) {
lprintf("&");
- lpintr(ifp->if_unit);
+ lp_intr(dev);
}
- if (lpoutbyte(0x08, LPMAXSPIN1, &sc->lp_dev))
+ if (lpoutbyte(0x08, LPMAXSPIN1, ppbus))
goto end;
- if (lpoutbyte(0x00, LPMAXSPIN2, &sc->lp_dev))
+ if (lpoutbyte(0x00, LPMAXSPIN2, ppbus))
goto end;
mm = m;
@@ -733,7 +754,7 @@ lpoutput (struct ifnet *ifp, struct mbuf *m,
cp = mtod(mm,u_char *);
len = mm->m_len;
while (len--)
- if (lpoutbyte(*cp++, LPMAXSPIN2, &sc->lp_dev))
+ if (lpoutbyte(*cp++, LPMAXSPIN2, ppbus))
goto end;
} while ((mm = mm->m_next));
@@ -741,7 +762,7 @@ lpoutput (struct ifnet *ifp, struct mbuf *m,
end:
--cp;
- ppb_wdtr(&sc->lp_dev, txmitl[*cp] ^ 0x17);
+ ppb_wdtr(ppbus, txmitl[*cp] ^ 0x17);
if (err) { /* if we didn't timeout... */
ifp->if_oerrors++;
@@ -755,11 +776,15 @@ lpoutput (struct ifnet *ifp, struct mbuf *m,
m_freem(m);
- if (ppb_rstr(&sc->lp_dev) & LPIP_SHAKE) {
+ if (ppb_rstr(ppbus) & LPIP_SHAKE) {
lprintf("^");
- lpintr(ifp->if_unit);
+ lp_intr(dev);
}
(void) splx(s);
return 0;
}
+
+DRIVER_MODULE(plip, ppbus, lp_driver, lp_devclass, 0, 0);
+
+#endif /* NPLIP > 0 */
diff --git a/sys/dev/ppbus/immio.c b/sys/dev/ppbus/immio.c
index e10f9a1..30d9117 100644
--- a/sys/dev/ppbus/immio.c
+++ b/sys/dev/ppbus/immio.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1998 Nicolas Souchu
+ * Copyright (c) 1998, 1999 Nicolas Souchu
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -36,6 +36,8 @@
#ifdef _KERNEL
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/module.h>
+#include <sys/bus.h>
#include <sys/malloc.h>
#include <sys/buf.h>
@@ -49,11 +51,14 @@
#include "opt_vpo.h"
+#include <dev/ppbus/ppbio.h>
#include <dev/ppbus/ppbconf.h>
#include <dev/ppbus/ppb_msq.h>
#include <dev/ppbus/vpoio.h>
#include <dev/ppbus/ppb_1284.h>
+#include "ppbus_if.h"
+
#define VP0_SELTMO 5000 /* select timeout */
#define VP0_FAST_SPINTMO 500000 /* wait status timeout */
#define VP0_LOW_SPINTMO 5000000 /* wait status timeout */
@@ -275,6 +280,7 @@ imm_disconnect(struct vpoio_data *vpo, int *connected, int release_bus)
{
DECLARE_CPP_MICROSEQ;
+ device_t ppbus = device_get_parent(vpo->vpo_dev);
char s1, s2, s3;
int ret;
@@ -286,7 +292,7 @@ imm_disconnect(struct vpoio_data *vpo, int *connected, int release_bus)
CPP_S2, (void *)&s2, CPP_S3, (void *)&s3,
CPP_PARAM, 0x30);
- ppb_MS_microseq(&vpo->vpo_dev, cpp_microseq, &ret);
+ ppb_MS_microseq(ppbus, vpo->vpo_dev, cpp_microseq, &ret);
if ((s1 != (char)0xb8 || s2 != (char)0x18 || s3 != (char)0x38)) {
if (bootverbose)
@@ -297,7 +303,7 @@ imm_disconnect(struct vpoio_data *vpo, int *connected, int release_bus)
}
if (release_bus)
- return (ppb_release_bus(&vpo->vpo_dev));
+ return (ppb_release_bus(ppbus, vpo->vpo_dev));
else
return (0);
}
@@ -310,6 +316,7 @@ imm_connect(struct vpoio_data *vpo, int how, int *disconnected, int request_bus)
{
DECLARE_CPP_MICROSEQ;
+ device_t ppbus = device_get_parent(vpo->vpo_dev);
char s1, s2, s3;
int error;
int ret;
@@ -319,7 +326,7 @@ imm_connect(struct vpoio_data *vpo, int how, int *disconnected, int request_bus)
*disconnected = 0;
if (request_bus)
- if ((error = ppb_request_bus(&vpo->vpo_dev, how)))
+ if ((error = ppb_request_bus(ppbus, vpo->vpo_dev, how)))
return (error);
ppb_MS_init_msq(cpp_microseq, 3, CPP_S1, (void *)&s1,
@@ -327,18 +334,18 @@ imm_connect(struct vpoio_data *vpo, int how, int *disconnected, int request_bus)
/* select device 0 in compatible mode */
ppb_MS_init_msq(cpp_microseq, 1, CPP_PARAM, 0xe0);
- ppb_MS_microseq(&vpo->vpo_dev, cpp_microseq, &ret);
+ ppb_MS_microseq(ppbus, vpo->vpo_dev, cpp_microseq, &ret);
/* disconnect all devices */
ppb_MS_init_msq(cpp_microseq, 1, CPP_PARAM, 0x30);
- ppb_MS_microseq(&vpo->vpo_dev, cpp_microseq, &ret);
+ ppb_MS_microseq(ppbus, vpo->vpo_dev, cpp_microseq, &ret);
- if (PPB_IN_EPP_MODE(&vpo->vpo_dev))
+ if (PPB_IN_EPP_MODE(ppbus))
ppb_MS_init_msq(cpp_microseq, 1, CPP_PARAM, 0x28);
else
ppb_MS_init_msq(cpp_microseq, 1, CPP_PARAM, 0xe0);
- ppb_MS_microseq(&vpo->vpo_dev, cpp_microseq, &ret);
+ ppb_MS_microseq(ppbus, vpo->vpo_dev, cpp_microseq, &ret);
if ((s1 != (char)0xb8 || s2 != (char)0x18 || s3 != (char)0x30)) {
if (bootverbose)
@@ -359,9 +366,10 @@ imm_connect(struct vpoio_data *vpo, int how, int *disconnected, int request_bus)
static int
imm_detect(struct vpoio_data *vpo)
{
+ device_t ppbus = device_get_parent(vpo->vpo_dev);
int error;
- if ((error = ppb_request_bus(&vpo->vpo_dev, PPB_DONTWAIT)))
+ if ((error = ppb_request_bus(ppbus, vpo->vpo_dev, PPB_DONTWAIT)))
return (error);
/* disconnect the drive, keep the bus */
@@ -378,7 +386,7 @@ imm_detect(struct vpoio_data *vpo)
}
/* send SCSI reset signal */
- ppb_MS_microseq(&vpo->vpo_dev, reset_microseq, NULL);
+ ppb_MS_microseq(ppbus, vpo->vpo_dev, reset_microseq, NULL);
/* release the bus now */
imm_disconnect(vpo, &error, 1);
@@ -396,7 +404,7 @@ imm_detect(struct vpoio_data *vpo)
return (0);
error:
- ppb_release_bus(&vpo->vpo_dev);
+ ppb_release_bus(ppbus, vpo->vpo_dev);
return (VP0_EINITFAILED);
}
@@ -406,12 +414,13 @@ error:
static int
imm_outstr(struct vpoio_data *vpo, char *buffer, int size)
{
+ device_t ppbus = device_get_parent(vpo->vpo_dev);
int error = 0;
- if (PPB_IN_EPP_MODE(&vpo->vpo_dev))
- ppb_reset_epp_timeout(&vpo->vpo_dev);
+ if (PPB_IN_EPP_MODE(ppbus))
+ ppb_reset_epp_timeout(ppbus);
- ppb_MS_exec(&vpo->vpo_dev, MS_OP_PUT, (union ppb_insarg)buffer,
+ ppb_MS_exec(ppbus, vpo->vpo_dev, MS_OP_PUT, (union ppb_insarg)buffer,
(union ppb_insarg)size, (union ppb_insarg)MS_UNKNOWN, &error);
return (error);
@@ -423,12 +432,13 @@ imm_outstr(struct vpoio_data *vpo, char *buffer, int size)
static int
imm_instr(struct vpoio_data *vpo, char *buffer, int size)
{
+ device_t ppbus = device_get_parent(vpo->vpo_dev);
int error = 0;
- if (PPB_IN_EPP_MODE(&vpo->vpo_dev))
- ppb_reset_epp_timeout(&vpo->vpo_dev);
+ if (PPB_IN_EPP_MODE(ppbus))
+ ppb_reset_epp_timeout(ppbus);
- ppb_MS_exec(&vpo->vpo_dev, MS_OP_GET, (union ppb_insarg)buffer,
+ ppb_MS_exec(ppbus, vpo->vpo_dev, MS_OP_GET, (union ppb_insarg)buffer,
(union ppb_insarg)size, (union ppb_insarg)MS_UNKNOWN, &error);
return (error);
@@ -438,13 +448,14 @@ static char
imm_select(struct vpoio_data *vpo, int initiator, int target)
{
DECLARE_SELECT_MICROSEQUENCE;
+ device_t ppbus = device_get_parent(vpo->vpo_dev);
int ret;
/* initialize the select microsequence */
ppb_MS_init_msq(select_microseq, 1,
SELECT_TARGET, 1 << initiator | 1 << target);
- ppb_MS_microseq(&vpo->vpo_dev, select_microseq, &ret);
+ ppb_MS_microseq(ppbus, vpo->vpo_dev, select_microseq, &ret);
return (ret);
}
@@ -459,15 +470,15 @@ imm_select(struct vpoio_data *vpo, int initiator, int target)
static char
imm_wait(struct vpoio_data *vpo, int tmo)
{
-
+ device_t ppbus = device_get_parent(vpo->vpo_dev);
register int k;
register char r;
- ppb_wctr(&vpo->vpo_dev, 0xc);
+ ppb_wctr(ppbus, 0xc);
/* XXX should be ported to microseq */
k = 0;
- while (!((r = ppb_rstr(&vpo->vpo_dev)) & 0x80) && (k++ < tmo))
+ while (!((r = ppb_rstr(ppbus)) & 0x80) && (k++ < tmo))
DELAY(1);
/*
@@ -477,7 +488,7 @@ imm_wait(struct vpoio_data *vpo, int tmo)
* 0xa8 = ZIP+ wants command
* 0xb8 = end of transfer, ZIP+ is sending status
*/
- ppb_wctr(&vpo->vpo_dev, 0x4);
+ ppb_wctr(ppbus, 0x4);
if (k < tmo)
return (r & 0xb8);
@@ -488,26 +499,28 @@ static int
imm_negociate(struct vpoio_data *vpo)
{
DECLARE_NEGOCIATE_MICROSEQ;
+ device_t ppbus = device_get_parent(vpo->vpo_dev);
int negociate_mode;
int ret;
- if (PPB_IN_NIBBLE_MODE(&vpo->vpo_dev))
+ if (PPB_IN_NIBBLE_MODE(ppbus))
negociate_mode = 0;
- else if (PPB_IN_PS2_MODE(&vpo->vpo_dev))
+ else if (PPB_IN_PS2_MODE(ppbus))
negociate_mode = 1;
else
return (0);
#if 0 /* XXX use standalone code not to depend on ppb_1284 code yet */
- ret = ppb_1284_negociate(&vpo->vpo_dev, negociate_mode);
+ ret = ppb_1284_negociate(ppbus, negociate_mode);
if (ret)
return (VP0_ENEGOCIATE);
#endif
- ppb_MS_init_msq(negociate_microseq, 1, NEGOCIATED_MODE, negociate_mode);
+ ppb_MS_init_msq(negociate_microseq, 1,
+ NEGOCIATED_MODE, negociate_mode);
- ppb_MS_microseq(&vpo->vpo_dev, negociate_microseq, &ret);
+ ppb_MS_microseq(ppbus, vpo->vpo_dev, negociate_microseq, &ret);
return (ret);
}
@@ -518,21 +531,20 @@ imm_negociate(struct vpoio_data *vpo)
* Low level probe of vpo device
*
*/
-struct ppb_device *
-imm_probe(struct ppb_data *ppb, struct vpoio_data *vpo)
+int
+imm_probe(device_t dev, struct vpoio_data *vpo)
{
+ int error;
/* ppbus dependent initialisation */
- vpo->vpo_dev.id_unit = vpo->vpo_unit;
- vpo->vpo_dev.name = "vpo";
- vpo->vpo_dev.ppb = ppb;
+ vpo->vpo_dev = dev;
/* now, try to initialise the drive */
- if (imm_detect(vpo)) {
- return (NULL);
+ if ((error = imm_detect(vpo))) {
+ return (error);
}
- return (&vpo->vpo_dev);
+ return (0);
}
/*
@@ -544,22 +556,17 @@ imm_probe(struct ppb_data *ppb, struct vpoio_data *vpo)
int
imm_attach(struct vpoio_data *vpo)
{
+ device_t ppbus = device_get_parent(vpo->vpo_dev);
int epp;
/*
- * Report ourselves
- */
- printf("imm%d: <Iomega Matchmaker Parallel to SCSI interface> on ppbus %d\n",
- vpo->vpo_dev.id_unit, vpo->vpo_dev.ppb->ppb_link->adapter_unit);
-
- /*
* Initialize microsequence code
*/
vpo->vpo_nibble_inbyte_msq = (struct ppb_microseq *)malloc(
sizeof(nibble_inbyte_submicroseq), M_DEVBUF, M_NOWAIT);
if (!vpo->vpo_nibble_inbyte_msq)
- return (0);
+ return (ENXIO);
bcopy((void *)nibble_inbyte_submicroseq,
(void *)vpo->vpo_nibble_inbyte_msq,
@@ -570,32 +577,32 @@ imm_attach(struct vpoio_data *vpo)
/*
* Initialize mode dependent in/out microsequences
*/
- ppb_request_bus(&vpo->vpo_dev, PPB_WAIT);
+ ppb_request_bus(ppbus, vpo->vpo_dev, PPB_WAIT);
/* enter NIBBLE mode to configure submsq */
- if (ppb_set_mode(&vpo->vpo_dev, PPB_NIBBLE) != -1) {
+ if (ppb_set_mode(ppbus, PPB_NIBBLE) != -1) {
- ppb_MS_GET_init(&vpo->vpo_dev, vpo->vpo_nibble_inbyte_msq);
- ppb_MS_PUT_init(&vpo->vpo_dev, spp_outbyte_submicroseq);
+ ppb_MS_GET_init(ppbus, vpo->vpo_dev, vpo->vpo_nibble_inbyte_msq);
+ ppb_MS_PUT_init(ppbus, vpo->vpo_dev, spp_outbyte_submicroseq);
}
/* enter PS2 mode to configure submsq */
- if (ppb_set_mode(&vpo->vpo_dev, PPB_PS2) != -1) {
+ if (ppb_set_mode(ppbus, PPB_PS2) != -1) {
- ppb_MS_GET_init(&vpo->vpo_dev, ps2_inbyte_submicroseq);
- ppb_MS_PUT_init(&vpo->vpo_dev, spp_outbyte_submicroseq);
+ ppb_MS_GET_init(ppbus, vpo->vpo_dev, ps2_inbyte_submicroseq);
+ ppb_MS_PUT_init(ppbus, vpo->vpo_dev, spp_outbyte_submicroseq);
}
- epp = ppb_get_epp_protocol(&vpo->vpo_dev);
+ epp = ppb_get_epp_protocol(ppbus);
/* enter EPP mode to configure submsq */
- if (ppb_set_mode(&vpo->vpo_dev, PPB_EPP) != -1) {
+ if (ppb_set_mode(ppbus, PPB_EPP) != -1) {
switch (epp) {
case EPP_1_9:
case EPP_1_7:
- ppb_MS_GET_init(&vpo->vpo_dev, epp17_instr);
- ppb_MS_PUT_init(&vpo->vpo_dev, epp17_outstr);
+ ppb_MS_GET_init(ppbus, vpo->vpo_dev, epp17_instr);
+ ppb_MS_PUT_init(ppbus, vpo->vpo_dev, epp17_outstr);
break;
default:
panic("%s: unknown EPP protocol (0x%x)", __FUNCTION__,
@@ -604,7 +611,7 @@ imm_attach(struct vpoio_data *vpo)
}
/* try to enter EPP or PS/2 mode, NIBBLE otherwise */
- if (ppb_set_mode(&vpo->vpo_dev, PPB_EPP) != -1) {
+ if (ppb_set_mode(ppbus, PPB_EPP) != -1) {
switch (epp) {
case EPP_1_9:
printf("imm%d: EPP 1.9 mode\n", vpo->vpo_unit);
@@ -616,25 +623,25 @@ imm_attach(struct vpoio_data *vpo)
panic("%s: unknown EPP protocol (0x%x)", __FUNCTION__,
epp);
}
- } else if (ppb_set_mode(&vpo->vpo_dev, PPB_PS2) != -1)
+ } else if (ppb_set_mode(ppbus, PPB_PS2) != -1)
printf("imm%d: PS2 mode\n", vpo->vpo_unit);
- else if (ppb_set_mode(&vpo->vpo_dev, PPB_NIBBLE) != -1)
+ else if (ppb_set_mode(ppbus, PPB_NIBBLE) != -1)
printf("imm%d: NIBBLE mode\n", vpo->vpo_unit);
else {
printf("imm%d: can't enter NIBBLE, PS2 or EPP mode\n",
vpo->vpo_unit);
- ppb_release_bus(&vpo->vpo_dev);
+ ppb_release_bus(ppbus, vpo->vpo_dev);
free(vpo->vpo_nibble_inbyte_msq, M_DEVBUF);
- return (0);
+ return (ENXIO);
}
- ppb_release_bus(&vpo->vpo_dev);
+ ppb_release_bus(ppbus, vpo->vpo_dev);
- return (1);
+ return (0);
}
/*
@@ -644,6 +651,7 @@ imm_attach(struct vpoio_data *vpo)
int
imm_reset_bus(struct vpoio_data *vpo)
{
+ device_t ppbus = device_get_parent(vpo->vpo_dev);
int disconnected;
/* first, connect to the drive and request the bus */
@@ -652,7 +660,7 @@ imm_reset_bus(struct vpoio_data *vpo)
if (!disconnected) {
/* reset the SCSI bus */
- ppb_MS_microseq(&vpo->vpo_dev, reset_microseq, NULL);
+ ppb_MS_microseq(ppbus, vpo->vpo_dev, reset_microseq, NULL);
/* then disconnect */
imm_disconnect(vpo, NULL, 1);
@@ -672,7 +680,7 @@ imm_do_scsi(struct vpoio_data *vpo, int host, int target, char *command,
int clen, char *buffer, int blen, int *result, int *count,
int *ret)
{
-
+ device_t ppbus = device_get_parent(vpo->vpo_dev);
register char r;
char l, h = 0;
int len, error = 0, not_connected = 0;
@@ -752,7 +760,7 @@ imm_do_scsi(struct vpoio_data *vpo, int host, int target, char *command,
error = imm_outstr(vpo, &buffer[*count], len);
} else {
- if (!PPB_IN_EPP_MODE(&vpo->vpo_dev))
+ if (!PPB_IN_EPP_MODE(ppbus))
len = 1;
else
len = (((blen - *count) >= VP0_SECTOR_SIZE)) ?
@@ -769,9 +777,9 @@ imm_do_scsi(struct vpoio_data *vpo, int host, int target, char *command,
*count += len;
}
- if ((PPB_IN_NIBBLE_MODE(&vpo->vpo_dev) ||
- PPB_IN_PS2_MODE(&vpo->vpo_dev)) && negociated)
- ppb_MS_microseq(&vpo->vpo_dev, transfer_epilog, NULL);
+ if ((PPB_IN_NIBBLE_MODE(ppbus) ||
+ PPB_IN_PS2_MODE(ppbus)) && negociated)
+ ppb_MS_microseq(ppbus, vpo->vpo_dev, transfer_epilog, NULL);
/*
* Retrieve status ...
@@ -795,9 +803,9 @@ imm_do_scsi(struct vpoio_data *vpo, int host, int target, char *command,
*result = ((int) h << 8) | ((int) l & 0xff);
error:
- if ((PPB_IN_NIBBLE_MODE(&vpo->vpo_dev) ||
- PPB_IN_PS2_MODE(&vpo->vpo_dev)) && negociated)
- ppb_MS_microseq(&vpo->vpo_dev, transfer_epilog, NULL);
+ if ((PPB_IN_NIBBLE_MODE(ppbus) ||
+ PPB_IN_PS2_MODE(ppbus)) && negociated)
+ ppb_MS_microseq(ppbus, vpo->vpo_dev, transfer_epilog, NULL);
/* return to printer state, release the ppbus */
imm_disconnect(vpo, NULL, 1);
diff --git a/sys/dev/ppbus/lpbb.c b/sys/dev/ppbus/lpbb.c
index b98f80e2..5b0c75e 100644
--- a/sys/dev/ppbus/lpbb.c
+++ b/sys/dev/ppbus/lpbb.c
@@ -46,19 +46,19 @@
#include <machine/clock.h>
#include <dev/ppbus/ppbconf.h>
+#include "ppbus_if.h"
+#include <dev/ppbus/ppbio.h>
#include <dev/iicbus/iiconf.h>
#include <dev/iicbus/iicbus.h>
#include "iicbb_if.h"
-/* iicbus softc */
struct lpbb_softc {
-
- struct ppb_device lpbb_dev;
+ int dummy;
};
-static int lpbb_detect(struct lpbb_softc *);
+static int lpbb_detect(device_t dev);
static int lpbb_probe(device_t);
static int lpbb_attach(device_t);
@@ -93,38 +93,14 @@ static driver_t lpbb_driver = {
sizeof(struct lpbb_softc),
};
-/*
- * Make ourselves visible as a ppbus driver
- */
-static struct ppb_device *lpbb_ppb_probe(struct ppb_data *ppb);
-static int lpbb_ppb_attach(struct ppb_device *dev);
-
-#define MAXLPBB 8 /* XXX not much better! */
-static struct lpbb_softc *lpbbdata[MAXLPBB];
-static int nlpbb = 0;
-
-#ifdef _KERNEL
-
-static struct ppb_driver lpbbdriver = {
- lpbb_ppb_probe, lpbb_ppb_attach, "lpbb"
-};
-DATA_SET(ppbdriver_set, lpbbdriver);
-
-#endif
-
static int
lpbb_probe(device_t dev)
{
- struct lpbb_softc *sc = lpbbdata[device_get_unit(dev)];
- struct lpbb_softc *scdst = (struct lpbb_softc *)device_get_softc(dev);
-
- /* XXX copy softc. Yet, ppbus device is sc->lpbb_dev, but will be
- * dev->parent when ppbus will be ported to the new bus architecture */
- bcopy(sc, scdst, sizeof(struct lpbb_softc));
+ device_set_desc(dev, "Parallel I2C bit-banging interface");
- device_set_desc(dev, "parallel I2C bit-banging interface");
+ if (!lpbb_detect(dev))
+ return (ENXIO);
- /* probe done by ppbus initialization */
return (0);
}
@@ -147,60 +123,10 @@ lpbb_attach(device_t dev)
return (0);
}
-/*
- * lppbb_ppb_probe()
- */
-static struct ppb_device *
-lpbb_ppb_probe(struct ppb_data *ppb)
-{
- struct lpbb_softc *sc;
-
- sc = (struct lpbb_softc *) malloc(sizeof(struct lpbb_softc),
- M_TEMP, M_NOWAIT);
- if (!sc) {
- printf("lpbb: cannot malloc!\n");
- return (0);
- }
- bzero(sc, sizeof(struct lpbb_softc));
-
- lpbbdata[nlpbb] = sc;
-
- /*
- * ppbus dependent initialisation.
- */
- sc->lpbb_dev.id_unit = nlpbb;
- sc->lpbb_dev.name = lpbbdriver.name;
- sc->lpbb_dev.ppb = ppb;
- sc->lpbb_dev.intr = 0;
-
- if (!lpbb_detect(sc)) {
- free(sc, M_TEMP);
- return (NULL);
- }
-
- /* Ok, go to next device on next probe */
- nlpbb ++;
-
- /* XXX wrong according to new bus architecture. ppbus needs to be
- * ported
- */
- return (&sc->lpbb_dev);
-}
-
-static int
-lpbb_ppb_attach(struct ppb_device *dev)
-{
- /* add the parallel port I2C interface to the bus tree */
- if (!device_add_child(root_bus, "lpbb", dev->id_unit))
- return (0);
-
- return (1);
-}
-
static int
lpbb_callback(device_t dev, int index, caddr_t *data)
{
- struct lpbb_softc *sc = (struct lpbb_softc *)device_get_softc(dev);
+ device_t ppbus = device_get_parent(dev);
int error = 0;
int how;
@@ -208,12 +134,12 @@ lpbb_callback(device_t dev, int index, caddr_t *data)
case IIC_REQUEST_BUS:
/* request the ppbus */
how = *(int *)data;
- error = ppb_request_bus(&sc->lpbb_dev, how);
+ error = ppb_request_bus(ppbus, dev, how);
break;
case IIC_RELEASE_BUS:
/* release the ppbus */
- error = ppb_release_bus(&sc->lpbb_dev);
+ error = ppb_release_bus(ppbus, dev);
break;
default:
@@ -230,49 +156,51 @@ lpbb_callback(device_t dev, int index, caddr_t *data)
#define ALIM 0x20
#define I2CKEY 0x50
-static int getSDA(struct lpbb_softc *sc)
+static int getSDA(device_t ppbus)
{
-if((ppb_rstr(&sc->lpbb_dev)&SDA_in)==SDA_in)
- return 1;
-else
- return 0;
+ if((ppb_rstr(ppbus)&SDA_in)==SDA_in)
+ return 1;
+ else
+ return 0;
}
-static void setSDA(struct lpbb_softc *sc, char val)
+static void setSDA(device_t ppbus, char val)
{
-if(val==0)
- ppb_wdtr(&sc->lpbb_dev, (u_char)SDA_out);
-else
- ppb_wdtr(&sc->lpbb_dev, (u_char)~SDA_out);
+ if(val==0)
+ ppb_wdtr(ppbus, (u_char)SDA_out);
+ else
+ ppb_wdtr(ppbus, (u_char)~SDA_out);
}
-static void setSCL(struct lpbb_softc *sc, unsigned char val)
+static void setSCL(device_t ppbus, unsigned char val)
{
-if(val==0)
- ppb_wctr(&sc->lpbb_dev, (u_char)(ppb_rctr(&sc->lpbb_dev)&~SCL_out));
-else
- ppb_wctr(&sc->lpbb_dev, (u_char)(ppb_rctr(&sc->lpbb_dev)|SCL_out));
+ if(val==0)
+ ppb_wctr(ppbus, (u_char)(ppb_rctr(ppbus)&~SCL_out));
+ else
+ ppb_wctr(ppbus, (u_char)(ppb_rctr(ppbus)|SCL_out));
}
-static int lpbb_detect(struct lpbb_softc *sc)
+static int lpbb_detect(device_t dev)
{
- if (ppb_request_bus(&sc->lpbb_dev, PPB_DONTWAIT)) {
- printf("lpbb: can't allocate ppbus\n");
+ device_t ppbus = device_get_parent(dev);
+
+ if (ppb_request_bus(ppbus, dev, PPB_DONTWAIT)) {
+ device_printf(dev, "can't allocate ppbus\n");
return (0);
}
/* reset bus */
- setSDA(sc, 1);
- setSCL(sc, 1);
+ setSDA(ppbus, 1);
+ setSCL(ppbus, 1);
- if ((ppb_rstr(&sc->lpbb_dev) & I2CKEY) ||
- ((ppb_rstr(&sc->lpbb_dev) & ALIM) != ALIM)) {
+ if ((ppb_rstr(ppbus) & I2CKEY) ||
+ ((ppb_rstr(ppbus) & ALIM) != ALIM)) {
- ppb_release_bus(&sc->lpbb_dev);
+ ppb_release_bus(ppbus, dev);
return (0);
}
- ppb_release_bus(&sc->lpbb_dev);
+ ppb_release_bus(ppbus, dev);
return (1);
}
@@ -280,11 +208,11 @@ static int lpbb_detect(struct lpbb_softc *sc)
static int
lpbb_reset(device_t dev, u_char speed, u_char addr, u_char * oldaddr)
{
- struct lpbb_softc *sc = (struct lpbb_softc *)device_get_softc(dev);
+ device_t ppbus = device_get_parent(dev);
/* reset bus */
- setSDA(sc, 1);
- setSCL(sc, 1);
+ setSDA(ppbus, 1);
+ setSCL(ppbus, 1);
return (IIC_ENOADDR);
}
@@ -292,18 +220,18 @@ lpbb_reset(device_t dev, u_char speed, u_char addr, u_char * oldaddr)
static void
lpbb_setlines(device_t dev, int ctrl, int data)
{
- struct lpbb_softc *sc = (struct lpbb_softc *)device_get_softc(dev);
+ device_t ppbus = device_get_parent(dev);
- setSCL(sc, ctrl);
- setSDA(sc, data);
+ setSCL(ppbus, ctrl);
+ setSDA(ppbus, data);
}
static int
lpbb_getdataline(device_t dev)
{
- struct lpbb_softc *sc = (struct lpbb_softc *)device_get_softc(dev);
+ device_t ppbus = device_get_parent(dev);
- return (getSDA(sc));
+ return (getSDA(ppbus));
}
-DRIVER_MODULE(lpbb, root, lpbb_driver, lpbb_devclass, 0, 0);
+DRIVER_MODULE(lpbb, ppbus, lpbb_driver, lpbb_devclass, 0, 0);
diff --git a/sys/dev/ppbus/lpt.c b/sys/dev/ppbus/lpt.c
index 531ad48..f652a81 100644
--- a/sys/dev/ppbus/lpt.c
+++ b/sys/dev/ppbus/lpt.c
@@ -60,28 +60,37 @@
* Updated for ppbus by Nicolas Souchu
* [Mon Jul 28 1997]
*/
+#include "lpt.h"
+#if NLPT > 0
#ifdef _KERNEL
+#include "opt_lpt.h"
+
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/module.h>
+#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/buf.h>
#include <sys/kernel.h>
#include <sys/uio.h>
#include <sys/syslog.h>
-#include <sys/malloc.h>
#include <machine/clock.h>
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/rman.h>
+
#include <machine/lpt.h>
#endif
#include <dev/ppbus/ppbconf.h>
#include <dev/ppbus/ppb_1284.h>
#include <dev/ppbus/lpt.h>
-
-#include "opt_lpt.h"
+#include "ppbus_if.h"
+#include <dev/ppbus/ppbio.h>
#ifndef LPT_DEBUG
#define lprintf(args)
@@ -105,9 +114,6 @@ static int volatile lptflag = 1;
#define LPTFLAGS(s) ((s)&0xfc)
struct lpt_data {
- unsigned short lpt_unit;
-
- struct ppb_device lpt_dev;
short sc_state;
/* default case: negative prime, negative ack, handshake strobe,
@@ -132,36 +138,45 @@ struct lpt_data {
#define LP_ENABLE_EXT 0x10 /* we shall use advanced mode when possible */
u_char sc_backoff ; /* time to call lptout() again */
-};
+ struct resource *intr_resource; /* interrupt resource */
+ void *intr_cookie; /* interrupt registration cookie */
-static int nlpt = 0;
-#define MAXLPT 8 /* XXX not much better! */
-static struct lpt_data *lptdata[MAXLPT];
+};
#define LPT_NAME "lpt" /* our official name */
static timeout_t lptout;
-static int lpt_port_test(struct lpt_data *sc, u_char data, u_char mask);
-static int lpt_detect(struct lpt_data *sc);
+static int lpt_port_test(device_t dev, u_char data, u_char mask);
+static int lpt_detect(device_t dev);
-/*
- * Make ourselves visible as a ppbus driver
- */
+#define DEVTOSOFTC(dev) \
+ ((struct lpt_data *)device_get_softc(dev))
+#define UNITOSOFTC(unit) \
+ ((struct lpt_data *)devclass_get_softc(lpt_devclass, (unit)))
+#define UNITODEVICE(unit) \
+ (devclass_get_device(lpt_devclass, (unit)))
-static struct ppb_device *lptprobe(struct ppb_data *ppb);
-static int lptattach(struct ppb_device *dev);
-static void lptintr(int unit);
+static int lpt_probe(device_t dev);
+static int lpt_attach(device_t dev);
-static void lpt_intr(int unit); /* without spls */
+static void lptintr(device_t dev);
+static void lpt_intr(void *arg); /* without spls */
-#ifdef _KERNEL
+static devclass_t lpt_devclass;
+
+static device_method_t lpt_methods[] = {
+ /* device interface */
+ DEVMETHOD(device_probe, lpt_probe),
+ DEVMETHOD(device_attach, lpt_attach),
-static struct ppb_driver lptdriver = {
- lptprobe, lptattach, LPT_NAME
+ { 0, 0 }
};
-DATA_SET(ppbdriver_set, lptdriver);
-#endif
+static driver_t lpt_driver = {
+ "lpt",
+ lpt_methods,
+ sizeof(struct lpt_data),
+};
/* bits for state */
#define OPEN (1<<0) /* device is open */
@@ -184,7 +199,7 @@ DATA_SET(ppbdriver_set, lptdriver);
/* Only used in polling code */
#define LPS_INVERT (LPS_NBSY | LPS_NACK | LPS_SEL | LPS_NERR)
#define LPS_MASK (LPS_NBSY | LPS_NACK | LPS_OUT | LPS_SEL | LPS_NERR)
-#define NOT_READY(lpt) ((ppb_rstr(&(lpt)->lpt_dev)^LPS_INVERT)&LPS_MASK)
+#define NOT_READY(ppbus) ((ppb_rstr(ppbus)^LPS_INVERT)&LPS_MASK)
#define MAX_SLEEP (hz*5) /* Timeout while waiting for device ready */
#define MAX_SPIN 20 /* Max delay for device ready in usecs */
@@ -215,43 +230,49 @@ static struct cdevsw lpt_cdevsw = {
};
static int
-lpt_request_ppbus(struct lpt_data *sc, int how)
+lpt_request_ppbus(device_t dev, int how)
{
+ device_t ppbus = device_get_parent(dev);
+ struct lpt_data *sc = DEVTOSOFTC(dev);
int error;
if (sc->sc_state & HAVEBUS)
return (0);
/* we have the bus only if the request succeded */
- if ((error = ppb_request_bus(&sc->lpt_dev, how)) == 0)
+ if ((error = ppb_request_bus(ppbus, dev, how)) == 0)
sc->sc_state |= HAVEBUS;
return (error);
}
static int
-lpt_release_ppbus(struct lpt_data *sc)
+lpt_release_ppbus(device_t dev)
{
- ppb_release_bus(&sc->lpt_dev);
- sc->sc_state &= ~HAVEBUS;
+ device_t ppbus = device_get_parent(dev);
+ struct lpt_data *sc = DEVTOSOFTC(dev);
+ int error = 0;
- return (0);
+ if ((error = ppb_release_bus(ppbus, dev)) == 0)
+ sc->sc_state &= ~HAVEBUS;
+
+ return (error);
}
/*
* Internal routine to lptprobe to do port tests of one byte value
*/
static int
-lpt_port_test(struct lpt_data *sc, u_char data, u_char mask)
+lpt_port_test(device_t ppbus, u_char data, u_char mask)
{
int temp, timeout;
data = data & mask;
- ppb_wdtr(&sc->lpt_dev, data);
+ ppb_wdtr(ppbus, data);
timeout = 10000;
do {
DELAY(10);
- temp = ppb_rdtr(&sc->lpt_dev) & mask;
+ temp = ppb_rdtr(ppbus) & mask;
}
while (temp != data && --timeout);
lprintf(("out=%x\tin=%x\ttout=%d\n", data, temp, timeout));
@@ -306,8 +327,10 @@ lpt_port_test(struct lpt_data *sc, u_char data, u_char mask)
* Quick exit on fail added.
*/
static int
-lpt_detect(struct lpt_data *sc)
+lpt_detect(device_t dev)
{
+ device_t ppbus = device_get_parent(dev);
+
static u_char testbyte[18] = {
0x55, /* alternating zeros */
0xaa, /* alternating ones */
@@ -320,33 +343,33 @@ lpt_detect(struct lpt_data *sc)
status = 1; /* assume success */
- if ((error = lpt_request_ppbus(sc, PPB_DONTWAIT))) {
+ if ((error = lpt_request_ppbus(dev, PPB_DONTWAIT))) {
printf(LPT_NAME ": cannot alloc ppbus (%d)!\n", error);
status = 0;
goto end_probe;
}
for (i = 0; i < 18 && status; i++)
- if (!lpt_port_test(sc, testbyte[i], 0xff)) {
+ if (!lpt_port_test(ppbus, testbyte[i], 0xff)) {
status = 0;
goto end_probe;
}
end_probe:
/* write 0's to control and data ports */
- ppb_wdtr(&sc->lpt_dev, 0);
- ppb_wctr(&sc->lpt_dev, 0);
+ ppb_wdtr(ppbus, 0);
+ ppb_wctr(ppbus, 0);
- lpt_release_ppbus(sc);
+ lpt_release_ppbus(dev);
return (status);
}
/*
- * lptprobe()
+ * lpt_probe()
*/
-static struct ppb_device *
-lptprobe(struct ppb_data *ppb)
+static int
+lpt_probe(device_t dev)
{
struct lpt_data *sc;
static int once;
@@ -354,96 +377,81 @@ lptprobe(struct ppb_data *ppb)
if (!once++)
cdevsw_add(&lpt_cdevsw);
- sc = (struct lpt_data *) malloc(sizeof(struct lpt_data),
- M_TEMP, M_NOWAIT);
- if (!sc) {
- printf(LPT_NAME ": cannot malloc!\n");
- return (0);
- }
+ sc = DEVTOSOFTC(dev);
bzero(sc, sizeof(struct lpt_data));
- lptdata[nlpt] = sc;
-
- /*
- * lpt dependent initialisation.
- */
- sc->lpt_unit = nlpt;
-
- /*
- * ppbus dependent initialisation.
- */
- sc->lpt_dev.id_unit = sc->lpt_unit;
- sc->lpt_dev.name = lptdriver.name;
- sc->lpt_dev.ppb = ppb;
- sc->lpt_dev.intr = lptintr;
-
/*
* Now, try to detect the printer.
*/
- if (!lpt_detect(sc)) {
- free(sc, M_TEMP);
- return (0);
- }
+ if (!lpt_detect(dev))
+ return (ENXIO);
- /* Ok, go to next device on next probe */
- nlpt ++;
+ device_set_desc(dev, "Printer");
- return (&sc->lpt_dev);
+ return (0);
}
static int
-lptattach(struct ppb_device *dev)
+lpt_attach(device_t dev)
{
- struct lpt_data *sc = lptdata[dev->id_unit];
+ device_t ppbus = device_get_parent(dev);
+ struct lpt_data *sc = DEVTOSOFTC(dev);
+ int zero = 0, irq, unit = device_get_unit(dev);
int error;
- /*
- * Report ourselves
- */
- printf(LPT_NAME "%d: <generic printer> on ppbus %d\n",
- dev->id_unit, dev->ppb->ppb_link->adapter_unit);
-
sc->sc_primed = 0; /* not primed yet */
- if ((error = lpt_request_ppbus(sc, PPB_DONTWAIT))) {
+ if ((error = lpt_request_ppbus(dev, PPB_DONTWAIT))) {
printf(LPT_NAME ": cannot alloc ppbus (%d)!\n", error);
return (0);
}
- ppb_wctr(&sc->lpt_dev, LPC_NINIT);
+ ppb_wctr(ppbus, LPC_NINIT);
/* check if we can use interrupt, should be done by ppc stuff */
lprintf(("oldirq %x\n", sc->sc_irq));
- if (ppb_get_irq(&sc->lpt_dev)) {
+
+ /* retrieve the ppbus irq */
+ BUS_READ_IVAR(ppbus, dev, PPBUS_IVAR_IRQ, &irq);
+
+ if (irq > 0) {
+ /* declare our interrupt handler */
+ sc->intr_resource = bus_alloc_resource(dev, SYS_RES_IRQ,
+ &zero, irq, irq, 1, RF_SHAREABLE);
+ }
+ if (sc->intr_resource) {
sc->sc_irq = LP_HAS_IRQ | LP_USE_IRQ | LP_ENABLE_IRQ;
- printf(LPT_NAME "%d: Interrupt-driven port\n", dev->id_unit);
+ device_printf(dev, "Interrupt-driven port\n");
} else {
sc->sc_irq = 0;
- lprintf((LPT_NAME "%d: Polled port\n", dev->id_unit));
+ device_printf(dev, "Polled port\n");
}
- lprintf(("irq %x\n", sc->sc_irq));
+ lprintf(("irq %x %x\n", irq, sc->sc_irq));
- lpt_release_ppbus(sc);
+ lpt_release_ppbus(dev);
- make_dev(&lpt_cdevsw, dev->id_unit,
- UID_ROOT, GID_WHEEL, 0600, LPT_NAME "%d", dev->id_unit);
- make_dev(&lpt_cdevsw, dev->id_unit | LP_BYPASS,
- UID_ROOT, GID_WHEEL, 0600, LPT_NAME "%d.ctl", dev->id_unit);
- return (1);
+ make_dev(&lpt_cdevsw, unit,
+ UID_ROOT, GID_WHEEL, 0600, LPT_NAME "%d", unit);
+ make_dev(&lpt_cdevsw, unit | LP_BYPASS,
+ UID_ROOT, GID_WHEEL, 0600, LPT_NAME "%d.ctl", unit);
+ return (0);
}
static void
lptout(void *arg)
{
- struct lpt_data *sc = arg;
- int pl;
+ device_t dev = (device_t)arg;
+ struct lpt_data *sc = DEVTOSOFTC(dev);
+#ifdef LPT_DEBUG
+ device_t ppbus = device_get_parent(dev);
+#endif
- lprintf(("T %x ", ppb_rstr(&sc->lpt_dev)));
+ lprintf(("T %x ", ppb_rstr(ppbus)));
if (sc->sc_state & OPEN) {
sc->sc_backoff++;
if (sc->sc_backoff > hz/LPTOUTMAX)
sc->sc_backoff = sc->sc_backoff > hz/LPTOUTMAX;
- timeout(lptout, (caddr_t)sc, sc->sc_backoff);
+ timeout(lptout, (caddr_t)dev, sc->sc_backoff);
} else
sc->sc_state &= ~TOUT;
@@ -451,15 +459,13 @@ lptout(void *arg)
sc->sc_state &= ~EERROR;
/*
- * Avoid possible hangs do to missed interrupts
+ * Avoid possible hangs due to missed interrupts
*/
if (sc->sc_xfercnt) {
- pl = spltty();
- lpt_intr(sc->lpt_unit);
- splx(pl);
+ lptintr(dev);
} else {
sc->sc_state &= ~OBUSY;
- wakeup((caddr_t)sc);
+ wakeup((caddr_t)dev);
}
}
@@ -472,17 +478,16 @@ lptout(void *arg)
static int
lptopen(dev_t dev, int flags, int fmt, struct proc *p)
{
- struct lpt_data *sc;
-
int s;
int trys, err;
u_int unit = LPTUNIT(minor(dev));
+ struct lpt_data *sc = UNITOSOFTC(unit);
+ device_t lptdev = UNITODEVICE(unit);
+ device_t ppbus = device_get_parent(lptdev);
- if ((unit >= nlpt))
+ if (!sc)
return (ENXIO);
- sc = lptdata[unit];
-
if (sc->sc_state) {
lprintf((LPT_NAME ": still open %x\n", sc->sc_state));
return(EBUSY);
@@ -498,13 +503,17 @@ lptopen(dev_t dev, int flags, int fmt, struct proc *p)
}
/* request the ppbus only if we don't have it already */
- if ((err = lpt_request_ppbus(sc, PPB_WAIT|PPB_INTR)) != 0)
+ if ((err = lpt_request_ppbus(lptdev, PPB_WAIT|PPB_INTR)) != 0) {
+ /* give it a chance to try later */
+ sc->sc_state = 0;
return (err);
+ }
s = spltty();
lprintf((LPT_NAME " flags 0x%x\n", sc->sc_flags));
- /* set IRQ status according to ENABLE_IRQ flag */
+ /* set IRQ status according to ENABLE_IRQ flag
+ */
if (sc->sc_irq & LP_ENABLE_IRQ)
sc->sc_irq |= LP_USE_IRQ;
else
@@ -513,13 +522,13 @@ lptopen(dev_t dev, int flags, int fmt, struct proc *p)
/* init printer */
if ((sc->sc_flags & LP_NO_PRIME) == 0) {
if((sc->sc_flags & LP_PRIMEOPEN) || sc->sc_primed == 0) {
- ppb_wctr(&sc->lpt_dev, 0);
+ ppb_wctr(ppbus, 0);
sc->sc_primed++;
DELAY(500);
}
}
- ppb_wctr(&sc->lpt_dev, LPC_SEL|LPC_NINIT);
+ ppb_wctr(ppbus, LPC_SEL|LPC_NINIT);
/* wait till ready (printer running diagnostics) */
trys = 0;
@@ -528,24 +537,24 @@ lptopen(dev_t dev, int flags, int fmt, struct proc *p)
if (trys++ >= LPINITRDY*4) {
splx(s);
sc->sc_state = 0;
- lprintf(("status %x\n", ppb_rstr(&sc->lpt_dev)));
+ lprintf(("status %x\n", ppb_rstr(ppbus)));
- lpt_release_ppbus(sc);
+ lpt_release_ppbus(lptdev);
return (EBUSY);
}
/* wait 1/4 second, give up if we get a signal */
- if (tsleep((caddr_t)sc, LPPRI|PCATCH, "lptinit", hz/4) !=
+ if (tsleep((caddr_t)lptdev, LPPRI|PCATCH, "lptinit", hz/4) !=
EWOULDBLOCK) {
sc->sc_state = 0;
splx(s);
- lpt_release_ppbus(sc);
+ lpt_release_ppbus(lptdev);
return (EBUSY);
}
/* is printer online and ready for output */
- } while ((ppb_rstr(&sc->lpt_dev) &
+ } while ((ppb_rstr(ppbus) &
(LPS_SEL|LPS_OUT|LPS_NBSY|LPS_NERR)) !=
(LPS_SEL|LPS_NBSY|LPS_NERR));
@@ -557,7 +566,7 @@ lptopen(dev_t dev, int flags, int fmt, struct proc *p)
if (sc->sc_irq & LP_USE_IRQ)
sc->sc_control |= LPC_ENA;
- ppb_wctr(&sc->lpt_dev, sc->sc_control);
+ ppb_wctr(ppbus, sc->sc_control);
sc->sc_state = OPEN;
sc->sc_inbuf = geteblk(BUFSIZE);
@@ -566,13 +575,13 @@ lptopen(dev_t dev, int flags, int fmt, struct proc *p)
splx(s);
/* release the ppbus */
- lpt_release_ppbus(sc);
+ lpt_release_ppbus(lptdev);
/* only use timeout if using interrupt */
lprintf(("irq %x\n", sc->sc_irq));
if (sc->sc_irq & LP_USE_IRQ) {
sc->sc_state |= TOUT;
- timeout(lptout, (caddr_t)sc,
+ timeout(lptout, (caddr_t)lptdev,
(sc->sc_backoff = hz/LPTOUTINITIAL));
}
@@ -589,34 +598,39 @@ lptopen(dev_t dev, int flags, int fmt, struct proc *p)
static int
lptclose(dev_t dev, int flags, int fmt, struct proc *p)
{
- struct lpt_data *sc = lptdata[LPTUNIT(minor(dev))];
+ u_int unit = LPTUNIT(minor(dev));
+ struct lpt_data *sc = UNITOSOFTC(unit);
+ device_t lptdev = UNITODEVICE(unit);
+ device_t ppbus = device_get_parent(lptdev);
int err;
if(sc->sc_flags & LP_BYPASS)
goto end_close;
- if ((err = lpt_request_ppbus(sc, PPB_WAIT|PPB_INTR)) != 0)
+ if ((err = lpt_request_ppbus(lptdev, PPB_WAIT|PPB_INTR)) != 0)
return (err);
sc->sc_state &= ~OPEN;
/* if the last write was interrupted, don't complete it */
if((!(sc->sc_state & INTERRUPTED)) && (sc->sc_irq & LP_USE_IRQ))
- while ((ppb_rstr(&sc->lpt_dev) &
+ while ((ppb_rstr(ppbus) &
(LPS_SEL|LPS_OUT|LPS_NBSY|LPS_NERR)) !=
(LPS_SEL|LPS_NBSY|LPS_NERR) || sc->sc_xfercnt)
/* wait 1/4 second, give up if we get a signal */
- if (tsleep((caddr_t)sc, LPPRI|PCATCH,
+ if (tsleep((caddr_t)lptdev, LPPRI|PCATCH,
"lpclose", hz) != EWOULDBLOCK)
break;
- ppb_wctr(&sc->lpt_dev, LPC_NINIT);
+ ppb_wctr(ppbus, LPC_NINIT);
brelse(sc->sc_inbuf);
brelse(sc->sc_statbuf);
end_close:
- /* release the bus anyway */
- lpt_release_ppbus(sc);
+ /* release the bus anyway
+ * unregistration of interrupt forced by release
+ */
+ lpt_release_ppbus(lptdev);
sc->sc_state = 0;
sc->sc_xfercnt = 0;
@@ -633,8 +647,10 @@ end_close:
* This code is only used when we are polling the port
*/
static int
-lpt_pushbytes(struct lpt_data *sc)
+lpt_pushbytes(device_t dev)
{
+ struct lpt_data *sc = DEVTOSOFTC(dev);
+ device_t ppbus = device_get_parent(dev);
int spin, err, tic;
char ch;
@@ -651,11 +667,11 @@ lpt_pushbytes(struct lpt_data *sc)
* Loop 20 usecs testing BUSY bit, then sleep
* for exponentially increasing timeout. (vak)
*/
- for (spin = 0; NOT_READY(sc) && spin < MAX_SPIN; ++spin)
+ for (spin = 0; NOT_READY(ppbus) && spin < MAX_SPIN; ++spin)
DELAY(1); /* XXX delay is NOT this accurate! */
if (spin >= MAX_SPIN) {
tic = 0;
- while (NOT_READY(sc)) {
+ while (NOT_READY(ppbus)) {
/*
* Now sleep, every cycle a
* little longer ..
@@ -666,7 +682,7 @@ lpt_pushbytes(struct lpt_data *sc)
*/
if (tic > MAX_SLEEP)
tic = MAX_SLEEP;
- err = tsleep((caddr_t)sc, LPPRI,
+ err = tsleep((caddr_t)dev, LPPRI,
LPT_NAME "poll", tic);
if (err != EWOULDBLOCK) {
return (err);
@@ -675,10 +691,10 @@ lpt_pushbytes(struct lpt_data *sc)
}
/* output data */
- ppb_wdtr(&sc->lpt_dev, ch);
+ ppb_wdtr(ppbus, ch);
/* strobe */
- ppb_wctr(&sc->lpt_dev, sc->sc_control|LPC_STB);
- ppb_wctr(&sc->lpt_dev, sc->sc_control);
+ ppb_wctr(ppbus, sc->sc_control|LPC_STB);
+ ppb_wctr(ppbus, sc->sc_control);
}
return(0);
@@ -691,16 +707,19 @@ lpt_pushbytes(struct lpt_data *sc)
static int
lptread(dev_t dev, struct uio *uio, int ioflag)
{
- struct lpt_data *sc = lptdata[LPTUNIT(minor(dev))];
+ u_int unit = LPTUNIT(minor(dev));
+ struct lpt_data *sc = UNITOSOFTC(unit);
+ device_t lptdev = UNITODEVICE(unit);
+ device_t ppbus = device_get_parent(lptdev);
int error = 0, len;
- if ((error = ppb_1284_negociate(&sc->lpt_dev, PPB_NIBBLE, 0)))
+ if ((error = ppb_1284_negociate(ppbus, PPB_NIBBLE, 0)))
return (error);
/* read data in an other buffer, read/write may be simultaneous */
len = 0;
while (uio->uio_resid) {
- if ((error = ppb_1284_read(&sc->lpt_dev, PPB_NIBBLE,
+ if ((error = ppb_1284_read(ppbus, PPB_NIBBLE,
sc->sc_statbuf->b_data, min(BUFSTATSIZE,
uio->uio_resid), &len))) {
goto error;
@@ -714,7 +733,7 @@ lptread(dev_t dev, struct uio *uio, int ioflag)
}
error:
- ppb_1284_terminate(&sc->lpt_dev);
+ ppb_1284_terminate(ppbus);
return (error);
}
@@ -729,9 +748,11 @@ static int
lptwrite(dev_t dev, struct uio *uio, int ioflag)
{
register unsigned n;
- int pl, err;
+ int err;
u_int unit = LPTUNIT(minor(dev));
- struct lpt_data *sc = lptdata[LPTUNIT(minor(dev))];
+ struct lpt_data *sc = UNITOSOFTC(unit);
+ device_t lptdev = UNITODEVICE(unit);
+ device_t ppbus = device_get_parent(lptdev);
if(sc->sc_flags & LP_BYPASS) {
/* we can't do writes in bypass mode */
@@ -739,9 +760,22 @@ lptwrite(dev_t dev, struct uio *uio, int ioflag)
}
/* request the ppbus only if we don't have it already */
- if ((err = lpt_request_ppbus(sc, PPB_WAIT|PPB_INTR)) != 0)
+ /* XXX interrupt registration?! */
+ if ((err = lpt_request_ppbus(lptdev, PPB_WAIT|PPB_INTR)) != 0)
return (err);
+ /* if interrupts are working, register the handler */
+ if (sc->sc_irq & LP_USE_IRQ) {
+ /* register our interrupt handler */
+ err = BUS_SETUP_INTR(ppbus, lptdev, sc->intr_resource,
+ INTR_TYPE_TTY, lpt_intr, lptdev,
+ &sc->intr_cookie);
+ if (err) {
+ device_printf(lptdev, "handler registration failed, polled mode.\n");
+ sc->sc_irq &= ~LP_USE_IRQ;
+ }
+ }
+
sc->sc_state &= ~INTERRUPTED;
while ((n = min(BUFSIZE, uio->uio_resid)) != 0) {
sc->sc_cp = sc->sc_inbuf->b_data ;
@@ -750,8 +784,8 @@ lptwrite(dev_t dev, struct uio *uio, int ioflag)
if (sc->sc_irq & LP_ENABLE_EXT) {
/* try any extended mode */
- err = ppb_write(&sc->lpt_dev, sc->sc_cp,
- sc->sc_xfercnt, 0);
+ err = ppb_write(ppbus, sc->sc_cp,
+ sc->sc_xfercnt, 0);
switch (err) {
case 0:
/* if not all data was sent, we could rely
@@ -774,13 +808,11 @@ lptwrite(dev_t dev, struct uio *uio, int ioflag)
/* give it one */
if ((sc->sc_state & OBUSY) == 0){
lprintf(("\nC %d. ", sc->sc_xfercnt));
- pl = spltty();
- lpt_intr(sc->lpt_unit);
- (void) splx(pl);
+ lptintr(lptdev);
}
lprintf(("W "));
if (sc->sc_state & OBUSY)
- if ((err = tsleep((caddr_t)sc,
+ if ((err = tsleep((caddr_t)lptdev,
LPPRI|PCATCH, LPT_NAME "write", 0))) {
sc->sc_state |= INTERRUPTED;
return(err);
@@ -791,7 +823,7 @@ lptwrite(dev_t dev, struct uio *uio, int ioflag)
if(!(sc->sc_irq & LP_USE_IRQ) && (sc->sc_xfercnt)) {
lprintf(("p"));
- err = lpt_pushbytes(sc);
+ err = lpt_pushbytes(lptdev);
if (err)
return(err);
@@ -799,7 +831,7 @@ lptwrite(dev_t dev, struct uio *uio, int ioflag)
}
/* we have not been interrupted, release the ppbus */
- lpt_release_ppbus(sc);
+ lpt_release_ppbus(lptdev);
return(0);
}
@@ -812,9 +844,11 @@ lptwrite(dev_t dev, struct uio *uio, int ioflag)
*/
static void
-lpt_intr(int unit)
+lpt_intr(void *arg)
{
- struct lpt_data *sc = lptdata[unit];
+ device_t lptdev = (device_t)arg;
+ device_t ppbus = device_get_parent(lptdev);
+ struct lpt_data *sc = DEVTOSOFTC(lptdev);
int sts;
int i;
@@ -829,7 +863,7 @@ lpt_intr(int unit)
* to see if the printer will become ready ``really soon now''.
*/
for (i = 0; i < 100 &&
- ((sts=ppb_rstr(&sc->lpt_dev)) & RDY_MASK) != LP_READY; i++) ;
+ ((sts=ppb_rstr(ppbus)) & RDY_MASK) != LP_READY; i++) ;
if ((sts & RDY_MASK) == LP_READY) {
sc->sc_state = (sc->sc_state | OBUSY) & ~EERROR;
@@ -838,10 +872,10 @@ lpt_intr(int unit)
if (sc->sc_xfercnt) {
/* send char */
/*lprintf(("%x ", *sc->sc_cp)); */
- ppb_wdtr(&sc->lpt_dev, *sc->sc_cp++) ;
- ppb_wctr(&sc->lpt_dev, sc->sc_control|LPC_STB);
+ ppb_wdtr(ppbus, *sc->sc_cp++) ;
+ ppb_wctr(ppbus, sc->sc_control|LPC_STB);
/* DELAY(X) */
- ppb_wctr(&sc->lpt_dev, sc->sc_control);
+ ppb_wctr(ppbus, sc->sc_control);
/* any more data for printer */
if(--(sc->sc_xfercnt) > 0) return;
@@ -867,12 +901,12 @@ lpt_intr(int unit)
}
static void
-lptintr(int unit)
+lptintr(device_t dev)
{
/* call the interrupt at required spl level */
int s = spltty();
- lpt_intr(unit);
+ lpt_intr(dev);
splx(s);
return;
@@ -882,12 +916,10 @@ static int
lptioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p)
{
int error = 0;
- struct lpt_data *sc;
u_int unit = LPTUNIT(minor(dev));
+ struct lpt_data *sc = UNITOSOFTC(unit);
u_char old_sc_irq; /* old printer IRQ status */
- sc = lptdata[unit];
-
switch (cmd) {
case LPT_IRQ :
if(sc->sc_irq & LP_HAS_IRQ) {
@@ -939,3 +971,8 @@ lptioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p)
return(error);
}
+
+DRIVER_MODULE(lpt, ppbus, lpt_driver, lpt_devclass, 0, 0);
+
+#endif
+
diff --git a/sys/dev/ppbus/ppb_1284.c b/sys/dev/ppbus/ppb_1284.c
index 3022174..2040874 100644
--- a/sys/dev/ppbus/ppb_1284.c
+++ b/sys/dev/ppbus/ppb_1284.c
@@ -35,27 +35,34 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/bus.h>
#include <machine/clock.h>
#include <dev/ppbus/ppbconf.h>
#include <dev/ppbus/ppb_1284.h>
+#include "ppbus_if.h"
+
+#include <dev/ppbus/ppbio.h>
+
+#define DEVTOSOFTC(dev) ((struct ppb_data *)device_get_softc(dev))
+
/*
* do_1284_wait()
*
* Wait for the peripherial up to 40ms
*/
static int
-do_1284_wait(struct ppb_device *dev, char mask, char status)
+do_1284_wait(device_t bus, char mask, char status)
{
- return (ppb_poll_device(dev, 4, mask, status, PPB_NOINTR | PPB_POLL));
+ return (ppb_poll_bus(bus, 4, mask, status, PPB_NOINTR | PPB_POLL));
}
static int
-do_peripheral_wait(struct ppb_device *dev, char mask, char status)
+do_peripheral_wait(device_t bus, char mask, char status)
{
- return (ppb_poll_device(dev, 100, mask, status, PPB_NOINTR | PPB_POLL));
+ return (ppb_poll_bus(bus, 100, mask, status, PPB_NOINTR | PPB_POLL));
}
#define nibble2char(s) (((s & ~nACK) >> 3) | (~s & nBUSY) >> 4)
@@ -66,10 +73,12 @@ do_peripheral_wait(struct ppb_device *dev, char mask, char status)
* Unconditionaly reset the error field
*/
static int
-ppb_1284_reset_error(struct ppb_device *dev, int state)
+ppb_1284_reset_error(device_t bus, int state)
{
- dev->ppb->error = PPB_NO_ERROR;
- dev->ppb->state = state;
+ struct ppb_data *ppb = DEVTOSOFTC(bus);
+
+ ppb->error = PPB_NO_ERROR;
+ ppb->state = state;
return (0);
}
@@ -80,9 +89,9 @@ ppb_1284_reset_error(struct ppb_device *dev, int state)
* Get IEEE1284 state
*/
static int
-ppb_1284_get_state(struct ppb_device *dev)
+ppb_1284_get_state(device_t bus)
{
- return (dev->ppb->state);
+ return (DEVTOSOFTC(bus)->state);
}
/*
@@ -91,32 +100,36 @@ ppb_1284_get_state(struct ppb_device *dev)
* Change IEEE1284 state if no error occured
*/
static int
-ppb_1284_set_state(struct ppb_device *dev, int state)
+ppb_1284_set_state(device_t bus, int state)
{
+ struct ppb_data *ppb = DEVTOSOFTC(bus);
+
/* call ppb_1284_reset_error() if you absolutly want to change
* the state from PPB_ERROR to another */
- if ((dev->ppb->state != PPB_ERROR) &&
- (dev->ppb->error == PPB_NO_ERROR)) {
- dev->ppb->state = state;
- dev->ppb->error = PPB_NO_ERROR;
+ if ((ppb->state != PPB_ERROR) &&
+ (ppb->error == PPB_NO_ERROR)) {
+ ppb->state = state;
+ ppb->error = PPB_NO_ERROR;
}
return (0);
}
static int
-ppb_1284_set_error(struct ppb_device *dev, int error, int event)
+ppb_1284_set_error(device_t bus, int error, int event)
{
+ struct ppb_data *ppb = DEVTOSOFTC(bus);
+
/* do not accumulate errors */
- if ((dev->ppb->error == PPB_NO_ERROR) &&
- (dev->ppb->state != PPB_ERROR)) {
- dev->ppb->error = error;
- dev->ppb->state = PPB_ERROR;
+ if ((ppb->error == PPB_NO_ERROR) &&
+ (ppb->state != PPB_ERROR)) {
+ ppb->error = error;
+ ppb->state = PPB_ERROR;
}
#ifdef DEBUG_1284
printf("ppb1284: error=%d status=0x%x event=%d\n", error,
- ppb_rstr(dev) & 0xff, event);
+ ppb_rstr(bus) & 0xff, event);
#endif
return (0);
@@ -174,54 +187,54 @@ ppb_request_mode(int mode, int options)
* Negociate the peripheral side
*/
int
-ppb_peripheral_negociate(struct ppb_device *dev, int mode, int options)
+ppb_peripheral_negociate(device_t bus, int mode, int options)
{
int spin, request_mode, error = 0;
char r;
- ppb_set_mode(dev, PPB_COMPATIBLE);
- ppb_1284_set_state(dev, PPB_PERIPHERAL_NEGOCIATION);
+ ppb_set_mode(bus, PPB_COMPATIBLE);
+ ppb_1284_set_state(bus, PPB_PERIPHERAL_NEGOCIATION);
/* compute ext. value */
request_mode = ppb_request_mode(mode, options);
/* wait host */
spin = 10;
- while (spin-- && (ppb_rstr(dev) & nBUSY))
+ while (spin-- && (ppb_rstr(bus) & nBUSY))
DELAY(1);
/* check termination */
- if (!(ppb_rstr(dev) & SELECT) || !spin) {
+ if (!(ppb_rstr(bus) & SELECT) || !spin) {
error = ENODEV;
goto error;
}
/* Event 4 - read ext. value */
- r = ppb_rdtr(dev);
+ r = ppb_rdtr(bus);
/* nibble mode is not supported */
if ((r == (char)request_mode) ||
(r == NIBBLE_1284_NORMAL)) {
/* Event 5 - restore direction bit, no data avail */
- ppb_wctr(dev, (STROBE | nINIT) & ~(SELECTIN));
+ ppb_wctr(bus, (STROBE | nINIT) & ~(SELECTIN));
DELAY(1);
/* Event 6 */
- ppb_wctr(dev, (nINIT) & ~(SELECTIN | STROBE));
+ ppb_wctr(bus, (nINIT) & ~(SELECTIN | STROBE));
if (r == NIBBLE_1284_NORMAL) {
#ifdef DEBUG_1284
printf("R");
#endif
- ppb_1284_set_error(dev, PPB_MODE_UNSUPPORTED, 4);
+ ppb_1284_set_error(bus, PPB_MODE_UNSUPPORTED, 4);
error = EINVAL;
goto error;
} else {
- ppb_1284_set_state(dev, PPB_PERIPHERAL_IDLE);
+ ppb_1284_set_state(bus, PPB_PERIPHERAL_IDLE);
switch (r) {
case BYTE_1284_NORMAL:
- ppb_set_mode(dev, PPB_BYTE);
+ ppb_set_mode(bus, PPB_BYTE);
break;
default:
break;
@@ -233,12 +246,12 @@ ppb_peripheral_negociate(struct ppb_device *dev, int mode, int options)
}
} else {
/* Event 5 - mode not supported */
- ppb_wctr(dev, SELECTIN);
+ ppb_wctr(bus, SELECTIN);
DELAY(1);
/* Event 6 */
- ppb_wctr(dev, (SELECTIN) & ~(STROBE | nINIT));
- ppb_1284_set_error(dev, PPB_MODE_UNSUPPORTED, 4);
+ ppb_wctr(bus, (SELECTIN) & ~(STROBE | nINIT));
+ ppb_1284_set_error(bus, PPB_MODE_UNSUPPORTED, 4);
#ifdef DEBUG_1284
printf("r");
@@ -250,7 +263,7 @@ ppb_peripheral_negociate(struct ppb_device *dev, int mode, int options)
return (0);
error:
- ppb_peripheral_terminate(dev, PPB_WAIT);
+ ppb_peripheral_terminate(bus, PPB_WAIT);
return (error);
}
@@ -262,7 +275,7 @@ error:
* Always return 0 in compatible mode
*/
int
-ppb_peripheral_terminate(struct ppb_device *dev, int how)
+ppb_peripheral_terminate(device_t bus, int how)
{
int error = 0;
@@ -270,38 +283,38 @@ ppb_peripheral_terminate(struct ppb_device *dev, int how)
printf("t");
#endif
- ppb_1284_set_state(dev, PPB_PERIPHERAL_TERMINATION);
+ ppb_1284_set_state(bus, PPB_PERIPHERAL_TERMINATION);
/* Event 22 - wait up to host response time (1s) */
- if ((error = do_peripheral_wait(dev, SELECT | nBUSY, 0))) {
- ppb_1284_set_error(dev, PPB_TIMEOUT, 22);
+ if ((error = do_peripheral_wait(bus, SELECT | nBUSY, 0))) {
+ ppb_1284_set_error(bus, PPB_TIMEOUT, 22);
goto error;
}
/* Event 24 */
- ppb_wctr(dev, (nINIT | STROBE) & ~(AUTOFEED | SELECTIN));
+ ppb_wctr(bus, (nINIT | STROBE) & ~(AUTOFEED | SELECTIN));
/* Event 25 - wait up to host response time (1s) */
- if ((error = do_peripheral_wait(dev, nBUSY, nBUSY))) {
- ppb_1284_set_error(dev, PPB_TIMEOUT, 25);
+ if ((error = do_peripheral_wait(bus, nBUSY, nBUSY))) {
+ ppb_1284_set_error(bus, PPB_TIMEOUT, 25);
goto error;
}
/* Event 26 */
- ppb_wctr(dev, (SELECTIN | nINIT | STROBE) & ~(AUTOFEED));
+ ppb_wctr(bus, (SELECTIN | nINIT | STROBE) & ~(AUTOFEED));
DELAY(1);
/* Event 27 */
- ppb_wctr(dev, (SELECTIN | nINIT) & ~(STROBE | AUTOFEED));
+ ppb_wctr(bus, (SELECTIN | nINIT) & ~(STROBE | AUTOFEED));
/* Event 28 - wait up to host response time (1s) */
- if ((error = do_peripheral_wait(dev, nBUSY, 0))) {
- ppb_1284_set_error(dev, PPB_TIMEOUT, 28);
+ if ((error = do_peripheral_wait(bus, nBUSY, 0))) {
+ ppb_1284_set_error(bus, PPB_TIMEOUT, 28);
goto error;
}
error:
- ppb_set_mode(dev, PPB_COMPATIBLE);
- ppb_1284_set_state(dev, PPB_FORWARD_IDLE);
+ ppb_set_mode(bus, PPB_COMPATIBLE);
+ ppb_1284_set_state(bus, PPB_FORWARD_IDLE);
return (0);
}
@@ -312,19 +325,19 @@ error:
* Write 1 byte in BYTE mode
*/
static int
-byte_peripheral_outbyte(struct ppb_device *dev, char *buffer, int last)
+byte_peripheral_outbyte(device_t bus, char *buffer, int last)
{
int error = 0;
/* Event 7 */
- if ((error = do_1284_wait(dev, nBUSY, nBUSY))) {
- ppb_1284_set_error(dev, PPB_TIMEOUT, 7);
+ if ((error = do_1284_wait(bus, nBUSY, nBUSY))) {
+ ppb_1284_set_error(bus, PPB_TIMEOUT, 7);
goto error;
}
/* check termination */
- if (!(ppb_rstr(dev) & SELECT)) {
- ppb_peripheral_terminate(dev, PPB_WAIT);
+ if (!(ppb_rstr(bus) & SELECT)) {
+ ppb_peripheral_terminate(bus, PPB_WAIT);
goto error;
}
@@ -332,35 +345,35 @@ byte_peripheral_outbyte(struct ppb_device *dev, char *buffer, int last)
#ifdef DEBUG_1284
printf("B");
#endif
- ppb_wdtr(dev, *buffer);
+ ppb_wdtr(bus, *buffer);
/* Event 9 */
- ppb_wctr(dev, (AUTOFEED | STROBE) & ~(nINIT | SELECTIN));
+ ppb_wctr(bus, (AUTOFEED | STROBE) & ~(nINIT | SELECTIN));
/* Event 10 - wait data read */
- if ((error = do_peripheral_wait(dev, nBUSY, 0))) {
- ppb_1284_set_error(dev, PPB_TIMEOUT, 16);
+ if ((error = do_peripheral_wait(bus, nBUSY, 0))) {
+ ppb_1284_set_error(bus, PPB_TIMEOUT, 16);
goto error;
}
/* Event 11 */
if (!last) {
- ppb_wctr(dev, (AUTOFEED) & ~(nINIT | STROBE | SELECTIN));
+ ppb_wctr(bus, (AUTOFEED) & ~(nINIT | STROBE | SELECTIN));
} else {
- ppb_wctr(dev, (nINIT) & ~(STROBE | SELECTIN | AUTOFEED));
+ ppb_wctr(bus, (nINIT) & ~(STROBE | SELECTIN | AUTOFEED));
}
#if 0
/* Event 16 - wait strobe */
- if ((error = do_peripheral_wait(dev, nACK | nBUSY, 0))) {
- ppb_1284_set_error(dev, PPB_TIMEOUT, 16);
+ if ((error = do_peripheral_wait(bus, nACK | nBUSY, 0))) {
+ ppb_1284_set_error(bus, PPB_TIMEOUT, 16);
goto error;
}
#endif
/* check termination */
- if (!(ppb_rstr(dev) & SELECT)) {
- ppb_peripheral_terminate(dev, PPB_WAIT);
+ if (!(ppb_rstr(bus) & SELECT)) {
+ ppb_peripheral_terminate(bus, PPB_WAIT);
goto error;
}
@@ -374,12 +387,12 @@ error:
* Write n bytes in BYTE mode
*/
int
-byte_peripheral_write(struct ppb_device *dev, char *buffer, int len, int *sent)
+byte_peripheral_write(device_t bus, char *buffer, int len, int *sent)
{
int error = 0, i;
char r;
- ppb_1284_set_state(dev, PPB_PERIPHERAL_TRANSFER);
+ ppb_1284_set_state(bus, PPB_PERIPHERAL_TRANSFER);
/* wait forever, the remote host is master and should initiate
* termination
@@ -388,14 +401,14 @@ byte_peripheral_write(struct ppb_device *dev, char *buffer, int len, int *sent)
/* force remote nFAULT low to release the remote waiting
* process, if any
*/
- r = ppb_rctr(dev);
- ppb_wctr(dev, r & ~nINIT);
+ r = ppb_rctr(bus);
+ ppb_wctr(bus, r & ~nINIT);
#ifdef DEBUG_1284
printf("y");
#endif
/* Event 7 */
- error = ppb_poll_device(dev, PPB_FOREVER, nBUSY, nBUSY,
+ error = ppb_poll_bus(bus, PPB_FOREVER, nBUSY, nBUSY,
PPB_INTR);
if (error && error != EWOULDBLOCK)
@@ -404,12 +417,12 @@ byte_peripheral_write(struct ppb_device *dev, char *buffer, int len, int *sent)
#ifdef DEBUG_1284
printf("b");
#endif
- if ((error = byte_peripheral_outbyte(dev, buffer+i, (i == len-1))))
+ if ((error = byte_peripheral_outbyte(bus, buffer+i, (i == len-1))))
goto error;
}
error:
if (!error)
- ppb_1284_set_state(dev, PPB_PERIPHERAL_IDLE);
+ ppb_1284_set_state(bus, PPB_PERIPHERAL_IDLE);
*sent = i;
return (error);
@@ -421,35 +434,35 @@ error:
* Read 1 byte in BYTE mode
*/
int
-byte_1284_inbyte(struct ppb_device *dev, char *buffer)
+byte_1284_inbyte(device_t bus, char *buffer)
{
int error = 0;
/* Event 7 - ready to take data (nAUTO low) */
- ppb_wctr(dev, (PCD | nINIT | AUTOFEED) & ~(STROBE | SELECTIN));
+ ppb_wctr(bus, (PCD | nINIT | AUTOFEED) & ~(STROBE | SELECTIN));
/* Event 9 - peripheral set nAck low */
- if ((error = do_1284_wait(dev, nACK, 0))) {
- ppb_1284_set_error(dev, PPB_TIMEOUT, 9);
+ if ((error = do_1284_wait(bus, nACK, 0))) {
+ ppb_1284_set_error(bus, PPB_TIMEOUT, 9);
goto error;
}
/* read the byte */
- *buffer = ppb_rdtr(dev);
+ *buffer = ppb_rdtr(bus);
/* Event 10 - data received, can't accept more */
- ppb_wctr(dev, (nINIT) & ~(AUTOFEED | STROBE | SELECTIN));
+ ppb_wctr(bus, (nINIT) & ~(AUTOFEED | STROBE | SELECTIN));
/* Event 11 - peripheral ack */
- if ((error = do_1284_wait(dev, nACK, nACK))) {
- ppb_1284_set_error(dev, PPB_TIMEOUT, 11);
+ if ((error = do_1284_wait(bus, nACK, nACK))) {
+ ppb_1284_set_error(bus, PPB_TIMEOUT, 11);
goto error;
}
/* Event 16 - strobe */
- ppb_wctr(dev, (nINIT | STROBE) & ~(AUTOFEED | SELECTIN));
+ ppb_wctr(bus, (nINIT | STROBE) & ~(AUTOFEED | SELECTIN));
DELAY(3);
- ppb_wctr(dev, (nINIT) & ~(AUTOFEED | STROBE | SELECTIN));
+ ppb_wctr(bus, (nINIT) & ~(AUTOFEED | STROBE | SELECTIN));
error:
return (error);
@@ -461,7 +474,7 @@ error:
* Read 1 byte in NIBBLE mode
*/
int
-nibble_1284_inbyte(struct ppb_device *dev, char *buffer)
+nibble_1284_inbyte(device_t bus, char *buffer)
{
char nibble[2];
int i, error;
@@ -469,25 +482,25 @@ nibble_1284_inbyte(struct ppb_device *dev, char *buffer)
for (i = 0; i < 2; i++) {
/* Event 7 - ready to take data (nAUTO low) */
- ppb_wctr(dev, (nINIT | AUTOFEED) & ~(STROBE | SELECTIN));
+ ppb_wctr(bus, (nINIT | AUTOFEED) & ~(STROBE | SELECTIN));
/* Event 8 - peripheral writes the first nibble */
/* Event 9 - peripheral set nAck low */
- if ((error = do_1284_wait(dev, nACK, 0))) {
- ppb_1284_set_error(dev, PPB_TIMEOUT, 9);
+ if ((error = do_1284_wait(bus, nACK, 0))) {
+ ppb_1284_set_error(bus, PPB_TIMEOUT, 9);
goto error;
}
/* read nibble */
- nibble[i] = ppb_rstr(dev);
+ nibble[i] = ppb_rstr(bus);
/* Event 10 - ack, nibble received */
- ppb_wctr(dev, nINIT & ~(AUTOFEED | STROBE | SELECTIN));
+ ppb_wctr(bus, nINIT & ~(AUTOFEED | STROBE | SELECTIN));
/* Event 11 - wait ack from peripherial */
- if ((error = do_1284_wait(dev, nACK, nACK))) {
- ppb_1284_set_error(dev, PPB_TIMEOUT, 11);
+ if ((error = do_1284_wait(bus, nACK, nACK))) {
+ ppb_1284_set_error(bus, PPB_TIMEOUT, 11);
goto error;
}
}
@@ -505,7 +518,7 @@ error:
* Read in IEEE1284 NIBBLE/BYTE mode
*/
int
-spp_1284_read(struct ppb_device *dev, int mode, char *buffer, int max, int *read)
+spp_1284_read(device_t bus, int mode, char *buffer, int max, int *read)
{
int error = 0, len = 0;
int terminate_after_transfer = 1;
@@ -513,11 +526,11 @@ spp_1284_read(struct ppb_device *dev, int mode, char *buffer, int max, int *read
*read = len = 0;
- state = ppb_1284_get_state(dev);
+ state = ppb_1284_get_state(bus);
switch (state) {
case PPB_FORWARD_IDLE:
- if ((error = ppb_1284_negociate(dev, mode, 0)))
+ if ((error = ppb_1284_negociate(bus, mode, 0)))
return (error);
break;
@@ -526,15 +539,15 @@ spp_1284_read(struct ppb_device *dev, int mode, char *buffer, int max, int *read
break;
default:
- ppb_1284_terminate(dev);
- if ((error = ppb_1284_negociate(dev, mode, 0)))
+ ppb_1284_terminate(bus);
+ if ((error = ppb_1284_negociate(bus, mode, 0)))
return (error);
break;
}
- while ((len < max) && !(ppb_rstr(dev) & (nFAULT))) {
+ while ((len < max) && !(ppb_rstr(bus) & (nFAULT))) {
- ppb_1284_set_state(dev, PPB_REVERSE_TRANSFER);
+ ppb_1284_set_state(bus, PPB_REVERSE_TRANSFER);
#ifdef DEBUG_1284
printf("B");
@@ -543,11 +556,11 @@ spp_1284_read(struct ppb_device *dev, int mode, char *buffer, int max, int *read
switch (mode) {
case PPB_NIBBLE:
/* read a byte, error means no more data */
- if (nibble_1284_inbyte(dev, buffer+len))
+ if (nibble_1284_inbyte(bus, buffer+len))
goto end_while;
break;
case PPB_BYTE:
- if (byte_1284_inbyte(dev, buffer+len))
+ if (byte_1284_inbyte(bus, buffer+len))
goto end_while;
break;
default:
@@ -559,12 +572,12 @@ spp_1284_read(struct ppb_device *dev, int mode, char *buffer, int max, int *read
end_while:
if (!error)
- ppb_1284_set_state(dev, PPB_REVERSE_IDLE);
+ ppb_1284_set_state(bus, PPB_REVERSE_IDLE);
*read = len;
if (terminate_after_transfer || error)
- ppb_1284_terminate(dev);
+ ppb_1284_terminate(bus);
return (error);
}
@@ -574,7 +587,7 @@ end_while:
*
*/
int
-ppb_1284_read_id(struct ppb_device *dev, int mode, char *buffer,
+ppb_1284_read_id(device_t bus, int mode, char *buffer,
int max, int *read)
{
int error = 0;
@@ -585,20 +598,20 @@ ppb_1284_read_id(struct ppb_device *dev, int mode, char *buffer,
switch (mode) {
case PPB_NIBBLE:
case PPB_ECP:
- if ((error = ppb_1284_negociate(dev, PPB_NIBBLE, PPB_REQUEST_ID)))
+ if ((error = ppb_1284_negociate(bus, PPB_NIBBLE, PPB_REQUEST_ID)))
return (error);
- error = spp_1284_read(dev, PPB_NIBBLE, buffer, max, read);
+ error = spp_1284_read(bus, PPB_NIBBLE, buffer, max, read);
break;
case PPB_BYTE:
- if ((error = ppb_1284_negociate(dev, PPB_BYTE, PPB_REQUEST_ID)))
+ if ((error = ppb_1284_negociate(bus, PPB_BYTE, PPB_REQUEST_ID)))
return (error);
- error = spp_1284_read(dev, PPB_BYTE, buffer, max, read);
+ error = spp_1284_read(bus, PPB_BYTE, buffer, max, read);
break;
default:
panic("%s: unsupported mode %d\n", __FUNCTION__, mode);
}
- ppb_1284_terminate(dev);
+ ppb_1284_terminate(bus);
return (error);
}
@@ -608,7 +621,7 @@ ppb_1284_read_id(struct ppb_device *dev, int mode, char *buffer,
* IEEE1284 read
*/
int
-ppb_1284_read(struct ppb_device *dev, int mode, char *buffer,
+ppb_1284_read(device_t bus, int mode, char *buffer,
int max, int *read)
{
int error = 0;
@@ -616,7 +629,7 @@ ppb_1284_read(struct ppb_device *dev, int mode, char *buffer,
switch (mode) {
case PPB_NIBBLE:
case PPB_BYTE:
- error = spp_1284_read(dev, mode, buffer, max, read);
+ error = spp_1284_read(bus, mode, buffer, max, read);
break;
default:
return (EINVAL);
@@ -635,7 +648,7 @@ ppb_1284_read(struct ppb_device *dev, int mode, char *buffer,
* After negociation, nFAULT is low if data is available
*/
int
-ppb_1284_negociate(struct ppb_device *dev, int mode, int options)
+ppb_1284_negociate(device_t bus, int mode, int options)
{
int error;
int request_mode;
@@ -644,77 +657,77 @@ ppb_1284_negociate(struct ppb_device *dev, int mode, int options)
printf("n");
#endif
- if (ppb_1284_get_state(dev) >= PPB_PERIPHERAL_NEGOCIATION)
- ppb_peripheral_terminate(dev, PPB_WAIT);
+ if (ppb_1284_get_state(bus) >= PPB_PERIPHERAL_NEGOCIATION)
+ ppb_peripheral_terminate(bus, PPB_WAIT);
- if (ppb_1284_get_state(dev) != PPB_FORWARD_IDLE)
- ppb_1284_terminate(dev);
+ if (ppb_1284_get_state(bus) != PPB_FORWARD_IDLE)
+ ppb_1284_terminate(bus);
#ifdef DEBUG_1284
printf("%d", mode);
#endif
/* ensure the host is in compatible mode */
- ppb_set_mode(dev, PPB_COMPATIBLE);
+ ppb_set_mode(bus, PPB_COMPATIBLE);
/* reset error to catch the actual negociation error */
- ppb_1284_reset_error(dev, PPB_FORWARD_IDLE);
+ ppb_1284_reset_error(bus, PPB_FORWARD_IDLE);
/* calculate ext. value */
request_mode = ppb_request_mode(mode, options);
/* default state */
- ppb_wctr(dev, (nINIT | SELECTIN) & ~(STROBE | AUTOFEED));
+ ppb_wctr(bus, (nINIT | SELECTIN) & ~(STROBE | AUTOFEED));
DELAY(1);
/* enter negociation phase */
- ppb_1284_set_state(dev, PPB_NEGOCIATION);
+ ppb_1284_set_state(bus, PPB_NEGOCIATION);
/* Event 0 - put the exten. value on the data lines */
- ppb_wdtr(dev, request_mode);
+ ppb_wdtr(bus, request_mode);
#ifdef PERIPH_1284
/* request remote host attention */
- ppb_wctr(dev, (nINIT | STROBE) & ~(AUTOFEED | SELECTIN));
+ ppb_wctr(bus, (nINIT | STROBE) & ~(AUTOFEED | SELECTIN));
DELAY(1);
- ppb_wctr(dev, (nINIT) & ~(STROBE | AUTOFEED | SELECTIN));
+ ppb_wctr(bus, (nINIT) & ~(STROBE | AUTOFEED | SELECTIN));
#else
DELAY(1);
#endif /* !PERIPH_1284 */
/* Event 1 - enter IEEE1284 mode */
- ppb_wctr(dev, (nINIT | AUTOFEED) & ~(STROBE | SELECTIN));
+ ppb_wctr(bus, (nINIT | AUTOFEED) & ~(STROBE | SELECTIN));
#ifdef PERIPH_1284
/* ignore the PError line, wait a bit more, remote host's
* interrupts don't respond fast enough */
- if (ppb_poll_device(dev, 40, nACK | SELECT | nFAULT,
+ if (ppb_poll_bus(bus, 40, nACK | SELECT | nFAULT,
SELECT | nFAULT, PPB_NOINTR | PPB_POLL)) {
- ppb_1284_set_error(dev, PPB_NOT_IEEE1284, 2);
+ ppb_1284_set_error(bus, PPB_NOT_IEEE1284, 2);
error = ENODEV;
goto error;
}
#else
/* Event 2 - trying IEEE1284 dialog */
- if (do_1284_wait(dev, nACK | PERROR | SELECT | nFAULT,
+ if (do_1284_wait(bus, nACK | PERROR | SELECT | nFAULT,
PERROR | SELECT | nFAULT)) {
- ppb_1284_set_error(dev, PPB_NOT_IEEE1284, 2);
+ ppb_1284_set_error(bus, PPB_NOT_IEEE1284, 2);
error = ENODEV;
goto error;
}
#endif /* !PERIPH_1284 */
/* Event 3 - latch the ext. value to the peripheral */
- ppb_wctr(dev, (nINIT | STROBE | AUTOFEED) & ~SELECTIN);
+ ppb_wctr(bus, (nINIT | STROBE | AUTOFEED) & ~SELECTIN);
DELAY(1);
/* Event 4 - IEEE1284 device recognized */
- ppb_wctr(dev, nINIT & ~(SELECTIN | AUTOFEED | STROBE));
+ ppb_wctr(bus, nINIT & ~(SELECTIN | AUTOFEED | STROBE));
/* Event 6 - waiting for status lines */
- if (do_1284_wait(dev, nACK, nACK)) {
- ppb_1284_set_error(dev, PPB_TIMEOUT, 6);
+ if (do_1284_wait(bus, nACK, nACK)) {
+ ppb_1284_set_error(bus, PPB_TIMEOUT, 6);
error = EBUSY;
goto error;
}
@@ -724,19 +737,19 @@ ppb_1284_negociate(struct ppb_device *dev, int mode, int options)
if (options & PPB_EXTENSIBILITY_LINK) {
/* XXX not fully supported yet */
- ppb_1284_terminate(dev);
+ ppb_1284_terminate(bus);
return (0);
}
if (request_mode == NIBBLE_1284_NORMAL) {
- if (do_1284_wait(dev, nACK | SELECT, nACK)) {
- ppb_1284_set_error(dev, PPB_MODE_UNSUPPORTED, 7);
+ if (do_1284_wait(bus, nACK | SELECT, nACK)) {
+ ppb_1284_set_error(bus, PPB_MODE_UNSUPPORTED, 7);
error = ENODEV;
goto error;
}
} else {
- if (do_1284_wait(dev, nACK | SELECT, SELECT | nACK)) {
- ppb_1284_set_error(dev, PPB_MODE_UNSUPPORTED, 7);
+ if (do_1284_wait(bus, nACK | SELECT, SELECT | nACK)) {
+ ppb_1284_set_error(bus, PPB_MODE_UNSUPPORTED, 7);
error = ENODEV;
goto error;
}
@@ -746,46 +759,46 @@ ppb_1284_negociate(struct ppb_device *dev, int mode, int options)
case PPB_NIBBLE:
case PPB_PS2:
/* enter reverse idle phase */
- ppb_1284_set_state(dev, PPB_REVERSE_IDLE);
+ ppb_1284_set_state(bus, PPB_REVERSE_IDLE);
break;
case PPB_ECP:
/* negociation ok, now setup the communication */
- ppb_1284_set_state(dev, PPB_SETUP);
- ppb_wctr(dev, (nINIT | AUTOFEED) & ~(SELECTIN | STROBE));
+ ppb_1284_set_state(bus, PPB_SETUP);
+ ppb_wctr(bus, (nINIT | AUTOFEED) & ~(SELECTIN | STROBE));
#ifdef PERIPH_1284
/* ignore PError line */
- if (do_1284_wait(dev, nACK | SELECT | nBUSY,
+ if (do_1284_wait(bus, nACK | SELECT | nBUSY,
nACK | SELECT | nBUSY)) {
- ppb_1284_set_error(dev, PPB_TIMEOUT, 30);
+ ppb_1284_set_error(bus, PPB_TIMEOUT, 30);
error = ENODEV;
goto error;
}
#else
- if (do_1284_wait(dev, nACK | SELECT | PERROR | nBUSY,
+ if (do_1284_wait(bus, nACK | SELECT | PERROR | nBUSY,
nACK | SELECT | PERROR | nBUSY)) {
- ppb_1284_set_error(dev, PPB_TIMEOUT, 30);
+ ppb_1284_set_error(bus, PPB_TIMEOUT, 30);
error = ENODEV;
goto error;
}
#endif /* !PERIPH_1284 */
/* ok, the host enters the ForwardIdle state */
- ppb_1284_set_state(dev, PPB_ECP_FORWARD_IDLE);
+ ppb_1284_set_state(bus, PPB_ECP_FORWARD_IDLE);
break;
case PPB_EPP:
- ppb_1284_set_state(dev, PPB_EPP_IDLE);
+ ppb_1284_set_state(bus, PPB_EPP_IDLE);
break;
default:
panic("%s: unknown mode (%d)!", __FUNCTION__, mode);
}
- ppb_set_mode(dev, mode);
+ ppb_set_mode(bus, mode);
return (0);
error:
- ppb_1284_terminate(dev);
+ ppb_1284_terminate(bus);
return (error);
}
@@ -797,7 +810,7 @@ error:
* is _always_ in compatible mode after ppb_1284_terminate()
*/
int
-ppb_1284_terminate(struct ppb_device *dev)
+ppb_1284_terminate(device_t bus)
{
#ifdef DEBUG_1284
@@ -806,40 +819,40 @@ ppb_1284_terminate(struct ppb_device *dev)
/* do not reset error here to keep the error that
* may occured before the ppb_1284_terminate() call */
- ppb_1284_set_state(dev, PPB_TERMINATION);
+ ppb_1284_set_state(bus, PPB_TERMINATION);
#ifdef PERIPH_1284
/* request remote host attention */
- ppb_wctr(dev, (nINIT | STROBE | SELECTIN) & ~(AUTOFEED));
+ ppb_wctr(bus, (nINIT | STROBE | SELECTIN) & ~(AUTOFEED));
DELAY(1);
#endif /* PERIPH_1284 */
/* Event 22 - set nSelectin low and nAutoFeed high */
- ppb_wctr(dev, (nINIT | SELECTIN) & ~(STROBE | AUTOFEED));
+ ppb_wctr(bus, (nINIT | SELECTIN) & ~(STROBE | AUTOFEED));
/* Event 24 - waiting for peripheral, Xflag ignored */
- if (do_1284_wait(dev, nACK | nBUSY | nFAULT, nFAULT)) {
- ppb_1284_set_error(dev, PPB_TIMEOUT, 24);
+ if (do_1284_wait(bus, nACK | nBUSY | nFAULT, nFAULT)) {
+ ppb_1284_set_error(bus, PPB_TIMEOUT, 24);
goto error;
}
/* Event 25 - set nAutoFd low */
- ppb_wctr(dev, (nINIT | SELECTIN | AUTOFEED) & ~STROBE);
+ ppb_wctr(bus, (nINIT | SELECTIN | AUTOFEED) & ~STROBE);
/* Event 26 - compatible mode status is set */
/* Event 27 - peripheral set nAck high */
- if (do_1284_wait(dev, nACK, nACK)) {
- ppb_1284_set_error(dev, PPB_TIMEOUT, 27);
+ if (do_1284_wait(bus, nACK, nACK)) {
+ ppb_1284_set_error(bus, PPB_TIMEOUT, 27);
}
/* Event 28 - end termination, return to idle phase */
- ppb_wctr(dev, (nINIT | SELECTIN) & ~(STROBE | AUTOFEED));
+ ppb_wctr(bus, (nINIT | SELECTIN) & ~(STROBE | AUTOFEED));
error:
/* return to compatible mode */
- ppb_set_mode(dev, PPB_COMPATIBLE);
- ppb_1284_set_state(dev, PPB_FORWARD_IDLE);
+ ppb_set_mode(bus, PPB_COMPATIBLE);
+ ppb_1284_set_state(bus, PPB_FORWARD_IDLE);
return (0);
}
diff --git a/sys/dev/ppbus/ppb_1284.h b/sys/dev/ppbus/ppb_1284.h
index f975c26..de1f270 100644
--- a/sys/dev/ppbus/ppb_1284.h
+++ b/sys/dev/ppbus/ppb_1284.h
@@ -108,17 +108,17 @@
#define PPB_PERIPHERAL_TRANSFER 13
#define PPB_PERIPHERAL_TERMINATION 14
-extern int nibble_1284_inbyte(struct ppb_device *, char *);
-extern int byte_1284_inbyte(struct ppb_device *, char *);
-extern int spp_1284_read(struct ppb_device *, int, char *, int, int *);
-
-extern int ppb_1284_negociate(struct ppb_device *, int, int);
-extern int ppb_1284_terminate(struct ppb_device *);
-extern int ppb_1284_read_id(struct ppb_device *, int, char *, int, int *);
-extern int ppb_1284_read(struct ppb_device *, int, char *, int, int *);
-
-extern int ppb_peripheral_terminate(struct ppb_device *, int);
-extern int ppb_peripheral_negociate(struct ppb_device *, int, int);
-extern int byte_peripheral_write(struct ppb_device *, char *, int, int *);
+extern int nibble_1284_inbyte(device_t, char *);
+extern int byte_1284_inbyte(device_t, char *);
+extern int spp_1284_read(device_t, int, char *, int, int *);
+
+extern int ppb_1284_negociate(device_t, int, int);
+extern int ppb_1284_terminate(device_t);
+extern int ppb_1284_read_id(device_t, int, char *, int, int *);
+extern int ppb_1284_read(device_t, int, char *, int, int *);
+
+extern int ppb_peripheral_terminate(device_t, int);
+extern int ppb_peripheral_negociate(device_t, int, int);
+extern int byte_peripheral_write(device_t, char *, int, int *);
#endif
diff --git a/sys/dev/ppbus/ppb_base.c b/sys/dev/ppbus/ppb_base.c
index 250999b..c2f1d9b 100644
--- a/sys/dev/ppbus/ppb_base.c
+++ b/sys/dev/ppbus/ppb_base.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1997, 1998 Nicolas Souchu
+ * Copyright (c) 1997, 1998, 1999 Nicolas Souchu
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -29,49 +29,29 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+
#include <machine/clock.h>
#include <dev/ppbus/ppbconf.h>
+
+#include "ppbus_if.h"
+#include <dev/ppbus/ppbio.h>
+
+#define DEVTOSOFTC(dev) ((struct ppb_data *)device_get_softc(dev))
+
/*
- * ppb_intr()
+ * ppb_poll_bus()
*
- * Function called by ppcintr() when an intr occurs.
- */
-void
-ppb_intr(struct ppb_link *pl)
-{
- struct ppb_data *ppb = pl->ppbus;
-
- /*
- * Call chipset dependent code.
- * Should be filled at chipset initialisation if needed.
- */
- if (pl->adapter->intr_handler)
- (*pl->adapter->intr_handler)(pl->adapter_unit);
-
- /*
- * Call upper handler iff the bus is owned by a device and
- * this device has specified an interrupt handler.
- */
- if (ppb->ppb_owner && ppb->ppb_owner->intr)
- (*ppb->ppb_owner->intr)(ppb->ppb_owner->id_unit);
- if (ppb->ppb_owner && ppb->ppb_owner->bintr)
- (*ppb->ppb_owner->bintr)(ppb->ppb_owner);
-
- return;
-}
-
-/*
- * ppb_poll_device()
- *
- * Polls the device
+ * Polls the bus
*
* max is a delay in 10-milliseconds
*/
int
-ppb_poll_device(struct ppb_device *dev, int max,
- char mask, char status, int how)
+ppb_poll_bus(device_t bus, int max,
+ char mask, char status, int how)
{
int i, j, error;
char r;
@@ -79,7 +59,7 @@ ppb_poll_device(struct ppb_device *dev, int max,
/* try at least up to 10ms */
for (j = 0; j < ((how & PPB_POLL) ? max : 1); j++) {
for (i = 0; i < 10000; i++) {
- r = ppb_rstr(dev);
+ r = ppb_rstr(bus);
DELAY(1);
if ((r & mask) == status)
return (0);
@@ -88,19 +68,19 @@ ppb_poll_device(struct ppb_device *dev, int max,
if (!(how & PPB_POLL)) {
for (i = 0; max == PPB_FOREVER || i < max-1; i++) {
- if ((ppb_rstr(dev) & mask) == status)
+ if ((ppb_rstr(bus) & mask) == status)
return (0);
switch (how) {
case PPB_NOINTR:
/* wait 10 ms */
- tsleep((caddr_t)dev, PPBPRI, "ppbpoll", hz/100);
+ tsleep((caddr_t)bus, PPBPRI, "ppbpoll", hz/100);
break;
case PPB_INTR:
default:
/* wait 10 ms */
- if (((error = tsleep((caddr_t)dev, PPBPRI | PCATCH,
+ if (((error = tsleep((caddr_t)bus, PPBPRI | PCATCH,
"ppbpoll", hz/100)) != EWOULDBLOCK) != 0) {
return (error);
}
@@ -113,22 +93,48 @@ ppb_poll_device(struct ppb_device *dev, int max,
}
/*
- * ppb_set_mode()
+ * ppb_get_epp_protocol()
*
- * Set the operating mode of the chipset
+ * Return the chipset EPP protocol
*/
int
-ppb_set_mode(struct ppb_device *dev, int mode)
+ppb_get_epp_protocol(device_t bus)
{
- struct ppb_data *ppb = dev->ppb;
- int old_mode = ppb_get_mode(dev);
+ uintptr_t protocol;
+
+ BUS_READ_IVAR(device_get_parent(bus), bus, PPC_IVAR_EPP_PROTO, &protocol);
- if ((*ppb->ppb_link->adapter->setmode)(
- ppb->ppb_link->adapter_unit, mode))
- return (-1);
+ return (protocol);
+}
+
+/*
+ * ppb_get_mode()
+ *
+ */
+int
+ppb_get_mode(device_t bus)
+{
+ struct ppb_data *ppb = DEVTOSOFTC(bus);
/* XXX yet device mode = ppbus mode = chipset mode */
- dev->mode = ppb->mode = (mode & PPB_MASK);
+ return (ppb->mode);
+}
+
+/*
+ * ppb_set_mode()
+ *
+ * Set the operating mode of the chipset, return the previous mode
+ */
+int
+ppb_set_mode(device_t bus, int mode)
+{
+ struct ppb_data *ppb = DEVTOSOFTC(bus);
+ int old_mode = ppb_get_mode(bus);
+
+ if (!PPBUS_SETMODE(device_get_parent(bus), mode)) {
+ /* XXX yet device mode = ppbus mode = chipset mode */
+ ppb->mode = (mode & PPB_MASK);
+ }
return (old_mode);
}
@@ -139,12 +145,9 @@ ppb_set_mode(struct ppb_device *dev, int mode)
* Write charaters to the port
*/
int
-ppb_write(struct ppb_device *dev, char *buf, int len, int how)
+ppb_write(device_t bus, char *buf, int len, int how)
{
- struct ppb_data *ppb = dev->ppb;
-
- return (ppb->ppb_link->adapter->write(ppb->ppb_link->adapter_unit,
- buf, len, how));
+ return (PPBUS_WRITE(device_get_parent(bus), buf, len, how));
}
/*
@@ -153,16 +156,9 @@ ppb_write(struct ppb_device *dev, char *buf, int len, int how)
* Reset the EPP timeout bit in the status register
*/
int
-ppb_reset_epp_timeout(struct ppb_device *dev)
+ppb_reset_epp_timeout(device_t bus)
{
- struct ppb_data *ppb = dev->ppb;
-
- if (ppb->ppb_owner != dev)
- return (EACCES);
-
- (*ppb->ppb_link->adapter->reset_epp_timeout)(ppb->ppb_link->adapter_unit);
-
- return (0);
+ return(PPBUS_RESET_EPP(device_get_parent(bus)));
}
/*
@@ -171,16 +167,9 @@ ppb_reset_epp_timeout(struct ppb_device *dev)
* Wait for the ECP FIFO to be empty
*/
int
-ppb_ecp_sync(struct ppb_device *dev)
+ppb_ecp_sync(device_t bus)
{
- struct ppb_data *ppb = dev->ppb;
-
- if (ppb->ppb_owner != dev)
- return (EACCES);
-
- (*ppb->ppb_link->adapter->ecp_sync)(ppb->ppb_link->adapter_unit);
-
- return (0);
+ return (PPBUS_ECP_SYNC(device_get_parent(bus)));
}
/*
@@ -189,15 +178,11 @@ ppb_ecp_sync(struct ppb_device *dev)
* Read the status register and update the status info
*/
int
-ppb_get_status(struct ppb_device *dev, struct ppb_status *status)
+ppb_get_status(device_t bus, struct ppb_status *status)
{
- struct ppb_data *ppb = dev->ppb;
register char r;
- if (ppb->ppb_owner != dev)
- return (EACCES);
-
- r = status->status = ppb_rstr(dev);
+ r = status->status = ppb_rstr(bus);
status->timeout = r & TIMEOUT;
status->error = !(r & nFAULT);
diff --git a/sys/dev/ppbus/ppb_msq.c b/sys/dev/ppbus/ppb_msq.c
index a98b254..074dd07 100644
--- a/sys/dev/ppbus/ppb_msq.c
+++ b/sys/dev/ppbus/ppb_msq.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1998 Nicolas Souchu
+ * Copyright (c) 1998, 1999 Nicolas Souchu
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,10 +31,13 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
+#include <sys/bus.h>
#include <dev/ppbus/ppbconf.h>
#include <dev/ppbus/ppb_msq.h>
+#include "ppbus_if.h"
+
/* msq index (see PPB_MAX_XFER)
* These are device modes
*/
@@ -49,18 +52,18 @@
* Device mode to submsq conversion
*/
static struct ppb_xfer *
-mode2xfer(struct ppb_device *dev, int opcode)
+mode2xfer(device_t bus, struct ppb_device *ppbdev, int opcode)
{
int index, epp;
struct ppb_xfer *table;
switch (opcode) {
case MS_OP_GET:
- table = dev->get_xfer;
+ table = ppbdev->get_xfer;
break;
case MS_OP_PUT:
- table = dev->put_xfer;
+ table = ppbdev->put_xfer;
break;
default:
@@ -68,7 +71,7 @@ mode2xfer(struct ppb_device *dev, int opcode)
}
/* retrieve the device operating mode */
- switch (ppb_get_mode(dev)) {
+ switch (ppb_get_mode(bus)) {
case PPB_COMPATIBLE:
index = COMPAT_MSQ;
break;
@@ -79,7 +82,7 @@ mode2xfer(struct ppb_device *dev, int opcode)
index = PS2_MSQ;
break;
case PPB_EPP:
- switch ((epp = ppb_get_epp_protocol(dev))) {
+ switch ((epp = ppb_get_epp_protocol(bus))) {
case EPP_1_7:
index = EPP17_MSQ;
break;
@@ -95,7 +98,7 @@ mode2xfer(struct ppb_device *dev, int opcode)
index = ECP_MSQ;
break;
default:
- panic("%s: unknown mode (%d)", __FUNCTION__, dev->mode);
+ panic("%s: unknown mode (%d)", __FUNCTION__, ppbdev->mode);
}
return (&table[index]);
@@ -108,9 +111,10 @@ mode2xfer(struct ppb_device *dev, int opcode)
*
*/
int
-ppb_MS_init(struct ppb_device *dev, struct ppb_microseq *loop, int opcode)
+ppb_MS_init(device_t bus, device_t dev, struct ppb_microseq *loop, int opcode)
{
- struct ppb_xfer *xfer = mode2xfer(dev, opcode);
+ struct ppb_device *ppbdev = (struct ppb_device *)device_get_ivars(dev);
+ struct ppb_xfer *xfer = mode2xfer(bus, ppbdev, opcode);
xfer->loop = loop;
@@ -124,7 +128,7 @@ ppb_MS_init(struct ppb_device *dev, struct ppb_microseq *loop, int opcode)
*
*/
int
-ppb_MS_exec(struct ppb_device *dev, int opcode, union ppb_insarg param1,
+ppb_MS_exec(device_t bus, device_t dev, int opcode, union ppb_insarg param1,
union ppb_insarg param2, union ppb_insarg param3, int *ret)
{
struct ppb_microseq msq[] = {
@@ -139,7 +143,7 @@ ppb_MS_exec(struct ppb_device *dev, int opcode, union ppb_insarg param1,
msq[0].arg[2] = param3;
/* execute the microseq */
- return (ppb_MS_microseq(dev, msq, ret));
+ return (ppb_MS_microseq(bus, dev, msq, ret));
}
/*
@@ -149,7 +153,7 @@ ppb_MS_exec(struct ppb_device *dev, int opcode, union ppb_insarg param1,
*
*/
int
-ppb_MS_loop(struct ppb_device *dev, struct ppb_microseq *prolog,
+ppb_MS_loop(device_t bus, device_t dev, struct ppb_microseq *prolog,
struct ppb_microseq *body, struct ppb_microseq *epilog,
int iter, int *ret)
{
@@ -172,7 +176,7 @@ ppb_MS_loop(struct ppb_device *dev, struct ppb_microseq *prolog,
loop_microseq[4].arg[0].p = (void *)epilog;
/* execute the loop */
- return (ppb_MS_microseq(dev, loop_microseq, ret));
+ return (ppb_MS_microseq(bus, dev, loop_microseq, ret));
}
/*
@@ -242,9 +246,11 @@ ppb_MS_init_msq(struct ppb_microseq *msq, int nbparam, ...)
* level to avoid function call overhead between ppbus and the adapter
*/
int
-ppb_MS_microseq(struct ppb_device *dev, struct ppb_microseq *msq, int *ret)
+ppb_MS_microseq(device_t bus, device_t dev, struct ppb_microseq *msq, int *ret)
{
- struct ppb_data *ppb = dev->ppb;
+ struct ppb_data *ppb = (struct ppb_data *)device_get_softc(bus);
+ struct ppb_device *ppbdev = (struct ppb_device *)device_get_ivars(dev);
+
struct ppb_microseq *mi; /* current microinstruction */
int error;
@@ -269,13 +275,13 @@ ppb_MS_microseq(struct ppb_device *dev, struct ppb_microseq *msq, int *ret)
case MS_OP_GET:
/* attempt to choose the best mode for the device */
- xfer = mode2xfer(dev, mi->opcode);
+ xfer = mode2xfer(bus, ppbdev, mi->opcode);
/* figure out if we should use ieee1284 code */
if (!xfer->loop) {
if (mi->opcode == MS_OP_PUT) {
- if ((error = ppb->ppb_link->adapter->write(
- ppb->ppb_link->adapter_unit,
+ if ((error = PPBUS_WRITE(
+ device_get_parent(bus),
(char *)mi->arg[0].p,
mi->arg[1].i, 0)))
goto error;
@@ -291,7 +297,7 @@ ppb_MS_microseq(struct ppb_device *dev, struct ppb_microseq *msq, int *ret)
initxfer[1].arg[0].i = mi->arg[1].i;
/* initialize transfer */
- ppb_MS_microseq(dev, initxfer, &error);
+ ppb_MS_microseq(bus, dev, initxfer, &error);
if (error)
goto error;
@@ -299,7 +305,7 @@ ppb_MS_microseq(struct ppb_device *dev, struct ppb_microseq *msq, int *ret)
/* the xfer microsequence should not contain any
* MS_OP_PUT or MS_OP_GET!
*/
- ppb_MS_microseq(dev, xfer->loop, &error);
+ ppb_MS_microseq(bus, dev, xfer->loop, &error);
if (error)
goto error;
@@ -318,9 +324,8 @@ ppb_MS_microseq(struct ppb_device *dev, struct ppb_microseq *msq, int *ret)
* faster. This is the default if the microinstr
* is unknown here
*/
- if ((error = ppb->ppb_link->adapter->exec_microseq(
- ppb->ppb_link->adapter_unit,
- &mi)))
+ if ((error = PPBUS_EXEC_MICROSEQ(
+ device_get_parent(bus), &mi)))
goto error;
break;
}
diff --git a/sys/dev/ppbus/ppb_msq.h b/sys/dev/ppbus/ppb_msq.h
index 25b55fd..64d16d895 100644
--- a/sys/dev/ppbus/ppb_msq.h
+++ b/sys/dev/ppbus/ppb_msq.h
@@ -158,12 +158,13 @@
* Function abstraction level
*/
-#define ppb_MS_GET_init(dev,body) ppb_MS_init(dev, body, MS_OP_GET)
+#define ppb_MS_GET_init(bus,dev,body) ppb_MS_init(bus, dev, body, MS_OP_GET)
-#define ppb_MS_PUT_init(dev,body) ppb_MS_init(dev, body, MS_OP_PUT)
+#define ppb_MS_PUT_init(bus,dev,body) ppb_MS_init(bus, dev, body, MS_OP_PUT)
extern int ppb_MS_init(
- struct ppb_device *, /* ppbus device */
+ device_t, /* ppbus bus */
+ device_t, /* ppbus device */
struct ppb_microseq *, /* loop msq to assign */
int opcode /* MS_OP_GET, MS_OP_PUT */
);
@@ -175,7 +176,8 @@ extern int ppb_MS_init_msq(
);
extern int ppb_MS_exec(
- struct ppb_device *, /* ppbus device */
+ device_t, /* ppbus bus */
+ device_t, /* ppbus device */
int, /* microseq opcode */
union ppb_insarg, /* param1 */
union ppb_insarg, /* param2 */
@@ -184,7 +186,8 @@ extern int ppb_MS_exec(
);
extern int ppb_MS_loop(
- struct ppb_device *, /* ppbus device */
+ device_t, /* ppbus bus */
+ device_t, /* ppbus device */
struct ppb_microseq *, /* prologue msq of loop */
struct ppb_microseq *, /* body msq of loop */
struct ppb_microseq *, /* epilogue msq of loop */
@@ -193,7 +196,8 @@ extern int ppb_MS_loop(
);
extern int ppb_MS_microseq(
- struct ppb_device *, /* ppbus device */
+ device_t, /* ppbus bus */
+ device_t, /* ppbus device */
struct ppb_microseq *, /* msq to execute */
int * /* returned value */
);
diff --git a/sys/dev/ppbus/ppbconf.c b/sys/dev/ppbus/ppbconf.c
index f98fcf2..2d7aa1a 100644
--- a/sys/dev/ppbus/ppbconf.c
+++ b/sys/dev/ppbus/ppbconf.c
@@ -26,61 +26,154 @@
* $FreeBSD$
*
*/
+#include "opt_ppb_1284.h"
+
#include <sys/param.h>
#include <sys/systm.h>
-#include <sys/linker_set.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
#include <sys/malloc.h>
-#include <vm/vm.h>
-#include <vm/pmap.h>
-
#include <dev/ppbus/ppbconf.h>
#include <dev/ppbus/ppb_1284.h>
-#include "opt_ppb_1284.h"
+#include "ppbus_if.h"
+
+#define DEVTOSOFTC(dev) ((struct ppb_data *)device_get_softc(dev))
+
+MALLOC_DEFINE(M_PPBUSDEV, "ppbusdev", "Parallel Port bus device");
-static LIST_HEAD(, ppb_data) ppbdata; /* list of existing ppbus */
+static devclass_t ppbus_devclass;
/*
- * Add a null driver so that the linker set always exists.
+ * Device methods
*/
-
-static struct ppb_driver nulldriver = {
- NULL, NULL, "null"
+static int ppbus_probe(device_t);
+static int ppbus_attach(device_t);
+static void ppbus_print_child(device_t bus, device_t dev);
+static int ppbus_read_ivar(device_t, device_t, int, uintptr_t *);
+static int ppbus_write_ivar(device_t, device_t, int, u_long);
+static int ppbus_setup_intr(device_t, device_t, struct resource *, int,
+ void (*)(void *), void *, void **);
+static int ppbus_teardown_intr(device_t, device_t, struct resource *, void *);
+
+static device_method_t ppbus_methods[] = {
+ /* device interface */
+ DEVMETHOD(device_probe, ppbus_probe),
+ DEVMETHOD(device_attach, ppbus_attach),
+
+ /* bus interface */
+ DEVMETHOD(bus_print_child, ppbus_print_child),
+ DEVMETHOD(bus_read_ivar, ppbus_read_ivar),
+ DEVMETHOD(bus_write_ivar, ppbus_write_ivar),
+ DEVMETHOD(bus_setup_intr, ppbus_setup_intr),
+ DEVMETHOD(bus_teardown_intr, ppbus_teardown_intr),
+ DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
+
+ { 0, 0 }
};
-DATA_SET(ppbdriver_set, nulldriver);
+static driver_t ppbus_driver = {
+ "ppbus",
+ ppbus_methods,
+ sizeof(struct ppb_data),
+ };
+
+static void
+ppbus_print_child(device_t bus, device_t dev)
+{
+ struct ppb_device *ppbdev;
+
+ bus_print_child_header(bus, dev);
+
+ ppbdev = (struct ppb_device *)device_get_ivars(dev);
+
+ if (ppbdev->flags != 0)
+ printf(" flags 0x%x", ppbdev->flags);
+
+ printf(" on %s%d\n", device_get_name(bus), device_get_unit(bus));
+
+ return;
+}
+
+static int
+ppbus_probe(device_t dev)
+{
+ device_set_desc(dev, "Parallel port bus");
+
+ return (0);
+}
/*
- * ppb_alloc_bus()
+ * ppb_add_device()
*
- * Allocate area to store the ppbus description.
+ * Add a ppbus device, allocate/initialize the ivars
*/
-struct ppb_data *
-ppb_alloc_bus(void)
+static void
+ppbus_add_device(device_t dev, const char *name, int unit)
{
- struct ppb_data *ppb;
- static int ppbdata_initted = 0; /* done-init flag */
-
- ppb = (struct ppb_data *) malloc(sizeof(struct ppb_data),
- M_TEMP, M_NOWAIT);
+ struct ppb_device *ppbdev;
+ device_t child;
+
+ /* allocate ivars for the new ppbus child */
+ ppbdev = malloc(sizeof(struct ppb_device), M_PPBUSDEV, M_NOWAIT);
+ if (!ppbdev)
+ return;
+ bzero(ppbdev, sizeof *ppbdev);
+
+ /* initialize the ivars */
+ ppbdev->name = name;
+
+ /* add the device as a child to the ppbus bus with the allocated
+ * ivars */
+ child = device_add_child(dev, name, unit);
+ device_set_ivars(child, ppbdev);
- /*
- * Add the new parallel port bus to the list of existing ppbus.
- */
- if (ppb) {
- bzero(ppb, sizeof(struct ppb_data));
+ return;
+}
- if (!ppbdata_initted) { /* list not initialised */
- LIST_INIT(&ppbdata);
- ppbdata_initted = 1;
- }
- LIST_INSERT_HEAD(&ppbdata, ppb, ppb_chain);
- } else {
- printf("ppb_alloc_bus: cannot malloc!\n");
+static int
+ppbus_read_ivar(device_t bus, device_t dev, int index, uintptr_t* val)
+ {
+ struct ppb_device *ppbdev = (struct ppb_device *)device_get_ivars(dev);
+
+ switch (index) {
+ case PPBUS_IVAR_MODE:
+ /* XXX yet device mode = ppbus mode = chipset mode */
+ *val = (u_long)ppb_get_mode(bus);
+ ppbdev->mode = (u_short)*val;
+ break;
+ case PPBUS_IVAR_AVM:
+ *val = (u_long)ppbdev->avm;
+ break;
+ case PPBUS_IVAR_IRQ:
+ BUS_READ_IVAR(device_get_parent(bus), bus, PPC_IVAR_IRQ, val);
+ break;
+ default:
+ return (ENOENT);
}
- return(ppb);
+
+ return (0);
}
+
+static int
+ppbus_write_ivar(device_t bus, device_t dev, int index, u_long val)
+{
+ struct ppb_device *ppbdev = (struct ppb_device *)device_get_ivars(dev);
+
+ switch (index) {
+ case PPBUS_IVAR_MODE:
+ /* XXX yet device mode = ppbus mode = chipset mode */
+ ppb_set_mode(bus,val);
+ ppbdev->mode = ppb_get_mode(bus);
+ break;
+ default:
+ return (ENOENT);
+ }
+
+ return (0);
+ }
#define PPB_PNP_PRINTER 0
#define PPB_PNP_MODEM 1
@@ -151,17 +244,17 @@ search_token(char *str, int slen, char *token)
* Returns the class id. of the peripherial, -1 otherwise
*/
static int
-ppb_pnp_detect(struct ppb_data *ppb, struct ppb_device *pnpdev)
+ppb_pnp_detect(device_t bus)
{
char *token, *class = 0;
int i, len, error;
int class_id = -1;
char str[PPB_PnP_STRING_SIZE+1];
+ int unit = device_get_unit(bus);
- printf("Probing for PnP devices on ppbus%d:\n",
- ppb->ppb_link->adapter_unit);
+ printf("Probing for PnP devices on ppbus%d:\n", unit);
- if ((error = ppb_1284_read_id(pnpdev, PPB_NIBBLE, str,
+ if ((error = ppb_1284_read_id(bus, PPB_NIBBLE, str,
PPB_PnP_STRING_SIZE, &len)))
goto end_detect;
@@ -178,10 +271,10 @@ ppb_pnp_detect(struct ppb_data *ppb, struct ppb_device *pnpdev)
if ((token = search_token(str, len, "MFG")) != NULL ||
(token = search_token(str, len, "MANUFACTURER")) != NULL)
- printf("ppbus%d: <%s", ppb->ppb_link->adapter_unit,
+ printf("ppbus%d: <%s", unit,
search_token(token, UNKNOWN_LENGTH, ":") + 1);
else
- printf("ppbus%d: <unknown", ppb->ppb_link->adapter_unit);
+ printf("ppbus%d: <unknown", unit);
if ((token = search_token(str, len, "MDL")) != NULL ||
(token = search_token(str, len, "MODEL")) != NULL)
@@ -233,21 +326,11 @@ end_detect:
* Scan the ppbus for IEEE1284 compliant devices
*/
static int
-ppb_scan_bus(struct ppb_data *ppb)
+ppb_scan_bus(device_t bus)
{
- struct ppb_device pnpdev; /* temporary device to perform I/O */
+ struct ppb_data * ppb = (struct ppb_data *)device_get_softc(bus);
int error = 0;
-
- /* initialize the pnpdev structure for future use */
- bzero(&pnpdev, sizeof(pnpdev));
- pnpdev.ppb = ppb;
-
- if ((error = ppb_request_bus(&pnpdev, PPB_DONTWAIT))) {
- if (bootverbose)
- printf("ppb: cannot allocate ppbus!\n");
-
- return (error);
- }
+ int unit = device_get_unit(bus);
/* try all IEEE1284 modes, for one device only
*
@@ -255,207 +338,175 @@ ppb_scan_bus(struct ppb_data *ppb)
* daisy chained devices
*/
- error = ppb_1284_negociate(&pnpdev, PPB_NIBBLE, PPB_REQUEST_ID);
+ error = ppb_1284_negociate(bus, PPB_NIBBLE, PPB_REQUEST_ID);
if ((ppb->state == PPB_ERROR) && (ppb->error == PPB_NOT_IEEE1284))
goto end_scan;
- ppb_1284_terminate(&pnpdev);
+ ppb_1284_terminate(bus);
- printf("ppb%d: IEEE1284 device found ", ppb->ppb_link->adapter_unit);
+ printf("ppbus%d: IEEE1284 device found ", unit);
- if (!(error = ppb_1284_negociate(&pnpdev, PPB_NIBBLE, 0))) {
+ if (!(error = ppb_1284_negociate(bus, PPB_NIBBLE, 0))) {
printf("/NIBBLE");
- ppb_1284_terminate(&pnpdev);
+ ppb_1284_terminate(bus);
}
- if (!(error = ppb_1284_negociate(&pnpdev, PPB_PS2, 0))) {
+ if (!(error = ppb_1284_negociate(bus, PPB_PS2, 0))) {
printf("/PS2");
- ppb_1284_terminate(&pnpdev);
+ ppb_1284_terminate(bus);
}
- if (!(error = ppb_1284_negociate(&pnpdev, PPB_ECP, 0))) {
+ if (!(error = ppb_1284_negociate(bus, PPB_ECP, 0))) {
printf("/ECP");
- ppb_1284_terminate(&pnpdev);
+ ppb_1284_terminate(bus);
}
- if (!(error = ppb_1284_negociate(&pnpdev, PPB_ECP, PPB_USE_RLE))) {
+ if (!(error = ppb_1284_negociate(bus, PPB_ECP, PPB_USE_RLE))) {
printf("/ECP_RLE");
- ppb_1284_terminate(&pnpdev);
+ ppb_1284_terminate(bus);
}
- if (!(error = ppb_1284_negociate(&pnpdev, PPB_EPP, 0))) {
+ if (!(error = ppb_1284_negociate(bus, PPB_EPP, 0))) {
printf("/EPP");
- ppb_1284_terminate(&pnpdev);
+ ppb_1284_terminate(bus);
}
/* try more IEEE1284 modes */
if (bootverbose) {
- if (!(error = ppb_1284_negociate(&pnpdev, PPB_NIBBLE,
+ if (!(error = ppb_1284_negociate(bus, PPB_NIBBLE,
PPB_REQUEST_ID))) {
printf("/NIBBLE_ID");
- ppb_1284_terminate(&pnpdev);
+ ppb_1284_terminate(bus);
}
- if (!(error = ppb_1284_negociate(&pnpdev, PPB_PS2,
+ if (!(error = ppb_1284_negociate(bus, PPB_PS2,
PPB_REQUEST_ID))) {
printf("/PS2_ID");
- ppb_1284_terminate(&pnpdev);
+ ppb_1284_terminate(bus);
}
- if (!(error = ppb_1284_negociate(&pnpdev, PPB_ECP,
+ if (!(error = ppb_1284_negociate(bus, PPB_ECP,
PPB_REQUEST_ID))) {
printf("/ECP_ID");
- ppb_1284_terminate(&pnpdev);
+ ppb_1284_terminate(bus);
}
- if (!(error = ppb_1284_negociate(&pnpdev, PPB_ECP,
+ if (!(error = ppb_1284_negociate(bus, PPB_ECP,
PPB_REQUEST_ID | PPB_USE_RLE))) {
printf("/ECP_RLE_ID");
- ppb_1284_terminate(&pnpdev);
+ ppb_1284_terminate(bus);
}
- if (!(error = ppb_1284_negociate(&pnpdev, PPB_COMPATIBLE,
+ if (!(error = ppb_1284_negociate(bus, PPB_COMPATIBLE,
PPB_EXTENSIBILITY_LINK))) {
printf("/Extensibility Link");
- ppb_1284_terminate(&pnpdev);
+ ppb_1284_terminate(bus);
}
}
printf("\n");
/* detect PnP devices */
- ppb->class_id = ppb_pnp_detect(ppb, &pnpdev);
-
- ppb_release_bus(&pnpdev);
+ ppb->class_id = ppb_pnp_detect(bus);
return (0);
end_scan:
- ppb_release_bus(&pnpdev);
return (error);
}
#endif /* !DONTPROBE_1284 */
-/*
- * ppb_attachdevs()
- *
- * Called by ppcattach(), this function probes the ppbus and
- * attaches found devices.
- */
-int
-ppb_attachdevs(struct ppb_data *ppb)
+static int
+ppbus_attach(device_t dev)
{
- struct ppb_device *dev;
- struct ppb_driver **p_drvpp, *p_drvp;
+ int i;
+ int unit, disabled;
+ char *name;
- LIST_INIT(&ppb->ppb_devs); /* initialise device/driver list */
- p_drvpp = (struct ppb_driver **)ppbdriver_set.ls_items;
-
-#ifndef DONTPROBE_1284
- /* detect IEEE1284 compliant devices */
- ppb_scan_bus(ppb);
-#endif /* !DONTPROBE_1284 */
-
/*
- * Blindly try all probes here. Later we should look at
- * the parallel-port PnP standard, and intelligently seek
- * drivers based on configuration first.
+ * Add all devices configured to be attached to ppbus0.
*/
- while ((p_drvp = *p_drvpp++) != NULL) {
- if (p_drvp->probe && (dev = (p_drvp->probe(ppb))) != NULL) {
- /*
- * Add the device to the list of probed devices.
- */
- LIST_INSERT_HEAD(&ppb->ppb_devs, dev, chain);
-
- /* Call the device's attach routine */
- (void)p_drvp->attach(dev);
- }
+ for (i = resource_query_string(-1, "at", "ppbus0");
+ i != -1;
+ i = resource_query_string(i, "at", "ppbus0")) {
+ unit = resource_query_unit(i);
+ name = resource_query_name(i);
+ if (resource_int_value(name, unit, "disabled", &disabled) == 0) {
+ if (disabled)
+ continue;
+ }
+ ppbus_add_device(dev, name, unit);
}
- return (0);
-}
-
-/*
- * ppb_next_bus()
- *
- * Return the next bus in ppbus queue
- */
-struct ppb_data *
-ppb_next_bus(struct ppb_data *ppb)
-{
- if (ppb == NULL)
- return (ppbdata.lh_first);
-
- return (ppb->ppb_chain.le_next);
-}
+ /*
+ * and ppbus?
+ */
+ for (i = resource_query_string(-1, "at", "ppbus");
+ i != -1;
+ i = resource_query_string(i, "at", "ppbus")) {
+ unit = resource_query_unit(i);
+ name = resource_query_name(i);
+ if (resource_int_value(name, unit, "disabled", &disabled) == 0) {
+ if (disabled)
+ continue;
+ }
+ ppbus_add_device(dev, name, unit);
+ }
-/*
- * ppb_lookup_bus()
- *
- * Get ppb_data structure pointer according to the base address of the ppbus
- */
-struct ppb_data *
-ppb_lookup_bus(int base_port)
-{
- struct ppb_data *ppb;
+#ifndef DONTPROBE_1284
+ /* detect IEEE1284 compliant devices */
+ ppb_scan_bus(dev);
+#endif /* !DONTPROBE_1284 */
- for (ppb = ppbdata.lh_first; ppb; ppb = ppb->ppb_chain.le_next)
- if (ppb->ppb_link->base == base_port)
- break;
+ /* launch attachement of the added children */
+ bus_generic_attach(dev);
- return (ppb);
+ return 0;
}
-/*
- * ppb_lookup_link()
- *
- * Get ppb_data structure pointer according to the unit value
- * of the corresponding link structure
- */
-struct ppb_data *
-ppb_lookup_link(int unit)
+static int
+ppbus_setup_intr(device_t bus, device_t child, struct resource *r, int flags,
+ void (*ihand)(void *), void *arg, void **cookiep)
{
- struct ppb_data *ppb;
+ int error;
+ struct ppb_data *ppb = DEVTOSOFTC(bus);
+ struct ppb_device *ppbdev = (struct ppb_device *)device_get_ivars(child);
- for (ppb = ppbdata.lh_first; ppb; ppb = ppb->ppb_chain.le_next)
- if (ppb->ppb_link->adapter_unit == unit)
- break;
+ /* a device driver must own the bus to register an interrupt */
+ if (ppb->ppb_owner != child)
+ return (EINVAL);
- return (ppb);
-}
-
-/*
- * ppb_attach_device()
- *
- * Called by loadable kernel modules to add a device
- */
-int
-ppb_attach_device(struct ppb_device *dev)
-{
- struct ppb_data *ppb = dev->ppb;
+ if ((error = BUS_SETUP_INTR(device_get_parent(bus), child, r, flags,
+ ihand, arg, cookiep)))
+ return (error);
- /* add the device to the list of probed devices */
- LIST_INSERT_HEAD(&ppb->ppb_devs, dev, chain);
+ /* store the resource and the cookie for eventually forcing
+ * handler unregistration
+ */
+ ppbdev->intr_cookie = *cookiep;
+ ppbdev->intr_resource = r;
return (0);
}
-/*
- * ppb_remove_device()
- *
- * Called by loadable kernel modules to remove a device
- */
-void
-ppb_remove_device(struct ppb_device *dev)
+static int
+ppbus_teardown_intr(device_t bus, device_t child, struct resource *r, void *ih)
{
+ struct ppb_data *ppb = DEVTOSOFTC(bus);
+ struct ppb_device *ppbdev = (struct ppb_device *)device_get_ivars(child);
+
+ /* a device driver must own the bus to unregister an interrupt */
+ if ((ppb->ppb_owner != child) || (ppbdev->intr_cookie != ih) ||
+ (ppbdev->intr_resource != r))
+ return (EINVAL);
- /* remove the device from the list of probed devices */
- LIST_REMOVE(dev, chain);
+ ppbdev->intr_cookie = 0;
+ ppbdev->intr_resource = 0;
- return;
+ /* pass unregistration to the upper layer */
+ return (BUS_TEARDOWN_INTR(device_get_parent(bus), child, r, ih));
}
/*
@@ -466,10 +517,11 @@ ppb_remove_device(struct ppb_device *dev)
* how : PPB_WAIT or PPB_DONTWAIT
*/
int
-ppb_request_bus(struct ppb_device *dev, int how)
+ppb_request_bus(device_t bus, device_t dev, int how)
{
int s, error = 0;
- struct ppb_data *ppb = dev->ppb;
+ struct ppb_data *ppb = DEVTOSOFTC(bus);
+ struct ppb_device *ppbdev = (struct ppb_device *)device_get_ivars(dev);
while (!error) {
s = splhigh();
@@ -499,8 +551,8 @@ ppb_request_bus(struct ppb_device *dev, int how)
* drivers that do not set there operating mode
* during attachement
*/
- if (dev->ctx.valid)
- ppb_set_mode(dev, dev->ctx.mode);
+ if (ppbdev->ctx.valid)
+ ppb_set_mode(bus, ppbdev->ctx.mode);
splx(s);
return (0);
@@ -516,10 +568,17 @@ ppb_request_bus(struct ppb_device *dev, int how)
* Release the device allocated with ppb_request_dev()
*/
int
-ppb_release_bus(struct ppb_device *dev)
+ppb_release_bus(device_t bus, device_t dev)
{
- int s;
- struct ppb_data *ppb = dev->ppb;
+ int s, error;
+ struct ppb_data *ppb = DEVTOSOFTC(bus);
+ struct ppb_device *ppbdev = (struct ppb_device *)device_get_ivars(dev);
+
+ if (ppbdev->intr_resource != 0)
+ /* force interrupt handler unregistration when the ppbus is released */
+ if ((error = BUS_TEARDOWN_INTR(bus, dev, ppbdev->intr_resource,
+ ppbdev->intr_cookie)))
+ return (error);
s = splhigh();
if (ppb->ppb_owner != dev) {
@@ -531,13 +590,15 @@ ppb_release_bus(struct ppb_device *dev)
splx(s);
/* save the context of the device */
- dev->ctx.mode = ppb_get_mode(dev);
+ ppbdev->ctx.mode = ppb_get_mode(bus);
/* ok, now the context of the device is valid */
- dev->ctx.valid = 1;
+ ppbdev->ctx.valid = 1;
/* wakeup waiting processes */
wakeup(ppb);
return (0);
}
+
+DRIVER_MODULE(ppbus, ppc, ppbus_driver, ppbus_devclass, 0, 0);
diff --git a/sys/dev/ppbus/ppbconf.h b/sys/dev/ppbus/ppbconf.h
index 4160f0c..93fc886 100644
--- a/sys/dev/ppbus/ppbconf.h
+++ b/sys/dev/ppbus/ppbconf.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1997, 1998 Nicolas Souchu
+ * Copyright (c) 1997, 1998, 1999 Nicolas Souchu
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -55,9 +55,9 @@
#define PPB_OPTIONS_MASK 0xf0
#define PPB_IS_EPP(mode) (mode & PPB_EPP)
-#define PPB_IN_EPP_MODE(dev) (PPB_IS_EPP (ppb_get_mode (dev)))
-#define PPB_IN_NIBBLE_MODE(dev) (ppb_get_mode (dev) & PPB_NIBBLE)
-#define PPB_IN_PS2_MODE(dev) (ppb_get_mode (dev) & PPB_PS2)
+#define PPB_IN_EPP_MODE(bus) (PPB_IS_EPP (ppb_get_mode (bus)))
+#define PPB_IN_NIBBLE_MODE(bus) (ppb_get_mode (bus) & PPB_NIBBLE)
+#define PPB_IN_PS2_MODE(bus) (ppb_get_mode (bus) & PPB_PS2)
#define n(flags) (~(flags) & (flags))
@@ -101,6 +101,28 @@ struct ppb_status {
unsigned int busy:1;
};
+/* Parallel port bus I/O opcodes */
+#define PPB_OUTSB_EPP 1
+#define PPB_OUTSW_EPP 2
+#define PPB_OUTSL_EPP 3
+#define PPB_INSB_EPP 4
+#define PPB_INSW_EPP 5
+#define PPB_INSL_EPP 6
+#define PPB_RDTR 7
+#define PPB_RSTR 8
+#define PPB_RCTR 9
+#define PPB_REPP_A 10
+#define PPB_REPP_D 11
+#define PPB_RECR 12
+#define PPB_RFIFO 13
+#define PPB_WDTR 14
+#define PPB_WSTR 15
+#define PPB_WCTR 16
+#define PPB_WEPP_A 17
+#define PPB_WEPP_D 18
+#define PPB_WECR 19
+#define PPB_WFIFO 20
+
/*
* How tsleep() is called in ppb_request_bus().
*/
@@ -152,14 +174,23 @@ struct ppb_context {
struct microseq *curmsq; /* currently executed microseqence */
};
+/*
+ * List of IVARS available to ppb device drivers
+ */
+#define PPBUS_IVAR_MODE 0
+#define PPBUS_IVAR_AVM 1
+#define PPBUS_IVAR_IRQ 2
+
+/* other fields are reserved to the ppbus internals */
+
struct ppb_device {
- int id_unit; /* unit of the device */
- char *name; /* name of the device */
+ const char *name; /* name of the device */
ushort mode; /* current mode of the device */
ushort avm; /* available IEEE1284 modes of
* the device */
+ uint flags; /* flags */
struct ppb_context ctx; /* context of the device */
@@ -172,76 +203,21 @@ struct ppb_device {
* IEEE1284 code is used */
struct ppb_xfer
put_xfer[PPB_MAX_XFER];
-
- void (*intr)(int); /* interrupt handler */
- void (*bintr)(struct ppb_device *); /* interrupt handler */
+
+ struct resource *intr_resource;
+ void *intr_cookie;
void *drv1, *drv2; /* drivers private data */
-
- struct ppb_data *ppb; /* link to the ppbus */
-
- LIST_ENTRY(ppb_device) chain; /* list of devices on the bus */
};
-/*
- * Parallel Port Bus Adapter structure.
- */
-struct ppb_adapter {
-
- void (*intr_handler)(int);
- void (*reset_epp_timeout)(int);
- void (*ecp_sync)(int);
-
- int (*exec_microseq)(int, struct ppb_microseq **);
-
- int (*setmode)(int, int);
- int (*read)(int, char *, int, int);
- int (*write)(int, char *, int, int);
-
- void (*outsb_epp)(int, char *, int);
- void (*outsw_epp)(int, char *, int);
- void (*outsl_epp)(int, char *, int);
- void (*insb_epp)(int, char *, int);
- void (*insw_epp)(int, char *, int);
- void (*insl_epp)(int, char *, int);
-
- u_char (*r_dtr)(int);
- u_char (*r_str)(int);
- u_char (*r_ctr)(int);
- u_char (*r_epp_A)(int);
- u_char (*r_epp_D)(int);
- u_char (*r_ecr)(int);
- u_char (*r_fifo)(int);
-
- void (*w_dtr)(int, char);
- void (*w_str)(int, char);
- void (*w_ctr)(int, char);
- void (*w_epp_A)(int, char);
- void (*w_epp_D)(int, char);
- void (*w_ecr)(int, char);
- void (*w_fifo)(int, char);
-};
-
-/*
- * ppb_link structure.
- */
-struct ppb_link {
-
- int adapter_unit; /* unit of the adapter */
- int base; /* base address of the port */
- int id_irq; /* != 0 if irq enabled */
- int accum; /* microseq accum */
- char *ptr; /* current buffer pointer */
-
+/* EPP standards */
#define EPP_1_9 0x0 /* default */
#define EPP_1_7 0x1
-
- int epp_protocol; /* EPP protocol: 0=1.9, 1=1.7 */
-
- struct ppb_adapter *adapter; /* link to the ppc adapter */
- struct ppb_data *ppbus; /* link to the ppbus */
-};
-
+
+/* Parallel Port Chipset IVARS */ /* elsewhere XXX */
+#define PPC_IVAR_EPP_PROTO 0
+#define PPC_IVAR_IRQ 1
+
/*
* Maximum size of the PnP info string
*/
@@ -263,113 +239,36 @@ struct ppb_data {
#define PPB_PnP_SCANNER 8
#define PPB_PnP_DIGICAM 9
#define PPB_PnP_UNKNOWN 10
- int class_id; /* not a PnP device if class_id < 0 */
-
- int state; /* current IEEE1284 state */
- int error; /* last IEEE1284 error */
+ int class_id; /* not a PnP device if class_id < 0 */
- ushort mode; /* IEEE 1284-1994 mode
- * NIBBLE, PS2, EPP or ECP */
+ int state; /* current IEEE1284 state */
+ int error; /* last IEEE1284 error */
- struct ppb_link *ppb_link; /* link to the adapter */
- struct ppb_device *ppb_owner; /* device which owns the bus */
- LIST_HEAD(, ppb_device) ppb_devs; /* list of devices on the bus */
- LIST_ENTRY(ppb_data) ppb_chain; /* list of busses */
-};
+ int mode; /* IEEE 1284-1994 mode
+ * NIBBLE, PS2, EPP or ECP */
-/*
- * Parallel Port Bus driver structure.
- */
-struct ppb_driver
-{
- struct ppb_device *(*probe)(struct ppb_data *ppb);
- int (*attach)(struct ppb_device *pdp);
- char *name;
+ void *ppb_owner; /* device which owns the bus */
};
-extern struct linker_set ppbdriver_set;
-
-extern struct ppb_data *ppb_alloc_bus(void);
-extern struct ppb_data *ppb_next_bus(struct ppb_data *);
-extern struct ppb_data *ppb_lookup_bus(int);
-extern struct ppb_data *ppb_lookup_link(int);
+extern int ppb_attach_device(device_t);
+extern int ppb_request_bus(device_t, device_t, int);
+extern int ppb_release_bus(device_t, device_t);
-extern int ppb_attach_device(struct ppb_device *);
-extern void ppb_remove_device(struct ppb_device *);
-extern int ppb_attachdevs(struct ppb_data *);
-
-extern int ppb_request_bus(struct ppb_device *, int);
-extern int ppb_release_bus(struct ppb_device *);
-
-extern void ppb_intr(struct ppb_link *);
-
-extern int ppb_poll_device(struct ppb_device *, int, char, char, int);
-
-extern int ppb_reset_epp_timeout(struct ppb_device *);
-extern int ppb_ecp_sync(struct ppb_device *);
-extern int ppb_get_status(struct ppb_device *, struct ppb_status *);
-
-extern int ppb_set_mode(struct ppb_device *, int);
-extern int ppb_write(struct ppb_device *, char *, int, int);
+/* bus related functions */
+extern int ppb_get_status(device_t, struct ppb_status *);
+extern int ppb_poll_bus(device_t, int, char, char, int);
+extern int ppb_reset_epp_timeout(device_t);
+extern int ppb_ecp_sync(device_t);
+extern int ppb_get_epp_protocol(device_t);
+extern int ppb_set_mode(device_t, int); /* returns old mode */
+extern int ppb_get_mode(device_t); /* returns current mode */
+extern int ppb_write(device_t, char *, int, int);
/*
* These are defined as macros for speedup.
- */
#define ppb_get_base_addr(dev) ((dev)->ppb->ppb_link->base)
#define ppb_get_epp_protocol(dev) ((dev)->ppb->ppb_link->epp_protocol)
#define ppb_get_irq(dev) ((dev)->ppb->ppb_link->id_irq)
-
-#define ppb_get_mode(dev) ((dev)->mode)
-
-/* This set of function access only to the EPP _data_ registers
- * in 8, 16 and 32 bit modes */
-#define ppb_outsb_epp(dev,buf,cnt) \
- (*(dev)->ppb->ppb_link->adapter->outsb_epp) \
- ((dev)->ppb->ppb_link->adapter_unit, buf, cnt)
-#define ppb_outsw_epp(dev,buf,cnt) \
- (*(dev)->ppb->ppb_link->adapter->outsw_epp) \
- ((dev)->ppb->ppb_link->adapter_unit, buf, cnt)
-#define ppb_outsl_epp(dev,buf,cnt) \
- (*(dev)->ppb->ppb_link->adapter->outsl_epp) \
- ((dev)->ppb->ppb_link->adapter_unit, buf, cnt)
-#define ppb_insb_epp(dev,buf,cnt) \
- (*(dev)->ppb->ppb_link->adapter->insb_epp) \
- ((dev)->ppb->ppb_link->adapter_unit, buf, cnt)
-#define ppb_insw_epp(dev,buf,cnt) \
- (*(dev)->ppb->ppb_link->adapter->insw_epp) \
- ((dev)->ppb->ppb_link->adapter_unit, buf, cnt)
-#define ppb_insl_epp(dev,buf,cnt) \
- (*(dev)->ppb->ppb_link->adapter->insl_epp) \
- ((dev)->ppb->ppb_link->adapter_unit, buf, cnt)
-
-#define ppb_repp_A(dev) (*(dev)->ppb->ppb_link->adapter->r_epp_A) \
- ((dev)->ppb->ppb_link->adapter_unit)
-#define ppb_repp_D(dev) (*(dev)->ppb->ppb_link->adapter->r_epp_D) \
- ((dev)->ppb->ppb_link->adapter_unit)
-#define ppb_recr(dev) (*(dev)->ppb->ppb_link->adapter->r_ecr) \
- ((dev)->ppb->ppb_link->adapter_unit)
-#define ppb_rfifo(dev) (*(dev)->ppb->ppb_link->adapter->r_fifo) \
- ((dev)->ppb->ppb_link->adapter_unit)
-#define ppb_wepp_A(dev,byte) (*(dev)->ppb->ppb_link->adapter->w_epp_A) \
- ((dev)->ppb->ppb_link->adapter_unit, byte)
-#define ppb_wepp_D(dev,byte) (*(dev)->ppb->ppb_link->adapter->w_epp_D) \
- ((dev)->ppb->ppb_link->adapter_unit, byte)
-#define ppb_wecr(dev,byte) (*(dev)->ppb->ppb_link->adapter->w_ecr) \
- ((dev)->ppb->ppb_link->adapter_unit, byte)
-#define ppb_wfifo(dev,byte) (*(dev)->ppb->ppb_link->adapter->w_fifo) \
- ((dev)->ppb->ppb_link->adapter_unit, byte)
-
-#define ppb_rdtr(dev) (*(dev)->ppb->ppb_link->adapter->r_dtr) \
- ((dev)->ppb->ppb_link->adapter_unit)
-#define ppb_rstr(dev) (*(dev)->ppb->ppb_link->adapter->r_str) \
- ((dev)->ppb->ppb_link->adapter_unit)
-#define ppb_rctr(dev) (*(dev)->ppb->ppb_link->adapter->r_ctr) \
- ((dev)->ppb->ppb_link->adapter_unit)
-#define ppb_wdtr(dev,byte) (*(dev)->ppb->ppb_link->adapter->w_dtr) \
- ((dev)->ppb->ppb_link->adapter_unit, byte)
-#define ppb_wstr(dev,byte) (*(dev)->ppb->ppb_link->adapter->w_str) \
- ((dev)->ppb->ppb_link->adapter_unit, byte)
-#define ppb_wctr(dev,byte) (*(dev)->ppb->ppb_link->adapter->w_ctr) \
- ((dev)->ppb->ppb_link->adapter_unit, byte)
+ */
#endif
diff --git a/sys/dev/ppbus/ppbio.h b/sys/dev/ppbus/ppbio.h
new file mode 100644
index 0000000..2794edd
--- /dev/null
+++ b/sys/dev/ppbus/ppbio.h
@@ -0,0 +1,83 @@
+/*-
+ * Copyright (c) 1999 Nicolas Souchu
+ * 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 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$
+ *
+ */
+
+#ifndef __PPBIO_H
+#define __PPBIO_H
+
+/*
+ * Set of ppbus i/o routines callable from ppbus device drivers
+ */
+
+#define ppb_outsb_epp(dev,buf,cnt) \
+ (PPBUS_IO(device_get_parent(dev), PPB_OUTSB_EPP, buf, cnt, 0))
+#define ppb_outsw_epp(dev,buf,cnt) \
+ (PPBUS_IO(device_get_parent(dev), PPB_OUTSW_EPP, buf, cnt, 0))
+#define ppb_outsl_epp(dev,buf,cnt) \
+ (PPBUS_IO(device_get_parent(dev), PPB_OUTSL_EPP, buf, cnt, 0))
+
+#define ppb_insb_epp(dev,buf,cnt) \
+ (PPBUS_IO(device_get_parent(dev), PPB_INSB_EPP, buf, cnt, 0))
+#define ppb_insw_epp(dev,buf,cnt) \
+ (PPBUS_IO(device_get_parent(dev), PPB_INSW_EPP, buf, cnt, 0))
+#define ppb_insl_epp(dev,buf,cnt) \
+ (PPBUS_IO(device_get_parent(dev), PPB_INSL_EPP, buf, cnt, 0))
+
+#define ppb_repp_A(dev) \
+ (PPBUS_IO(device_get_parent(dev), PPB_REPP_A, 0, 0, 0))
+#define ppb_repp_D(dev) \
+ (PPBUS_IO(device_get_parent(dev), PPB_REPP_D, 0, 0, 0))
+#define ppb_recr(dev) \
+ (PPBUS_IO(device_get_parent(dev), PPB_RECR, 0, 0, 0))
+#define ppb_rfifo(dev) \
+ (PPBUS_IO(device_get_parent(dev), PPB_RFIFO, 0, 0, 0))
+
+#define ppb_wepp_A(dev,byte) \
+ (PPBUS_IO(device_get_parent(dev), PPB_WEPP_A, 0, 0, byte))
+#define ppb_wepp_D(dev,byte) \
+ (PPBUS_IO(device_get_parent(dev), PPB_WEPP_D, 0, 0, byte))
+#define ppb_wecr(dev,byte) \
+ (PPBUS_IO(device_get_parent(dev), PPB_WECR, 0, 0, byte))
+#define ppb_wfifo(dev,byte) \
+ (PPBUS_IO(device_get_parent(dev), PPB_WFIFO, 0, 0, byte))
+
+#define ppb_rdtr(dev) \
+ (PPBUS_IO(device_get_parent(dev), PPB_RDTR, 0, 0, 0))
+#define ppb_rstr(dev) \
+ (PPBUS_IO(device_get_parent(dev), PPB_RSTR, 0, 0, 0))
+#define ppb_rctr(dev) \
+ (PPBUS_IO(device_get_parent(dev), PPB_RCTR, 0, 0, 0))
+
+#define ppb_wdtr(dev,byte) \
+ (PPBUS_IO(device_get_parent(dev), PPB_WDTR, 0, 0, byte))
+#define ppb_wstr(dev,byte) \
+ (PPBUS_IO(device_get_parent(dev), PPB_WSTR, 0, 0, byte))
+#define ppb_wctr(dev,byte) \
+ (PPBUS_IO(device_get_parent(dev), PPB_WCTR, 0, 0, byte))
+
+#endif
diff --git a/sys/dev/ppbus/ppbus_if.m b/sys/dev/ppbus/ppbus_if.m
new file mode 100644
index 0000000..00af081
--- /dev/null
+++ b/sys/dev/ppbus/ppbus_if.m
@@ -0,0 +1,92 @@
+#
+# Copyright (c) 1999 Nicolas Souchu
+# 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 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$
+#
+
+#include <dev/ppbus/ppbconf.h>
+
+INTERFACE ppbus;
+
+#
+# Do low level i/o operations
+#
+METHOD u_char io {
+ device_t dev;
+ int opcode;
+ u_char *addr;
+ int cnt;
+ u_char byte;
+};
+
+#
+# Execution of a microsequence
+#
+METHOD int exec_microseq {
+ device_t dev;
+ struct ppb_microseq **ppb_microseq;
+};
+
+#
+# Reset EPP timeout
+#
+METHOD int reset_epp {
+ device_t dev;
+}
+
+#
+# Set chipset mode
+#
+METHOD int setmode {
+ device_t dev;
+ int mode;
+}
+
+#
+# Synchronize ECP FIFO
+#
+METHOD int ecp_sync {
+ device_t dev;
+}
+
+#
+# Do chipset dependent low level read
+#
+METHOD int read {
+ device_t dev;
+ char *buf;
+ int len;
+ int how;
+}
+
+#
+# Do chipset dependent low level write
+#
+METHOD int write {
+ device_t dev;
+ char *buf;
+ int len;
+ int how;
+}
diff --git a/sys/dev/ppbus/ppi.c b/sys/dev/ppbus/ppi.c
index c610e7f..bd0a638 100644
--- a/sys/dev/ppbus/ppi.c
+++ b/sys/dev/ppbus/ppi.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1997, 1998 Nicolas Souchu, Michael Smith
+ * Copyright (c) 1997, 1998, 1999 Nicolas Souchu, Michael Smith
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,27 +30,35 @@
#if NPPI > 0
+#include "opt_ppb_1284.h"
+
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/module.h>
+#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/uio.h>
-#include <sys/malloc.h>
#include <sys/fcntl.h>
#include <machine/clock.h>
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/rman.h>
#include <dev/ppbus/ppbconf.h>
#include <dev/ppbus/ppb_msq.h>
-#include "opt_ppb_1284.h"
-
#ifdef PERIPH_1284
#include <dev/ppbus/ppb_1284.h>
#endif
#include <dev/ppbus/ppi.h>
+#include "ppbus_if.h"
+
+#include <dev/ppbus/ppbio.h>
+
#define BUFSIZE 512
struct ppi_data {
@@ -64,25 +72,36 @@ struct ppi_data {
int ppi_mode; /* IEEE1284 mode */
char ppi_buffer[BUFSIZE];
- struct ppb_device ppi_dev;
+ struct resource *intr_resource; /* interrupt resource */
+ void *intr_cookie; /* interrupt registration cookie */
};
-#define MAXPPI 8 /* XXX not much better! */
-static int nppi = 0;
-static struct ppi_data *ppidata[MAXPPI];
+#define DEVTOSOFTC(dev) \
+ ((struct ppi_data *)device_get_softc(dev))
+#define UNITOSOFTC(unit) \
+ ((struct ppi_data *)devclass_get_softc(ppi_devclass, (unit)))
+#define UNITODEVICE(unit) \
+ (devclass_get_device(ppi_devclass, (unit)))
-/*
- * Make ourselves visible as a ppbus driver
- */
+static int ppi_probe(device_t);
+static int ppi_attach(device_t);
+static void ppiintr(void *arg);
+
+static devclass_t ppi_devclass;
-static struct ppb_device *ppiprobe(struct ppb_data *ppb);
-static int ppiattach(struct ppb_device *dev);
-static void ppiintr(int unit);
+static device_method_t ppi_methods[] = {
+ /* device interface */
+ DEVMETHOD(device_probe, ppi_probe),
+ DEVMETHOD(device_attach, ppi_attach),
-static struct ppb_driver ppidriver = {
- ppiprobe, ppiattach, "ppi"
+ { 0, 0 }
+};
+
+static driver_t ppi_driver = {
+ "ppi",
+ ppi_methods,
+ sizeof(struct ppi_data),
};
-DATA_SET(ppbdriver_set, ppidriver);
static d_open_t ppiopen;
static d_close_t ppiclose;
@@ -111,23 +130,25 @@ static struct cdevsw ppi_cdevsw = {
#ifdef PERIPH_1284
static void
-ppi_enable_intr(struct ppi_data *ppi)
+ppi_enable_intr(device_t ppidev)
{
char r;
+ device_t ppbus = device_get_parent(ppidev);
- r = ppb_rctr(&ppi->ppi_dev);
- ppb_wctr(&ppi->ppi_dev, r | IRQENABLE);
+ r = ppb_rctr(ppbus);
+ ppb_wctr(ppbus, r | IRQENABLE);
return;
}
static void
-ppi_disable_intr(struct ppi_data *ppi)
+ppi_disable_intr(device_t ppidev)
{
char r;
+ device_t ppbus = device_get_parent(ppidev);
- r = ppb_rctr(&ppi->ppi_dev);
- ppb_wctr(&ppi->ppi_dev, r & ~IRQENABLE);
+ r = ppb_rctr(ppbus);
+ ppb_wctr(ppbus, r & ~IRQENABLE);
return;
}
@@ -135,55 +156,48 @@ ppi_disable_intr(struct ppi_data *ppi)
#endif /* PERIPH_1284 */
/*
- * ppiprobe()
+ * ppi_probe()
*/
-static struct ppb_device *
-ppiprobe(struct ppb_data *ppb)
+static int
+ppi_probe(device_t dev)
{
struct ppi_data *ppi;
static int once;
+ /* probe is always ok */
+ device_set_desc(dev, "Parallel I/O");
+
if (!once++)
cdevsw_add(&ppi_cdevsw);
- ppi = (struct ppi_data *) malloc(sizeof(struct ppi_data),
- M_TEMP, M_NOWAIT);
- if (!ppi) {
- printf("ppi: cannot malloc!\n");
- return 0;
- }
+ ppi = DEVTOSOFTC(dev);
bzero(ppi, sizeof(struct ppi_data));
- ppidata[nppi] = ppi;
-
- /*
- * ppi dependent initialisation.
- */
- ppi->ppi_unit = nppi;
-
- /*
- * ppbus dependent initialisation.
- */
- ppi->ppi_dev.id_unit = ppi->ppi_unit;
- ppi->ppi_dev.ppb = ppb;
- ppi->ppi_dev.intr = ppiintr;
-
- /* Ok, go to next device on next probe */
- nppi ++;
-
- return &ppi->ppi_dev;
+ return (0);
}
+/*
+ * ppi_attach()
+ */
static int
-ppiattach(struct ppb_device *dev)
+ppi_attach(device_t dev)
{
- /*
- * Report ourselves
- */
- printf("ppi%d: <generic parallel i/o> on ppbus %d\n",
- dev->id_unit, dev->ppb->ppb_link->adapter_unit);
+ uintptr_t irq;
+ int zero = 0;
+ struct ppi_data *ppi = DEVTOSOFTC(dev);
+
+ /* retrive the irq */
+ BUS_READ_IVAR(device_get_parent(dev), dev, PPBUS_IVAR_IRQ, &irq);
- return (1);
+ /* declare our interrupt handler */
+ ppi->intr_resource = bus_alloc_resource(dev, SYS_RES_IRQ,
+ &zero, irq, irq, 1, RF_ACTIVE);
+
+ make_dev(&ppi_cdevsw, device_get_unit(dev), /* XXX cleanup */
+ UID_ROOT, GID_WHEEL,
+ 0600, "ppi%d", device_get_unit(dev));
+
+ return (0);
}
/*
@@ -199,20 +213,22 @@ ppiattach(struct ppb_device *dev)
*
*/
static void
-ppiintr(int unit)
+ppiintr(void *arg)
{
#ifdef PERIPH_1284
- struct ppi_data *ppi = ppidata[unit];
+ device_t ppidev = (device_t)arg;
+ device_t ppbus = device_get_parent(ppidev);
+ struct ppi_data *ppi = DEVTOSOFTC(ppidev);
- ppi_disable_intr(ppi);
+ ppi_disable_intr(ppidev);
- switch (ppi->ppi_dev.ppb->state) {
+ switch (ppb_1284_get_state(ppbus)) {
/* accept IEEE1284 negociation then wakeup an waiting process to
* continue negociation at process level */
case PPB_FORWARD_IDLE:
/* Event 1 */
- if ((ppb_rstr(&ppi->ppi_dev) & (SELECT | nBUSY)) ==
+ if ((ppb_rstr(ppbus) & (SELECT | nBUSY)) ==
(SELECT | nBUSY)) {
/* IEEE1284 negociation */
#ifdef DEBUG_1284
@@ -220,15 +236,15 @@ ppiintr(int unit)
#endif
/* Event 2 - prepare for reading the ext. value */
- ppb_wctr(&ppi->ppi_dev, (PCD | STROBE | nINIT) & ~SELECTIN);
+ ppb_wctr(ppbus, (PCD | STROBE | nINIT) & ~SELECTIN);
- ppi->ppi_dev.ppb->state = PPB_NEGOCIATION;
+ ppb_1284_set_state(ppbus, PPB_NEGOCIATION);
} else {
#ifdef DEBUG_1284
- printf("0x%x", ppb_rstr(&ppi->ppi_dev));
+ printf("0x%x", ppb_rstr(ppbus));
#endif
- ppb_peripheral_terminate(&ppi->ppi_dev, PPB_DONTWAIT);
+ ppb_peripheral_terminate(ppbus, PPB_DONTWAIT);
break;
}
@@ -242,14 +258,14 @@ ppiintr(int unit)
break;
default:
#ifdef DEBUG_1284
- printf("?%d", ppi->ppi_dev.ppb->state);
+ printf("?%d", ppb_1284_get_state(ppbus);
#endif
- ppi->ppi_dev.ppb->state = PPB_FORWARD_IDLE;
- ppb_set_mode(&ppi->ppi_dev, PPB_COMPATIBLE);
+ ppb_1284_set_state(ppbus, PPB_FORWARD_IDLE);
+ ppb_set_mode(ppbus, PPB_COMPATIBLE);
break;
}
- ppi_enable_intr(ppi);
+ ppi_enable_intr(ppidev);
#endif /* PERIPH_1284 */
return;
@@ -259,19 +275,25 @@ static int
ppiopen(dev_t dev, int flags, int fmt, struct proc *p)
{
u_int unit = minor(dev);
- struct ppi_data *ppi = ppidata[unit];
+ struct ppi_data *ppi = UNITOSOFTC(unit);
+ device_t ppidev = UNITODEVICE(unit);
+ device_t ppbus = device_get_parent(ppidev);
int res;
- if (unit >= nppi)
+ if (!ppi)
return (ENXIO);
if (!(ppi->ppi_flags & HAVE_PPBUS)) {
- if ((res = ppb_request_bus(&ppi->ppi_dev,
+ if ((res = ppb_request_bus(ppbus, ppidev,
(flags & O_NONBLOCK) ? PPB_DONTWAIT :
(PPB_WAIT | PPB_INTR))))
return (res);
ppi->ppi_flags |= HAVE_PPBUS;
+
+ /* register our interrupt handler */
+ BUS_SETUP_INTR(device_get_parent(ppidev), ppidev, ppi->intr_resource,
+ INTR_TYPE_TTY, ppiintr, dev, &ppi->intr_cookie);
}
ppi->ppi_count += 1;
@@ -282,26 +304,30 @@ static int
ppiclose(dev_t dev, int flags, int fmt, struct proc *p)
{
u_int unit = minor(dev);
- struct ppi_data *ppi = ppidata[unit];
+ struct ppi_data *ppi = UNITOSOFTC(unit);
+ device_t ppidev = UNITODEVICE(unit);
+ device_t ppbus = device_get_parent(ppidev);
ppi->ppi_count --;
if (!ppi->ppi_count) {
#ifdef PERIPH_1284
- switch (ppi->ppi_dev.ppb->state) {
+ switch (ppb_1284_get_state(ppbus)) {
case PPB_PERIPHERAL_IDLE:
- ppb_peripheral_terminate(&ppi->ppi_dev, 0);
+ ppb_peripheral_terminate(ppbus, 0);
break;
case PPB_REVERSE_IDLE:
case PPB_EPP_IDLE:
case PPB_ECP_FORWARD_IDLE:
default:
- ppb_1284_terminate(&ppi->ppi_dev);
+ ppb_1284_terminate(ppbus);
break;
}
#endif /* PERIPH_1284 */
- ppb_release_bus(&ppi->ppi_dev);
+ /* unregistration of interrupt forced by release */
+ ppb_release_bus(ppbus, ppidev);
+
ppi->ppi_flags &= ~HAVE_PPBUS;
}
@@ -321,19 +347,21 @@ ppiread(dev_t dev, struct uio *uio, int ioflag)
{
#ifdef PERIPH_1284
u_int unit = minor(dev);
- struct ppi_data *ppi = ppidata[unit];
+ struct ppi_data *ppi = UNITOSOFTC(unit);
+ device_t ppidev = UNITODEVICE(unit);
+ device_t ppbus = device_get_parent(ppidev);
int len, error = 0;
- switch (ppi->ppi_dev.ppb->state) {
+ switch (ppb_1284_get_state(ppbus)) {
case PPB_PERIPHERAL_IDLE:
- ppb_peripheral_terminate(&ppi->ppi_dev, 0);
+ ppb_peripheral_terminate(ppbus, 0);
/* fall throught */
case PPB_FORWARD_IDLE:
/* if can't negociate NIBBLE mode then try BYTE mode,
* the peripheral may be a computer
*/
- if ((ppb_1284_negociate(&ppi->ppi_dev,
+ if ((ppb_1284_negociate(ppbus,
ppi->ppi_mode = PPB_NIBBLE, 0))) {
/* XXX Wait 2 seconds to let the remote host some
@@ -341,7 +369,7 @@ ppiread(dev_t dev, struct uio *uio, int ioflag)
*/
tsleep(ppi, PPBPRI, "ppiread", 2*hz);
- if ((error = ppb_1284_negociate(&ppi->ppi_dev,
+ if ((error = ppb_1284_negociate(ppbus,
ppi->ppi_mode = PPB_BYTE, 0)))
return (error);
}
@@ -360,7 +388,7 @@ ppiread(dev_t dev, struct uio *uio, int ioflag)
/* read data */
len = 0;
while (uio->uio_resid) {
- if ((error = ppb_1284_read(&ppi->ppi_dev, ppi->ppi_mode,
+ if ((error = ppb_1284_read(ppbus, ppi->ppi_mode,
ppi->ppi_buffer, min(BUFSIZE, uio->uio_resid),
&len))) {
goto error;
@@ -403,8 +431,9 @@ ppiwrite(dev_t dev, struct uio *uio, int ioflag)
{
#ifdef PERIPH_1284
u_int unit = minor(dev);
- struct ppi_data *ppi = ppidata[unit];
- struct ppb_data *ppb = ppi->ppi_dev.ppb;
+ struct ppi_data *ppi = UNITOSOFTC(unit);
+ device_t ppidev = UNITODEVICE(unit);
+ device_t ppbus = device_get_parent(ppidev);
int len, error = 0, sent;
#if 0
@@ -419,7 +448,7 @@ ppiwrite(dev_t dev, struct uio *uio, int ioflag)
};
/* negociate ECP mode */
- if (ppb_1284_negociate(&ppi->ppi_dev, PPB_ECP, 0)) {
+ if (ppb_1284_negociate(ppbus, PPB_ECP, 0)) {
printf("ppiwrite: ECP negociation failed\n");
}
@@ -428,7 +457,7 @@ ppiwrite(dev_t dev, struct uio *uio, int ioflag)
ppb_MS_init_msq(msq, 2, ADDRESS, ppi->ppi_buffer, LENGTH, len);
- error = ppb_MS_microseq(&ppi->ppi_dev, msq, &ret);
+ error = ppb_MS_microseq(ppbus, msq, &ret);
}
#endif
@@ -436,7 +465,7 @@ ppiwrite(dev_t dev, struct uio *uio, int ioflag)
* wait for the appropriate state
*/
if (ppb->state < PPB_PERIPHERAL_NEGOCIATION)
- ppb_1284_terminate(&ppi->ppi_dev);
+ ppb_1284_terminate(ppbus);
while (ppb->state != PPB_PERIPHERAL_IDLE) {
/* XXX should check a variable before sleeping */
@@ -444,7 +473,7 @@ ppiwrite(dev_t dev, struct uio *uio, int ioflag)
printf("s");
#endif
- ppi_enable_intr(ppi);
+ ppi_enable_intr(ppidev);
/* sleep until IEEE1284 negociation starts */
error = tsleep(ppi, PCATCH | PPBPRI, "ppiwrite", 0);
@@ -452,7 +481,7 @@ ppiwrite(dev_t dev, struct uio *uio, int ioflag)
switch (error) {
case 0:
/* negociate peripheral side with BYTE mode */
- ppb_peripheral_negociate(&ppi->ppi_dev, PPB_BYTE, 0);
+ ppb_peripheral_negociate(ppbus, PPB_BYTE, 0);
break;
case EWOULDBLOCK:
break;
@@ -467,7 +496,7 @@ ppiwrite(dev_t dev, struct uio *uio, int ioflag)
/* negociation done, write bytes to master host */
while ((len = min(uio->uio_resid, BUFSIZE)) != 0) {
uiomove(ppi->ppi_buffer, len, uio);
- if ((error = byte_peripheral_write(&ppi->ppi_dev,
+ if ((error = byte_peripheral_write(ppbus,
ppi->ppi_buffer, len, &sent)))
goto error;
#ifdef DEBUG_1284
@@ -488,55 +517,54 @@ static int
ppiioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p)
{
u_int unit = minor(dev);
- struct ppi_data *ppi = ppidata[unit];
+ device_t ppidev = UNITODEVICE(unit);
+ device_t ppbus = device_get_parent(ppidev);
int error = 0;
u_int8_t *val = (u_int8_t *)data;
switch (cmd) {
case PPIGDATA: /* get data register */
- *val = ppb_rdtr(&ppi->ppi_dev);
+ *val = ppb_rdtr(ppbus);
break;
case PPIGSTATUS: /* get status bits */
- *val = ppb_rstr(&ppi->ppi_dev);
+ *val = ppb_rstr(ppbus);
break;
case PPIGCTRL: /* get control bits */
- *val = ppb_rctr(&ppi->ppi_dev);
+ *val = ppb_rctr(ppbus);
break;
case PPIGEPPD: /* get EPP data bits */
- *val = ppb_repp_D(&ppi->ppi_dev);
+ *val = ppb_repp_D(ppbus);
break;
case PPIGECR: /* get ECP bits */
- *val = ppb_recr(&ppi->ppi_dev);
+ *val = ppb_recr(ppbus);
break;
case PPIGFIFO: /* read FIFO */
- *val = ppb_rfifo(&ppi->ppi_dev);
+ *val = ppb_rfifo(ppbus);
break;
-
case PPISDATA: /* set data register */
- ppb_wdtr(&ppi->ppi_dev, *val);
+ ppb_wdtr(ppbus, *val);
break;
case PPISSTATUS: /* set status bits */
- ppb_wstr(&ppi->ppi_dev, *val);
+ ppb_wstr(ppbus, *val);
break;
case PPISCTRL: /* set control bits */
- ppb_wctr(&ppi->ppi_dev, *val);
+ ppb_wctr(ppbus, *val);
break;
case PPISEPPD: /* set EPP data bits */
- ppb_wepp_D(&ppi->ppi_dev, *val);
+ ppb_wepp_D(ppbus, *val);
break;
case PPISECR: /* set ECP bits */
- ppb_wecr(&ppi->ppi_dev, *val);
+ ppb_wecr(ppbus, *val);
break;
case PPISFIFO: /* write FIFO */
- ppb_wfifo(&ppi->ppi_dev, *val);
+ ppb_wfifo(ppbus, *val);
break;
-
case PPIGEPPA: /* get EPP address bits */
- *val = ppb_repp_A(&ppi->ppi_dev);
+ *val = ppb_repp_A(ppbus);
break;
case PPISEPPA: /* set EPP address bits */
- ppb_wepp_A(&ppi->ppi_dev, *val);
+ ppb_wepp_A(ppbus, *val);
break;
default:
error = ENOTTY;
@@ -546,4 +574,6 @@ ppiioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p)
return (error);
}
+DRIVER_MODULE(ppi, ppbus, ppi_driver, ppi_devclass, 0, 0);
+
#endif /* NPPI */
diff --git a/sys/dev/ppbus/pps.c b/sys/dev/ppbus/pps.c
index 1189c58..9a540dc 100644
--- a/sys/dev/ppbus/pps.c
+++ b/sys/dev/ppbus/pps.c
@@ -18,11 +18,18 @@
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
+#include <sys/module.h>
+#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/timepps.h>
#include <sys/malloc.h>
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/rman.h>
#include <dev/ppbus/ppbconf.h>
+#include "ppbus_if.h"
+#include <dev/ppbus/ppbio.h>
#include "pps.h"
#define PPS_NAME "pps" /* our official name */
@@ -31,23 +38,37 @@ struct pps_data {
int pps_open;
struct ppb_device pps_dev;
struct pps_state pps;
+
+ struct resource *intr_resource; /* interrupt resource */
+ void *intr_cookie; /* interrupt registration cookie */
};
-static int npps;
+static int ppsprobe(device_t dev);
+static int ppsattach(device_t dev);
+static void ppsintr(void *arg);
-/*
- * Make ourselves visible as a ppbus driver
- */
+#define DEVTOSOFTC(dev) \
+ ((struct pps_data *)device_get_softc(dev))
+#define UNITOSOFTC(unit) \
+ ((struct pps_data *)devclass_get_softc(pps_devclass, (unit)))
+#define UNITODEVICE(unit) \
+ (devclass_get_device(pps_devclass, (unit)))
-static struct ppb_device *ppsprobe(struct ppb_data *ppb);
-static int ppsattach(struct ppb_device *dev);
-static void ppsintr(struct ppb_device *ppd);
+static devclass_t pps_devclass;
-static struct ppb_driver ppsdriver = {
- ppsprobe, ppsattach, PPS_NAME
+static device_method_t pps_methods[] = {
+ /* device interface */
+ DEVMETHOD(device_probe, ppsprobe),
+ DEVMETHOD(device_attach, ppsattach),
+
+ { 0, 0 }
};
-DATA_SET(ppbdriver_set, ppsdriver);
+static driver_t pps_driver = {
+ PPS_NAME,
+ pps_methods,
+ sizeof(struct pps_data),
+};
static d_open_t ppsopen;
static d_close_t ppsclose;
@@ -71,71 +92,76 @@ static struct cdevsw pps_cdevsw = {
/* bmaj */ -1
};
-
-static struct ppb_device *
-ppsprobe(struct ppb_data *ppb)
+static int
+ppsprobe(device_t ppsdev)
{
struct pps_data *sc;
static int once;
dev_t dev;
+ int unit;
if (!once++)
cdevsw_add(&pps_cdevsw);
- sc = (struct pps_data *) malloc(sizeof(struct pps_data),
- M_TEMP, M_NOWAIT);
- if (!sc) {
- printf(PPS_NAME ": cannot malloc!\n");
- return (0);
- }
+ sc = DEVTOSOFTC(ppsdev);
bzero(sc, sizeof(struct pps_data));
- dev = make_dev(&pps_cdevsw, npps,
- UID_ROOT, GID_WHEEL, 0644, PPS_NAME "%d", npps);
+ unit = device_get_unit(ppsdev);
+ dev = make_dev(&pps_cdevsw, unit,
+ UID_ROOT, GID_WHEEL, 0644, PPS_NAME "%d", unit);
- dev->si_drv1 = sc;
-
- sc->pps_dev.id_unit = npps++;
- sc->pps_dev.ppb = ppb;
- sc->pps_dev.name = ppsdriver.name;
- sc->pps_dev.bintr = ppsintr;
- sc->pps_dev.drv1 = sc;
+ device_set_desc(ppsdev, "Pulse per second Timing Interface");
sc->pps.ppscap = PPS_CAPTUREASSERT | PPS_ECHOASSERT;
pps_init(&sc->pps);
- return (&sc->pps_dev);
+ return (0);
}
static int
-ppsattach(struct ppb_device *dev)
+ppsattach(device_t dev)
{
+ struct pps_data *sc = DEVTOSOFTC(dev);
+ device_t ppbus = device_get_parent(dev);
+ int irq, zero = 0;
- /*
- * Report ourselves
- */
- printf(PPS_NAME "%d: <Pulse per second Timing Interface> on ppbus %d\n",
- dev->id_unit, dev->ppb->ppb_link->adapter_unit);
+ /* retrieve the ppbus irq */
+ BUS_READ_IVAR(ppbus, dev, PPBUS_IVAR_IRQ, &irq);
- return (1);
+ if (irq > 0) {
+ /* declare our interrupt handler */
+ sc->intr_resource = bus_alloc_resource(dev, SYS_RES_IRQ,
+ &zero, irq, irq, 1, RF_SHAREABLE);
+ }
+ /* interrupts seem mandatory */
+ if (sc->intr_resource == 0)
+ return (ENXIO);
+
+ return (0);
}
static int
ppsopen(dev_t dev, int flags, int fmt, struct proc *p)
{
- struct pps_data *sc;
u_int unit = minor(dev);
-
- if ((unit >= npps))
- return (ENXIO);
-
- sc = dev->si_drv1;
+ struct pps_data *sc = UNITOSOFTC(unit);
+ device_t ppsdev = UNITODEVICE(unit);
+ device_t ppbus = device_get_parent(ppsdev);
+ int error;
if (!sc->pps_open) {
- if (ppb_request_bus(&sc->pps_dev, PPB_WAIT|PPB_INTR))
+ if (ppb_request_bus(ppbus, ppsdev, PPB_WAIT|PPB_INTR))
return (EINTR);
- ppb_wctr(&sc->pps_dev, 0);
- ppb_wctr(&sc->pps_dev, IRQENABLE);
+ /* attach the interrupt handler */
+ if ((error = BUS_SETUP_INTR(ppbus, ppsdev, sc->intr_resource,
+ INTR_TYPE_TTY, ppsintr, ppsdev,
+ &sc->intr_cookie))) {
+ ppb_release_bus(ppbus, ppsdev);
+ return (error);
+ }
+
+ ppb_wctr(ppbus, 0);
+ ppb_wctr(ppbus, IRQENABLE);
sc->pps_open = 1;
}
@@ -145,41 +171,49 @@ ppsopen(dev_t dev, int flags, int fmt, struct proc *p)
static int
ppsclose(dev_t dev, int flags, int fmt, struct proc *p)
{
- struct pps_data *sc = dev->si_drv1;
+ u_int unit = minor(dev);
+ struct pps_data *sc = UNITOSOFTC(unit);
+ device_t ppsdev = UNITODEVICE(unit);
+ device_t ppbus = device_get_parent(ppsdev);
sc->pps.ppsparam.mode = 0; /* PHK ??? */
- ppb_wdtr(&sc->pps_dev, 0);
- ppb_wctr(&sc->pps_dev, 0);
+ ppb_wdtr(ppbus, 0);
+ ppb_wctr(ppbus, 0);
- ppb_release_bus(&sc->pps_dev);
+ /* Note: the interrupt handler is automatically detached */
+ ppb_release_bus(ppbus, ppsdev);
sc->pps_open = 0;
return(0);
}
static void
-ppsintr(struct ppb_device *ppd)
+ppsintr(void *arg)
{
- struct pps_data *sc = ppd->drv1;
+ device_t ppsdev = (device_t)arg;
+ device_t ppbus = device_get_parent(ppsdev);
+ struct pps_data *sc = DEVTOSOFTC(ppsdev);
struct timecounter *tc;
unsigned count;
tc = timecounter;
count = timecounter->tc_get_timecount(tc);
- if (!(ppb_rstr(&sc->pps_dev) & nACK))
+ if (!(ppb_rstr(ppbus) & nACK))
return;
if (sc->pps.ppsparam.mode & PPS_ECHOASSERT)
- ppb_wctr(&sc->pps_dev, IRQENABLE | AUTOFEED);
+ ppb_wctr(ppbus, IRQENABLE | AUTOFEED);
pps_event(&sc->pps, tc, count, PPS_CAPTUREASSERT);
if (sc->pps.ppsparam.mode & PPS_ECHOASSERT)
- ppb_wctr(&sc->pps_dev, IRQENABLE);
+ ppb_wctr(ppbus, IRQENABLE);
}
static int
ppsioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p)
{
- struct pps_data *sc = dev->si_drv1;
+ u_int unit = minor(dev);
+ struct pps_data *sc = UNITOSOFTC(unit);
return (pps_ioctl(cmd, data, &sc->pps));
}
+DRIVER_MODULE(pps, ppbus, pps_driver, pps_devclass, 0, 0);
diff --git a/sys/dev/ppbus/vpo.c b/sys/dev/ppbus/vpo.c
index 23e6058..51ccacf 100644
--- a/sys/dev/ppbus/vpo.c
+++ b/sys/dev/ppbus/vpo.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1997, 1998 Nicolas Souchu
+ * Copyright (c) 1997, 1998, 1999 Nicolas Souchu
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,8 +30,8 @@
#ifdef _KERNEL
#include <sys/param.h>
#include <sys/systm.h>
-#include <sys/malloc.h>
-#include <sys/buf.h>
+#include <sys/module.h>
+#include <sys/bus.h>
#include <machine/clock.h>
@@ -56,6 +56,8 @@
#include <dev/ppbus/ppbconf.h>
#include <dev/ppbus/vpoio.h>
+#include "ppbus_if.h"
+
struct vpo_sense {
struct scsi_sense cmd;
unsigned int stat;
@@ -79,96 +81,84 @@ struct vpo_data {
struct vpoio_data vpo_io; /* interface to low level functions */
};
-/* cam related functions */
-static void vpo_action(struct cam_sim *sim, union ccb *ccb);
-static void vpo_poll(struct cam_sim *sim);
+static int vpo_probe(device_t);
+static int vpo_attach(device_t);
-static int nvpo = 0;
-#define MAXVP0 8 /* XXX not much better! */
-static struct vpo_data *vpodata[MAXVP0];
+#define DEVTOSOFTC(dev) \
+ ((struct vpo_data *)device_get_softc(dev))
-#ifdef _KERNEL
+static devclass_t vpo_devclass;
-/*
- * Make ourselves visible as a ppbus driver
- */
-static struct ppb_device *vpoprobe(struct ppb_data *ppb);
-static int vpoattach(struct ppb_device *dev);
+static device_method_t vpo_methods[] = {
+ /* device interface */
+ DEVMETHOD(device_probe, vpo_probe),
+ DEVMETHOD(device_attach, vpo_attach),
-static struct ppb_driver vpodriver = {
- vpoprobe, vpoattach, "vpo"
+ { 0, 0 }
};
-DATA_SET(ppbdriver_set, vpodriver);
-#endif
+static driver_t vpo_driver = {
+ "vpo",
+ vpo_methods,
+ sizeof(struct vpo_data),
+};
+
+/* cam related functions */
+static void vpo_action(struct cam_sim *sim, union ccb *ccb);
+static void vpo_poll(struct cam_sim *sim);
/*
- * vpoprobe()
- *
- * Called by ppb_attachdevs().
+ * vpo_probe()
*/
-static struct ppb_device *
-vpoprobe(struct ppb_data *ppb)
+static int
+vpo_probe(device_t dev)
{
struct vpo_data *vpo;
- struct ppb_device *dev;
-
- if (nvpo >= MAXVP0) {
- printf("vpo: Too many devices (max %d)\n", MAXVP0);
- return(NULL);
- }
+ int error;
- vpo = (struct vpo_data *)malloc(sizeof(struct vpo_data),
- M_DEVBUF, M_NOWAIT);
- if (!vpo) {
- printf("vpo: cannot malloc!\n");
- return(NULL);
- }
+ vpo = DEVTOSOFTC(dev);
bzero(vpo, sizeof(struct vpo_data));
- vpodata[nvpo] = vpo;
-
/* vpo dependent initialisation */
- vpo->vpo_unit = nvpo;
-
- /* ok, go to next device on next probe */
- nvpo ++;
+ vpo->vpo_unit = device_get_unit(dev);
/* low level probe */
vpoio_set_unit(&vpo->vpo_io, vpo->vpo_unit);
/* check ZIP before ZIP+ or imm_probe() will send controls to
* the printer or whatelse connected to the port */
- if ((dev = vpoio_probe(ppb, &vpo->vpo_io))) {
+ if ((error = vpoio_probe(dev, &vpo->vpo_io)) == 0) {
vpo->vpo_isplus = 0;
- } else if ((dev = imm_probe(ppb, &vpo->vpo_io))) {
+ device_set_desc(dev,
+ "Iomega VPI0 Parallel to SCSI interface");
+ } else if ((error = imm_probe(dev, &vpo->vpo_io)) == 0) {
vpo->vpo_isplus = 1;
+ device_set_desc(dev,
+ "Iomega Matchmaker Parallel to SCSI interface");
} else {
- free(vpo, M_DEVBUF);
- return (NULL);
+ return (error);
}
- return (dev);
+ return (0);
}
/*
- * vpoattach()
- *
- * Called by ppb_attachdevs().
+ * vpo_attach()
*/
static int
-vpoattach(struct ppb_device *dev)
+vpo_attach(device_t dev)
{
- struct vpo_data *vpo = vpodata[dev->id_unit];
+ struct vpo_data *vpo = DEVTOSOFTC(dev);
struct cam_devq *devq;
+ int error;
/* low level attachment */
if (vpo->vpo_isplus) {
- if (!imm_attach(&vpo->vpo_io))
- return (0);
+ if ((error = imm_attach(&vpo->vpo_io)))
+ return (error);
} else {
- if (!vpoio_attach(&vpo->vpo_io))
- return (0);
+ if ((error = vpoio_attach(&vpo->vpo_io)))
+ return (error);
}
/*
@@ -178,18 +168,19 @@ vpoattach(struct ppb_device *dev)
devq = cam_simq_alloc(/*maxopenings*/1);
/* XXX What about low-level detach on error? */
if (devq == NULL)
- return (0);
+ return (ENXIO);
- vpo->sim = cam_sim_alloc(vpo_action, vpo_poll, "vpo", vpo, dev->id_unit,
+ vpo->sim = cam_sim_alloc(vpo_action, vpo_poll, "vpo", vpo,
+ device_get_unit(dev),
/*untagged*/1, /*tagged*/0, devq);
if (vpo->sim == NULL) {
cam_simq_free(devq);
- return (0);
+ return (ENXIO);
}
if (xpt_bus_register(vpo->sim, /*bus*/0) != CAM_SUCCESS) {
cam_sim_free(vpo->sim, /*free_devq*/TRUE);
- return (0);
+ return (ENXIO);
}
if (xpt_create_path(&vpo->path, /*periph*/NULL,
@@ -197,12 +188,12 @@ vpoattach(struct ppb_device *dev)
CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
xpt_bus_deregister(cam_sim_path(vpo->sim));
cam_sim_free(vpo->sim, /*free_devq*/TRUE);
- return (0);
+ return (ENXIO);
}
/* all went ok */
- return (1);
+ return (0);
}
/*
@@ -445,3 +436,5 @@ vpo_poll(struct cam_sim *sim)
/* The ZIP is actually always polled throw vpo_action() */
return;
}
+
+DRIVER_MODULE(vpo, ppbus, vpo_driver, vpo_devclass, 0, 0);
diff --git a/sys/dev/ppbus/vpoio.c b/sys/dev/ppbus/vpoio.c
index 73e4adb..e5fd445 100644
--- a/sys/dev/ppbus/vpoio.c
+++ b/sys/dev/ppbus/vpoio.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1998 Nicolas Souchu
+ * Copyright (c) 1998, 1999 Nicolas Souchu
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,6 +30,8 @@
#ifdef _KERNEL
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/module.h>
+#include <sys/bus.h>
#include <sys/malloc.h>
#include <sys/buf.h>
@@ -43,10 +45,13 @@
#include "opt_vpo.h"
+#include <dev/ppbus/ppbio.h>
#include <dev/ppbus/ppbconf.h>
#include <dev/ppbus/ppb_msq.h>
#include <dev/ppbus/vpoio.h>
+#include "ppbus_if.h"
+
/*
* The driver pools the drive. We may add a timeout queue to avoid
* active polling on nACK. I've tried this but it leads to unreliable
@@ -271,10 +276,11 @@ static struct ppb_microseq in_disk_mode[] = {
static int
vpoio_disconnect(struct vpoio_data *vpo)
{
+ device_t ppbus = device_get_parent(vpo->vpo_dev);
int ret;
- ppb_MS_microseq(&vpo->vpo_dev, disconnect_microseq, &ret);
- return (ppb_release_bus(&vpo->vpo_dev));
+ ppb_MS_microseq(ppbus, vpo->vpo_dev, disconnect_microseq, &ret);
+ return (ppb_release_bus(ppbus, vpo->vpo_dev));
}
/*
@@ -283,10 +289,11 @@ vpoio_disconnect(struct vpoio_data *vpo)
static int
vpoio_connect(struct vpoio_data *vpo, int how)
{
+ device_t ppbus = device_get_parent(vpo->vpo_dev);
int error;
int ret;
- if ((error = ppb_request_bus(&vpo->vpo_dev, how))) {
+ if ((error = ppb_request_bus(ppbus, vpo->vpo_dev, how))) {
#ifdef VP0_DEBUG
printf("%s: can't request bus!\n", __FUNCTION__);
@@ -294,10 +301,10 @@ vpoio_connect(struct vpoio_data *vpo, int how)
return error;
}
- if (PPB_IN_EPP_MODE(&vpo->vpo_dev))
- ppb_MS_microseq(&vpo->vpo_dev, connect_epp_microseq, &ret);
+ if (PPB_IN_EPP_MODE(ppbus))
+ ppb_MS_microseq(ppbus, vpo->vpo_dev, connect_epp_microseq, &ret);
else
- ppb_MS_microseq(&vpo->vpo_dev, connect_spp_microseq, &ret);
+ ppb_MS_microseq(ppbus, vpo->vpo_dev, connect_spp_microseq, &ret);
return (0);
}
@@ -310,6 +317,7 @@ vpoio_connect(struct vpoio_data *vpo, int how)
static void
vpoio_reset (struct vpoio_data *vpo)
{
+ device_t ppbus = device_get_parent(vpo->vpo_dev);
int ret;
struct ppb_microseq reset_microseq[] = {
@@ -324,7 +332,7 @@ vpoio_reset (struct vpoio_data *vpo)
};
ppb_MS_init_msq(reset_microseq, 1, INITIATOR, 1 << VP0_INITIATOR);
- ppb_MS_microseq(&vpo->vpo_dev, reset_microseq, &ret);
+ ppb_MS_microseq(ppbus, vpo->vpo_dev, reset_microseq, &ret);
return;
}
@@ -335,9 +343,10 @@ vpoio_reset (struct vpoio_data *vpo)
static int
vpoio_in_disk_mode(struct vpoio_data *vpo)
{
+ device_t ppbus = device_get_parent(vpo->vpo_dev);
int ret;
- ppb_MS_microseq(&vpo->vpo_dev, in_disk_mode, &ret);
+ ppb_MS_microseq(ppbus, vpo->vpo_dev, in_disk_mode, &ret);
return (ret);
}
@@ -350,37 +359,38 @@ vpoio_in_disk_mode(struct vpoio_data *vpo)
static int
vpoio_detect(struct vpoio_data *vpo)
{
+ device_t ppbus = device_get_parent(vpo->vpo_dev);
int error, ret;
/* allocate the bus, then apply microsequences */
- if ((error = ppb_request_bus(&vpo->vpo_dev, PPB_DONTWAIT)))
+ if ((error = ppb_request_bus(ppbus, vpo->vpo_dev, PPB_DONTWAIT)))
return (error);
- ppb_MS_microseq(&vpo->vpo_dev, disconnect_microseq, &ret);
+ ppb_MS_microseq(ppbus, vpo->vpo_dev, disconnect_microseq, &ret);
- if (PPB_IN_EPP_MODE(&vpo->vpo_dev))
- ppb_MS_microseq(&vpo->vpo_dev, connect_epp_microseq, &ret);
+ if (PPB_IN_EPP_MODE(ppbus))
+ ppb_MS_microseq(ppbus, vpo->vpo_dev, connect_epp_microseq, &ret);
else
- ppb_MS_microseq(&vpo->vpo_dev, connect_spp_microseq, &ret);
+ ppb_MS_microseq(ppbus, vpo->vpo_dev, connect_spp_microseq, &ret);
- ppb_MS_microseq(&vpo->vpo_dev, in_disk_mode, &ret);
+ ppb_MS_microseq(ppbus, vpo->vpo_dev, in_disk_mode, &ret);
if (!ret) {
/* try spp mode (maybe twice or because previous mode was PS2)
* NIBBLE mode will be restored on next transfers if detection
* succeed
*/
- ppb_set_mode(&vpo->vpo_dev, PPB_NIBBLE);
- ppb_MS_microseq(&vpo->vpo_dev, connect_spp_microseq, &ret);
+ ppb_set_mode(ppbus, PPB_NIBBLE);
+ ppb_MS_microseq(ppbus, vpo->vpo_dev, connect_spp_microseq, &ret);
- ppb_MS_microseq(&vpo->vpo_dev, in_disk_mode, &ret);
+ ppb_MS_microseq(ppbus, vpo->vpo_dev, in_disk_mode, &ret);
if (!ret) {
if (bootverbose)
printf("vpo%d: can't connect to the drive\n",
vpo->vpo_unit);
/* disconnect and release the bus */
- ppb_MS_microseq(&vpo->vpo_dev, disconnect_microseq,
+ ppb_MS_microseq(ppbus, vpo->vpo_dev, disconnect_microseq,
&ret);
goto error;
}
@@ -389,12 +399,12 @@ vpoio_detect(struct vpoio_data *vpo)
/* send SCSI reset signal */
vpoio_reset(vpo);
- ppb_MS_microseq(&vpo->vpo_dev, disconnect_microseq, &ret);
+ ppb_MS_microseq(ppbus, vpo->vpo_dev, disconnect_microseq, &ret);
/* ensure we are disconnected or daisy chained peripheral
* may cause serious problem to the disk */
- ppb_MS_microseq(&vpo->vpo_dev, in_disk_mode, &ret);
+ ppb_MS_microseq(ppbus, vpo->vpo_dev, in_disk_mode, &ret);
if (ret) {
if (bootverbose)
printf("vpo%d: can't disconnect from the drive\n",
@@ -402,11 +412,11 @@ vpoio_detect(struct vpoio_data *vpo)
goto error;
}
- ppb_release_bus(&vpo->vpo_dev);
+ ppb_release_bus(ppbus, vpo->vpo_dev);
return (0);
error:
- ppb_release_bus(&vpo->vpo_dev);
+ ppb_release_bus(ppbus, vpo->vpo_dev);
return (VP0_EINITFAILED);
}
@@ -416,37 +426,35 @@ error:
static int
vpoio_outstr(struct vpoio_data *vpo, char *buffer, int size)
{
-
+ device_t ppbus = device_get_parent(vpo->vpo_dev);
int error = 0;
- ppb_MS_exec(&vpo->vpo_dev, MS_OP_PUT, (union ppb_insarg)buffer,
+ ppb_MS_exec(ppbus, vpo->vpo_dev, MS_OP_PUT, (union ppb_insarg)buffer,
(union ppb_insarg)size, (union ppb_insarg)MS_UNKNOWN, &error);
#if 0
/* XXX EPP 1.9 not implemented with microsequences */
else {
- ppb_reset_epp_timeout(&vpo->vpo_dev);
- ppb_wctr(&vpo->vpo_dev,
- H_AUTO | H_SELIN | H_INIT | H_STROBE);
+ ppb_reset_epp_timeout(ppbus);
+ ppb_wctr(ppbus, H_AUTO | H_SELIN | H_INIT | H_STROBE);
if (((long) buffer | size) & 0x03)
- ppb_outsb_epp(&vpo->vpo_dev,
+ ppb_outsb_epp(ppbus,
buffer, size);
else
- ppb_outsl_epp(&vpo->vpo_dev,
+ ppb_outsl_epp(ppbus,
buffer, size/4);
- if ((ppb_rstr(&vpo->vpo_dev) & TIMEOUT)) {
+ if ((ppb_rstr(ppbus) & TIMEOUT)) {
error = VP0_EPPDATA_TIMEOUT;
goto error;
}
- ppb_wctr(&vpo->vpo_dev,
- H_AUTO | H_nSELIN | H_INIT | H_STROBE);
+ ppb_wctr(ppbus, H_AUTO | H_nSELIN | H_INIT | H_STROBE);
}
#endif
- ppb_ecp_sync(&vpo->vpo_dev);
+ ppb_ecp_sync(ppbus);
return (error);
}
@@ -457,36 +465,37 @@ vpoio_outstr(struct vpoio_data *vpo, char *buffer, int size)
static int
vpoio_instr(struct vpoio_data *vpo, char *buffer, int size)
{
+ device_t ppbus = device_get_parent(vpo->vpo_dev);
int error = 0;
- ppb_MS_exec(&vpo->vpo_dev, MS_OP_GET, (union ppb_insarg)buffer,
+ ppb_MS_exec(ppbus, vpo->vpo_dev, MS_OP_GET, (union ppb_insarg)buffer,
(union ppb_insarg)size, (union ppb_insarg)MS_UNKNOWN, &error);
#if 0
/* XXX EPP 1.9 not implemented with microsequences */
else {
- ppb_reset_epp_timeout(&vpo->vpo_dev);
- ppb_wctr(&vpo->vpo_dev, PCD |
+ ppb_reset_epp_timeout(ppbus);
+ ppb_wctr(ppbus, PCD |
H_AUTO | H_SELIN | H_INIT | H_STROBE);
if (((long) buffer | size) & 0x03)
- ppb_insb_epp(&vpo->vpo_dev,
+ ppb_insb_epp(ppbus,
buffer, size);
else
- ppb_insl_epp(&vpo->vpo_dev,
+ ppb_insl_epp(ppbus,
buffer, size/4);
- if ((ppb_rstr(&vpo->vpo_dev) & TIMEOUT)) {
+ if ((ppb_rstr(ppbus) & TIMEOUT)) {
error = VP0_EPPDATA_TIMEOUT;
goto error;
}
- ppb_wctr(&vpo->vpo_dev, PCD |
+ ppb_wctr(ppbus, PCD |
H_AUTO | H_nSELIN | H_INIT | H_STROBE);
}
#endif
- ppb_ecp_sync(&vpo->vpo_dev);
+ ppb_ecp_sync(ppbus);
return (error);
}
@@ -494,6 +503,7 @@ vpoio_instr(struct vpoio_data *vpo, char *buffer, int size)
static char
vpoio_select(struct vpoio_data *vpo, int initiator, int target)
{
+ device_t ppbus = device_get_parent(vpo->vpo_dev);
int ret;
struct ppb_microseq select_microseq[] = {
@@ -523,7 +533,7 @@ vpoio_select(struct vpoio_data *vpo, int initiator, int target)
SELECT_TARGET, 1 << target,
SELECT_INITIATOR, 1 << initiator);
- ppb_MS_microseq(&vpo->vpo_dev, select_microseq, &ret);
+ ppb_MS_microseq(ppbus, vpo->vpo_dev, select_microseq, &ret);
if (ret)
return (VP0_ESELECT_TIMEOUT);
@@ -541,20 +551,20 @@ vpoio_select(struct vpoio_data *vpo, int initiator, int target)
static char
vpoio_wait(struct vpoio_data *vpo, int tmo)
{
-
+ device_t ppbus = device_get_parent(vpo->vpo_dev);
register int k;
register char r;
#if 0 /* broken */
- if (ppb_poll_device(&vpo->vpo_dev, 150, nBUSY, nBUSY, PPB_INTR))
+ if (ppb_poll_device(ppbus, 150, nBUSY, nBUSY, PPB_INTR))
return (0);
- return (ppb_rstr(&vpo->vpo_dev) & 0xf0);
+ return (ppb_rstr(ppbus) & 0xf0);
#endif
/* XXX should be ported to microseq */
k = 0;
- while (!((r = ppb_rstr(&vpo->vpo_dev)) & nBUSY) && (k++ < tmo))
+ while (!((r = ppb_rstr(ppbus)) & nBUSY) && (k++ < tmo))
;
/*
@@ -576,14 +586,13 @@ vpoio_wait(struct vpoio_data *vpo, int tmo)
* Low level probe of vpo device
*
*/
-struct ppb_device *
-vpoio_probe(struct ppb_data *ppb, struct vpoio_data *vpo)
+int
+vpoio_probe(device_t dev, struct vpoio_data *vpo)
{
+ int error;
/* ppbus dependent initialisation */
- vpo->vpo_dev.id_unit = vpo->vpo_unit;
- vpo->vpo_dev.name = "vpo";
- vpo->vpo_dev.ppb = ppb;
+ vpo->vpo_dev = dev;
/*
* Initialize microsequence code
@@ -591,11 +600,11 @@ vpoio_probe(struct ppb_data *ppb, struct vpoio_data *vpo)
INIT_TRIG_MICROSEQ;
/* now, try to initialise the drive */
- if (vpoio_detect(vpo)) {
- return (NULL);
+ if ((error = vpoio_detect(vpo))) {
+ return (error);
}
- return (&vpo->vpo_dev);
+ return (0);
}
/*
@@ -607,19 +616,14 @@ vpoio_probe(struct ppb_data *ppb, struct vpoio_data *vpo)
int
vpoio_attach(struct vpoio_data *vpo)
{
+ device_t ppbus = device_get_parent(vpo->vpo_dev);
int epp;
- /*
- * Report ourselves
- */
- printf("vpo%d: <Iomega VPI0 Parallel to SCSI interface> on ppbus %d\n",
- vpo->vpo_dev.id_unit, vpo->vpo_dev.ppb->ppb_link->adapter_unit);
-
vpo->vpo_nibble_inbyte_msq = (struct ppb_microseq *)malloc(
sizeof(nibble_inbyte_submicroseq), M_DEVBUF, M_NOWAIT);
if (!vpo->vpo_nibble_inbyte_msq)
- return (0);
+ return (ENXIO);
bcopy((void *)nibble_inbyte_submicroseq,
(void *)vpo->vpo_nibble_inbyte_msq,
@@ -630,36 +634,36 @@ vpoio_attach(struct vpoio_data *vpo)
/*
* Initialize mode dependent in/out microsequences
*/
- ppb_request_bus(&vpo->vpo_dev, PPB_WAIT);
+ ppb_request_bus(ppbus, vpo->vpo_dev, PPB_WAIT);
/* enter NIBBLE mode to configure submsq */
- if (ppb_set_mode(&vpo->vpo_dev, PPB_NIBBLE) != -1) {
+ if (ppb_set_mode(ppbus, PPB_NIBBLE) != -1) {
- ppb_MS_GET_init(&vpo->vpo_dev, vpo->vpo_nibble_inbyte_msq);
+ ppb_MS_GET_init(ppbus, vpo->vpo_dev, vpo->vpo_nibble_inbyte_msq);
- ppb_MS_PUT_init(&vpo->vpo_dev, spp_outbyte_submicroseq);
+ ppb_MS_PUT_init(ppbus, vpo->vpo_dev, spp_outbyte_submicroseq);
}
/* enter PS2 mode to configure submsq */
- if (ppb_set_mode(&vpo->vpo_dev, PPB_PS2) != -1) {
+ if (ppb_set_mode(ppbus, PPB_PS2) != -1) {
- ppb_MS_GET_init(&vpo->vpo_dev, ps2_inbyte_submicroseq);
+ ppb_MS_GET_init(ppbus, vpo->vpo_dev, ps2_inbyte_submicroseq);
- ppb_MS_PUT_init(&vpo->vpo_dev, spp_outbyte_submicroseq);
+ ppb_MS_PUT_init(ppbus, vpo->vpo_dev, spp_outbyte_submicroseq);
}
- epp = ppb_get_epp_protocol(&vpo->vpo_dev);
+ epp = ppb_get_epp_protocol(ppbus);
/* enter EPP mode to configure submsq */
- if (ppb_set_mode(&vpo->vpo_dev, PPB_EPP) != -1) {
+ if (ppb_set_mode(ppbus, PPB_EPP) != -1) {
switch (epp) {
case EPP_1_9:
/* XXX EPP 1.9 support should be improved */
case EPP_1_7:
- ppb_MS_GET_init(&vpo->vpo_dev, epp17_instr_body);
+ ppb_MS_GET_init(ppbus, vpo->vpo_dev, epp17_instr_body);
- ppb_MS_PUT_init(&vpo->vpo_dev, epp17_outstr_body);
+ ppb_MS_PUT_init(ppbus, vpo->vpo_dev, epp17_outstr_body);
break;
default:
panic("%s: unknown EPP protocol (0x%x)", __FUNCTION__,
@@ -668,7 +672,7 @@ vpoio_attach(struct vpoio_data *vpo)
}
/* try to enter EPP or PS/2 mode, NIBBLE otherwise */
- if (ppb_set_mode(&vpo->vpo_dev, PPB_EPP) != -1) {
+ if (ppb_set_mode(ppbus, PPB_EPP) != -1) {
switch (epp) {
case EPP_1_9:
printf("vpo%d: EPP 1.9 mode\n", vpo->vpo_unit);
@@ -680,25 +684,25 @@ vpoio_attach(struct vpoio_data *vpo)
panic("%s: unknown EPP protocol (0x%x)", __FUNCTION__,
epp);
}
- } else if (ppb_set_mode(&vpo->vpo_dev, PPB_PS2) != -1)
+ } else if (ppb_set_mode(ppbus, PPB_PS2) != -1)
printf("vpo%d: PS2 mode\n", vpo->vpo_unit);
- else if (ppb_set_mode(&vpo->vpo_dev, PPB_NIBBLE) != -1)
+ else if (ppb_set_mode(ppbus, PPB_NIBBLE) != -1)
printf("vpo%d: NIBBLE mode\n", vpo->vpo_unit);
else {
printf("vpo%d: can't enter NIBBLE, PS2 or EPP mode\n",
vpo->vpo_unit);
- ppb_release_bus(&vpo->vpo_dev);
+ ppb_release_bus(ppbus, vpo->vpo_dev);
free(vpo->vpo_nibble_inbyte_msq, M_DEVBUF);
- return (0);
+ return (ENXIO);
}
- ppb_release_bus(&vpo->vpo_dev);
+ ppb_release_bus(ppbus, vpo->vpo_dev);
- return (1);
+ return (0);
}
/*
@@ -739,7 +743,7 @@ vpoio_do_scsi(struct vpoio_data *vpo, int host, int target, char *command,
int clen, char *buffer, int blen, int *result, int *count,
int *ret)
{
-
+ device_t ppbus = device_get_parent(vpo->vpo_dev);
register char r;
char l, h = 0;
int len, error = 0;
@@ -768,7 +772,7 @@ vpoio_do_scsi(struct vpoio_data *vpo, int host, int target, char *command,
*
* set H_SELIN low for vpoio_wait().
*/
- ppb_wctr(&vpo->vpo_dev, H_AUTO | H_nSELIN | H_INIT | H_STROBE);
+ ppb_wctr(ppbus, H_AUTO | H_nSELIN | H_INIT | H_STROBE);
for (k = 0; k < clen; k++) {
if (vpoio_wait(vpo, VP0_FAST_SPINTMO) != (char)0xe0) {
@@ -804,7 +808,7 @@ vpoio_do_scsi(struct vpoio_data *vpo, int host, int target, char *command,
/* if in EPP mode or writing bytes, try to transfer a sector
* otherwise, just send one byte
*/
- if (PPB_IN_EPP_MODE(&vpo->vpo_dev) || r == (char)0xc0)
+ if (PPB_IN_EPP_MODE(ppbus) || r == (char)0xc0)
len = (((blen - *count) >= VP0_SECTOR_SIZE)) ?
VP0_SECTOR_SIZE : 1;
else
diff --git a/sys/dev/ppbus/vpoio.h b/sys/dev/ppbus/vpoio.h
index e007d3e..211ca00 100644
--- a/sys/dev/ppbus/vpoio.h
+++ b/sys/dev/ppbus/vpoio.h
@@ -67,12 +67,12 @@ struct vpoio_data {
/* each device must have its own nibble inbyte microsequence */
struct ppb_microseq *vpo_nibble_inbyte_msq;
- struct ppb_device vpo_dev;
+ device_t vpo_dev;
};
#define vpoio_set_unit(vpo,unit) ((vpo)->vpo_unit = unit)
-struct ppb_device *vpoio_probe(struct ppb_data *ppb, struct vpoio_data *vpo);
+int vpoio_probe(device_t dev, struct vpoio_data *vpo);
int vpoio_attach(struct vpoio_data *vpo);
int vpoio_reset_bus(struct vpoio_data *vpo);
@@ -81,7 +81,7 @@ int vpoio_do_scsi(struct vpoio_data *vpo, int host, int target, char *command,
int clen, char *buffer, int blen, int *result, int *count,
int *ret);
-struct ppb_device *imm_probe(struct ppb_data *ppb, struct vpoio_data *vpo);
+int imm_probe(device_t dev, struct vpoio_data *vpo);
int imm_attach(struct vpoio_data *vpo);
int imm_reset_bus(struct vpoio_data *vpo);
OpenPOWER on IntegriCloud