ppi.c revision 28257
1143211Sdas/*-
2226245Sdas * Copyright (c) 1997 Nicolas Souchu
3143211Sdas * All rights reserved.
4143211Sdas *
5143211Sdas * Redistribution and use in source and binary forms, with or without
6143211Sdas * modification, are permitted provided that the following conditions
7143211Sdas * are met:
8143211Sdas * 1. Redistributions of source code must retain the above copyright
9143211Sdas *    notice, this list of conditions and the following disclaimer.
10143211Sdas * 2. Redistributions in binary form must reproduce the above copyright
11143211Sdas *    notice, this list of conditions and the following disclaimer in the
12143211Sdas *    documentation and/or other materials provided with the distribution.
13143211Sdas *
14143211Sdas * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15143211Sdas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16143211Sdas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17143211Sdas * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18143211Sdas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19143211Sdas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20143211Sdas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21143211Sdas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22143211Sdas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23143211Sdas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24143211Sdas * SUCH DAMAGE.
25143211Sdas *
26143211Sdas *	$Id: ppi.c,v 1.1 1997/08/14 13:57:43 msmith Exp $
27143211Sdas *
28143211Sdas */
29143211Sdas#include "ppi.h"
30143211Sdas
31143211Sdas#if NPPI > 0
32143211Sdas
33143211Sdas#include <sys/types.h>
34226371Sdas
35226371Sdas#ifdef KERNEL
36143211Sdas#include <sys/param.h>
37226245Sdas#include <sys/systm.h>
38226245Sdas#include <sys/conf.h>
39226245Sdas#include <sys/proc.h>
40226245Sdas#include <sys/buf.h>
41226245Sdas#include <sys/kernel.h>
42226245Sdas#include <sys/uio.h>
43226245Sdas#include <sys/syslog.h>
44226245Sdas#include <sys/malloc.h>
45226245Sdas
46226245Sdas#include <machine/stdarg.h>
47226245Sdas#include <machine/clock.h>
48226245Sdas
49226245Sdas#include <i386/isa/isa.h>
50226245Sdas#include <i386/isa/isa_device.h>
51226245Sdas
52226245Sdas#include <sys/kernel.h>
53226245Sdas#endif /*KERNEL */
54226245Sdas
55226245Sdas#include <dev/ppbus/ppbconf.h>
56226245Sdas
57226245Sdasstruct ppi_data {
58226245Sdas
59226245Sdas	int ppi_unit;
60226245Sdas
61226245Sdas	struct ppb_device ppi_dev;
62226245Sdas};
63226245Sdas
64226371Sdas#define MAXPPI	8			/* XXX not much better! */
65226371Sdasstatic int 	nppi = 0;
66226371Sdasstatic struct ppi_data *ppidata[MAXPPI];
67226371Sdas
68226371Sdas/*
69226371Sdas * Make ourselves visible as a ppbus driver
70226371Sdas */
71226371Sdas
72226371Sdasstatic struct ppb_device	*ppiprobe(struct ppb_data *ppb);
73226371Sdasstatic int			ppiattach(struct ppb_device *dev);
74226371Sdasstatic void			ppiintr(int unit);
75226371Sdas
76226371Sdasstatic struct ppb_driver ppidriver = {
77226371Sdas    ppiprobe, ppiattach, "ppi"
78226371Sdas};
79226371SdasDATA_SET(ppbdriver_set, ppidriver);
80226371Sdas
81226371Sdas
82226371Sdasstatic	d_open_t	ppiopen;
83226371Sdasstatic	d_close_t	ppiclose;
84226371Sdasstatic	d_ioctl_t	ppiioctl;
85226371Sdas
86226371Sdas#define CDEV_MAJOR 14			/* XXX */
87226371Sdasstatic struct cdevsw ppi_cdevsw =
88226371Sdas	{ ppiopen,	ppiclose,	noread,		nowrite,	/* 14 */
89226371Sdas	  ppiioctl,	nullstop,	nullreset,	nodevtotty,
90226371Sdas	  seltrue,	nommap,		nostrat,	"ppi",	NULL,	-1 };
91226371Sdas
92226371Sdas/*
93226371Sdas * ppiprobe()
94226371Sdas */
95226371Sdasstatic struct ppb_device *
96226371Sdasppiprobe(struct ppb_data *ppb)
97226371Sdas{
98226371Sdas	struct ppi_data *ppi;
99226371Sdas
100226371Sdas	ppi = (struct ppi_data *) malloc(sizeof(struct ppi_data),
101226371Sdas							M_TEMP, M_NOWAIT);
102226371Sdas	if (!ppi) {
103226371Sdas		printf("ppi: cannot malloc!\n");
104226371Sdas		return 0;
105226371Sdas	}
106226371Sdas	bzero(ppi, sizeof(struct ppi_data));
107226371Sdas
108226371Sdas	ppidata[nppi] = ppi;
109226371Sdas
110226371Sdas	/*
111226371Sdas	 * ppi dependent initialisation.
112226371Sdas	 */
113226371Sdas	ppi->ppi_unit = nppi;
114226371Sdas
115226371Sdas	/*
116252170Seadler	 * ppbus dependent initialisation.
117226371Sdas	 */
118226371Sdas	ppi->ppi_dev.id_unit = ppi->ppi_unit;
119226371Sdas	ppi->ppi_dev.ppb = ppb;
120226371Sdas	ppi->ppi_dev.intr = ppiintr;
121226371Sdas
122226371Sdas	/* Ok, go to next device on next probe */
123226245Sdas	nppi ++;
124226245Sdas
125226245Sdas	return &ppi->ppi_dev;
126226245Sdas}
127226245Sdas
128226245Sdasstatic int
129226245Sdasppiattach(struct ppb_device *dev)
130226245Sdas{
131226245Sdas	struct ppi_data *ppi = ppidata[dev->id_unit];
132226245Sdas
133226245Sdas	/*
134226245Sdas	 * Report ourselves
135226245Sdas	 */
136226245Sdas	printf("ppi%d: <generic parallel i/o> on ppbus %d\n",
137226245Sdas	       dev->id_unit, dev->ppb->ppb_link->adapter_unit);
138226245Sdas
139226245Sdas	return (1);
140226245Sdas}
141226245Sdas
142226245Sdasstatic void
143226245Sdasppiintr(int unit)
144226245Sdas{
145226245Sdas	return;
146226245Sdas}
147226245Sdas
148226245Sdasstatic int
149226245Sdasppiopen(dev_t dev, int flags, int fmt, struct proc *p)
150226245Sdas{
151226245Sdas	u_int unit = minor(dev);
152226245Sdas
153226245Sdas	if (unit >= nppi)
154226245Sdas		return (ENXIO);
155226245Sdas
156226245Sdas	printf("ppi open!\n");
157143211Sdas
158143211Sdas	return (EOPNOTSUPP);
159143211Sdas}
160143211Sdas
161143211Sdasstatic int
162143211Sdasppiclose(dev_t dev, int flags, int fmt, struct proc *p)
163143211Sdas{
164143211Sdas	return (EOPNOTSUPP);
165143211Sdas}
166143211Sdas
167143211Sdasstatic int
168226371Sdasppiioctl(dev_t dev, int cmd, caddr_t data, int flags, struct proc *p)
169226371Sdas{
170143211Sdas	return (EOPNOTSUPP);
171143211Sdas}
172143211Sdas
173143211Sdas#ifdef PPI_MODULE
174177875Sdas
175177875Sdas#include <sys/exec.h>
176177875Sdas#include <sys/sysent.h>
177177875Sdas#include <sys/lkm.h>
178177875Sdas
179177875SdasMOD_DEV(ppi, LM_DT_CHAR, CDEV_MAJOR, &ppi_cdevsw);
180177875Sdas
181143211Sdasstatic int
182143211Sdasppi_load(struct lkm_table *lkmtp, int cmd)
183177875Sdas{
184143211Sdas	struct ppb_data *ppb;
185177875Sdas	struct ppb_device *dev;
186177875Sdas	int i;
187143211Sdas
188143211Sdas	for (ppb = ppb_next_bus(NULL); ppb; ppb = ppb_next_bus(ppb)) {
189143211Sdas
190143211Sdas		dev = ppiprobe(ppb);
191143211Sdas		ppiattach(dev);
192143211Sdas
193143211Sdas		ppb_attach_device(dev);
194143211Sdas	}
195143211Sdas
196143211Sdas	return (0);
197143211Sdas}
198143211Sdas
199143211Sdasstatic int
200143211Sdasppi_unload(struct lkm_table *lkmtp, int cmd)
201143211Sdas{
202143211Sdas	int i;
203143211Sdas
204143211Sdas	for (i = nppi-1; i > 0; i--) {
205143211Sdas		ppb_remove_device(&ppidata[i]->ppi_dev);
206143211Sdas		free(ppidata[i], M_TEMP);
207143211Sdas	}
208143211Sdas
209143211Sdas	return (0);
210143211Sdas}
211143211Sdas
212143211Sdasint
213143211Sdasppi_mod(struct lkm_table *lkmtp, int cmd, int ver)
214143211Sdas{
215143211Sdas	DISPATCH(lkmtp, cmd, ver, ppi_load, ppi_unload, lkm_nullcmd);
216143211Sdas}
217143211Sdas
218143211Sdas#endif /* PPI_MODULE */
219143211Sdas
220143211Sdasstatic ppi_devsw_installed = 0;
221143211Sdas
222143211Sdasstatic void ppi_drvinit(void *unused)
223226371Sdas{
224226371Sdas	dev_t dev;
225226371Sdas
226226371Sdas	if (!ppi_devsw_installed ) {
227143211Sdas		dev = makedev(CDEV_MAJOR, 0);
228143211Sdas		cdevsw_add(&dev, &ppi_cdevsw, NULL);
229251024Sdas		ppi_devsw_installed = 1;
230251024Sdas    	}
231143211Sdas}
232226371Sdas
233226371SdasSYSINIT(ppidev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,ppi_drvinit,NULL)
234226371Sdas
235226371Sdas#endif /* NPPI */
236226371Sdas