1 /* $NetBSD: pi1ppc.c,v 1.1 2005/12/28 08:31:09 kurahone Exp $ */ 2 3 /* 4 * Copyright (c) 2001 Alcove - Nicolas Souchu 5 * Copyright (c) 2003, 2004 Gary Thorpe <gathorpe@users.sourceforge.net> 6 * Copyright (c) 2005 Joe Britt <britt@danger.com> - SGI PI1 version 7 * All rights reserved. 8 * 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 * 31 * FreeBSD: src/sys/isa/ppc.c,v 1.26.2.5 2001/10/02 05:21:45 nsouch Exp 32 * 33 */ 34 35 #include <sys/cdefs.h> 36 __KERNEL_RCSID(0, "$NetBSD: pi1ppc.c,v 1.1 2005/12/28 08:31:09 kurahone Exp $"); 37 38 #include "opt_pi1ppc.h" 39 40 #include <sys/types.h> 41 #include <sys/param.h> 42 #include <sys/kernel.h> 43 #include <sys/device.h> 44 #include <sys/malloc.h> 45 #include <sys/proc.h> 46 #include <sys/systm.h> 47 #include <sys/vnode.h> 48 #include <sys/syslog.h> 49 50 #include <machine/bus.h> 51 /*#include <machine/intr.h>*/ 52 53 #include <dev/ppbus/ppbus_conf.h> 54 #include <dev/ppbus/ppbus_msq.h> 55 #include <dev/ppbus/ppbus_io.h> 56 #include <dev/ppbus/ppbus_var.h> 57 58 #include <machine/autoconf.h> 59 #include <machine/machtype.h> 60 61 #include <sgimips/ioc/iocreg.h> 62 63 #include <sgimips/hpc/hpcvar.h> 64 #include <sgimips/hpc/hpcreg.h> 65 66 #include <sgimips/hpc/pi1ppcreg.h> 67 #include <sgimips/hpc/pi1ppcvar.h> 68 69 #ifdef PI1PPC_DEBUG 70 int pi1ppc_debug = 1; 71 #endif 72 73 #ifdef PI1PPC_VERBOSE 74 int pi1ppc_verbose = 1; 75 #endif 76 77 78 /* Prototypes for functions. */ 79 80 /* PC-style register emulation */ 81 static u_int8_t r_reg(int reg, struct pi1ppc_softc *pi1ppc); 82 static void w_reg(int reg, struct pi1ppc_softc *pi1ppc, u_int8_t byte); 83 84 #define AT_DATA_REG 0 85 #define AT_STAT_REG 1 86 #define AT_CTL_REG 2 87 88 #define pi1ppc_r_str(_x) r_reg(AT_STAT_REG,_x) 89 #define pi1ppc_r_ctr(_x) r_reg(AT_CTL_REG,_x) 90 #define pi1ppc_r_dtr(_x) r_reg(AT_DATA_REG,_x) 91 92 #define pi1ppc_w_str(_x,_y) 93 #define pi1ppc_w_ctr(_x,_y) w_reg(AT_CTL_REG,_x,_y) 94 #define pi1ppc_w_dtr(_x,_y) w_reg(AT_DATA_REG,_x,_y) 95 96 /* do we need to do these? */ 97 #define pi1ppc_barrier_r(_x) bus_space_barrier(_x->sc_iot,_x->sc_ioh, \ 98 0,4,BUS_SPACE_BARRIER_READ) 99 #define pi1ppc_barrier_w(_x) bus_space_barrier(_x->sc_iot,_x->sc_ioh, \ 100 0,4,BUS_SPACE_BARRIER_WRITE) 101 #define pi1ppc_barrier(_x) pi1ppc_barrier_r(_x) 102 103 104 /* Print function for config_found() */ 105 static int pi1ppc_print(void *, const char *); 106 107 /* Routines for ppbus interface (bus + device) */ 108 static int pi1ppc_read(struct device *, char *, int, int, size_t *); 109 static int pi1ppc_write(struct device *, char *, int, int, size_t *); 110 static int pi1ppc_setmode(struct device *, int); 111 static int pi1ppc_getmode(struct device *); 112 static int pi1ppc_exec_microseq(struct device *, struct ppbus_microseq * *); 113 static u_int8_t pi1ppc_io(struct device *, int, u_char *, int, u_char); 114 static int pi1ppc_read_ivar(struct device *, int, unsigned int *); 115 static int pi1ppc_write_ivar(struct device *, int, unsigned int *); 116 static int pi1ppc_add_handler(struct device *, void (*)(void *), void *); 117 static int pi1ppc_remove_handler(struct device *, void (*)(void *)); 118 119 /* no-ops, do any IOC machines have ECP/EPP-capable ports? */ 120 static void pi1ppc_reset_epp_timeout(struct device *); 121 static void pi1ppc_ecp_sync(struct device *); 122 123 /* Utility functions */ 124 125 /* Functions to read bytes into device's input buffer */ 126 static void pi1ppc_nibble_read(struct pi1ppc_softc * const); 127 static void pi1ppc_byte_read(struct pi1ppc_softc * const); 128 129 /* Functions to write bytes to device's output buffer */ 130 static void pi1ppc_std_write(struct pi1ppc_softc * const); 131 132 /* Miscellaneous */ 133 static void pi1ppc_set_intr_mask(struct pi1ppc_softc * const, u_int8_t); 134 static u_int8_t pi1ppc_get_intr_stat(struct pi1ppc_softc * const); 135 136 #ifdef USE_INDY_ACK_HACK 137 static u_int8_t pi1ppc_get_intr_mask(struct pi1ppc_softc * const); 138 #endif 139 140 static int pi1ppc_poll_str(struct pi1ppc_softc * const, const u_int8_t, 141 const u_int8_t); 142 static int pi1ppc_wait_interrupt(struct pi1ppc_softc * const, const caddr_t, 143 const u_int8_t); 144 145 static int pi1ppc_poll_interrupt_stat(struct pi1ppc_softc * const, 146 const u_int8_t); 147 148 static int pi1ppc_match(struct device * parent, struct cfdata * match, void *aux); 149 static void pi1ppc_attach(struct device * parent, struct device *self, void *aux); 150 151 CFATTACH_DECL(pi1ppc, sizeof(struct pi1ppc_softc), 152 pi1ppc_match, 153 pi1ppc_attach, 154 NULL, 155 NULL); 156 157 /* Currently only matching on Indy, though I think the Indigo1 also 158 uses PI1. If it does, then the driver should work (if it is attached 159 at the appropriate base addr). 160 */ 161 162 static int 163 pi1ppc_match(struct device * parent, struct cfdata * match, void *aux) 164 { 165 if (mach_type == MACH_SGI_IP22) 166 return 1; 167 168 return 0; 169 } 170 171 static void 172 pi1ppc_attach(struct device * parent, struct device *self, void *aux) 173 { 174 struct pi1ppc_softc *sc; 175 struct hpc_attach_args *haa; 176 177 sc = (struct pi1ppc_softc *)self; 178 haa = aux; 179 sc->sc_iot = haa->ha_st; 180 181 if (bus_space_subregion(haa->ha_st, haa->ha_sh, haa->ha_devoff, 182 0x28, /* # bytes in par port regs */ 183 &sc->sc_ioh)) { 184 aprint_error(": unable to map control registers\n"); 185 return; 186 } 187 188 pi1ppc_sc_attach(sc); 189 } 190 191 /* 192 * Generic attach and detach functions for pi1ppc device. 193 * 194 * If sc_dev_ok in soft configuration data is not ATPPC_ATTACHED, these should 195 * be skipped altogether. 196 */ 197 198 /* Soft configuration attach for pi1ppc */ 199 void 200 pi1ppc_sc_attach(struct pi1ppc_softc *lsc) 201 { 202 /* Adapter used to configure ppbus device */ 203 struct parport_adapter sc_parport_adapter; 204 char buf[64]; 205 206 PI1PPC_LOCK_INIT(lsc); 207 208 /* For a PC, this is where the installed chipset is probed. 209 * We *know* what we have, no need to probe. 210 */ 211 lsc->sc_type = PI1PPC_TYPE_INDY; 212 lsc->sc_model = GENERIC; 213 214 /* XXX Once we support Interrupts & DMA, update this */ 215 lsc->sc_has = PI1PPC_HAS_PS2; 216 217 /* Print out chipset capabilities */ 218 bitmask_snprintf(lsc->sc_has, "\20\1INTR\2DMA\3FIFO\4PS2\5ECP\6EPP", 219 buf, sizeof(buf)); 220 printf("\n%s: capabilities=%s\n", lsc->sc_dev.dv_xname, buf); 221 222 /* Initialize device's buffer pointers */ 223 lsc->sc_outb = lsc->sc_outbstart = lsc->sc_inb = lsc->sc_inbstart 224 = NULL; 225 lsc->sc_inb_nbytes = lsc->sc_outb_nbytes = 0; 226 227 /* Last configuration step: set mode to standard mode */ 228 if (pi1ppc_setmode(&(lsc->sc_dev), PPBUS_COMPATIBLE) != 0) { 229 PI1PPC_DPRINTF(("%s: unable to initialize mode.\n", 230 lsc->sc_dev.dv_xname)); 231 } 232 233 #if defined (MULTIPROCESSOR) || defined (LOCKDEBUG) 234 /* Initialize lock structure */ 235 simple_lock_init(&(lsc->sc_lock)); 236 #endif 237 238 /* Set up parport_adapter structure */ 239 240 /* Set capabilites */ 241 sc_parport_adapter.capabilities = 0; 242 if (lsc->sc_has & PI1PPC_HAS_INTR) { 243 sc_parport_adapter.capabilities |= PPBUS_HAS_INTR; 244 } 245 if (lsc->sc_has & PI1PPC_HAS_DMA) { 246 sc_parport_adapter.capabilities |= PPBUS_HAS_DMA; 247 } 248 if (lsc->sc_has & PI1PPC_HAS_FIFO) { 249 sc_parport_adapter.capabilities |= PPBUS_HAS_FIFO; 250 } 251 if (lsc->sc_has & PI1PPC_HAS_PS2) { 252 sc_parport_adapter.capabilities |= PPBUS_HAS_PS2; 253 } 254 255 /* Set function pointers */ 256 sc_parport_adapter.parport_io = pi1ppc_io; 257 sc_parport_adapter.parport_exec_microseq = pi1ppc_exec_microseq; 258 sc_parport_adapter.parport_setmode = pi1ppc_setmode; 259 sc_parport_adapter.parport_getmode = pi1ppc_getmode; 260 sc_parport_adapter.parport_read = pi1ppc_read; 261 sc_parport_adapter.parport_write = pi1ppc_write; 262 sc_parport_adapter.parport_read_ivar = pi1ppc_read_ivar; 263 sc_parport_adapter.parport_write_ivar = pi1ppc_write_ivar; 264 sc_parport_adapter.parport_dma_malloc = lsc->sc_dma_malloc; 265 sc_parport_adapter.parport_dma_free = lsc->sc_dma_free; 266 sc_parport_adapter.parport_add_handler = pi1ppc_add_handler; 267 sc_parport_adapter.parport_remove_handler = pi1ppc_remove_handler; 268 269 /* these are no-ops (does later machines have ECP/EPP support?) */ 270 sc_parport_adapter.parport_ecp_sync = pi1ppc_ecp_sync; 271 sc_parport_adapter.parport_reset_epp_timeout = 272 pi1ppc_reset_epp_timeout; 273 274 /* Initialize handler list, may be added to by grandchildren */ 275 SLIST_INIT(&(lsc->sc_handler_listhead)); 276 277 /* Initialize interrupt state */ 278 lsc->sc_irqstat = PI1PPC_IRQ_NONE; 279 lsc->sc_ecr_intr = lsc->sc_ctr_intr = lsc->sc_str_intr = 0; 280 281 /* Disable DMA/interrupts (each ppbus driver selects usage itself) */ 282 lsc->sc_use = 0; 283 284 /* Configure child of the device. */ 285 lsc->child = config_found(&(lsc->sc_dev), &(sc_parport_adapter), 286 pi1ppc_print); 287 288 return; 289 } 290 291 /* Soft configuration detach */ 292 int 293 pi1ppc_sc_detach(struct pi1ppc_softc *lsc, int flag) 294 { 295 struct device *dev = (struct device *)lsc; 296 297 /* Detach children devices */ 298 if (config_detach(lsc->child, flag) && !(flag & DETACH_QUIET)) { 299 printf("%s not able to detach child device, ", dev->dv_xname); 300 301 if (!(flag & DETACH_FORCE)) { 302 printf("cannot detach\n"); 303 return 1; 304 } else { 305 printf("continuing (DETACH_FORCE)\n"); 306 } 307 } 308 309 if (!(flag & DETACH_QUIET)) 310 printf("%s detached", dev->dv_xname); 311 312 return 0; 313 } 314 315 /* Used by config_found() to print out device information */ 316 static int 317 pi1ppc_print(void *aux, const char *name) 318 { 319 /* Print out something on failure. */ 320 if (name != NULL) { 321 printf("%s: child devices", name); 322 return UNCONF; 323 } 324 325 return QUIET; 326 } 327 328 /* Interrupt handler for pi1ppc device: wakes up read/write functions */ 329 int 330 pi1ppcintr(void *arg) 331 { 332 /* NO INTERRUPTS YET */ 333 #if 0 334 struct pi1ppc_softc *pi1ppc = (struct pi1ppc_softc *)arg; 335 struct device *dev = &pi1ppc->sc_dev; 336 int claim = 1; 337 enum { NONE, READER, WRITER } wake_up = NONE; 338 int s; 339 340 s = splpi1ppc(); 341 PI1PPC_LOCK(pi1ppc); 342 343 /* Record registers' status */ 344 pi1ppc->sc_str_intr = pi1ppc_r_str(pi1ppc); 345 pi1ppc->sc_ctr_intr = pi1ppc_r_ctr(pi1ppc); 346 pi1ppc_barrier_r(pi1ppc); 347 348 /* Determine cause of interrupt and wake up top half */ 349 switch (atppc->sc_mode) { 350 case ATPPC_MODE_STD: 351 /* nAck pulsed for 5 usec, too fast to check reliably, assume */ 352 atppc->sc_irqstat = ATPPC_IRQ_nACK; 353 if (atppc->sc_outb) 354 wake_up = WRITER; 355 else 356 claim = 0; 357 break; 358 359 case ATPPC_MODE_NIBBLE: 360 case ATPPC_MODE_PS2: 361 /* nAck is set low by device and then high on ack */ 362 if (!(atppc->sc_str_intr & nACK)) { 363 claim = 0; 364 break; 365 } 366 atppc->sc_irqstat = ATPPC_IRQ_nACK; 367 if (atppc->sc_inb) 368 wake_up = READER; 369 break; 370 371 case ATPPC_MODE_ECP: 372 case ATPPC_MODE_FAST: 373 /* Confirm interrupt cause: these are not pulsed as in nAck. */ 374 if (atppc->sc_ecr_intr & ATPPC_SERVICE_INTR) { 375 if (atppc->sc_ecr_intr & ATPPC_ENABLE_DMA) 376 atppc->sc_irqstat |= ATPPC_IRQ_DMA; 377 else 378 atppc->sc_irqstat |= ATPPC_IRQ_FIFO; 379 380 /* Decide where top half will be waiting */ 381 if (atppc->sc_mode & ATPPC_MODE_ECP) { 382 if (atppc->sc_ctr_intr & PCD) { 383 if (atppc->sc_inb) 384 wake_up = READER; 385 else 386 claim = 0; 387 } else { 388 if (atppc->sc_outb) 389 wake_up = WRITER; 390 else 391 claim = 0; 392 } 393 } else { 394 if (atppc->sc_outb) 395 wake_up = WRITER; 396 else 397 claim = 0; 398 } 399 } 400 /* Determine if nFault has occurred */ 401 if ((atppc->sc_mode & ATPPC_MODE_ECP) && 402 (atppc->sc_ecr_intr & ATPPC_nFAULT_INTR) && 403 !(atppc->sc_str_intr & nFAULT)) { 404 405 /* Device is requesting the channel */ 406 atppc->sc_irqstat |= ATPPC_IRQ_nFAULT; 407 claim = 1; 408 } 409 break; 410 411 case ATPPC_MODE_EPP: 412 /* nAck pulsed for 5 usec, too fast to check reliably */ 413 atppc->sc_irqstat = ATPPC_IRQ_nACK; 414 if (atppc->sc_inb) 415 wake_up = WRITER; 416 else if (atppc->sc_outb) 417 wake_up = READER; 418 else 419 claim = 0; 420 break; 421 422 default: 423 panic("%s: chipset is in invalid mode.", dev->dv_xname); 424 } 425 426 if (claim) { 427 switch (wake_up) { 428 case NONE: 429 break; 430 431 case READER: 432 wakeup(atppc->sc_inb); 433 break; 434 435 case WRITER: 436 wakeup(atppc->sc_outb); 437 break; 438 } 439 } 440 441 PI1PPC_UNLOCK(atppc); 442 443 /* Call all of the installed handlers */ 444 if (claim) { 445 struct atppc_handler_node * callback; 446 SLIST_FOREACH(callback, &(atppc->sc_handler_listhead), 447 entries) { 448 (*callback->func)(callback->arg); 449 } 450 } 451 452 splx(s); 453 454 return claim; 455 #else 456 return 0; /* NO INTERRUPTS YET */ 457 #endif 458 } 459 460 /* Functions which support ppbus interface */ 461 462 static void 463 pi1ppc_reset_epp_timeout(struct device *dev) 464 { 465 return; 466 } 467 468 /* Read from pi1ppc device: returns 0 on success. */ 469 static int 470 pi1ppc_read(struct device *dev, char *buf, int len, int ioflag, 471 size_t *cnt) 472 { 473 struct pi1ppc_softc *pi1ppc = (struct pi1ppc_softc *)dev; 474 int error = 0; 475 int s; 476 477 s = splpi1ppc(); 478 PI1PPC_LOCK(pi1ppc); 479 480 *cnt = 0; 481 482 /* Initialize buffer */ 483 pi1ppc->sc_inb = pi1ppc->sc_inbstart = buf; 484 pi1ppc->sc_inb_nbytes = len; 485 486 /* Initialize device input error state for new operation */ 487 pi1ppc->sc_inerr = 0; 488 489 /* Call appropriate function to read bytes */ 490 switch(pi1ppc->sc_mode) { 491 case PI1PPC_MODE_STD: 492 error = ENODEV; 493 break; 494 495 case PI1PPC_MODE_NIBBLE: 496 pi1ppc_nibble_read(pi1ppc); 497 break; 498 499 case PI1PPC_MODE_PS2: 500 pi1ppc_byte_read(pi1ppc); 501 break; 502 503 default: 504 panic("%s(%s): chipset in invalid mode.\n", __func__, 505 dev->dv_xname); 506 } 507 508 /* Update counter*/ 509 *cnt = (pi1ppc->sc_inbstart - pi1ppc->sc_inb); 510 511 /* Reset buffer */ 512 pi1ppc->sc_inb = pi1ppc->sc_inbstart = NULL; 513 pi1ppc->sc_inb_nbytes = 0; 514 515 if (!(error)) 516 error = pi1ppc->sc_inerr; 517 518 PI1PPC_UNLOCK(pi1ppc); 519 splx(s); 520 521 return (error); 522 } 523 524 /* Write to pi1ppc device: returns 0 on success. */ 525 static int 526 pi1ppc_write(struct device *dev, char *buf, int len, int ioflag, size_t *cnt) 527 { 528 struct pi1ppc_softc * const pi1ppc = (struct pi1ppc_softc *)dev; 529 int error = 0; 530 int s; 531 532 *cnt = 0; 533 534 s = splpi1ppc(); 535 PI1PPC_LOCK(pi1ppc); 536 537 /* Set up line buffer */ 538 pi1ppc->sc_outb = pi1ppc->sc_outbstart = buf; 539 pi1ppc->sc_outb_nbytes = len; 540 541 /* Initialize device output error state for new operation */ 542 pi1ppc->sc_outerr = 0; 543 544 /* Call appropriate function to write bytes */ 545 switch (pi1ppc->sc_mode) { 546 case PI1PPC_MODE_STD: 547 pi1ppc_std_write(pi1ppc); 548 break; 549 550 case PI1PPC_MODE_NIBBLE: 551 case PI1PPC_MODE_PS2: 552 error = ENODEV; 553 break; 554 555 default: 556 panic("%s(%s): chipset in invalid mode.\n", __func__, 557 dev->dv_xname); 558 } 559 560 /* Update counter*/ 561 *cnt = (pi1ppc->sc_outbstart - pi1ppc->sc_outb); 562 563 /* Reset output buffer */ 564 pi1ppc->sc_outb = pi1ppc->sc_outbstart = NULL; 565 pi1ppc->sc_outb_nbytes = 0; 566 567 if (!(error)) 568 error = pi1ppc->sc_outerr; 569 570 PI1PPC_UNLOCK(pi1ppc); 571 splx(s); 572 573 return (error); 574 } 575 576 /* 577 * Set mode of chipset to mode argument. Modes not supported are ignored. If 578 * multiple modes are flagged, the mode is not changed. Modes are those 579 * defined for ppbus_softc.sc_mode in ppbus_conf.h. Only ECP-capable chipsets 580 * can change their mode of operation. However, ALL operation modes support 581 * centronics mode and nibble mode. Modes determine both hardware AND software 582 * behaviour. 583 * NOTE: the mode for ECP should only be changed when the channel is in 584 * forward idle mode. This function does not make sure FIFO's have flushed or 585 * any consistency checks. 586 */ 587 static int 588 pi1ppc_setmode(struct device *dev, int mode) 589 { 590 struct pi1ppc_softc *pi1ppc = (struct pi1ppc_softc *)dev; 591 u_int8_t ecr; 592 u_int8_t chipset_mode; 593 int s; 594 int rval = 0; 595 596 s = splpi1ppc(); 597 PI1PPC_LOCK(pi1ppc); 598 599 switch (mode) { 600 case PPBUS_PS2: 601 /* Indy has this, other PI1 machines do too? */ 602 chipset_mode = PI1PPC_MODE_PS2; 603 break; 604 605 case PPBUS_NIBBLE: 606 /* Set nibble mode (virtual) */ 607 chipset_mode = PI1PPC_MODE_NIBBLE; 608 break; 609 610 case PPBUS_COMPATIBLE: 611 chipset_mode = PI1PPC_MODE_STD; 612 break; 613 614 case PPBUS_ECP: 615 case PPBUS_EPP: 616 rval = ENODEV; 617 goto end; 618 619 default: 620 PI1PPC_DPRINTF(("%s(%s): invalid mode passed as " 621 "argument.\n", __func__, dev->dv_xname)); 622 rval = ENODEV; 623 goto end; 624 } 625 626 pi1ppc->sc_mode = chipset_mode; 627 if (chipset_mode == PI1PPC_MODE_PS2) { 628 /* Set direction bit to reverse */ 629 ecr = pi1ppc_r_ctr(pi1ppc); 630 pi1ppc_barrier_r(pi1ppc); 631 ecr |= PCD; /* data is INPUT */ 632 pi1ppc_w_ctr(pi1ppc, ecr); 633 pi1ppc_barrier_w(pi1ppc); 634 } 635 636 end: 637 PI1PPC_UNLOCK(pi1ppc); 638 splx(s); 639 640 return rval; 641 } 642 643 /* Get the current mode of chipset */ 644 static int 645 pi1ppc_getmode(struct device *dev) 646 { 647 struct pi1ppc_softc *pi1ppc = (struct pi1ppc_softc *)dev; 648 int mode; 649 int s; 650 651 s = splpi1ppc(); 652 PI1PPC_LOCK(pi1ppc); 653 654 /* The chipset can only be in one mode at a time logically */ 655 switch (pi1ppc->sc_mode) { 656 case PI1PPC_MODE_PS2: 657 mode = PPBUS_PS2; 658 break; 659 660 case PI1PPC_MODE_STD: 661 mode = PPBUS_COMPATIBLE; 662 break; 663 664 case PI1PPC_MODE_NIBBLE: 665 mode = PPBUS_NIBBLE; 666 break; 667 668 default: 669 panic("%s(%s): device is in invalid mode!", __func__, 670 dev->dv_xname); 671 break; 672 } 673 674 PI1PPC_UNLOCK(pi1ppc); 675 splx(s); 676 677 return mode; 678 } 679 680 681 /* Wait for FIFO buffer to empty for ECP-capable chipset */ 682 static void 683 pi1ppc_ecp_sync(struct device *dev) 684 { 685 return; 686 } 687 688 /* Execute a microsequence to handle fast I/O operations. */ 689 690 /* microsequence registers are equivalent to PC-like port registers */ 691 /* therefore, translate bit positions & polarities */ 692 693 /* Bit 4 of ctl_reg_int_en is used to emulate the PC's int enable 694 bit. Without it, lpt doesn't like the port. 695 */ 696 static u_int8_t ctl_reg_int_en = 0; 697 698 static u_int8_t 699 r_reg(int reg, struct pi1ppc_softc *pi1ppc) 700 { 701 int val = 0; 702 703 /* if we read the status reg, make it look like the PC */ 704 if(reg == AT_STAT_REG) { 705 val = bus_space_read_4((pi1ppc)->sc_iot, 706 (pi1ppc)->sc_ioh, IOC_PLP_STAT); 707 val &= 0xff; 708 709 /* invert /BUSY */ 710 val ^= 0x80; 711 712 /* bit 2 reads as '1' on Indy (why?) */ 713 val &= 0xf8; 714 715 return val; 716 } 717 718 /* if we read the ctl reg, make it look like the PC */ 719 if(reg == AT_CTL_REG) { 720 val = bus_space_read_4((pi1ppc)->sc_iot, 721 (pi1ppc)->sc_ioh, IOC_PLP_CTL); 722 val &= 0xff; 723 724 /* get the dir bit in the right place */ 725 val = ((val >> 1) & 0x20) | (val & 0x0f); 726 727 /* invert /SEL, /AUTOFD, and /STB */ 728 val ^= 0x0b; 729 730 /* emulate the PC's int enable ctl bit */ 731 val |= (ctl_reg_int_en & 0x10); 732 733 return val; 734 } 735 736 if(reg == AT_DATA_REG) { 737 val = bus_space_read_4((pi1ppc)->sc_iot, 738 (pi1ppc)->sc_ioh, IOC_PLP_DATA); 739 val &= 0xff; 740 741 return val; 742 } 743 744 return 0; 745 } 746 747 static void 748 w_reg(int reg, struct pi1ppc_softc *pi1ppc, u_int8_t byte) 749 { 750 /* don't try to write to the status reg */ 751 752 /* if we are writing the ctl reg, adjust PC style -> IOC style */ 753 if(reg == AT_CTL_REG) { 754 /* preserve pc-style int enable bit */ 755 ctl_reg_int_en = (byte & 0x10); 756 757 /* get the dir bit in the right place */ 758 byte = ((byte << 1) & 0x40) | (byte & 0x0f); 759 760 /* invert /SEL, /AUTOFD, and /STB */ 761 byte ^= 0x0b; 762 763 bus_space_write_4((pi1ppc)->sc_iot, 764 (pi1ppc)->sc_ioh, IOC_PLP_CTL, byte); 765 } 766 767 if(reg == AT_DATA_REG) { 768 bus_space_write_4((pi1ppc)->sc_iot, 769 (pi1ppc)->sc_ioh, IOC_PLP_DATA, byte); 770 } 771 } 772 773 static int 774 pi1ppc_exec_microseq(struct device *dev, struct ppbus_microseq **p_msq) 775 { 776 struct pi1ppc_softc *pi1ppc = (struct pi1ppc_softc *)dev; 777 struct ppbus_microseq *mi = *p_msq; 778 char cc, *p; 779 int i, iter, len; 780 int error; 781 int s; 782 register int reg; 783 register unsigned char mask; 784 register int accum = 0; 785 register char *ptr = NULL; 786 struct ppbus_microseq *stack = NULL; 787 788 s = splpi1ppc(); 789 PI1PPC_LOCK(pi1ppc); 790 791 /* Loop until microsequence execution finishes (ending op code) */ 792 for (;;) { 793 switch (mi->opcode) { 794 case MS_OP_RSET: 795 cc = r_reg(mi->arg[0].i, pi1ppc); 796 pi1ppc_barrier_r(pi1ppc); 797 cc &= (char)mi->arg[2].i; /* clear mask */ 798 cc |= (char)mi->arg[1].i; /* assert mask */ 799 w_reg(mi->arg[0].i, pi1ppc, cc); 800 pi1ppc_barrier_w(pi1ppc); 801 mi++; 802 break; 803 804 case MS_OP_RASSERT_P: 805 reg = mi->arg[1].i; 806 ptr = pi1ppc->sc_ptr; 807 808 if ((len = mi->arg[0].i) == MS_ACCUM) { 809 accum = pi1ppc->sc_accum; 810 for (; accum; accum--) { 811 w_reg(reg, pi1ppc, *ptr++); 812 pi1ppc_barrier_w(pi1ppc); 813 } 814 pi1ppc->sc_accum = accum; 815 } else { 816 for (i = 0; i < len; i++) { 817 w_reg(reg, pi1ppc, *ptr++); 818 pi1ppc_barrier_w(pi1ppc); 819 } 820 } 821 822 pi1ppc->sc_ptr = ptr; 823 mi++; 824 break; 825 826 case MS_OP_RFETCH_P: 827 reg = mi->arg[1].i; 828 mask = (char)mi->arg[2].i; 829 ptr = pi1ppc->sc_ptr; 830 831 if ((len = mi->arg[0].i) == MS_ACCUM) { 832 accum = pi1ppc->sc_accum; 833 for (; accum; accum--) { 834 *ptr++ = r_reg(reg, pi1ppc) & mask; 835 pi1ppc_barrier_r(pi1ppc); 836 } 837 pi1ppc->sc_accum = accum; 838 } else { 839 for (i = 0; i < len; i++) { 840 *ptr++ = r_reg(reg, pi1ppc) & mask; 841 pi1ppc_barrier_r(pi1ppc); 842 } 843 } 844 845 pi1ppc->sc_ptr = ptr; 846 mi++; 847 break; 848 849 case MS_OP_RFETCH: 850 *((char *)mi->arg[2].p) = r_reg(mi->arg[0].i, pi1ppc) & 851 (char)mi->arg[1].i; 852 pi1ppc_barrier_r(pi1ppc); 853 mi++; 854 break; 855 856 case MS_OP_RASSERT: 857 case MS_OP_DELAY: 858 /* let's suppose the next instr. is the same */ 859 do { 860 for (;mi->opcode == MS_OP_RASSERT; mi++) { 861 w_reg(mi->arg[0].i, pi1ppc, 862 (char)mi->arg[1].i); 863 pi1ppc_barrier_w(pi1ppc); 864 } 865 866 for (;mi->opcode == MS_OP_DELAY; mi++) { 867 delay(mi->arg[0].i); 868 } 869 } while (mi->opcode == MS_OP_RASSERT); 870 break; 871 872 case MS_OP_ADELAY: 873 if (mi->arg[0].i) { 874 tsleep(pi1ppc, PPBUSPRI, "pi1ppcdelay", 875 mi->arg[0].i * (hz/1000)); 876 } 877 mi++; 878 break; 879 880 case MS_OP_TRIG: 881 reg = mi->arg[0].i; 882 iter = mi->arg[1].i; 883 p = (char *)mi->arg[2].p; 884 885 /* XXX delay limited to 255 us */ 886 for (i = 0; i < iter; i++) { 887 w_reg(reg, pi1ppc, *p++); 888 pi1ppc_barrier_w(pi1ppc); 889 delay((unsigned char)*p++); 890 } 891 892 mi++; 893 break; 894 895 case MS_OP_SET: 896 pi1ppc->sc_accum = mi->arg[0].i; 897 mi++; 898 break; 899 900 case MS_OP_DBRA: 901 if (--pi1ppc->sc_accum > 0) { 902 mi += mi->arg[0].i; 903 } 904 905 mi++; 906 break; 907 908 case MS_OP_BRSET: 909 cc = pi1ppc_r_str(pi1ppc); 910 pi1ppc_barrier_r(pi1ppc); 911 if ((cc & (char)mi->arg[0].i) == (char)mi->arg[0].i) { 912 mi += mi->arg[1].i; 913 } 914 mi++; 915 break; 916 917 case MS_OP_BRCLEAR: 918 cc = pi1ppc_r_str(pi1ppc); 919 pi1ppc_barrier_r(pi1ppc); 920 if ((cc & (char)mi->arg[0].i) == 0) { 921 mi += mi->arg[1].i; 922 } 923 mi++; 924 break; 925 926 case MS_OP_BRSTAT: 927 cc = pi1ppc_r_str(pi1ppc); 928 pi1ppc_barrier_r(pi1ppc); 929 if ((cc & ((char)mi->arg[0].i | (char)mi->arg[1].i)) == 930 (char)mi->arg[0].i) { 931 mi += mi->arg[2].i; 932 } 933 mi++; 934 break; 935 936 case MS_OP_C_CALL: 937 /* 938 * If the C call returns !0 then end the microseq. 939 * The current state of ptr is passed to the C function 940 */ 941 if ((error = mi->arg[0].f(mi->arg[1].p, 942 pi1ppc->sc_ptr))) { 943 PI1PPC_UNLOCK(pi1ppc); 944 splx(s); 945 return (error); 946 } 947 mi++; 948 break; 949 950 case MS_OP_PTR: 951 pi1ppc->sc_ptr = (char *)mi->arg[0].p; 952 mi++; 953 break; 954 955 case MS_OP_CALL: 956 if (stack) { 957 panic("%s - %s: too many calls", dev->dv_xname, 958 __func__); 959 } 960 961 if (mi->arg[0].p) { 962 /* store state of the actual microsequence */ 963 stack = mi; 964 965 /* jump to the new microsequence */ 966 mi = (struct ppbus_microseq *)mi->arg[0].p; 967 } else { 968 mi++; 969 } 970 break; 971 972 case MS_OP_SUBRET: 973 /* retrieve microseq and pc state before the call */ 974 mi = stack; 975 976 /* reset the stack */ 977 stack = 0; 978 979 /* XXX return code */ 980 981 mi++; 982 break; 983 984 case MS_OP_PUT: 985 case MS_OP_GET: 986 case MS_OP_RET: 987 /* 988 * Can't return to pi1ppc level during the execution 989 * of a submicrosequence. 990 */ 991 if (stack) { 992 panic("%s: cannot return to pi1ppc level", 993 __func__); 994 } 995 /* update pc for pi1ppc level of execution */ 996 *p_msq = mi; 997 998 PI1PPC_UNLOCK(pi1ppc); 999 splx(s); 1000 return (0); 1001 break; 1002 1003 default: 1004 panic("%s: unknown microsequence " 1005 "opcode 0x%x", __func__, mi->opcode); 1006 break; 1007 } 1008 } 1009 1010 /* Should not be reached! */ 1011 #ifdef PI1PPC_DEBUG 1012 panic("%s: unexpected code reached!\n", __func__); 1013 #endif 1014 } 1015 1016 /* General I/O routine */ 1017 static u_int8_t 1018 pi1ppc_io(struct device *dev, int iop, u_char *addr, int cnt, u_char byte) 1019 { 1020 struct pi1ppc_softc *pi1ppc = (struct pi1ppc_softc *)dev; 1021 u_int8_t val = 0; 1022 int s; 1023 1024 s = splpi1ppc(); 1025 PI1PPC_LOCK(pi1ppc); 1026 1027 switch (iop) { 1028 case PPBUS_RDTR: 1029 val = r_reg(AT_DATA_REG, pi1ppc); 1030 break; 1031 case PPBUS_RSTR: 1032 val = r_reg(AT_STAT_REG, pi1ppc); 1033 break; 1034 case PPBUS_RCTR: 1035 val = r_reg(AT_CTL_REG, pi1ppc); 1036 break; 1037 case PPBUS_WDTR: 1038 w_reg(AT_DATA_REG, pi1ppc, byte); 1039 break; 1040 case PPBUS_WSTR: 1041 /* writing to the status register is weird */ 1042 break; 1043 case PPBUS_WCTR: 1044 w_reg(AT_CTL_REG, pi1ppc, byte); 1045 break; 1046 default: 1047 panic("%s(%s): unknown I/O operation", dev->dv_xname, 1048 __func__); 1049 break; 1050 } 1051 1052 pi1ppc_barrier(pi1ppc); 1053 1054 PI1PPC_UNLOCK(pi1ppc); 1055 splx(s); 1056 1057 return val; 1058 } 1059 1060 /* Read "instance variables" of pi1ppc device */ 1061 static int 1062 pi1ppc_read_ivar(struct device *dev, int index, unsigned int *val) 1063 { 1064 struct pi1ppc_softc *pi1ppc = (struct pi1ppc_softc *)dev; 1065 int rval = 0; 1066 int s; 1067 1068 s = splpi1ppc(); 1069 PI1PPC_LOCK(pi1ppc); 1070 1071 switch(index) { 1072 case PPBUS_IVAR_INTR: 1073 *val = ((pi1ppc->sc_use & PI1PPC_USE_INTR) != 0); 1074 break; 1075 1076 case PPBUS_IVAR_DMA: 1077 *val = ((pi1ppc->sc_use & PI1PPC_USE_DMA) != 0); 1078 break; 1079 1080 default: 1081 rval = ENODEV; 1082 } 1083 1084 PI1PPC_UNLOCK(pi1ppc); 1085 splx(s); 1086 1087 return rval; 1088 } 1089 1090 /* Write "instance varaibles" of pi1ppc device */ 1091 static int 1092 pi1ppc_write_ivar(struct device *dev, int index, unsigned int *val) 1093 { 1094 struct pi1ppc_softc *pi1ppc = (struct pi1ppc_softc *)dev; 1095 int rval = 0; 1096 int s; 1097 1098 s = splpi1ppc(); 1099 PI1PPC_LOCK(pi1ppc); 1100 1101 switch(index) { 1102 case PPBUS_IVAR_INTR: 1103 if (*val == 0) 1104 pi1ppc->sc_use &= ~PI1PPC_USE_INTR; 1105 else if (pi1ppc->sc_has & PI1PPC_HAS_INTR) 1106 pi1ppc->sc_use |= PI1PPC_USE_INTR; 1107 else 1108 rval = ENODEV; 1109 break; 1110 1111 case PPBUS_IVAR_DMA: 1112 if (*val == 0) 1113 pi1ppc->sc_use &= ~PI1PPC_USE_DMA; 1114 else if (pi1ppc->sc_has & PI1PPC_HAS_DMA) 1115 pi1ppc->sc_use |= PI1PPC_USE_DMA; 1116 else 1117 rval = ENODEV; 1118 break; 1119 1120 default: 1121 rval = ENODEV; 1122 } 1123 1124 PI1PPC_UNLOCK(pi1ppc); 1125 splx(s); 1126 1127 return rval; 1128 } 1129 1130 /* Add a handler routine to be called by the interrupt handler */ 1131 static int 1132 pi1ppc_add_handler(struct device *dev, void (*handler)(void *), void *arg) 1133 { 1134 struct pi1ppc_softc *pi1ppc = (struct pi1ppc_softc *)dev; 1135 struct pi1ppc_handler_node *callback; 1136 int rval = 0; 1137 int s; 1138 1139 s = splpi1ppc(); 1140 PI1PPC_LOCK(pi1ppc); 1141 1142 if (handler == NULL) { 1143 PI1PPC_DPRINTF(("%s(%s): attempt to register NULL handler.\n", 1144 __func__, dev->dv_xname)); 1145 rval = EINVAL; 1146 } else { 1147 callback = malloc(sizeof(struct pi1ppc_handler_node), M_DEVBUF, 1148 M_NOWAIT); 1149 if (callback) { 1150 callback->func = handler; 1151 callback->arg = arg; 1152 SLIST_INSERT_HEAD(&(pi1ppc->sc_handler_listhead), 1153 callback, entries); 1154 } else { 1155 rval = ENOMEM; 1156 } 1157 } 1158 1159 PI1PPC_UNLOCK(pi1ppc); 1160 splx(s); 1161 1162 return rval; 1163 } 1164 1165 /* Remove a handler added by pi1ppc_add_handler() */ 1166 static int 1167 pi1ppc_remove_handler(struct device *dev, void (*handler)(void *)) 1168 { 1169 struct pi1ppc_softc *pi1ppc = (struct pi1ppc_softc *)dev; 1170 struct pi1ppc_handler_node *callback; 1171 int rval = EINVAL; 1172 int s; 1173 1174 s = splpi1ppc(); 1175 PI1PPC_LOCK(pi1ppc); 1176 1177 if (SLIST_EMPTY(&(pi1ppc->sc_handler_listhead))) 1178 panic("%s(%s): attempt to remove handler from empty list.\n", 1179 __func__, dev->dv_xname); 1180 1181 /* Search list for handler */ 1182 SLIST_FOREACH(callback, &(pi1ppc->sc_handler_listhead), entries) { 1183 if (callback->func == handler) { 1184 SLIST_REMOVE(&(pi1ppc->sc_handler_listhead), callback, 1185 pi1ppc_handler_node, entries); 1186 free(callback, M_DEVBUF); 1187 rval = 0; 1188 break; 1189 } 1190 } 1191 1192 PI1PPC_UNLOCK(pi1ppc); 1193 splx(s); 1194 1195 return rval; 1196 } 1197 1198 /* Utility functions */ 1199 1200 /* 1201 * Functions that read bytes from port into buffer: called from interrupt 1202 * handler depending on current chipset mode and cause of interrupt. Return 1203 * value: number of bytes moved. 1204 */ 1205 1206 /* note: BUSY is inverted in the PC world, but not on Indy, but the r_reg() 1207 and w_reg() functions make the Indy look like the PC. */ 1208 1209 /* Only the lower 4 bits of the final value are valid */ 1210 #define nibble2char(s) ((((s) & ~nACK) >> 3) | (~(s) & nBUSY) >> 4) 1211 1212 1213 /* Read bytes in nibble mode */ 1214 static void 1215 pi1ppc_nibble_read(struct pi1ppc_softc *pi1ppc) 1216 { 1217 int i; 1218 u_int8_t nibble[2]; 1219 u_int8_t ctr; 1220 u_int8_t str; 1221 1222 /* Enable interrupts if needed */ 1223 if (pi1ppc->sc_use & PI1PPC_USE_INTR) { 1224 1225 /* XXX JOE - need code to enable interrupts 1226 --> emulate PC behavior in r_reg/w_reg 1227 */ 1228 #if 0 1229 ctr = pi1ppc_r_ctr(pi1ppc); 1230 pi1ppc_barrier_r(ioppc); 1231 if (!(ctr & IRQENABLE)) { 1232 ctr |= IRQENABLE; 1233 pi1ppc_w_ctr(pi1ppc, ctr); 1234 pi1ppc_barrier_w(pi1ppc); 1235 } 1236 #endif 1237 } 1238 1239 while (pi1ppc->sc_inbstart < (pi1ppc->sc_inb + pi1ppc->sc_inb_nbytes)) { 1240 /* Check if device has data to send in idle phase */ 1241 str = pi1ppc_r_str(pi1ppc); 1242 pi1ppc_barrier_r(pi1ppc); 1243 if (str & nDATAVAIL) { 1244 return; 1245 } 1246 1247 /* Nibble-mode handshake transfer */ 1248 for (i = 0; i < 2; i++) { 1249 /* Event 7 - ready to take data (HOSTBUSY low) */ 1250 ctr = pi1ppc_r_ctr(pi1ppc); 1251 pi1ppc_barrier_r(pi1ppc); 1252 ctr |= HOSTBUSY; 1253 pi1ppc_w_ctr(pi1ppc, ctr); 1254 pi1ppc_barrier_w(pi1ppc); 1255 1256 /* Event 8 - peripheral writes the first nibble */ 1257 1258 /* Event 9 - peripheral set nAck low */ 1259 pi1ppc->sc_inerr = pi1ppc_poll_str(pi1ppc, 0, PTRCLK); 1260 if (pi1ppc->sc_inerr) 1261 return; 1262 1263 /* read nibble */ 1264 nibble[i] = pi1ppc_r_str(pi1ppc); 1265 1266 /* Event 10 - ack, nibble received */ 1267 ctr &= ~HOSTBUSY; 1268 pi1ppc_w_ctr(pi1ppc, ctr); 1269 1270 /* Event 11 - wait ack from peripherial */ 1271 if (pi1ppc->sc_use & PI1PPC_USE_INTR) 1272 pi1ppc->sc_inerr = pi1ppc_wait_interrupt(pi1ppc, 1273 pi1ppc->sc_inb, PI1PPC_IRQ_nACK); 1274 else 1275 pi1ppc->sc_inerr = pi1ppc_poll_str(pi1ppc, PTRCLK, 1276 PTRCLK); 1277 if (pi1ppc->sc_inerr) 1278 return; 1279 } 1280 1281 /* Store byte transfered */ 1282 *(pi1ppc->sc_inbstart) = ((nibble2char(nibble[1]) << 4) & 0xf0) | 1283 (nibble2char(nibble[0]) & 0x0f); 1284 pi1ppc->sc_inbstart++; 1285 } 1286 } 1287 1288 /* Read bytes in bidirectional mode */ 1289 static void 1290 pi1ppc_byte_read(struct pi1ppc_softc * const pi1ppc) 1291 { 1292 u_int8_t ctr; 1293 u_int8_t str; 1294 1295 /* Check direction bit */ 1296 ctr = pi1ppc_r_ctr(pi1ppc); 1297 pi1ppc_barrier_r(pi1ppc); 1298 if (!(ctr & PCD)) { 1299 PI1PPC_DPRINTF(("%s: byte-mode read attempted without direction " 1300 "bit set.", pi1ppc->sc_dev.dv_xname)); 1301 pi1ppc->sc_inerr = ENODEV; 1302 return; 1303 } 1304 /* Enable interrupts if needed */ 1305 1306 /* XXX JOE - need code to enable interrupts */ 1307 #if 0 1308 if (pi1ppc->sc_use & PI1PPC_USE_INTR) { 1309 if (!(ctr & IRQENABLE)) { 1310 ctr |= IRQENABLE; 1311 pi1ppc_w_ctr(pi1ppc, ctr); 1312 pi1ppc_barrier_w(pi1ppc); 1313 } 1314 } 1315 #endif 1316 1317 /* Byte-mode handshake transfer */ 1318 while (pi1ppc->sc_inbstart < (pi1ppc->sc_inb + pi1ppc->sc_inb_nbytes)) { 1319 /* Check if device has data to send */ 1320 str = pi1ppc_r_str(pi1ppc); 1321 pi1ppc_barrier_r(pi1ppc); 1322 if (str & nDATAVAIL) { 1323 return; 1324 } 1325 1326 /* Event 7 - ready to take data (nAUTO low) */ 1327 ctr |= HOSTBUSY; 1328 pi1ppc_w_ctr(pi1ppc, ctr); 1329 pi1ppc_barrier_w(pi1ppc); 1330 1331 /* Event 9 - peripheral set nAck low */ 1332 pi1ppc->sc_inerr = pi1ppc_poll_str(pi1ppc, 0, PTRCLK); 1333 if (pi1ppc->sc_inerr) 1334 return; 1335 1336 /* Store byte transfered */ 1337 *(pi1ppc->sc_inbstart) = pi1ppc_r_dtr(pi1ppc); 1338 pi1ppc_barrier_r(pi1ppc); 1339 1340 /* Event 10 - data received, can't accept more */ 1341 ctr &= ~HOSTBUSY; 1342 pi1ppc_w_ctr(pi1ppc, ctr); 1343 pi1ppc_barrier_w(pi1ppc); 1344 1345 /* Event 11 - peripheral ack */ 1346 if (pi1ppc->sc_use & PI1PPC_USE_INTR) 1347 pi1ppc->sc_inerr = pi1ppc_wait_interrupt(pi1ppc, 1348 pi1ppc->sc_inb, PI1PPC_IRQ_nACK); 1349 else 1350 pi1ppc->sc_inerr = pi1ppc_poll_str(pi1ppc, PTRCLK, PTRCLK); 1351 if (pi1ppc->sc_inerr) 1352 return; 1353 1354 /* Event 16 - strobe */ 1355 str |= HOSTCLK; 1356 pi1ppc_w_str(pi1ppc, str); 1357 pi1ppc_barrier_w(pi1ppc); 1358 DELAY(1); 1359 str &= ~HOSTCLK; 1360 pi1ppc_w_str(pi1ppc, str); 1361 pi1ppc_barrier_w(pi1ppc); 1362 1363 /* Update counter */ 1364 pi1ppc->sc_inbstart++; 1365 } 1366 } 1367 1368 /* 1369 * Functions that write bytes to port from buffer: called from pi1ppc_write() 1370 * function depending on current chipset mode. Returns number of bytes moved. 1371 */ 1372 1373 static void 1374 pi1ppc_set_intr_mask(struct pi1ppc_softc * const pi1ppc, u_int8_t mask) 1375 { 1376 /* invert valid bits (0 = enabled) */ 1377 mask = ~mask; 1378 mask &= 0xfc; 1379 1380 bus_space_write_4((pi1ppc)->sc_iot, (pi1ppc)->sc_ioh, IOC_PLP_INTMASK, mask); 1381 pi1ppc_barrier_w(pi1ppc); 1382 } 1383 1384 1385 #ifdef USE_INDY_ACK_HACK 1386 static u_int8_t 1387 pi1ppc_get_intr_mask(struct pi1ppc_softc * const pi1ppc) 1388 { 1389 int val; 1390 val = bus_space_read_4((pi1ppc)->sc_iot, (pi1ppc)->sc_ioh, IOC_PLP_INTMASK); 1391 pi1ppc_barrier_r(pi1ppc); 1392 1393 /* invert (0 = enabled) */ 1394 val = ~val; 1395 1396 return (val & 0xfc); 1397 } 1398 #endif 1399 1400 static u_int8_t 1401 pi1ppc_get_intr_stat(struct pi1ppc_softc * const pi1ppc) 1402 { 1403 int val; 1404 val = bus_space_read_4((pi1ppc)->sc_iot, (pi1ppc)->sc_ioh, IOC_PLP_INTSTAT); 1405 pi1ppc_barrier_r(pi1ppc); 1406 1407 return (val & 0xfc); 1408 } 1409 1410 /* Write bytes in std/bidirectional mode */ 1411 static void 1412 pi1ppc_std_write(struct pi1ppc_softc * const pi1ppc) 1413 { 1414 unsigned char ctr; 1415 1416 ctr = pi1ppc_r_ctr(pi1ppc); 1417 pi1ppc_barrier_r(pi1ppc); 1418 1419 /* Ensure that the data lines are in OUTPUT mode */ 1420 ctr &= ~PCD; 1421 pi1ppc_w_ctr(pi1ppc, ctr); 1422 pi1ppc_barrier_w(pi1ppc); 1423 1424 /* XXX JOE - need code to enable interrupts */ 1425 #if 0 1426 /* Enable interrupts if needed */ 1427 if (pi1ppc->sc_use & PI1PPC_USE_INTR) { 1428 if (!(ctr & IRQENABLE)) { 1429 ctr |= IRQENABLE; 1430 pi1ppc_w_ctr(pi1ppc, ctr); 1431 pi1ppc_barrier_w(pi1ppc); 1432 } 1433 } 1434 #endif 1435 1436 while (pi1ppc->sc_outbstart < (pi1ppc->sc_outb + pi1ppc->sc_outb_nbytes)) { 1437 1438 /* Wait for peripheral to become ready for MAXBUSYWAIT */ 1439 pi1ppc->sc_outerr = pi1ppc_poll_str(pi1ppc, SPP_READY, SPP_MASK); 1440 if (pi1ppc->sc_outerr) { 1441 printf("pi1ppc: timeout waiting for peripheral to become ready\n"); 1442 return; 1443 } 1444 1445 /* Put data in data register */ 1446 pi1ppc_w_dtr(pi1ppc, *(pi1ppc->sc_outbstart)); 1447 pi1ppc_barrier_w(pi1ppc); 1448 DELAY(1); 1449 1450 /* If no intr, prepare to catch the rising edge of nACK */ 1451 if (!(pi1ppc->sc_use & PI1PPC_USE_INTR)) { 1452 pi1ppc_get_intr_stat(pi1ppc); /* clear any pending intr */ 1453 pi1ppc_set_intr_mask(pi1ppc, PI1_PLP_ACK_INTR); 1454 } 1455 1456 /* Pulse strobe to indicate valid data on lines */ 1457 ctr |= STROBE; 1458 pi1ppc_w_ctr(pi1ppc, ctr); 1459 pi1ppc_barrier_w(pi1ppc); 1460 DELAY(1); 1461 ctr &= ~STROBE; 1462 pi1ppc_w_ctr(pi1ppc, ctr); 1463 pi1ppc_barrier_w(pi1ppc); 1464 1465 /* Wait for nACK for MAXBUSYWAIT */ 1466 if (pi1ppc->sc_use & PI1PPC_USE_INTR) { 1467 pi1ppc->sc_outerr = pi1ppc_wait_interrupt(pi1ppc, 1468 pi1ppc->sc_outb, PI1PPC_IRQ_nACK); 1469 if (pi1ppc->sc_outerr) 1470 return; 1471 } else { 1472 /* Try to catch the pulsed acknowledgement */ 1473 pi1ppc->sc_outerr = pi1ppc_poll_interrupt_stat(pi1ppc, 1474 PI1_PLP_ACK_INTR); 1475 1476 if (pi1ppc->sc_outerr) { 1477 printf("pi1ppc: timeout waiting for ACK: %02x\n",pi1ppc_r_str(pi1ppc)); 1478 return; 1479 } 1480 } 1481 1482 /* Update buffer position, byte count and counter */ 1483 pi1ppc->sc_outbstart++; 1484 } 1485 } 1486 1487 1488 /* 1489 * Poll status register using mask and status for MAXBUSYWAIT. 1490 * Returns 0 if device ready, error value otherwise. 1491 */ 1492 static int 1493 pi1ppc_poll_str(struct pi1ppc_softc * const pi1ppc, const u_int8_t status, 1494 const u_int8_t mask) 1495 { 1496 unsigned int timecount; 1497 u_int8_t str; 1498 int error = EIO; 1499 1500 /* Wait for str to have status for MAXBUSYWAIT */ 1501 for (timecount = 0; timecount < ((MAXBUSYWAIT/hz)*1000000); 1502 timecount++) { 1503 1504 str = pi1ppc_r_str(pi1ppc); 1505 pi1ppc_barrier_r(pi1ppc); 1506 if ((str & mask) == status) { 1507 error = 0; 1508 break; 1509 } 1510 DELAY(1); 1511 } 1512 1513 return error; 1514 } 1515 1516 /* Wait for interrupt for MAXBUSYWAIT: returns 0 if acknowledge received. */ 1517 static int 1518 pi1ppc_wait_interrupt(struct pi1ppc_softc * const pi1ppc, const caddr_t where, 1519 const u_int8_t irqstat) 1520 { 1521 int error = EIO; 1522 1523 pi1ppc->sc_irqstat &= ~irqstat; 1524 1525 /* Wait for interrupt for MAXBUSYWAIT */ 1526 error = ltsleep(where, PPBUSPRI | PCATCH, __func__, MAXBUSYWAIT, 1527 PI1PPC_SC_LOCK(pi1ppc)); 1528 1529 if (!(error) && (pi1ppc->sc_irqstat & irqstat)) { 1530 pi1ppc->sc_irqstat &= ~irqstat; 1531 error = 0; 1532 } 1533 1534 return error; 1535 } 1536 1537 /* 1538 INDY ACK HACK DESCRIPTION 1539 1540 There appears to be a bug in the Indy's PI1 hardware - it sometimes 1541 *misses* the rising edge of /ACK. Ugh! 1542 1543 (Also, unlike the other status bits, /ACK doesn't generate an 1544 interrupt on its falling edge.) 1545 1546 So, we do something kind of skanky here. We use a shorter timeout, 1547 and, if we timeout, we first check BUSY. If BUSY is high, we go 1548 back to waiting for /ACK (because maybe this really is just a slow 1549 peripheral). 1550 1551 If it's a normal printer, it will raise BUSY from when it sees our 1552 /STROBE until it raises its /ACK: 1553 _____ _____________________ 1554 /STB \_/ 1555 ________________ __________ 1556 /ACK \_/ 1557 ___________ 1558 BUSY ______/ \__________ 1559 1560 So, if we time out and see BUSY low, then we probably just missed 1561 the /ACK. 1562 1563 In that case, we then check /ERROR and SELECTIN. If both are hi, 1564 (the peripheral thinks it is selected, and is not asserting /ERROR) 1565 we assume that the Indy's parallel port missed the /ACK, and return 1566 success. 1567 */ 1568 1569 #ifdef USE_INDY_ACK_HACK 1570 #define ACK_TIMEOUT_SCALER 1000 1571 #else 1572 #define ACK_TIMEOUT_SCALER 1000000 1573 #endif 1574 1575 static int 1576 pi1ppc_poll_interrupt_stat(struct pi1ppc_softc * const pi1ppc, 1577 const u_int8_t match) 1578 { 1579 unsigned int timecount; 1580 u_int8_t cur; 1581 int error = EIO; 1582 1583 #ifdef USE_INDY_ACK_HACK 1584 /* retry 10000x */ 1585 int retry_count = 10000; 1586 1587 retry: 1588 #endif 1589 1590 /* Wait for intr status to have match bits set for MAXBUSYWAIT */ 1591 for (timecount = 0; timecount < ((MAXBUSYWAIT/hz)*ACK_TIMEOUT_SCALER); 1592 timecount++) { 1593 cur = pi1ppc_get_intr_stat(pi1ppc); 1594 if ((cur & match) == match) { 1595 error = 0; 1596 break; 1597 } 1598 DELAY(1); 1599 } 1600 1601 #ifdef USE_INDY_ACK_HACK 1602 if(error != 0) { 1603 cur = pi1ppc_r_str(pi1ppc); 1604 1605 /* retry if BUSY is hi (inverted, so lo) and we haven't 1606 waited the usual amt */ 1607 1608 if(((cur&nBUSY) == 0) && retry_count) { 1609 retry_count--; 1610 goto retry; 1611 } 1612 1613 /* if /ERROR and SELECT are high, and the peripheral isn't 1614 BUSY, assume that we just missed the /ACK. 1615 (Remember, we emulate the PC's inverted BUSY!) 1616 */ 1617 1618 if((cur&(nFAULT|SELECT|nBUSY)) == (nFAULT|SELECT|nBUSY)) 1619 error = 0; 1620 1621 /* if things still look bad, print out some info */ 1622 if(error!=0) 1623 printf("int mask=%02x, int stat=%02x, str=%02x\n", 1624 pi1ppc_get_intr_mask(pi1ppc), 1625 pi1ppc_get_intr_stat(pi1ppc), 1626 cur); 1627 } 1628 #endif 1629 1630 return error; 1631 } 1632 1633