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