Annotation of XNU/iokit/Families/IOFireWire/IOFWAddressSpace.cpp, revision 1.1.1.1

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:  *
                     24:  *     IOFWAddressSpace.cpp
                     25:  *
                     26:  * Classes which describe addresses in the local node which are accessable to other nodes
                     27:  * via firewire asynchronous read/write/lock requests.
                     28:  */
                     29: #include <IOKit/firewire/IOFWAddressSpace.h>
                     30: 
                     31: /*
                     32:  * Base class for FireWire address space objects
                     33:  */
                     34: OSDefineMetaClass( IOFWAddressSpace, OSObject )
                     35: OSDefineAbstractStructors(IOFWAddressSpace, OSObject)
                     36: 
                     37: /*
                     38:  * Direct physical memory <-> FireWire address.
                     39:  * Accesses to these addresses will be handled automatically by the
                     40:  * hardware without notification.
                     41:  *
                     42:  * The 64 bit FireWire address of (32 bit) physical addr xxxx:xxxx is hostNode:0000:xxxx:xxxx
                     43:  */
                     44: OSDefineMetaClassAndStructors(IOFWPhysicalAddressSpace, IOFWAddressSpace)
                     45: 
                     46: bool IOFWPhysicalAddressSpace::initWithDesc(IOMemoryDescriptor *mem)
                     47: {
                     48:     if(!IOFWAddressSpace::init())
                     49:         return false;
                     50:     fMem = mem;
                     51:     fLen = mem->getLength();
                     52: {
                     53:     vm_size_t pos;
                     54:     IOPhysicalAddress phys;
                     55:     pos = 0;
                     56:     while(pos < fLen) {
                     57:         IOPhysicalLength lengthOfSegment;
                     58:         phys = fMem->getPhysicalSegment(pos, &lengthOfSegment);
                     59:         pos += PAGE_SIZE - (phys & (PAGE_SIZE-1));
                     60:     }
                     61: }
                     62: 
                     63:     return true;
                     64: }
                     65: 
                     66: UInt32 IOFWPhysicalAddressSpace::doRead(UInt16 nodeID, FWAddress addr, UInt32 len, 
                     67:                                        IOMemoryDescriptor **buf, IOByteCount * offset,
                     68:                                        bool lockRead)
                     69: {
                     70:     UInt32 res = kFWResponseAddressError;
                     71:     vm_size_t pos;
                     72:     IOPhysicalAddress phys;
                     73:     if(addr.addressHi != 0)
                     74:        return kFWResponseAddressError;
                     75: 
                     76:     pos = 0;
                     77:     while(pos < fLen) {
                     78:         IOPhysicalLength lengthOfSegment;
                     79:         phys = fMem->getPhysicalSegment(pos, &lengthOfSegment);
                     80:         if(addr.addressLo >= phys && addr.addressLo+len <= phys+lengthOfSegment) {
                     81:             // OK, block is in space and is within one VM page
                     82:            // Set position to exact start
                     83:            *offset = pos + addr.addressLo - phys;
                     84:             *buf = fMem;
                     85:             res = kFWResponseComplete;
                     86:             break;
                     87:         }
                     88:         pos += PAGE_SIZE - (phys & (PAGE_SIZE-1));
                     89:     }
                     90:     return res;
                     91: }
                     92: 
                     93: UInt32 IOFWPhysicalAddressSpace::doWrite(UInt16 nodeID, FWAddress addr, UInt32 len, 
                     94:                                        const void *buf, bool lockWrite)
                     95: {
                     96:     UInt32 res = kFWResponseAddressError;
                     97:     vm_size_t pos;
                     98:     IOPhysicalAddress phys;
                     99:     if(addr.addressHi != 0)
                    100:        return kFWResponseAddressError;
                    101: 
                    102:     pos = 0;
                    103:     while(pos < fLen) {
                    104:         IOPhysicalLength lengthOfSegment;
                    105:         phys = fMem->getPhysicalSegment(pos, &lengthOfSegment);
                    106:         if(addr.addressLo >= phys && addr.addressLo+len <= phys+lengthOfSegment) {
                    107:             // OK, block is in space and is within one VM page
                    108:            // Set position to exact start
                    109:             fMem->writeBytes(pos + addr.addressLo - phys, buf, len);
                    110:             res = kFWResponseComplete;
                    111:             break;
                    112:         }
                    113:         pos += PAGE_SIZE - (phys & (PAGE_SIZE-1));
                    114:     }
                    115:     return res;
                    116: }
                    117: 
                    118: /*
                    119:  * Pseudo firewire addresses usually represent emulated registers of some kind.
                    120:  * Accesses to these addresses will result in the owner being notified.
                    121:  * 
                    122:  * Virtual addresses should not have zero as the top 16 bits of the 48 bit local address,
                    123:  * since that may look like a physical address to hardware (eg. OHCI).
                    124:  * if reader is NULL then reads will not be allowed.
                    125:  * if writer is NULL then writes will not be allowed.
                    126:  * if either is NULL then lock requests will not be allowed.
                    127:  * refcon is passed back as the first argument of read and write callbacks.
                    128:  */
                    129: OSDefineMetaClassAndStructors(IOFWPseudoAddressSpace, IOFWAddressSpace)
                    130: 
                    131: UInt32 IOFWPseudoAddressSpace::simpleReader(void *refcon, UInt16 nodeID,
                    132:                                        FWAddress addr, UInt32 len, IOMemoryDescriptor **buf,
                    133:                                        IOByteCount * offset, bool lockRead)
                    134: {
                    135:     IOFWPseudoAddressSpace * space = (IOFWPseudoAddressSpace *)refcon;
                    136:     *buf = space->fDesc;
                    137:     *offset = addr.addressLo - space->fBase.addressLo;
                    138: 
                    139:     return kFWResponseComplete;
                    140: }
                    141: 
                    142: UInt32 IOFWPseudoAddressSpace::simpleWriter(void *refcon, UInt16 nodeID,
                    143:                                FWAddress addr, UInt32 len, const void *buf, bool lockRead)
                    144: {
                    145:     IOFWPseudoAddressSpace * space = (IOFWPseudoAddressSpace *)refcon;
                    146:     space->fDesc->writeBytes(addr.addressLo - space->fBase.addressLo, buf, len);
                    147: 
                    148:     return kFWResponseComplete;
                    149: }
                    150: 
                    151: IOFWPseudoAddressSpace *
                    152: IOFWPseudoAddressSpace::simpleRead(FWAddress addr, UInt32 len, const void *data)
                    153: {
                    154:     IOFWPseudoAddressSpace * me;
                    155:     me = new IOFWPseudoAddressSpace;
                    156:     do {
                    157:         if(!me)
                    158:             break;
                    159:         if(!me->initAll(addr, len, simpleReader, NULL, (void *)me)) {
                    160:             me->release();
                    161:             me = NULL;
                    162:             break;
                    163:         }
                    164:         me->fDesc = IOMemoryDescriptor::withAddress((void *)data, len, kIODirectionOut);
                    165:         if(!me->fDesc) {
                    166:             me->release();
                    167:             me = NULL;
                    168:         }
                    169:     } while(false);
                    170: 
                    171:     return me;
                    172: }
                    173: 
                    174: IOFWPseudoAddressSpace *IOFWPseudoAddressSpace::simpleRW(FWAddress addr, UInt32 len, void *data)
                    175: {
                    176:     IOFWPseudoAddressSpace * me;
                    177:     me = new IOFWPseudoAddressSpace;
                    178:     do {
                    179:         if(!me)
                    180:             break;
                    181:         if(!me->initAll(addr, len, simpleReader, simpleWriter, (void *)me)) {
                    182:             me->release();
                    183:             me = NULL;
                    184:             break;
                    185:         }
                    186:         me->fDesc = IOMemoryDescriptor::withAddress(data, len, kIODirectionOut);
                    187:         if(!me->fDesc) {
                    188:             me->release();
                    189:             me = NULL;
                    190:         }
                    191:     } while(false);
                    192: 
                    193:     return me;
                    194: }
                    195: 
                    196: bool IOFWPseudoAddressSpace::initAll(FWAddress addr, UInt32 len, 
                    197:                FWReadCallback reader, FWWriteCallback writer, void *refCon)
                    198: {
                    199:     if(!IOFWAddressSpace::init())
                    200:        return false;
                    201: 
                    202:     fBase = addr;
                    203:     fBase.addressHi &= 0xFFFF; // Mask off nodeID part.
                    204:     fLen = len;
                    205:     fDesc = NULL;      // Only used by simpleRead case.
                    206:     fRefCon = refCon;
                    207:     fReader = reader;
                    208:     fWriter = writer;
                    209:     return true;
                    210: }
                    211: 
                    212: void IOFWPseudoAddressSpace::free()
                    213: {
                    214:     if(fDesc)
                    215:        fDesc->release();
                    216:     IOFWAddressSpace::free();
                    217: }
                    218: 
                    219: UInt32 IOFWPseudoAddressSpace::doRead(UInt16 nodeID, FWAddress addr, UInt32 len, 
                    220:                                        IOMemoryDescriptor **buf, IOByteCount * offset,
                    221:                                        bool lockRead)
                    222: {
                    223:     if(addr.addressHi != fBase.addressHi)
                    224:        return kFWResponseAddressError;
                    225:     if(addr.addressLo < fBase.addressLo)
                    226:        return kFWResponseAddressError;
                    227:     if(addr.addressLo > fBase.addressLo+fLen)
                    228:        return kFWResponseAddressError;
                    229:     if(!fReader)
                    230:         return kFWResponseTypeError;
                    231:     if(lockRead && !fWriter)
                    232:         return kFWResponseTypeError;
                    233: 
                    234:     return fReader(fRefCon, nodeID, addr, len, buf, offset, lockRead);
                    235: }
                    236: 
                    237: UInt32 IOFWPseudoAddressSpace::doWrite(UInt16 nodeID, FWAddress addr, UInt32 len, 
                    238:                                        const void *buf, bool lockWrite)
                    239: {
                    240:     if(addr.addressHi != fBase.addressHi)
                    241:        return kFWResponseAddressError;
                    242:     if(addr.addressLo < fBase.addressLo)
                    243:        return kFWResponseAddressError;
                    244:     if(addr.addressLo > fBase.addressLo+fLen)
                    245:        return kFWResponseAddressError;
                    246:     if(!fWriter)
                    247:         return kFWResponseTypeError;
                    248:     if(lockWrite && !fReader)
                    249:         return kFWResponseTypeError;
                    250: 
                    251:     return fWriter(fRefCon, nodeID, addr, len, buf, lockWrite);
                    252: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.