ppc.c (dea9268b7006769d7f1834f4bdcc149692725aca) ppc.c (bc35c17446fab005a7e11b67b9004736f1c8498b)
1/*-
2 * Copyright (c) 1997, 1998 Nicolas Souchu
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 unchanged lines hidden (view full) ---

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 *
1/*-
2 * Copyright (c) 1997, 1998 Nicolas Souchu
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 unchanged lines hidden (view full) ---

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 * $Id: ppc.c,v 1.12 1998/12/07 21:58:22 archie Exp $
26 * $Id: ppc.c,v 1.13 1998/12/30 00:37:42 hoek Exp $
27 *
28 */
29#include "ppc.h"
30
31#if NPPC > 0
32
33#include <sys/param.h>
34#include <sys/systm.h>

--- 9 unchanged lines hidden (view full) ---

44
45#include <i386/isa/isa_device.h>
46
47#include <dev/ppbus/ppbconf.h>
48#include <dev/ppbus/ppb_msq.h>
49
50#include <i386/isa/ppcreg.h>
51
27 *
28 */
29#include "ppc.h"
30
31#if NPPC > 0
32
33#include <sys/param.h>
34#include <sys/systm.h>

--- 9 unchanged lines hidden (view full) ---

44
45#include <i386/isa/isa_device.h>
46
47#include <dev/ppbus/ppbconf.h>
48#include <dev/ppbus/ppb_msq.h>
49
50#include <i386/isa/ppcreg.h>
51
52#include "opt_ppc.h"
53
54#define LOG_PPC(function, ppc, string) \
55 if (bootverbose) printf("%s: %s\n", function, string)
56
52static int ppcprobe(struct isa_device *);
53static int ppcattach(struct isa_device *);
54
55struct isa_driver ppcdriver = {
56 ppcprobe, ppcattach, "ppc"
57};
58
59static struct ppc_data *ppcdata[NPPC];

--- 65 unchanged lines hidden (view full) ---

125static void ppc_reset_epp_timeout(int);
126static void ppc_ecp_sync(int);
127static ointhand2_t ppcintr;
128
129static int ppc_exec_microseq(int, struct ppb_microseq **);
130static int ppc_generic_setmode(int, int);
131static int ppc_smclike_setmode(int, int);
132
57static int ppcprobe(struct isa_device *);
58static int ppcattach(struct isa_device *);
59
60struct isa_driver ppcdriver = {
61 ppcprobe, ppcattach, "ppc"
62};
63
64static struct ppc_data *ppcdata[NPPC];

--- 65 unchanged lines hidden (view full) ---

130static void ppc_reset_epp_timeout(int);
131static void ppc_ecp_sync(int);
132static ointhand2_t ppcintr;
133
134static int ppc_exec_microseq(int, struct ppb_microseq **);
135static int ppc_generic_setmode(int, int);
136static int ppc_smclike_setmode(int, int);
137
138static int ppc_read(int, char *, int, int);
139static int ppc_write(int, char *, int, int);
140
133static struct ppb_adapter ppc_smclike_adapter = {
134
135 0, /* no intr handler, filled by chipset dependent code */
136
137 ppc_reset_epp_timeout, ppc_ecp_sync,
138
139 ppc_exec_microseq,
140
141static struct ppb_adapter ppc_smclike_adapter = {
142
143 0, /* no intr handler, filled by chipset dependent code */
144
145 ppc_reset_epp_timeout, ppc_ecp_sync,
146
147 ppc_exec_microseq,
148
141 ppc_smclike_setmode,
149 ppc_smclike_setmode, ppc_read, ppc_write,
142
143 ppc_outsb_epp, ppc_outsw_epp, ppc_outsl_epp,
144 ppc_insb_epp, ppc_insw_epp, ppc_insl_epp,
145
146 ppc_rdtr, ppc_rstr, ppc_rctr, ppc_repp, ppc_recr, ppc_rfifo,
147 ppc_wdtr, ppc_wstr, ppc_wctr, ppc_wepp, ppc_wecr, ppc_wfifo
148};
149
150static struct ppb_adapter ppc_generic_adapter = {
151
152 0, /* no intr handler, filled by chipset dependent code */
153
154 ppc_reset_epp_timeout, ppc_ecp_sync,
155
156 ppc_exec_microseq,
157
150
151 ppc_outsb_epp, ppc_outsw_epp, ppc_outsl_epp,
152 ppc_insb_epp, ppc_insw_epp, ppc_insl_epp,
153
154 ppc_rdtr, ppc_rstr, ppc_rctr, ppc_repp, ppc_recr, ppc_rfifo,
155 ppc_wdtr, ppc_wstr, ppc_wctr, ppc_wepp, ppc_wecr, ppc_wfifo
156};
157
158static struct ppb_adapter ppc_generic_adapter = {
159
160 0, /* no intr handler, filled by chipset dependent code */
161
162 ppc_reset_epp_timeout, ppc_ecp_sync,
163
164 ppc_exec_microseq,
165
158 ppc_generic_setmode,
166 ppc_generic_setmode, ppc_read, ppc_write,
159
160 ppc_outsb_epp, ppc_outsw_epp, ppc_outsl_epp,
161 ppc_insb_epp, ppc_insw_epp, ppc_insl_epp,
162
163 ppc_rdtr, ppc_rstr, ppc_rctr, ppc_repp, ppc_recr, ppc_rfifo,
164 ppc_wdtr, ppc_wstr, ppc_wctr, ppc_wepp, ppc_wecr, ppc_wfifo
165};
166
167/*
168 * ppc_ecp_sync() XXX
169 */
170static void
171ppc_ecp_sync(int unit) {
172
173 struct ppc_data *ppc = ppcdata[unit];
174 int i, r;
175
167
168 ppc_outsb_epp, ppc_outsw_epp, ppc_outsl_epp,
169 ppc_insb_epp, ppc_insw_epp, ppc_insl_epp,
170
171 ppc_rdtr, ppc_rstr, ppc_rctr, ppc_repp, ppc_recr, ppc_rfifo,
172 ppc_wdtr, ppc_wstr, ppc_wctr, ppc_wepp, ppc_wecr, ppc_wfifo
173};
174
175/*
176 * ppc_ecp_sync() XXX
177 */
178static void
179ppc_ecp_sync(int unit) {
180
181 struct ppc_data *ppc = ppcdata[unit];
182 int i, r;
183
184 if (!(ppc->ppc_avm & PPB_ECP))
185 return;
186
176 r = r_ecr(ppc);
187 r = r_ecr(ppc);
177 if ((r & 0xe0) != 0x80)
188 if ((r & 0xe0) != PPC_ECR_EPP)
178 return;
179
180 for (i = 0; i < 100; i++) {
181 r = r_ecr(ppc);
182 if (r & 0x1)
183 return;
184 DELAY(100);
185 }
186
187 printf("ppc%d: ECP sync failed as data still " \
188 "present in FIFO.\n", unit);
189
190 return;
191}
192
189 return;
190
191 for (i = 0; i < 100; i++) {
192 r = r_ecr(ppc);
193 if (r & 0x1)
194 return;
195 DELAY(100);
196 }
197
198 printf("ppc%d: ECP sync failed as data still " \
199 "present in FIFO.\n", unit);
200
201 return;
202}
203
193static void
194ppcintr(int unit)
204/*
205 * ppc_detect_fifo()
206 *
207 * Detect parallel port FIFO
208 */
209static int
210ppc_detect_fifo(struct ppc_data *ppc)
195{
211{
196 /* call directly upper code */
197 ppb_intr(&ppcdata[unit]->ppc_link);
212 char ecr_sav;
213 char ctr_sav, ctr, cc;
214 short i;
215
216 /* save registers */
217 ecr_sav = r_ecr(ppc);
218 ctr_sav = r_ctr(ppc);
198
219
199 return;
220 /* enter ECP configuration mode, no interrupt, no DMA */
221 w_ecr(ppc, 0xf4);
222
223 /* read PWord size - transfers in FIFO mode must be PWord aligned */
224 ppc->ppc_pword = (r_cnfgA(ppc) & PPC_PWORD_MASK);
225
226 /* XXX 16 and 32 bits implementations not supported */
227 if (ppc->ppc_pword != PPC_PWORD_8) {
228 LOG_PPC(__FUNCTION__, ppc, "PWord not supported");
229 goto error;
230 }
231
232 w_ecr(ppc, 0x34); /* byte mode, no interrupt, no DMA */
233 ctr = r_ctr(ppc);
234 w_ctr(ppc, ctr | PCD); /* set direction to 1 */
235
236 /* enter ECP test mode, no interrupt, no DMA */
237 w_ecr(ppc, 0xd4);
238
239 /* flush the FIFO */
240 for (i=0; i<1024; i++) {
241 if (r_ecr(ppc) & PPC_FIFO_EMPTY)
242 break;
243 cc = r_fifo(ppc);
244 }
245
246 if (i >= 1024) {
247 LOG_PPC(__FUNCTION__, ppc, "can't flush FIFO");
248 goto error;
249 }
250
251 /* enable interrupts, no DMA */
252 w_ecr(ppc, 0xd0);
253
254 /* determine readIntrThreshold
255 * fill the FIFO until serviceIntr is set
256 */
257 for (i=0; i<1024; i++) {
258 w_fifo(ppc, (char)i);
259 if (!ppc->ppc_rthr && (r_ecr(ppc) & PPC_SERVICE_INTR)) {
260 /* readThreshold reached */
261 ppc->ppc_rthr = i+1;
262 }
263 if (r_ecr(ppc) & PPC_FIFO_FULL) {
264 ppc->ppc_fifo = i+1;
265 break;
266 }
267 }
268
269 if (i >= 1024) {
270 LOG_PPC(__FUNCTION__, ppc, "can't fill FIFO");
271 goto error;
272 }
273
274 w_ecr(ppc, 0xd4); /* test mode, no interrupt, no DMA */
275 w_ctr(ppc, ctr & ~PCD); /* set direction to 0 */
276 w_ecr(ppc, 0xd0); /* enable interrupts */
277
278 /* determine writeIntrThreshold
279 * empty the FIFO until serviceIntr is set
280 */
281 for (i=ppc->ppc_fifo; i>0; i--) {
282 if (r_fifo(ppc) != (char)(ppc->ppc_fifo-i)) {
283 LOG_PPC(__FUNCTION__, ppc, "invalid data in FIFO");
284 goto error;
285 }
286 if (r_ecr(ppc) & PPC_SERVICE_INTR) {
287 /* writeIntrThreshold reached */
288 ppc->ppc_wthr = ppc->ppc_fifo - i+1;
289 }
290 /* if FIFO empty before the last byte, error */
291 if (i>1 && (r_ecr(ppc) & PPC_FIFO_EMPTY)) {
292 LOG_PPC(__FUNCTION__, ppc, "data lost in FIFO");
293 goto error;
294 }
295 }
296
297 /* FIFO must be empty after the last byte */
298 if (!(r_ecr(ppc) & PPC_FIFO_EMPTY)) {
299 LOG_PPC(__FUNCTION__, ppc, "can't empty the FIFO");
300 goto error;
301 }
302
303 w_ctr(ppc, ctr_sav);
304 w_ecr(ppc, ecr_sav);
305
306 return (0);
307
308error:
309 w_ctr(ppc, ctr_sav);
310 w_ecr(ppc, ecr_sav);
311
312 return (EINVAL);
200}
201
202static int
203ppc_detect_port(struct ppc_data *ppc)
204{
205
206 w_ctr(ppc, 0x0c); /* To avoid missing PS2 ports */
207 w_dtr(ppc, 0xaa);

--- 441 unchanged lines hidden (view full) ---

649 outb(cio, r | SMC_EPPSPP);
650 if (bootverbose)
651 printf(" EPP SPP");
652 }
653 }
654 ppc->ppc_avm = chipset_mode;
655 }
656
313}
314
315static int
316ppc_detect_port(struct ppc_data *ppc)
317{
318
319 w_ctr(ppc, 0x0c); /* To avoid missing PS2 ports */
320 w_dtr(ppc, 0xaa);

--- 441 unchanged lines hidden (view full) ---

762 outb(cio, r | SMC_EPPSPP);
763 if (bootverbose)
764 printf(" EPP SPP");
765 }
766 }
767 ppc->ppc_avm = chipset_mode;
768 }
769
770 /* set FIFO threshold to 16 */
771 if (ppc->ppc_avm & PPB_ECP) {
772 /* select CRA */
773 outb(csr, 0xa);
774 outb(cio, 16);
775 }
776
657end_detect:
658
659 if (bootverbose)
660 printf ("\n");
661
662 if (ppc->ppc_avm & PPB_EPP) {
663 /* select CR4 */
664 outb(csr, 0x4);

--- 214 unchanged lines hidden (view full) ---

879 /* default to generic */
880 ppc->ppc_link.adapter = &ppc_generic_adapter;
881
882 if (bootverbose)
883 printf("ppc%d:", ppc->ppc_unit);
884
885 if (!chipset_mode) {
886 /* first, check for ECP */
777end_detect:
778
779 if (bootverbose)
780 printf ("\n");
781
782 if (ppc->ppc_avm & PPB_EPP) {
783 /* select CR4 */
784 outb(csr, 0x4);

--- 214 unchanged lines hidden (view full) ---

999 /* default to generic */
1000 ppc->ppc_link.adapter = &ppc_generic_adapter;
1001
1002 if (bootverbose)
1003 printf("ppc%d:", ppc->ppc_unit);
1004
1005 if (!chipset_mode) {
1006 /* first, check for ECP */
887 w_ecr(ppc, 0x20);
888 if ((r_ecr(ppc) & 0xe0) == 0x20) {
1007 w_ecr(ppc, PPC_ECR_PS2);
1008 if ((r_ecr(ppc) & 0xe0) == PPC_ECR_PS2) {
889 ppc->ppc_avm |= PPB_ECP | PPB_SPP;
890 if (bootverbose)
891 printf(" ECP SPP");
892
893 /* search for SMC style ECP+EPP mode */
1009 ppc->ppc_avm |= PPB_ECP | PPB_SPP;
1010 if (bootverbose)
1011 printf(" ECP SPP");
1012
1013 /* search for SMC style ECP+EPP mode */
894 w_ecr(ppc, 0x80);
1014 w_ecr(ppc, PPC_ECR_EPP);
895 }
896
897 /* try to reset EPP timeout bit */
898 if (ppc_check_epp_timeout(ppc)) {
899 ppc->ppc_avm |= PPB_EPP;
900
901 if (ppc->ppc_avm & PPB_ECP) {
902 /* SMC like chipset found */
903 ppc->ppc_type = SMC_LIKE;
904 ppc->ppc_link.adapter = &ppc_smclike_adapter;
905
906 if (bootverbose)
907 printf(" ECP+EPP");
908 } else {
909 if (bootverbose)
910 printf(" EPP");
911 }
912 } else {
913 /* restore to standard mode */
1015 }
1016
1017 /* try to reset EPP timeout bit */
1018 if (ppc_check_epp_timeout(ppc)) {
1019 ppc->ppc_avm |= PPB_EPP;
1020
1021 if (ppc->ppc_avm & PPB_ECP) {
1022 /* SMC like chipset found */
1023 ppc->ppc_type = SMC_LIKE;
1024 ppc->ppc_link.adapter = &ppc_smclike_adapter;
1025
1026 if (bootverbose)
1027 printf(" ECP+EPP");
1028 } else {
1029 if (bootverbose)
1030 printf(" EPP");
1031 }
1032 } else {
1033 /* restore to standard mode */
914 w_ecr(ppc, 0x0);
1034 w_ecr(ppc, PPC_ECR_STD);
915 }
916
917 /* XXX try to detect NIBBLE and PS2 modes */
918 ppc->ppc_avm |= PPB_NIBBLE;
919
920 if (bootverbose)
921 printf(" SPP");
922

--- 50 unchanged lines hidden (view full) ---

973 for (i=0; chipset_detect[i] != NULL; i++) {
974 if ((mode = chipset_detect[i](ppc, chipset_mode)) != -1) {
975 ppc->ppc_mode = mode;
976 break;
977 }
978 }
979 }
980
1035 }
1036
1037 /* XXX try to detect NIBBLE and PS2 modes */
1038 ppc->ppc_avm |= PPB_NIBBLE;
1039
1040 if (bootverbose)
1041 printf(" SPP");
1042

--- 50 unchanged lines hidden (view full) ---

1093 for (i=0; chipset_detect[i] != NULL; i++) {
1094 if ((mode = chipset_detect[i](ppc, chipset_mode)) != -1) {
1095 ppc->ppc_mode = mode;
1096 break;
1097 }
1098 }
1099 }
1100
1101 /* configure/detect ECP FIFO */
1102 if ((ppc->ppc_avm & PPB_ECP) && !(ppc->ppc_flags & 0x80))
1103 ppc_detect_fifo(ppc);
1104
981 return (0);
982}
983
984/*
985 * ppc_exec_microseq()
986 *
987 * Execute a microsequence.
988 * Microsequence mechanism is supposed to handle fast I/O operations.

--- 208 unchanged lines hidden (view full) ---

1197 panic("%s: unknown microsequence opcode 0x%x",
1198 __FUNCTION__, mi->opcode);
1199 }
1200 }
1201
1202 /* unreached */
1203}
1204
1105 return (0);
1106}
1107
1108/*
1109 * ppc_exec_microseq()
1110 *
1111 * Execute a microsequence.
1112 * Microsequence mechanism is supposed to handle fast I/O operations.

--- 208 unchanged lines hidden (view full) ---

1321 panic("%s: unknown microsequence opcode 0x%x",
1322 __FUNCTION__, mi->opcode);
1323 }
1324 }
1325
1326 /* unreached */
1327}
1328
1329static void
1330ppcintr(int unit)
1331{
1332 struct ppc_data *ppc = ppcdata[unit];
1333 char ctr, ecr;
1334
1335 ctr = r_ctr(ppc);
1336 ecr = r_ecr(ppc);
1337
1338#ifdef PPC_DEBUG
1339 printf("!");
1340#endif
1341
1342 /* don't use ecp mode with IRQENABLE set */
1343 if (ctr & IRQENABLE) {
1344 /* call upper code */
1345 ppb_intr(&ppc->ppc_link);
1346 return;
1347 }
1348
1349 if (ctr & nFAULT) {
1350 if (ppc->ppc_irqstat & PPC_IRQ_nFAULT) {
1351
1352 w_ecr(ppc, ecr | PPC_nFAULT_INTR);
1353 ppc->ppc_irqstat &= ~PPC_IRQ_nFAULT;
1354 } else {
1355 /* call upper code */
1356 ppb_intr(&ppc->ppc_link);
1357 return;
1358 }
1359 }
1360
1361 if (ppc->ppc_irqstat & PPC_IRQ_DMA) {
1362 /* disable interrupts (should be done by hardware though) */
1363 w_ecr(ppc, ecr | PPC_SERVICE_INTR);
1364 ppc->ppc_irqstat &= ~PPC_IRQ_DMA;
1365 ecr = r_ecr(ppc);
1366
1367 /* check if DMA completed */
1368 if ((ppc->ppc_avm & PPB_ECP) && (ecr & PPC_ENABLE_DMA)) {
1369#ifdef PPC_DEBUG
1370 printf("a");
1371#endif
1372 /* stop DMA */
1373 w_ecr(ppc, ecr & ~PPC_ENABLE_DMA);
1374 ecr = r_ecr(ppc);
1375
1376 if (ppc->ppc_dmastat == PPC_DMA_STARTED) {
1377#ifdef PPC_DEBUG
1378 printf("d");
1379#endif
1380 isa_dmadone(
1381 ppc->ppc_dmaflags,
1382 ppc->ppc_dmaddr,
1383 ppc->ppc_dmacnt,
1384 ppc->ppc_dmachan);
1385
1386 ppc->ppc_dmastat = PPC_DMA_COMPLETE;
1387
1388 /* wakeup the waiting process */
1389 wakeup((caddr_t)ppc);
1390 }
1391 }
1392 } else if (ppc->ppc_irqstat & PPC_IRQ_FIFO) {
1393
1394 /* classic interrupt I/O */
1395 ppc->ppc_irqstat &= ~PPC_IRQ_FIFO;
1396
1397 }
1398
1399 return;
1400}
1401
1402static int
1403ppc_read(int unit, char *buf, int len, int mode)
1404{
1405 return (EINVAL);
1406}
1407
1205/*
1408/*
1409 * Call this function if you want to send data in any advanced mode
1410 * of your parallel port: FIFO, DMA
1411 *
1412 * If what you want is not possible (no ECP, no DMA...),
1413 * EINVAL is returned
1414 */
1415static int
1416ppc_write(int unit, char *buf, int len, int how)
1417{
1418 struct ppc_data *ppc = ppcdata[unit];
1419 char ecr, ecr_sav, ctr, ctr_sav;
1420 int s, error = 0;
1421 int spin;
1422
1423#ifdef PPC_DEBUG
1424 printf("w");
1425#endif
1426
1427 ecr_sav = r_ecr(ppc);
1428 ctr_sav = r_ctr(ppc);
1429
1430 /*
1431 * Send buffer with DMA, FIFO and interrupts
1432 */
1433 if (ppc->ppc_avm & PPB_ECP) {
1434
1435 if (ppc->ppc_dmachan >= 0) {
1436
1437 /* byte mode, no intr, no DMA, dir=0, flush fifo
1438 */
1439 ecr = PPC_ECR_STD | PPC_DISABLE_INTR;
1440 w_ecr(ppc, ecr);
1441
1442 /* disable nAck interrupts */
1443 ctr = r_ctr(ppc);
1444 ctr &= ~IRQENABLE;
1445 w_ctr(ppc, ctr);
1446
1447 ppc->ppc_dmaflags = 0;
1448 ppc->ppc_dmaddr = (caddr_t)buf;
1449 ppc->ppc_dmacnt = (u_int)len;
1450
1451 switch (ppc->ppc_mode) {
1452 case PPB_COMPATIBLE:
1453 /* compatible mode with FIFO, no intr, DMA, dir=0 */
1454 ecr = PPC_ECR_FIFO | PPC_DISABLE_INTR | PPC_ENABLE_DMA;
1455 break;
1456 case PPB_ECP:
1457 ecr = PPC_ECR_ECP | PPC_DISABLE_INTR | PPC_ENABLE_DMA;
1458 break;
1459 default:
1460 error = EINVAL;
1461 goto error;
1462 }
1463
1464 w_ecr(ppc, ecr);
1465 ecr = r_ecr(ppc);
1466
1467 /* enter splhigh() not to be preempted
1468 * by the dma interrupt, we may miss
1469 * the wakeup otherwise
1470 */
1471 s = splhigh();
1472
1473 ppc->ppc_dmastat = PPC_DMA_INIT;
1474
1475 /* enable interrupts */
1476 ecr &= ~PPC_SERVICE_INTR;
1477 ppc->ppc_irqstat = PPC_IRQ_DMA;
1478 w_ecr(ppc, ecr);
1479
1480 isa_dmastart(
1481 ppc->ppc_dmaflags,
1482 ppc->ppc_dmaddr,
1483 ppc->ppc_dmacnt,
1484 ppc->ppc_dmachan);
1485#ifdef PPC_DEBUG
1486 printf("s%d", ppc->ppc_dmacnt);
1487#endif
1488 ppc->ppc_dmastat = PPC_DMA_STARTED;
1489
1490 /* Wait for the DMA completed interrupt. We hope we won't
1491 * miss it, otherwise a signal will be necessary to unlock the
1492 * process.
1493 */
1494 do {
1495 /* release CPU */
1496 error = tsleep((caddr_t)ppc,
1497 PPBPRI | PCATCH, "ppcdma", 0);
1498
1499 } while (error == EWOULDBLOCK);
1500
1501 splx(s);
1502
1503 if (error) {
1504#ifdef PPC_DEBUG
1505 printf("i");
1506#endif
1507 /* stop DMA */
1508 isa_dmadone(
1509 ppc->ppc_dmaflags, ppc->ppc_dmaddr,
1510 ppc->ppc_dmacnt, ppc->ppc_dmachan);
1511
1512 /* no dma, no interrupt, flush the fifo */
1513 w_ecr(ppc, PPC_ECR_RESET);
1514
1515 ppc->ppc_dmastat = PPC_DMA_INTERRUPTED;
1516 goto error;
1517 }
1518
1519 /* wait for an empty fifo */
1520 while (!(r_ecr(ppc) & PPC_FIFO_EMPTY)) {
1521
1522 for (spin=100; spin; spin--)
1523 if (r_ecr(ppc) & PPC_FIFO_EMPTY)
1524 goto fifo_empty;
1525#ifdef PPC_DEBUG
1526 printf("Z");
1527#endif
1528 error = tsleep((caddr_t)ppc, PPBPRI | PCATCH, "ppcfifo", hz/100);
1529 if (error != EWOULDBLOCK) {
1530#ifdef PPC_DEBUG
1531 printf("I");
1532#endif
1533 /* no dma, no interrupt, flush the fifo */
1534 w_ecr(ppc, PPC_ECR_RESET);
1535
1536 ppc->ppc_dmastat = PPC_DMA_INTERRUPTED;
1537 error = EINTR;
1538 goto error;
1539 }
1540 }
1541
1542fifo_empty:
1543 /* no dma, no interrupt, flush the fifo */
1544 w_ecr(ppc, PPC_ECR_RESET);
1545
1546 } else
1547 error = EINVAL; /* XXX we should FIFO and
1548 * interrupts */
1549 } else
1550 error = EINVAL;
1551
1552error:
1553
1554 /* PDRQ must be kept unasserted until nPDACK is
1555 * deasserted for a minimum of 350ns (SMC datasheet)
1556 *
1557 * Consequence may be a FIFO that never empty
1558 */
1559 DELAY(1);
1560
1561 w_ecr(ppc, ecr_sav);
1562 w_ctr(ppc, ctr_sav);
1563
1564 return (error);
1565}
1566
1567/*
1206 * Configure current operating mode
1207 */
1208static int
1209ppc_generic_setmode(int unit, int mode)
1210{
1211 struct ppc_data *ppc = ppcdata[unit];
1568 * Configure current operating mode
1569 */
1570static int
1571ppc_generic_setmode(int unit, int mode)
1572{
1573 struct ppc_data *ppc = ppcdata[unit];
1574 u_char ecr = 0;
1212
1575
1213 /* back to compatible mode, XXX don't know yet what to do here */
1214 if (mode == 0) {
1215 ppc->ppc_mode = PPB_COMPATIBLE;
1216 return (0);
1217 }
1218
1219 /* check if mode is available */
1576 /* check if mode is available */
1220 if (!(ppc->ppc_avm & mode))
1221 return (EOPNOTSUPP);
1577 if (mode && !(ppc->ppc_avm & mode))
1578 return (EINVAL);
1222
1223 /* if ECP mode, configure ecr register */
1224 if (ppc->ppc_avm & PPB_ECP) {
1579
1580 /* if ECP mode, configure ecr register */
1581 if (ppc->ppc_avm & PPB_ECP) {
1582 /* return to byte mode (keeping direction bit),
1583 * no interrupt, no DMA to be able to change to
1584 * ECP
1585 */
1586 w_ecr(ppc, PPC_ECR_RESET);
1587 ecr = PPC_DISABLE_INTR;
1225
1588
1226 /* XXX disable DMA, enable interrupts */
1227 if (mode & PPB_EPP)
1589 if (mode & PPB_EPP)
1228 return (EOPNOTSUPP);
1229 else if (mode & PPB_PS2)
1230 /* select PS2 mode with ECP */
1231 w_ecr(ppc, 0x20);
1590 return (EINVAL);
1232 else if (mode & PPB_ECP)
1233 /* select ECP mode */
1591 else if (mode & PPB_ECP)
1592 /* select ECP mode */
1234 w_ecr(ppc, 0x60);
1593 ecr |= PPC_ECR_ECP;
1594 else if (mode & PPB_PS2)
1595 /* select PS2 mode with ECP */
1596 ecr |= PPC_ECR_PS2;
1235 else
1597 else
1236 /* select standard parallel port mode */
1237 w_ecr(ppc, 0x00);
1598 /* select COMPATIBLE/NIBBLE mode */
1599 ecr |= PPC_ECR_STD;
1600
1601 w_ecr(ppc, ecr);
1238 }
1239
1240 ppc->ppc_mode = mode;
1241
1242 return (0);
1243}
1244
1602 }
1603
1604 ppc->ppc_mode = mode;
1605
1606 return (0);
1607}
1608
1609/*
1610 * The ppc driver is free to choose options like FIFO or DMA
1611 * if ECP mode is available.
1612 *
1613 * The 'RAW' option allows the upper drivers to force the ppc mode
1614 * even with FIFO, DMA available.
1615 */
1245int
1246ppc_smclike_setmode(int unit, int mode)
1247{
1248 struct ppc_data *ppc = ppcdata[unit];
1616int
1617ppc_smclike_setmode(int unit, int mode)
1618{
1619 struct ppc_data *ppc = ppcdata[unit];
1620 u_char ecr = 0;
1249
1621
1250 /* back to compatible mode, XXX don't know yet what to do here */
1251 if (mode == 0) {
1252 ppc->ppc_mode = PPB_COMPATIBLE;
1253 return (0);
1254 }
1255
1256 /* check if mode is available */
1622 /* check if mode is available */
1257 if (!(ppc->ppc_avm & mode))
1258 return (EOPNOTSUPP);
1623 if (mode && !(ppc->ppc_avm & mode))
1624 return (EINVAL);
1259
1260 /* if ECP mode, configure ecr register */
1261 if (ppc->ppc_avm & PPB_ECP) {
1625
1626 /* if ECP mode, configure ecr register */
1627 if (ppc->ppc_avm & PPB_ECP) {
1628 /* return to byte mode (keeping direction bit),
1629 * no interrupt, no DMA to be able to change to
1630 * ECP or EPP mode
1631 */
1632 w_ecr(ppc, PPC_ECR_RESET);
1633 ecr = PPC_DISABLE_INTR;
1262
1634
1263 /* XXX disable DMA, enable interrupts */
1264 if (mode & PPB_EPP)
1265 /* select EPP mode */
1635 if (mode & PPB_EPP)
1636 /* select EPP mode */
1266 w_ecr(ppc, 0x80);
1267 else if (mode & PPB_PS2)
1268 /* select PS2 mode with ECP */
1269 w_ecr(ppc, 0x20);
1637 ecr |= PPC_ECR_EPP;
1270 else if (mode & PPB_ECP)
1271 /* select ECP mode */
1638 else if (mode & PPB_ECP)
1639 /* select ECP mode */
1272 w_ecr(ppc, 0x60);
1640 ecr |= PPC_ECR_ECP;
1641 else if (mode & PPB_PS2)
1642 /* select PS2 mode with ECP */
1643 ecr |= PPC_ECR_PS2;
1273 else
1644 else
1274 /* select standard parallel port mode */
1275 w_ecr(ppc, 0x00);
1645 /* select COMPATIBLE/NIBBLE mode */
1646 ecr |= PPC_ECR_STD;
1647
1648 w_ecr(ppc, ecr);
1276 }
1277
1278 ppc->ppc_mode = mode;
1279
1649 }
1650
1651 ppc->ppc_mode = mode;
1652
1280
1281 return (0);
1282}
1283
1284/*
1285 * EPP timeout, according to the PC87332 manual
1286 * Semantics of clearing EPP timeout bit.
1287 * PC87332 - reading SPP_STR does it...
1288 * SMC - write 1 to EPP timeout bit XXX

--- 20 unchanged lines hidden (view full) ---

1309
1310 /*
1311 * If port not specified, use bios list.
1312 */
1313 if(dvp->id_iobase < 0) {
1314 if((next_bios_ppc < BIOS_MAX_PPC) &&
1315 (*(BIOS_PORTS+next_bios_ppc) != 0) ) {
1316 dvp->id_iobase = *(BIOS_PORTS+next_bios_ppc++);
1653 return (0);
1654}
1655
1656/*
1657 * EPP timeout, according to the PC87332 manual
1658 * Semantics of clearing EPP timeout bit.
1659 * PC87332 - reading SPP_STR does it...
1660 * SMC - write 1 to EPP timeout bit XXX

--- 20 unchanged lines hidden (view full) ---

1681
1682 /*
1683 * If port not specified, use bios list.
1684 */
1685 if(dvp->id_iobase < 0) {
1686 if((next_bios_ppc < BIOS_MAX_PPC) &&
1687 (*(BIOS_PORTS+next_bios_ppc) != 0) ) {
1688 dvp->id_iobase = *(BIOS_PORTS+next_bios_ppc++);
1317 printf("ppc: parallel port found at 0x%x\n",
1318 dvp->id_iobase);
1689 if (bootverbose)
1690 printf("ppc: parallel port found at 0x%x\n",
1691 dvp->id_iobase);
1319 } else
1320 return (0);
1321 }
1322
1323 /*
1324 * Port was explicitly specified.
1325 * This allows probing of ports unknown to the BIOS.
1326 */

--- 19 unchanged lines hidden (view full) ---

1346 ppc->ppc_epp = (dvp->id_flags & 0x10) >> 4;
1347
1348 /*
1349 * XXX Try and detect if interrupts are working
1350 */
1351 if (!(dvp->id_flags & 0x20))
1352 ppc->ppc_irq = ffs(dvp->id_irq) - 1;
1353
1692 } else
1693 return (0);
1694 }
1695
1696 /*
1697 * Port was explicitly specified.
1698 * This allows probing of ports unknown to the BIOS.
1699 */

--- 19 unchanged lines hidden (view full) ---

1719 ppc->ppc_epp = (dvp->id_flags & 0x10) >> 4;
1720
1721 /*
1722 * XXX Try and detect if interrupts are working
1723 */
1724 if (!(dvp->id_flags & 0x20))
1725 ppc->ppc_irq = ffs(dvp->id_irq) - 1;
1726
1727 ppc->ppc_dmachan = dvp->id_drq;
1728
1354 ppcdata[ppc->ppc_unit] = ppc;
1355 nppc ++;
1356
1357 /*
1358 * Link the Parallel Port Chipset (adapter) to
1359 * the future ppbus. Default to a generic chipset
1360 */
1361 ppc->ppc_link.adapter_unit = ppc->ppc_unit;

--- 17 unchanged lines hidden (view full) ---

1379 struct ppc_data *ppc = ppcdata[isdp->id_unit];
1380 struct ppb_data *ppbus;
1381
1382 printf("ppc%d: %s chipset (%s) in %s mode%s\n", ppc->ppc_unit,
1383 ppc_types[ppc->ppc_type], ppc_avms[ppc->ppc_avm],
1384 ppc_modes[ppc->ppc_mode], (PPB_IS_EPP(ppc->ppc_mode)) ?
1385 ppc_epp_protocol[ppc->ppc_epp] : "");
1386
1729 ppcdata[ppc->ppc_unit] = ppc;
1730 nppc ++;
1731
1732 /*
1733 * Link the Parallel Port Chipset (adapter) to
1734 * the future ppbus. Default to a generic chipset
1735 */
1736 ppc->ppc_link.adapter_unit = ppc->ppc_unit;

--- 17 unchanged lines hidden (view full) ---

1754 struct ppc_data *ppc = ppcdata[isdp->id_unit];
1755 struct ppb_data *ppbus;
1756
1757 printf("ppc%d: %s chipset (%s) in %s mode%s\n", ppc->ppc_unit,
1758 ppc_types[ppc->ppc_type], ppc_avms[ppc->ppc_avm],
1759 ppc_modes[ppc->ppc_mode], (PPB_IS_EPP(ppc->ppc_mode)) ?
1760 ppc_epp_protocol[ppc->ppc_epp] : "");
1761
1762 if (ppc->ppc_fifo)
1763 printf("ppc%d: FIFO with %d/%d/%d bytes threshold\n",
1764 ppc->ppc_unit, ppc->ppc_fifo, ppc->ppc_wthr,
1765 ppc->ppc_rthr);
1766
1387 isdp->id_ointr = ppcintr;
1388
1389 /*
1390 * Prepare ppbus data area for upper level code.
1391 */
1392 ppbus = ppb_alloc_bus();
1393
1394 if (!ppbus)
1395 return (0);
1396
1397 ppc->ppc_link.ppbus = ppbus;
1398 ppbus->ppb_link = &ppc->ppc_link;
1399
1767 isdp->id_ointr = ppcintr;
1768
1769 /*
1770 * Prepare ppbus data area for upper level code.
1771 */
1772 ppbus = ppb_alloc_bus();
1773
1774 if (!ppbus)
1775 return (0);
1776
1777 ppc->ppc_link.ppbus = ppbus;
1778 ppbus->ppb_link = &ppc->ppc_link;
1779
1780 if ((ppc->ppc_avm & PPB_ECP) && (ppc->ppc_dmachan > 0)) {
1781
1782 /* acquire the DMA channel forever */
1783 isa_dma_acquire(ppc->ppc_dmachan);
1784 isa_dmainit(ppc->ppc_dmachan, 1024); /* nlpt.BUFSIZE */
1785 }
1786
1400 /*
1401 * Probe the ppbus and attach devices found.
1402 */
1403 ppb_attachdevs(ppbus);
1404
1405 return (1);
1406}
1407#endif
1787 /*
1788 * Probe the ppbus and attach devices found.
1789 */
1790 ppb_attachdevs(ppbus);
1791
1792 return (1);
1793}
1794#endif