Annotation of XNU/iokit/Drivers/usb/drvAppleKeyboard/AppleKeyboard.cpp, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: /*
                     23:  * Copyright (c) 1998, 1999 Apple Computer, Inc.  All rights reserved.
                     24:  *
                     25:  * HISTORY
                     26:  *
                     27:  */
                     28: #include <libkern/OSByteOrder.h>
                     29: 
                     30: #include "AppleKeyboard.h"
                     31: #include <IOKit/hidsystem/IOHIPointing.h>
                     32: #include <IOKit/IOBufferMemoryDescriptor.h>
                     33: #include <IOKit/usb/IOUSBInterface.h>
                     34: #include <IOKit/usb/IOUSBPipe.h>
                     35: #include <IOKit/usb/IOUSBController.h>
                     36: 
                     37: extern "C" {
                     38: #include <pexpert/pexpert.h>
                     39: }
                     40: 
                     41: 
                     42: #define super IOHIKeyboard
                     43: #define self this
                     44: #define DEBUGGING_LEVEL 0
                     45: 
                     46: OSDefineMetaClassAndStructors(AppleKeyboard, IOHIKeyboard)
                     47: 
                     48: extern unsigned char usb_2_adb_keymap[];  //In Cosmo_USB2ADB.cpp
                     49: 
                     50: static IOUSBController *sPollControl;
                     51: static IOUSBPipe *sPollPipe;
                     52: static UInt8 sBuffer[8];
                     53: static IOMemoryDescriptor *sBufDesc;
                     54: static bool sComplete = true;
                     55: 
                     56: 
                     57: static void bodgeComplete(void *target, void * parameter, IOReturn status, UInt32 bufferSizeRemaining)
                     58: {
                     59:     sComplete = true;
                     60: }
                     61: 
                     62: static int PE_usb_poll_input(unsigned int options, char * c)
                     63: {
                     64:     static char        adbkeycodes2ascii[] = "asdfhgzxcv_bqwer"//00
                     65:                                     "yt123465=97-80]o" //10
                     66:                                     "u[ip\nlj'k;_,/nm."        //20
                     67:                                     "\t_";             //30
                     68:     *c = 0xff;
                     69: 
                     70:     if(!sPollPipe)
                     71:        return 0;
                     72:     if(sComplete) {
                     73:         IOUSBCompletion        completion;
                     74:        sComplete = false;
                     75: 
                     76:         *c = adbkeycodes2ascii[usb_2_adb_keymap[sBuffer[2]]];
                     77:         completion.target = 0;
                     78:         completion.action = bodgeComplete;
                     79:         completion.parameter = 0;
                     80: 
                     81:         sPollControl->PolledRead(
                     82:                     sPollPipe->address()               /*functionAddress*/,
                     83:                     sPollPipe->endpoint()->number      /*endpointNumber*/,
                     84:                     completion                         /*completion*/,
                     85:                     sBufDesc                           /*buffer*/,
                     86:                     true                               /*bufferRounding*/,
                     87:                     sizeof(sBuffer)                    /*bufferSize*/);
                     88:     }
                     89:     else
                     90:         sPollControl->pollInterrupts(bodgeComplete);   // Only complete our transactions
                     91: 
                     92:     return 0;
                     93: }
                     94: 
                     95: void usb_asyncLED ( AppleKeyboard * me );
                     96: AppleKeyboard  *glob_usbkeyboard_obj;
                     97: 
                     98: bool AppleKeyboard::start(IOService * provider)
                     99: {
                    100:     IOReturn                   err = 0;
                    101:     
                    102:     if( !super::start(provider))
                    103:         return (false);
                    104: 
                    105:     // remember my device
                    106:     _interface         = OSDynamicCast(IOUSBInterface, provider);
                    107:     _deviceDescriptor  = _interface->deviceDescriptor();
                    108:     _prevent_LED_set    = FALSE;
                    109: 
                    110:     //Following 3 lines moved here from Simulate_ADB_Event to make multiple 
                    111:     // keyboards work correctly.  The instance variables cannot be shared
                    112:     // between each instance of this driver for each USB keyboard.
                    113:     prev_bytes_read=8;
                    114:     oldmodifier = 0xff;
                    115:     bzero( old_array, kUSB_LOWSPEED_MAXPACKET);
                    116: 
                    117: 
                    118:     if (_interface->open(self) == false) return false;
                    119: 
                    120:     //Fix hardware bug in iMac USB keyboard mapping for ISO keyboards
                    121:     //kprintf("\nUSB product = %x, vendor = %x\n", _deviceDescriptor->product, _deviceDescriptor->vendor);
                    122:     if ( _deviceDescriptor)    //just to be safe
                    123:     {
                    124:         if (_deviceDescriptor->vendor == 0xac05)  //Apple Corp. vendor ID, not byte swapped
                    125:         {
                    126:             switch (_deviceDescriptor->product)
                    127:             {  
                    128:                 case 0x0201: //North American iMac keyboard
                    129:                 break;   // return 18 
                    130:                 case 0x0203: //38=Japanese.  34 is adjustable JIS
                    131:                 break;  // return 34;
                    132:                 case 0x0202: //Arabic, other ISO such as German
                    133:                 //Swap two ISO keys around
                    134:                 usb_2_adb_keymap[0x35] = 0x0a;  //Cosmo key18 swaps with key74, 0a is ADB keycode
                    135:                 usb_2_adb_keymap[0x64] = 0x32;
                    136:                break;
                    137:                         // return 21; //21 is Apple ISO Extended Keyboard
                    138:                 default:
                    139:                 //return 18;
                    140:                break;
                    141:             }
                    142:         }
                    143: 
                    144: 
                    145: 
                    146:         if (_deviceDescriptor->vendor == 0x5e04)  //Microsoft ID
                    147:         {
                    148:        //Figure out what to do with Microsoft keyboard later
                    149: 
                    150:         //if (usb_kbd_product_id == 0x000b)   //Natural USB+PS/2 keyboard
                    151:             //return 18;
                    152:         }    
                    153:     }
                    154: 
                    155:     do {
                    156:         IOLog("%s: USB Generic Keyboard @ %d\n", getName(), _interface->address());
                    157: 
                    158: #if 0
                    159: 
                    160: kprintf("Adam: Class is %d\n", req.theClass);  //3 HID
                    161: kprintf("Adam: SubClass is %d\n", req.subClass);  //1
                    162: kprintf("Adam: Protocol is %d\n", req.protocol); //1 keyboard
                    163: 
                    164: kprintf("Adam: Type is %d\n", (_interface->endpoints[0])->transferType); //I get 1
                    165: kprintf("Adam: Number is %d\n", (_interface->endpoints[0])->number); // I get 1
                    166: 
                    167: #endif
                    168: 
                    169:         //setAlphaLockFeedback(false);  //Disable caps lock LED at first
                    170: 
                    171:         IOUSBFindEndpointRequest request;
                    172:         request.type = kUSBInterrupt;
                    173:         request.direction = kUSBIn;
                    174:         _interruptPipe = _interface->findNextPipe(NULL, &request);
                    175: 
                    176:         if(!_interruptPipe)
                    177:             return false;
                    178: 
                    179:         _maxPacketSize = request.maxPacketSize;
                    180:         _buffer = IOBufferMemoryDescriptor::withCapacity(8, kIODirectionIn);
                    181: 
                    182:         _completion.target = (void *)self;
                    183:         _completion.action = (IOUSBCompletionAction) &AppleKeyboard::readHandler;
                    184:         _completion.parameter = (void *)0;  // not used
                    185: 
                    186:         _buffer->setLength(_maxPacketSize); // shouldn't this be _maxPacketSize?
                    187: 
                    188:         if ((err = _interruptPipe->read(_buffer, &_completion)))
                    189:             break;
                    190: 
                    191: #if (DEBUGGING_LEVEL > 0)
                    192:         //printInterfaceDescriptor(_interface->descriptor);
                    193: #endif
                    194: 
                    195:         // Save stuff for polled mode
                    196:         sPollControl = _interface->bus();
                    197:         sPollPipe = _interruptPipe;
                    198:         sBufDesc = IOMemoryDescriptor::withAddress(sBuffer, 8, kIODirectionIn);
                    199:        PE_poll_input = PE_usb_poll_input;
                    200: 
                    201:         return(true);
                    202: 
                    203:     } while (false);
                    204: 
                    205:     IOLog("%s: aborting startup.  err = %d\n", getName(), err);
                    206: 
                    207:     provider->close(this);
                    208:     stop(provider);
                    209: 
                    210:     return(false);
                    211: }
                    212: 
                    213: void AppleKeyboard::stop(IOService * provider)
                    214: {
                    215:     if (_buffer) {
                    216:        _buffer->release();
                    217:         _buffer = 0;
                    218:     }
                    219:     if(sPollPipe == _interruptPipe) {
                    220:         sPollControl = NULL;
                    221:         sPollPipe = NULL;
                    222:         sBufDesc->release();
                    223:        sBufDesc = NULL;
                    224:     }
                    225:     super::stop(provider);
                    226: }
                    227: 
                    228: void AppleKeyboard::test_myusb_f1(void)
                    229: {
                    230: /*
                    231:     char               dummy[8];
                    232:     IOReturn           err = kIOReturnSuccess;
                    233:     OSData             *writebuf;
                    234:     IOUSBPipe *        tinterruptPipe;
                    235: 
                    236:        writebuf = OSData::withCapacity(8);
                    237:        err = _device->openPipe(&tinterruptPipe, _interface->endpoints[0]);
                    238:        kprintf("Adam1: err is %x\n", err);
                    239:        dummy[0] = 0xff;
                    240:        dummy[1] = 0xff;
                    241:        dummy[2] = 0xff;
                    242:        dummy[3] = 0xff;
                    243:        dummy[4] = 0xff;
                    244:        dummy[5] = 0xff;
                    245:        dummy[6] = 0xff;
                    246:        dummy[7] = 0xff;
                    247: 
                    248:        writebuf->appendBytes(dummy, 8);
                    249: //     err = _device->write(writebuf, tinterruptPipe);
                    250:        kprintf("Adam2: err is %x\n", err);
                    251:        //deallocate writebuf
                    252: */
                    253: }
                    254: 
                    255: 
                    256: //bits = 2 is Caps Lock, I haven't tried anything else.  0 clears all
                    257: void AppleKeyboard::Set_LED_States(UInt8 bits)
                    258: {
                    259:     IOReturn    err = kIOReturnSuccess;
                    260:     IOUSBCompletion    completion;
                    261: 
                    262: 
                    263:     if (_prevent_LED_set)
                    264:         return; 
                    265: 
                    266:     //_request and _hid_report must be static because the deviceRequest() call
                    267:     // is asynchronous.
                    268: 
                    269:     _request.rqDirection = kUSBOut;
                    270:     _request.rqType = kUSBClass;
                    271:     _request.rqRecipient = kUSBInterface;
                    272:     _request.bRequest = kHIDRqSetReport;  //Set Report in HID specs
                    273:     OSWriteLittleInt16(&_request.wValue, 0, (UInt16) kHIDRtOutputReport << 8 );
                    274:     OSWriteLittleInt16(&_request.wIndex, 0,
                    275:                _interface->interfaceDescriptor()->interfaceNumber); // 0 for iMac keyboards
                    276:     OSWriteLittleInt16(&_request.wLength, 0, 1); // MacOS 8.5 hard-codes it to 1 byte length
                    277:     _hid_report[0] = bits;  // 2 to set LED, 0 to clear all LEDs
                    278:     _hid_report[1] = 0;
                    279:     _request.pData = (void *)_hid_report;
                    280: 
                    281:     completion.target = (void *)self;
                    282:     completion.action = &AppleKeyboard::setLEDHandler;
                    283:     completion.parameter = (void *)0;
                    284:     err = _interface->deviceRequest(&_request, &completion);
                    285:     return;
                    286: 
                    287: }
                    288: 
                    289: 
                    290: extern "C" { 
                    291:        void Debugger( const char * ); 
                    292:        void boot(int paniced, int howto, char * command);
                    293: #define RB_BOOT                1       /* Causes reboot, not halt.  Is in xnu/bsd/sys/reboot.h */
                    294: 
                    295: }
                    296: 
                    297: 
                    298: //This helper function is only called by StartHandler below.  key_ptr points
                    299: // to 8 (kUSB_LOWSPEED_MAXPACKET) valid bytes of data
                    300: void AppleKeyboard::Simulate_ADB_Event(UInt8 *key_ptr, UInt32 bytes_read)
                    301: {
                    302:     UInt8              alpha, modifier=0;
                    303:     bool               found;
                    304:     AbsoluteTime       now;
                    305:     UInt8              seq_key, i;//counter for alpha keys pressed.
                    306: 
                    307: /**
                    308: UInt8          *kbdData;
                    309: kbdData = key_ptr;
                    310: kprintf("Num = %d x%x  x%x  x%x  x%x  x%x  x%x  x%x  x%x\n",
                    311: bytes_read, *kbdData, *(kbdData +1),
                    312: *(kbdData+2), *(kbdData +3),
                    313: *(kbdData+4), *(kbdData +5),
                    314: *(kbdData+6), *(kbdData +7)
                    315: );
                    316: **/
                    317: 
                    318:     // Test for the keyboard bug where all the keys are 0x01. JDC.
                    319:     found = true;
                    320:     for (seq_key = 2; seq_key < prev_bytes_read; seq_key++) {
                    321:       if (*(key_ptr + seq_key) != 1) found = false;
                    322:     }
                    323:     if (found) return;
                    324: 
                    325: 
                    326:     if (bytes_read > kUSB_LOWSPEED_MAXPACKET)  // 8 bytes
                    327:     {
                    328:        bytes_read = kUSB_LOWSPEED_MAXPACKET;  //Limit myself to low-speed keyboards
                    329:     }
                    330:     modifier = *key_ptr;
                    331:     //alpha = *(key_ptr +2);  // byte +1 seems to be unused
                    332:     //adb_code = usb_2_adb_keymap[alpha];
                    333: 
                    334:     //Handle new key information.  The first byte is a set of bits describing
                    335:     //  which modifier keys are down.  The 2nd byte never seems to be used.
                    336:     //  The third byte is the first USB key down, and the fourth byte is the
                    337:     //  second key down, and so on.
                    338:     //When a key is released, there's no code... just a zero upon USB polling
                    339:     //8/2/99 A.W. fixed Blue Box's multiple modifier keys being pressed 
                    340:     //   simultaneously.  The trick is if a modifier key DOWN event is reported,
                    341:     //   and another DOWN is reported, then Blue Box loses track of it.  I must
                    342:     //   report a UP key event first, or else avoid resending the DOWN event.
                    343: 
                    344:  
                    345:     //SECTION 1. Handle modifier keys here first
                    346:     if (modifier == oldmodifier) 
                    347:     {
                    348:         //Do nothing.  Same keys are still pressed, or if 0 then none pressed
                    349:        // so don't overload the HID system with useless events.
                    350:     }
                    351:     else //Modifiers may or may not be pressed right now
                    352:     {
                    353:        //kprintf("mod is %x\n", modifier);
                    354:         clock_get_uptime(&now);
                    355: 
                    356:         //left-hand CONTROL modifier key
                    357:         if ((modifier & kUSB_LEFT_CONTROL_BIT) && !(oldmodifier & kUSB_LEFT_CONTROL_BIT))
                    358:         {
                    359:             dispatchKeyboardEvent(0x36, true, now);  //ADB left-hand CONTROL
                    360:            _control_key = true;        //determine if we reboot CPU.  Is instance variable.
                    361:         }
                    362:        else if ((oldmodifier & kUSB_LEFT_CONTROL_BIT) && !(modifier & kUSB_LEFT_CONTROL_BIT))
                    363:        {
                    364:            //Now check for released modifier keys
                    365:            dispatchKeyboardEvent(0x36, false, now); 
                    366:            _control_key = false;       
                    367:        }
                    368: 
                    369:         //right-hand CONTROL modifier
                    370:         if ((modifier & kUSB_RIGHT_CONTROL_BIT) && !(oldmodifier & kUSB_RIGHT_CONTROL_BIT))
                    371:         {
                    372:             dispatchKeyboardEvent(0x7d, true, now);  //right-hand CONTROL
                    373:            _control_key = true;        //determine if we reboot CPU.  Is instance variable.
                    374:         }
                    375:        else if ((oldmodifier & kUSB_RIGHT_CONTROL_BIT) && !(modifier & kUSB_RIGHT_CONTROL_BIT))
                    376:        {
                    377:            dispatchKeyboardEvent(0x7d, false, now); 
                    378:            _control_key = false;       
                    379:        }
                    380: 
                    381:         //left-hand SHIFT
                    382:         if ((modifier & kUSB_LEFT_SHIFT_BIT) && !(oldmodifier & kUSB_LEFT_SHIFT_BIT))
                    383:         {
                    384:            // Debugger("LEFT SHIFT");
                    385: 
                    386:             dispatchKeyboardEvent(0x38, true, now);
                    387:         }
                    388:        else if ((oldmodifier & kUSB_LEFT_SHIFT_BIT) && !(modifier & kUSB_LEFT_SHIFT_BIT))
                    389:        {
                    390:            dispatchKeyboardEvent(0x38, false, now); 
                    391:        }
                    392: 
                    393:         //right-hand SHIFT
                    394:         if ((modifier & kUSB_RIGHT_SHIFT_BIT) && !(oldmodifier & kUSB_RIGHT_SHIFT_BIT))
                    395:         {
                    396:             dispatchKeyboardEvent(0x7b, true, now);
                    397:         }
                    398:        else if ((oldmodifier & kUSB_RIGHT_SHIFT_BIT) && !(modifier & kUSB_RIGHT_SHIFT_BIT))
                    399:        {
                    400:            dispatchKeyboardEvent(0x7b, false, now); 
                    401:        }
                    402: 
                    403:         if ((modifier & kUSB_LEFT_ALT_BIT) && !(oldmodifier & kUSB_LEFT_ALT_BIT))
                    404:         {
                    405:             dispatchKeyboardEvent(0x3a, true, now);
                    406:         }
                    407:        else if ((oldmodifier & kUSB_LEFT_ALT_BIT) && !(modifier & kUSB_LEFT_ALT_BIT))
                    408:        {
                    409:            dispatchKeyboardEvent(0x3a, false, now); 
                    410:        }
                    411: 
                    412:         if ((modifier & kUSB_RIGHT_ALT_BIT) && !(oldmodifier & kUSB_RIGHT_ALT_BIT))
                    413:         {
                    414:             dispatchKeyboardEvent(0x7c, true, now);
                    415:         }
                    416:        else if ((oldmodifier & kUSB_RIGHT_ALT_BIT) && !(modifier & kUSB_RIGHT_ALT_BIT))
                    417:        {
                    418:            dispatchKeyboardEvent(0x7c, false, now); 
                    419:        }
                    420: 
                    421:         if ((modifier & kUSB_LEFT_FLOWER_BIT) && !(oldmodifier & kUSB_LEFT_FLOWER_BIT))
                    422:         {
                    423:             dispatchKeyboardEvent(0x37, true, now);
                    424:            _flower_key = true; //determine if we go into kernel debugger, or reboot CPU
                    425:         }
                    426:        else if ((oldmodifier & kUSB_LEFT_FLOWER_BIT) && !(modifier & kUSB_LEFT_FLOWER_BIT))
                    427:        {
                    428:            dispatchKeyboardEvent(0x37, false, now); 
                    429:            _flower_key = false;
                    430:        }
                    431: 
                    432:         if ((modifier & kUSB_RIGHT_FLOWER_BIT) && !(oldmodifier & kUSB_RIGHT_FLOWER_BIT))
                    433:         {
                    434:             //dispatchKeyboardEvent(0x7e, true, now);
                    435:            //WARNING... NeXT only recognizes left-hand flower key, so
                    436:            //  emulate that for now
                    437:            dispatchKeyboardEvent(0x37, true, now);
                    438:            _flower_key = true; 
                    439:         }
                    440:        else if ((oldmodifier & kUSB_RIGHT_FLOWER_BIT) && !(modifier & kUSB_RIGHT_FLOWER_BIT))
                    441:        {
                    442:            dispatchKeyboardEvent(0x37, false, now); 
                    443:            _flower_key = false;
                    444:        }
                    445: 
                    446:     }
                    447: 
                    448:     //SECTION 2. Handle regular alphanumeric keys now.  Look first at previous keystrokes.
                    449:     //  Alphanumeric portion of HID report starts at byte +2.
                    450: 
                    451:     for (seq_key = 2; seq_key < prev_bytes_read; seq_key++)
                    452:     {
                    453:         alpha = old_array[seq_key];
                    454:        if (alpha == 0) //No keys pressed
                    455:        {
                    456:            break;
                    457:        }
                    458:        found = false;
                    459:        for (i = 2; i < bytes_read; i++)  //Look through current keypresses
                    460:        {
                    461:             if (alpha == *(key_ptr + i))
                    462:            {
                    463:                found = true;   //This key has been held down for a while, so do nothing.
                    464:                break;          //   Autorepeat is taken care of by IOKit.
                    465:            }
                    466:        }
                    467:        if (!found)
                    468:        {
                    469:            clock_get_uptime(&now);
                    470:            if (alpha == 0x39)    //This is USB Caps Lock scan code
                    471:            {
                    472:                if (!_capsLockState)
                    473:                 {
                    474:                    dispatchKeyboardEvent(usb_2_adb_keymap[0x39], false, now);
                    475:                    //Only dispatch if we're in the correct state for Caps Lock
                    476:                    Set_LED_States(0);
                    477:                }
                    478:            }
                    479:            else  //For any other keys except LED-setting keys, dispatch immediately
                    480:            {
                    481:                dispatchKeyboardEvent(usb_2_adb_keymap[alpha], false, now);  //KEY UP
                    482:            }
                    483:        }
                    484:     }
                    485: 
                    486:     //Now take care of KEY DOWN.  
                    487:     for (seq_key = 2; seq_key < bytes_read; seq_key++)
                    488:     {
                    489:         alpha = *(key_ptr + seq_key);
                    490:        if (alpha == 0) //No keys pressed
                    491:        {
                    492:            break;
                    493:        }
                    494:        else if (alpha == 0x66)    //POWER ON key
                    495:        {
                    496:            if ((_control_key) && (_flower_key))  //User wants to reboot
                    497:            {
                    498:                boot( RB_BOOT, 0, 0 );  //call to xnu/bsd/kern/kern_shutdown.c
                    499:            }
                    500:            if (_flower_key)  // Apple CMD modifier must be simultaneously held down
                    501:            {
                    502:                PE_enter_debugger("USB Programmer Key");
                    503:                //In xnu/pexpert/ppc/pe_interrupt.c  and defined in pexpert.h above
                    504:            }
                    505:            //The reason this kernel debugger call is made here instead of KEY UP
                    506:            //  is that the HID system will see the POWER key and bring up a
                    507:            //  dialog box to shut down the computer, which is not what we want.
                    508:        }
                    509: 
                    510:        //Don't dispatch the same key again which was held down previously
                    511:        found = false;
                    512:        for (i = 2; i < prev_bytes_read; i++)
                    513:        {
                    514:             if (alpha == old_array[i])
                    515:            {
                    516:                found = true;
                    517:                break;
                    518:            }
                    519:        }
                    520:        if (!found)
                    521:        {
                    522:                    clock_get_uptime(&now);
                    523:            //If Debugger() is triggered then I shouldn't show the restart dialog
                    524:            //  box, but I think developers doing kernel debugging can live with
                    525:            //  this minor incovenience.  Otherwise I need to do more checking here.
                    526: 
                    527:            if (alpha == 0x39)    //This is USB Caps Lock scan code
                    528:            {
                    529:                if (_capsLockState)
                    530:                 {
                    531:                    _capsLockState = 0;
                    532:                    //Don't do anything else, wait for KEY_UP loop above to handle it
                    533:                 }
                    534:                else
                    535:                {
                    536:                    _capsLockState = 1;
                    537:                    Set_LED_States(kUSB_CAPSLOCKLED_SET);  // kUSB_CAPSLOCKLED_SET  = 2
                    538:                }
                    539:            }
                    540: 
                    541:            dispatchKeyboardEvent(usb_2_adb_keymap[alpha], true, now);
                    542:        }
                    543:     }
                    544: 
                    545:     //Save the history for next time
                    546:     oldmodifier = modifier;
                    547:     prev_bytes_read = bytes_read;
                    548:     for (i=0; i< bytes_read; i++)  //guaranteed not to exceed 8
                    549:     {
                    550:        old_array[i] = *(key_ptr + i);
                    551:     }
                    552: 
                    553: }
                    554: 
                    555: 
                    556: 
                    557: void AppleKeyboard::setLEDHandler(void *               parameter,
                    558:                                   IOReturn             status,
                    559:                                   UInt32               bufferSizeRemaining)
                    560: {
                    561:     if (status)
                    562:     {       
                    563:         //Setting the LED causes problems on CMD USB controller on MacOSX, 
                    564:         //  so if error then prevent further attempts.  Log the failure 
                    565:         IOLog("USB Keyboard Caps Lock LED failed\n");
                    566:         kprintf("USB Keyboard Caps Lock LED failed\n");
                    567:         _prevent_LED_set = TRUE;
                    568:     }   
                    569: }
                    570: 
                    571: void AppleKeyboard::readHandler(void *                 parameter,
                    572:                                 IOReturn       status,
                    573:                                 UInt32         bufferSizeRemaining)
                    574: {
                    575:     IOReturn                   err = kIOReturnSuccess;
                    576: 
                    577:     // Handle the error if any
                    578:     switch (status)
                    579:     {
                    580:         case kIOReturnSuccess:
                    581:             break;
                    582: 
                    583:         case kIOReturnOverrun:
                    584:             // Not sure what to do with this error.  It means more data
                    585:             // came back than the size of a descriptor.  Hmmm.  For now
                    586:             // just ignore it and assume the data that did come back is
                    587:             // useful.
                    588:             IOLog("%s: overrun error.  ignoring.\n", getName());
                    589:             break;
                    590: 
                    591:         case kIOReturnNotResponding:
                    592:             // This probably means the device was unplugged.  Now
                    593:             // we need to close the driver.
                    594:             IOLog("%s: Device unplugged.  Goodbye\n", getName());
                    595:             goto close;
                    596: 
                    597:         default:
                    598:             // We should handle other errors more intelligently, but
                    599:             // for now just return and assume the error is recoverable.
                    600:             IOLog("%s: error %d reading interrupt pipe\n", getName(), status);
                    601:             goto queueAnother;
                    602:     }
                    603: 
                    604:     // Handle the data
                    605:     Simulate_ADB_Event((UInt8 *)_buffer->getBytesNoCopy(), 
                    606:               (UInt32)  _maxPacketSize - bufferSizeRemaining);
                    607: 
                    608: queueAnother:
                    609:     // Reset the buffer
                    610:     _buffer->setLength(_maxPacketSize);
                    611: 
                    612:     // Queue up another one before we leave.
                    613:     if ((err = _interruptPipe->read(_buffer, &_completion)))
                    614:     {
                    615:         // This is bad.  We probably shouldn't continue on from here.
                    616:         IOLog("%s: immediate error %d queueing read\n", getName(), err);
                    617:         goto close;
                    618:     }
                    619: 
                    620:     return;
                    621:     
                    622: close:
                    623:     _interface->close(this);
                    624:     return;
                    625: }
                    626: 
                    627: 
                    628: 
                    629: // ***************************************************************************
                    630: // usb_asyncLED
                    631: //
                    632: // Called asynchronously to turn on/off the keyboard LED
                    633: //
                    634: // **************************************************************************
                    635: void usb_asyncLED( thread_call_param_t param, thread_call_param_t )
                    636: {
                    637:     AppleKeyboard * me = (AppleKeyboard *) param;
                    638:     me->Set_LED_States( me->_ledState ); 
                    639: }
                    640: 
                    641: 
                    642: //******************************************************************************
                    643: // COPIED from ADB keyboard driver 3/25/99
                    644: // This is usually called on a call-out thread after the caps-lock key is pressed.
                    645: // ADB operations to PMU are synchronous, and this is must not be done
                    646: // on the call-out thread since that is the PMU driver workloop thread, and
                    647: // it will block itself.
                    648: //
                    649: // Therefore, we schedule the ADB write to disconnect the call-out thread
                    650: // and the one that initiates the ADB write.
                    651: //
                    652: // *******************************************************************************
                    653: void AppleKeyboard::setLEDFeedback( UInt8 LED_state)
                    654: {
                    655:     _ledState = LED_state;
                    656: 
                    657:     thread_call_func(usb_asyncLED, (thread_call_param_t)this, true);
                    658: }
                    659: 
                    660: 
                    661: // *****************************************************************************
                    662: // maxKeyCodes
                    663: // A.W. copied 3/25/99 from ADB keyboard driver, I don't know what this does
                    664: // ***************************************************************************
                    665: UInt32 AppleKeyboard::maxKeyCodes (void )
                    666: {
                    667: return 0x80;
                    668: }
                    669: 
                    670: 
                    671: // *************************************************************************
                    672: // deviceType
                    673: //
                    674: // **************************************************************************
                    675: UInt32 AppleKeyboard::deviceType ( void )
                    676: {
                    677:     return 2;
                    678: }
                    679: 
                    680: // ************************************************************************
                    681: // interfaceID.  Fake ADB for now since USB defaultKeymapOfLength is too complex
                    682: //
                    683: // **************************************************************************
                    684: UInt32 AppleKeyboard::interfaceID ( void )
                    685: {
                    686:     //Return value must match "interface" line in .keyboard file
                    687:     return NX_EVS_DEVICE_INTERFACE_ADB;  // 2 This matches contents of AppleExt.keyboard
                    688: }
                    689: 
                    690: 
                    691: /***********************************************/
                    692: //Get handler ID 
                    693: //
                    694: //  I assume that this method is only called if a valid USB keyboard
                    695: //  is found. This method should return a 0 or something if there's
                    696: //  no keyboard, but then the USB keyboard driver should never have
                    697: //  been probed if there's no keyboard, so for now it won't return 0.
                    698: UInt32 AppleKeyboard::handlerID ( void )
                    699: {
                    700:     UInt32 ret_id = 0x201;  //513 decimal is ANSI USB iMac keyboard
                    701: 
                    702:     //Return value must match "handler_id" line in .keyboard file
                    703:     // For some reason the ADB and PS/2 keyboard drivers are missing this method
                    704:     // Also, Beaker Keyboard Prefs doesn't run properly
                    705:     //Fix hardware bug in iMac USB keyboard mapping for ISO keyboards
                    706:     //kprintf("\nUSB product = %x, vendor = %x\n", _deviceDescriptor->product, _deviceDescriptor->vendor);
                    707:     if ( _deviceDescriptor)    //just to be safe
                    708:     {
                    709:         if (_deviceDescriptor->vendor == 0xac05) //Apple USB keyboards
                    710:         {
                    711:             ret_id = _deviceDescriptor->product;  //0x201=ANSI, 0x202=ISO, or 0x203=JIS
                    712:            if (ret_id == 0x202)
                    713:            {
                    714:                 usb_2_adb_keymap[0x35] = 0x0a;  //Cosmo key18 swaps with key74, 0a is ADB keycode
                    715:                 usb_2_adb_keymap[0x64] = 0x32;
                    716:                IOLog("USB ISO keys swapped\n");
                    717:            }
                    718:         }
                    719: 
                    720:         if (_deviceDescriptor->vendor == 0x045e)  //Microsoft ID
                    721:         {
                    722:             if (_deviceDescriptor->product == 0x000b)   //Natural USB+PS/2 keyboard
                    723:                 ret_id = 18;  //18 is Apple Extended ADB keyboard
                    724:         }
                    725:     }
                    726: 
                    727:     return ret_id;
                    728: }
                    729: 
                    730: 
                    731: // *****************************************************************************
                    732: // defaultKeymapOfLength
                    733: // A.W. copied from ADB keyboard, I don't have time to make custom USB version
                    734: // *****************************************************************************
                    735: const unsigned char * AppleKeyboard::defaultKeymapOfLength (UInt32 * length )
                    736: {
                    737:     static const unsigned char appleUSAKeyMap[] = {
                    738:         0x00,0x00,0x07,
                    739:         0x00,0x01,0x39,
                    740:         0x01,0x02,0x38,0x7b,
                    741:         0x02,0x02,0x36,0x7d,0x03,0x02,0x3a,0x7c,0x04,
                    742:         0x01,0x37,0x05,0x15,0x52,0x41,0x4c,0x53,0x54,0x55,0x45,0x58,0x57,0x56,0x5b,0x5c,
                    743:         0x43,0x4b,0x51,0x3b,0x3d,0x3e,0x3c,0x4e,0x59,0x06,0x01,0x72,0x7b,0x0d,0x00,0x61,
                    744:         0x00,0x41,0x00,0x01,0x00,0x01,0x00,0xca,0x00,0xc7,0x00,0x01,0x00,0x01,0x0d,0x00,
                    745:         0x73,0x00,0x53,0x00,0x13,0x00,0x13,0x00,0xfb,0x00,0xa7,0x00,0x13,0x00,0x13,0x0d,
                    746:         0x00,0x64,0x00,0x44,0x00,0x04,0x00,0x04,0x01,0x44,0x01,0xb6,0x00,0x04,0x00,0x04,
                    747:         0x0d,0x00,0x66,0x00,0x46,0x00,0x06,0x00,0x06,0x00,0xa6,0x01,0xac,0x00,0x06,0x00,
                    748:             0x06,0x0d,0x00,0x68,0x00,0x48,0x00,0x08,0x00,0x08,0x00,0xe3,0x00,0xeb,0x00,0x00,
                    749:             0x18,0x00,0x0d,0x00,0x67,0x00,0x47,0x00,0x07,0x00,0x07,0x00,0xf1,0x00,0xe1,0x00,
                    750:             0x07,0x00,0x07,0x0d,0x00,0x7a,0x00,0x5a,0x00,0x1a,0x00,0x1a,0x00,0xcf,0x01,0x57,
                    751:             0x00,0x1a,0x00,0x1a,0x0d,0x00,0x78,0x00,0x58,0x00,0x18,0x00,0x18,0x01,0xb4,0x01,
                    752:             0xce,0x00,0x18,0x00,0x18,0x0d,0x00,0x63,0x00,0x43,0x00,0x03,0x00,0x03,0x01,0xe3,
                    753:             0x01,0xd3,0x00,0x03,0x00,0x03,0x0d,0x00,0x76,0x00,0x56,0x00,0x16,0x00,0x16,0x01,
                    754:             0xd6,0x01,0xe0,0x00,0x16,0x00,0x16,0x02,0x00,0x3c,0x00,0x3e,0x0d,0x00,0x62,0x00,
                    755:             0x42,0x00,0x02,0x00,0x02,0x01,0xe5,0x01,0xf2,0x00,0x02,0x00,0x02,0x0d,0x00,0x71,
                    756:             0x00,0x51,0x00,0x11,0x00,0x11,0x00,0xfa,0x00,0xea,0x00,0x11,0x00,0x11,0x0d,0x00,
                    757:             0x77,0x00,0x57,0x00,0x17,0x00,0x17,0x01,0xc8,0x01,0xc7,0x00,0x17,0x00,0x17,0x0d,
                    758:             0x00,0x65,0x00,0x45,0x00,0x05,0x00,0x05,0x00,0xc2,0x00,0xc5,0x00,0x05,0x00,0x05,
                    759:             0x0d,0x00,0x72,0x00,0x52,0x00,0x12,0x00,0x12,0x01,0xe2,0x01,0xd2,0x00,0x12,0x00,
                    760:             0x12,0x0d,0x00,0x79,0x00,0x59,0x00,0x19,0x00,0x19,0x00,0xa5,0x01,0xdb,0x00,0x19,
                    761:             0x00,0x19,0x0d,0x00,0x74,0x00,0x54,0x00,0x14,0x00,0x14,0x01,0xe4,0x01,0xd4,0x00,
                    762:             0x14,0x00,0x14,0x0a,0x00,0x31,0x00,0x21,0x01,0xad,0x00,0xa1,0x0e,0x00,0x32,0x00,
                    763:             0x40,0x00,0x32,0x00,0x00,0x00,0xb2,0x00,0xb3,0x00,0x00,0x00,0x00,0x0a,0x00,0x33,
                    764:             0x00,0x23,0x00,0xa3,0x01,0xba,0x0a,0x00,0x34,0x00,0x24,0x00,0xa2,0x00,0xa8,0x0e,
                    765:             0x00,0x36,0x00,0x5e,0x00,0x36,0x00,0x1e,0x00,0xb6,0x00,0xc3,0x00,0x1e,0x00,0x1e,
                    766:             0x0a,0x00,0x35,0x00,0x25,0x01,0xa5,0x00,0xbd,0x0a,0x00,0x3d,0x00,0x2b,0x01,0xb9,
                    767:             0x01,0xb1,0x0a,0x00,0x39,0x00,0x28,0x00,0xac,0x00,0xab,0x0a,0x00,0x37,0x00,0x26,
                    768:             0x01,0xb0,0x01,0xab,0x0e,0x00,0x2d,0x00,0x5f,0x00,0x1f,0x00,0x1f,0x00,0xb1,0x00,
                    769:             0xd0,0x00,0x1f,0x00,0x1f,0x0a,0x00,0x38,0x00,0x2a,0x00,0xb7,0x00,0xb4,0x0a,0x00,
                    770:             0x30,0x00,0x29,0x00,0xad,0x00,0xbb,0x0e,0x00,0x5d,0x00,0x7d,0x00,0x1d,0x00,0x1d,
                    771:             0x00,0x27,0x00,0xba,0x00,0x1d,0x00,0x1d,0x0d,0x00,0x6f,0x00,0x4f,0x00,0x0f,0x00,
                    772:             0x0f,0x00,0xf9,0x00,0xe9,0x00,0x0f,0x00,0x0f,0x0d,0x00,0x75,0x00,0x55,0x00,0x15,
                    773:             0x00,0x15,0x00,0xc8,0x00,0xcd,0x00,0x15,0x00,0x15,0x0e,0x00,0x5b,0x00,0x7b,0x00,
                    774:             0x1b,0x00,0x1b,0x00,0x60,0x00,0xaa,0x00,0x1b,0x00,0x1b,0x0d,0x00,0x69,0x00,0x49,
                    775:             0x00,0x09,0x00,0x09,0x00,0xc1,0x00,0xf5,0x00,0x09,0x00,0x09,0x0d,0x00,0x70,0x00,
                    776:             0x50,0x00,0x10,0x00,0x10,0x01,0x70,0x01,0x50,0x00,0x10,0x00,0x10,0x10,0x00,0x0d,
                    777:             0x00,0x03,0x0d,0x00,0x6c,0x00,0x4c,0x00,0x0c,0x00,0x0c,0x00,0xf8,0x00,0xe8,0x00,
                    778:             0x0c,0x00,0x0c,0x0d,0x00,0x6a,0x00,0x4a,0x00,0x0a,0x00,0x0a,0x00,0xc6,0x00,0xae,
                    779:             0x00,0x0a,0x00,0x0a,0x0a,0x00,0x27,0x00,0x22,0x00,0xa9,0x01,0xae,0x0d,0x00,0x6b,
                    780:             0x00,0x4b,0x00,0x0b,0x00,0x0b,0x00,0xce,0x00,0xaf,0x00,0x0b,0x00,0x0b,0x0a,0x00,
                    781:             0x3b,0x00,0x3a,0x01,0xb2,0x01,0xa2,0x0e,0x00,0x5c,0x00,0x7c,0x00,0x1c,0x00,0x1c,
                    782:             0x00,0xe3,0x00,0xeb,0x00,0x1c,0x00,0x1c,0x0a,0x00,0x2c,0x00,0x3c,0x00,0xcb,0x01,
                    783:             0xa3,0x0a,0x00,0x2f,0x00,0x3f,0x01,0xb8,0x00,0xbf,0x0d,0x00,0x6e,0x00,0x4e,0x00,
                    784:             0x0e,0x00,0x0e,0x00,0xc4,0x01,0xaf,0x00,0x0e,0x00,0x0e,0x0d,0x00,0x6d,0x00,0x4d,
                    785:             0x00,0x0d,0x00,0x0d,0x01,0x6d,0x01,0xd8,0x00,0x0d,0x00,0x0d,0x0a,0x00,0x2e,0x00,
                    786:             0x3e,0x00,0xbc,0x01,0xb3,0x02,0x00,0x09,0x00,0x19,0x0c,0x00,0x20,0x00,0x00,0x00,
                    787:             0x80,0x00,0x00,0x0a,0x00,0x60,0x00,0x7e,0x00,0x60,0x01,0xbb,0x02,0x00,0x7f,0x00,
                    788:             0x08,0xff,0x02,0x00,0x1b,0x00,0x7e,0xff,0xff,0xff,0xff,0xff,0x00,0x01,0xac,0x00,
                    789:             0x01,0xae,0x00,0x01,0xaf,0x00,0x01,0xad,0xff,0xff,0x00,0x00,0x2e,0xff,0x00,0x00,
                    790:             0x2a,0xff,0x00,0x00,0x2b,0xff,0x00,0x00,0x1b,0xff,0xff,0xff,0x0e,0x00,0x2f,0x00,
                    791:             0x5c,0x00,0x2f,0x00,0x1c,0x00,0x2f,0x00,0x5c,0x00,0x00,0x0a,0x00,0x00,0x00,0x0d, //XX03
                    792:             0xff,0x00,0x00,0x2d,0xff,0xff,0x0e,0x00,0x3d,0x00,0x7c,0x00,0x3d,0x00,0x1c,0x00,
                    793:             0x3d,0x00,0x7c,0x00,0x00,0x18,0x46,0x00,0x00,0x30,0x00,0x00,0x31,0x00,0x00,0x32,
                    794:             0x00,0x00,0x33,0x00,0x00,0x34,0x00,0x00,0x35,0x00,0x00,0x36,0x00,0x00,0x37,0xff,
                    795:             0x00,0x00,0x38,0x00,0x00,0x39,0xff,0xff,0xff,0x00,0xfe,0x24,0x00,0xfe,0x25,0x00,
                    796:             0xfe,0x26,0x00,0xfe,0x22,0x00,0xfe,0x27,0x00,0xfe,0x28,0xff,0x00,0xfe,0x2a,0xff,
                    797:             0x00,0xfe,0x32,0xff,0x00,0xfe,0x33,0xff,0x00,0xfe,0x29,0xff,0x00,0xfe,0x2b,0xff,
                    798:             0x00,0xfe,0x34,0xff,0x00,0xfe,0x2e,0x00,0xfe,0x30,0x00,0xfe,0x2d,0x00,0xfe,0x23,
                    799:             0x00,0xfe,0x2f,0x00,0xfe,0x21,0x00,0xfe,0x31,0x00,0xfe,0x20,0x0f,0x02,0xff,0x04,
                    800:             0x00,0x31,0x02,0xff,0x04,0x00,0x32,0x02,0xff,0x04,0x00,0x33,0x02,0xff,0x04,0x00,
                    801:             0x34,0x02,0xff,0x04,0x00,0x35,0x02,0xff,0x04,0x00,0x36,0x02,0xff,0x04,0x00,0x37,
                    802:             0x02,0xff,0x04,0x00,0x38,0x02,0xff,0x04,0x00,0x39,0x02,0xff,0x04,0x00,0x30,0x02,
                    803:             0xff,0x04,0x00,0x2d,0x02,0xff,0x04,0x00,0x3d,0x02,0xff,0x04,0x00,0x70,0x02,0xff,
                    804:             0x04,0x00,0x5d,0x02,0xff,0x04,0x00,0x5b,0x04,0x05,0x72,0x06,0x7f,0x07,
                    805:             0x3e,0x08,0x3d
                    806:     };
                    807: 
                    808: *length = sizeof(appleUSAKeyMap);
                    809: return appleUSAKeyMap;
                    810: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.