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 |