The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/iokit/Kernel/IOMemoryCursor.cpp

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
    3  *
    4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
    5  * 
    6  * This file contains Original Code and/or Modifications of Original Code
    7  * as defined in and that are subject to the Apple Public Source License
    8  * Version 2.0 (the 'License'). You may not use this file except in
    9  * compliance with the License. The rights granted to you under the License
   10  * may not be used to create, or enable the creation or redistribution of,
   11  * unlawful or unlicensed copies of an Apple operating system, or to
   12  * circumvent, violate, or enable the circumvention or violation of, any
   13  * terms of an Apple operating system software license agreement.
   14  * 
   15  * Please obtain a copy of the License at
   16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
   17  * 
   18  * The Original Code and all software distributed under the License are
   19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
   20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
   21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
   22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
   23  * Please see the License for the specific language governing rights and
   24  * limitations under the License.
   25  * 
   26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
   27  */
   28 /* IOMemoryCursor.cpp created by wgulland on 1999-3-02 */
   29 
   30 #include <IOKit/assert.h>
   31 #include <IOKit/IOLib.h>
   32 #include <IOKit/IOMemoryCursor.h>
   33 #include <IOKit/IOMemoryDescriptor.h>
   34 #include <libkern/OSByteOrder.h>
   35 
   36 /**************************** class IOMemoryCursor ***************************/
   37 
   38 #undef super
   39 #define super OSObject
   40 OSDefineMetaClassAndStructors(IOMemoryCursor, OSObject)
   41 
   42 IOMemoryCursor *
   43 IOMemoryCursor::withSpecification(SegmentFunction  inSegFunc,
   44                                   IOPhysicalLength inMaxSegmentSize,
   45                                   IOPhysicalLength inMaxTransferSize,
   46                                   IOPhysicalLength inAlignment)
   47 {
   48     IOMemoryCursor * me = new IOMemoryCursor;
   49 
   50     if (me && !me->initWithSpecification(inSegFunc,
   51                                          inMaxSegmentSize,
   52                                          inMaxTransferSize,
   53                                          inAlignment))
   54     {
   55         me->release();
   56         return 0;
   57     }
   58 
   59     return me;
   60 }
   61 
   62 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
   63 
   64 bool
   65 IOMemoryCursor::initWithSpecification(SegmentFunction  inSegFunc,
   66                                       IOPhysicalLength inMaxSegmentSize,
   67                                       IOPhysicalLength inMaxTransferSize,
   68                                       IOPhysicalLength inAlignment)
   69 {
   70 // @@@ gvdl: Remove me
   71 #if 1
   72 static UInt sMaxDBDMASegment;
   73 if (!sMaxDBDMASegment) {
   74     sMaxDBDMASegment = (UInt) -1;
   75     if (PE_parse_boot_arg("mseg", &sMaxDBDMASegment))
   76         IOLog("Setting MaxDBDMASegment to %d\n", sMaxDBDMASegment);
   77 }
   78 
   79 if (inMaxSegmentSize > sMaxDBDMASegment) inMaxSegmentSize = sMaxDBDMASegment;
   80 #endif
   81 
   82     if (!super::init())
   83         return false;
   84 
   85     if (!inSegFunc)
   86         return false;
   87 
   88     outSeg              = inSegFunc;
   89     maxSegmentSize      = inMaxSegmentSize;
   90     if (inMaxTransferSize)
   91         maxTransferSize = inMaxTransferSize;
   92     else
   93         maxTransferSize = (IOPhysicalLength) -1;
   94     alignMask           = inAlignment - 1;
   95     assert(alignMask == 0);             // No alignment code yet!
   96 
   97     return true;
   98 }
   99 
  100 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  101 
  102 UInt32 
  103 IOMemoryCursor::genPhysicalSegments(IOMemoryDescriptor *inDescriptor,
  104                                     IOPhysicalLength    fromPosition,
  105                                     void *              inSegments,
  106                                     UInt32              inMaxSegments,
  107                                     UInt32              inMaxTransferSize,
  108                                     IOByteCount         *outTransferSize)
  109 {
  110     if (!inDescriptor)
  111         return 0;
  112 
  113     if (!inMaxSegments)
  114         return 0;
  115 
  116     if (!inMaxTransferSize)
  117         inMaxTransferSize = maxTransferSize;
  118 
  119     /*
  120      * Iterate over the packet, translating segments where allowed
  121      *
  122      * If we finished cleanly return number of segments found
  123      * and update the position in the descriptor.
  124      */
  125     PhysicalSegment curSeg = { 0, 0 };
  126     UInt curSegIndex = 0;
  127     UInt curTransferSize = 0;
  128     IOByteCount inDescriptorLength = inDescriptor->getLength();
  129     PhysicalSegment seg = { 0, 0 };
  130 
  131     while ((seg.location) || (fromPosition < inDescriptorLength)) 
  132     {
  133         if (!seg.location)
  134         {
  135             seg.location = inDescriptor->getPhysicalSegment(
  136                                fromPosition, &seg.length);
  137             assert(seg.location);
  138             assert(seg.length);
  139             fromPosition += seg.length;
  140         }
  141 
  142         if (!curSeg.location)
  143         {
  144             curTransferSize += seg.length;
  145             curSeg = seg;
  146             seg.location = 0;
  147         }
  148         else if ((curSeg.location + curSeg.length == seg.location))
  149         {
  150             curTransferSize += seg.length;
  151             curSeg.length += seg.length;
  152             seg.location = 0;
  153         }
  154 
  155         if (!seg.location)
  156         {
  157             if ((curSeg.length > maxSegmentSize))
  158             {
  159                 seg.location = curSeg.location + maxSegmentSize;
  160                 seg.length = curSeg.length - maxSegmentSize;
  161                 curTransferSize -= seg.length;
  162                 curSeg.length -= seg.length;
  163             }
  164 
  165             if ((curTransferSize >= inMaxTransferSize))
  166             {
  167                 curSeg.length -= curTransferSize - inMaxTransferSize;
  168                 curTransferSize = inMaxTransferSize;
  169                 break;
  170             }
  171         }
  172 
  173         if (seg.location)
  174         {
  175             if ((curSegIndex + 1 == inMaxSegments))
  176                 break;
  177             (*outSeg)(curSeg, inSegments, curSegIndex++);
  178             curSeg.location = 0;
  179         }
  180     }
  181 
  182     if (curSeg.location)
  183         (*outSeg)(curSeg, inSegments, curSegIndex++);
  184 
  185     if (outTransferSize)
  186         *outTransferSize = curTransferSize;
  187 
  188     return curSegIndex;
  189 }
  190 
  191 /************************ class IONaturalMemoryCursor ************************/
  192 
  193 #undef super
  194 #define super IOMemoryCursor
  195 OSDefineMetaClassAndStructors(IONaturalMemoryCursor, IOMemoryCursor)
  196 
  197 void IONaturalMemoryCursor::outputSegment(PhysicalSegment segment,
  198                                           void *          outSegments,
  199                                           UInt32          outSegmentIndex)
  200 {
  201     ((PhysicalSegment *) outSegments)[outSegmentIndex] = segment;
  202 }
  203 
  204 IONaturalMemoryCursor * 
  205 IONaturalMemoryCursor::withSpecification(IOPhysicalLength inMaxSegmentSize,
  206                                          IOPhysicalLength inMaxTransferSize,
  207                                          IOPhysicalLength inAlignment)
  208 {
  209     IONaturalMemoryCursor *me = new IONaturalMemoryCursor;
  210 
  211     if (me && !me->initWithSpecification(inMaxSegmentSize,
  212                                          inMaxTransferSize,
  213                                          inAlignment))
  214     {
  215         me->release();
  216         return 0;
  217     }
  218 
  219     return me;
  220 }
  221 
  222 bool 
  223 IONaturalMemoryCursor::initWithSpecification(IOPhysicalLength inMaxSegmentSize,
  224                                              IOPhysicalLength inMaxTransferSize,
  225                                              IOPhysicalLength inAlignment)
  226 {
  227     return super::initWithSpecification(&IONaturalMemoryCursor::outputSegment,
  228                                         inMaxSegmentSize,
  229                                         inMaxTransferSize,
  230                                         inAlignment);
  231 }
  232 
  233 /************************** class IOBigMemoryCursor **************************/
  234 
  235 #undef super
  236 #define super IOMemoryCursor
  237 OSDefineMetaClassAndStructors(IOBigMemoryCursor, IOMemoryCursor)
  238 
  239 void 
  240 IOBigMemoryCursor::outputSegment(PhysicalSegment inSegment,
  241                                  void *          inSegments,
  242                                  UInt32          inSegmentIndex)
  243 {
  244     IOPhysicalAddress * segment;
  245 
  246     segment = &((PhysicalSegment *) inSegments)[inSegmentIndex].location;
  247     OSWriteBigInt(segment, 0, inSegment.location);
  248     OSWriteBigInt(segment, sizeof(IOPhysicalAddress), inSegment.length);
  249 }
  250 
  251 IOBigMemoryCursor *
  252 IOBigMemoryCursor::withSpecification(IOPhysicalLength inMaxSegmentSize,
  253                                      IOPhysicalLength inMaxTransferSize,
  254                                      IOPhysicalLength inAlignment)
  255 {
  256     IOBigMemoryCursor * me = new IOBigMemoryCursor;
  257 
  258     if (me && !me->initWithSpecification(inMaxSegmentSize,
  259                                          inMaxTransferSize,
  260                                          inAlignment))
  261     {
  262         me->release();
  263         return 0;
  264     }
  265 
  266     return me;
  267 }
  268 
  269 bool 
  270 IOBigMemoryCursor::initWithSpecification(IOPhysicalLength inMaxSegmentSize,
  271                                          IOPhysicalLength inMaxTransferSize,
  272                                          IOPhysicalLength inAlignment)
  273 {
  274     return super::initWithSpecification(&IOBigMemoryCursor::outputSegment,
  275                                         inMaxSegmentSize,
  276                                         inMaxTransferSize,
  277                                         inAlignment);
  278 }
  279 
  280 /************************* class IOLittleMemoryCursor ************************/
  281 
  282 #undef super
  283 #define super IOMemoryCursor
  284 OSDefineMetaClassAndStructors(IOLittleMemoryCursor, IOMemoryCursor)
  285 
  286 void 
  287 IOLittleMemoryCursor::outputSegment(PhysicalSegment inSegment,
  288                                     void *          inSegments,
  289                                     UInt32          inSegmentIndex)
  290 {
  291     IOPhysicalAddress * segment;
  292 
  293     segment = &((PhysicalSegment *) inSegments)[inSegmentIndex].location;
  294     OSWriteLittleInt(segment, 0, inSegment.location);
  295     OSWriteLittleInt(segment, sizeof(IOPhysicalAddress), inSegment.length);
  296 }
  297 
  298 IOLittleMemoryCursor *
  299 IOLittleMemoryCursor::withSpecification(IOPhysicalLength inMaxSegmentSize,
  300                                         IOPhysicalLength inMaxTransferSize,
  301                                         IOPhysicalLength inAlignment)
  302 {
  303     IOLittleMemoryCursor * me = new IOLittleMemoryCursor;
  304 
  305     if (me && !me->initWithSpecification(inMaxSegmentSize,
  306                                          inMaxTransferSize,
  307                                          inAlignment))
  308     {
  309         me->release();
  310         return 0;
  311     }
  312 
  313     return me;
  314 }
  315 
  316 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  317 
  318 bool 
  319 IOLittleMemoryCursor::initWithSpecification(IOPhysicalLength inMaxSegmentSize,
  320                                             IOPhysicalLength inMaxTransferSize,
  321                                             IOPhysicalLength inAlignment)
  322 {
  323     return super::initWithSpecification(&IOLittleMemoryCursor::outputSegment,
  324                                         inMaxSegmentSize,
  325                                         inMaxTransferSize,
  326                                         inAlignment);
  327 }
  328 
  329 /************************* class IODBDMAMemoryCursor *************************/
  330 
  331 #if defined(__ppc__)
  332 
  333 #include <IOKit/ppc/IODBDMA.h>
  334 
  335 #undef super
  336 #define super IOMemoryCursor
  337 OSDefineMetaClassAndStructors(IODBDMAMemoryCursor, IOMemoryCursor)
  338 
  339 void 
  340 IODBDMAMemoryCursor::outputSegment(PhysicalSegment inSegment,
  341                                    void *          inSegments,
  342                                    UInt32          inSegmentIndex)
  343 {
  344     IODBDMADescriptor *segment;
  345 
  346     segment = &((IODBDMADescriptor *) inSegments)[inSegmentIndex];
  347 
  348     // Write location into address field
  349     OSWriteSwapInt32((UInt32 *) segment, 4, inSegment.location);
  350 
  351     // Write count into 1st two bytes of operation field.
  352     // DO NOT touch rest of operation field as it should contain a STOP command.
  353     OSWriteSwapInt16((UInt16 *) segment, 0, inSegment.length);
  354 }
  355 
  356 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  357 
  358 IODBDMAMemoryCursor *
  359 IODBDMAMemoryCursor::withSpecification(IOPhysicalLength inMaxSegmentSize,
  360                                        IOPhysicalLength inMaxTransferSize,
  361                                        IOPhysicalLength inAlignment)
  362 {
  363     IODBDMAMemoryCursor *me = new IODBDMAMemoryCursor;
  364 
  365     if (me && !me->initWithSpecification(inMaxSegmentSize,
  366                                          inMaxTransferSize,
  367                                          inAlignment))
  368     {
  369         me->release();
  370         return 0;
  371     }
  372 
  373     return me;
  374 }
  375 
  376 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  377 
  378 bool
  379 IODBDMAMemoryCursor::initWithSpecification(IOPhysicalLength inMaxSegmentSize,
  380                                            IOPhysicalLength inMaxTransferSize,
  381                                            IOPhysicalLength inAlignment)
  382 {
  383     return super::initWithSpecification(&IODBDMAMemoryCursor::outputSegment,
  384                                         inMaxSegmentSize,
  385                                         inMaxTransferSize,
  386                                         inAlignment);
  387 }
  388 
  389 #endif /* defined(__ppc__) */
  390 

Cache object: 9f2b91e4b945bc690c63d5cc2e558b82


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.