1 /* $NetBSD: cpi_nubus.c,v 1.3 2008/06/11 23:54:45 cegger Exp $ */ 2 3 /*- 4 * Copyright (c) 2008 Hauke Fath 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 #include <sys/cdefs.h> 28 __KERNEL_RCSID(0, "$NetBSD: cpi_nubus.c,v 1.3 2008/06/11 23:54:45 cegger Exp $"); 29 30 #include <sys/param.h> 31 #include <sys/systm.h> 32 #include <sys/proc.h> 33 #include <sys/device.h> 34 #include <sys/malloc.h> 35 #include <sys/event.h> 36 #include <sys/callout.h> 37 #include <sys/conf.h> 38 #include <sys/file.h> 39 #include <sys/uio.h> 40 #include <sys/ioctl.h> 41 #include <sys/tty.h> 42 #include <sys/time.h> 43 #include <sys/kernel.h> 44 #include <sys/syslog.h> 45 #include <sys/errno.h> 46 47 #include <machine/intr.h> 48 #include <machine/bus.h> 49 #include <machine/viareg.h> 50 51 #include <dev/ic/z8536reg.h> 52 #include <mac68k/nubus/nubus.h> 53 #include <mac68k/nubus/cpi_nubusvar.h> 54 55 #include "ioconf.h" 56 57 #ifdef DEBUG 58 #define CPI_DEBUG 59 #endif 60 61 /* 62 * Stuff taken from Egan/Teixeira ch 8: 'if(TRACE_FOO)' debug output 63 * statements don't break indentation, and when DEBUG is not defined, 64 * the compiler code optimizer drops them as dead code. 65 */ 66 #ifdef CPI_DEBUG 67 #define M_TRACE_CONFIG 0x0001 68 #define M_TRACE_OPEN 0x0002 69 #define M_TRACE_CLOSE 0x0004 70 #define M_TRACE_READ 0x0008 71 #define M_TRACE_WRITE 0x0010 72 #define M_TRACE_IOCTL 0x0020 73 #define M_TRACE_STATUS 0x0040 74 #define M_TRACE_ALL 0xFFFF 75 #define M_TRACE_NONE 0x0000 76 77 #define TRACE_CONFIG (cpi_debug_mask & M_TRACE_CONFIG) 78 #define TRACE_OPEN (cpi_debug_mask & M_TRACE_OPEN) 79 #define TRACE_CLOSE (cpi_debug_mask & M_TRACE_CLOSE) 80 #define TRACE_READ (cpi_debug_mask & M_TRACE_READ) 81 #define TRACE_WRITE (cpi_debug_mask & M_TRACE_WRITE) 82 #define TRACE_IOCTL (cpi_debug_mask & M_TRACE_IOCTL) 83 #define TRACE_STATUS (cpi_debug_mask & M_TRACE_STATUS) 84 #define TRACE_ALL (cpi_debug_mask & M_TRACE_ALL) 85 #define TRACE_NONE (cpi_debug_mask & M_TRACE_NONE) 86 87 uint32_t cpi_debug_mask = M_TRACE_NONE /* |�M_TRACE_WRITE */ ; 88 89 #else 90 #define TRACE_CONFIG 0 91 #define TRACE_OPEN 0 92 #define TRACE_CLOSE 0 93 #define TRACE_READ 0 94 #define TRACE_WRITE 0 95 #define TRACE_IOCTL 0 96 #define TRACE_STATUS 0 97 #define TRACE_ALL 0 98 #define TRACE_NONE 0 99 #endif 100 101 #undef USE_CIO_TIMERS /* TBD */ 102 103 /* autoconf interface */ 104 int cpi_nubus_match(device_t, cfdata_t, void *); 105 void cpi_nubus_attach(device_t, device_t, void *); 106 void cpi_nubus_intr(void *); 107 108 CFATTACH_DECL(cpi, sizeof(struct cpi_softc), 109 cpi_nubus_match, cpi_nubus_attach, NULL, NULL); 110 111 dev_type_open(cpi_open); 112 dev_type_close(cpi_close); 113 dev_type_read(cpi_read); 114 dev_type_write(cpi_write); 115 dev_type_ioctl(cpi_ioctl); 116 117 const struct cdevsw cpi_cdevsw = { 118 cpi_open, cpi_close, noread, cpi_write, cpi_ioctl, 119 nostop, notty, nopoll, nommap, nokqfilter, D_OTHER 120 }; 121 122 /* prototypes */ 123 static void cpi_lpreset(struct cpi_softc *); 124 static int cpi_notready(struct cpi_softc *); 125 static void cpi_wakeup(void *); 126 static int cpi_flush(struct cpi_softc *); 127 static void cpi_intr(void *); 128 129 #ifdef USE_CIO_TIMERS 130 static void cpi_initclock(struct cpi_softc *); 131 static u_int cpi_get_timecount(struct timecounter *); 132 #endif 133 134 static inline void z8536_reg_set(bus_space_tag_t, bus_space_handle_t, 135 uint8_t, uint8_t); 136 static inline uint8_t z8536_reg_get(bus_space_tag_t, bus_space_handle_t, 137 uint8_t); 138 139 140 const uint8_t cio_reset[] = { 141 /* register value */ 142 Z8536_MICR, 0x00, 143 Z8536_MICR, MICR_RESET, 144 Z8536_MICR, 0x00 145 }; 146 147 const uint8_t cio_init[] = { 148 /* register value */ 149 150 /* Interrupt vectors - clear all */ 151 Z8536_IVRA, 0x00, 152 Z8536_IVRB, 0x00, 153 Z8536_IVRCT, 0x20 /* ??? Do we use this? */, 154 155 /* 156 * Port A specification - bit port, single buffered, 157 * latched output, pulsed handshake, all bits non-inverting 158 * non-special I/O 159 */ 160 Z8536_PMSRA, PMSR_PTS_OUT | PMSR_LPM, 161 Z8536_PHSRA, PHSR_HTS_PUL, 162 Z8536_DPPRA, 0x00, 163 Z8536_DDRA, 0x00, 164 Z8536_SIOCRA, 0x00, 165 166 /* 167 * Port B specification - bit port, transparent output, 168 * pulsed handshake, all bits non-inverting 169 * bits 0, 4 output; bits 1-3, 5-8 input, 170 * non-special I/O 171 * Pattern matching: Bit 6 (BUSY) matching "1" 172 * Alternatively: Bit 3 (/ACK) matching "0" 173 */ 174 Z8536_PMSRB, PMSR_PMS_OR_PEV, 175 Z8536_PHSRB, 0x00, 176 Z8536_DPPRB, 0x00, 177 Z8536_DDRB, 0xee /*11101110b*/, 178 Z8536_SIOCRB, 0x00, 179 Z8536_PPRB, 0x00, 180 Z8536_PTRB, 0x00, 181 Z8536_PMRB, 0x40 /*01000000b = PB6 */, 182 183 Z8536_PDRB, 0xFE, /* Assign printer -RESET */ 184 Z8536_PCSRA, 0x00, /* Clear port A interrupt bits */ 185 186 /* 187 * Port C specification - bit 3 out, bits 0-2 in, 188 * all 4 non-inverting, non-special I/O 189 */ 190 Z8536_DDRC, 0x07 /*00000111b*/, 191 Z8536_DPPRC, 0x00, 192 Z8536_SIOCRC, 0x00, 193 194 #ifdef USE_CIO_TIMERS 195 /* 196 * Counter/Timers 1+2 are joined to form a free-running 197 * 32 bit timecounter 198 */ 199 Z8536_CTMSR1, CTMS_CSC, 200 Z8536_CTTCR1_MSB, 0x00, 201 Z8536_CTTCR1_LSB, 0x00, 202 Z8536_CTMSR2, CTMS_CSC, 203 Z8536_CTTCR2_MSB, 0x00, 204 Z8536_CTTCR2_LSB, 0x00, 205 #endif /* USE_CIO_TIMERS */ 206 207 /* 208 * We need Timer 3 for running port A in strobed mode. 209 * 210 * Counter/Timer 3 specification -- clear IP & IUS, trigger + 211 * gate command bit, one-shot operation 212 */ 213 Z8536_CTCSR3, CTCS_CLR_IP_IUS | CTCS_GCB | CTCS_TCB, 214 Z8536_CTMSR3, CTMS_DCS_ONESHOT, 215 Z8536_CTTCR3_MSB, 0x00, 216 Z8536_CTTCR3_LSB, 0x03, 217 218 /* 219 * Enable ports A+B+C+CT3 220 * Set timer 1 to clock timer 2, but not yet enabled. 221 */ 222 Z8536_MCCR, MCCR_PAE | MCCR_PBE | MCCR_CT1CT2 | MCCR_PC_CT3E, 223 /* Master Interrupt Enable, Disable Lower Chain, 224 * No Vector, port A+B+CT vectors include status */ 225 Z8536_MICR, MICR_MIE | MICR_DLC | MICR_NV | MICR_PAVIS | 226 MICR_PBVIS | MICR_CTVIS, 227 Z8536_PDRB, 0xFE, /* Clear printer -RESET */ 228 }; 229 230 231 /* 232 * Look for Creative Systems Inc. "Hurdler Centronics Parallel Interface" 233 */ 234 int 235 cpi_nubus_match(device_t parent, cfdata_t cf, void *aux) 236 { 237 struct nubus_attach_args *na; 238 239 na = aux; 240 if ((na->category == NUBUS_CATEGORY_COMMUNICATIONS) && 241 (na->type == NUBUS_TYPE_CENTRONICS) && 242 (na->drsw == NUBUS_DRSW_CPI) && 243 (na->drhw == NUBUS_DRHW_CPI)) 244 return 1; 245 else 246 return 0; 247 } 248 249 void 250 cpi_nubus_attach(device_t parent, device_t self, void *aux) 251 { 252 struct cpi_softc *sc; 253 struct nubus_attach_args *na; 254 int err, ii; 255 256 sc = device_private(self); 257 na = aux; 258 sc->sc_bst = na->na_tag; 259 memcpy(&sc->sc_slot, na->fmt, sizeof(nubus_slot)); 260 sc->sc_basepa = (bus_addr_t)NUBUS_SLOT2PA(na->slot); 261 262 /* 263 * The CIO sits on the MSB (top byte lane) of the 32 bit 264 * Nubus, so map 16 byte. 265 */ 266 if (TRACE_CONFIG) { 267 printf("\n"); 268 printf("\tcpi_nubus_attach() mapping 8536 CIO at 0x%lx.\n", 269 sc->sc_basepa + CIO_BASE_OFFSET); 270 } 271 272 err = bus_space_map(sc->sc_bst, sc->sc_basepa + CIO_BASE_OFFSET, 273 (Z8536_IOSIZE << 4), 0, &sc->sc_bsh); 274 if (err) { 275 aprint_normal(": failed to map memory space.\n"); 276 return; 277 } 278 279 sc->sc_lpstate = LP_INITIAL; 280 sc->sc_intcount = 0; 281 sc->sc_bytestoport = 0; 282 283 if (TRACE_CONFIG) 284 printf("\tcpi_nubus_attach() about to set up 8536 CIO.\n"); 285 286 for (ii = 0; ii < sizeof(cio_reset); ii += 2) 287 z8536_reg_set(sc->sc_bst, sc->sc_bsh, cio_reset[ii], 288 cio_reset[ii + 1]); 289 290 delay(1000); /* Just in case */ 291 for (ii = 0; ii < sizeof(cio_init); ii += 2) { 292 z8536_reg_set(sc->sc_bst, sc->sc_bsh, cio_init[ii], 293 cio_init[ii + 1]); 294 } 295 296 if (TRACE_CONFIG) 297 printf("\tcpi_nubus_attach() done with 8536 CIO setup.\n"); 298 299 /* XXX Get the information strings from the card's ROM */ 300 aprint_normal(": CSI Hurdler II Centronics\n"); 301 302 #ifdef USE_CIO_TIMERS 303 /* Attach CIO timers as timecounters */ 304 if (TRACE_CONFIG) 305 printf("\tcpi_nubus_attach() about to attach timers\n"); 306 307 cpi_initclock(sc); 308 #endif /* USE_CIO_TIMERS */ 309 310 callout_init(&sc->sc_wakeupchan, 0); /* XXX */ 311 312 /* make sure interrupts are vectored to us */ 313 add_nubus_intr(na->slot, cpi_nubus_intr, sc); 314 } 315 316 void 317 cpi_nubus_intr(void *arg) 318 { 319 struct cpi_softc *sc; 320 int s; 321 322 sc = (struct cpi_softc *)arg; 323 324 s = spltty(); 325 326 sc->sc_intcount++; 327 328 /* Check for interrupt source, and clear interrupt */ 329 330 /* 331 * Clear port A interrupt 332 * Interrupt from register A, clear "pending" 333 * and set "under service" 334 */ 335 z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_PCSRA, PCSR_CLR_IE); 336 z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_PCSRA, PCSR_CLR_IP); 337 z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_PCSRA, PCSR_SET_IUS); 338 339 cpi_intr(sc); 340 341 /* Interrupt from register A, mark serviced */ 342 z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_PCSRA, PCSR_CLR_IUS); 343 z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_PCSRA, PCSR_SET_IE); 344 345 splx(s); 346 } 347 348 349 /* cpi nuts and bolts */ 350 351 int 352 cpi_open(dev_t device, int flag, int mode, struct lwp *l) 353 { 354 int err, ii, s; 355 struct cpi_softc *sc; 356 357 if (TRACE_OPEN) 358 printf("\tcpi_open() called...\n"); 359 360 /* Consistency checks: Valid unit number, softc, device state */ 361 sc = device_lookup_private(&cpi_cd, CPI_UNIT(device)); 362 if (NULL == sc) { 363 if (TRACE_OPEN) 364 printf("Tried to cpi_open() with NULL softc\n"); 365 return ENXIO; 366 } 367 if (sc->sc_lpstate != LP_INITIAL) { 368 if (TRACE_OPEN) 369 printf("%s not in initial state (%x).\n", 370 sc->sc_dev.dv_xname, sc->sc_lpstate); 371 return EBUSY; 372 } 373 sc->sc_lpstate = LP_OPENING; 374 375 if (TRACE_OPEN) 376 printf("\tcpi_open() resetting the printer...\n"); 377 cpi_lpreset(sc); 378 379 if (TRACE_OPEN) 380 printf("\tcpi_open() waiting for printer ready...\n"); 381 382 /* Wait max 15 sec for printer to get ready */ 383 for (ii = 15; cpi_notready(sc); ii--) { 384 if (0 == ii) { 385 sc->sc_lpstate = LP_INITIAL; 386 return EBUSY; 387 } 388 /* sleep for a second, unless we get a signal */ 389 err = ltsleep(sc, PZERO | PCATCH, "cpi_open", hz, NULL); 390 if (err != EWOULDBLOCK) { 391 sc->sc_lpstate = LP_INITIAL; 392 return err; 393 } 394 } 395 if (TRACE_OPEN) 396 printf("\tcpi_open() allocating printer buffer...\n"); 397 398 /* Allocate the driver's line buffer */ 399 sc->sc_printbuf = malloc(CPI_BUFSIZE, M_DEVBUF, M_WAITOK); 400 sc->sc_bufbytes = 0; 401 sc->sc_lpstate = LP_OPEN; 402 403 /* Statistics */ 404 sc->sc_intcount = 0; 405 sc->sc_bytestoport = 0; 406 407 /* Kick off transfer */ 408 cpi_wakeup(sc); 409 410 /* 411 * Reset "interrupt {pending, under service}" bits, then 412 * enable Port A interrupts 413 */ 414 s = spltty(); 415 416 z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_PCSRA, PCSR_CLR_IP_IUS); 417 z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_PCSRA, PCSR_SET_IE); 418 splx(s); 419 420 if (TRACE_OPEN) 421 printf("\tcpi_open() done...\n"); 422 423 return 0; 424 } 425 426 int 427 cpi_close(dev_t device, int flag, int mode, struct lwp *l) 428 { 429 struct cpi_softc *sc; 430 431 sc = device_lookup_private(&cpi_cd, CPI_UNIT(device)); 432 433 if (TRACE_CLOSE) 434 printf("\tcpi_close() called (%lu hard, %lu bytes to port)\n", 435 sc->sc_intcount, sc->sc_bytestoport); 436 437 /* Flush the remaining buffer content, ignoring any errors */ 438 if (0 < sc->sc_bufbytes) 439 (void)cpi_flush(sc); 440 441 callout_stop(&sc->sc_wakeupchan); 442 443 /* Disable Port A interrupts */ 444 z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_PCSRA, PCSR_CLR_IE); 445 z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_PCSRA, PCSR_CLR_IP_IUS); 446 447 sc->sc_lpstate = LP_INITIAL; 448 free(sc->sc_printbuf, M_DEVBUF); 449 450 return 0; 451 } 452 453 int 454 cpi_write(dev_t device, struct uio *uio, int flags) 455 { 456 int err; 457 size_t numbytes; 458 struct cpi_softc *sc; 459 460 err = 0; 461 462 if (TRACE_WRITE) 463 printf("\tcpi_write() called for %u bytes\n", uio->uio_resid); 464 465 sc = device_lookup_private(&cpi_cd, CPI_UNIT(device)); 466 467 /* Send data to printer, a line buffer full at a time */ 468 while (uio->uio_resid > 0) { 469 numbytes = min(CPI_BUFSIZE, uio->uio_resid); 470 sc->sc_cp = sc->sc_printbuf; 471 uiomove(sc->sc_cp, numbytes, uio); 472 sc->sc_bufbytes = numbytes; 473 474 if (TRACE_WRITE) 475 printf("\tQueuing %u bytes\n", numbytes); 476 err = cpi_flush(sc); 477 if (err) { 478 /* Failure; adjust residual counter */ 479 if (TRACE_WRITE) 480 printf("\tQueuing failed with %d\n", err); 481 uio->uio_resid += sc->sc_bufbytes; 482 sc->sc_bufbytes = 0; 483 break; 484 } 485 } 486 return err; 487 } 488 489 int 490 cpi_ioctl(dev_t device, unsigned long cmd, void *data, 491 int flag, struct lwp *l) 492 { 493 int err; 494 495 err = 0; 496 497 if (TRACE_IOCTL) 498 printf("\tcpi_ioctl() called with %ld...\n", cmd); 499 500 switch (cmd) { 501 default: 502 if (TRACE_IOCTL) 503 printf("\tcpi_ioctl() unknown ioctl %ld\n", cmd); 504 err = ENODEV; 505 break; 506 } 507 return err; 508 } 509 510 /* 511 * Flush the print buffer that our top half uses to provide data to 512 * our bottom, interrupt-driven half. 513 */ 514 static int 515 cpi_flush(struct cpi_softc *sc) 516 { 517 int err, s; 518 519 err = 0; 520 while (0 < sc->sc_bufbytes) { 521 /* Feed the printer a char, if it's ready */ 522 if ( !cpi_notready(sc)) { 523 if (TRACE_WRITE) 524 printf("\tcpi_flush() writes %u bytes " 525 "(%lu hard, %lu bytes to port)\n", 526 sc->sc_bufbytes, sc->sc_intcount, 527 sc->sc_bytestoport); 528 s = spltty(); 529 cpi_intr(sc); 530 splx(s); 531 } 532 /* XXX Sure we want to wait forever for the printer? */ 533 err = ltsleep((void *)sc, PZERO | PCATCH, 534 "cpi_flush", (60 * hz), NULL); 535 } 536 return err; 537 } 538 539 540 static void 541 cpi_wakeup(void *param) 542 { 543 struct cpi_softc *sc; 544 int s; 545 546 sc = param; 547 548 s = spltty(); 549 cpi_intr(sc); 550 splx(s); 551 552 callout_reset(&sc->sc_wakeupchan, hz, cpi_wakeup, sc); 553 } 554 555 556 static void 557 cpi_lpreset(struct cpi_softc *sc) 558 { 559 uint8_t portb; /* Centronics -RESET is on port B, bit 0 */ 560 #ifdef DIRECT_PORT_ACCESS 561 int s; 562 563 s = spltty(); 564 565 portb = bus_space_read_1(sc->sc_bst, sc->sc_bsh, CIO_PORTB); 566 bus_space_write_1(sc->sc_bst, sc->sc_bsh, 567 CIO_PORTB, portb & ~CPI_RESET); 568 delay(100); 569 portb = bus_space_read_1(sc->sc_bst, sc->sc_bsh, CIO_PORTB); 570 bus_space_write_1(sc->sc_bst, sc->sc_bsh, 571 CIO_PORTB, portb | CPI_RESET); 572 573 splx(s); 574 #else 575 portb = z8536_reg_get(sc->sc_bst, sc->sc_bsh, Z8536_PDRB); 576 z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_PDRB, portb & ~CPI_RESET); 577 delay(100); 578 portb = z8536_reg_get(sc->sc_bst, sc->sc_bsh, Z8536_PDRB); 579 z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_PDRB, portb | CPI_RESET); 580 #endif /* DIRECT_PORT_ACCESS */ 581 } 582 583 584 /* 585 * Centronics BUSY is on port B, bit 6 586 * SELECT is on Port B, bit 5 587 * /FAULT is on Port B, bit 1 588 * PAPER EMPTY is on Port C, bit 1 589 */ 590 static int 591 cpi_notready(struct cpi_softc *sc) 592 { 593 uint8_t portb, portc; 594 int is_busy, is_select, is_fault, is_paper_empty; 595 596 if (TRACE_STATUS) 597 printf("\tcpi_notready() checking printer status...\n"); 598 599 portb = bus_space_read_1(sc->sc_bst, sc->sc_bsh, CIO_PORTB); 600 if (TRACE_STATUS) 601 printf("\tPort B has 0x0%X\n", portb); 602 603 is_busy = CPI_BUSY & portb; 604 if (TRACE_STATUS) 605 printf("\t\tBUSY = %d\n", is_busy); 606 607 is_select = CPI_SELECT & portb; 608 if (TRACE_STATUS) 609 printf("\t\tSELECT = %d\n", is_select); 610 611 is_fault = CPI_FAULT & portb; 612 if (TRACE_STATUS) 613 printf("\t\t/FAULT = %d\n", is_fault); 614 615 portc = bus_space_read_1(sc->sc_bst, sc->sc_bsh, CIO_PORTC); 616 if (TRACE_STATUS) 617 printf("\tPort C has 0x0%X\n", portc); 618 619 is_paper_empty = CPI_PAPER_EMPTY & portc; 620 if (TRACE_STATUS) 621 printf("\t\tPAPER EMPTY = %d\n", is_paper_empty); 622 623 return (is_busy || !is_select || !is_fault || is_paper_empty); 624 } 625 626 static void 627 cpi_intr(void *arg) 628 { 629 struct cpi_softc *sc; 630 631 sc = arg; 632 633 /* Printer ready for output? */ 634 if (cpi_notready(sc)) 635 return; 636 637 if (0 && TRACE_WRITE) 638 printf("\tcpi_soft_intr() has %u bytes.\n", sc->sc_bufbytes); 639 640 /* Anything to print? */ 641 if (sc->sc_bufbytes) { 642 /* Data byte */ 643 bus_space_write_1(sc->sc_bst, sc->sc_bsh, 644 CIO_PORTA, *sc->sc_cp++); 645 sc->sc_bufbytes--; 646 sc->sc_bytestoport++; 647 } 648 if (0 == sc->sc_bufbytes) 649 /* line buffer empty, wake up our top half */ 650 wakeup((void *)sc); 651 } 652 653 #ifdef USE_CIO_TIMERS 654 /* 655 * Z8536 CIO timers 1 + 2 used for timecounter(9) support 656 */ 657 static void 658 cpi_initclock(struct cpi_softc *sc) 659 { 660 static struct timecounter cpi_timecounter = { 661 .tc_get_timecount = cpi_get_timecount, 662 .tc_poll_pps = 0, 663 .tc_counter_mask = 0x0ffffu, 664 .tc_frequency = CLK_FREQ, 665 .tc_name = "CPI Z8536 CIO", 666 .tc_quality = 50, 667 .tc_priv = NULL, 668 .tc_next = NULL 669 }; 670 671 /* 672 * Set up timers A and B as a single, free-running 32 bit counter 673 */ 674 675 /* Disable counters A and B */ 676 reg = z8536_reg_get(sc->sc_bst, sc->sc_bsh, Z8536_MCCR); 677 z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_MCCR, 678 reg & ~(MCCR_CT1E |�MCCR_CT2E)); 679 680 /* Make sure interrupt enable bits are cleared */ 681 z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTCSR1, 682 CTCS_CLR_IE); 683 z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTCSR2, 684 CTCS_CLR_IE); 685 686 /* Initialise counter start values, and set to continuous cycle */ 687 z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTMSR1, CTMS_CSC); 688 z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTTCR1_MSB, 0x00); 689 z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTTCR1_LSB, 0x00); 690 691 z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTMSR2, CTMS_CSC); 692 z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTTCR2_MSB, 0x00); 693 z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTTCR2_LSB, 0x00); 694 695 /* Re-enable counters A and B */ 696 reg = z8536_reg_get(sc->sc_bst, sc->sc_bsh, Z8536_MCCR); 697 z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_MCCR, 698 reg |�MCCR_CT1E |�MCCR_CT2E |�MCCR_CT1CT2); 699 700 /* Start counters A and B */ 701 reg = z8536_reg_get(sc->sc_bst, sc->sc_bsh, Z8536_CTCSR1); 702 z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTCSR1, 703 reg | CTCS_TCB); 704 reg = z8536_reg_get(sc->sc_bst, sc->sc_bsh, Z8536_CTCSR2); 705 z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTCSR2, 706 reg |�CTCS_TCB); 707 708 tc_init(&cpi_timecounter); 709 } 710 711 static u_int 712 cpi_get_timecount(struct timecounter *tc) 713 { 714 uint8_t high, high2, low; 715 int s; 716 717 /* 718 * Make the timer access atomic 719 * 720 * XXX How expensive is this? And is it really necessary? 721 */ 722 s = splhigh(); 723 724 /* TBD */ 725 726 } 727 #endif /* USE_CIO_TIMERS */ 728 729 730 /* 731 * Z8536 CIO nuts and bolts 732 */ 733 734 static inline void 735 z8536_reg_set(bus_space_tag_t bspace, bus_space_handle_t bhandle, 736 uint8_t reg, uint8_t val) 737 { 738 int s; 739 740 s = splhigh(); 741 bus_space_write_1(bspace, bhandle, CIO_CTRL, reg); 742 delay(1); 743 bus_space_write_1(bspace, bhandle, CIO_CTRL, val); 744 splx(s); 745 } 746 747 static inline uint8_t 748 z8536_reg_get(bus_space_tag_t bspace, bus_space_handle_t bhandle, uint8_t reg) 749 { 750 int s; 751 uint8_t val; 752 753 s = splhigh(); 754 bus_space_write_1(bspace, bhandle, CIO_CTRL, reg); 755 delay(1); 756 val = bus_space_read_1(bspace, bhandle, CIO_CTRL); 757 splx(s); 758 759 return val; 760 } 761