|
|
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) 1999 Apple Computer, Inc. All rights reserved.
24: *
25: * HISTORY
26: * 21 May 99 wgulland created.
27: *
28: */
29:
30: #define DEBUGGING_LEVEL 0 // 1 = low; 2 = high; 3 = extreme
31: #define DEBUGLOG kprintf
32: #include <IOKit/assert.h>
33:
34: #include <IOKit/IOMessage.h>
35: #include <IOKit/firewire/IOFireWireDevice.h>
36: #include <IOKit/firewire/IOFireWireUnit.h>
37: #include <IOKit/firewire/IOFireWireController.h>
38:
39: #define super IOFireWireNub
40:
41: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
42:
43: OSDefineMetaClassAndStructors(IOFireWireDevice, IOFireWireNub)
44:
45: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
46:
47: bool IOFireWireDevice::attach(IOService *provider)
48: {
49: assert(OSDynamicCast(IOFireWireController, provider));
50: if( !super::attach(provider))
51: return (false);
52: fControl = (IOFireWireController *)provider;
53:
54: return(true);
55: }
56:
57: void IOFireWireDevice::setNodeROM(UInt32 gen, UInt16 nodeID, UInt16 localID,
58: OSData *rom, UInt32 *selfIDs, int numSelfIDs)
59: {
60: OSObject *prop;
61: OSArray *strings;
62: IOMessage mess;
63: int i;
64: UInt32 newROMSize;
65: const UInt32 *newROM;
66:
67: fNodeID = nodeID;
68: fLocalNodeID = localID;
69: fGeneration = gen;
70: prop = OSNumber::withNumber(nodeID, 16);
71: setProperty(gFireWireNodeID, prop);
72: prop->release();
73:
74: // Notify clients of current state
75: mess = kIOMessageServiceIsResumed;
76: if(nodeID == 0xffff)
77: mess = kIOMessageServiceIsSuspended;
78: messageClients( mess );
79:
80: if(!rom)
81: return;
82:
83: // Store selfIDs
84: fNumSelfIDs = numSelfIDs;
85: for(i=0; i<numSelfIDs; i++) {
86: fSelfIDs[i] = selfIDs[i];
87: }
88: prop = OSData::withBytes(fSelfIDs, numSelfIDs*sizeof(UInt32));
89: setProperty(gFireWireSelfIDs, prop);
90: prop->release();
91:
92: // Process new ROM
93:
94: newROMSize = rom->getLength()/4;
95: newROM = (UInt32 *)rom->getBytesNoCopy();
96:
97: if(newROMSize == fROMSize) {
98: if(!bcmp(newROM, fROM, newROMSize*4))
99: return; // ROM unchanged
100: }
101:
102: setProperty(gFireWireROM, rom);
103: fROMSize = newROMSize;
104: fROM = newROM;
105:
106: if(fROMSize > 3) {
107: UInt32 vendorID = fROM[3] >> 8;
108: prop = OSNumber::withNumber(vendorID, 32);
109: setProperty(gFireWireVendor_ID, prop);
110: prop->release();
111: }
112: if(fROMSize < 6)
113: return; // Done.
114:
115: strings = OSArray::withCapacity(3);
116: // search for a unit directory - should create a nub for each one
117: //zzz should search for nodes/modules if there are no unit directories.
118: CSRROMEntryIterator csrUnitIterator = kInvalidCSRROMIterator;
119: CSRROMEntryID csrROMEntryID = kInvalidCSRROMEntryID;
120: CSRROMSearchCriteria unitSearchCriteria;
121: int doneUnits;
122: IOReturn error;
123:
124: unitSearchCriteria.csrROMSearchType = kCSRROMSearchForKey;
125: unitSearchCriteria.keyType = kCSRDirectoryKeyTypeBit;
126: unitSearchCriteria.keyHi = kCSRUnitDirectoryKeyHiBit;
127: unitSearchCriteria.keyLo = kCSRUnitDirectoryKeyLoBit;
128:
129: // Create CSR ROM search iterator.
130: error = CSRROMCreateIterator (&csrUnitIterator);
131: doneUnits = !(error == kIOReturnSuccess); // don't search if we couldn't create the iterator
132:
133: ///////////////////////////////
134: // look for units
135:
136: while ( !doneUnits ) {
137: // Search for a unit directory.
138: error = FWCSRROMEntrySearch (csrUnitIterator,
139: kIterateContinue,
140: &csrROMEntryID,
141: &doneUnits,
142: &unitSearchCriteria,
143: NULL,
144: NULL);
145: if(error != kIOReturnSuccess)
146: doneUnits = true;
147: if(doneUnits)
148: break;
149:
150: CSRROMEntryIterator csrROMIterator = NULL;
151: CSRROMSearchCriteria searchCriteria;
152: UInt32 unitSpecID;
153: UInt32 unitSoftwareVersion;
154: UInt32 csrROMEntrySize;
155: IOReturn status, stat2;
156: int done;
157:
158: ////////////////////////////////////////////////////////////////////////////
159: //
160: // Get unit spec ID.
161: //
162:
163: // Create a CSR ROM iterator.
164: status = CSRROMCreateIterator(&csrROMIterator);
165:
166: // Set it to unit directory.
167: if (status == kIOReturnSuccess) {
168: status = FWCSRROMSetIterator(csrROMIterator, csrROMEntryID, kIterateDescendants);
169: }
170:
171: // Search for unit spec ID.
172: //zzz what if none preset???
173: if (status == kIOReturnSuccess) {
174: searchCriteria.csrROMSearchType = kCSRROMSearchForKey;
175: searchCriteria.keyType = kCSRImmediateKeyTypeBit;
176: searchCriteria.keyHi = kCSRUnitSpecIdKeyHiBit;
177: searchCriteria.keyLo = kCSRUnitSpecIdKeyLoBit;
178: csrROMEntrySize = sizeof (UInt32);
179: status =
180: FWCSRROMEntrySearch
181: (csrROMIterator,
182: kIterateContinue,
183: NULL,
184: &done,
185: &searchCriteria,
186: (UInt8 *) &unitSpecID,
187: &csrROMEntrySize);
188:
189: if ((status == kIOReturnSuccess) && (done))
190: status = kIOReturnNoDevice;//zzz is this right?
191: }
192:
193: // Clean up iterator.
194: if (csrROMIterator != kInvalidCSRROMIterator) {
195: FWCSRROMDisposeIterator (csrROMIterator);
196: csrROMIterator = kInvalidCSRROMIterator;
197: }
198:
199: ////////////////////////////////////////////////////////////////////////////
200: //
201: // Get unit software version.
202: //
203:
204: // Create a CSR ROM iterator.
205: if (status == kIOReturnSuccess) {
206: status = CSRROMCreateIterator(&csrROMIterator);
207: }
208:
209: // Set it to unit directory.
210: if (status == kIOReturnSuccess){
211: status = FWCSRROMSetIterator
212: (csrROMIterator, csrROMEntryID, kIterateDescendants);
213: }
214:
215: // Search for the software version.
216: if (status == kIOReturnSuccess) {
217: searchCriteria.csrROMSearchType = kCSRROMSearchForKey;
218: searchCriteria.keyType = kCSRImmediateKeyTypeBit;
219: searchCriteria.keyHi = kCSRUnitSwVersionKeyHiBit;
220: searchCriteria.keyLo = kCSRUnitSwVersionKeyLoBit;
221: csrROMEntrySize = sizeof (UInt32);
222: status =
223: FWCSRROMEntrySearch
224: (csrROMIterator,
225: kIterateContinue,
226: NULL,
227: &done,
228: &searchCriteria,
229: (UInt8 *) &unitSoftwareVersion,
230: &csrROMEntrySize);
231:
232: if ((status == kIOReturnSuccess) && (done))
233: status = kIOReturnNoDevice;//zzz is this right?
234: }
235:
236: // Clean up iterator.
237: if (csrROMIterator != kInvalidCSRROMIterator) {
238: FWCSRROMDisposeIterator (csrROMIterator);
239: csrROMIterator = kInvalidCSRROMIterator;
240: }
241:
242: // Search for text strings.
243: searchCriteria.csrROMSearchType = kCSRROMSearchForKey;
244: searchCriteria.keyType = kCSRLeafKeyTypeBit;
245: searchCriteria.keyHi = kCSRTextualDescriptorKeyHiBit;
246: searchCriteria.keyLo = kCSRTextualDescriptorKeyLoBit;
247: char text[128];
248: done = false;
249: // Create a CSR ROM iterator.
250: stat2 = CSRROMCreateIterator(&csrROMIterator);
251: while (stat2 == kIOReturnSuccess && !done) {
252: unsigned int i;
253: csrROMEntrySize = sizeof (text)-1;
254: stat2 =
255: FWCSRROMEntrySearch
256: (csrROMIterator,
257: kIterateDescendants,
258: NULL,
259: &done,
260: &searchCriteria,
261: (UInt8 *) text,
262: &csrROMEntrySize);
263: if(stat2 == kIOReturnSuccess && !done) {
264: // Skip leading zeros in text
265: for(i=0; i<csrROMEntrySize; i++)
266: if(text[i])
267: break;
268: text[csrROMEntrySize] = 0;
269: if(strings) {
270: OSString * astring = OSString::withCString(text+i);
271: if ( astring ) {
272: strings->setObject(astring);
273: astring->release();
274: }
275: }
276: }
277:
278: }
279: // Clean up iterator.
280: if (csrROMIterator != kInvalidCSRROMIterator) {
281: FWCSRROMDisposeIterator (csrROMIterator);
282: csrROMIterator = kInvalidCSRROMIterator;
283: }
284:
285: // Add entry to registry.
286: if (status == kIOReturnSuccess) {
287: OSDictionary * propTable = 0;
288: IOFireWireUnit * newDevice = 0;
289: do {
290: propTable = OSDictionary::withCapacity(5);
291: if (!propTable)
292: continue;
293: /*
294: * Set the IOMatchCategory so that things that want to connect to
295: * the device still can even if it already has IOFireWireUnits attached
296: */
297: prop = OSSymbol::withCString("FireWire Unit");
298: propTable->setObject(gIOMatchCategoryKey, prop);
299: prop->release();
300:
301: prop = OSNumber::withNumber(unitSpecID, 32);
302: propTable->setObject(gFireWireUnit_Spec_ID, prop);
303: prop->release();
304: prop = OSNumber::withNumber(unitSoftwareVersion, 32);
305: propTable->setObject(gFireWireUnit_SW_Version, prop);
306: prop->release();
307:
308: // Copy over matching properties from Device
309: prop = getProperty(gFireWireVendor_ID);
310: if(prop)
311: propTable->setObject(gFireWireVendor_ID, prop);
312: prop = getProperty(gFireWire_GUID);
313: if(prop)
314: propTable->setObject(gFireWire_GUID, prop);
315:
316: newDevice = new IOFireWireUnit;
317:
318: if (!newDevice || !newDevice->init(propTable))
319: break;
320: if (!newDevice->attach(this))
321: break;
322: newDevice->registerService();
323: } while (false);
324: if(newDevice)
325: newDevice->release();
326: if(propTable)
327: propTable->release();
328: }
329: if(strings) {
330: setProperty("Description", strings);
331: strings->release();
332: }
333: }
334: // Clean up iterator and entryID 'object'
335: if (csrUnitIterator != kInvalidCSRROMIterator) {
336: FWCSRROMDisposeIterator (csrUnitIterator);
337: csrUnitIterator = kInvalidCSRROMIterator;
338: }
339: if(csrROMEntryID != kInvalidCSRROMEntryID) {
340: FWCSRROMDisposeEntryID(csrROMEntryID);
341: csrROMEntryID = kInvalidCSRROMEntryID;
342: }
343:
344: }
345:
346: /*
347: * Create an iterator for the device ROM
348: */
349: IOReturn IOFireWireDevice::CSRROMCreateIterator (CSRROMEntryIterator *pCSRROMIterator)
350: {
351: CSRROMEntryIteratorRecPtr pIteratorRec;
352: UInt32 hdrSize;
353:
354: // Allocate memory for iterator record.
355: pIteratorRec = (CSRROMEntryIteratorRecPtr)IOMalloc (sizeof (CSRROMEntryIteratorRec));
356: if (pIteratorRec == NULL)
357: return kIOReturnNoMemory;
358:
359: // Fill in other record fields.
360: // Set relationship to descendants.
361: pIteratorRec->relationship = kIterateDescendants;
362: // Find start of root directory.
363: hdrSize = ((fROM[0] & kCSRBusInfoBlockLength) >> kCSRBusInfoBlockLengthPhase) + 1;
364: pIteratorRec->data = fROM;
365: pIteratorRec->logicalPath[0] = 0;
366: pIteratorRec->physicalPath[0] = hdrSize;
367:
368: pIteratorRec->logicalPath[1] = 0;
369: pIteratorRec->physicalPath[1] = pIteratorRec->physicalPath[0] + 1;
370:
371: pIteratorRec->pathSize = 2;
372: pIteratorRec->reset = true;
373:
374: // Return iterator.
375: *pCSRROMIterator = (CSRROMEntryIterator) pIteratorRec;
376:
377: return (kIOReturnSuccess);
378: }
379:
380: /**
381: ** Matching methods
382: **/
383: bool IOFireWireDevice::matchPropertyTable(OSDictionary * table)
384: {
385: //
386: // If the service object wishes to compare some of its properties in its
387: // property table against the supplied matching dictionary,
388: // it should do so in this method and return truth on success.
389: //
390: if (!super::matchPropertyTable(table)) return false;
391:
392: // We return success if the following expression is true -- individual
393: // comparisions evaluate to truth if the named property is not present
394: // in the supplied matching dictionary.
395:
396: return compareProperty(table, gFireWireVendor_ID) &&
397: compareProperty(table, gFireWire_GUID);
398: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.