1 /* $NetBSD: ppbus_base.c,v 1.17 2008/04/15 15:02:29 cegger Exp $ */ 2 3 /*- 4 * Copyright (c) 1997, 1998, 1999 Nicolas Souchu 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * 28 * FreeBSD: src/sys/dev/ppbus/ppb_base.c,v 1.10.2.1 2000/08/01 23:26:26 n_hibma Exp 29 * 30 */ 31 32 #include <sys/cdefs.h> 33 __KERNEL_RCSID(0, "$NetBSD: ppbus_base.c,v 1.17 2008/04/15 15:02:29 cegger Exp $"); 34 35 #include "opt_ppbus_1284.h" 36 #include "opt_ppbus.h" 37 38 #include <sys/param.h> 39 #include <sys/kernel.h> 40 #include <sys/malloc.h> 41 #include <sys/proc.h> 42 #include <sys/systm.h> 43 44 #include <dev/ppbus/ppbus_1284.h> 45 #include <dev/ppbus/ppbus_conf.h> 46 #include <dev/ppbus/ppbus_base.h> 47 #include <dev/ppbus/ppbus_device.h> 48 #include <dev/ppbus/ppbus_io.h> 49 #include <dev/ppbus/ppbus_var.h> 50 51 #ifndef DONTPROBE_1284 52 /* Utility functions */ 53 static char * search_token(char *, int, const char *); 54 #endif 55 56 /* Perform general ppbus I/O request */ 57 int 58 ppbus_io(device_t dev, int iop, u_char * addr, int cnt, u_char byte) 59 { 60 struct ppbus_softc * bus = device_private(dev); 61 return (bus->ppbus_io(device_parent(dev), iop, addr, cnt, byte)); 62 } 63 64 /* Execute microsequence */ 65 int 66 ppbus_exec_microseq(device_t dev, struct ppbus_microseq ** sequence) 67 { 68 struct ppbus_softc * bus = device_private(dev); 69 return (bus->ppbus_exec_microseq(device_parent(dev), sequence)); 70 } 71 72 /* Read instance variables of ppbus */ 73 int 74 ppbus_read_ivar(device_t dev, int index, unsigned int * val) 75 76 { 77 struct ppbus_softc * bus = device_private(dev); 78 79 switch (index) { 80 case PPBUS_IVAR_INTR: 81 case PPBUS_IVAR_EPP_PROTO: 82 case PPBUS_IVAR_DMA: 83 return (bus->ppbus_read_ivar(device_parent(dev), index, val)); 84 85 case PPBUS_IVAR_IEEE: 86 *val = (bus->sc_use_ieee == PPBUS_ENABLE_IEEE) ? 1 : 0; 87 break; 88 89 default: 90 return (ENOENT); 91 } 92 93 return 0; 94 } 95 96 /* Write an instance variable */ 97 int 98 ppbus_write_ivar(device_t dev, int index, unsigned int * val) 99 { 100 struct ppbus_softc * bus = device_private(dev); 101 102 switch (index) { 103 case PPBUS_IVAR_INTR: 104 case PPBUS_IVAR_EPP_PROTO: 105 case PPBUS_IVAR_DMA: 106 return (bus->ppbus_write_ivar(device_parent(dev), index, val)); 107 108 case PPBUS_IVAR_IEEE: 109 bus->sc_use_ieee = ((*val != 0) ? PPBUS_ENABLE_IEEE : 110 PPBUS_DISABLE_IEEE); 111 break; 112 113 default: 114 return (ENOENT); 115 } 116 117 return 0; 118 } 119 120 /* Polls the bus for a max of 10-milliseconds */ 121 int 122 ppbus_poll_bus(device_t dev, int maxp, char mask, char status, 123 int how) 124 { 125 int i, j, error; 126 char r; 127 128 /* try at least up to 10ms */ 129 for (j = 0; j < ((how & PPBUS_POLL) ? maxp : 1); j++) { 130 for (i = 0; i < 10000; i++) { 131 r = ppbus_rstr(dev); 132 DELAY(1); 133 if ((r & mask) == status) 134 return (0); 135 } 136 } 137 138 if (!(how & PPBUS_POLL)) { 139 for (i = 0; maxp == PPBUS_FOREVER || i < maxp-1; i++) { 140 if ((ppbus_rstr(dev) & mask) == status) 141 return (0); 142 143 switch (how) { 144 case PPBUS_NOINTR: 145 /* wait 10 ms */ 146 tsleep((void *)dev, PPBUSPRI, "ppbuspoll", hz/100); 147 break; 148 149 case PPBUS_INTR: 150 default: 151 /* wait 10 ms */ 152 if (((error = tsleep((void *)dev, PPBUSPRI | PCATCH, 153 "ppbuspoll", hz/100)) != EWOULDBLOCK) != 0) { 154 return (error); 155 } 156 break; 157 } 158 } 159 } 160 161 return (EWOULDBLOCK); 162 } 163 164 /* Get operating mode of the chipset */ 165 int 166 ppbus_get_mode(device_t dev) 167 { 168 struct ppbus_softc * bus = device_private(dev); 169 170 return (bus->sc_mode); 171 } 172 173 /* Set the operating mode of the chipset, return 0 on success. */ 174 int 175 ppbus_set_mode(device_t dev, int mode, int options) 176 { 177 struct ppbus_softc * bus = device_private(dev); 178 int error = 0; 179 180 /* If no mode change, do nothing */ 181 if(bus->sc_mode == mode) 182 return error; 183 184 /* Do necessary negotiations */ 185 if(bus->sc_use_ieee == PPBUS_ENABLE_IEEE) { 186 /* Cannot negotiate standard mode */ 187 if(!(mode & (PPBUS_FAST | PPBUS_COMPATIBLE))) { 188 error = ppbus_1284_negotiate(dev, mode, options); 189 } 190 /* Termination is unnecessary for standard<->fast */ 191 else if(!(bus->sc_mode & (PPBUS_FAST | PPBUS_COMPATIBLE))) { 192 ppbus_1284_terminate(dev); 193 } 194 } 195 196 if(!error) { 197 /* Set mode and update mode of ppbus to actual mode */ 198 error = bus->ppbus_setmode(device_parent(dev), mode); 199 bus->sc_mode = bus->ppbus_getmode(device_parent(dev)); 200 } 201 202 /* Update host state if necessary */ 203 if(!(error) && (bus->sc_use_ieee == PPBUS_ENABLE_IEEE)) { 204 switch(mode) { 205 case PPBUS_COMPATIBLE: 206 case PPBUS_FAST: 207 case PPBUS_EPP: 208 case PPBUS_ECP: 209 ppbus_1284_set_state(dev, PPBUS_FORWARD_IDLE); 210 break; 211 212 case PPBUS_NIBBLE: 213 case PPBUS_PS2: 214 ppbus_1284_set_state(dev, PPBUS_REVERSE_IDLE); 215 break; 216 } 217 } 218 219 return error; 220 } 221 222 /* Write charaters to the port */ 223 int 224 ppbus_write(device_t dev, char * buf, int len, int how, size_t * cnt) 225 { 226 struct ppbus_softc * bus = device_private(dev); 227 228 if(bus->sc_use_ieee == PPBUS_ENABLE_IEEE) { 229 if(bus->sc_1284_state != PPBUS_FORWARD_IDLE) { 230 printf("%s(%s): bus not in forward idle mode.\n", 231 __func__, device_xname(dev)); 232 return ENODEV; 233 } 234 } 235 236 return (bus->ppbus_write(device_parent(bus->sc_dev), buf, len, how, cnt)); 237 } 238 239 /* Read charaters from the port */ 240 int 241 ppbus_read(device_t dev, char * buf, int len, int how, size_t * cnt) 242 { 243 struct ppbus_softc * bus = device_private(dev); 244 245 if(bus->sc_use_ieee == PPBUS_ENABLE_IEEE) { 246 if(bus->sc_1284_state != PPBUS_REVERSE_IDLE) { 247 printf("%s(%s): bus not in reverse idle mode.\n", 248 __func__, device_xname(dev)); 249 return ENODEV; 250 } 251 } 252 253 return (bus->ppbus_read(device_parent(dev), buf, len, how, cnt)); 254 } 255 256 /* Reset the EPP timeout bit in the status register */ 257 int 258 ppbus_reset_epp_timeout(device_t dev) 259 { 260 struct ppbus_softc * bus = device_private(dev); 261 262 if(bus->sc_capabilities & PPBUS_HAS_EPP) { 263 bus->ppbus_reset_epp_timeout(device_parent(dev)); 264 return 0; 265 } 266 else { 267 return ENODEV; 268 } 269 } 270 271 /* Wait for the ECP FIFO to be empty */ 272 int 273 ppbus_ecp_sync(device_t dev) 274 { 275 struct ppbus_softc * bus = device_private(dev); 276 277 if(bus->sc_capabilities & PPBUS_HAS_ECP) { 278 bus->ppbus_ecp_sync(device_parent(dev)); 279 return 0; 280 } 281 else { 282 return ENODEV; 283 } 284 } 285 286 /* Allocate DMA for use with ppbus */ 287 int 288 ppbus_dma_malloc(device_t dev, void ** buf, bus_addr_t * addr, 289 bus_size_t size) 290 { 291 struct ppbus_softc * ppbus = device_private(dev); 292 293 if(ppbus->sc_capabilities & PPBUS_HAS_DMA) 294 return (ppbus->ppbus_dma_malloc(device_parent(dev), buf, addr, 295 size)); 296 else 297 return ENODEV; 298 } 299 300 /* Free memory allocated with ppbus_dma_malloc() */ 301 int 302 ppbus_dma_free(device_t dev, void ** buf, bus_addr_t * addr, 303 bus_size_t size) 304 { 305 struct ppbus_softc * ppbus = device_private(dev); 306 307 if(ppbus->sc_capabilities & PPBUS_HAS_DMA) { 308 ppbus->ppbus_dma_free(device_parent(dev), buf, addr, size); 309 return 0; 310 } 311 else { 312 return ENODEV; 313 } 314 } 315 316 /* Install a handler to be called by hardware interrupt handler */ 317 int ppbus_add_handler(device_t dev, void (*func)(void *), void *arg) 318 { 319 struct ppbus_softc * bus = device_private(dev); 320 321 if(bus->sc_capabilities & PPBUS_HAS_INTR) 322 return bus->ppbus_add_handler(device_parent(dev), func, arg); 323 else 324 return ENODEV; 325 } 326 327 /* Remove a handler registered with ppbus_add_handler() */ 328 int ppbus_remove_handler(device_t dev, void (*func)(void *)) 329 { 330 struct ppbus_softc * bus = device_private(dev); 331 332 if(bus->sc_capabilities & PPBUS_HAS_INTR) 333 return bus->ppbus_remove_handler(device_parent(dev), func); 334 else 335 return ENODEV; 336 } 337 338 /* 339 * ppbus_get_status() 340 * 341 * Read the status register and update the status info 342 */ 343 int 344 ppbus_get_status(device_t dev, struct ppbus_status * status) 345 { 346 register char r = status->status = ppbus_rstr(dev); 347 348 status->timeout = r & TIMEOUT; 349 status->error = !(r & nFAULT); 350 status->select = r & SELECT; 351 status->paper_end = r & PERROR; 352 status->ack = !(r & nACK); 353 status->busy = !(r & nBUSY); 354 355 return (0); 356 } 357 358 /* Allocate the device to perform transfers */ 359 int 360 ppbus_request_bus(device_t dev, device_t busdev, int how, 361 unsigned int timeout) 362 { 363 struct ppbus_softc * bus = device_private(dev); 364 unsigned int counter = timeout; 365 int priority = PPBUSPRI; 366 int error; 367 368 if(how & PPBUS_INTR) 369 priority |= PCATCH; 370 371 /* Loop until lock acquired (if PPBUS_WAIT) or an error occurs */ 372 for(;;) { 373 if (mutex_tryenter(&(bus->sc_lock))) 374 break; 375 376 if(how & PPBUS_WAIT) { 377 error = ltsleep(bus, priority, __func__, hz/2, NULL); 378 counter -= (hz/2); 379 if(!(error)) 380 continue; 381 else if(error != EWOULDBLOCK) 382 goto end; 383 if(counter == 0) { 384 error = ETIMEDOUT; 385 goto end; 386 } 387 } 388 else { 389 error = EWOULDBLOCK; 390 goto end; 391 } 392 } 393 394 /* Set bus owner or return error if bus is taken */ 395 if(bus->ppbus_owner == NULL) { 396 bus->ppbus_owner = busdev; 397 error = 0; 398 } 399 else { 400 error = EBUSY; 401 } 402 403 /* Release lock */ 404 mutex_exit(&(bus->sc_lock)); 405 406 end: 407 return error; 408 } 409 410 /* Release the device allocated with ppbus_request_bus() */ 411 int 412 ppbus_release_bus(device_t dev, device_t busdev, int how, 413 unsigned int timeout) 414 { 415 struct ppbus_softc * bus = device_private(dev); 416 unsigned int counter = timeout; 417 int priority = PPBUSPRI; 418 int error; 419 420 if(how & PPBUS_INTR) 421 priority |= PCATCH; 422 423 /* Loop until lock acquired (if PPBUS_WAIT) or an error occurs */ 424 for(;;) { 425 if (mutex_tryenter(&(bus->sc_lock))) 426 break; 427 428 if(how & PPBUS_WAIT) { 429 error = ltsleep(bus, priority, __func__, hz/2, NULL); 430 counter -= (hz/2); 431 if(!(error)) 432 continue; 433 else if(error != EWOULDBLOCK) 434 goto end; 435 if(counter == 0) { 436 error = ETIMEDOUT; 437 goto end; 438 } 439 } 440 else { 441 error = EWOULDBLOCK; 442 goto end; 443 } 444 } 445 446 /* If the device is the owner, release bus */ 447 if(bus->ppbus_owner != busdev) { 448 error = EINVAL; 449 } 450 else { 451 bus->ppbus_owner = NULL; 452 error = 0; 453 } 454 455 /* Release lock */ 456 mutex_exit(&(bus->sc_lock)); 457 458 end: 459 return error; 460 } 461 462 463 /* IEEE 1284-based probes */ 464 465 #ifndef DONTPROBE_1284 466 467 static const char *pnp_tokens[] = { 468 "PRINTER", "MODEM", "NET", "HDC", "PCMCIA", "MEDIA", 469 "FDC", "PORTS", "SCANNER", "DIGICAM", "", NULL }; 470 471 /* ??? */ 472 #if 0 473 static char *pnp_classes[] = { 474 "printer", "modem", "network device", 475 "hard disk", "PCMCIA", "multimedia device", 476 "floppy disk", "ports", "scanner", 477 "digital camera", "unknown device", NULL }; 478 #endif 479 480 /* 481 * Search the first occurence of a token within a string 482 * XXX should use strxxx() calls 483 */ 484 static char * 485 search_token(char *str, int slen, const char *token) 486 { 487 const char *p; 488 int tlen, i, j; 489 490 #define UNKNOWN_LENGTH -1 491 492 if (slen == UNKNOWN_LENGTH) 493 /* get string's length */ 494 for (slen = 0, p = str; *p != '\0'; p++) 495 slen++; 496 497 /* get token's length */ 498 for (tlen = 0, p = token; *p != '\0'; p++) 499 tlen++; 500 501 if (tlen == 0) 502 return (str); 503 504 for (i = 0; i <= slen-tlen; i++) { 505 for (j = 0; j < tlen; j++) 506 if (str[i+j] != token[j]) 507 break; 508 if (j == tlen) 509 return (&str[i]); 510 } 511 512 return (NULL); 513 } 514 515 /* Stores the class ID of the peripherial in soft config data */ 516 void 517 ppbus_pnp_detect(device_t dev) 518 { 519 struct ppbus_softc * bus = device_private(dev); 520 int i; 521 int error; 522 size_t len = 0; 523 size_t str_sz = 0; 524 char * str = NULL; 525 char * class = NULL; 526 char * token; 527 528 #ifdef PPBUS_VERBOSE 529 printf("%s: Probing for PnP devices.\n", device_xname(dev)); 530 #endif 531 532 error = ppbus_1284_read_id(dev, PPBUS_NIBBLE, &str, &str_sz, &len); 533 if(str_sz != len) { 534 #ifdef DEBUG_1284 535 printf("%s(%s): device returned less characters than expected " 536 "in device ID.\n", __func__, device_xname(dev)); 537 #endif 538 } 539 if(error) { 540 printf("%s: Error getting device ID (errno = %d)\n", 541 device_xname(dev), error); 542 goto end_detect; 543 } 544 545 #ifdef DEBUG_1284 546 printf("%s: <PnP> %d characters: ", device_xname(dev), len); 547 for (i = 0; i < len; i++) 548 printf("%c(0x%x) ", str[i], str[i]); 549 printf("\n"); 550 #endif 551 552 /* replace ';' characters by '\0' */ 553 for (i = 0; i < len; i++) 554 if(str[i] == ';') str[i] = '\0'; 555 /* str[i] = (str[i] == ';') ? '\0' : str[i]; */ 556 557 if ((token = search_token(str, len, "MFG")) != NULL || 558 (token = search_token(str, len, "MANUFACTURER")) != NULL) 559 printf("%s: <%s", device_xname(dev), 560 search_token(token, UNKNOWN_LENGTH, ":") + 1); 561 else 562 printf("%s: <unknown", device_xname(dev)); 563 564 if ((token = search_token(str, len, "MDL")) != NULL || 565 (token = search_token(str, len, "MODEL")) != NULL) 566 printf(" %s", 567 search_token(token, UNKNOWN_LENGTH, ":") + 1); 568 569 if ((token = search_token(str, len, "REV")) != NULL) 570 printf(".%s", 571 search_token(token, UNKNOWN_LENGTH, ":") + 1); 572 573 printf(">"); 574 575 if ((token = search_token(str, len, "CLS")) != NULL) { 576 class = search_token(token, UNKNOWN_LENGTH, ":") + 1; 577 printf(" %s", class); 578 } 579 580 if ((token = search_token(str, len, "CMD")) != NULL || 581 (token = search_token(str, len, "COMMAND")) != NULL) 582 printf(" %s", 583 search_token(token, UNKNOWN_LENGTH, ":") + 1); 584 585 printf("\n"); 586 587 if (class) { 588 /* identify class ident */ 589 for (i = 0; pnp_tokens[i] != NULL; i++) { 590 if (search_token(class, len, pnp_tokens[i]) != NULL) { 591 bus->sc_class_id = i; 592 goto end_detect; 593 } 594 } 595 } 596 bus->sc_class_id = PPBUS_PNP_UNKNOWN; 597 598 end_detect: 599 if(str) 600 free(str, M_DEVBUF); 601 return; 602 } 603 604 /* Scan the ppbus for IEEE1284 compliant devices */ 605 int 606 ppbus_scan_bus(device_t dev) 607 { 608 struct ppbus_softc * bus = device_private(dev); 609 int error; 610 611 /* Try IEEE1284 modes, one device only (no IEEE1284.3 support) */ 612 613 error = ppbus_1284_negotiate(dev, PPBUS_NIBBLE, 0); 614 if (error && bus->sc_1284_state == PPBUS_ERROR 615 && bus->sc_1284_error == PPBUS_NOT_IEEE1284) 616 return (error); 617 ppbus_1284_terminate(dev); 618 619 #if defined(PPBUS_VERBOSE) || defined(PPBUS_DEBUG) 620 /* IEEE1284 supported, print info */ 621 printf("%s: IEEE1284 negotiation: modes %s", 622 device_xname(dev), "NIBBLE"); 623 624 error = ppbus_1284_negotiate(dev, PPBUS_PS2, 0); 625 if (!error) 626 printf("/PS2"); 627 ppbus_1284_terminate(dev); 628 629 error = ppbus_1284_negotiate(dev, PPBUS_ECP, 0); 630 if (!error) 631 printf("/ECP"); 632 ppbus_1284_terminate(dev); 633 634 error = ppbus_1284_negotiate(dev, PPBUS_ECP, PPBUS_USE_RLE); 635 if (!error) 636 printf("/ECP_RLE"); 637 ppbus_1284_terminate(dev); 638 639 error = ppbus_1284_negotiate(dev, PPBUS_EPP, 0); 640 if (!error) 641 printf("/EPP"); 642 ppbus_1284_terminate(dev); 643 644 printf("\n"); 645 #endif /* PPBUS_VERBOSE || PPBUS_DEBUG */ 646 647 return 0; 648 } 649 650 #endif /* !DONTPROBE_1284 */ 651 652