|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.1 (the "License"). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License. ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: ! 25: /* ! 26: * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991 ! 27: * All Rights Reserved ! 28: * ! 29: * Permission to use, copy, modify, and distribute this software and ! 30: * its documentation for any purpose and without fee is hereby granted, ! 31: * provided that the above copyright notice appears in all copies and ! 32: * that both the copyright notice and this permission notice appear in ! 33: * supporting documentation. ! 34: * ! 35: * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE ! 36: * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ! 37: * FOR A PARTICULAR PURPOSE. ! 38: * ! 39: * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR ! 40: * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM ! 41: * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, ! 42: * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION ! 43: * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ! 44: * ! 45: */ ! 46: /* ! 47: * Copyright 1996 1995 by Apple Computer, Inc. 1997 1996 1995 1994 1993 1992 1991 ! 48: * All Rights Reserved ! 49: * ! 50: * Permission to use, copy, modify, and distribute this software and ! 51: * its documentation for any purpose and without fee is hereby granted, ! 52: * provided that the above copyright notice appears in all copies and ! 53: * that both the copyright notice and this permission notice appear in ! 54: * supporting documentation. ! 55: * ! 56: * APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE ! 57: * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ! 58: * FOR A PARTICULAR PURPOSE. ! 59: * ! 60: * IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR ! 61: * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM ! 62: * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, ! 63: * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION ! 64: * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ! 65: */ ! 66: /* ! 67: * MKLINUX-1.0DR2 ! 68: */ ! 69: ! 70: /* ! 71: * ADB Driver - used internally by ADB device drivers ! 72: * ! 73: * Currently this is heavily tied to the design of ! 74: * the CUDA hardware and MACH driver ! 75: */ ! 76: ! 77: ! 78: #include <mach_kdb.h> ! 79: #include <mach/mach_types.h> ! 80: #include <machdep/ppc/powermac.h> //for HasPMU() definition ! 81: #include <sys/tty.h> ! 82: #include <sys/conf.h> ! 83: #include "busses.h" ! 84: #include "adb.h" ! 85: #include "adb_io.h" ! 86: #include "drvPMU/pmu.h" ! 87: ! 88: void waitForCallback(void); ! 89: void ADBcallback(id, UInt32, UInt32, UInt8 *); ! 90: void ADBReadCallback(id, UInt32, UInt32, UInt8 *); ! 91: void ADBReadCallback2(id, UInt32, UInt32, UInt8 *); ! 92: void inputHandler(id, UInt32, UInt32, UInt32, UInt8*); ! 93: ! 94: id PMUdriver = NULL; ! 95: UInt8 read_buffer[8]; ! 96: int read_length; ! 97: boolean_t adb_initted = FALSE; ! 98: int adb_count = 0; ! 99: ! 100: adb_request_t *adb_queue_root = NULL, *adb_queue_end = NULL; ! 101: ! 102: #define ADB_POOL_COUNT 16 ! 103: ! 104: adb_device_t adb_devices[ADB_DEVICE_COUNT]; ! 105: adb_request_t adb_async_requests[ADB_POOL_COUNT], *adb_async_pool; ! 106: boolean_t adb_hardware = FALSE; ! 107: ! 108: ! 109: void adbattach( struct bus_device *device); ! 110: int adbprobe(caddr_t addr, void *ui); ! 111: ! 112: struct bus_device *adb_info[NADB]; ! 113: ! 114: void ! 115: InitializeADB(void) ! 116: { ! 117: ! 118: if (adb_hardware == FALSE) { ! 119: [PMUdriver registerForADBAutopoll:inputHandler:(id)NULL]; ! 120: adb_hardware = TRUE; ! 121: adbprobe(0, 0); ! 122: } ! 123: } ! 124: ! 125: ! 126: static int ! 127: adb_is_dev_present(unsigned short addr) ! 128: { ! 129: struct adb_device *devp = &adb_devices[addr]; ! 130: unsigned short value; ! 131: int retval; ! 132: ! 133: //kprintf("adb_is_dev_present: addr = %08x, devp = %08x\n", addr, devp); ! 134: ! 135: retval = adb_readreg(addr, 3, &value); ! 136: ! 137: //kprintf("adb_is_dev_present: retval = %08x, ADB_RET_TIMEOUT = %08x\n", ! 138: // retval, ADB_RET_TIMEOUT); ! 139: ! 140: #if notdef_next // DEBUG ! 141: if (retval != ADB_RET_TIMEOUT) ! 142: printf("adb_is_dev_present(%2d) returned %d\n", addr, retval); ! 143: #endif /* DEBUG */ ! 144: if (retval != ADB_RET_TIMEOUT) { ! 145: ! 146: //kprintf("adb_is_dev_present: value = %08x\n", value); ! 147: ! 148: devp->a_dev_addr = (value >> 8) & 0xf; ! 149: devp->a_dev_orighandler = devp->a_dev_handler = (value & 0xff); ! 150: devp->a_flags |= ADB_FLAGS_PRESENT; ! 151: return TRUE; ! 152: } ! 153: ! 154: return FALSE; ! 155: } ! 156: ! 157: int ! 158: adb_set_handler(struct adb_device *devp, int handler) ! 159: { ! 160: unsigned long retval; ! 161: unsigned short value; ! 162: ! 163: retval = adb_readreg(devp->a_addr, 3, &value); ! 164: ! 165: if (retval != ADB_RET_OK) ! 166: return( retval); ! 167: ! 168: value = (value & 0xF000) | handler; ! 169: ! 170: retval = adb_writereg(devp->a_addr, 3, value); ! 171: ! 172: if (retval != ADB_RET_OK) ! 173: return( retval); ! 174: ! 175: retval = adb_readreg(devp->a_addr, 3, &value); ! 176: ! 177: if (retval != ADB_RET_OK) ! 178: return( retval); ! 179: ! 180: if( (value & 0xFF) != handler) ! 181: retval = ADB_RET_UNEXPECTED_RESULT; ! 182: ! 183: /* Update to new handler/id */ ! 184: devp->a_dev_handler = (value & 0xff); ! 185: ! 186: ! 187: return( retval); ! 188: } ! 189: ! 190: static void ! 191: adb_move_dev(unsigned short from, unsigned short to) ! 192: { ! 193: int addr; ! 194: adb_writereg(from, 3, ((to << 8) | 0xfe)); ! 195: ! 196: addr = adb_devices[to].a_addr; ! 197: adb_devices[to] = adb_devices[from]; ! 198: adb_devices[to].a_addr = addr; ! 199: adb_devices[from].a_flags = 0; ! 200: ! 201: return; ! 202: } ! 203: ! 204: static boolean_t ! 205: adb_find_unresolved_dev(unsigned short *devnum) ! 206: { ! 207: int i; ! 208: struct adb_device *devp; ! 209: ! 210: devp = &adb_devices[1]; ! 211: ! 212: for (i = 1; i < ADB_DEVICE_COUNT; i++, devp++) { ! 213: if (devp->a_flags & ADB_FLAGS_UNRESOLVED) { ! 214: *devnum = i; ! 215: return TRUE; ! 216: } ! 217: } ! 218: ! 219: return FALSE; ! 220: } ! 221: ! 222: static int ! 223: adb_find_freedev(void) ! 224: { ! 225: struct adb_device *devp; ! 226: int i; ! 227: ! 228: for (i = ADB_DEVICE_COUNT-1; i >= 1; i--) { ! 229: devp = &adb_devices[i]; ! 230: ! 231: if ((devp->a_flags & ADB_FLAGS_PRESENT) == 0) ! 232: return i; ! 233: } ! 234: ! 235: panic("ADB: Cannot find a free ADB slot for reassignment!"); ! 236: return -1; ! 237: } ! 238: ! 239: int ! 240: adbprobe(caddr_t addr, void *ui) ! 241: { ! 242: unsigned short devnum, freenum, devlist; ! 243: struct adb_device *devp; ! 244: int i; ! 245: spl_t s; ! 246: ! 247: //kprintf("adbprobe: Begining\n"); ! 248: ! 249: if (adb_initted) ! 250: return 1; ! 251: ! 252: //kprintf("adbprobe: Not initted\n"); ! 253: ! 254: for (i = 0; i < ADB_POOL_COUNT; i++) { ! 255: adb_async_requests[i].a_next = adb_async_pool; ! 256: adb_async_pool = &adb_async_requests[i]; ! 257: } ! 258: ! 259: s = spltty(); ! 260: ! 261: /* Kill the auto poll until a new dev id's have been setup */ ! 262: ! 263: if ( [PMUdriver ADBPollDisable:(UInt32)current_thread():0:ADBcallback] == kPMUNoError ) { ! 264: waitForCallback(); ! 265: } ! 266: /* ! 267: * Send a ADB bus reset - reply is sent after bus has reset, ! 268: * so there is no need to wait for the reset to complete. ! 269: */ ! 270: ! 271: if ( [PMUdriver ADBReset:(UInt32)current_thread():0:ADBcallback] == kPMUNoError ) { ! 272: waitForCallback(); ! 273: } ! 274: /* ! 275: * Okay, now attempt reassign the ! 276: * bus ! 277: */ ! 278: ! 279: //kprintf("adbprobe: probing\n"); ! 280: ! 281: /* Skip 0 -- its special! */ ! 282: for (i = 1; i < ADB_DEVICE_COUNT; i++) { ! 283: adb_devices[i].a_addr = i; ! 284: ! 285: //kprintf("adbprobe: probing %x\n", i); ! 286: ! 287: if (adb_is_dev_present(i)) { ! 288: ! 289: //kprintf("adbprobe: adb_is_dev_present\n"); ! 290: ! 291: adb_devices[i].a_dev_type = i; ! 292: adb_devices[i].a_flags |= ADB_FLAGS_UNRESOLVED; ! 293: } ! 294: } ! 295: ! 296: /* Now attempt to reassign the addresses */ ! 297: while (adb_find_unresolved_dev(&devnum)) { ! 298: freenum = adb_find_freedev(); ! 299: adb_move_dev(devnum, freenum); ! 300: ! 301: if (!adb_is_dev_present(freenum)) { ! 302: /* It didn't move.. damn! */ ! 303: adb_devices[devnum].a_flags &= ~ADB_FLAGS_UNRESOLVED; ! 304: printf("WARNING : ADB DEVICE %d having problems " ! 305: "probing!\n", devnum); ! 306: continue; ! 307: } ! 308: ! 309: if (!adb_is_dev_present(devnum)) { ! 310: /* no more at this address, good !*/ ! 311: /* Move it back.. */ ! 312: ! 313: adb_move_dev(freenum, devnum); ! 314: ! 315: /* Check the device to talk again.. */ ! 316: (void) adb_is_dev_present(devnum); ! 317: adb_devices[devnum].a_flags &= ~ADB_FLAGS_UNRESOLVED; ! 318: } else { ! 319: /* Found another device at the address, leave ! 320: * the first device moved to one side and set up ! 321: * newly found device for probing ! 322: */ ! 323: /* device_present already called on freenum above */ ! 324: adb_devices[freenum].a_flags &= ~ADB_FLAGS_UNRESOLVED; ! 325: ! 326: /* device_present already called on devnum above */ ! 327: adb_devices[devnum].a_dev_type = devnum; ! 328: adb_devices[devnum].a_flags |= ADB_FLAGS_UNRESOLVED; ! 329: #if 0 ! 330: printf("Found hidden device at %d, previous device " ! 331: "moved to %d\n", devnum, freenum); ! 332: #endif /* DEBUG */ ! 333: } ! 334: } ! 335: ! 336: /* ! 337: * Now build up a dev list bitmap and total device count ! 338: */ ! 339: ! 340: devp = adb_devices; ! 341: devlist = 0; ! 342: ! 343: for (i = 0; i < ADB_DEVICE_COUNT; i++, devp++) { ! 344: if ((devp->a_flags & ADB_FLAGS_PRESENT) == 0) ! 345: continue; ! 346: ! 347: devlist |= (1<<i); ! 348: adb_count++; ! 349: } ! 350: ! 351: ! 352: // ADBSetPollList calls the callback before it returns when ! 353: // autopolling is off. ! 354: if (HasPMU()) ! 355: { ! 356: [PMUdriver ADBSetPollList:devlist:0:0:NULL]; ! 357: //PG&E doesn't perform this hardware operation immediately ! 358: // so it's OK not to wait for callback ! 359: } ! 360: else ! 361: if ( [PMUdriver ADBSetPollList:devlist:(UInt32)current_thread():0:ADBcallback] == kPMUNoError) ! 362: { ! 363: waitForCallback(); ! 364: } ! 365: ! 366: ! 367: if ( [PMUdriver ADBSetPollRate:11:(UInt32)current_thread():0:ADBcallback] == kPMUNoError ) { ! 368: waitForCallback(); ! 369: } ! 370: ! 371: if ( [PMUdriver ADBPollEnable:(UInt32)current_thread():0:ADBcallback] == kPMUNoError ) { ! 372: waitForCallback(); ! 373: } ! 374: ! 375: if ( [PMUdriver ADBSetFileServerMode:(UInt32)current_thread():0:ADBcallback] == kPMUNoError ) { ! 376: waitForCallback(); ! 377: } ! 378: ! 379: ! 380: adb_initted = TRUE; ! 381: splx(s); ! 382: ! 383: return 1; ! 384: } ! 385: ! 386: void ! 387: adbattach( struct bus_device *device) ! 388: { ! 389: int i; ! 390: adb_device_t *devp = &adb_devices[0]; ! 391: ! 392: printf("\nadb0: %d devices on bus.\n", adb_count); ! 393: for (i = 0; i < ADB_DEVICE_COUNT; i++, devp++) { ! 394: if (devp->a_flags & ADB_FLAGS_PRESENT) { ! 395: printf(" %d: ", i); ! 396: switch (devp->a_dev_type) { ! 397: case ADB_DEV_PROTECT: ! 398: printf("security device"); ! 399: break; ! 400: case ADB_DEV_KEYBOARD: ! 401: printf("keyboard"); ! 402: break; ! 403: case ADB_DEV_MOUSE: ! 404: printf("mouse"); ! 405: break; ! 406: case ADB_DEV_TABLET: ! 407: printf("tablet"); ! 408: break; ! 409: case ADB_DEV_MODEM: ! 410: printf("modem"); ! 411: break; ! 412: case ADB_DEV_APPL: ! 413: printf("application device"); ! 414: break; ! 415: default: ! 416: printf("unknown device id=%d", i); ! 417: } ! 418: printf("\n"); ! 419: } ! 420: } ! 421: } ! 422: ! 423: /* ! 424: * adbopen ! 425: * ! 426: */ ! 427: ! 428: io_return_t ! 429: adbopen(dev_t dev, dev_mode_t flag, io_req_t ior) ! 430: { ! 431: return D_SUCCESS; ! 432: } ! 433: ! 434: void ! 435: adbclose(dev_t dev) ! 436: { ! 437: return; ! 438: } ! 439: ! 440: io_return_t ! 441: adbread(dev_t dev, io_req_t ior) ! 442: { ! 443: return D_INVALID_OPERATION; ! 444: } ! 445: ! 446: io_return_t ! 447: adbwrite(dev_t dev, io_req_t ior) ! 448: { ! 449: return D_INVALID_OPERATION; ! 450: } ! 451: ! 452: boolean_t ! 453: adbportdeath(dev_t dev, ipc_port_t port) ! 454: { ! 455: return FALSE; ! 456: } ! 457: ! 458: #if 0 ! 459: io_return_t ! 460: adbgetstatus(dev_t dev, dev_flavor_t flavor, dev_status_t data, ! 461: mach_msg_type_number_t *status_count) ! 462: { ! 463: /* DS1 ! 464: struct adb_info *info = (struct adb_info *) data; ! 465: struct adb_device *devp; ! 466: int i; ! 467: ! 468: switch (flavor) { ! 469: case ADB_GET_INFO: ! 470: devp = adb_devices; ! 471: for (i = 0; i < ADB_DEVICE_COUNT; i++, devp++) { ! 472: if ((devp->a_flags & ADB_FLAGS_PRESENT) == 0) ! 473: continue; ! 474: ! 475: info->a_addr = devp->a_addr; ! 476: info->a_type = devp->a_dev_type; ! 477: info->a_handler = devp->a_dev_handler; ! 478: info->a_orighandler = devp->a_dev_orighandler; ! 479: info++; ! 480: } ! 481: *status_count = (sizeof(struct adb_info)*adb_count)/sizeof(int); ! 482: break; ! 483: ! 484: case ADB_GET_COUNT: ! 485: *((unsigned int *) data) = adb_count; ! 486: *status_count = 1; ! 487: break; ! 488: ! 489: case ADB_READ_DATA: { ! 490: struct adb_regdata *reg = (struct adb_regdata *) data; ! 491: ! 492: reg->a_count = adb_reg_data.a_reply.a_bcount; ! 493: bcopy((char *) adb_reg_data.a_reply.a_buffer, ! 494: (char *) reg->a_buffer, adb_reg_data.a_reply.a_bcount); ! 495: *status_count = (sizeof(struct adb_regdata))/sizeof(int); ! 496: } ! 497: break; ! 498: ! 499: default: ! 500: return D_INVALID_OPERATION; ! 501: } ! 502: DS1 */ ! 503: return D_SUCCESS; ! 504: } ! 505: ! 506: io_return_t ! 507: adbsetstatus(dev_t dev, dev_flavor_t flavor, dev_status_t data, ! 508: mach_msg_type_number_t status_count) ! 509: { ! 510: /* DS1 ! 511: struct adb_info *info = (struct adb_info *) data; ! 512: struct adb_device *devp; ! 513: ! 514: switch (flavor) { ! 515: case ADB_SET_HANDLER: ! 516: if (info->a_addr < 1 || info->a_addr >= ADB_DEVICE_COUNT) ! 517: return D_NO_SUCH_DEVICE; ! 518: ! 519: devp = &adb_devices[info->a_addr]; ! 520: adb_set_handler(devp, info->a_handler); ! 521: if (devp->a_dev_handler != info->a_handler) ! 522: return D_READ_ONLY; ! 523: break; ! 524: ! 525: case ADB_READ_REG: { ! 526: struct adb_regdata *reg = (struct adb_regdata *) data; ! 527: ! 528: adb_init_request(&adb_reg_data); ! 529: ADB_BUILD_CMD2(&adb_reg_data, ADB_PACKET_ADB, ! 530: (ADB_ADBCMD_READ_ADB|(reg->a_addr<<4)|reg->a_reg)); ! 531: ! 532: adb_send(&adb_reg_data, TRUE); ! 533: ! 534: if (adb_reg_data.a_result != ADB_RET_OK) ! 535: return D_IO_ERROR; ! 536: ! 537: } ! 538: break; ! 539: ! 540: case ADB_WRITE_REG: { ! 541: struct adb_regdata *reg = (struct adb_regdata *) data; ! 542: ! 543: adb_init_request(&adb_reg_data); ! 544: ADB_BUILD_CMD2_BUFFER(&adb_reg_data, ADB_PACKET_ADB, ! 545: (ADB_ADBCMD_WRITE_ADB|(reg->a_addr<<4)|reg->a_reg), ! 546: reg->a_count, ®->a_buffer); ! 547: ! 548: adb_send(&adb_reg_data, TRUE); ! 549: ! 550: if (adb_reg_data.a_result != ADB_RET_OK) ! 551: return D_IO_ERROR; ! 552: } ! 553: break; ! 554: ! 555: default: ! 556: return D_INVALID_OPERATION; ! 557: } ! 558: DS1 */ ! 559: return D_SUCCESS; ! 560: } ! 561: #endif ! 562: ! 563: /* ! 564: * Register a routine which is to send events from all ! 565: * devices matching a given type. ! 566: */ ! 567: ! 568: void ! 569: adb_register_handler(int type, ! 570: void (*handler)(int number, unsigned char *packet, int count, void * ssp)) ! 571: { ! 572: int dev; ! 573: adb_device_t *devp; ! 574: ! 575: //kprintf("adb_register_handler: type = %08x, handler = %08x\n", ! 576: // type, handler); ! 577: ! 578: for (dev = 0; dev < ADB_DEVICE_COUNT; dev++) { ! 579: devp = &adb_devices[dev]; ! 580: ! 581: //kprintf("adb_register_handler: dev = %08x, devp = %08x, devp->a_dev_type = %08x\n", dev, devp, devp->a_dev_type); ! 582: ! 583: if (devp->a_dev_type != type) ! 584: continue; ! 585: ! 586: devp->a_flags |= ADB_FLAGS_REGISTERED; ! 587: devp->a_handler = handler; ! 588: } ! 589: } ! 590: ! 591: /* ! 592: * Register a routine to handle a dev at a specific address ! 593: */ ! 594: ! 595: void ! 596: adb_register_dev(int devnum, void (*handler)(int number, unsigned char *packet, int count, void * ssp)) ! 597: { ! 598: adb_device_t *devp; ! 599: ! 600: if (devnum < 0 || devnum > ADB_DEVICE_COUNT) ! 601: panic("adb_register: addr is out of range."); ! 602: ! 603: devp = &adb_devices[devnum]; ! 604: ! 605: devp->a_flags |= ADB_FLAGS_REGISTERED; ! 606: devp->a_handler = handler; ! 607: } ! 608: ! 609: ! 610: static void (*oldHandlers[ ADB_DEVICE_COUNT ])(int number, unsigned char *buffer, int bytes, void * ssp); ! 611: ! 612: void ! 613: borrow_adb( void (*handler)(int number, unsigned char *packet, int count, void * ssp)) ! 614: { ! 615: int dev; ! 616: adb_device_t *devp; ! 617: ! 618: for (dev = 1; dev < ADB_DEVICE_COUNT; dev++) { ! 619: devp = &adb_devices[dev]; ! 620: ! 621: if( devp->a_flags & ADB_FLAGS_REGISTERED) ! 622: oldHandlers[ dev] = devp->a_handler; ! 623: else ! 624: oldHandlers[ dev] = 0; ! 625: ! 626: devp->a_flags |= ADB_FLAGS_REGISTERED; ! 627: devp->a_handler = handler; ! 628: } ! 629: } ! 630: ! 631: void ! 632: return_adb( void ) ! 633: { ! 634: ! 635: int dev; ! 636: adb_device_t *devp; ! 637: ! 638: for (dev = 1; dev < ADB_DEVICE_COUNT; dev++) { ! 639: ! 640: devp = &adb_devices[dev]; ! 641: ! 642: if( oldHandlers[ dev] ) { ! 643: devp->a_flags |= ADB_FLAGS_REGISTERED; ! 644: devp->a_handler = oldHandlers[ dev]; ! 645: } else ! 646: devp->a_flags &= ~ADB_FLAGS_REGISTERED; ! 647: } ! 648: } ! 649: ! 650: ! 651: #if 0 ! 652: /* DS2... ! 653: void ! 654: adb_done(adb_request_t *req) ! 655: { ! 656: adb_packet_t *pack = &req->a_reply; ! 657: DS2 */ ! 658: /* Note, adb_busy is not reset because the CUDA chip ! 659: * needs time to settle back into an idle state. ! 660: * adb_busy will be reset in adb_next_request() when ! 661: * the CUDA driver is ready for the next one. ! 662: */ ! 663: /* DS2 ! 664: if (req->a_flags & ADB_IS_ASYNC) { ! 665: req->a_next = adb_async_pool; ! 666: adb_async_pool = req; ! 667: return; ! 668: } ! 669: ! 670: req->a_flags |= ADB_DONE; ! 671: ! 672: if (!adb_polling) { ! 673: if (req->a_done) ! 674: req->a_done(req); ! 675: else thread_wakeup((event_t) req); ! 676: } ! 677: } ! 678: ! 679: void ! 680: adb_unsolicited_done(adb_packet_t *pack, void * ssp) ! 681: { ! 682: adb_device_t *devp; ! 683: int devnum; ! 684: ! 685: DS2 */ ! 686: /* adb_next_request() will reset this when CUDA ! 687: * asks for the next request.. until then the bus ! 688: * has to become idle ! 689: */ ! 690: /* DS2 ! 691: adb_busy = TRUE; ! 692: ! 693: devnum = pack->a_header[2] >> 4; ! 694: devp = &adb_devices[devnum]; ! 695: ! 696: if (devp->a_flags & ADB_FLAGS_REGISTERED) ! 697: devp->a_handler(devnum, pack->a_buffer, pack->a_bcount, ssp); ! 698: } ! 699: ...DS2 */ ! 700: ! 701: #endif ! 702: ! 703: int ! 704: adb_readreg(int number, int reg, unsigned short *value) ! 705: { ! 706: if ([PMUdriver ADBRead:number :reg :(UInt32)current_thread() :0 :ADBReadCallback] != kPMUNoError) { ! 707: return ADB_RET_UNEXPECTED_RESULT; ! 708: } ! 709: ! 710: waitForCallback(); ! 711: ! 712: if ( read_length ) { ! 713: *value = (read_buffer[0] << 8) | read_buffer[1]; ! 714: return ADB_RET_OK; ! 715: } ! 716: else { ! 717: return ADB_RET_TIMEOUT; ! 718: } ! 719: } ! 720: ! 721: int ! 722: adb_readreg2(int number, int reg, unsigned char *buffer, int *length) ! 723: { ! 724: if ([PMUdriver ADBRead:number :reg :(UInt32)current_thread() :0 :ADBReadCallback2] != kPMUNoError) { ! 725: return ADB_RET_UNEXPECTED_RESULT; ! 726: } ! 727: waitForCallback(); ! 728: ! 729: *length = read_length; ! 730: if ( read_length ) { ! 731: int i; ! 732: for ( i = 0; i < read_length; i++ ) { ! 733: buffer[i] = read_buffer[i]; ! 734: } ! 735: if ( reg == 3 ) { // snoop on reads from reg 3 ! 736: adb_devices[number].a_dev_handler = read_buffer[1]; ! 737: } ! 738: ! 739: return ADB_RET_OK; ! 740: } ! 741: else { ! 742: return ADB_RET_TIMEOUT; ! 743: } ! 744: ! 745: } ! 746: ! 747: ! 748: int ! 749: adb_flush(int number) ! 750: { ! 751: if ([PMUdriver ADBFlush: number :(UInt32)current_thread() :0 :ADBReadCallback] != kPMUNoError) { ! 752: return ADB_RET_UNEXPECTED_RESULT; ! 753: } ! 754: ! 755: waitForCallback(); ! 756: ! 757: return ADB_RET_OK; ! 758: } ! 759: ! 760: int ! 761: adb_writereg(int number, int reg, unsigned short value) ! 762: { ! 763: UInt8 buffer[2]; ! 764: ! 765: buffer[0] = value >> 8; ! 766: buffer[1] = value & 0xff; ! 767: ! 768: if ([PMUdriver ADBWrite:number :reg :2 :buffer :(UInt32)current_thread() :0 :ADBcallback] != kPMUNoError) { ! 769: return ADB_RET_UNEXPECTED_RESULT; ! 770: } ! 771: ! 772: waitForCallback(); ! 773: return ADB_RET_OK; ! 774: } ! 775: ! 776: int ! 777: adb_writereg2(int number, int reg, unsigned char *buffer, int length) ! 778: { ! 779: if ([PMUdriver ADBWrite:number :reg :length :buffer :(UInt32)current_thread() :0 :ADBcallback] != kPMUNoError) { ! 780: return ADB_RET_UNEXPECTED_RESULT; ! 781: } ! 782: ! 783: waitForCallback(); ! 784: return ADB_RET_OK; ! 785: } ! 786: ! 787: void ! 788: adb_writereg_async(int number, int reg, unsigned short value) ! 789: { ! 790: UInt8 buffer[2]; ! 791: ! 792: buffer[0] = value >> 8; ! 793: buffer[1] = value & 0xff; ! 794: ! 795: if ([PMUdriver ADBWrite:number :reg :2 :buffer :0 :0:NULL] != kPMUNoError) { ! 796: return; ! 797: } ! 798: ! 799: return; ! 800: } ! 801: ! 802: #if 0 ! 803: /* DS1 ! 804: void ! 805: adb_send(adb_request_t *adb, boolean_t wait) ! 806: { ! 807: spl_t s; ! 808: ! 809: if (!adb_polling) ! 810: s = spltty(); ! 811: ! 812: adb->a_reply.a_bsize = sizeof(adb->a_reply.a_buffer); ! 813: ! 814: if (wait) ! 815: adb->a_done = NULL; ! 816: ! 817: adb->a_flags &= ~ADB_DONE; ! 818: adb->a_next = NULL; ! 819: ! 820: if (adb_busy) { ! 821: if (adb_queue_root == NULL) ! 822: adb_queue_root = adb_queue_end = adb; ! 823: else { ! 824: adb_queue_end->a_next = adb; ! 825: adb_queue_end = adb; ! 826: } ! 827: if (adb_polling) { ! 828: adb_hardware->ao_poll(); ! 829: if ((adb->a_flags & ADB_DONE) == 0) ! 830: panic("adb_send: request did not complete?!?"); ! 831: } ! 832: } else { ! 833: adb_busy = TRUE; ! 834: adb_hardware->ao_send(adb); ! 835: } ! 836: ! 837: if (wait && !adb_polling) { ! 838: simple_lock(&adb->a_lock); ! 839: // simon: was thread_sleep_simple_lock ! 840: thread_sleep((event_t) adb, simple_lock_addr(adb->a_lock), TRUE); ! 841: } ! 842: ! 843: if (!adb_polling) ! 844: splx(s); ! 845: } ! 846: adb_request_t * ! 847: adb_next_request() ! 848: { ! 849: adb_request_t *adb; ! 850: ! 851: adb = adb_queue_root; ! 852: ! 853: if (adb) { ! 854: adb_queue_root = adb_queue_root->a_next; ! 855: if (adb_queue_root == NULL) ! 856: adb_queue_end = NULL; ! 857: adb_busy = TRUE; ! 858: } else adb_busy = FALSE; ! 859: ! 860: ! 861: return adb; ! 862: } ! 863: void ! 864: adb_poll(void) ! 865: { ! 866: boolean_t save_poll = adb_polling; ! 867: ! 868: adb_polling = TRUE; ! 869: ! 870: adb_hardware->ao_poll(); ! 871: ! 872: adb_polling = save_poll; ! 873: } ! 874: DS1 */ ! 875: ! 876: #endif ! 877: ! 878: // The PMU driver is finished sending the last command. ! 879: // Wake up the thread that is waiting. ! 880: void ADBcallback(id unused, UInt32 refnum, UInt32 length, UInt8* buffer) ! 881: { ! 882: clear_wait(refnum,0,FALSE); ! 883: } ! 884: ! 885: ! 886: // The PMU driver has received data from the PMU that is the result of our ! 887: // previous read. Copy the data and wake up the thread. ! 888: void ADBReadCallback(id unused, UInt32 refnum, UInt32 length, UInt8* buffer) ! 889: { ! 890: if (buffer != NULL) { ! 891: read_buffer[0] = *buffer; ! 892: read_buffer[1] = *(buffer+1); ! 893: } ! 894: ! 895: read_length = length; ! 896: ! 897: clear_wait(refnum,0,FALSE); ! 898: } ! 899: ! 900: ! 901: // The PMU driver has received data from the PMU that is the result of our ! 902: // previous read. Copy the data and wake up the thread. ! 903: void ADBReadCallback2(id unused, UInt32 refnum, UInt32 length, UInt8* buffer) ! 904: { ! 905: int i; ! 906: ! 907: for ( i = 0; i < length; i++ ) { ! 908: read_buffer[i] = buffer[i]; ! 909: } ! 910: read_length = length; ! 911: ! 912: clear_wait(refnum,0,FALSE); ! 913: } ! 914: ! 915: ! 916: // We have sent a command to the PMU driver with current_thread as the refnum. ! 917: // Sleep until it has sent the command to the PMU. ! 918: void waitForCallback(void) ! 919: { ! 920: assert_wait(current_thread(), FALSE); ! 921: thread_block(); ! 922: } ! 923: ! 924: // Called by the keyboard driver. Interrupts are off. Call PMU/Cuda ! 925: // to let it service any interrupts. ! 926: void CheckADBPoll(void) ! 927: { ! 928: [PMUdriver poll_device]; ! 929: } ! 930: ! 931: ! 932: // Autopoll data has arrived from the PMU. ! 933: void inputHandler(id unused, UInt32 refnum, UInt32 devnum, UInt32 length, UInt8* buffer) ! 934: { ! 935: adb_device_t *devp; ! 936: ! 937: //kprintf("inputHandler: refnum: %08x, devnum = %08x, length = %08x, buffer = %08x\n", refnum, devnum, length, buffer); ! 938: //kprintf("buffer[0] = %02x, buffer[1] = %02x\n", buffer[0], buffer[1]); ! 939: ! 940: devp = &adb_devices[devnum]; ! 941: ! 942: //kprintf("devp = %08x, devp->a_handler = %08x\n", devp, devp->a_handler); ! 943: ! 944: if (devp->a_flags & ADB_FLAGS_REGISTERED) { ! 945: devp->a_handler(devnum, buffer, length, 0); ! 946: } ! 947: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.