|
|
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: *
27: */
28:
29: #include <IOKit/IOLib.h>
30: #include <IOKit/firewire/IOFWDCLProgram.h>
31:
32: #define super OSObject
33:
34: OSDefineMetaClass( IODCLProgram, OSObject )
35: OSDefineAbstractStructors(IODCLProgram, OSObject)
36:
37: bool IODCLProgram::init(IOFireWireBus::DCLTaskInfo *info)
38: {
39: bool ok;
40: ok = OSObject::init();
41: if(!ok || info == NULL)
42: return ok;
43: do {
44: // Have to map DCL as read/write because timestamp opcode writes
45: // into the DCL.
46: fDCLDesc = IOMemoryDescriptor::withAddress(info->fDCLBaseAddr,
47: info->fDCLSize, kIODirectionOutIn, info->fTask);
48: if(!fDCLDesc) {
49: ok = false;
50: break;
51: }
52: fDataDesc = IOMemoryDescriptor::withAddress(info->fDataBaseAddr,
53: info->fDataSize, kIODirectionOutIn, info->fTask);
54: if(!fDataDesc) {
55: ok = false;
56: break;
57: }
58: // 6250 is the total bandwidth per frame at 400Mb/sec, seems a reasonable limit!
59: fDataCursor = IONaturalMemoryCursor::withSpecification(PAGE_SIZE, 6250);
60: if(!fDataCursor) {
61: ok = false;
62: break;
63: }
64: vm_address_t kernelDCL;
65: IOReturn res;
66: IOByteCount len;
67: res = fDCLDesc->prepare(kIODirectionOutIn);
68: if(res != kIOReturnSuccess) {
69: ok = false;
70: break;
71: }
72: kernelDCL = (vm_address_t)fDCLDesc->getVirtualSegment(0, &len);
73: assert(len >= info->fDCLSize);
74: fDCLTaskToKernel = kernelDCL - info->fDCLBaseAddr;
75: res = fDataDesc->prepare(kIODirectionOutIn);
76: if(res != kIOReturnSuccess) {
77: ok = false;
78: break;
79: }
80: fCallUser = info->fCallUser;
81: fCallRefCon = info->fCallRefCon;
82: fDataBase = info->fDataBaseAddr;
83: } while (false);
84: if(!ok) {
85: if(fDCLDesc)
86: fDCLDesc->release();
87: if(fDataDesc)
88: fDataDesc->release();
89: if(fDataCursor)
90: fDataCursor->release();
91: }
92: return ok;
93: }
94:
95: void IODCLProgram::free()
96: {
97: if(fDCLDesc) {
98: fDCLDesc->complete(kIODirectionOutIn);
99: fDCLDesc->release();
100: }
101: if(fDataDesc) {
102: fDataDesc->complete(kIODirectionOutIn);
103: fDataDesc->release();
104: }
105: if(fDataCursor)
106: fDataCursor->release();
107: OSObject::free();
108: }
109:
110: UInt32 IODCLProgram::getPhysicalSegs(void *addr, IOByteCount len,
111: IOMemoryCursor::PhysicalSegment segs[], UInt32 maxSegs)
112: {
113: UInt32 nSegs;
114: if(fDataDesc && fDataCursor) {
115: nSegs = fDataCursor->genPhysicalSegments(fDataDesc, (IOByteCount)addr - fDataBase, segs, maxSegs, len);
116: }
117: else {
118: UInt32 i;
119: vm_address_t pos;
120: pos = (vm_address_t)addr;
121: nSegs = (round_page(pos+len) - trunc_page(pos))/(PAGE_SIZE);
122: if (nSegs > maxSegs) {
123: IOLog("IODCLProgram::getPhysicalSegs(): Data descriptor too complex for compiler!\n");
124: nSegs = 0;
125: }
126: for(i = 0; i<nSegs; i++) {
127: IOByteCount segLen;
128: segs[i].location = pmap_extract(kernel_pmap, pos);
129: segLen = PAGE_SIZE - (pos & (PAGE_SIZE - 1));
130: if(segLen > len)
131: segLen = len;
132: segs[i].length = segLen;
133: pos += segLen;
134: len -= segLen;
135: }
136: }
137: return nSegs;
138: }
139:
140: void IODCLProgram::dumpDCL(DCLCommand *op)
141: {
142: while(op) {
143: UInt32 opcode;
144: IOLog("(0x%x)", op);
145: op = convertDCLPtrToKernel(op);
146: // Dispatch off of opcode.
147: opcode = op->opcode & ~kFWDCLOpFlagMask;
148: IOLog("Opcode 0x%x:", op);
149: switch(opcode) {
150: case kDCLReceivePacketStartOp :
151: {
152: DCLTransferPacketPtr t = (DCLTransferPacketPtr) op;
153:
154: IOLog("ReceivePacketStartDCL to 0x%x, size %d", t->buffer, t->size);
155: break;
156: }
157: case kDCLReceivePacketOp :
158: {
159: DCLTransferPacketPtr t = (DCLTransferPacketPtr) op;
160:
161: IOLog("ReceivePacketDCL to 0x%x, size %d", t->buffer, t->size);
162: break;
163: }
164:
165: case kDCLSendPacketStartOp :
166: {
167: DCLTransferPacketPtr t = (DCLTransferPacketPtr) op;
168:
169: IOLog("SendPacketStartDCL from 0x%x, size %d", t->buffer, t->size);
170: break;
171: }
172:
173: case kDCLSendPacketWithHeaderStartOp :
174: {
175: DCLTransferPacketPtr t = (DCLTransferPacketPtr) op;
176:
177: IOLog("SendPacketWithHeaderStartDCL from 0x%x, size %d", t->buffer, t->size);
178: break;
179: }
180:
181: case kDCLSendPacketOp :
182: {
183: DCLTransferPacketPtr t = (DCLTransferPacketPtr) op;
184:
185: IOLog("SendPacketDCL from 0x%x, size %d", t->buffer, t->size);
186: break;
187: }
188:
189: case kDCLCallProcOp :
190: {
191: DCLCallProcPtr t = (DCLCallProcPtr) op;
192:
193: IOLog("CallProcDCL calling 0x%x(0x%x)", t->proc, t->procData);
194: break;
195: }
196: case kDCLJumpOp :
197: IOLog("JumpDCL to 0x%x", ((DCLJumpPtr)op)->pJumpDCLLabel);
198: break;
199:
200: case kDCLLabelOp :
201: IOLog("LabelDCL");
202: break;
203:
204: case kDCLSetTagSyncBitsOp :
205: IOLog("SetTagSyncBitsDCL");
206: break;
207:
208: case kDCLUpdateDCLListOp :
209: {
210: int i;
211: DCLUpdateDCLListPtr t = (DCLUpdateDCLListPtr) op;
212: DCLCommandPtr *p = t->dclCommandList;
213: IOLog("updateDCLListDCL:");
214: for(i=0; i<t->numDCLCommands; i++)
215: IOLog("0x%x ", *p++);
216: break;
217: }
218:
219: case kDCLTimeStampOp :
220: IOLog("timeStampDCL");
221: break;
222: default: IOLog("Unknown opcode %d", opcode);
223: break;
224: }
225: IOLog("\n");
226: op = op->pNextDCLCommand;
227: }
228: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.