|
|
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: File: KeyboardModule.c
27:
28: Contains: HID Module for USB Keyboard
29:
30: Version: xxx put version here xxx
31:
32: Copyright: � 1997-1998 by Apple Computer, Inc., all rights reserved.
33:
34: File Ownership:
35:
36: DRI: Craig Keithley
37:
38: Other Contact: xxx put other contact here xxx
39:
40: Technology: xxx put technology here xxx
41:
42: Writers:
43:
44: (BT) Barry Twycross
45: (DF) David Ferguson
46: (CJK) Craig Keithley
47:
48: Change History (most recent first):
49:
50: <USB35> 10/28/98 CJK [2281764] use the supplied interface descriptor (for the ,
51: rather than searching the configuration descriptor and using the
52: one found.
53: <USB34> 8/25/98 BT Isoc name changes
54: <USB33> 6/22/98 CJK rename FindNextEndpointDescriptor to
55: FindNextEndpointDescriptorImmediate (no functional change, just
56: a name change)
57: <USB32> 6/17/98 CJK leave retries in place for non-pipe stall situations. That's the
58: most compatible with the earlier versions of the driver... It
59: feels pretty risky disabling that functionality this close to
60: intro.
61: <USB31> 6/17/98 CJK change to check pipe status, if stalled, then try to clear it.
62: <USB30> 6/17/98 CJK change error handling to not retry on some types of errors
63: <USB29> 6/16/98 CJK change FindHIDInterfaceByProtocol to FindHIDInterfaceByNumber
64: <USB28> 6/15/98 CJK Change "USL Reported an error" message so that it shows the
65: refcon (and not the deviceRef)
66: <USB27> 6/11/98 CJK Remove driverentry routine (not needed or used).
67: <USB26> 6/8/98 CJK eliminate PBVERSION1 define
68: <USB25> 6/5/98 CJK remove ExpertStatus calls; cluttering up expert log
69: <USB24> 5/20/98 BT Add V2 param block stuff
70: <USB23> 5/20/98 CJK change driver name from USBKeyboardModule to
71: USBHIDKeyboardModule
72: <USB22> 5/20/98 CJK add prototype for SetParamBlock
73: <USB21> 4/30/98 CJK add a "send raw report" mode. initialize rawdatamode and
74: initialized flags appropriately.
75: <USB20> 4/29/98 CJK Back out, just for the Columbus demo, the changes since the
76: 1.0a9 release.
77: <USB19> 4/29/98 CJK add break where needed
78: <USB18> 4/27/98 CJK don't fatalerror if setidle never succeeds. just give up after
79: 5 tries and move on to opening the pipe.
80: <USB17> 4/26/98 CJK Add clear param block routine. Dramatically reorganized to
81: match the "new" style used in the mouse module. The keyboard
82: module now searchs for an interface, and when it finds a
83: keyboard interface, it locates the interrupt pipe. No more hard
84: coded assumptions! Okay, so we're still assuming that keyboard
85: reports (in boot protocol mode) are 8 bytes.
86: <USB16> 4/9/98 CJK change driver services to be a externally supplied header file
87: (using < & >) rather than quotes.
88: <USB15> 4/9/98 DF Massaged to work with MasterInterfaces
89: <14> 4/8/98 CJK add initialization of saved interrupt routine ptr.
90: <13> 3/26/98 CJK remove init of delay field inside of my keyboard structure.
91: Clean up USBExpertFatalError messages (to show USB error code,
92: etc.)
93: <12> 3/25/98 CJK Remove unneeded poll & delay code
94: <11> 3/24/98 CJK turn on interrupt pipe usage. This required some changes in the
95: USL, as well as doing a "set_idle" in order to get the reports
96: when keys were released.
97: <10> 3/17/98 CJK Begin adding support for interrupt transactions. Change the
98: occasion "};" to just "}", as MetroWerks has a problem with some
99: "};".
100: <9> 3/12/98 CJK add initialization of the shim keyboard param block.
101: <8> 3/2/98 CJK remove include of KBDHIDEmulation.h
102: <7> 2/26/98 CJK change poll rate to 10ms. Add support for LEDs
103: <6> 2/17/98 CJK remove "" from each notify expert call.
104: <5> 2/16/98 CJK change poll time to 8ms
105: <4> 2/11/98 CJK change debugstrs to USBExpertFatalError calls.
106: <3> 2/11/98 CJK remove unneeded states
107: <2> 2/10/98 CJK Correct change history (to reflect the keyboard module changes)
108: <1> 2/10/98 CJK First time checkin. Cloned from Mouse HID Module.
109: */
110: /*
111: #include <Types.h>
112: #include <Devices.h>
113: #include <processes.h>
114: */
115: #include "../driverservices.h"
116: #include "../USB.h"
117:
118: #include "KeyboardModule.h"
119:
120: usbKeyboardPBStruct myKeyboardPB;
121: usbKeyboardPBStruct shimKeyboardPB;
122:
123:
124: static void KeyboardModuleDelay1CompletionProc(USBPB *pb);
125: void SetParamBlock(USBDeviceRef theDeviceRef, USBPB * paramblock);
126:
127: void SetParamBlock(USBDeviceRef theDeviceRef, USBPB * paramblock)
128: {
129: paramblock->usbReference = theDeviceRef;
130: paramblock->pbVersion = kUSBCurrentPBVersion;
131: paramblock->usb.cntl.WIndex = 0;
132: paramblock->usbBuffer = nil;
133: paramblock->usbStatus = noErr;
134: paramblock->usbReqCount = 0;
135: paramblock->usb.cntl.WValue = 0;
136: paramblock->usbFlags = 0;
137: }
138: static Boolean immediateError(OSStatus err)
139: {
140: return((err != kUSBPending) && (err != noErr) );
141: }
142: void KeyboardModuleInitiateTransaction(USBPB *pb)
143: {
144: register usbKeyboardPBStruct *pKeyboardPB;
145: OSStatus myErr;
146:
147: //A.W. 12/9/98 It seems this code is never called
148: pKeyboardPB = (usbKeyboardPBStruct *)(pb);
149: pKeyboardPB->transDepth++;
150: if (pKeyboardPB->transDepth < 0)
151: {
152: printf("transdepth<0\n");
153: USBExpertFatalError(pKeyboardPB->deviceRef, kUSBInternalErr, "USBHIDKeyboardModule: transDepth < 0 (initiation)", pKeyboardPB->pb.usbRefcon );
154: }
155:
156: //A.W. 12/9/98 It seems this code is never called
157: if (pKeyboardPB->transDepth > 1)
158: {
159: printf("transdepth>1\n");
160: USBExpertFatalError(pKeyboardPB->deviceRef, kUSBInternalErr, "USBHIDKeyboardModule: transDepth > 1 (initiation)", pKeyboardPB->pb.usbRefcon );
161: }
162:
163: switch(pKeyboardPB->pb.usbRefcon & ~kRetryTransaction)
164: {
165: case kSetKeyboardLEDs:
166: SetParamBlock(pKeyboardPB->deviceRef, &pKeyboardPB->pb);
167:
168: pKeyboardPB->pb.usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBOut, kUSBClass, kUSBInterface);
169:
170: pKeyboardPB->pb.usb.cntl.BRequest = kHIDRqSetReport;
171: pKeyboardPB->pb.usb.cntl.WValue = (kHIDRtOutputReport << 8);
172: pKeyboardPB->pb.usb.cntl.WIndex = pKeyboardPB->interfaceDescriptor.interfaceNumber;
173:
174: pKeyboardPB->pb.usbBuffer = (Ptr)&pKeyboardPB->hidReport[0];
175: pKeyboardPB->pb.usbReqCount = 1;
176:
177: pKeyboardPB->pb.usbCompletion = (USBCompletion)KeyboardCompletionProc;
178: pKeyboardPB->pb.usbRefcon |= kCompletionPending;
179:
180: myErr = USBDeviceRequest(&pKeyboardPB->pb);
181: if(immediateError(myErr))
182: {
183: USBExpertFatalError(pKeyboardPB->deviceRef, kUSBInternalErr, "USBHIDKeyboardModule: kSetKeyboardLEDs - immediate error", myErr);
184: }
185: //A.W. 12/9/98 This code seems to be going through OK
186:
187: break;
188:
189: case kGetFullConfiguration:
190: SetParamBlock(pKeyboardPB->deviceRef, &pKeyboardPB->pb);
191:
192: pKeyboardPB->pb.usbRefcon |= kCompletionPending;
193: pKeyboardPB->pb.usbCompletion = (USBCompletion)KeyboardCompletionProc;
194: myErr = USBGetFullConfigurationDescriptor(pb);
195: if(immediateError(myErr))
196: {
197: USBExpertFatalError(pKeyboardPB->pb.usbReference, kUSBInternalErr, "USBHIDKeyboardModule: kGetFullConfiguration (ImmediateError)", myErr);
198: }
199: break;
200:
201: case kFindInterfaceAndSetProtocol:
202: myErr = kbd_FindHIDInterfaceByNumber(pKeyboardPB->pFullConfigDescriptor, pKeyboardPB->interfaceDescriptor.interfaceNumber, &pKeyboardPB->pInterfaceDescriptor ); // find the HID interface
203: if ((pKeyboardPB->pInterfaceDescriptor == NULL) ||
204: (myErr != noErr))
205: {
206: USBExpertFatalError(pKeyboardPB->deviceRef, kUSBInternalErr, "USBHIDKeyboardModule: Interface not found", myErr);
207: pKeyboardPB->pb.usbRefcon = kReturnFromDriver;
208: }
209:
210: SetParamBlock(pKeyboardPB->deviceRef, &pKeyboardPB->pb);
211:
212: pKeyboardPB->pb.usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBOut, kUSBClass, kUSBInterface);
213: pKeyboardPB->pb.usb.cntl.BRequest = kHIDRqSetProtocol;
214: pKeyboardPB->pb.usb.cntl.WValue = kHIDBootProtocolValue;
215: pKeyboardPB->pb.usb.cntl.WIndex = pKeyboardPB->interfaceDescriptor.interfaceNumber;
216: pKeyboardPB->pb.usbCompletion = (USBCompletion)KeyboardCompletionProc;
217:
218: pKeyboardPB->pb.usbRefcon |= kCompletionPending;
219: myErr = USBDeviceRequest(&pKeyboardPB->pb);
220: if (immediateError(myErr))
221: {
222: USBExpertFatalError(pKeyboardPB->deviceRef, kUSBInternalErr, "USBHIDKeyboardModule: kSetProtocol (ImmediateError)", myErr);
223: }
224: break;
225:
226: case kSetIdleRequest:
227: SetParamBlock(pKeyboardPB->deviceRef, &pKeyboardPB->pb);
228:
229: pKeyboardPB->pb.usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBOut, kUSBClass, kUSBInterface);
230:
231: pKeyboardPB->pb.usb.cntl.BRequest = kHIDRqSetIdle;
232: pKeyboardPB->pb.usb.cntl.WValue = ((24/4)<<8); // force a read completion if idle for more than 24ms
233: pKeyboardPB->pb.usb.cntl.WIndex = pKeyboardPB->interfaceDescriptor.interfaceNumber;
234: pKeyboardPB->pb.usbCompletion = (USBCompletion)KeyboardCompletionProc;
235:
236: pKeyboardPB->pb.usbRefcon |= kCompletionPending;
237:
238: myErr = USBDeviceRequest(&pKeyboardPB->pb);
239: if(immediateError(myErr))
240: {
241: USBExpertFatalError(pKeyboardPB->deviceRef, kUSBInternalErr, "USBHIDKeyboardModule: kSetIdleRequest - immediate error", myErr);
242: }
243: break;
244:
245: case kFindAndOpenInterruptPipe:
246: pKeyboardPB->pb.usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBIn, kUSBClass, kUSBInterface);
247: pKeyboardPB->pb.usbFlags = kUSBIn;
248: pKeyboardPB->pb.usbClassType = kUSBInterrupt;
249: pKeyboardPB->pb.usbOther = 0;
250: pKeyboardPB->pb.usbBuffer = pKeyboardPB->pInterfaceDescriptor;
251: pKeyboardPB->pb.usbReqCount = (UInt8*)pKeyboardPB->pInterfaceDescriptor - (UInt8*)pKeyboardPB->pFullConfigDescriptor;
252: myErr = USBFindNextEndpointDescriptorImmediate( &pKeyboardPB->pb );
253: if((immediateError(myErr)) || (pKeyboardPB->pb.usbBuffer == nil))
254: {
255: USBExpertFatalError(pKeyboardPB->deviceRef, kUSBInternalErr, "USBHIDKeyboardModule: Endpoint not found", myErr);
256: pKeyboardPB->pb.usbRefcon = kReturnFromDriver;
257: }
258: else
259: {
260: pKeyboardPB->pEndpointDescriptor = (USBEndPointDescriptorPtr) pKeyboardPB->pb.usbBuffer;
261:
262: SetParamBlock(pKeyboardPB->deviceRef, &pKeyboardPB->pb);
263:
264: pKeyboardPB->pb.usbFlags = kUSBIn;
265: pKeyboardPB->pb.usb.cntl.WValue = 0x08;
266: pKeyboardPB->pb.usbClassType = kUSBInterrupt;
267: pKeyboardPB->pb.usbOther = (pKeyboardPB->pEndpointDescriptor->endpointAddress & 0x0f);
268: pKeyboardPB->pb.usbRefcon |= kCompletionPending;
269: pKeyboardPB->pb.usbCompletion = (USBCompletion)KeyboardCompletionProc;
270:
271: myErr = USBOpenPipe( &pKeyboardPB->pb );
272: if(immediateError(myErr))
273: {
274: USBExpertFatalError(pKeyboardPB->deviceRef, kUSBInternalErr, "USBHIDKeyboardModule: USBOpenPipe Failed (ImmediateError)", myErr);
275: }
276: }
277: break;
278:
279: case kReadInterruptPipe:
280: SetParamBlock(pKeyboardPB->pipeRef, &pKeyboardPB->pb);
281:
282: pKeyboardPB->pb.usbBuffer = (Ptr)pKeyboardPB->hidReport;
283: pKeyboardPB->pb.usbReqCount = 0x08;
284: pKeyboardPB->pb.usb.cntl.WIndex = pKeyboardPB->interfaceDescriptor.interfaceNumber;
285: pKeyboardPB->pb.usbCompletion = (USBCompletion)KeyboardCompletionProc;
286:
287: pKeyboardPB->pb.usbRefcon |= kCompletionPending;
288: kprintf("***Issuing keyboard USBIntRead\n");
289: myErr = USBIntRead(&pKeyboardPB->pb);
290: if(immediateError(myErr))
291: {
292: USBExpertFatalError(pKeyboardPB->deviceRef, kUSBInternalErr, "USBHIDKeyboardModule: Read Interrupt Pipe (ImmediateError)", myErr);
293: }
294: break;
295:
296: default:
297: USBExpertFatalError(pKeyboardPB->deviceRef, kUSBInternalErr, "USBHIDKeyboardModule - Transaction completed with bad refcon value", pKeyboardPB->pb.usbRefcon );
298: pKeyboardPB->pb.usbRefcon = kUndefined + kReturnFromDriver;
299: break;
300: }
301:
302: // At this point the control is returned to the system. If a USB transaction
303: // has been initiated, then it will call the Complete procs
304: // (below) to handle the results of the transaction.
305: }
306:
307: void KeyboardCompletionProc(USBPB *pb)
308: {
309: unsigned char * errstring;
310: register usbKeyboardPBStruct *pKeyboardPB;
311: USBPipeState pipeState;
312:
313: pKeyboardPB = (usbKeyboardPBStruct *)(pb);
314: pKeyboardPB->transDepth--;
315: if (pKeyboardPB->transDepth < 0)
316: {
317: printf("transDepth<0\n");
318: USBExpertFatalError(pKeyboardPB->deviceRef, kUSBInternalErr, "USBHIDKeyboardModule: transDepth < 0 (completion)", pKeyboardPB->pb.usbRefcon );
319: }
320:
321: if (pKeyboardPB->transDepth > 1)
322: {
323: printf("transDepth>1\n");
324: USBExpertFatalError(pKeyboardPB->deviceRef, kUSBInternalErr, "USBHIDKeyboardModule: transDepth > 1 (completion)", pKeyboardPB->pb.usbRefcon );
325: }
326:
327: if(pKeyboardPB->pb.usbStatus != noErr) // was there an error?
328: {
329: switch(pKeyboardPB->pb.usbRefcon & 0x0fff) // yes, so show where the error occurred
330: {
331: case kSetKeyboardLEDs: errstring = "USBHIDKeyboardModule: Error during SetKeyboardLEDs"; break;
332: case kGetFullConfiguration: errstring = "USBHIDKeyboardModule: Error during GetFullConfiguration"; break;
333: case kFindInterfaceAndSetProtocol: errstring = "USBHIDKeyboardModule: Error during FindInterfaceAndSetProtocol"; break;
334: case kFindAndOpenInterruptPipe: errstring = "USBHIDKeyboardModule: Error during FindAndOpenInterruptPipe"; break;
335: case kReadInterruptPipe: errstring = "USBHIDKeyboardModule: Error during ReadInterruptPipe"; break;
336: default: errstring = "USBHIDKeyboardModule: Error occurred, but state is unknown"; break;
337: };
338: USBExpertFatalError(pKeyboardPB->deviceRef, pKeyboardPB->pb.usbStatus, errstring, (pKeyboardPB->pb.usbRefcon & 0x0fff));
339:
340: pKeyboardPB->pb.usbRefcon &= ~(kCompletionPending + kReturnFromDriver); // set up to retry the transaction
341: pKeyboardPB->pb.usbRefcon |= kRetryTransaction;
342: pKeyboardPB->retryCount--;
343:
344: if ((!pKeyboardPB->retryCount) || (pKeyboardPB->pb.usbStatus == kUSBAbortedError)) // have we exhausted the retries?
345: { // or received an abort?
346: USBExpertStatus(pKeyboardPB->deviceRef, "USBHIDKeyboardModule: Pipe abort or unable to recover from error", pKeyboardPB->deviceRef);
347: pKeyboardPB->pb.usbRefcon = kReturnFromDriver; // if so, just exit.
348: }
349: else // if it didn't abort and there's retries left, then...
350: {
351: if (pKeyboardPB->pipeRef) // check if the pipe is open.
352: {
353: USBGetPipeStatusByReference(pKeyboardPB->pipeRef, &pipeState); // yes, so what it's state?
354: if (pipeState != kUSBActive) // if it's not active, try to clear it. It might be stalled...
355: {
356: USBExpertStatus(pKeyboardPB->deviceRef, "USBHIDKeyboardModule: Pipe is open and stalled, clearing stall...", pKeyboardPB->deviceRef);
357: USBClearPipeStallByReference(pKeyboardPB->pipeRef);
358: }
359: }
360: }
361: }
362: else
363: {
364: pKeyboardPB->pb.usbRefcon &= ~kRetryTransaction;
365: pKeyboardPB->retryCount = kKeyboardRetryCount;
366: }
367:
368: if (pKeyboardPB->pb.usbRefcon & kCompletionPending)
369: {
370: pKeyboardPB->pb.usbRefcon &= ~(kCompletionPending + kReturnFromDriver);
371: switch(pKeyboardPB->pb.usbRefcon)
372: {
373: case kSetKeyboardLEDs:
374: pKeyboardPB->pb.usbRefcon = kReturnFromDriver;
375: break;
376:
377: case kGetFullConfiguration:
378: pKeyboardPB->pFullConfigDescriptor = pKeyboardPB->pb.usbBuffer;
379: if (pKeyboardPB->pFullConfigDescriptor == nil)
380: {
381: USBExpertFatalError(pKeyboardPB->pb.usbReference, kUSBInternalErr, "USBHIDKeyboardModule: USBGetFullConfiguration - pointer is nil", pKeyboardPB->pb.usbRefcon);
382: pKeyboardPB->pb.usbRefcon = kReturnFromDriver;
383: }
384: else
385: {
386: pKeyboardPB->pb.usbRefcon = kFindInterfaceAndSetProtocol;
387: }
388: break;
389:
390: case kFindInterfaceAndSetProtocol:
391: pKeyboardPB->pb.usbRefcon = kSetIdleRequest;
392: break;
393:
394: case kSetIdleRequest:
395: pKeyboardPB->pb.usbRefcon = kFindAndOpenInterruptPipe;
396: break;
397:
398: case kFindAndOpenInterruptPipe:
399: pKeyboardPB->pipeRef = pKeyboardPB->pb.usbReference;
400: pKeyboardPB->pb.usbRefcon = kReadInterruptPipe;
401: break;
402:
403: case kReadInterruptPipe:
404: kbd_NotifyRegisteredHIDUser(pKeyboardPB->hidDeviceType, pKeyboardPB->hidReport);
405: pKeyboardPB->pb.usbRefcon = kReadInterruptPipe;
406: break;
407:
408: default:
409: USBExpertFatalError(pKeyboardPB->deviceRef, kUSBInternalErr, "USBHIDKeyboardModule - Transaction completed with bad refcon value", pKeyboardPB->pb.usbRefcon );
410: pKeyboardPB->pb.usbRefcon = kUndefined + kReturnFromDriver;
411: break;
412: }
413: }
414: if (!(pKeyboardPB->pb.usbRefcon & kReturnFromDriver))
415: KeyboardModuleInitiateTransaction(pb);
416: }
417:
418:
419: void kbd_InterfaceEntry(UInt32 interfacenum, USBInterfaceDescriptorPtr pInterfaceDescriptor, USBDeviceDescriptorPtr pDeviceDescriptor, USBDeviceRef device)
420: {
421: #pragma unused (interfacenum)
422:
423: static Boolean beenThereDoneThat = false;
424:
425: if(beenThereDoneThat)
426: {
427: USBExpertFatalError(device, kUSBInternalErr, "USBHIDKeyboardModule is not reentrant", 12);
428: return;
429: }
430: //Hot Plug n Play
431: //naga beenThereDoneThat = true;
432:
433: // DebugStr("In Keyboard Module Interface entry routine");
434: shimKeyboardPB.deviceDescriptor = *pDeviceDescriptor;
435: shimKeyboardPB.interfaceDescriptor = *pInterfaceDescriptor;
436: shimKeyboardPB.transDepth = 0;
437: shimKeyboardPB.retryCount = kKeyboardRetryCount;
438: shimKeyboardPB.pSHIMInterruptRoutine = nil;
439: shimKeyboardPB.pSavedInterruptRoutine = nil;
440: shimKeyboardPB.deviceRef = device;
441: shimKeyboardPB.interfaceRef = 0;
442: shimKeyboardPB.pipeRef = 0;
443:
444: shimKeyboardPB.deviceRef = device;
445: shimKeyboardPB.interfaceRef = nil;
446: shimKeyboardPB.pipeRef = nil;
447:
448: SetParamBlock(device, &shimKeyboardPB.pb);
449: shimKeyboardPB.pb.pbLength = sizeof(usbKeyboardPBStruct);
450: shimKeyboardPB.pb.usbRefcon = 0;
451:
452: myKeyboardPB.deviceDescriptor = *pDeviceDescriptor;
453: myKeyboardPB.interfaceDescriptor = *pInterfaceDescriptor;
454: myKeyboardPB.transDepth = 0;
455: myKeyboardPB.retryCount = kKeyboardRetryCount;
456: myKeyboardPB.pSHIMInterruptRoutine = nil;
457: myKeyboardPB.pSavedInterruptRoutine = nil;
458: myKeyboardPB.deviceRef = device;
459: myKeyboardPB.interfaceRef = 0;
460: myKeyboardPB.pipeRef = 0;
461:
462: myKeyboardPB.deviceRef = device;
463: myKeyboardPB.interfaceRef = nil;
464: myKeyboardPB.pipeRef = nil;
465:
466: myKeyboardPB.sendRawReportFlag = false;
467: myKeyboardPB.hidEmulationInit = false;
468:
469: SetParamBlock(device, &myKeyboardPB.pb);
470: myKeyboardPB.pb.pbLength = sizeof(usbKeyboardPBStruct);
471: myKeyboardPB.pb.usbRefcon = kGetFullConfiguration; /* Start with setting the interface protocol */
472:
473:
474: kbd_USBHIDControlDevice(kHIDEnableDemoMode,0);
475: KeyboardModuleInitiateTransaction(&myKeyboardPB.pb);
476: }
477:
478:
479:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.