|
|
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: * 3 June 99 wgulland created.
27: *
28: * IOFireWireController methods to build the local device ROM.
29: */
30:
31: #include <assert.h>
32:
33: #define DEBUGGING_LEVEL 0 // 1 = low; 2 = high; 3 = extreme
34: #define DEBUGLOG kprintf
35:
36: #include <IOKit/IOWorkLoop.h>
37: #include <IOKit/firewire/IOFireWireController.h>
38: #include <IOKit/firewire/IOFWCommand.h>
39: #include <IOKit/firewire/IOFireWireDevice.h>
40:
41: static void FWCSRROMDisposeLeafEntryData(CSRROMEntryDataPtr pCSRROMEntryData);
42: static void FWCSRROMDisposeEntryData(CSRROMEntryDataPtr pCSRROMEntryData);
43:
44:
45: ////////////////////////////////////////////////////////////////////////////////
46: //
47: // FWCSRROMCreateDirectoryEntryData
48: //
49: // Create a local directory entry data record.
50: //
51:
52: static IOReturn FWCSRROMCreateDirectoryEntryData(
53: CSRROMDirectoryDataPtr pParentCSRROMDirectoryData,
54: CSRROMEntryDataPtr *ppCSRROMEntryData,
55: UInt32 entryKeyValue)
56: {
57: CSRROMDirectoryDataPtr pCSRROMDirectoryData;
58: IOReturn status = kIOReturnSuccess;
59:
60: // Allocate memory for entry data record.
61: pCSRROMDirectoryData =
62: (CSRROMDirectoryDataPtr) IOMalloc (sizeof (CSRROMDirectoryData));
63: if (pCSRROMDirectoryData == NULL)
64: status = kIOReturnNoMemory;
65:
66: // Fill in entry data record fields.
67: if (status == kIOReturnSuccess) {
68: // Copy parent's FWIM.
69: //pCSRROMDirectoryData->csrROMEntryData.fwimID =
70: // pParentCSRROMDirectoryData->csrROMEntryData.fwimID;
71:
72: // Set entry type and key value.
73: pCSRROMDirectoryData->csrROMEntryData.entryType = kDirectoryCSRROMEntryType;
74: pCSRROMDirectoryData->csrROMBasicEntryData.keyValue = entryKeyValue;
75:
76: // Fill in entry data.
77: pCSRROMDirectoryData->pChildCSRROMEntryData = NULL;
78: pCSRROMDirectoryData->numChildren = 0;
79: }
80:
81: // Return results.
82: if (status == kIOReturnSuccess)
83: *ppCSRROMEntryData = (CSRROMEntryDataPtr) pCSRROMDirectoryData;
84: else
85: *ppCSRROMEntryData = NULL;
86:
87: return (status);
88: }
89:
90: ////////////////////////////////////////////////////////////////////////////////
91: //
92: // FWCSRROMCreateImmediateEntryData
93: //
94: // Create a local immediate entry data record.
95: //
96:
97: static IOReturn FWCSRROMCreateImmediateEntryData(
98: CSRROMDirectoryDataPtr pParentCSRROMDirectoryData,
99: CSRROMEntryDataPtr *ppCSRROMEntryData,
100: UInt32 entryKeyValue,
101: UInt8 * pEntryData)
102: {
103: CSRROMImmediateDataPtr pCSRROMImmediateData;
104: IOReturn status = kIOReturnSuccess;
105:
106: // Allocate memory for entry data record.
107: pCSRROMImmediateData =
108: (CSRROMImmediateDataPtr) IOMalloc (sizeof (CSRROMImmediateData));
109: if (pCSRROMImmediateData == NULL)
110: status = kIOReturnNoMemory;
111:
112: // Fill in entry data record fields.
113: if (status == kIOReturnSuccess) {
114: // Copy parent's FWIM.
115: //pCSRROMImmediateData->csrROMEntryData.fwimID =
116: // pParentCSRROMDirectoryData->csrROMEntryData.fwimID;
117:
118: // Set entry type and key value.
119: pCSRROMImmediateData->csrROMEntryData.entryType = kImmediateCSRROMEntryType;
120: pCSRROMImmediateData->csrROMBasicEntryData.keyValue = entryKeyValue;
121:
122: // Fill in entry data.
123: pCSRROMImmediateData->immediateData = (*((UInt32 *) pEntryData)) >> 8;
124: }
125:
126: // Return results.
127: if (status == kIOReturnSuccess)
128: *ppCSRROMEntryData = (CSRROMEntryDataPtr) pCSRROMImmediateData;
129: else
130: *ppCSRROMEntryData = NULL;
131:
132: return (status);
133: }
134:
135: ////////////////////////////////////////////////////////////////////////////////
136: //
137: // FWCSRROMCreateLeafEntryData
138: //
139: // Create a local leaf entry data record.
140: //
141:
142: static IOReturn FWCSRROMCreateLeafEntryData(
143: CSRROMDirectoryDataPtr pParentCSRROMDirectoryData,
144: CSRROMEntryDataPtr *ppCSRROMEntryData,
145: UInt32 entryKeyValue,
146: UInt8 * pEntryData,
147: UInt32 entrySize)
148: {
149: CSRROMLeafDataPtr pCSRROMLeafData = NULL;
150: UInt8 * leafStorage;
151: UInt32 leafDataSize;
152: IOReturn status = kIOReturnSuccess;
153:
154: // Allocate memory for entry data record.
155: pCSRROMLeafData = (CSRROMLeafDataPtr) IOMalloc (sizeof (CSRROMLeafData));
156: if (pCSRROMLeafData == NULL)
157: status = kIOReturnNoMemory;
158:
159: // Allocate leaf storage.
160: if (status == kIOReturnSuccess) {
161: leafDataSize = (entrySize + 3) & (~0x03);
162: leafStorage = (UInt8 *)IOMalloc (leafDataSize);
163: if (leafStorage != NULL) {
164: *((UInt32 *) (leafStorage + leafDataSize - 4)) = 0;
165: pCSRROMLeafData->leafData = leafStorage;
166: pCSRROMLeafData->leafDataSize = leafDataSize;
167: }
168: else
169: status = kIOReturnNoMemory;
170: }
171:
172: // Fill in entry data record fields.
173: if (status == kIOReturnSuccess) {
174: // Copy parent's FWIM.
175: //pCSRROMLeafData->csrROMEntryData.fwimID =
176: // pParentCSRROMDirectoryData->csrROMEntryData.fwimID;
177:
178: // Set entry type and key value.
179: pCSRROMLeafData->csrROMEntryData.entryType = kLeafCSRROMEntryType;
180: pCSRROMLeafData->csrROMBasicEntryData.keyValue = entryKeyValue;
181:
182: // Fill in entry data.
183: bcopy (pEntryData, pCSRROMLeafData->leafData, entrySize);
184: }
185:
186: // Clean up on error.
187: if (status != kIOReturnSuccess) {
188: if (pCSRROMLeafData != NULL)
189: FWCSRROMDisposeLeafEntryData ((CSRROMEntryDataPtr) pCSRROMLeafData);
190: }
191:
192: // Return results.
193: if (status == kIOReturnSuccess)
194: *ppCSRROMEntryData = (CSRROMEntryDataPtr) pCSRROMLeafData;
195: else
196: *ppCSRROMEntryData = NULL;
197:
198: return (status);
199: }
200:
201:
202: ////////////////////////////////////////////////////////////////////////////////
203: //
204: // FWCSRROMCreateOffsetEntryData
205: //
206: // Create a local offset entry data record.
207: //
208:
209: static IOReturn FWCSRROMCreateOffsetEntryData(
210: CSRROMDirectoryDataPtr pParentCSRROMDirectoryData,
211: CSRROMEntryDataPtr *ppCSRROMEntryData,
212: UInt32 entryKeyValue,
213: FWAddressPtr pFWAddress)
214: {
215: CSRROMOffsetDataPtr pCSRROMOffsetData;
216: IOReturn status = kIOReturnSuccess;
217:
218: // Check address range and alignment.
219: if ((pFWAddress->addressHi != kCSRRegisterSpaceBaseAddressHi) ||
220: (pFWAddress->addressLo < kCSRROMBaseAddress) ||
221: (pFWAddress->addressLo >= 0xF4000000)) {
222: status = kIOReturnBadArgument;
223: }
224: else if ((pFWAddress->addressLo & 0x03) != 0) {
225: status = kIOReturnNotAligned;
226: }
227:
228: // Allocate memory for entry data record.
229: if (status == kIOReturnSuccess) {
230: pCSRROMOffsetData =
231: (CSRROMOffsetDataPtr) IOMalloc (sizeof (CSRROMOffsetData));
232: if (pCSRROMOffsetData == NULL)
233: status = kIOReturnNoMemory;
234: }
235:
236: // Fill in entry data record fields.
237: if (status == kIOReturnSuccess) {
238: // Copy parent's FWIM.
239: //pCSRROMOffsetData->csrROMEntryData.fwimID =
240: // pParentCSRROMDirectoryData->csrROMEntryData.fwimID;
241:
242: // Set entry type and key value.
243: pCSRROMOffsetData->csrROMEntryData.entryType = kOffsetCSRROMEntryType;
244: pCSRROMOffsetData->csrROMBasicEntryData.keyValue = entryKeyValue;
245:
246: // Fill in entry data.
247: pCSRROMOffsetData->address = pFWAddress->addressLo;
248: }
249:
250: // Return results.
251: if (status == kIOReturnSuccess)
252: *ppCSRROMEntryData = (CSRROMEntryDataPtr) pCSRROMOffsetData;
253: else
254: *ppCSRROMEntryData = NULL;
255:
256: return (status);
257: }
258:
259: ////////////////////////////////////////////////////////////////////////////////
260: //
261: // FWCSRROMDisposeDirectoryEntryData
262: //
263: // Dispose of a local directory entry data record.
264: //
265:
266: static void FWCSRROMDisposeDirectoryEntryData(CSRROMEntryDataPtr pCSRROMEntryData)
267: {
268: CSRROMDirectoryDataPtr pCSRROMDirectoryData;
269: CSRROMEntryDataPtr pChildCSRROMEntryData, pNextCSRROMEntryData;
270: UInt32 numChildren, childNum;
271:
272: if (pCSRROMEntryData != NULL) {
273: // Recast entry data.
274: pCSRROMDirectoryData = (CSRROMDirectoryDataPtr) pCSRROMEntryData;
275:
276: // Deallocate all children entry data records.
277: pChildCSRROMEntryData = pCSRROMDirectoryData->pChildCSRROMEntryData;
278: numChildren = pCSRROMDirectoryData->numChildren;
279: for (childNum = 0; childNum < numChildren; childNum++) {
280: // Get next child entry data record.
281: pNextCSRROMEntryData = pChildCSRROMEntryData->pNextCSRROMEntryData;
282:
283: // Deallocate current child entry data record.
284: FWCSRROMDisposeEntryData (pChildCSRROMEntryData);
285:
286: // Go to next child entry data.
287: pChildCSRROMEntryData = pNextCSRROMEntryData;
288: }
289:
290: // Deallocate memory for entry data record.
291: IOFree(pCSRROMEntryData, sizeof(CSRROMDirectoryData));
292: }
293: }
294:
295: ////////////////////////////////////////////////////////////////////////////////
296: //
297: // FWCSRROMDisposeImmediateEntryData
298: //
299: // Dispose of a local immediate entry data record.
300: //
301:
302: static void FWCSRROMDisposeImmediateEntryData(CSRROMEntryDataPtr pCSRROMEntryData)
303: {
304: // Deallocate memory for entry data record.
305: if (pCSRROMEntryData != NULL)
306: IOFree (pCSRROMEntryData, sizeof(CSRROMImmediateData));
307: }
308:
309: ////////////////////////////////////////////////////////////////////////////////
310: //
311: // FWCSRROMDisposeLeafEntryData
312: //
313: // Dispose of a local leaf entry data record.
314: //
315:
316: static void FWCSRROMDisposeLeafEntryData(CSRROMEntryDataPtr pCSRROMEntryData)
317: {
318: CSRROMLeafDataPtr pCSRROMLeafData;
319: if (pCSRROMEntryData != NULL) {
320: // Recast entry data.
321: pCSRROMLeafData = (CSRROMLeafDataPtr) pCSRROMEntryData;
322:
323: // Deallocate leaf data storage.
324: if (pCSRROMLeafData->leafData != NULL)
325: IOFree(pCSRROMLeafData->leafData, pCSRROMLeafData->leafDataSize);
326:
327: // Deallocate memory for entry data record.
328: IOFree(pCSRROMEntryData, sizeof(CSRROMLeafData));
329: }
330: }
331:
332: ////////////////////////////////////////////////////////////////////////////////
333: //
334: // FWCSRROMDisposeOffsetEntryData
335: //
336: // Dispose of a local offset entry data record.
337: //
338:
339: static void FWCSRROMDisposeOffsetEntryData(CSRROMEntryDataPtr pCSRROMEntryData)
340: {
341: // Deallocate memory for entry data record.
342: if (pCSRROMEntryData != NULL)
343: IOFree (pCSRROMEntryData, sizeof(CSRROMOffsetData));
344: }
345:
346:
347: ////////////////////////////////////////////////////////////////////////////////
348: //
349: // FWCSRROMDisposeEntryData
350: //
351: // Dispose of a local entry data record.
352: //
353:
354: static void FWCSRROMDisposeEntryData(CSRROMEntryDataPtr pCSRROMEntryData)
355: {
356: if (pCSRROMEntryData != NULL) {
357: switch (pCSRROMEntryData->entryType) {
358: case kImmediateCSRROMEntryType :
359: FWCSRROMDisposeImmediateEntryData (pCSRROMEntryData);
360: break;
361:
362: case kOffsetCSRROMEntryType :
363: FWCSRROMDisposeOffsetEntryData (pCSRROMEntryData);
364: break;
365:
366: case kLeafCSRROMEntryType :
367: FWCSRROMDisposeLeafEntryData (pCSRROMEntryData);
368: break;
369:
370: case kDirectoryCSRROMEntryType :
371: FWCSRROMDisposeDirectoryEntryData (pCSRROMEntryData);
372: break;
373:
374: default :
375: break;
376: }
377: }
378: }
379:
380:
381: ////////////////////////////////////////////////////////////////////////////////
382: //
383: // FWCSRROMInsertEntryData
384: //
385: // This routine inserts a CSR ROM entry data record into the local CSR ROM
386: // tree.
387: //
388:
389: static void FWCSRROMInsertEntryData(
390: CSRROMDirectoryDataPtr pParentCSRROMDirectoryData,
391: CSRROMEntryDataPtr pCSRROMEntryData)
392: {
393: CSRROMEntryDataPtr pFirstCSRROMEntryData, pPrevCSRROMEntryData, pNextCSRROMEntryData;
394:
395: // Get the first entry data record in the parent directory's list.
396: pFirstCSRROMEntryData = pParentCSRROMDirectoryData->pChildCSRROMEntryData;
397:
398: // Insert entry into list.
399: if (pFirstCSRROMEntryData != NULL) {
400: pPrevCSRROMEntryData = pFirstCSRROMEntryData->pPrevCSRROMEntryData;
401: pNextCSRROMEntryData = pFirstCSRROMEntryData;
402:
403: pPrevCSRROMEntryData->pNextCSRROMEntryData = pCSRROMEntryData;
404: pCSRROMEntryData->pPrevCSRROMEntryData = pPrevCSRROMEntryData;
405:
406: pNextCSRROMEntryData->pPrevCSRROMEntryData = pCSRROMEntryData;
407: pCSRROMEntryData->pNextCSRROMEntryData = pNextCSRROMEntryData;
408: }
409: else {
410: pParentCSRROMDirectoryData->pChildCSRROMEntryData = pCSRROMEntryData;
411:
412: pCSRROMEntryData->pPrevCSRROMEntryData = pCSRROMEntryData;
413: pCSRROMEntryData->pNextCSRROMEntryData = pCSRROMEntryData;
414: }
415:
416: pCSRROMEntryData->pParentCSRROMEntryData = (CSRROMEntryDataPtr) pParentCSRROMDirectoryData;
417: pParentCSRROMDirectoryData->numChildren++;
418: }
419:
420: ////////////////////////////////////////////////////////////////////////////////
421: //
422: // FWCSRROMEntrySize
423: //
424: // Calculate size of entry (including children)
425: //
426:
427: static int FWCSRROMEntrySize(CSRROMEntryDataPtr pCSRROMEntryData)
428: {
429: CSRROMEntryDataPtr pChildCSRROMEntryData;
430: CSRROMLeafDataPtr pCSRROMLeafData;
431: CSRROMDirectoryDataPtr pCSRROMDirectoryData;
432: UInt32 numChildren;
433: UInt32 i;
434: int size = 0;
435:
436: // Compute entry key type, value, and data.
437: switch (pCSRROMEntryData->entryType) {
438: case kImmediateCSRROMEntryType :
439: break;
440:
441: case kOffsetCSRROMEntryType :
442: break;
443:
444: case kLeafCSRROMEntryType :
445: pCSRROMLeafData = (CSRROMLeafDataPtr) pCSRROMEntryData;
446: size = (pCSRROMLeafData->leafDataSize >> 2) + 1;
447: break;
448:
449: case kDirectoryCSRROMEntryType :
450: pCSRROMDirectoryData = (CSRROMDirectoryDataPtr) pCSRROMEntryData;
451: numChildren = pCSRROMDirectoryData->numChildren;
452: size = 1;
453:
454: pChildCSRROMEntryData = pCSRROMDirectoryData->pChildCSRROMEntryData;
455: size += numChildren;
456: for (i = 0; i < numChildren; i++) {
457: size += FWCSRROMEntrySize(pChildCSRROMEntryData);
458: pChildCSRROMEntryData = pChildCSRROMEntryData->pNextCSRROMEntryData;
459: }
460:
461: break;
462:
463: default :
464: //zzz should we do anything on error?
465: break;
466: }
467:
468: return (size);
469: }
470:
471: ////////////////////////////////////////////////////////////////////////////////
472: //
473: // FWCSRROMInstantiateEntry
474: //
475: // Instantiate and entry in the local CSR ROM.
476: //
477:
478: static void FWCSRROMInstantiateEntry(CSRROMEntryDataPtr pCSRROMEntryData,
479: UInt32 **ppCSRROMStorage, UInt32 *pEntryLocation)
480: {
481: CSRROMEntryDataPtr pChildCSRROMEntryData;
482: CSRROMImmediateDataPtr pCSRROMImmediateData;
483: CSRROMOffsetDataPtr pCSRROMOffsetData;
484: CSRROMLeafDataPtr pCSRROMLeafData;
485: CSRROMDirectoryDataPtr pCSRROMDirectoryData;
486: UInt32 *pCSRROMStorage = *ppCSRROMStorage;
487: UInt32 *pCSRROMDirectoryStorage;
488: UInt32 *pHeader;
489: UInt32 crc16;
490: UInt32 entryOffset;
491: UInt32 entryValue;
492: UInt32 entryKeyType, entryKeyValue;
493: UInt32 numChildren;
494: UInt32 i;
495:
496: // Compute entry key type, value, and data.
497: switch (pCSRROMEntryData->entryType) {
498: case kImmediateCSRROMEntryType :
499: pCSRROMImmediateData = (CSRROMImmediateDataPtr) pCSRROMEntryData;
500: entryKeyType = kCSRImmediateKeyType;
501: entryKeyValue = pCSRROMImmediateData->csrROMBasicEntryData.keyValue;
502: entryValue = pCSRROMImmediateData->immediateData;
503: *pEntryLocation =
504: ((entryKeyType << kCSREntryKeyTypePhase) & kCSREntryKeyType) |
505: ((entryKeyValue << kCSREntryKeyValuePhase) & kCSREntryKeyValue) |
506: ((entryValue << kCSREntryValuePhase) & kCSREntryValue);
507: break;
508:
509: case kOffsetCSRROMEntryType :
510: pCSRROMOffsetData = (CSRROMOffsetDataPtr) pCSRROMEntryData;
511: entryKeyType = kCSROffsetKeyType;
512: entryKeyValue = pCSRROMOffsetData->csrROMBasicEntryData.keyValue;
513: entryOffset =
514: (pCSRROMOffsetData->address - kCSRRegisterSpaceBaseAddressLo) >> 2;
515: *pEntryLocation =
516: ((entryKeyType << kCSREntryKeyTypePhase) & kCSREntryKeyType) |
517: ((entryKeyValue << kCSREntryKeyValuePhase) & kCSREntryKeyValue) |
518: ((entryOffset << kCSREntryValuePhase) & kCSREntryValue);
519: break;
520:
521: case kLeafCSRROMEntryType :
522: pCSRROMLeafData = (CSRROMLeafDataPtr) pCSRROMEntryData;
523: entryKeyType = kCSRLeafKeyType;
524: entryKeyValue = pCSRROMLeafData->csrROMBasicEntryData.keyValue;
525: entryOffset = pCSRROMStorage - pEntryLocation;
526: *pEntryLocation =
527: ((entryKeyType << kCSREntryKeyTypePhase) & kCSREntryKeyType) |
528: ((entryKeyValue << kCSREntryKeyValuePhase) & kCSREntryKeyValue) |
529: ((entryOffset << kCSREntryValuePhase) & kCSREntryValue);
530:
531: crc16 = FWComputeCRC16 ((UInt32 *) pCSRROMLeafData->leafData,
532: pCSRROMLeafData->leafDataSize/4);
533:
534: *pCSRROMStorage++ =
535: (((pCSRROMLeafData->leafDataSize >> 2) << kCSRLeafDirLengthPhase) &
536: kCSRLeafDirLength) |
537: ((crc16 << kCSRLeafDirCRCPhase) & kCSRLeafDirCRC);
538:
539: bcopy(pCSRROMLeafData->leafData, pCSRROMStorage, pCSRROMLeafData->leafDataSize);
540: pCSRROMStorage =
541: (UInt32 *) ((UInt8 *) pCSRROMStorage + pCSRROMLeafData->leafDataSize);
542: break;
543:
544: case kDirectoryCSRROMEntryType :
545: pCSRROMDirectoryData = (CSRROMDirectoryDataPtr) pCSRROMEntryData;
546: entryKeyType = kCSRDirectoryKeyType;
547: entryKeyValue = pCSRROMDirectoryData->csrROMBasicEntryData.keyValue;
548: entryOffset = pCSRROMStorage - pEntryLocation;
549: if (pEntryLocation != NULL) {
550: *pEntryLocation =
551: ((entryKeyType << kCSREntryKeyTypePhase) & kCSREntryKeyType) |
552: ((entryKeyValue << kCSREntryKeyValuePhase) & kCSREntryKeyValue) |
553: ((entryOffset << kCSREntryValuePhase) & kCSREntryValue);
554: }
555:
556: numChildren = pCSRROMDirectoryData->numChildren;
557: pHeader = pCSRROMStorage;
558: pCSRROMStorage++;
559:
560: pChildCSRROMEntryData = pCSRROMDirectoryData->pChildCSRROMEntryData;
561: pCSRROMDirectoryStorage = pCSRROMStorage;
562: pCSRROMStorage += numChildren;
563: for (i = 0; i < numChildren; i++) {
564: FWCSRROMInstantiateEntry (pChildCSRROMEntryData, &pCSRROMStorage, pCSRROMDirectoryStorage++);
565: pChildCSRROMEntryData = pChildCSRROMEntryData->pNextCSRROMEntryData;
566: }
567:
568: crc16 = FWComputeCRC16 (pHeader + 1, numChildren);
569: *pHeader =
570: ((numChildren << kCSRLeafDirLengthPhase) & kCSRLeafDirLength) |
571: ((crc16 << kCSRLeafDirCRCPhase) & kCSRLeafDirCRC);
572:
573: break;
574:
575: default :
576: //zzz should we do anything on error?
577: break;
578: }
579:
580: // Update ROM storage.
581: *ppCSRROMStorage = pCSRROMStorage;
582: }
583:
584: ////////////////////////////////////////////////////////////////////////////////
585: //
586: // CSRROMGetRootDirectory
587: //
588: // Return the Entry ID of the root directory for our ROM.
589: //
590:
591: IOReturn IOFireWireController::CSRROMGetRootDirectory(CSRROMEntryID *pCSRROMEntryID)
592: {
593: CSRROMEntryID csrROMEntryID;
594: CSRROMEntryIDDataPtr pCSRROMEntryIDData;
595: CSRROMLocalIDDataPtr pCSRROMLocalIDData;
596: IOReturn status = kIOReturnSuccess;
597:
598: // Get the output entry ID and allocate if invalid.
599: csrROMEntryID = *pCSRROMEntryID;
600: if (csrROMEntryID == kInvalidCSRROMEntryID) {
601: csrROMEntryID = FWCSRROMCreateEntryID ();
602: if (csrROMEntryID == kInvalidCSRROMEntryID)
603: status = kIOReturnNoMemory;
604: }
605:
606: // Set to root directory.
607: if (status == kIOReturnSuccess) {
608: pCSRROMEntryIDData = (CSRROMEntryIDDataPtr) csrROMEntryID;
609: // Invalidate output entry ID type if it's not local.
610: if ((pCSRROMEntryIDData->entryType != kInvalidCSRROMEntryIDType) &&
611: (pCSRROMEntryIDData->entryType != kLocalCSRROMEntryIDType)) {
612: FWCSRROMInvalidateEntryIDType (csrROMEntryID);
613: }
614:
615: // Recast entry ID data.
616: pCSRROMLocalIDData = (CSRROMLocalIDDataPtr) pCSRROMEntryIDData;
617:
618: // Make entry ID reference local root directory.
619: pCSRROMLocalIDData->csrROMEntryIDData.entryType = kLocalCSRROMEntryIDType;
620: pCSRROMLocalIDData->pCSRROMEntryData =
621: (CSRROMEntryDataPtr) &fCSRROMRootDirectory;
622: *pCSRROMEntryID = csrROMEntryID;
623: }
624: return (status);
625: }
626:
627: ////////////////////////////////////////////////////////////////////////////////
628: //
629: // CSRROMCreateEntry
630: //
631: // Create an entry in the local CSR Configuration ROM.
632: //
633:
634: IOReturn IOFireWireController::CSRROMCreateEntry(
635: CSRROMEntryID parentCSRROMEntryID, CSRROMEntryID *pCSRROMEntryID,
636: UInt32 entryType, UInt32 entryKeyValue, void *entryData, UInt32 entrySize)
637: {
638: CSRROMEntryID csrROMEntryID;
639: CSRROMEntryIDDataPtr pCSRROMEntryIDData;
640: CSRROMLocalIDDataPtr pParentCSRROMLocalIDData;
641: CSRROMLocalIDDataPtr pCSRROMLocalIDData;
642: CSRROMDirectoryDataPtr pParentCSRROMDirectoryData;
643: CSRROMEntryDataPtr pNewCSRROMEntryData = NULL;
644: bool csrROMEntryIDAllocated = false;
645: IOReturn status = kIOReturnSuccess;
646:
647: // Get and validate parent directory.
648: pParentCSRROMLocalIDData = (CSRROMLocalIDDataPtr) parentCSRROMEntryID;
649: if (pParentCSRROMLocalIDData->csrROMEntryIDData.entryType == kLocalCSRROMEntryIDType) {
650: pParentCSRROMDirectoryData =
651: (CSRROMDirectoryDataPtr) pParentCSRROMLocalIDData->pCSRROMEntryData;
652: if (pParentCSRROMDirectoryData->csrROMEntryData.entryType != kDirectoryCSRROMEntryType)
653: status = kIOReturnBadArgument;
654: }
655: else {
656: status = kIOReturnBadArgument;
657: }
658:
659: // Get the output entry ID and allocate if invalid.
660: if (status == kIOReturnSuccess) {
661: csrROMEntryID = *pCSRROMEntryID;
662: if (csrROMEntryID == kInvalidCSRROMEntryID) {
663: csrROMEntryID = FWCSRROMCreateEntryID ();
664: if (csrROMEntryID != kInvalidCSRROMEntryID)
665: csrROMEntryIDAllocated = true;
666: else
667: status = kIOReturnNoMemory;
668: }
669:
670: if (csrROMEntryID != kInvalidCSRROMEntryID)
671: pCSRROMEntryIDData = (CSRROMEntryIDDataPtr) csrROMEntryID;
672: }
673:
674: // If output entry ID is not local, invalidate it.
675: if (status == kIOReturnSuccess) {
676: if ((pCSRROMEntryIDData->entryType != kInvalidCSRROMEntryIDType) &&
677: (pCSRROMEntryIDData->entryType != kLocalCSRROMEntryIDType)) {
678: FWCSRROMInvalidateEntryIDType (csrROMEntryID);
679: }
680: }
681:
682: // Create the requested type of entry data record.
683: if (status == kIOReturnSuccess) {
684: switch (entryType) {
685: case kImmediateCSRROMEntryType :
686: status = FWCSRROMCreateImmediateEntryData (pParentCSRROMDirectoryData,
687: &pNewCSRROMEntryData,
688: entryKeyValue,
689: (UInt8 *) entryData);
690: break;
691:
692: case kOffsetCSRROMEntryType :
693: status = FWCSRROMCreateOffsetEntryData (pParentCSRROMDirectoryData,
694: &pNewCSRROMEntryData,
695: entryKeyValue,
696: (FWAddressPtr) entryData);
697: break;
698:
699: case kLeafCSRROMEntryType :
700: status = FWCSRROMCreateLeafEntryData (pParentCSRROMDirectoryData,
701: &pNewCSRROMEntryData,
702: entryKeyValue,
703: (UInt8 *) entryData,
704: entrySize);
705: break;
706:
707: case kDirectoryCSRROMEntryType :
708: status = FWCSRROMCreateDirectoryEntryData (pParentCSRROMDirectoryData,
709: &pNewCSRROMEntryData,
710: entryKeyValue);
711: break;
712:
713: default :
714: status = kIOReturnBadArgument;
715: break;
716: }
717: }
718:
719: // Insert new entry into CSR Configuration ROM.
720: if (status == kIOReturnSuccess)
721: FWCSRROMInsertEntryData (pParentCSRROMDirectoryData, pNewCSRROMEntryData);
722:
723: // Set ID to reference new entry.
724: if (status == kIOReturnSuccess) {
725: pCSRROMLocalIDData = (CSRROMLocalIDDataPtr) pCSRROMEntryIDData;
726: pCSRROMLocalIDData->csrROMEntryIDData.entryType = kLocalCSRROMEntryIDType;
727: pCSRROMLocalIDData->pCSRROMEntryData = pNewCSRROMEntryData;
728: }
729:
730: // Clean up on error.
731: if (status != kIOReturnSuccess) {
732: if (pNewCSRROMEntryData != NULL)
733: FWCSRROMDisposeEntryData (pNewCSRROMEntryData);
734:
735: if (csrROMEntryIDAllocated)
736: FWCSRROMDisposeEntryID (csrROMEntryID);
737: }
738:
739: // Return results.
740: if (status == kIOReturnSuccess)
741: *pCSRROMEntryID = csrROMEntryID;
742:
743: return (status);
744: }
745:
746: ////////////////////////////////////////////////////////////////////////////////
747: //
748: // UpdateROM()
749: //
750: // Instantiate the local CSR ROM.
751: // Always causes at least one bus reset.
752: //
753:
754: IOReturn IOFireWireController::UpdateROM()
755: {
756: CSRROMDirectoryDataPtr pCSRROMDirectoryData;
757: CSRROMImmediateDataPtr pCSRROMImmediateData;
758: UInt32 *pCSRROMStorage;
759: UInt32 busInfoBlockSize;
760: UInt32 *pHeader;
761: UInt32 romSize;
762: UInt32 crc16;
763: OSData * rom;
764: IOReturn ret;
765:
766: // Update CSR ROM generation.
767: //zzz assumes first entry is generation value.
768: pCSRROMDirectoryData = &fCSRROMRootDirectory;
769: pCSRROMImmediateData =
770: (CSRROMImmediateDataPtr) pCSRROMDirectoryData->pChildCSRROMEntryData;
771: if (pCSRROMImmediateData->csrROMBasicEntryData.keyValue == kCSRGenerationKey)
772: pCSRROMImmediateData->immediateData++;
773:
774: busInfoBlockSize = (fROMHeader[0] & kCSRBusInfoBlockLength) >>
775: kCSRBusInfoBlockLengthPhase;
776: romSize = FWCSRROMEntrySize((CSRROMEntryDataPtr) pCSRROMDirectoryData) +
777: busInfoBlockSize;
778: kprintf("Rom size: %d\n", romSize);
779: rom = OSData::withCapacity((romSize+1)*4);
780: if(!rom)
781: return kIOReturnNoMemory;
782: pHeader = (UInt32 *)IOMalloc((romSize+1)*4);
783: if(!pHeader) {
784: rom->release();
785: return kIOReturnNoMemory;
786: }
787:
788: // Recursively build configuration ROM.
789: bcopy(fROMHeader, pHeader, 4*(busInfoBlockSize+1));
790: pCSRROMStorage = pHeader + busInfoBlockSize + 1;
791: FWCSRROMInstantiateEntry((CSRROMEntryDataPtr) pCSRROMDirectoryData,
792: &pCSRROMStorage, NULL);
793:
794: // Reconstruct Bus Info Block header.
795:
796: crc16 = FWComputeCRC16 (pHeader + 1, romSize);
797: *pHeader =
798: ((busInfoBlockSize << kCSRBusInfoBlockLengthPhase) & kCSRBusInfoBlockLength) |
799: ((romSize << kCSRROMCRCLengthPhase) & kCSRROMCRCLength) |
800: ((crc16 << kCSRROMCRCValuePhase) & kCSRROMCRCValue);
801: rom->appendBytes(pHeader, (romSize+1)*4);
802: IOFree(pHeader, (romSize+1)*4);
803: setProperty(gFireWireROM, rom);
804:
805: // If we have a FWIM that is fully FSL 1.1 compatible, use the set CSR ROM function.
806: // Otherwise just reset the bus.
807: #if 0
808: // Tell the FWIM to use this new CSR ROM data (and reset the bus)
809: //zzz Should support other (larger) ROM sizes
810: status = FWSetCSRROM (pHeader, (romSize+1)*4);
811: #endif
812: kprintf("old romspace: 0x%x\n", fROMAddrSpace);
813: if(fROMAddrSpace) {
814: freeAddress(fROMAddrSpace);
815: fROMAddrSpace->release();
816: fROMAddrSpace = NULL;
817: }
818: fROMAddrSpace = IOFWPseudoAddressSpace::simpleRead(
819: FWAddress(kCSRRegisterSpaceBaseAddressHi, kCSRROMBaseAddress),
820: (romSize+1)*4, rom->getBytesNoCopy());
821: ret = allocAddress(fROMAddrSpace);
822:
823: return (ret);
824: }
825:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.