|
|
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: #import <driverkit/i386/directDevice.h>
25:
26: @implementation ExampleController
27:
28: /*
29: * Probe, configure board and init new instance.
30: */
31: + probe:deviceDescription
32: {
33: ExampleController *example = [self alloc];
34:
35: /*
36: * Probe this instance at the possible addresses for the Example
37: * controller. In this case, we ignore the configuration info,
38: * which we should really check to be completely consistent.
39: */
40: if (![example probeAtPortBase:0x1f0] &&
41: ![example probeAtPortBase:0x170]) {
42: [example free];
43: return nil;
44: }
45:
46: return [example initFromDeviceDescription:deviceDescription];
47: }
48:
49:
50: - initFromDeviceDescription:deviceDescription
51: {
52: /*
53: * The call to [super init...] reserves all of our resources, or it
54: * returns nil.
55: */
56: if ([super initFromDeviceDescription:deviceDescription] == nil)
57: return [super free];
58:
59: /* a bunch of driver specific stuff here... */
60:
61: /*
62: * Now we're all set! Just register ourselves, set some driverkit
63: * stuff driverkit stuff, enable interrupts and go...
64: */
65: [self setUnit:some unique number];
66: [self setDeviceName:a unique name];
67: [self setDeviceKind:"sc"]; /* a scsi controller */
68:
69: [self registerDevice];
70:
71: [self enableAllInterrupts];
72:
73: return self;
74: }
75:
76:
77: /*
78: * Can be called if init runs to completion.
79: */
80: - free
81: {
82: /* device specific stuff here */
83: return [super free];
84: }
85:
86:
87: /*
88: * Override IODevice's attachInterrupt method so we can start the interrupt
89: * thread after our interrupt port has been allocated.
90: */
91: - (void) attachInterrupt
92: {
93: [super attachInterrupt];
94: IOForkThread((IOThreadFcn)InterruptHanderThread, self);
95: }
96:
97:
98: /*
99: * Handle an interrupt. Called in a thread context from the handler thread.
100: */
101: - interrupt
102: {
103: /* clear interrupts and do something meaningful */
104: return self;
105: }
106:
107: @end
108:
109: static volatile void
110: InterruptHandlerThread(id self)
111: {
112: kern_return_t krtn;
113: msg_header_t *msgp = (msg_header_t *) IOMalloc(MSG_SIZE_MAX);
114:
115: while(1) {
116: /*
117: * Wait for something to do.
118: */
119: msgp->msg_local_port = [self interruptPort];
120: msgp->msg_size = MSG_SIZE_MAX;
121: krtn = msg_receive(msgp, RCV_TIMEOUT, 5000); /* XXX */
122: if (krtn != KERN_SUCCESS)
123: continue;
124:
125: /*
126: * Hardware interrupt. Dispatch.
127: */
128: switch(msgp->msg_id) {
129: case INT_MSG_DEVICE:
130: [self interrupt];
131: break;
132: case INT_MSG_TIMEOUT:
133: [self timeout];
134: break;
135: default:
136: break;
137: }
138: }
139: }
140:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.