FreeBSD/Linux Kernel Cross Reference
sys/dev/ppbus/ppi.c
1 /*-
2 * Copyright (c) 1997, 1998 Nicolas Souchu, Michael Smith
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD$
27 *
28 */
29 #include "ppi.h"
30
31 #if NPPI > 0
32
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/conf.h>
36 #include <sys/kernel.h>
37 #include <sys/uio.h>
38 #include <sys/malloc.h>
39 #include <sys/fcntl.h>
40
41 #include <machine/clock.h>
42
43 #include <dev/ppbus/ppbconf.h>
44 #include <dev/ppbus/ppb_msq.h>
45
46 #include "opt_ppb_1284.h"
47
48 #ifdef PERIPH_1284
49 #include <dev/ppbus/ppb_1284.h>
50 #endif
51
52 #include <dev/ppbus/ppi.h>
53
54 #define BUFSIZE 512
55
56 struct ppi_data {
57
58 int ppi_unit;
59 int ppi_flags;
60 #define HAVE_PPBUS (1<<0)
61 #define HAD_PPBUS (1<<1)
62
63 int ppi_count;
64 int ppi_mode; /* IEEE1284 mode */
65 char ppi_buffer[BUFSIZE];
66
67 struct ppb_device ppi_dev;
68 };
69
70 #define MAXPPI 8 /* XXX not much better! */
71 static int nppi = 0;
72 static struct ppi_data *ppidata[MAXPPI];
73
74 /*
75 * Make ourselves visible as a ppbus driver
76 */
77
78 static struct ppb_device *ppiprobe(struct ppb_data *ppb);
79 static int ppiattach(struct ppb_device *dev);
80 static void ppiintr(int unit);
81
82 static struct ppb_driver ppidriver = {
83 ppiprobe, ppiattach, "ppi"
84 };
85 DATA_SET(ppbdriver_set, ppidriver);
86
87 static d_open_t ppiopen;
88 static d_close_t ppiclose;
89 static d_ioctl_t ppiioctl;
90 static d_write_t ppiwrite;
91 static d_read_t ppiread;
92
93 #define CDEV_MAJOR 82
94 static struct cdevsw ppi_cdevsw =
95 { ppiopen, ppiclose, ppiread, ppiwrite, /* 82 */
96 ppiioctl, nullstop, nullreset, nodevtotty,
97 seltrue, nommap, nostrat, "ppi", NULL, -1 };
98
99 #ifdef PERIPH_1284
100
101 static void
102 ppi_enable_intr(struct ppi_data *ppi)
103 {
104 char r;
105
106 r = ppb_rctr(&ppi->ppi_dev);
107 ppb_wctr(&ppi->ppi_dev, r | IRQENABLE);
108
109 return;
110 }
111
112 static void
113 ppi_disable_intr(struct ppi_data *ppi)
114 {
115 char r;
116
117 r = ppb_rctr(&ppi->ppi_dev);
118 ppb_wctr(&ppi->ppi_dev, r & ~IRQENABLE);
119
120 return;
121 }
122
123 #endif /* PERIPH_1284 */
124
125 /*
126 * ppiprobe()
127 */
128 static struct ppb_device *
129 ppiprobe(struct ppb_data *ppb)
130 {
131 struct ppi_data *ppi;
132
133 ppi = (struct ppi_data *) malloc(sizeof(struct ppi_data),
134 M_TEMP, M_NOWAIT);
135 if (!ppi) {
136 printf("ppi: cannot malloc!\n");
137 return 0;
138 }
139 bzero(ppi, sizeof(struct ppi_data));
140
141 ppidata[nppi] = ppi;
142
143 /*
144 * ppi dependent initialisation.
145 */
146 ppi->ppi_unit = nppi;
147
148 /*
149 * ppbus dependent initialisation.
150 */
151 ppi->ppi_dev.id_unit = ppi->ppi_unit;
152 ppi->ppi_dev.ppb = ppb;
153 ppi->ppi_dev.intr = ppiintr;
154
155 /* Ok, go to next device on next probe */
156 nppi ++;
157
158 return &ppi->ppi_dev;
159 }
160
161 static int
162 ppiattach(struct ppb_device *dev)
163 {
164 /*
165 * Report ourselves
166 */
167 printf("ppi%d: <generic parallel i/o> on ppbus %d\n",
168 dev->id_unit, dev->ppb->ppb_link->adapter_unit);
169
170 return (1);
171 }
172
173 /*
174 * Cable
175 * -----
176 *
177 * Use an IEEE1284 compliant (DB25/DB25) cable with the following tricks:
178 *
179 * nStrobe <-> nAck 1 <-> 10
180 * nAutofd <-> Busy 11 <-> 14
181 * nSelectin <-> Select 17 <-> 13
182 * nInit <-> nFault 15 <-> 16
183 *
184 */
185 static void
186 ppiintr(int unit)
187 {
188 #ifdef PERIPH_1284
189 struct ppi_data *ppi = ppidata[unit];
190
191 ppi_disable_intr(ppi);
192
193 switch (ppi->ppi_dev.ppb->state) {
194
195 /* accept IEEE1284 negociation then wakeup an waiting process to
196 * continue negociation at process level */
197 case PPB_FORWARD_IDLE:
198 /* Event 1 */
199 if ((ppb_rstr(&ppi->ppi_dev) & (SELECT | nBUSY)) ==
200 (SELECT | nBUSY)) {
201 /* IEEE1284 negociation */
202 #ifdef DEBUG_1284
203 printf("N");
204 #endif
205
206 /* Event 2 - prepare for reading the ext. value */
207 ppb_wctr(&ppi->ppi_dev, (PCD | STROBE | nINIT) & ~SELECTIN);
208
209 ppi->ppi_dev.ppb->state = PPB_NEGOCIATION;
210
211 } else {
212 #ifdef DEBUG_1284
213 printf("0x%x", ppb_rstr(&ppi->ppi_dev));
214 #endif
215 ppb_peripheral_terminate(&ppi->ppi_dev, PPB_DONTWAIT);
216 break;
217 }
218
219 /* wake up any process waiting for negociation from
220 * remote master host */
221
222 /* XXX should set a variable to warn the process about
223 * the interrupt */
224
225 wakeup(ppi);
226 break;
227 default:
228 #ifdef DEBUG_1284
229 printf("?%d", ppi->ppi_dev.ppb->state);
230 #endif
231 ppi->ppi_dev.ppb->state = PPB_FORWARD_IDLE;
232 ppb_set_mode(&ppi->ppi_dev, PPB_COMPATIBLE);
233 break;
234 }
235
236 ppi_enable_intr(ppi);
237 #endif /* PERIPH_1284 */
238
239 return;
240 }
241
242 static int
243 ppiopen(dev_t dev, int flags, int fmt, struct proc *p)
244 {
245 u_int unit = minor(dev);
246 struct ppi_data *ppi = ppidata[unit];
247 int res;
248
249 if (unit >= nppi)
250 return (ENXIO);
251
252 if (!(ppi->ppi_flags & HAVE_PPBUS)) {
253 if ((res = ppb_request_bus(&ppi->ppi_dev,
254 (flags & O_NONBLOCK) ? PPB_DONTWAIT :
255 (PPB_WAIT | PPB_INTR))))
256 return (res);
257
258 ppi->ppi_flags |= HAVE_PPBUS;
259 }
260 ppi->ppi_count += 1;
261
262 return (0);
263 }
264
265 static int
266 ppiclose(dev_t dev, int flags, int fmt, struct proc *p)
267 {
268 u_int unit = minor(dev);
269 struct ppi_data *ppi = ppidata[unit];
270
271 ppi->ppi_count --;
272 if (!ppi->ppi_count) {
273
274 #ifdef PERIPH_1284
275 switch (ppi->ppi_dev.ppb->state) {
276 case PPB_PERIPHERAL_IDLE:
277 ppb_peripheral_terminate(&ppi->ppi_dev, 0);
278 break;
279 case PPB_REVERSE_IDLE:
280 case PPB_EPP_IDLE:
281 case PPB_ECP_FORWARD_IDLE:
282 default:
283 ppb_1284_terminate(&ppi->ppi_dev);
284 break;
285 }
286 #endif /* PERIPH_1284 */
287
288 ppb_release_bus(&ppi->ppi_dev);
289 ppi->ppi_flags &= ~HAVE_PPBUS;
290 }
291
292 return (0);
293 }
294
295 /*
296 * ppiread()
297 *
298 * IEEE1284 compliant read.
299 *
300 * First, try negociation to BYTE then NIBBLE mode
301 * If no data is available, wait for it otherwise transfer as much as possible
302 */
303 static int
304 ppiread(dev_t dev, struct uio *uio, int ioflag)
305 {
306 #ifdef PERIPH_1284
307 u_int unit = minor(dev);
308 struct ppi_data *ppi = ppidata[unit];
309 int len, error = 0;
310
311 switch (ppi->ppi_dev.ppb->state) {
312 case PPB_PERIPHERAL_IDLE:
313 ppb_peripheral_terminate(&ppi->ppi_dev, 0);
314 /* fall throught */
315
316 case PPB_FORWARD_IDLE:
317 /* if can't negociate NIBBLE mode then try BYTE mode,
318 * the peripheral may be a computer
319 */
320 if ((ppb_1284_negociate(&ppi->ppi_dev,
321 ppi->ppi_mode = PPB_NIBBLE, 0))) {
322
323 /* XXX Wait 2 seconds to let the remote host some
324 * time to terminate its interrupt
325 */
326 tsleep(ppi, PPBPRI, "ppiread", 2*hz);
327
328 if ((error = ppb_1284_negociate(&ppi->ppi_dev,
329 ppi->ppi_mode = PPB_BYTE, 0)))
330 return (error);
331 }
332 break;
333
334 case PPB_REVERSE_IDLE:
335 case PPB_EPP_IDLE:
336 case PPB_ECP_FORWARD_IDLE:
337 default:
338 break;
339 }
340
341 #ifdef DEBUG_1284
342 printf("N");
343 #endif
344 /* read data */
345 len = 0;
346 while (uio->uio_resid) {
347 if ((error = ppb_1284_read(&ppi->ppi_dev, ppi->ppi_mode,
348 ppi->ppi_buffer, min(BUFSIZE, uio->uio_resid),
349 &len))) {
350 goto error;
351 }
352
353 if (!len)
354 goto error; /* no more data */
355
356 #ifdef DEBUG_1284
357 printf("d");
358 #endif
359 if ((error = uiomove(ppi->ppi_buffer, len, uio)))
360 goto error;
361 }
362
363 error:
364
365 #else /* PERIPH_1284 */
366 int error = ENODEV;
367 #endif
368
369 return (error);
370 }
371
372 /*
373 * ppiwrite()
374 *
375 * IEEE1284 compliant write
376 *
377 * Actually, this is the peripheral side of a remote IEEE1284 read
378 *
379 * The first part of the negociation (IEEE1284 device detection) is
380 * done at interrupt level, then the remaining is done by the writing
381 * process
382 *
383 * Once negociation done, transfer data
384 */
385 static int
386 ppiwrite(dev_t dev, struct uio *uio, int ioflag)
387 {
388 #ifdef PERIPH_1284
389 u_int unit = minor(dev);
390 struct ppi_data *ppi = ppidata[unit];
391 struct ppb_data *ppb = ppi->ppi_dev.ppb;
392 int len, error = 0, sent;
393
394 #if 0
395 int ret;
396
397 #define ADDRESS MS_PARAM(0, 0, MS_TYP_PTR)
398 #define LENGTH MS_PARAM(0, 1, MS_TYP_INT)
399
400 struct ppb_microseq msq[] = {
401 { MS_OP_PUT, { MS_UNKNOWN, MS_UNKNOWN, MS_UNKNOWN } },
402 MS_RET(0)
403 };
404
405 /* negociate ECP mode */
406 if (ppb_1284_negociate(&ppi->ppi_dev, PPB_ECP, 0)) {
407 printf("ppiwrite: ECP negociation failed\n");
408 }
409
410 while (!error && (len = min(uio->uio_resid, BUFSIZE))) {
411 uiomove(ppi->ppi_buffer, len, uio);
412
413 ppb_MS_init_msq(msq, 2, ADDRESS, ppi->ppi_buffer, LENGTH, len);
414
415 error = ppb_MS_microseq(&ppi->ppi_dev, msq, &ret);
416 }
417 #endif
418
419 /* we have to be peripheral to be able to send data, so
420 * wait for the appropriate state
421 */
422 if (ppb->state < PPB_PERIPHERAL_NEGOCIATION)
423 ppb_1284_terminate(&ppi->ppi_dev);
424
425 while (ppb->state != PPB_PERIPHERAL_IDLE) {
426 /* XXX should check a variable before sleeping */
427 #ifdef DEBUG_1284
428 printf("s");
429 #endif
430
431 ppi_enable_intr(ppi);
432
433 /* sleep until IEEE1284 negociation starts */
434 error = tsleep(ppi, PCATCH | PPBPRI, "ppiwrite", 0);
435
436 switch (error) {
437 case 0:
438 /* negociate peripheral side with BYTE mode */
439 ppb_peripheral_negociate(&ppi->ppi_dev, PPB_BYTE, 0);
440 break;
441 case EWOULDBLOCK:
442 break;
443 default:
444 goto error;
445 }
446 }
447 #ifdef DEBUG_1284
448 printf("N");
449 #endif
450
451 /* negociation done, write bytes to master host */
452 while (len = min(uio->uio_resid, BUFSIZE)) {
453 uiomove(ppi->ppi_buffer, len, uio);
454 if ((error = byte_peripheral_write(&ppi->ppi_dev,
455 ppi->ppi_buffer, len, &sent)))
456 goto error;
457 #ifdef DEBUG_1284
458 printf("d");
459 #endif
460 }
461
462 error:
463
464 #else /* PERIPH_1284 */
465 int error = ENODEV;
466 #endif
467
468 return (error);
469 }
470
471 static int
472 ppiioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p)
473 {
474 u_int unit = minor(dev);
475 struct ppi_data *ppi = ppidata[unit];
476 int error = 0;
477 u_int8_t *val = (u_int8_t *)data;
478
479 switch (cmd) {
480
481 case PPIGDATA: /* get data register */
482 *val = ppb_rdtr(&ppi->ppi_dev);
483 break;
484 case PPIGSTATUS: /* get status bits */
485 *val = ppb_rstr(&ppi->ppi_dev);
486 break;
487 case PPIGCTRL: /* get control bits */
488 *val = ppb_rctr(&ppi->ppi_dev);
489 break;
490 case PPIGEPP: /* get EPP bits */
491 *val = ppb_repp(&ppi->ppi_dev);
492 break;
493 case PPIGECR: /* get ECP bits */
494 *val = ppb_recr(&ppi->ppi_dev);
495 break;
496 case PPIGFIFO: /* read FIFO */
497 *val = ppb_rfifo(&ppi->ppi_dev);
498 break;
499
500 case PPISDATA: /* set data register */
501 ppb_wdtr(&ppi->ppi_dev, *val);
502 break;
503 case PPISSTATUS: /* set status bits */
504 ppb_wstr(&ppi->ppi_dev, *val);
505 break;
506 case PPISCTRL: /* set control bits */
507 ppb_wctr(&ppi->ppi_dev, *val);
508 break;
509 case PPISEPP: /* set EPP bits */
510 ppb_wepp(&ppi->ppi_dev, *val);
511 break;
512 case PPISECR: /* set ECP bits */
513 ppb_wecr(&ppi->ppi_dev, *val);
514 break;
515 case PPISFIFO: /* write FIFO */
516 ppb_wfifo(&ppi->ppi_dev, *val);
517 break;
518 default:
519 error = ENOTTY;
520 break;
521 }
522
523 return (error);
524 }
525
526 #ifdef PPI_MODULE
527
528 MOD_DEV(ppi, LM_DT_CHAR, CDEV_MAJOR, &ppi_cdevsw);
529
530 static int
531 ppi_load(struct lkm_table *lkmtp, int cmd)
532 {
533 struct ppb_data *ppb;
534 struct ppb_device *dev;
535 int i;
536
537 for (ppb = ppb_next_bus(NULL); ppb; ppb = ppb_next_bus(ppb)) {
538
539 dev = ppiprobe(ppb);
540 ppiattach(dev);
541
542 ppb_attach_device(dev);
543 }
544
545 return (0);
546 }
547
548 static int
549 ppi_unload(struct lkm_table *lkmtp, int cmd)
550 {
551 int i;
552
553 for (i = nppi-1; i > 0; i--) {
554 ppb_remove_device(&ppidata[i]->ppi_dev);
555 free(ppidata[i], M_TEMP);
556 }
557
558 return (0);
559 }
560
561 int
562 ppi_mod(struct lkm_table *lkmtp, int cmd, int ver)
563 {
564 DISPATCH(lkmtp, cmd, ver, ppi_load, ppi_unload, lkm_nullcmd);
565 }
566
567 #endif /* PPI_MODULE */
568
569 static ppi_devsw_installed = 0;
570
571 static void ppi_drvinit(void *unused)
572 {
573 dev_t dev;
574
575 if (!ppi_devsw_installed ) {
576 dev = makedev(CDEV_MAJOR, 0);
577 cdevsw_add(&dev, &ppi_cdevsw, NULL);
578 ppi_devsw_installed = 1;
579 }
580 }
581
582 SYSINIT(ppidev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,ppi_drvinit,NULL)
583
584 #endif /* NPPI */
Cache object: 5f3f4b8c3fbef3119bec0fd27c3fc66d
|