Annotation of kernel/bsd/dev/ppc/drvUSBCMD/ohciuim.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
        !             7:  * Reserved.  This file contains Original Code and/or Modifications of
        !             8:  * Original Code as defined in and that are subject to the Apple Public
        !             9:  * Source License Version 1.1 (the "License").  You may not use this file
        !            10:  * except in compliance with the License.  Please obtain a copy of the
        !            11:  * License at http://www.apple.com/publicsource and read it before using
        !            12:  * this file.
        !            13:  * 
        !            14:  * The Original Code and all software distributed under the License are
        !            15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            19:  * License for the specific language governing rights and limitations
        !            20:  * under the License.
        !            21:  * 
        !            22:  * @APPLE_LICENSE_HEADER_END@
        !            23:  */
        !            24: 
        !            25: /*
        !            26:        File:           OHCIUIM.c
        !            27: 
        !            28:        Contains:       OHCI implementation of USB Hal for Neptune Project
        !            29: 
        !            30:        Version:        xxx put version here xxx
        !            31: 
        !            32:        Written by:     Guillermo Gallegos
        !            33: 
        !            34:        Copyright:      � 1997-1998 by Apple Computer, Inc., all rights reserved.
        !            35: 
        !            36:        File Ownership:
        !            37: 
        !            38:                DRI:                            xxx put dri here xxx
        !            39: 
        !            40:                Other Contact:          xxx put other contact here xxx
        !            41: 
        !            42:                Technology:                     xxx put technology here xxx
        !            43: 
        !            44:        Writers:
        !            45: 
        !            46:                (TC)    Tom Clark
        !            47:                (DRF)   Dave Falkenburg
        !            48:                (DF)    David Ferguson
        !            49:                (GG)    Guillermo Gallegos
        !            50:                (BT)    Barry Twycross
        !            51:                (CJK)   Craig Keithley
        !            52: 
        !            53:        Change History (most recent first):
        !            54: 
        !            55:         <USB89>        11/20/98        GG              [2287626]  Fixed bug where I was instantiating the same callback
        !            56:                                                                        twice, which was causing a crash with the Imation Drive.
        !            57:         <USB88>        11/18/98        GG              [2283557]  Changed the calculation of the frame number to
        !            58:                                                                        account for use of bit 15 of the frame number register as a
        !            59:                                                                        toggle overflow. Should fix bug where the framenumber was too
        !            60:                                                                        high.
        !            61:         <USB87>        11/16/98        GG              Fixed off by one error in isochronous transfers and cleaned up
        !            62:                                                                        finalize routines memory deallocations.
        !            63:         <USB86>        11/12/98        GG              Fixed memory leaks in descriptor allocation, PCI allocatio and
        !            64:                                                                        pphysical to virtual allocations.
        !            65:         <USB85>        11/11/98        GG              Fixed how ischronous tranfers get the end of there buffer
        !            66:                                                                        calculated for each TD.
        !            67:         <USB84>         11/9/98        CJK             Back out some changes to rev 80.  Should make bulk work again.
        !            68:         <USB83>         11/5/98        GG              Fix bug where Bulk didnt work due to bug introduced in 81.  Also
        !            69:                                                                        cleaned up a little.
        !            70:         <USB82>        10/24/98        GG              Changed power on of root hub to call rootHubPower, instead of
        !            71:                                                                        tripping the bit directly. Also added a function to find out
        !            72:                                                                        what machine we are on.
        !            73:         <USB81>        10/22/98        GG              Fixed bug where pages needed would be mis calculated if the the
        !            74:                                                                        buffer ended on the first byte of a page.
        !            75:         <USB80>         9/14/98        GG              Fix Isoch bug where Isochronous was being disabled when Opti
        !            76:                                                                        errata fix was being implemented.
        !            77:         <USB79>          9/9/98        BT              Fix Isoc
        !            78:         <USB78>          9/9/98        BT              Fix size of Isoc refcon
        !            79:         <USB77>          9/5/98        GG              Some more Isoch fixes.
        !            80:         <USB76>          9/4/98        GG              Fix page used calcualation and internal loop condition.
        !            81:         <USB75>          9/3/98        GG              Add Isochronous Suppurt for Create, Abort, Delete endpoint and
        !            82:                                                                        create transfers.  Also rolled in earlier branch fix to TOT, the
        !            83:                                                                        off by 2 bug.
        !            84:         <USB74>         8/12/98        GG              Initialize pointer in zero length bulk transfer condition.
        !            85:         <USB73>         8/12/98        BT              Move root hub into UIM again.
        !            86:         <USB72>         8/11/98        GG              Fixed the original Compiles and works with symbols, but compiles
        !            87:                                                                        but not works without symbols.  Turns out to be an uninitialized
        !            88:                                                                        pointer to the register set.
        !            89:         <USB71>         8/11/98        GG              Commented out a for(j=0;j<0;j++) loop that the compiler did not
        !            90:                                                                        know how to optimize, with symbols on it worked, symbols off it
        !            91:                                                                        didnt.
        !            92:         <USB70>         8/11/98        GG              stuff
        !            93:         <USB69>          8/7/98        GG              Fixed Opti data corruption problem. Also fixed bug where an
        !            94:                                                                        aborted transfer would return wrong value for pending data.
        !            95:                                                                        Tweaked interface to USL to be consistent with direction
        !            96:                                                                        parameter.
        !            97:         <USB68>         7/28/98        GG              Merged to TOT: <USB62a2> 7/15/98 GG Fixed bug that was caused by
        !            98:                                                                        previous checkin where transfer setup would try to use data
        !            99:                                                                        outsided the preparememforio physical data block. <USB62a1>
        !           100:                                                                        7/14/98 GG [2252282] <TC> Fixed Bulk to not generate short
        !           101:                                                                        packets in the middle of a tranfer, both read and write. This
        !           102:                                                                        was caused when the data buffer was not aligned in memory to max
        !           103:                                                                        packet size. The fix was to check for unalignment and to
        !           104:                                                                        generate 4k or less Transfer Descriptors.
        !           105:         <USB67>         7/23/98        BT              fix fix
        !           106:         <USB66>         7/23/98        BT              Fix Endpoint Delete to not hose bulk and control queues
        !           107:         <USB65>         7/10/98        TC              Back out <USB63>
        !           108:         <USB64>         6/30/98        BT              Tidy up
        !           109:         <USB63>         6/30/98        BT              Move Root hub sim into UIM
        !           110:         <USB62>         6/24/98        GG              Changed PeriodStart Register to static value instead of
        !           111:                                                                        calculating it.
        !           112:         <USB61>         6/23/98        DF              [2238756, 2243961]  always reset the endpoint virtual head when
        !           113:                                                                        deleting TDs.
        !           114:         <USB60>         6/15/98        DF              Turn off power when finializing the UIM
        !           115:         <USB59>         6/14/98        DF              Remove unused variable that was causing a warning
        !           116:         <USB58>         6/14/98        DF              Shutdown the OHCI controller when Finalize function is called.
        !           117:         <USB57>         6/13/98        BT              Stop hanging is we don't see a start of frame interrupt.
        !           118:         <USB56>          6/4/98        DF              turn off debugstrs and other clean up
        !           119:         <USB55>          6/4/98        DRF             In UIMInitialize & UIMFinalize, add a Ptr to facilitate
        !           120:                                                                        handing-off global state when performing replacement. NOTE:
        !           121:                                                                        These routines still to be changed to do the additional work.
        !           122:         <USB54>          6/3/98        GG              Changed UInt64 operations to use macros from Math64.h.  Made
        !           123:                                                                        interrupts go to their requested period and randomly generated
        !           124:                                                                        slot with given period.
        !           125:         <USB53>          6/3/98        GG              Checked if UInt64 is a structure or integer.
        !           126:         <USB52>          6/3/98        DF              [2240506]  clear skipped bit when aborting transfers, also
        !           127:                                                                        slight tweek to the frame number stuff to work with the
        !           128:                                                                        compilers used when building in SuperMario.
        !           129:         <USB51>          6/2/98        GG              Add interfaces IsochEndpointCreate, and IsochTransfer.  Also
        !           130:                                                                        added a getFrameCount function.
        !           131:         <USB50>          6/2/98        DRF             Added params to UIMInitialize & UIMFinalize for replacement. Use
        !           132:                                                                        them later
        !           133:         <USB49>         5/16/98        DF              For now, always call CheckPointIO after getting the physical
        !           134:                                                                        address of transfer buffers.  PrepareMemoryForIO and
        !           135:                                                                        CheckpointIO are not implemented as advertised that's why we are
        !           136:                                                                        having so much trouble with them.  The real solution is to carry
        !           137:                                                                        a copy of the ioPreparation table with each active transfer
        !           138:                                                                        descriptor.
        !           139:         <USB48>         5/15/98        DF              make the bus operational following an unrecoverable error
        !           140:                                                                        interrupt, fix TD leak in bulk transfers, turn back on the
        !           141:                                                                        CheckpointIOs, misc cleanups.
        !           142:         <USB47>         5/14/98        GG              Added BufferUnderrun Errata Fix for CMD KAB4 and KAB4 revA.
        !           143:                                                                        Also increased memory usage and added some checks for out of
        !           144:                                                                        memory cases.  Took out CheckpointIO usage for now.
        !           145:         <USB46>         5/14/98        DF              Initialize the root hub status register
        !           146:         <USB45>          5/8/98        DF              Make sure interrupt transfer descriptors use the endpoint for
        !           147:                                                                        the data toggle carry.
        !           148:         <USB44>          5/7/98        BT              Hack find interrupt endpoint so it never finds control endpoint
        !           149:                                                                        for (0,0).
        !           150:         <USB43>          5/5/98        GG              Change Buffersize from short to unsigned long in BulkTransfer.
        !           151:         <USB42>          5/4/98        GG              Another fix for Bulk transfers in done Q processing.
        !           152:         <USB41>          5/4/98        GG              Fixed Done Queue Processing to do error recovery.
        !           153:         <USB40>          5/4/98        DF              fix errata test, and check the Bulk list when clearing endpoint
        !           154:                                                                        stalls
        !           155:         <USB39>          5/2/98        DF              fix bulk transfers, add errata checks, remove VooDoo, add
        !           156:                                                                        CheckPointIO() calls when TDs are released.
        !           157:         <USB38>         4/29/98        BT              Fix returned errors, hasck in FSMPS
        !           158:         <USB37>         4/29/98        GG              Added calculation of FSMPS based on FMInterval.
        !           159:         <USB36>         4/27/98        DF              Initialize the Control & Bulk Current Pointers
        !           160:         <USB35>         4/24/98        GG              Added support for bulk transfers greater than 4k.  Added fix to
        !           161:                                                                        support to clear an endpoint stall.
        !           162:         <USB34>         4/22/98        DF              Mask off low-order interrupt bits when reading the hccaDoneHead.
        !           163:                                                                        Also change to match pci class code instead of a specific
        !           164:                                                                        vendor's chip.
        !           165:         <USB33>         4/16/98        BT              Fix codewarrior incompatabilities
        !           166:         <USB32>         4/14/98        DF              make ProcessDoneQueue do something useful
        !           167:         <USB31>          4/9/98        BT              Use USB.h
        !           168:                <30>      4/8/98        GG              Modified OHCIUIMEndpointDelete to not be static.
        !           169:                <29>      4/7/98        GG              Added support for OF generic driver.  Added suypport for UHCI to
        !           170:                                                                        OHCI mode.
        !           171:                <28>      4/7/98        GG              Added Abort and Delete Apis.
        !           172:                <27>     3/19/98        BT              Split UIM into UIM and root hub parts
        !           173:                <26>     3/18/98        BT              Add reset enable change to root hub.
        !           174:                <25>     3/11/98        BT              Root hub interrupt transaction simulation support
        !           175:                <24>     2/25/98        GG              Re enabled queue processing.
        !           176:                <23>     2/25/98        GG              Modified Interrupt transfer to call a separate troutine to find
        !           177:                                                                        an enpoint.
        !           178:                <22>     2/24/98        GG              Calculated Periodic Start using Frame Interval.  Changed
        !           179:                                                                        calculation of Interrupt tree.
        !           180:                <21>     2/23/98        GG              Added checks for task time.  Changed Interrupt heads to be an
        !           181:                                                                        array of structs.  Changed the value of hcPeriodicStart register
        !           182:                                                                        to spec static value.  Corrected interrupt tree structure.
        !           183:                <20>     2/20/98        GG              Fixed compile problem.
        !           184:                <19>     2/20/98        GG              Changed DelayFor to DelayForHardware, modifed
        !           185:                                                                        InterruptInitialize.
        !           186:                <18>     2/20/98        GG              Changed to CMD from Opti.
        !           187:                <17>     2/20/98        GG              Enabled periodic endpoint processing.
        !           188:                <16>     2/20/98        GG              Added Interrupt Transfer Support.  Modified Interrupt Endpoint
        !           189:                                                                        Creation.
        !           190:                <15>     2/19/98        GG              Added endpoint creation functonality.
        !           191:         <USB14>         2/17/98        DF              Add HW Interrupt handling, and a few changes related to getting
        !           192:                                                                        operation in a VM environment working.
        !           193:                <13>     2/13/98        GG              Comment out debug strings
        !           194:                <12>     2/13/98        GG              Comment out debug strings
        !           195:                <11>     2/12/98        GG              Added Rom in Ram memory offset support.  Overwrote #10 and 9
        !           196:                                                                        Checkins.
        !           197:         <USB10>         2/12/98        DF              Detect unrecoverable error at initialize time, and try to
        !           198:                                                                        recover by resetting
        !           199:          <USB9>         2/12/98        DF              Add more error checking on memory allocations
        !           200:                 <8>      2/2/98        BT              Add bulk stuff
        !           201:                 <7>     1/26/98        BT              Add unstall endpoint
        !           202:                 <6>    12/19/97        BT              Temp hack, Make it a shared lib
        !           203:                 <5>    12/18/97        BT              Add in my changes so this works with multiple endpoints
        !           204:                 <4>    11/30/97        BT              Various mods to get perliminary USL running
        !           205:                <3*>    11/20/97        GG              Add callback parameter to bulk and control creators.
        !           206:                 <3>    11/20/97        GG              Initial check in has minimal support for Root Hub, Control and
        !           207:                                                                        Bulk transfers.
        !           208:                 <2>    11/20/97        GG              Filled in Contains Field.
        !           209:                 <1>    11/20/97        GG              first checked in
        !           210: 
        !           211: */
        !           212: 
        !           213: #import <mach/mach_types.h>
        !           214: #import <architecture/arch_types.h>
        !           215: #import <machdep/ppc/interrupts.h>
        !           216: #import <kernserv/prototypes.h>
        !           217: #import <kernserv/clock_timer.h>
        !           218: #import <kernserv/ns_timer.h>
        !           219: #import <sys/time.h>     
        !           220: #import <sys/callout.h>
        !           221: #include <bsd/sys/systm.h>
        !           222: #import <sys/proc.h>    // prototypes for sleep,wakeup                  
        !           223: #import <sys/fcntl.h>                                                   
        !           224: #include <vm/vm_kern.h>
        !           225: #import <driverkit/generalFuncs.h>
        !           226:                 
        !           227: #include "driverservices.h"
        !           228: #include "USB.h"
        !           229: #include "USBpriv.h"
        !           230: #include "OHCIUIM.h"     
        !           231: #include "OHCIRootHub.h"
        !           232: #include "pci.h"                                                        
        !           233: 
        !           234: #define  ProgressDebugStr(s)   kprintf(s)         /* SysDebugStr(s)    */
        !           235: #define  MemoryDebugStr(s)    kprintf(s)          /* SysDebugStr(s)    */
        !           236: #define  AssertDebugStr(s)   kprintf(s)                 /* SysDebugStr(s)    */
        !           237: #define  FailureDebugStr(s)  kprintf(s)          /* SysDebugStr(s)    */
        !           238: 
        !           239: void IOSync(void);       
        !           240: simple_lock_t usb_slock; 
        !           241: char Desc_Buffer_Usb[54*4096];  //naga  
        !           242: extern OHCIUIMDataPtr                           pOHCIUIMData;
        !           243: #define KBD_UNIQUE_ADDRESS    10
        !           244: #define MOUSE_UNIQUE_ADDRESS  0x61
        !           245: 
        !           246: 
        !           247: 
        !           248: 
        !           249: static OSStatus OHCIUIMFinalizeOHCIUIMData(
        !           250:        OHCIUIMDataPtr                          pOHCIUIMData);
        !           251: 
        !           252: static OSStatus        OHCIUIMGetRegisterBaseAddress (
        !           253:        RegEntryIDPtr                           pOHCIRegEntryID,
        !           254:        OHCIRegistersPtr                        *ppOHCIRegisters);
        !           255: 
        !           256: UInt32 OHCIUIMCreatePhysicalAddress(
        !           257:        UInt32                                          LogicalAddress,
        !           258:        UInt32                                          count);
        !           259:        
        !           260: UInt32 OHCIUIMGetPhysicalAddress(
        !           261:        UInt32                                          LogicalAddress,
        !           262:        UInt32                                          count);
        !           263: 
        !           264: UInt32 OHCIUIMGetLogicalAddress (
        !           265:        UInt32                          pPhysicalAddress);
        !           266: 
        !           267: OSStatus OHCIUIMAllocateBuffer();
        !           268: 
        !           269: OSStatus OHCIUIMDeallocateED (
        !           270:        OHCIEndpointDescriptorPtr pED);
        !           271:        
        !           272: OSStatus OHCIUIMDeallocateTD (
        !           273:        OHCIGeneralTransferDescriptorPtr pTD);
        !           274:        
        !           275: OSStatus OHCIUIMDeallocateITD (
        !           276:        OHCIIsochTransferDescriptorPtr pTD);
        !           277:        
        !           278: OHCIEndpointDescriptorPtr OHCIUIMAllocateED();
        !           279: 
        !           280: OHCIGeneralTransferDescriptorPtr OHCIUIMAllocateTD();
        !           281: 
        !           282: OHCIIsochTransferDescriptorPtr OHCIUIMAllocateITD();
        !           283: 
        !           284: OSStatus OHCIUIMAllocateMemory (
        !           285:        int                                                             num_of_TDs,
        !           286:        int                                                                     num_of_EDs,
        !           287:        int                                                                     num_of_ITDs);
        !           288: 
        !           289: OSStatus OHCIUIMInterruptFindED();
        !           290: 
        !           291: OSStatus OHCIUIMInterruptBandwidthCheck();
        !           292: 
        !           293: OSStatus OHCIUIMInterruptfits();
        !           294: 
        !           295: OSStatus OHCIUIMInterruptschedule();
        !           296: 
        !           297: OSStatus OHCIUIMIsochronousInitialize();
        !           298: OSStatus OHCIUIMInterruptInitialize ();
        !           299: OSStatus OHCIUIMBulkInitialize ();
        !           300: OSStatus OHCIUIMControlInitialize ();
        !           301: 
        !           302: OSStatus OHCIUIMInstallInterruptHandler();
        !           303: 
        !           304: OSStatus OHCIUIMInterruptHandler (InterruptSetMember member, void *refCon, UInt32 interruptCount);
        !           305: 
        !           306: OSStatus DoDoneQueueProcessing(OHCIGeneralTransferDescriptorPtr pHCDoneTD, Boolean immediateFlag);
        !           307: 
        !           308: Boolean BandwidthAvailable(
        !           309:        UInt32                  pollingRate, 
        !           310:        UInt32                  reserveBandwidth,
        !           311:        int                             *offset);
        !           312: 
        !           313: OHCIEndpointDescriptorPtr FindEndpoint (
        !           314:        short                                           functionNumber, 
        !           315:        short                                           endpointNumber,
        !           316:        short                                           direction, 
        !           317:        OHCIEndpointDescriptorPtr       *pEDQueueBack, 
        !           318:        UInt32                                          *controlMask);
        !           319: 
        !           320: 
        !           321: OHCIEndpointDescriptorPtr FindInterruptEndpoint(
        !           322:        short                                           functionNumber,
        !           323:        short                                           endpointNumber,
        !           324:        OHCIEndpointDescriptorPtr       *pEDBack);
        !           325: 
        !           326: OHCIEndpointDescriptorPtr FindBulkEndpoint (
        !           327:        short                                           functionNumber, 
        !           328:        short                                           endpointNumber,
        !           329:        short                                           direction,
        !           330:        OHCIEndpointDescriptorPtr   *pEDBack);
        !           331: 
        !           332: OHCIEndpointDescriptorPtr FindControlEndpoint (
        !           333:        short                                           functionNumber, 
        !           334:        short                                           endpointNumber, 
        !           335:        OHCIEndpointDescriptorPtr   *pEDBack);
        !           336: 
        !           337: OHCIEndpointDescriptorPtr FindIsochronousEndpoint(
        !           338:        short                                           functionNumber, 
        !           339:        short                                           endpointNumber,
        !           340:        short                                           direction, 
        !           341:        OHCIEndpointDescriptorPtr       *pEDBack);
        !           342: 
        !           343: static OSStatus RemoveTDs (OHCIEndpointDescriptorPtr pED);
        !           344: 
        !           345: static OSStatus RemoveAllTDs (OHCIEndpointDescriptorPtr pED);
        !           346: 
        !           347: static UInt32 GetErrataBits (RegEntryIDPtr);
        !           348: 
        !           349: void doCallback(
        !           350:        OHCIGeneralTransferDescriptorPtr                        nextTD,
        !           351:        UInt32                  transferStatus,
        !           352:        UInt32                  bufferSizeRemaining);
        !           353: 
        !           354: OHCIEndpointDescriptorPtr AddEmptyEndPoint(
        !           355:        UInt8                                           functionAddress,
        !           356:        UInt8                                           endpointNumber,
        !           357:        UInt16                                          maxPacketSize,
        !           358:        UInt8                                           speed,
        !           359:        UInt8                                           direction,
        !           360:        OHCIEndpointDescriptorPtr       pED,
        !           361:        int                                                     isoch);
        !           362: 
        !           363: OHCIIsochTransferDescriptorPtr QueueITD (
        !           364:        OHCIIsochTransferDescriptorPtr  pITD, 
        !           365:        OHCIEndpointDescriptorPtr               pED);
        !           366: 
        !           367: void SwapIsoc(OHCIIsochTransferDescriptorPtr pITD);
        !           368: 
        !           369: UInt32 findBufferRemaining (OHCIGeneralTransferDescriptorPtr pCurrentTD);
        !           370: 
        !           371: void DoOptiFix(OHCIEndpointDescriptorPtr pIsochHead);
        !           372: 
        !           373: void trivialSwap( UInt32 *thing);
        !           374: 
        !           375: int GetEDType(
        !           376:        OHCIEndpointDescriptorPtr pED);
        !           377: 
        !           378: void ProcessCompletedITD (OHCIIsochTransferDescriptorPtr pITD);
        !           379: 
        !           380: OSStatus OptiLSHSFix();
        !           381: 
        !           382: Boolean AmIThisMachine(Str255 inMachineNameStr);
        !           383: 
        !           384: OSStatus OHCIResetRootHub(uslBusRef bus);
        !           385: OSStatus OHCIRootHubPortEnable( uslBusRef bus, short port, Boolean on);
        !           386: 
        !           387: void Get_Config_Info(void);
        !           388: void enable_intr();
        !           389: void ReadConfigVal(UInt32 ctl, UInt32 *val);
        !           390: void WriteConfigVal(UInt32 ctl, UInt32 val);
        !           391: 
        !           392: typedef struct{
        !           393:         UInt8 len;
        !           394:         UInt8 type;
        !           395:         UInt16 totalLen;
        !           396:         char rest_data[34];   /* = totalLen for mouse  naga needs change later */
        !           397:         } configHeader;     
        !           398: //configHeader usbConfDesc;
        !           399: 
        !           400: char usb_data_buffer[8];    /* General purpose buffer */
        !           401: int usb_task_level = kKernelLevel;
        !           402: 
        !           403: void usb_iodone_wakeup(long lParam, OSStatus status, short s16Param);
        !           404: int usb_iodone = 1;
        !           405: char ports_connected[2] = {0,0};
        !           406: usbControlBits usbConfig;       /* 8 bytes */
        !           407: USBDeviceDescriptor  usbDesc;   /* 18 bytes */
        !           408: struct usbConfDesc
        !           409: {
        !           410:      USBConfigurationDescriptor   header;
        !           411:      USBInterfaceDescriptor       interface;
        !           412:      USBEndPointDescriptor       endpoint;
        !           413:      char   rest_data[29];         
        !           414: }  usbConfDesc;
        !           415: void usb_donone(char *x,...)
        !           416: {
        !           417: }
        !           418: void fill_usbDesc()
        !           419: {
        !           420: int i;
        !           421: for(i=0;i<18;++i)
        !           422: {
        !           423:     char *x = (char *)&usbDesc;
        !           424:     *x++ = 0xbc;
        !           425: }
        !           426: }    
        !           427: void print_usbDesc(char *usbDesc,int size)
        !           428: {
        !           429: int i;
        !           430: 
        !           431: for(i=1;i<=size;++i)
        !           432: {
        !           433:     kprintf("0x%02x ",(int) *usbDesc++);
        !           434:         if(i%10 == 0)kprintf("\n");
        !           435: }
        !           436: kprintf("\n");
        !           437: }
        !           438: 
        !           439: void print_td(OHCIGeneralTransferDescriptorPtr x)
        !           440: {
        !           441:    // kprintf("TD(0x%08x):w0=0x%08x,w1(cbp)=0x%08x,w2=0x%08x,w3=0x%08x\n",x,EndianSwap32Bit(x->dWord0),EndianSwap32Bit(x->dWord1),EndianSwap32Bit(x->dWord2),EndianSwap32Bit(x->dWord3));
        !           442: }
        !           443: 
        !           444: void print_ed(OHCIEndpointDescriptorPtr x)
        !           445: {
        !           446:     //kprintf("ED(0x%08x):w0=0x%08x,w1(cbp)=0x%08x,w2=0x%08x,w3=0x%08x\n",x,EndianSwap32Bit(x->dWord0),EndianSwap32Bit(x->dWord1),EndianSwap32Bit(x->dWord2),EndianSwap32Bit(x->dWord3));
        !           447: }
        !           448:  
        !           449: void usbAddBus()
        !           450: {
        !           451:  extern struct UIMPluginDispatchTable ThePluginDispatchTable;
        !           452:   USBAddBus(0,&ThePluginDispatchTable,1);
        !           453: }
        !           454: UInt16 EndianSwap16Bit(UInt16 x)
        !           455: {
        !           456:    UInt16 byte1,byte2;
        !           457:    byte1 = x & 0xFF;
        !           458:    byte2 = (x>>8) & 0xFF;
        !           459:    return (byte1<<8) | byte2;
        !           460: }
        !           461: UInt32 EndianSwap32Bit(UInt32 x)
        !           462: {
        !           463:    UInt32 byte1,byte2,byte3,byte4;
        !           464:    UInt32 result;
        !           465: 
        !           466:    byte1 = x & 0xFF;
        !           467:    byte2 = (x>>8) & 0xFF;
        !           468:    byte3 = (x>>16) & 0xFF;
        !           469:    byte4 = (x>>24) & 0xFF;
        !           470:    result =  (byte1<<24) | (byte2<<16) | (byte3<<8) | byte4;
        !           471:    return result;
        !           472: }
        !           473: void dump_regs(volatile UInt32 *x)
        !           474: {
        !           475: int i;
        !           476:       printf("Regs:\n");
        !           477:  for(i=0;i<23;++i)
        !           478: {
        !           479:       printf("offset %2x: 0x%x\n",4*i,EndianSwap32Bit(*x++));
        !           480: IOSync();
        !           481: }
        !           482: printf("End Regs\n");
        !           483: }
        !           484: 
        !           485: OSStatus CheckpointIO(IOPreparationID theIOPreparation, IOCheckpointOptions    options)
        !           486: {
        !           487:    return 0;
        !           488: }
        !           489: OSStatus DelayForHardware (AbsoluteTime                   absoluteTime) 
        !           490: {
        !           491:      int x = (int)((AbsoluteTime)1000*absoluteTime);
        !           492: //     delay((int)((AbsoluteTime)1000*absoluteTime));
        !           493: kprintf("***Delaying for %d microseconds***\n",x);
        !           494:      delay(x);
        !           495:    return 0;
        !           496: }
        !           497: AbsoluteTime DurationToAbsolute(Duration duration)   
        !           498: {
        !           499:    AbsoluteTime x = (AbsoluteTime)duration;    //naga
        !           500:     return x;
        !           501: }
        !           502: 
        !           503: AbsoluteTime UpTime(void)
        !           504: {
        !           505:        static long r=67;
        !           506:        AbsoluteTime x ;
        !           507:        r=  (r+12061999)%1389;  //Random number  better replace by std random fn
        !           508:        x = (AbsoluteTime)r;
        !           509:        return x;
        !           510: }
        !           511: 
        !           512: ExecutionLevel CurrentExecutionLevel()
        !           513: {
        !           514:     return  usb_task_level;
        !           515: }
        !           516: 
        !           517: LogicalAddress PoolAllocateResident(ByteCount byteSize, Boolean flag)
        !           518: {
        !           519:      return (LogicalAddress)kalloc(byteSize);
        !           520: }
        !           521: OSStatus PoolDeallocate(LogicalAddress address)
        !           522: {
        !           523: //naga    kfree(address,size??);
        !           524:        return 0;
        !           525: }
        !           526: 
        !           527: OSStatus QueueSecondaryInterruptHandler(SecondaryInterruptHandler2  theHandler, ExceptionHandler      exceptionHandler, void *p1,     void *p2)
        !           528: {
        !           529:    (*theHandler)(p1,p2);
        !           530:    return 0;
        !           531: }
        !           532: 
        !           533: OSStatus CallSecondaryInterruptHandler2(SecondaryInterruptHandler2  theHandler, ExceptionHandler exceptionHandler, void *p1, void *p2)
        !           534: {
        !           535:      (*theHandler)(p1,p2);
        !           536:      return 0;
        !           537: }
        !           538: 
        !           539: 
        !           540: 
        !           541: void BlockCopy(const void *src, void *tgt, Size len)
        !           542: {
        !           543:      bcopy(src,tgt,len);
        !           544: }
        !           545: void usb_BlockMoveData(void *src, void *tgt, UInt32 len)
        !           546: {
        !           547:      bcopy(src,tgt,len);
        !           548: }
        !           549: OSStatus CompareAndSwap(UInt32 old, UInt32 new, UInt32 *adr)
        !           550: {
        !           551:      simple_lock(usb_slock);
        !           552:      if(*adr ==  old)
        !           553:      {
        !           554:           *adr = new;
        !           555:           simple_unlock(usb_slock);
        !           556:           return true;
        !           557:      }
        !           558:      simple_unlock(usb_slock);
        !           559:      return false;
        !           560: }
        !           561: 
        !           562: UInt16 Disable68kInterrupts(void)
        !           563: {
        !           564: return 0;
        !           565: }
        !           566: void Restore68kInterrupts(UInt16 a)
        !           567: {
        !           568: }
        !           569: 
        !           570: /* See Page 276 of Writing drivers for PCI cards */
        !           571: SInt32 AddAtomic(SInt32 amount, SInt32 *value)
        !           572: {
        !           573:     simple_lock(usb_slock);
        !           574:     *value += amount;
        !           575:     simple_unlock(usb_slock);
        !           576:     return (*value);
        !           577: }
        !           578: 
        !           579: /* see pg. 271 */
        !           580: AbsoluteTime AddAbsoluteToAbsolute(AbsoluteTime a, AbsoluteTime b)
        !           581: {
        !           582:     AbsoluteTime c;
        !           583:       
        !           584:     simple_lock(usb_slock);
        !           585:     c = a+b;
        !           586:     simple_unlock(usb_slock);
        !           587:       return c;
        !           588: }
        !           589: void SysDebugStr(ConstStr255Param str)
        !           590: {
        !           591: kprintf("SysDebugStr: Not implemented yet\n");
        !           592: }
        !           593: 
        !           594: OSStatus CancelTimer (TimerID theTimer, AbsoluteTime *timeRemaining)
        !           595: {
        !           596: kprintf("***CancelTimer not yet implemented***\n");
        !           597: return 0;
        !           598: }
        !           599: /*
        !           600: OSStatus SetInterruptTimer (const AbsoluteTime *expirationTime, SecondaryInterruptHandler2  handler, void *p1, TimerID *theTimer)
        !           601: {
        !           602: kprintf("*** SetInterruptTimer not yet implemented***\n");
        !           603: IOSchduleFunc((IOThreadFunc)handler, p1,1)
        !           604: return 0;
        !           605: }
        !           606:  */
        !           607: OSStatus PrepareMemoryForIO(IOPreparationTable                      *ioPrep)
        !           608: {
        !           609:    return 0;
        !           610: }
        !           611: 
        !           612: void BlockZero(void *ptr, int size)
        !           613: {
        !           614:       bzero(ptr,size);
        !           615: }
        !           616: OSStatus RegistryEntryIDDispose (RegEntryID  *foundEntry)
        !           617: {
        !           618:       kprintf("***RegistryEntryIDDispose:Not yet Implemented***\n");
        !           619: return noErr;
        !           620: }
        !           621:     
        !           622: OSStatus RegistryCStrEntryLookup(const RegEntryID *searchPointID, const RegCStrPathName *pathName, RegEntryID *foundEntry) 
        !           623: {
        !           624:       kprintf("***RegistryCStrEntryLookupisposePtr:Not yet Implemented***\n");
        !           625:       return noErr;
        !           626: }
        !           627:     
        !           628: Ptr usb_NewPtr(RegPropertyValueSize propertySize)      
        !           629: {
        !           630:      return (Ptr)kalloc(propertySize);
        !           631: }
        !           632: void usb_DisposePtr(Ptr modelNamePropertyStrPtr )
        !           633: {
        !           634:       kprintf("usb_DisposePtr:Not yet Implemented\n");
        !           635: }
        !           636: void c2pstr(Ptr modelNamePropertyStrPtr )
        !           637: {
        !           638: kprintf("c2pstr:Not yet Implemented\n");
        !           639: }
        !           640: OSStatus CompareString(Str255 inMachineNameStr, Str255 MacMachineName, char *ignore_null)
        !           641: {
        !           642:      return strcmp((char *)inMachineNameStr, (char *) MacMachineName);
        !           643: }
        !           644: OSStatus RegistryPropertyGetSize(const RegEntryID *entryID, const RegPropertyName *propertyName, RegPropertyValueSize *propertySize)
        !           645: {
        !           646:     kprintf("RegistryPropertyGetSize not implemented\n");
        !           647:     return 0;
        !           648: }
        !           649: void USBDemoKeyIn(UInt32 refcon, void *theData)
        !           650: {
        !           651:       kprintf("USBDemoKeyIn:Not yet Implemented\n");
        !           652: }
        !           653: 
        !           654: 
        !           655: UInt64 usb_U64Add(UInt64 a, UInt64 b)
        !           656: {
        !           657:     return a+b;
        !           658: }
        !           659: 
        !           660: UInt64 U64SetU(UInt32 a)
        !           661: {
        !           662:     return (UInt64) a;
        !           663: }
        !           664: UInt32 U32SetU(UInt64 a)
        !           665: {
        !           666:     return (UInt32) a;
        !           667: }
        !           668: 
        !           669: /* Barry - Silly routine to stop unused paramter warnings */
        !           670: 
        !           671: static void parameterNotUsed(UInt32 notUsed)
        !           672: {
        !           673:        notUsed = 0;
        !           674: }
        !           675: void usb_iodone_wakeup(long lParam, OSStatus status, short s16Param)
        !           676: {   
        !           677:         usb_iodone = 1; 
        !           678: }    
        !           679: void wait_usbio()
        !           680: {
        !           681: #if 0
        !           682:      while(usb_iodone == 0)
        !           683:      {
        !           684:           timeout((timeout_fcn_t)wakeup,&usb_iodone,(100*HZ+999)/1000);
        !           685:           sleep((char *)&usb_iodone,PZERO);
        !           686:      }
        !           687: #endif
        !           688: }   
        !           689: 
        !           690: 
        !           691: ////////////////////////////////////////////////////////////////////////////////
        !           692: ////////////////////////////////////////////////////////////////////////////////
        !           693: //
        !           694: // UIM interface routines.
        !           695: //
        !           696: ////////////////////////////////////////////////////////////////////////////////
        !           697: ////////////////////////////////////////////////////////////////////////////////
        !           698: 
        !           699: /* This is here so the UIM knows what its address is and can shunt those off to the sim */
        !           700: Boolean OHCISetOurAddress(uslBusRef bus, UInt16 addr)
        !           701: {
        !           702:        pOHCIUIMData->rootHubFuncAddress = addr;
        !           703:        bus = 0; // not used 
        !           704:        return(false);
        !           705: }
        !           706: 
        !           707: 
        !           708: ////////////////////////////////////////////////////////////////////////////////
        !           709: //
        !           710: // OHCIUIMInitialize
        !           711: //
        !           712: //   This is the UIM initialization procedure.
        !           713: //
        !           714: 
        !           715: 
        !           716: int OHCIUIMInitialize(unsigned long ioBase)
        !           717: {
        !           718:        RegEntryIDPtr                           pUIMRegEntryID;
        !           719:        OHCIRegistersPtr                        pOHCIRegisters;
        !           720:        UInt32                                          hccaAlignment;
        !           721:        Ptr                                                     pHCCAAllocation;
        !           722:        UInt32                                          hcFmInterval;
        !           723:        OSStatus                                        status = noErr;
        !           724: 
        !           725:         pOHCIUIMData = (OHCIUIMDataPtr)kalloc (sizeof (OHCIUIMData));
        !           726:        if (pOHCIUIMData == NULL)
        !           727:               return 1;
        !           728:         BlockZero(pOHCIUIMData,sizeof(OHCIUIMData));
        !           729:        pOHCIUIMData->errataBits = GetErrataBits(pUIMRegEntryID);
        !           730:        pOHCIUIMData->pageSize = PAGE_SIZE;
        !           731: 
        !           732:        //Allocate TDs, EDs;need to find out real numbers to use, CPU specific.
        !           733:        OHCIUIMAllocateMemory(1500,1500, 1300);
        !           734:        //OHCIUIMAllocateMemory(40,40, 100);
        !           735:         pOHCIUIMData->pOHCIRegisters = pOHCIRegisters = ioBase; //Should be 3519000 on PowerSurge
        !           736: dump_regs((volatile UInt32 *)ioBase);
        !           737:        // is this a goofy CMD chip that is using UHCI-style test mode?  If so, make it behave like an OHCI controller.
        !           738: kprintf("errata bits=0x%x,mask=0x%x\n",pOHCIUIMData->errataBits,kErrataCMDDisableTestMode);
        !           739:        if (pOHCIUIMData->errataBits & kErrataCMDDisableTestMode)
        !           740:        {
        !           741:                UInt32 registerVal;
        !           742: kprintf("fixing errata bits for cmd\n");
        !           743:                // see CMD 670 documentation, appendix A for rev KAB-4 parts
        !           744:                 ReadConfigVal(0x4C,&registerVal);
        !           745:                     //[deviceDescription configReadLong:0x4C value:&registerVal];
        !           746:                registerVal &= ~2;
        !           747:                    // [deviceDescription configWriteLong:0x4C value:registerVal];
        !           748:                 WriteConfigVal(0x4C,registerVal);
        !           749:        }
        !           750:         WriteConfigVal(cwCommand,(cwCommandEnableBusMaster | cwCommandEnableMemorySpace));
        !           751:              //[deviceDescription configWriteLong:cwCommand value:(cwCommandEnableBusMaster | cwCommandEnableMemorySpace)]; 
        !           752:        pOHCIRegisters->hcControlCurrentED = pOHCIRegisters->hcControlHeadED = pOHCIRegisters->hcDoneHead = 0;
        !           753:         IOSync();
        !           754:        // Set up HCCA.
        !           755:        if (status == noErr)
        !           756:        {
        !           757:                // Compute alignment of HCCA. zzz do for real 
        !           758:                hccaAlignment = 256;
        !           759: kprintf("settingup HCCA\n");
        !           760:                // Allocate HCCA.  
        !           761:                pHCCAAllocation = kalloc (2 * hccaAlignment);
        !           762:                if (pHCCAAllocation != nil)
        !           763:                {
        !           764:                        //Needs to be the physical Address
        !           765:                        pOHCIUIMData->pHCCAAllocation = pHCCAAllocation;
        !           766:                        pOHCIUIMData->pHCCA = (Ptr) (((UInt32) pHCCAAllocation + hccaAlignment) & ~(hccaAlignment - 1));
        !           767:                         pOHCIRegisters->hcHCCA =  EndianSwap32Bit((UInt32)kvtophys((vm_offset_t) pOHCIUIMData->pHCCA));
        !           768:                         IOSync();
        !           769: kprintf("pHCCAAllocation=0x%x,aligned logical=0x%x,phy=0x%x\n",pHCCAAllocation,pOHCIUIMData->pHCCA,pOHCIRegisters->hcHCCA);
        !           770:                        /* Set the HC to write the donehead to the HCCA, and enable interrupts */
        !           771:                        pOHCIRegisters->hcInterruptStatus = EndianSwap32Bit(kOHCIHcInterrupt_WDH);
        !           772:                         IOSync();
        !           773: 
        !           774:                }
        !           775:                else
        !           776:                {
        !           777: kprintf("kalloc failed!!\n");
        !           778:                        status = 1;  // memory full
        !           779:                }
        !           780: 
        !           781:        }
        !           782: 
        !           783:        // Initialize the Root Hub registers
        !           784:        if (status == noErr)
        !           785:        {
        !           786:                pOHCIRegisters->hcRhStatus = EndianSwap32Bit (/*kOHCIHcRhStatus_LPSC |*/kOHCIHcRhStatus_OCIC | kOHCIHcRhStatus_CRWE);
        !           787:                 OHCIResetRootHub(0);
        !           788:                 IOSync();
        !           789:        }
        !           790:                
        !           791:        // set up Interrupt transfer tree
        !           792:        if (status == noErr)
        !           793:        {
        !           794:                status = OHCIUIMIsochronousInitialize();
        !           795:                status = OHCIUIMInterruptInitialize();
        !           796:                status = OHCIUIMBulkInitialize();
        !           797:                status = OHCIUIMControlInitialize();
        !           798:                pOHCIUIMData->rootHubFuncAddress = 0;
        !           799:        } 
        !           800:                
        !           801: kprintf("over interrupt transfer tree,status=%d\n",status);
        !           802:        // Set up hcFmInterval.
        !           803:        //zzz what would be a good number for FSMPS?
        !           804:        if (status == noErr)
        !           805:        {
        !           806:                UInt32  hcFSMPS;
        !           807:                hcFmInterval = 11999;
        !           808: //             hcFSMPS = (((hcFmInterval & kOHCIHcFmInterval_FI)-kOHCIMax_OverHead) * 6)/7;
        !           809:                hcFSMPS = 10100;        // Barry fix undefineds.
        !           810:                hcFmInterval = (hcFmInterval & ~kOHCIHcFmInterval_FSMPS) |
        !           811:                                           (hcFSMPS << kOHCIHcFmInterval_FSMPSPhase);
        !           812:                pOHCIRegisters->hcFmInterval = EndianSwap32Bit (hcFmInterval);
        !           813:         IOSync();
        !           814:        }
        !           815: 
        !           816:        // Set up OHCI periodic start to determine time to start processing periodic values, 
        !           817:        // use hcfminterval and get 90% of that,  can use simple integer math, since frame interval
        !           818:        // is no more than 14 bits.
        !           819:        hcFmInterval = EndianSwap32Bit (pOHCIRegisters->hcFmInterval);
        !           820:         IOSync();
        !           821:        hcFmInterval &= kOHCIHcFmInterval_FIPhase;
        !           822:        pOHCIRegisters->hcPeriodicStart = EndianSwap32Bit (10800);
        !           823:         IOSync();
        !           824: //     pOHCIRegisters->hcPeriodicStart = EndianSwap32Bit (( hcFmInterval*9)/10);
        !           825:        
        !           826:        // Set OHCI to operational state and enable processing of control list.
        !           827:        if (status == noErr)
        !           828:        {
        !           829: kprintf("Setting up usb operational\n");
        !           830:                pOHCIRegisters->hcControl = EndianSwapImm32Bit ((kOHCIFunctionalState_Operational << kOHCIHcControl_HCFSPhase) |
        !           831:                                 kOHCIHcControl_CLE | kOHCIHcControl_BLE | kOHCIHcControl_PLE | kOHCIHcControl_IE);
        !           832:                  IOSync();
        !           833:        }
        !           834: 
        !           835:        if (status == noErr)
        !           836:        {
        !           837: kprintf("enabling interrupts\n");
        !           838:                pOHCIRegisters->hcInterruptEnable = EndianSwap32Bit (kOHCIHcInterrupt_MIE | kOHCIDefaultInterrupts);
        !           839:         IOSync();
        !           840: kprintf("After Enabling regs=:\n");
        !           841: dump_regs((volatile UInt32 *)ioBase);
        !           842: enable_intr();
        !           843:        //naga  (*pOHCIUIMData->interruptEnabler)(pOHCIUIMData->interruptSetMember, nil);
        !           844:        }
        !           845:        
        !           846:        if (pOHCIUIMData->errataBits & kErrataLSHSOpti)
        !           847:                status = OptiLSHSFix();
        !           848: 
        !           849:        // Clean up on error.
        !           850:        if (status != noErr)
        !           851:        {
        !           852: kprintf("OHCIUIMFinalize called!!!!\n");
        !           853:                if (pOHCIUIMData != nil)
        !           854:                        OHCIUIMFinalizeOHCIUIMData (pOHCIUIMData);
        !           855:        }
        !           856: //naga
        !           857: usb_slock = simple_lock_alloc();
        !           858: simple_lock_init(usb_slock);
        !           859:        return (status);
        !           860: }
        !           861: 
        !           862: ////////////////////////////////////////////////////////////////////////////////
        !           863: //
        !           864: // OHCIUIMFinalize
        !           865: //
        !           866: //   This is the UIM finalization procedure.
        !           867: //
        !           868: 
        !           869: 
        !           870: OSStatus       OHCIUIMFinalize(
        !           871:        Boolean                                         beingReplaced,
        !           872:        Ptr *                                           savedStatePtr)
        !           873: {
        !           874:        OHCIRegistersPtr                        pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
        !           875:        OSStatus                                        status = noErr;
        !           876: 
        !           877: 
        !           878:        if (!beingReplaced) {
        !           879:                ProgressDebugStr ((ConstStr255Param) "OHCIUIMFinalize (shutting down HW)");
        !           880: 
        !           881:                // Disable All OHCI Interrupts
        !           882:                (*pOHCIUIMData->interruptDisabler)(pOHCIUIMData->interruptSetMember, nil);
        !           883:                pOHCIRegisters->hcInterruptDisable = kOHCIHcInterrupt_MIE;
        !           884: /*naga
        !           885:                // restore interrupt set
        !           886:                status = InstallInterruptFunctions
        !           887:                                        (pOHCIUIMData->interruptSetMember.setID, pOHCIUIMData->interruptSetMember.member,
        !           888:                                         pOHCIUIMData->oldInterruptRefCon, pOHCIUIMData->oldInterruptHandler,
        !           889:                                         pOHCIUIMData->interruptEnabler, pOHCIUIMData->interruptDisabler);
        !           890: */
        !           891:                
        !           892:                // Place the USB bus into the Reset State
        !           893:                pOHCIRegisters->hcControl = EndianSwapImm32Bit ((kOHCIFunctionalState_Reset << kOHCIHcControl_HCFSPhase));
        !           894:                
        !           895:                // Take away the controllers ability be a bus master.
        !           896: //naga         status = ExpMgrConfigWriteWord(&pOHCIUIMData->ohciRegEntryID,(LogicalAddress) cwCommand, cwCommandEnableMemorySpace);  // turn off busmastering,
        !           897: WriteConfigVal(cwCommand,cwCommandEnableMemorySpace);
        !           898:                // Clear all Processing Registers
        !           899:                pOHCIRegisters->hcHCCA = nil;
        !           900:                pOHCIRegisters->hcPeriodCurrentED = nil;
        !           901:                pOHCIRegisters->hcControlHeadED = nil;
        !           902:                pOHCIRegisters->hcControlCurrentED = nil;
        !           903:                pOHCIRegisters->hcBulkHeadED = nil;
        !           904:                pOHCIRegisters->hcBulkCurrentED = nil;
        !           905:                pOHCIRegisters->hcDoneHead = nil;
        !           906:                
        !           907:                OHCIRootHubPower( 0, 0);        // turn off the global power zzzzz - check for per-port vs. Global power control
        !           908:                
        !           909:                status = OHCIUIMFinalizeOHCIUIMData ((OHCIUIMDataPtr) pOHCIUIMData);
        !           910:        } else {
        !           911:                ProgressDebugStr ((ConstStr255Param) "OHCIUIMFinalize (being replaced)");
        !           912:                pOHCIRegisters->hcInterruptDisable = kOHCIHcInterrupt_MIE;
        !           913: /*naga
        !           914:                // restore interrupt set
        !           915:                status = InstallInterruptFunctions
        !           916:                                        (pOHCIUIMData->interruptSetMember.setID, pOHCIUIMData->interruptSetMember.member,
        !           917:                                         pOHCIUIMData->oldInterruptRefCon, pOHCIUIMData->oldInterruptHandler,
        !           918:                                         pOHCIUIMData->interruptEnabler, pOHCIUIMData->interruptDisabler);
        !           919: */
        !           920:                *savedStatePtr = (Ptr) pOHCIUIMData;
        !           921:        }
        !           922: 
        !           923:        ProgressDebugStr ((ConstStr255Param) "OHCIUIMFinalize Exit");
        !           924: 
        !           925: 
        !           926:        return (status);
        !           927: }
        !           928: static OSStatus OHCIUIMFinalizeOHCIUIMData(
        !           929:        OHCIUIMDataPtr                          pOHCIUIMData)
        !           930: {
        !           931:        OSStatus                                        status = noErr;
        !           932:        ProgressDebugStr ((ConstStr255Param) "OHCIUIMfinalize");
        !           933: 
        !           934:        if (pOHCIUIMData != nil)
        !           935:        {
        !           936:                // Deallocate HCCA.
        !           937:                if (pOHCIUIMData->pHCCAAllocation != nil){
        !           938:                        PoolDeallocate (pOHCIUIMData->pHCCAAllocation);
        !           939:                        pOHCIUIMData->pHCCAAllocation = nil;
        !           940:                }
        !           941:                //nagaif (pOHCIUIMData->pDataAllocation)
        !           942:                //naga  MemDeallocatePhysicallyContiguous(pOHCIUIMData->pDataAllocation);
        !           943:                
        !           944:                if (pOHCIUIMData->pPhysicalLogical)
        !           945:                        PoolDeallocate (pOHCIUIMData->pPhysicalLogical);
        !           946:                
        !           947:                // Deallocate UIM data record.
        !           948:                PoolDeallocate ((Ptr) pOHCIUIMData);
        !           949:                pOHCIUIMData = nil;
        !           950:        }
        !           951: 
        !           952:        return (status);
        !           953: }
        !           954: 
        !           955: // Barry set frame interrupt on. This will be disabled by the service routine, so this is one shot
        !           956: 
        !           957: void OHCISetFrameInterrupt(void)
        !           958: {
        !           959: #if 0
        !           960: OHCIRegistersPtr                       pOHCIRegisters;
        !           961:        pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
        !           962:        pOHCIRegisters->hcInterruptEnable = EndianSwap32Bit(kOHCIHcInterrupt_SF);
        !           963: #endif
        !           964: }
        !           965: 
        !           966: 
        !           967: 
        !           968: //     What needs to be done?
        !           969: //             Need to figure out an efficient way of keeping track of callbackroutines for when a transaction completes.
        !           970: //             what to do with control transaction which are really three transactions, must call callback only after 
        !           971: //             status transaction completes, but must also keep track of what happens to setup and bulk transactions.  
        !           972: //             hmmmmmmmmmm...its guaranteed that they will finish inorder, but if setup or bulk fails will the HC disable
        !           973: //             the endpoint until I clean up or will the it continue on til the next one.
        !           974: 
        !           975: 
        !           976: 
        !           977: OHCIEndpointDescriptorPtr AddEmptyEndPoint(
        !           978:        UInt8                                           functionAddress,
        !           979:        UInt8                                           endpointNumber,
        !           980:        UInt16                                          maxPacketSize,
        !           981:        UInt8                                           speed,
        !           982:        UInt8                                           direction,
        !           983:        OHCIEndpointDescriptorPtr       pED,
        !           984:        int                                                     isoch)
        !           985: 
        !           986: {
        !           987:        UInt32                                                          myFunctionAddress, myEndPointNumber,myEndPointDirection,myMaxPacketSize, mySpeed, myIsoch;
        !           988:        OHCIEndpointDescriptorPtr                       pOHCIEndpointDescriptor;
        !           989:        OHCIGeneralTransferDescriptorPtr        pOHCIGeneralTransferDescriptor;
        !           990:        OHCIIsochTransferDescriptorPtr          pITD;
        !           991:        
        !           992:        pOHCIEndpointDescriptor = (OHCIEndpointDescriptorPtr) OHCIUIMAllocateED();
        !           993:        myFunctionAddress = ((UInt32) functionAddress) << kOHCIEDControl_FAPhase;
        !           994:        myEndPointNumber = ((UInt32) endpointNumber) << kOHCIEDControl_ENPhase;
        !           995:        
        !           996:        myEndPointDirection = ((UInt32) direction) << kOHCIEDControl_DPhase;
        !           997:        
        !           998:        mySpeed = ((UInt32) speed) << kOHCIEDControl_SPhase;
        !           999: 
        !          1000:        myMaxPacketSize = ((UInt32) maxPacketSize) << kOHCIEDControl_MPSPhase;
        !          1001:        
        !          1002:        myIsoch = ((UInt32) isoch) << kOHCIEDControl_FPhase;
        !          1003:        pOHCIEndpointDescriptor->dWord0 = EndianSwap32Bit(myFunctionAddress | myEndPointNumber 
        !          1004:                                                                                | myEndPointDirection | myMaxPacketSize |mySpeed | myIsoch);
        !          1005:        if (isoch == kOHCIEDFormatGeneralTD) {
        !          1006:                pOHCIGeneralTransferDescriptor = OHCIUIMAllocateTD();
        !          1007: 
        !          1008:                /* These were previously nil */
        !          1009:                pOHCIEndpointDescriptor->dWord1 = EndianSwap32Bit( (UInt32) pOHCIGeneralTransferDescriptor->pPhysical);
        !          1010:                pOHCIEndpointDescriptor->dWord2 = EndianSwap32Bit( (UInt32) pOHCIGeneralTransferDescriptor->pPhysical);
        !          1011:                pOHCIEndpointDescriptor->pVirtualTailP = (UInt32) pOHCIGeneralTransferDescriptor;
        !          1012:                pOHCIEndpointDescriptor->pVirtualHeadP = (UInt32) pOHCIGeneralTransferDescriptor;
        !          1013: 
        !          1014:        } else {
        !          1015:                pITD = OHCIUIMAllocateITD();
        !          1016:                
        !          1017:                /* These were previously nil */
        !          1018:                pOHCIEndpointDescriptor->dWord1 = EndianSwap32Bit( (UInt32) pITD->pPhysical);
        !          1019:                pOHCIEndpointDescriptor->dWord2 = EndianSwap32Bit( (UInt32) pITD->pPhysical);
        !          1020:                pOHCIEndpointDescriptor->pVirtualTailP = (UInt32) pITD;
        !          1021:                pOHCIEndpointDescriptor->pVirtualHeadP = (UInt32) pITD;         
        !          1022:        
        !          1023:        }
        !          1024: 
        !          1025:        pOHCIEndpointDescriptor->dWord3 =  pED->dWord3;
        !          1026:        pOHCIEndpointDescriptor->pVirtualNext = pED->pVirtualNext;
        !          1027:        pED->pVirtualNext = (UInt32) pOHCIEndpointDescriptor;
        !          1028:        pED->dWord3 = EndianSwap32Bit (pOHCIEndpointDescriptor->pPhysical);
        !          1029: 
        !          1030: 
        !          1031:        return (pOHCIEndpointDescriptor);
        !          1032: 
        !          1033: }
        !          1034: 
        !          1035: OSStatus OHCIUIMControlEDCreate(
        !          1036:        UInt8                                           functionAddress,
        !          1037:        UInt8                                           endpointNumber,
        !          1038:        UInt16                                          maxPacketSize,
        !          1039:        UInt8                                           speed)
        !          1040: {
        !          1041:        OHCIEndpointDescriptorPtr       pOHCIEndpointDescriptor, pED;
        !          1042:        OSStatus                                        status = noErr;
        !          1043:        
        !          1044: #if 0
        !          1045:                /* BT - Let the set address command do this */
        !          1046:        if ((pOHCIUIMData->rootHubFuncAddress == 0) && (functionAddress == 0))
        !          1047:        {
        !          1048:                return(status);
        !          1049:        }
        !          1050:        if (pOHCIUIMData->rootHubFuncAddress == 0){ 
        !          1051:                pOHCIUIMData->rootHubFuncAddress = functionAddress;
        !          1052:                return(status);
        !          1053:        }
        !          1054: #endif
        !          1055: 
        !          1056: kprintf("OHCIUIMControlEDCreate: fn=%d,ep=%d\n",functionAddress,endpointNumber);
        !          1057:        if (pOHCIUIMData->rootHubFuncAddress == functionAddress) 
        !          1058:                return (status);
        !          1059:                
        !          1060:        pED = (OHCIEndpointDescriptorPtr) pOHCIUIMData->pControlHead;
        !          1061:        if ((speed == kOHCIEDSpeedFull) && pOHCIUIMData->OptiOn)
        !          1062:                pED = (OHCIEndpointDescriptorPtr) pOHCIUIMData->pBulkHead;
        !          1063: 
        !          1064:        pOHCIEndpointDescriptor = AddEmptyEndPoint (
        !          1065:                                        functionAddress, endpointNumber, maxPacketSize, speed, kOHCIEDDirectionTD, pED, kOHCIEDFormatGeneralTD);
        !          1066: 
        !          1067:        if (pOHCIEndpointDescriptor == nil)
        !          1068:                return(-1);
        !          1069:        return (status);
        !          1070: }
        !          1071: 
        !          1072: 
        !          1073: 
        !          1074: OSStatus OHCIUIMControlTransfer(
        !          1075:        UInt32                                          refcon,
        !          1076:        CallBackFuncPtr                         handler,
        !          1077:        UInt32                                          CBP,
        !          1078:        Boolean                                         bufferRounding,
        !          1079:        short                                           functionNumber,
        !          1080:        short                                           endpointNumber,
        !          1081:        short                                           bufferSize,
        !          1082:        short                                           direction)
        !          1083: {
        !          1084:        OHCIRegistersPtr                        pOHCIRegisters;
        !          1085:        OHCIGeneralTransferDescriptorPtr
        !          1086:                                                                pOHCIGeneralTransferDescriptor,
        !          1087:                                                                newOHCIGeneralTransferDescriptor;
        !          1088:        OSStatus                                        status = noErr;
        !          1089:        UInt32                                          myBufferRounding;
        !          1090:        UInt32                                          myDirection;
        !          1091:        UInt32                                          myToggle;
        !          1092:        UInt32                                          CBPPhysical;
        !          1093: 
        !          1094:        OHCIEndpointDescriptorPtr       pEDQueue, pEDDummy;
        !          1095: 
        !          1096: 
        !          1097:        
        !          1098:        if (pOHCIUIMData->rootHubFuncAddress == functionNumber) 
        !          1099:        {
        !          1100: //kprintf("OHCIUIMControlTransfer:Calling UIMSimulateRootHubStages\n");
        !          1101:                return(UIMSimulateRootHubStages(refcon, handler, CBP, bufferRounding, 
        !          1102:                                                endpointNumber, bufferSize, direction));
        !          1103:        }
        !          1104: //kprintf("Cntl Tx:roothubfuncaddr=0x%x,fnumb=0x%x;calling FindControlEndpoint\n",pOHCIUIMData->rootHubFuncAddress , functionNumber);
        !          1105:        if (direction == kUSBOut)
        !          1106:                direction = kOHCIGTDPIDOut;
        !          1107:        else if (direction == kUSBIn) 
        !          1108:                direction = kOHCIGTDPIDIn;
        !          1109:        else
        !          1110:                direction = kOHCIGTDPIDSetup;
        !          1111: 
        !          1112: 
        !          1113:        pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
        !          1114:        //search for endpoint descriptor
        !          1115: 
        !          1116:        pEDQueue = FindControlEndpoint(functionNumber, endpointNumber, &pEDDummy);
        !          1117:        if (pEDQueue == nil){
        !          1118:                kprintf("OHCIUIMControlTransfer: Couldnot find endpoint\n");
        !          1119:                status = kUSBNotFound;
        !          1120:                return(status);
        !          1121:        }
        !          1122:        myBufferRounding = (UInt32) bufferRounding << kOHCIBufferRoundingOffset;
        !          1123:        myDirection = (UInt32) direction << kOHCIDirectionOffset;
        !          1124:        myToggle = kOHCIBit25;  /* Take data toggle from TD */
        !          1125:        if(direction !=0)
        !          1126:        {       /* Setup uses Data 0, data status use Data1 */
        !          1127:                myToggle |= kOHCIBit24; /* use Data1 */
        !          1128:        }
        !          1129: 
        !          1130:        // setup transfer descriptor
        !          1131:        newOHCIGeneralTransferDescriptor = OHCIUIMAllocateTD();
        !          1132:        if (newOHCIGeneralTransferDescriptor == nil)
        !          1133:         {
        !          1134:                 kprintf("Kalloc TD failed\n");
        !          1135:                return (-1);
        !          1136:         }
        !          1137: 
        !          1138:        /* Last in queue is a dummy descriptor. Fill it in then add new dummy */
        !          1139:        pOHCIGeneralTransferDescriptor =  (OHCIGeneralTransferDescriptorPtr) pEDQueue->pVirtualTailP;
        !          1140: pOHCIGeneralTransferDescriptor->pEndpoint = (UInt32) pEDQueue;    //naga added for our reference
        !          1141:        pOHCIGeneralTransferDescriptor->dWord0 = EndianSwap32Bit (myBufferRounding | myDirection | myToggle);
        !          1142: //kprintf("dword0=0x%x,round=0x%x,dir=0x%x,toggle=0x%x\n",EndianSwap32Bit (pOHCIGeneralTransferDescriptor->dWord0),myBufferRounding,myDirection,myToggle);
        !          1143:        pOHCIGeneralTransferDescriptor->dWord2 = EndianSwap32Bit ((UInt32)newOHCIGeneralTransferDescriptor->pPhysical);
        !          1144:        pOHCIGeneralTransferDescriptor->pVirtualNext = (UInt32)newOHCIGeneralTransferDescriptor;
        !          1145: 
        !          1146:        if (bufferSize != 0)
        !          1147:        {
        !          1148:                 CBPPhysical = kvtophys((vm_offset_t) CBP);
        !          1149:                pOHCIGeneralTransferDescriptor->dWord1 = EndianSwap32Bit (CBPPhysical);
        !          1150:                pOHCIGeneralTransferDescriptor->dWord3 = EndianSwap32Bit (CBPPhysical + bufferSize-1);
        !          1151:        }
        !          1152:        else
        !          1153:        {
        !          1154:                pOHCIGeneralTransferDescriptor->dWord1 = 0;
        !          1155:                pOHCIGeneralTransferDescriptor->dWord3 = 0;
        !          1156:        }
        !          1157:        pOHCIGeneralTransferDescriptor->CallBack = handler;
        !          1158:        pOHCIGeneralTransferDescriptor->refcon = refcon;
        !          1159: 
        !          1160:        /* Make new descriptor the tail */
        !          1161:        pEDQueue->dWord1 = pOHCIGeneralTransferDescriptor->dWord2;
        !          1162:        pEDQueue->pVirtualTailP = (UInt32) newOHCIGeneralTransferDescriptor;
        !          1163: 
        !          1164: print_ed(pEDQueue);
        !          1165: print_td(pOHCIGeneralTransferDescriptor);
        !          1166:        pOHCIRegisters->hcCommandStatus = EndianSwap32Bit (kOHCIHcCommandStatus_CLF);
        !          1167:         IOSync();
        !          1168:        return (status);
        !          1169: }
        !          1170: OSStatus OHCIUIMControlEDDelete(
        !          1171:        short                                           functionNumber,
        !          1172:        short                                           endpointNumber)
        !          1173: {
        !          1174:        OSStatus                                        status = noErr;
        !          1175:        
        !          1176:        if (pOHCIUIMData->rootHubFuncAddress == functionNumber) 
        !          1177:                return (status);
        !          1178: kprintf("OHCIUIMControlEDDelete: calling OHCIUIMEndpointDelete if fn=ep fn=%d,ep=%d\n",functionNumber,endpointNumber);
        !          1179:        status = OHCIUIMEndpointDelete(functionNumber, endpointNumber, 3);
        !          1180:        
        !          1181:        return (status);
        !          1182: }
        !          1183: 
        !          1184: OSStatus OHCIUIMBulkEDCreate(
        !          1185:        UInt8                                           functionAddress,
        !          1186:        UInt8                                           endpointNumber,
        !          1187:        UInt8                                           direction,
        !          1188:        UInt8                                           maxPacketSize)
        !          1189: {
        !          1190:        OHCIEndpointDescriptorPtr       pOHCIEndpointDescriptor, pED;
        !          1191:        OSStatus                                        status = noErr;
        !          1192:        if (direction == kUSBOut)
        !          1193:                direction = kOHCIEDDirectionOut;
        !          1194:        else if (direction == kUSBIn) 
        !          1195:                direction = kOHCIEDDirectionIn;
        !          1196:        else
        !          1197:                direction = kOHCIEDDirectionTD;
        !          1198: 
        !          1199:        pED = (OHCIEndpointDescriptorPtr) pOHCIUIMData->pBulkHead;
        !          1200:        pOHCIEndpointDescriptor = AddEmptyEndPoint (
        !          1201:                                        functionAddress, endpointNumber, maxPacketSize, kOHCIEDSpeedFull, direction, pED, kOHCIEDFormatGeneralTD);
        !          1202:        if (pOHCIEndpointDescriptor == nil)
        !          1203:                return(-1);
        !          1204:        return (status);
        !          1205:        
        !          1206: }
        !          1207: 
        !          1208: /* Naga  This function needs to be edited to replace prepareMemoryforio with kvtophys -- see OHCIUIMInterruptTransfer for cut/paste */
        !          1209: OSStatus OHCIUIMBulkTransfer(
        !          1210:        UInt32                                          refcon,
        !          1211:        CallBackFuncPtr                         handler,
        !          1212:        UInt32                                          CBP,
        !          1213:        Boolean                                         bufferRounding,
        !          1214:        short                                           functionNumber,
        !          1215:        short                                           endpointNumber,
        !          1216:        UInt32                                          bufferSize,
        !          1217:        short                                           direction)
        !          1218: {
        !          1219:        OHCIRegistersPtr                        pOHCIRegisters;
        !          1220:        OHCIGeneralTransferDescriptorPtr
        !          1221:                                                                pOHCIGeneralTransferDescriptor,
        !          1222:                                                                newOHCIGeneralTransferDescriptor;
        !          1223:        OSStatus                                        status = noErr;
        !          1224:        UInt32                                          myBufferRounding;
        !          1225:        UInt32                                          endPtDirection;
        !          1226:        UInt32                                          TDDirection;
        !          1227:        OHCIEndpointDescriptorPtr       pEDQueue, pEDDummy;
        !          1228:        IOPreparationTable                      *ioPrep;
        !          1229:        IOPreparationTable                      IOPrep;
        !          1230:        UInt32                                          physicalAddresses[kOHCIMaxPages];       
        !          1231:        UInt32                                          numPages, firstCount, lastCount;
        !          1232:        IOPreparationID                         preparationID;
        !          1233:        UInt32                                          pageSize, pageOffsetMask;
        !          1234:        int                                                     i;
        !          1235:        UInt32                                          alignment, pageOffset, pageMask, pageCount;
        !          1236: 
        !          1237: //     DebugStr("OHCIUIM: InSide Bulk TD setup");
        !          1238: 
        !          1239:        pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
        !          1240:        pageSize = pOHCIUIMData->pageSize;
        !          1241:        ioPrep = &IOPrep;
        !          1242:        
        !          1243:        if (direction == kUSBOut)
        !          1244:                direction = kOHCIEDDirectionOut;
        !          1245:        else if (direction == kUSBIn) 
        !          1246:                direction = kOHCIEDDirectionIn;
        !          1247:        else
        !          1248:                direction = kOHCIEDDirectionTD;
        !          1249: 
        !          1250:        //search for endpoint descriptor
        !          1251:        pEDQueue = FindBulkEndpoint (functionNumber, endpointNumber, direction, &pEDDummy);
        !          1252: 
        !          1253:        if (!pEDQueue){
        !          1254:                FailureDebugStr("UIMBulkTransfer: Couldnot find endpoint");
        !          1255:                status = kUSBNotFound;
        !          1256:                return (status);
        !          1257:        }
        !          1258: 
        !          1259: 
        !          1260:        pageOffsetMask = pageSize - 1;
        !          1261:        pageMask = ~pageOffsetMask;
        !          1262:        
        !          1263:        myBufferRounding = (UInt32) bufferRounding << kOHCIBufferRoundingOffset;
        !          1264:        endPtDirection = (UInt32) direction << kOHCIEndpointDirectionOffset;
        !          1265:        TDDirection = (UInt32) direction << kOHCIDirectionOffset;
        !          1266: 
        !          1267: // FERG DEBUG
        !          1268: // uncomment the next line to force the data to be put in TD list, but not be processed
        !          1269: // this is handy for using USBProber/Macsbug to look at TD's to see if they're OK.
        !          1270: //                     pEDQueue->dWord0 |= EndianSwap32Bit (kOHCIEDControl_K);
        !          1271: // FERG DEBUG
        !          1272:        alignment = CBP % ((EndianSwap32Bit (pEDQueue->dWord0)
        !          1273:                                                & kOHCIEDControl_MPS) >> kOHCIEDControl_MPSPhase);
        !          1274:        if(alignment != 0)  
        !          1275:        {
        !          1276: //     DebugStr("OHCIUIM: determining pageOffset");
        !          1277: 
        !          1278:                pageOffset = CBP & pageOffsetMask;
        !          1279:        }       
        !          1280:        if (bufferSize != 0)
        !          1281:        {
        !          1282:                while ((status == noErr) && (bufferSize > 0)) {
        !          1283:                
        !          1284:                        firstCount = pageSize - (CBP & pageOffsetMask);
        !          1285:                        if (bufferSize <= firstCount){
        !          1286:                                lastCount = 0;
        !          1287:                                numPages = 1;
        !          1288:                                firstCount = bufferSize;
        !          1289:                        } else {
        !          1290:                                lastCount = (CBP + bufferSize) & pageOffsetMask;
        !          1291:                                numPages = (bufferSize - firstCount - lastCount)/pageSize;
        !          1292:                                if (firstCount) numPages++;
        !          1293:                                if (lastCount) numPages++;
        !          1294:                        }
        !          1295:                        
        !          1296:                        // Prepare for IO and get physical address
        !          1297:                        ioPrep->options = kIOLogicalRanges | kIOIsInput | kIOIsOutput;
        !          1298:                        ioPrep->addressSpace = kCurrentAddressSpaceID;                  // default
        !          1299:                        ioPrep->granularity = 0;                                                                // do it all now
        !          1300:                        ioPrep->firstPrepared = 0;
        !          1301:                        ioPrep->mappingEntryCount = MIN (numPages, kOHCIMaxPages) ;                             // # of pages we will use
        !          1302:                        ioPrep->logicalMapping = 0;
        !          1303:                        ioPrep->physicalMapping = (PhysicalMappingTablePtr) physicalAddresses;  // return list of phys addrs
        !          1304:                        ioPrep->rangeInfo.range.base = (void *) CBP;
        !          1305:                        ioPrep->rangeInfo.range.length =  bufferSize;
        !          1306:                                        
        !          1307:                        status = PrepareMemoryForIO (ioPrep);
        !          1308:                        if (status == noErr){
        !          1309:                                preparationID = ioPrep->preparationID;
        !          1310:                                pageCount = ioPrep->mappingEntryCount;
        !          1311:                                if ((alignment != 0) && (ioPrep->mappingEntryCount == kOHCIMaxPages))
        !          1312:                                        pageCount--;
        !          1313:                                for (i = 0; i< pageCount; i++) {
        !          1314:                                        newOHCIGeneralTransferDescriptor = OHCIUIMAllocateTD();
        !          1315:                                        if (newOHCIGeneralTransferDescriptor == nil) {
        !          1316:                                                return (-1);
        !          1317:                                        }
        !          1318:                                        pOHCIGeneralTransferDescriptor = (OHCIGeneralTransferDescriptorPtr) pEDQueue->pVirtualTailP;
        !          1319:                                        pOHCIGeneralTransferDescriptor->dWord0 = EndianSwap32Bit (myBufferRounding | TDDirection);
        !          1320:                                        pOHCIGeneralTransferDescriptor->dWord2 = EndianSwap32Bit ((UInt32)newOHCIGeneralTransferDescriptor->pPhysical);
        !          1321:                                        pOHCIGeneralTransferDescriptor->pVirtualNext = (UInt32)newOHCIGeneralTransferDescriptor;
        !          1322:                                        pOHCIGeneralTransferDescriptor->dWord1 = EndianSwap32Bit (physicalAddresses[i]);
        !          1323:                                        pOHCIGeneralTransferDescriptor->pEndpoint = (UInt32) pEDQueue;
        !          1324:                                        // zzzzzz - really should check the direction to specify IN or OUT type.
        !          1325:                                        pOHCIGeneralTransferDescriptor->pType = (UInt32) kOHCIBulkTransferOutType;
        !          1326:                                        firstCount = pageSize - (CBP & pageOffsetMask);
        !          1327:                                        // if an IN and not aligned
        !          1328:                                        if(alignment != 0) {
        !          1329:        //              DebugStr("OHCIUIM: unaligned in buffer");
        !          1330:                                                pOHCIGeneralTransferDescriptor->dWord1 = EndianSwap32Bit (
        !          1331:                                                                                                        (physicalAddresses[i] & pageMask) + pageOffset);
        !          1332:                                                if ( bufferSize > pageSize) 
        !          1333:                                                        pOHCIGeneralTransferDescriptor->dWord3 = EndianSwap32Bit (
        !          1334:                                                                                                        physicalAddresses[i+1] + pageOffset -1);
        !          1335:                                                else if (bufferSize >= (pageSize - pageOffset))
        !          1336:                                                        pOHCIGeneralTransferDescriptor->dWord3 = EndianSwap32Bit (
        !          1337:                                                                                                        physicalAddresses[++i] + bufferSize - (pageSize - pageOffset) -1);
        !          1338:                                                else
        !          1339:                                                        pOHCIGeneralTransferDescriptor->dWord3 = EndianSwap32Bit ((physicalAddresses[i]& pageMask)
        !          1340:                                                                                                + bufferSize + pageOffset - 1);
        !          1341:                                                                        
        !          1342:                                                lastCount = MIN(pageSize, bufferSize);
        !          1343:                                                firstCount = 0;
        !          1344:                                        }else if ((firstCount >= bufferSize) 
        !          1345:                                                        || (i+1 == ioPrep->mappingEntryCount)           // this is really the last (non-full) block to be transferred
        !          1346:                                                        || pOHCIUIMData->errataBits & kErrataOnlySinglePageTransfers){  // only do a max of one page per transfer descriptor
        !          1347:                                                lastCount = 0;
        !          1348:                                                firstCount = MIN(firstCount, bufferSize);
        !          1349:                                                pOHCIGeneralTransferDescriptor->dWord3 = EndianSwap32Bit (physicalAddresses[i] + firstCount - 1);
        !          1350:                                        } else {
        !          1351:                                                i++;
        !          1352:                                                lastCount = MIN (bufferSize - firstCount, pageSize);
        !          1353:                                                pOHCIGeneralTransferDescriptor->dWord3 = EndianSwap32Bit (physicalAddresses[i] + lastCount - 1);
        !          1354:                                        }
        !          1355:                                        bufferSize -= (firstCount + lastCount);
        !          1356:                                        // only supply a callback when the entire buffer has been transfered.
        !          1357:                                        pOHCIGeneralTransferDescriptor->CallBack = (bufferSize <= 0) ? handler : nil;
        !          1358:                                        pOHCIGeneralTransferDescriptor->refcon = refcon;
        !          1359:                                        // supply a preparationID at the end of each prepared range
        !          1360:                                        // pOHCIGeneralTransferDescriptor->preparationID = (i+1 == ioPrep->mappingEntryCount) ? preparationID : nil;
        !          1361:                                        CBP += (firstCount + lastCount);
        !          1362:                                        pEDQueue->dWord1 = pOHCIGeneralTransferDescriptor->dWord2;
        !          1363:                                        pEDQueue->pVirtualTailP = (UInt32) newOHCIGeneralTransferDescriptor;
        !          1364:                                        pOHCIRegisters->hcCommandStatus = EndianSwap32Bit (kOHCIHcCommandStatus_BLF);
        !          1365:                                }
        !          1366:                                CheckpointIO(ioPrep->preparationID, nil);  // zzzz - Ferg - keep from overflowing the locked page count
        !          1367: 
        !          1368:                        } else {
        !          1369:                                AssertDebugStr("OHCIUIM: PrepareMemoryForIO failed!");
        !          1370:                        }
        !          1371:                }
        !          1372: 
        !          1373:        }
        !          1374:        else
        !          1375:        {
        !          1376:                newOHCIGeneralTransferDescriptor = OHCIUIMAllocateTD();
        !          1377:                /* last in queue is dummy descriptor. Fill it in then add new dummy */
        !          1378:                pOHCIGeneralTransferDescriptor =  (OHCIGeneralTransferDescriptorPtr) pEDQueue->pVirtualTailP;
        !          1379: 
        !          1380:                pOHCIGeneralTransferDescriptor->dWord0 = EndianSwap32Bit (myBufferRounding | TDDirection);
        !          1381:                pOHCIGeneralTransferDescriptor->dWord2 = EndianSwap32Bit ((UInt32)newOHCIGeneralTransferDescriptor->pPhysical);
        !          1382:                pOHCIGeneralTransferDescriptor->pVirtualNext = (UInt32)newOHCIGeneralTransferDescriptor;
        !          1383: 
        !          1384:                /*for zero sized buffers */
        !          1385:                pOHCIGeneralTransferDescriptor->dWord1 = 0;
        !          1386:                pOHCIGeneralTransferDescriptor->dWord3 = 0;
        !          1387:                pOHCIGeneralTransferDescriptor->CallBack = handler;
        !          1388:                pOHCIGeneralTransferDescriptor->refcon = refcon;
        !          1389: 
        !          1390:                /* Make new descriptor the tail */
        !          1391:                pEDQueue->dWord1 = pOHCIGeneralTransferDescriptor->dWord2;
        !          1392:                pEDQueue->pVirtualTailP = (UInt32) newOHCIGeneralTransferDescriptor;
        !          1393:        }
        !          1394:        pOHCIRegisters->hcCommandStatus = EndianSwap32Bit (kOHCIHcCommandStatus_BLF);
        !          1395:        if ( pOHCIUIMData->OptiOn)
        !          1396:                pOHCIRegisters->hcCommandStatus = EndianSwap32Bit (kOHCIHcCommandStatus_CLF);           
        !          1397: 
        !          1398:        return (status);
        !          1399: }
        !          1400: 
        !          1401: OSStatus OHCIUIMBulkEDDelete(
        !          1402:        short                                           functionNumber,
        !          1403:        short                                           endpointNumber,
        !          1404:        short                                           direction)
        !          1405: {
        !          1406:        OSStatus                                        status = noErr;
        !          1407:        
        !          1408: kprintf("OHCIUIMBulkDelete: calling OHCIUIMEndpointDelete for fn=%d,ep=%d\n",functionNumber,endpointNumber);
        !          1409:        status = OHCIUIMEndpointDelete(functionNumber, endpointNumber, direction);
        !          1410:        
        !          1411:        return (status);
        !          1412: }
        !          1413: 
        !          1414: Boolean BandwidthAvailable(
        !          1415:        UInt32                  pollingRate, 
        !          1416:        UInt32                  reserveBandwidth,
        !          1417:        int                             *offset)
        !          1418: {
        !          1419:        int num;
        !          1420:        OHCIRegistersPtr                        pOHCIRegisters;
        !          1421: 
        !          1422: #pragma unused reserveBandwidth
        !          1423:        pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
        !          1424: 
        !          1425:        num = EndianSwap32Bit(pOHCIRegisters->hcFmNumber)&kOHCIFmNumberMask;
        !          1426:        if (pollingRate <  1)
        !          1427:                //error condition
        !          1428:                return(false);
        !          1429:        else if(pollingRate < 2)
        !          1430:                *offset = 62;
        !          1431:        else if(pollingRate < 4)
        !          1432:                *offset = (num%2) + 60;
        !          1433:        else if(pollingRate < 8)
        !          1434:                *offset = (num%4) + 56;
        !          1435:        else if(pollingRate < 16)
        !          1436:                *offset = (num%8) + 48;
        !          1437:        else if(pollingRate < 32)
        !          1438:                *offset = (num%16) + 32;
        !          1439:        else
        !          1440:                *offset = (num%32) + 0;
        !          1441:        return (true);
        !          1442: }
        !          1443: 
        !          1444: 
        !          1445: OSStatus OHCIUIMInterruptEDCreate(
        !          1446:        short                                           functionAddress,
        !          1447:        short                                           endpointNumber,
        !          1448:        short                                           speed,
        !          1449:        UInt16                                          maxPacketSize,
        !          1450:        short                                           pollingRate,
        !          1451:        UInt32                                          reserveBandwidth)
        !          1452: {
        !          1453:        OHCIRegistersPtr                        pOHCIRegisters;
        !          1454:        OHCIEndpointDescriptorPtr       pOHCIEndpointDescriptor;
        !          1455:        OHCIEndpointDescriptorPtr       pED;
        !          1456:        UInt32                                          myFunctionAddress;
        !          1457:        UInt32                                          myEndpointNumber;
        !          1458:        UInt32                                          myMaxPacketSize, myEndPointDirection;
        !          1459:        UInt32                                          mySpeed;
        !          1460:        OHCIGeneralTransferDescriptorPtr
        !          1461:                                                                pOHCIGeneralTransferDescriptor;
        !          1462:        OSStatus                                        status = noErr;
        !          1463:        OHCIIntHeadPtr                          pInterruptHead;
        !          1464:        int                                                     offset;
        !          1465: 
        !          1466:        if (pOHCIUIMData->rootHubFuncAddress == functionAddress) 
        !          1467:                return (status);
        !          1468: 
        !          1469:        pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
        !          1470:        pInterruptHead = pOHCIUIMData->pInterruptHead;
        !          1471: 
        !          1472: 
        !          1473: ///ZZZZz  opti bug fix!!!!
        !          1474:        if (pOHCIUIMData->OptiOn) 
        !          1475:                if (speed == kOHCIEDSpeedFull) 
        !          1476:                        if (pollingRate >= 8)
        !          1477:                                pollingRate = 7;
        !          1478: 
        !          1479: 
        !          1480:        // Do we have room?? if so return with offset equal to location
        !          1481:        if((Boolean) BandwidthAvailable(pollingRate, reserveBandwidth, &offset) == false) 
        !          1482:                return(bandWidthFullErr);
        !          1483: 
        !          1484:        //  Allocate Endpoint Descripter
        !          1485:        pOHCIEndpointDescriptor = (OHCIEndpointDescriptorPtr) OHCIUIMAllocateED();
        !          1486: 
        !          1487:        // Fill in necessary data for descriptor
        !          1488:        myFunctionAddress = ((UInt32) functionAddress) << kOHCIEDControl_FAPhase;
        !          1489:        myEndpointNumber = ((UInt32) endpointNumber) << kOHCIEndpointNumberOffset;
        !          1490:        myMaxPacketSize = (UInt32) maxPacketSize << kOHCIMaxPacketSizeOffset;
        !          1491:        mySpeed = (UInt32) speed << kOHCISpeedOffset;
        !          1492:        myEndPointDirection = ((UInt32) 2) << kOHCIEndpointDirectionOffset;
        !          1493: 
        !          1494: 
        !          1495:        pOHCIEndpointDescriptor->dWord0 = EndianSwap32Bit(myFunctionAddress | myEndpointNumber | myMaxPacketSize 
        !          1496:                                                                                                                | mySpeed | myEndPointDirection);
        !          1497: 
        !          1498:        pOHCIGeneralTransferDescriptor = OHCIUIMAllocateTD();
        !          1499:        if (pOHCIGeneralTransferDescriptor == nil) {
        !          1500:                return (-1);
        !          1501:        }
        !          1502: 
        !          1503: 
        !          1504:        /* These were previously nil */
        !          1505:        pOHCIEndpointDescriptor->dWord1 = EndianSwap32Bit( (UInt32) pOHCIGeneralTransferDescriptor->pPhysical);
        !          1506:        pOHCIEndpointDescriptor->dWord2 = EndianSwap32Bit( (UInt32) pOHCIGeneralTransferDescriptor->pPhysical);
        !          1507:        pOHCIEndpointDescriptor->pVirtualTailP = (UInt32) pOHCIGeneralTransferDescriptor;
        !          1508:        pOHCIEndpointDescriptor->pVirtualHeadP = (UInt32) pOHCIGeneralTransferDescriptor;
        !          1509:        
        !          1510:        // Add to Queue
        !          1511:        pED = pInterruptHead[offset].pHead;
        !          1512:        pOHCIEndpointDescriptor->dWord3 = pED->dWord3;
        !          1513:        pED->dWord3 = EndianSwap32Bit ((UInt32) pOHCIEndpointDescriptor->pPhysical);
        !          1514:        pOHCIEndpointDescriptor->pVirtualNext = pED->pVirtualNext;
        !          1515:        pED->pVirtualNext = (UInt32) pOHCIEndpointDescriptor;
        !          1516: 
        !          1517: /// will never happen???
        !          1518:        if (pInterruptHead[offset].pHead == pInterruptHead[offset].pTail)
        !          1519:                pInterruptHead[offset].pTail = pOHCIEndpointDescriptor;
        !          1520:        
        !          1521:        pInterruptHead[offset].nodeBandwidth += reserveBandwidth;
        !          1522:        
        !          1523:        return (status);
        !          1524: }
        !          1525: 
        !          1526: 
        !          1527: OSStatus OHCIUIMInterruptTransfer(
        !          1528:        short                                           functionNumber,
        !          1529:        short                                           endpointNumber,
        !          1530:        UInt32                                          refcon,
        !          1531:        CallBackFuncPtr                         handler,
        !          1532:        UInt32                                          CBP,
        !          1533:        Boolean                                         bufferRounding,
        !          1534:        short                                           bufferSize)
        !          1535: {
        !          1536:        OHCIRegistersPtr                        pOHCIRegisters;
        !          1537:        OHCIGeneralTransferDescriptorPtr
        !          1538:                                                                pOHCIGeneralTransferDescriptor,
        !          1539:                                                                newOHCIGeneralTransferDescriptor;
        !          1540:        OSStatus                                        status = noErr;
        !          1541:        UInt32                                          myBufferRounding;
        !          1542:        UInt32                                          myDirection;
        !          1543:        UInt32                                          myToggle;
        !          1544:        OHCIEndpointDescriptorPtr       pEDQueue, temp;
        !          1545:        OHCIIntHeadPtr                          pInterruptHead;
        !          1546:        IOPreparationTable                      *ioPrep;
        !          1547:        IOPreparationTable                      IOPrep;
        !          1548:        UInt32                                          CBPPhysical;
        !          1549:        Boolean done = false;
        !          1550: 
        !          1551: kprintf("OHCIUIMInterruptTransfer:functionNumber=%d,roothubfn=%d\n",functionNumber,pOHCIUIMData->rootHubFuncAddress);
        !          1552:        if (pOHCIUIMData->rootHubFuncAddress == functionNumber) 
        !          1553:        {
        !          1554:                SimulateRootHubInt(endpointNumber, (void *)CBP, bufferSize, handler, refcon);
        !          1555:                return(noErr);
        !          1556:        }
        !          1557: 
        !          1558:        pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
        !          1559:        pInterruptHead = pOHCIUIMData->pInterruptHead;
        !          1560:        
        !          1561:        pEDQueue = FindInterruptEndpoint(functionNumber, endpointNumber, &temp);
        !          1562:        if ( pEDQueue != nil) 
        !          1563:        {
        !          1564:                newOHCIGeneralTransferDescriptor = OHCIUIMAllocateTD();
        !          1565:                if (newOHCIGeneralTransferDescriptor == nil) {
        !          1566:                        return (-1);
        !          1567:                }
        !          1568:                
        !          1569:                myBufferRounding = (UInt32) bufferRounding << kOHCIBufferRoundingOffset;
        !          1570:                myToggle = 0;   /* Take data toggle from Endpoint Descriptor */
        !          1571: 
        !          1572: 
        !          1573:                /* Last in queue is a dummy descriptor. Fill it in then add new dummy */
        !          1574:                pOHCIGeneralTransferDescriptor =  (OHCIGeneralTransferDescriptorPtr) pEDQueue->pVirtualTailP;
        !          1575:        
        !          1576:                myDirection = kOHCIBit20;       // Barry - This was undefined, make it IN. Should be in endpoint anyway
        !          1577:        
        !          1578:                pOHCIGeneralTransferDescriptor->dWord0 = EndianSwap32Bit (myBufferRounding | myDirection | myToggle);
        !          1579:                pOHCIGeneralTransferDescriptor->dWord2 = EndianSwap32Bit ((UInt32)newOHCIGeneralTransferDescriptor->pPhysical);
        !          1580:                pOHCIGeneralTransferDescriptor->pVirtualNext = (UInt32)newOHCIGeneralTransferDescriptor;
        !          1581:        
        !          1582:                if (bufferSize != 0)
        !          1583:                {
        !          1584:                         CBPPhysical = kvtophys((vm_offset_t) CBP);
        !          1585:                        pOHCIGeneralTransferDescriptor->dWord1 = EndianSwap32Bit (CBPPhysical);
        !          1586:                        pOHCIGeneralTransferDescriptor->dWord3 = EndianSwap32Bit (CBPPhysical + bufferSize-1);
        !          1587: 
        !          1588:                } else {
        !          1589:                        pOHCIGeneralTransferDescriptor->dWord1 = 0;
        !          1590:                        pOHCIGeneralTransferDescriptor->dWord3 = 0;
        !          1591:                }
        !          1592:                pOHCIGeneralTransferDescriptor->CallBack = handler;
        !          1593:                pOHCIGeneralTransferDescriptor->refcon = refcon;
        !          1594:                
        !          1595:                /* Make new descriptor the tail */
        !          1596:                pEDQueue->dWord1 = pOHCIGeneralTransferDescriptor->dWord2;
        !          1597:                pEDQueue->pVirtualTailP = (UInt32) newOHCIGeneralTransferDescriptor;
        !          1598:        } else {
        !          1599:                FailureDebugStr("UIMInterruptTransfer: Couldnot find endpoint");
        !          1600:                status = kUSBNotFound;
        !          1601:        }
        !          1602:         kprintf("OHCIUIMInterruptTransfer: returning status=%d\n",status);
        !          1603:        return ( status);
        !          1604: }
        !          1605: 
        !          1606: 
        !          1607: OSStatus OHCIUIMEndpointDelete(
        !          1608:        short                                           functionNumber,
        !          1609:        short                                           endpointNumber,
        !          1610:        short                                           direction)
        !          1611: {
        !          1612:        OHCIRegistersPtr                        pOHCIRegisters;
        !          1613:        OSStatus                                        status = noErr;
        !          1614:        OHCIEndpointDescriptorPtr       pED;
        !          1615:        OHCIEndpointDescriptorPtr       pEDQueueBack;
        !          1616:        UInt32                                          hcControl;
        !          1617:        UInt32                                          something, controlMask;
        !          1618: //     UInt32                                          edDirection;
        !          1619: 
        !          1620: 
        !          1621:        if (pOHCIUIMData->rootHubFuncAddress == functionNumber) 
        !          1622:                return (status);
        !          1623: 
        !          1624:        pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
        !          1625:        
        !          1626:        //search for endpoint descriptor
        !          1627:        if (direction == kUSBOut)
        !          1628:                direction = kOHCIEDDirectionOut;
        !          1629:        else if (direction == kUSBIn) 
        !          1630:                direction = kOHCIEDDirectionIn;
        !          1631:        else
        !          1632:                direction = kOHCIEDDirectionTD;
        !          1633:                
        !          1634: kprintf("OHCIUIMEndpointDelete: calling FindEndpoint\n");
        !          1635:        if((pED = FindEndpoint (functionNumber, endpointNumber, direction, &pEDQueueBack, &controlMask)) == nil)
        !          1636:        {
        !          1637:                FailureDebugStr("UIMEndpointDelete: Couldnot find endpoint\n");
        !          1638:                return (kUSBNotFound);
        !          1639:        }
        !          1640: 
        !          1641:        // Remove Endpoint
        !          1642:        //mark sKipped
        !          1643:        pED->dWord0 |= EndianSwap32Bit (kOHCIEDControl_K);
        !          1644: //     edDirection = EndianSwap32Bit(pED->dWord0) & kOHCIEndpointDirectionMask;
        !          1645:        // remove pointer wraps
        !          1646:        pEDQueueBack->dWord3 = pED->dWord3;
        !          1647:        pEDQueueBack->pVirtualNext = pED->pVirtualNext;
        !          1648: 
        !          1649: 
        !          1650:        // clear some bit in hcControl
        !          1651:        hcControl = EndianSwap32Bit (pOHCIRegisters->hcControl);        
        !          1652:        hcControl &= ~controlMask;
        !          1653:        hcControl &= OHCIBitRange(0, 10);
        !          1654: 
        !          1655:        pOHCIRegisters->hcControl = EndianSwap32Bit (hcControl);
        !          1656: 
        !          1657:        // poll for interrupt  zzzzz turn into real interrupt
        !          1658:        pOHCIRegisters->hcInterruptStatus = EndianSwap32Bit(kOHCIBit2);
        !          1659:        DelayForHardware(DurationToAbsolute(1*durationMillisecond));
        !          1660:        something = EndianSwap32Bit(pOHCIRegisters->hcInterruptStatus) & kOHCIInterruptSOFMask;
        !          1661: #if 1
        !          1662:                        if(!something)
        !          1663:                        {       /* This should have been set, just in case wait another ms */
        !          1664:                                DelayForHardware(DurationToAbsolute(1*durationMillisecond));
        !          1665:                        }
        !          1666: #else
        !          1667:        /* BT - 13Jun98, this was hanging, the grey screen with andromeda hub */
        !          1668:                        while (!something) {
        !          1669:                                DelayForHardware(DurationToAbsolute(1*durationMillisecond));
        !          1670:                                something = EndianSwap32Bit(pOHCIRegisters->hcInterruptStatus) & kOHCIHcInterrupt_SF;
        !          1671:                        }
        !          1672: #endif
        !          1673:        //restart hcControl
        !          1674:        hcControl |= controlMask;
        !          1675:        pOHCIRegisters->hcControl = EndianSwap32Bit (hcControl);
        !          1676: 
        !          1677:        RemoveAllTDs(pED);
        !          1678:        
        !          1679:        pED->dWord3 = nil;
        !          1680:        
        !          1681:        //deallocate ED
        !          1682:        OHCIUIMDeallocateED(pED);
        !          1683:        return (status);
        !          1684: }
        !          1685: 
        !          1686: 
        !          1687: OSStatus OHCIUIMAbortEndpoint(
        !          1688:        short                                           functionNumber,
        !          1689:        short                                           endpointNumber,
        !          1690:        short                                           direction)
        !          1691: {
        !          1692:        OHCIRegistersPtr                        pOHCIRegisters;
        !          1693:        OSStatus                                        status = noErr;
        !          1694:        OHCIEndpointDescriptorPtr       pED;
        !          1695:        OHCIEndpointDescriptorPtr       pEDQueueBack;
        !          1696:        UInt32                                          hcControl;
        !          1697:        UInt32                                          something, controlMask;
        !          1698: 
        !          1699:        if (pOHCIUIMData->rootHubFuncAddress == functionNumber) 
        !          1700:                return (status);
        !          1701: 
        !          1702:        pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
        !          1703:        
        !          1704:        if (direction == kUSBOut)
        !          1705:                direction = kOHCIEDDirectionOut;
        !          1706:        else if (direction == kUSBIn) 
        !          1707:                direction = kOHCIEDDirectionIn;
        !          1708:        else
        !          1709:                direction = kOHCIEDDirectionTD;
        !          1710: 
        !          1711:        //search for endpoint descriptor
        !          1712: kprintf("OHCIUIMAbort EP:calling FindEndpoint\n");
        !          1713:        if((pED = FindEndpoint (functionNumber, endpointNumber, direction, &pEDQueueBack, &controlMask)) == nil)
        !          1714:                return(kUSBNotFound);
        !          1715: 
        !          1716: 
        !          1717:        pED->dWord0 |= EndianSwap32Bit (kOHCIEDControl_K);
        !          1718:        hcControl = EndianSwap32Bit (pOHCIRegisters->hcControl);        
        !          1719:        hcControl &= ~controlMask;
        !          1720:        hcControl &= OHCIBitRange(0, 10);
        !          1721: 
        !          1722:        pOHCIRegisters->hcControl = EndianSwap32Bit (hcControl);
        !          1723: 
        !          1724:        // poll for interrupt  zzzzz turn into real interrupt
        !          1725:        pOHCIRegisters->hcInterruptStatus = EndianSwap32Bit(kOHCIBit2);
        !          1726:        DelayForHardware(DurationToAbsolute(1*durationMillisecond));
        !          1727:        something = EndianSwap32Bit(pOHCIRegisters->hcInterruptStatus) & kOHCIInterruptSOFMask;
        !          1728: #if 1
        !          1729:                        if(!something)
        !          1730:                        {       /* This should have been set, just in case wait another ms */
        !          1731:                                DelayForHardware(DurationToAbsolute(1*durationMillisecond));
        !          1732:                        }
        !          1733: #else
        !          1734:        /* BT - 13Jun98, this was hanging, the grey screen with andromeda hub */
        !          1735:                        while (!something) {
        !          1736:                                DelayForHardware(DurationToAbsolute(1*durationMillisecond));
        !          1737:                                something = EndianSwap32Bit(pOHCIRegisters->hcInterruptStatus) & kOHCIHcInterrupt_SF;
        !          1738:                        }
        !          1739: #endif
        !          1740:        //restart hcBulk
        !          1741:        hcControl |= controlMask;
        !          1742:        pOHCIRegisters->hcControl = EndianSwap32Bit (hcControl);
        !          1743: 
        !          1744:        RemoveTDs(pED);
        !          1745: 
        !          1746:        pED->dWord0 &= ~EndianSwap32Bit (kOHCIEDControl_K);
        !          1747: 
        !          1748:        return (0);
        !          1749: 
        !          1750: }
        !          1751: 
        !          1752: UInt64 OHCIUIMGetCurrentFrameNumber(void) 
        !          1753: {
        !          1754: 
        !          1755:        UInt64                                          time;
        !          1756:        OHCIRegistersPtr                        pOHCIRegisters;
        !          1757:        
        !          1758:        pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
        !          1759:        time = usb_U64Add (pOHCIUIMData->frameNumber, U64SetU(EndianSwap32Bit(pOHCIRegisters->hcFmNumber)&kOHCIFmNumberMask));
        !          1760:        return (time);
        !          1761: 
        !          1762: }
        !          1763: 
        !          1764: 
        !          1765: 
        !          1766: ////////////////////////////////////////////////////////////////////////////////
        !          1767: ////////////////////////////////////////////////////////////////////////////////
        !          1768: //
        !          1769: // Internal routines.
        !          1770: //
        !          1771: ////////////////////////////////////////////////////////////////////////////////
        !          1772: ////////////////////////////////////////////////////////////////////////////////
        !          1773: 
        !          1774: 
        !          1775: 
        !          1776: ////////////////////////////////////////////////////////////////////////////////
        !          1777: //
        !          1778: // OHCIUIMGetRegisterBaseAddress
        !          1779: //
        !          1780: //   This proc uses the name registry to find the base address of the registers.
        !          1781: //
        !          1782: 
        !          1783: #if 0  //naga
        !          1784: static OSStatus        OHCIUIMGetRegisterBaseAddress(
        !          1785:        RegEntryIDPtr                           pOHCIRegEntryID,
        !          1786:        OHCIRegistersPtr                        *ppOHCIRegisters)
        !          1787: {
        !          1788:        PCIAssignedAddressPtr           pPCIAssignedAddresses = nil;
        !          1789:        DeviceLogicalAddressPtr         pDeviceLogicalAddresses = nil;
        !          1790:        RegPropertyValueSize            propSize;
        !          1791:        UInt32                                          addressSpaceFlags;
        !          1792:        UInt32                                          registerNumber;
        !          1793:        OHCIRegistersPtr                        pOHCIRegisters;
        !          1794:        UInt32                                          numAddresses,
        !          1795:                                                                addressNum;
        !          1796:        Boolean                                         done;
        !          1797:        OSStatus                                        status = noErr;
        !          1798: 
        !          1799:        // Get assigned addresses property.
        !          1800:        status = RegistryPropertyGetSize
        !          1801:                                (pOHCIRegEntryID,
        !          1802:                                 (RegPropertyNamePtr) kPCIAssignedAddressProperty,
        !          1803:                                 &propSize);
        !          1804: 
        !          1805:        if (status == noErr)
        !          1806:        {
        !          1807:                if (CurrentExecutionLevel() != kTaskLevel){
        !          1808:                        MemoryDebugStr("OHCIUIM: Allocating memory (3) at non-task time, report stack trace please; sc");
        !          1809:                }
        !          1810:                // zzzz do we deallocate this?
        !          1811:                pPCIAssignedAddresses =
        !          1812:                        (PCIAssignedAddressPtr) PoolAllocateResident (propSize, false);
        !          1813:                if (pPCIAssignedAddresses == nil)
        !          1814:                        status = memFullErr;
        !          1815:        }
        !          1816: 
        !          1817:        if (status == noErr)
        !          1818:        {
        !          1819:                status = RegistryPropertyGet
        !          1820:                                        (pOHCIRegEntryID,
        !          1821:                                         (RegPropertyNamePtr) kPCIAssignedAddressProperty,
        !          1822:                                         pPCIAssignedAddresses,
        !          1823:                                         &propSize);
        !          1824:                if (status == noErr)
        !          1825:                        numAddresses = propSize / sizeof (PCIAssignedAddress);
        !          1826:        }
        !          1827: 
        !          1828:        // Get logical addresses property.
        !          1829:        if (status == noErr)
        !          1830:        {
        !          1831:                status = RegistryPropertyGetSize
        !          1832:                                        (pOHCIRegEntryID,
        !          1833:                                         (RegPropertyNamePtr) kAAPLDeviceLogicalAddress,
        !          1834:                                         &propSize);
        !          1835:        }
        !          1836: 
        !          1837:        if (status == noErr)
        !          1838:        {
        !          1839:                // zzzzz do we dealocate this?
        !          1840:                pDeviceLogicalAddresses =
        !          1841:                        (DeviceLogicalAddressPtr) PoolAllocateResident (propSize, false);
        !          1842:                if (pDeviceLogicalAddresses == nil)
        !          1843:                        status = memFullErr;
        !          1844:        }
        !          1845: 
        !          1846:        if (status == noErr)
        !          1847:        {
        !          1848:                status = RegistryPropertyGet
        !          1849:                                        (pOHCIRegEntryID,
        !          1850:                                         (RegPropertyNamePtr) kAAPLDeviceLogicalAddress,
        !          1851:                                         pDeviceLogicalAddresses,
        !          1852:                                         &propSize);
        !          1853:        }
        !          1854: 
        !          1855:        // Get main memory mapped register file base address.
        !          1856:        if (status == noErr)
        !          1857:        {
        !          1858:                done = false;
        !          1859:                for (addressNum = 0; ((addressNum < numAddresses) && (!done)); addressNum++)
        !          1860:                {
        !          1861:                        addressSpaceFlags = pPCIAssignedAddresses[addressNum].addressSpaceFlags;
        !          1862:                        registerNumber = pPCIAssignedAddresses[addressNum].registerNumber;
        !          1863:                        if ((registerNumber == kOHCIConfigRegBaseAddressRegisterNumber) &&
        !          1864:                                (addressSpaceFlags & kPCI32BitMemorySpace))
        !          1865:                        {
        !          1866:                                pOHCIRegisters = pDeviceLogicalAddresses[addressNum];
        !          1867:                                done = true;
        !          1868:                        } 
        !          1869:                }
        !          1870: 
        !          1871:                if (!done)
        !          1872: //zzzz
        !          1873:                        status = -4161;
        !          1874: //                     status = notFoundErr;
        !          1875:        }
        !          1876: 
        !          1877:        // Clean up.
        !          1878:        if (pDeviceLogicalAddresses != nil)
        !          1879:                PoolDeallocate ((Ptr) pDeviceLogicalAddresses);
        !          1880:        if (pPCIAssignedAddresses != nil)
        !          1881:                PoolDeallocate ((Ptr) pPCIAssignedAddresses);
        !          1882: 
        !          1883:        // Return results.
        !          1884:        if (status == noErr)
        !          1885:                *ppOHCIRegisters = pOHCIRegisters;
        !          1886:        else
        !          1887:                *ppOHCIRegisters = nil;
        !          1888: 
        !          1889:        return (status);
        !          1890: }
        !          1891: 
        !          1892: 
        !          1893: OSStatus OHCIUIMInstallInterruptHandler ()
        !          1894: 
        !          1895: {
        !          1896:        RegEntryIDPtr                           pOHCIRegEntryID = &(pOHCIUIMData->ohciRegEntryID);
        !          1897:        ISTProperty                                     interruptSets;
        !          1898:        InterruptSetID                          interruptSetID;
        !          1899:        InterruptMemberNumber           interruptMemberNumber;
        !          1900:        void                                            *oldInterruptRefCon;
        !          1901:        InterruptHandler                        oldInterruptHandler;
        !          1902:        InterruptEnabler                        oldInterruptEnabler;
        !          1903:        InterruptDisabler                       oldInterruptDisabler;
        !          1904:        RegPropertyValueSize            propSize;
        !          1905:        OSStatus                                        status = noErr;
        !          1906: 
        !          1907: 
        !          1908:        // Get our interrupt set from the name registry.
        !          1909:        propSize = sizeof (ISTProperty);
        !          1910:        status = RegistryPropertyGet (pOHCIRegEntryID, kISTPropertyName,
        !          1911:                                                                  &interruptSets, &propSize);
        !          1912:        interruptSetID = interruptSets[kISTChipInterruptSource].setID;
        !          1913:        interruptMemberNumber = interruptSets[kISTChipInterruptSource].member;
        !          1914: 
        !          1915:        // Get the interrupt enabler and disabler for our chip interrupt set.
        !          1916:        if (status == noErr)
        !          1917:        {
        !          1918:                status = GetInterruptFunctions
        !          1919:                                        (interruptSetID, interruptMemberNumber,
        !          1920:                                         &oldInterruptRefCon, &oldInterruptHandler,
        !          1921:                                         &oldInterruptEnabler, &oldInterruptDisabler);
        !          1922:        }
        !          1923: 
        !          1924:        // Install the refCon and interrupt handler for our chip interrupt set.
        !          1925:        if (status == noErr)
        !          1926:        {
        !          1927:                status = InstallInterruptFunctions
        !          1928:                                        (interruptSetID, interruptMemberNumber,
        !          1929:                                         pOHCIUIMData, (InterruptHandler) OHCIUIMInterruptHandler,
        !          1930:                                         nil, nil);
        !          1931:        }
        !          1932: 
        !          1933:        // Add info to our UIM Data record.
        !          1934:        if (status == noErr)
        !          1935:        {
        !          1936:                pOHCIUIMData->interruptSetMember.setID = interruptSetID;
        !          1937:                pOHCIUIMData->interruptSetMember.member = interruptMemberNumber;
        !          1938:                pOHCIUIMData->oldInterruptRefCon = oldInterruptRefCon;
        !          1939:                pOHCIUIMData->oldInterruptHandler = oldInterruptHandler;
        !          1940:                pOHCIUIMData->interruptEnabler = oldInterruptEnabler;
        !          1941:                pOHCIUIMData->interruptDisabler = oldInterruptDisabler;
        !          1942:        }
        !          1943:        
        !          1944:        return (status);
        !          1945: }
        !          1946: #endif 0 
        !          1947: 
        !          1948: OSStatus OHCIUIMInterruptHandler (InterruptSetMember member, void *refCon, UInt32 interruptCount)
        !          1949: {
        !          1950:        register OHCIRegistersPtr                       pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
        !          1951:        register UInt32                                         activeInterrupts, interruptEnable;
        !          1952:        UInt32                                                          PhysAddr;
        !          1953:        OHCIGeneralTransferDescriptorPtr        pHCDoneTD;
        !          1954:        
        !          1955: #pragma unused member
        !          1956: #pragma unused refCon
        !          1957: #pragma unused interruptCount
        !          1958: 
        !          1959:      usb_task_level = kSecondaryInterruptLevel;
        !          1960:        interruptEnable = EndianSwap32Bit(pOHCIRegisters->hcInterruptEnable);
        !          1961:        
        !          1962:        activeInterrupts = interruptEnable & EndianSwap32Bit(pOHCIRegisters->hcInterruptStatus);
        !          1963:        
        !          1964:        if ((interruptEnable & kOHCIHcInterrupt_MIE) && (activeInterrupts != 0)){
        !          1965: 
        !          1966:                if (activeInterrupts & kOHCIHcInterrupt_SO){            // SchedulingOverrun Interrupt
        !          1967:                        pOHCIUIMData->errors.scheduleOverrun++;
        !          1968:                        pOHCIRegisters->hcInterruptStatus = EndianSwap32Bit(kOHCIHcInterrupt_SO);
        !          1969:                }
        !          1970:                if (activeInterrupts & kOHCIHcInterrupt_WDH){           // WritebackDoneHead Interrupt
        !          1971:                        PhysAddr = (UInt32) EndianSwap32Bit(*(UInt32 *)(pOHCIUIMData->pHCCA + 0x84));
        !          1972:                        PhysAddr &= kOHCIHeadPMask; // mask off interrupt bits
        !          1973:                        pHCDoneTD = (OHCIGeneralTransferDescriptorPtr) OHCIUIMGetLogicalAddress (PhysAddr);
        !          1974:                        // write to 0 to the HCCA DoneHead ptr so we won't look at it anymore.
        !          1975:                        *(UInt32 *)(pOHCIUIMData->pHCCA + 0x84) = 0L;  
        !          1976:                        QueueSecondaryInterruptHandler((SecondaryInterruptHandler2)DoDoneQueueProcessing, 
        !          1977:                                                                                        nil, (void *)pHCDoneTD, (void *)false);
        !          1978:                        pOHCIRegisters->hcInterruptStatus = EndianSwap32Bit(kOHCIHcInterrupt_WDH);
        !          1979:                }
        !          1980:                if (activeInterrupts & kOHCIHcInterrupt_SF){            // StartofFrame Interrupt
        !          1981:                        // does USL have SF notification set?
        !          1982:                        // if so, tell them now's the time!
        !          1983:                        
        !          1984:                        // Clear the interrrupt
        !          1985:                        pOHCIRegisters->hcInterruptStatus = EndianSwap32Bit(kOHCIHcInterrupt_SF);
        !          1986:                        
        !          1987:                        // and mask it off so it doesn't happen again.
        !          1988:                        // will have to be turned on manually to happen again.
        !          1989:                        pOHCIRegisters->hcInterruptDisable = EndianSwap32Bit(kOHCIHcInterrupt_SF);
        !          1990: SysDebugStr("Frame Interrupt");                        
        !          1991:                        QueueSecondaryInterruptHandler(RootHubFrame, nil, nil, nil);
        !          1992: 
        !          1993:                }
        !          1994:                if (activeInterrupts & kOHCIHcInterrupt_RD){            // ResumeDetected Interrupt
        !          1995:                        // does USL have SF notification set?
        !          1996:                        // if so, tell them now's the time to resume!
        !          1997:                        pOHCIRegisters->hcInterruptStatus = EndianSwap32Bit(kOHCIHcInterrupt_RD);
        !          1998:                }
        !          1999:                if (activeInterrupts & kOHCIHcInterrupt_UE){            // Unrecoverable Error Interrupt
        !          2000:                        pOHCIUIMData->errors.unrecoverableError++;
        !          2001:                        // Let's do a SW reset to recover from this condition.  We could make sure all 
        !          2002:                        // OCHI registers and in-memory data structures are valid, too.
        !          2003:                        pOHCIRegisters->hcCommandStatus = EndianSwap32Bit(kOHCIHcCommandStatus_HCR);  
        !          2004:                        DelayForHardware(DurationToAbsolute(10*durationMicrosecond));
        !          2005:                        pOHCIRegisters->hcInterruptStatus = EndianSwap32Bit(kOHCIHcInterrupt_UE);
        !          2006:                        // zzzz - note I'm leaving the Control/Bulk list processing off for now.
        !          2007:                        pOHCIRegisters->hcControl = EndianSwapImm32Bit((kOHCIFunctionalState_Operational << kOHCIHcControl_HCFSPhase) | kOHCIHcControl_PLE);
        !          2008:                }
        !          2009:                if (activeInterrupts & kOHCIHcInterrupt_FNO){           // FrameNumberOverflow Interrupt
        !          2010:                        // not really an error, but close enough
        !          2011:                        pOHCIUIMData->errors.frameNumberOverflow++;     
        !          2012:                        if ((EndianSwap32Bit(pOHCIRegisters->hcFmNumber)&kOHCIFmNumberMask) < kOHCIBit15)
        !          2013:                                pOHCIUIMData->frameNumber = usb_U64Add (pOHCIUIMData->frameNumber, U64SetU(kOHCIFrameOverflowBit));
        !          2014: 
        !          2015:                        pOHCIRegisters->hcInterruptStatus = EndianSwap32Bit(kOHCIHcInterrupt_FNO);
        !          2016:                }
        !          2017:                if (activeInterrupts & kOHCIHcInterrupt_RHSC){          // RootHubStatusChange Interrupt
        !          2018:  
        !          2019:                        // Clear status change.
        !          2020:                        pOHCIRegisters->hcInterruptStatus = EndianSwap32Bit(kOHCIHcInterrupt_RHSC);
        !          2021: SysDebugStr("RHSC Interrupt");                 
        !          2022:                //      QueueSecondaryInterruptHandler(RootHubStatusChange, nil, nil, nil);
        !          2023:                }
        !          2024:                if (activeInterrupts & kOHCIHcInterrupt_OC){            // OwnershipChange Interrupt
        !          2025:                        // well, we certainly weren't expecting this!
        !          2026:                        pOHCIUIMData->errors.ownershipChange++;         
        !          2027:                        // Let the USL know about the status change?
        !          2028:                        pOHCIRegisters->hcInterruptStatus = EndianSwap32Bit(kOHCIHcInterrupt_OC);
        !          2029:                }
        !          2030:                        
        !          2031:        } else {
        !          2032:      usb_task_level = kKernelLevel;
        !          2033:                return(kIsrIsNotComplete);   // wasn't our interrupt
        !          2034:        }
        !          2035:      usb_task_level = kKernelLevel;
        !          2036:        return(kIsrIsComplete);  
        !          2037: }
        !          2038: 
        !          2039: 
        !          2040: OSStatus OHCIProcessDoneQueue (void) 
        !          2041: {
        !          2042:        OHCIRegistersPtr                                        pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
        !          2043:        OSStatus                                                        status = noErr;
        !          2044:        UInt32                                                          interruptStatus;
        !          2045:        UInt32                                                          PhysAddr;
        !          2046:        OHCIGeneralTransferDescriptorPtr        pHCDoneTD;
        !          2047: 
        !          2048: //     DebugStr ((ConstStr255Param) "OHCIProcessDoneQueue");
        !          2049: 
        !          2050:        // check if the OHCI has written the DoneHead yet
        !          2051:        interruptStatus = EndianSwap32Bit(pOHCIRegisters->hcInterruptStatus);
        !          2052:        if( (interruptStatus & kOHCIHcInterrupt_WDH) == 0)
        !          2053:        {       
        !          2054:                return(noErr);
        !          2055:        }
        !          2056:        
        !          2057:        // get the pointer to the list (logical address)
        !          2058:        PhysAddr = (UInt32) EndianSwap32Bit(*(UInt32 *)(pOHCIUIMData->pHCCA + 0x84));
        !          2059:        PhysAddr &= kOHCIHeadPMask; // mask off interrupt bits
        !          2060:        pHCDoneTD = (OHCIGeneralTransferDescriptorPtr) OHCIUIMGetLogicalAddress (PhysAddr);
        !          2061:        // write to 0 to the HCCA DoneHead ptr so we won't look at it anymore.
        !          2062:        *(UInt32 *)(pOHCIUIMData->pHCCA + 0x84) = 0L;  
        !          2063:                        
        !          2064:        // Since we have a copy of the queue to process, we can let the host update it again.
        !          2065:        pOHCIRegisters->hcInterruptStatus = EndianSwap32Bit(kOHCIHcInterrupt_WDH);
        !          2066: 
        !          2067:        DoDoneQueueProcessing(pHCDoneTD, true);
        !          2068:        return(true);
        !          2069: }
        !          2070: 
        !          2071: 
        !          2072: OSStatus OHCIUIMIsochEDCreate(
        !          2073:        short                                           functionAddress,
        !          2074:        short                                           endpointNumber,
        !          2075:        UInt32                                          maxPacketSize,
        !          2076:        UInt8                                           direction)
        !          2077:        
        !          2078: {      
        !          2079:        OHCIEndpointDescriptorPtr       pOHCIEndpointDescriptor, pED;
        !          2080:        OSStatus                                        status = noErr;
        !          2081:        if (direction == kUSBOut)
        !          2082:                direction = kOHCIEDDirectionOut;
        !          2083:        else if (direction == kUSBIn) 
        !          2084:                direction = kOHCIEDDirectionIn;
        !          2085:        else
        !          2086:                direction = kOHCIEDDirectionTD;
        !          2087: 
        !          2088:        pED = (OHCIEndpointDescriptorPtr) pOHCIUIMData->pIsochHead;
        !          2089:        pOHCIEndpointDescriptor = AddEmptyEndPoint (
        !          2090:                                        functionAddress, endpointNumber, maxPacketSize, kOHCIEDSpeedFull, direction, pED, kOHCIEDFormatIsochronousTD);
        !          2091:        if (pOHCIEndpointDescriptor == nil)
        !          2092:                return(-1);
        !          2093:        return (status);
        !          2094: }
        !          2095: 
        !          2096: OSStatus OHCIUIMIsochTransfer(
        !          2097:        short                                           functionAddress,                                                
        !          2098:        short                                           endpointNumber, 
        !          2099:        UInt32                                          refcon,
        !          2100:        UInt8                                           direction,
        !          2101:        IsocCallBackFuncPtr                     pIsochHandler,                                                  
        !          2102:        UInt64                                          frameNumberStart,                                                               
        !          2103:        UInt32                                          pBufferStart,                                                   
        !          2104:        UInt32                                          frameCount,                                                                     
        !          2105:        USBIsocFrame                            *pFrames)                                                               
        !          2106: {
        !          2107: 
        !          2108:        OHCIIsochTransferDescriptorPtr          pITD;
        !          2109:        int                                                                     i;
        !          2110:        UInt32                                                          currentFrame;
        !          2111:        UInt32                                                          numOfPages;
        !          2112:        UInt32                                                          bufferSize;
        !          2113:        OHCIEndpointDescriptorPtr                       pED, temp;
        !          2114:        UInt32                                                          pageSize, pageMask;
        !          2115:        OSStatus                                                        status = noErr;
        !          2116:        IOPreparationTable                                      *ioPrep;
        !          2117:        IOPreparationTable                                      IOPrep;
        !          2118:        UInt32                                                          physicalAddresses[kOHCIMaxPages];       
        !          2119:        UInt32                                                          frameTD, pagesUsed;
        !          2120:        UInt32                                                          alreadyCrossed = kOHCIITDConditionNotCrossPage;
        !          2121:        UInt16                                                          frameNumber;
        !          2122:        UInt32                                                          firstCount, lastCount, pageOffsetMask;
        !          2123: //     DebugStr("ISOC check write to 0");
        !          2124: 
        !          2125:        
        !          2126:        if (direction == kUSBOut)
        !          2127:                direction = kOHCIEDDirectionOut;
        !          2128:        else if (direction == kUSBIn) 
        !          2129:                direction = kOHCIEDDirectionIn;
        !          2130:        else
        !          2131:                direction = kOHCIEDDirectionTD;
        !          2132: 
        !          2133:        pED = FindIsochronousEndpoint(functionAddress, endpointNumber, direction, &temp);
        !          2134:        
        !          2135:        if (!pED){
        !          2136:                FailureDebugStr("UIMIsochTransfer: Couldnot find endpoint");
        !          2137:                status = kUSBNotFound;
        !          2138:                return (status);
        !          2139:        }
        !          2140:        frameNumber = (UInt16) U32SetU (frameNumberStart);
        !          2141:        ioPrep = &IOPrep;
        !          2142:        pageSize = pOHCIUIMData->pageSize;
        !          2143:        pageMask = ~(pageSize - 1);
        !          2144:        frameTD = 0;
        !          2145:        pageOffsetMask = pageSize - 1;
        !          2146: //  Get the total size of buffer
        !          2147:        bufferSize = 0;
        !          2148:        for ( i = 0; i< frameCount; i++)
        !          2149:                bufferSize += pFrames[i].frReqCount;
        !          2150:        
        !          2151:        currentFrame = 0;
        !          2152:        while (currentFrame < frameCount -1) {
        !          2153:                
        !          2154:                firstCount = pageSize - (pBufferStart & pageOffsetMask);
        !          2155:                if (bufferSize <= firstCount){
        !          2156:                        lastCount = 0;
        !          2157:                        numOfPages = 1;
        !          2158:                } else {
        !          2159:                        lastCount = (pBufferStart + bufferSize) & pageOffsetMask;
        !          2160:                        numOfPages = (bufferSize - firstCount - lastCount)/pageSize;
        !          2161:                        if (firstCount) numOfPages++;
        !          2162:                        if (lastCount) numOfPages++;
        !          2163:                }
        !          2164:                // Prepare for IO and get physical address
        !          2165:                ioPrep->options = kIOLogicalRanges | kIOIsInput | kIOIsOutput;
        !          2166:                ioPrep->addressSpace = kCurrentAddressSpaceID;                  // default
        !          2167:                ioPrep->granularity = 0;                                                                // do it all now
        !          2168:                ioPrep->firstPrepared = 0;
        !          2169:                ioPrep->mappingEntryCount = MIN (numOfPages, kOHCIMaxPages);                            // # of pages we will use
        !          2170:                ioPrep->logicalMapping = 0;
        !          2171:                ioPrep->physicalMapping = (PhysicalMappingTablePtr) physicalAddresses;  // return list of phys addrs
        !          2172:                ioPrep->rangeInfo.range.base = (void *) pBufferStart;
        !          2173:                ioPrep->rangeInfo.range.length =  MIN (numOfPages, kOHCIMaxPages) * pageSize;
        !          2174: 
        !          2175:                status = PrepareMemoryForIO (ioPrep);
        !          2176:                pITD = (OHCIIsochTransferDescriptorPtr) pED->pVirtualTailP;
        !          2177:                pagesUsed = 0;
        !          2178:                while (((pagesUsed < kOHCIMaxPages -1) || (pagesUsed == numOfPages-1)) && (currentFrame < frameCount-1))
        !          2179:                {                
        !          2180:                        if (frameTD == 8){
        !          2181:                                // make current ITD = 7 frames
        !          2182:                                pITD->dWord0 |= (frameTD-1) << kOHCIITDControl_FCPhase;
        !          2183: 
        !          2184:                                pITD->dWord3 = physicalAddresses[pagesUsed] + ((pBufferStart-1) & ~pageMask);
        !          2185:                                // queue another pITD
        !          2186:                                pITD = QueueITD(pITD, pED);
        !          2187:                                frameTD = 0;
        !          2188:                                alreadyCrossed = kOHCIITDConditionNotCrossPage;
        !          2189:                        }
        !          2190:                        // check if buffer crosses page
        !          2191:                        if ((pBufferStart & pageMask) != ((pBufferStart + pFrames[currentFrame].frReqCount) & pageMask)) {
        !          2192:                                if (alreadyCrossed == kOHCIITDConditionCrossPage) {
        !          2193:                                        // fill in value for number of frames
        !          2194:                                        pITD->dWord0 |= (frameTD-1) << kOHCIITDControl_FCPhase;
        !          2195: 
        !          2196:                                        pITD->dWord3 = physicalAddresses[pagesUsed] + ((pBufferStart-1) & ~pageMask);
        !          2197:                                        // queue another ITD
        !          2198:                                        pITD = QueueITD(pITD, pED);
        !          2199:                                        frameTD = 0;
        !          2200:                                }
        !          2201:                                pagesUsed++;
        !          2202:                                alreadyCrossed = kOHCIITDConditionCrossPage;
        !          2203:                        }
        !          2204:                        if (frameTD == 0) {
        !          2205:                                pITD->offset[frameTD] = (pBufferStart & ~pageMask) | 
        !          2206:                                                                                kOHCIITDConditionNotAccessed << kOHCIITDOffset_CCPhase  | 
        !          2207:                                                                                alreadyCrossed << kOHCIITDOffset_PCPhase;
        !          2208:                                if (alreadyCrossed == kOHCIITDConditionCrossPage)
        !          2209:                                        pITD->dWord1 = physicalAddresses[pagesUsed-1] & pageMask;
        !          2210:                                else
        !          2211:                                        pITD->dWord1 = physicalAddresses[pagesUsed] & pageMask;
        !          2212:                                pITD->dWord0 |= frameNumber;
        !          2213:                                pITD->pIsocFrame = (UInt32) pFrames;
        !          2214:                                pITD->frameNum = currentFrame;
        !          2215:                                frameTD++;
        !          2216:                        }
        !          2217:                        // fill in normally, if alreadycrossed = true, make the 12th bit a 1
        !          2218:                        pITD->offset[frameTD] = kOHCIITDConditionNotAccessed << kOHCIITDOffset_CCPhase  | 
        !          2219:                                                                        alreadyCrossed << kOHCIITDOffset_PCPhase |
        !          2220:                                                                        ((pBufferStart+pFrames[currentFrame].frReqCount) & ~pageMask) 
        !          2221:                                                                        + (physicalAddresses[pagesUsed] & ~pageMask);                                                   
        !          2222:                        frameTD++;
        !          2223:                        frameNumber++;
        !          2224:                        bufferSize -= pFrames[currentFrame].frReqCount;
        !          2225:                        pBufferStart += pFrames[currentFrame].frReqCount;
        !          2226:                        currentFrame++;
        !          2227:                }
        !          2228:                
        !          2229:                CheckpointIO(ioPrep->preparationID, nil);       
        !          2230:        }
        !          2231:        
        !          2232:        pITD->dWord0 |= (frameTD-1) << kOHCIITDControl_FCPhase;
        !          2233: // barry stuff
        !          2234: //     pITD->dWord3 = physicalAddresses[pagesUsed] + 2*pFrames[currentFrame].frReqCount - 1;
        !          2235:        pBufferStart += pFrames[currentFrame].frReqCount;
        !          2236:        pITD->dWord3 = physicalAddresses[pagesUsed] + ((pBufferStart-1) & ~pageMask);
        !          2237:        pITD->refcon = refcon;
        !          2238:        pITD->handler = pIsochHandler;
        !          2239:        QueueITD(pITD, pED);
        !          2240: //     DebugStr("ISOC check write to 0");
        !          2241:        return(0);
        !          2242: 
        !          2243: }
        !          2244: 
        !          2245: OHCIIsochTransferDescriptorPtr QueueITD (
        !          2246:        OHCIIsochTransferDescriptorPtr  pITD, 
        !          2247:        OHCIEndpointDescriptorPtr               pED)
        !          2248: {
        !          2249:        OHCIIsochTransferDescriptorPtr          pITDTemp;
        !          2250:        
        !          2251:        pITDTemp = OHCIUIMAllocateITD();
        !          2252:        pITD->dWord2 = pITDTemp->pPhysical;  // assign pitdnext to pitdtemp
        !          2253:        pED->pVirtualTailP = pITD->pVirtualNext = (UInt32) pITDTemp;
        !          2254:        SwapIsoc(pITD);
        !          2255:        pED->dWord1 = pITD->dWord2;                     // assign tail pointer to pitd next
        !          2256:        return (pITDTemp);
        !          2257: }
        !          2258: 
        !          2259: 
        !          2260: void SwapIsoc(OHCIIsochTransferDescriptorPtr pITD) 
        !          2261: {
        !          2262:        pITD->dWord0= EndianSwap32Bit(pITD->dWord0);
        !          2263:        pITD->dWord1= EndianSwap32Bit(pITD->dWord1);
        !          2264:        pITD->dWord2= EndianSwap32Bit(pITD->dWord2);
        !          2265:        pITD->dWord3= EndianSwap32Bit(pITD->dWord3);
        !          2266:        
        !          2267:        /* barry stuff BT 16bit words in right order, but each is swapped */
        !          2268:        pITD->offset[0] = EndianSwap16Bit(pITD->offset[0]);
        !          2269:        pITD->offset[1] = EndianSwap16Bit(pITD->offset[1]);
        !          2270:        pITD->offset[2] = EndianSwap16Bit(pITD->offset[2]);
        !          2271:        pITD->offset[3] = EndianSwap16Bit(pITD->offset[3]);
        !          2272:        pITD->offset[4] = EndianSwap16Bit(pITD->offset[4]);
        !          2273:        pITD->offset[5] = EndianSwap16Bit(pITD->offset[5]);
        !          2274:        pITD->offset[6] = EndianSwap16Bit(pITD->offset[6]);
        !          2275:        pITD->offset[7] = EndianSwap16Bit(pITD->offset[7]);
        !          2276: }
        !          2277: 
        !          2278: void trivialSwap( UInt32 *thing) {
        !          2279: 
        !          2280:        *thing = EndianSwap32Bit (*thing);
        !          2281: }
        !          2282: 
        !          2283: 
        !          2284: 
        !          2285: 
        !          2286: OSStatus
        !          2287: DoDoneQueueProcessing(OHCIGeneralTransferDescriptorPtr pHCDoneTD, Boolean immediateFlag)
        !          2288: {
        !          2289:        UInt32                                          control, transferStatus;
        !          2290:        long                                            bufferSizeRemaining;
        !          2291:        OHCIGeneralTransferDescriptorPtr
        !          2292:                                                                prevTD, nextTD;
        !          2293:        UInt32                                          PhysAddr;
        !          2294:        UInt32                                          pageSize;
        !          2295:        UInt32                                          pageMask;
        !          2296:        OHCIEndpointDescriptorPtr       tempED;
        !          2297:        OHCIRegistersPtr                        pOHCIRegisters;
        !          2298:        OHCIIsochTransferDescriptorPtr          pITD;
        !          2299: 
        !          2300: #pragma unused immediateFlag
        !          2301:        pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
        !          2302: 
        !          2303:        if(pHCDoneTD == nil)
        !          2304:        {       /* This should not happen */
        !          2305:                return(noErr);
        !          2306:        }
        !          2307: //     DebugStr ((ConstStr255Param) "DoDoneQueueProcessing");
        !          2308: 
        !          2309:        pageSize = pOHCIUIMData->pageSize;
        !          2310:        pageMask = ~(pageSize - 1);
        !          2311: 
        !          2312:        /* Reverse the done queue use only the virtual Address fields */
        !          2313:        prevTD = 0;
        !          2314:        while(pHCDoneTD != nil)
        !          2315:        {
        !          2316:                PhysAddr = (UInt32) EndianSwap32Bit(pHCDoneTD->dWord2) & kOHCIHeadPMask;
        !          2317:                nextTD = (OHCIGeneralTransferDescriptorPtr) OHCIUIMGetLogicalAddress (PhysAddr);
        !          2318:                pHCDoneTD->pVirtualNext = (UInt32)prevTD;
        !          2319:                prevTD = pHCDoneTD;
        !          2320:                pHCDoneTD = nextTD;
        !          2321:        }
        !          2322: //     DebugStr ((ConstStr255Param) "DoDoneQueueProcessing queue reversed");
        !          2323:        
        !          2324:        pHCDoneTD = prevTD;     /* New qHead */
        !          2325:        
        !          2326:        while (pHCDoneTD != nil) 
        !          2327:        {
        !          2328:                // find the next one
        !          2329:                nextTD  = (void *)pHCDoneTD->pVirtualNext;
        !          2330: 
        !          2331:                control = EndianSwap32Bit(pHCDoneTD->dWord0);
        !          2332:                transferStatus = (control & kOHCIGTDControl_CC) >> kOHCIGTDControl_CCPhase;
        !          2333:                if (pOHCIUIMData->OptiOn && (pHCDoneTD->pType == kOHCIOptiLSBug)) {
        !          2334:                        // clear any bad errors
        !          2335:                        tempED = (OHCIEndpointDescriptorPtr) pHCDoneTD->pEndpoint;
        !          2336:                        pHCDoneTD->dWord0 = pHCDoneTD->dWord0 & EndianSwap32Bit (kOHCIGTDClearErrorMask);
        !          2337:                        tempED->dWord2 &=  EndianSwap32Bit (kOHCIHeadPMask);
        !          2338:                        pHCDoneTD->dWord2 = tempED->dWord1 & EndianSwap32Bit (kOHCIHeadPMask); 
        !          2339:                        tempED->dWord1 = EndianSwap32Bit (pHCDoneTD->pPhysical);
        !          2340:                        pOHCIRegisters->hcCommandStatus = EndianSwap32Bit (kOHCIHcCommandStatus_CLF);
        !          2341: 
        !          2342:                // For CMD Buffer Underrun Errata
        !          2343:                } else if ((transferStatus == kOHCIGTDConditionBufferUnderrun) && 
        !          2344:                                                (pHCDoneTD->pType == kOHCIBulkTransferOutType) && 
        !          2345:                                                (pOHCIUIMData->errataBits & kErrataRetryBufferUnderruns)) {
        !          2346:                
        !          2347: 
        !          2348:                        tempED = (OHCIEndpointDescriptorPtr) pHCDoneTD->pEndpoint;
        !          2349:                        pHCDoneTD->dWord0 = pHCDoneTD->dWord0 & EndianSwap32Bit (kOHCIGTDClearErrorMask);
        !          2350:                        pHCDoneTD->dWord2 = tempED->dWord2 & EndianSwap32Bit (kOHCIHeadPMask); 
        !          2351:                        pHCDoneTD->pVirtualNext =  OHCIUIMGetLogicalAddress (EndianSwap32Bit (tempED->dWord3) & kOHCIHeadPMask);
        !          2352:                        
        !          2353:                        tempED->dWord2 = EndianSwap32Bit (pHCDoneTD->pPhysical) | 
        !          2354:                                                                                (tempED->dWord2 & EndianSwap32Bit( kOHCIEDToggleBitMask));
        !          2355:                        pOHCIRegisters->hcCommandStatus = EndianSwap32Bit (kOHCIHcCommandStatus_BLF);
        !          2356:                
        !          2357:                
        !          2358:                
        !          2359:                } else if (pHCDoneTD->pType == kOHCIIsochronousType) {
        !          2360:                        // cast to a isoc type
        !          2361:                        pITD = (OHCIIsochTransferDescriptorPtr) pHCDoneTD;
        !          2362:                        ProcessCompletedITD(pITD);
        !          2363:                        // deallocate td
        !          2364:                        OHCIUIMDeallocateITD(pITD);
        !          2365:                        
        !          2366:                } else {
        !          2367: 
        !          2368:                        if (pHCDoneTD->preparationID)
        !          2369:                                CheckpointIO(pHCDoneTD->preparationID, nil);
        !          2370:                        pHCDoneTD->preparationID = nil;
        !          2371:                        
        !          2372:                        bufferSizeRemaining = findBufferRemaining (pHCDoneTD);
        !          2373:                        if (pHCDoneTD->CallBack){
        !          2374:                                CallBackFuncPtr pCallBack;
        !          2375:                                // zero out callback first than call it
        !          2376:                                pCallBack = pHCDoneTD->CallBack;
        !          2377:                                pHCDoneTD->CallBack = nil;
        !          2378:                                (*pCallBack) (pHCDoneTD->refcon, transferStatus, bufferSizeRemaining);
        !          2379:                        } else if (transferStatus != nil) 
        !          2380:                                doCallback(pHCDoneTD, transferStatus, bufferSizeRemaining);
        !          2381: 
        !          2382:                        OHCIUIMDeallocateTD(pHCDoneTD);
        !          2383:                }
        !          2384:                pHCDoneTD = nextTD;     /* New qHead */
        !          2385:        }
        !          2386: 
        !          2387:        return(noErr);
        !          2388: }
        !          2389: 
        !          2390: 
        !          2391: 
        !          2392: void doCallback(
        !          2393:        OHCIGeneralTransferDescriptorPtr                        nextTD,
        !          2394:        UInt32                  transferStatus,
        !          2395:        UInt32                  bufferSizeRemaining) 
        !          2396: {
        !          2397:        OHCIGeneralTransferDescriptorPtr        pCurrentTD;
        !          2398:        OHCIEndpointDescriptorPtr                       pED;
        !          2399:        UInt32                                                          PhysAddr;
        !          2400:        
        !          2401:        pED = (OHCIEndpointDescriptorPtr) nextTD->pEndpoint;
        !          2402:        
        !          2403:        PhysAddr = (UInt32) EndianSwap32Bit(pED->dWord2) & kOHCIHeadPMask;
        !          2404:        nextTD = (OHCIGeneralTransferDescriptorPtr) OHCIUIMGetLogicalAddress (PhysAddr);
        !          2405: 
        !          2406:        pCurrentTD = (OHCIGeneralTransferDescriptorPtr) nextTD;
        !          2407:        while (pCurrentTD->pVirtualNext != nil) 
        !          2408:        {
        !          2409:        
        !          2410:                bufferSizeRemaining += findBufferRemaining (pCurrentTD);
        !          2411:                pCurrentTD->dWord1 = 0; // make sure this TD won't be added to any future buffer remaining calculations
        !          2412: 
        !          2413:                if (pCurrentTD->preparationID)
        !          2414:                        CheckpointIO(pCurrentTD->preparationID, nil);
        !          2415:                pCurrentTD->preparationID = nil;  // make sure we don't try to do another CheckpointIO later
        !          2416: 
        !          2417:                if (pCurrentTD->CallBack!=nil) {
        !          2418:                        CallBackFuncPtr pCallBack;
        !          2419:                        // zero out callback first than call it
        !          2420:                        pCallBack = pCurrentTD->CallBack;
        !          2421:                        pCurrentTD->CallBack = nil;
        !          2422:                        (*pCallBack) (pCurrentTD->refcon, transferStatus, bufferSizeRemaining);
        !          2423:                        bufferSizeRemaining = nil;
        !          2424:                        return;
        !          2425:                }
        !          2426:                
        !          2427:                pCurrentTD = (OHCIGeneralTransferDescriptorPtr) pCurrentTD->pVirtualNext;
        !          2428:        }
        !          2429: }
        !          2430: 
        !          2431: 
        !          2432: UInt32 findBufferRemaining (OHCIGeneralTransferDescriptorPtr pCurrentTD)
        !          2433: {
        !          2434:        UInt32                                          pageSize;
        !          2435:        UInt32                                          pageMask;
        !          2436:        UInt32                                          bufferSizeRemaining;
        !          2437:        pageSize = pOHCIUIMData->pageSize;
        !          2438:        pageMask = ~(pageSize - 1);
        !          2439: 
        !          2440:                if (pCurrentTD->dWord1 == 0){
        !          2441:                        bufferSizeRemaining = 0;
        !          2442:                }else if ((EndianSwap32Bit(pCurrentTD->dWord3) & (pageMask)) == 
        !          2443:                                                (EndianSwap32Bit(pCurrentTD->dWord1)& (pageMask))) {
        !          2444:                        // we're on the same page
        !          2445:                        bufferSizeRemaining = (EndianSwap32Bit (pCurrentTD->dWord3) & ~pageMask) - 
        !          2446:                                                                        (EndianSwap32Bit (pCurrentTD->dWord1) & ~pageMask) + 1;
        !          2447:                } else {
        !          2448:                        bufferSizeRemaining = ((EndianSwap32Bit(pCurrentTD->dWord3) & ~pageMask) + 1)  +  
        !          2449:                                                                        (pageSize - (EndianSwap32Bit(pCurrentTD->dWord1) & ~pageMask));
        !          2450:                }
        !          2451: 
        !          2452:        return (bufferSizeRemaining);
        !          2453: }
        !          2454: 
        !          2455: 
        !          2456: OSStatus OHCIUIMControlInitialize () 
        !          2457: {
        !          2458:        OHCIRegistersPtr                        pOHCIRegisters;
        !          2459:        OHCIEndpointDescriptorPtr       pED, pED2;
        !          2460: 
        !          2461: 
        !          2462:        pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
        !          2463:        
        !          2464:        // Create ED mark it skipped and assign it to ControlTail
        !          2465:        pED = OHCIUIMAllocateED();
        !          2466:        pED->dWord0 = EndianSwap32Bit (kOHCIEDControl_K);
        !          2467:        pOHCIUIMData->pControlTail = (UInt32) pED;
        !          2468: //kprintf("OHCIUIMControlInitialize:pOHCIUIMData->pControlTail=0x%x\n",pED);   
        !          2469:        // Create ED mark it skipped and assign it to control head
        !          2470:        pED2 = OHCIUIMAllocateED();
        !          2471:        pED2->dWord0 = EndianSwap32Bit (kOHCIEDControl_K);
        !          2472:        pOHCIUIMData->pControlHead = (UInt32) pED2;
        !          2473: //kprintf("OHCIUIMControlInitialize:pOHCIUIMData->pControlHead=0x%x\n",pED2);  
        !          2474:        pOHCIRegisters->hcControlHeadED = EndianSwap32Bit ((UInt32) pED2->pPhysical);
        !          2475:        
        !          2476:        // have bulk head ED point to Control tail ED
        !          2477:        pED2->dWord3 = EndianSwap32Bit ((UInt32) pED->pPhysical);
        !          2478:        pED2->pVirtualNext = (UInt32) pED;
        !          2479: //kprintf("OHCIUIMControlInitialize:pOHCIUIMData->pControlHead->pVirtualNext=0x%x\n",pED);     
        !          2480:        return (0);
        !          2481: }
        !          2482: 
        !          2483: 
        !          2484: OSStatus OHCIUIMBulkInitialize (){
        !          2485: 
        !          2486:        OHCIRegistersPtr                        pOHCIRegisters;
        !          2487:        OHCIEndpointDescriptorPtr       pED, pED2;
        !          2488: 
        !          2489: 
        !          2490:        pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
        !          2491:        
        !          2492:        // Create ED mark it skipped and assign it to bulkTail
        !          2493:        pED = OHCIUIMAllocateED();
        !          2494:        pED->dWord0 = EndianSwap32Bit (kOHCIEDControl_K);
        !          2495:        pOHCIUIMData->pBulkTail = (UInt32) pED;
        !          2496:        
        !          2497:        // Create ED mark it skipped and assign it to bulk head
        !          2498:        pED2 = OHCIUIMAllocateED();
        !          2499:        pED2->dWord0 = EndianSwap32Bit (kOHCIEDControl_K);
        !          2500:        pOHCIUIMData->pBulkHead = (UInt32) pED2;
        !          2501:        pOHCIRegisters->hcBulkHeadED = EndianSwap32Bit ((UInt32) pED2->pPhysical);
        !          2502:        
        !          2503:        // have bulk head ED point to Bulk tail ED
        !          2504:        pED2->dWord3 = EndianSwap32Bit ((UInt32) pED->pPhysical);
        !          2505:        pED2->pVirtualNext = (UInt32) pED;
        !          2506:        return (0);
        !          2507: 
        !          2508: }
        !          2509: 
        !          2510: OSStatus OHCIUIMIsochronousInitialize()
        !          2511: {
        !          2512: 
        !          2513:        OHCIRegistersPtr                        pOHCIRegisters;
        !          2514:        OHCIEndpointDescriptorPtr       pED, pED2;
        !          2515: 
        !          2516: 
        !          2517:        pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
        !          2518:        
        !          2519:        // Create ED mark it skipped and assign it to bulkTail
        !          2520:        pED = OHCIUIMAllocateED();
        !          2521:        pED->dWord0 = EndianSwap32Bit (kOHCIEDControl_K);
        !          2522:        pOHCIUIMData->pIsochTail = (UInt32) pED;
        !          2523:        
        !          2524:        // Create ED mark it skipped and assign it to bulk head
        !          2525:        pED2 = OHCIUIMAllocateED();
        !          2526:        pED2->dWord0 = EndianSwap32Bit (kOHCIEDControl_K);
        !          2527:        pOHCIUIMData->pIsochHead = (UInt32) pED2;
        !          2528:        
        !          2529: 
        !          2530:        // have bulk head ED point to Bulk tail ED
        !          2531:        pED2->dWord3 = EndianSwap32Bit ((UInt32) pED->pPhysical);
        !          2532:        pED2->pVirtualNext = (UInt32) pED;
        !          2533:        return (0);
        !          2534: 
        !          2535: }
        !          2536: 
        !          2537: //Initializes the HCCA Interrupt list with statically 
        !          2538: //disabled ED's to form the Interrupt polling queues
        !          2539: OSStatus OHCIUIMInterruptInitialize ()
        !          2540: {
        !          2541: 
        !          2542:        OHCIRegistersPtr                        pOHCIRegisters;
        !          2543:        OHCIIntHeadPtr                          pInterruptHead;
        !          2544:        OSStatus                                        status = 0;
        !          2545:        UInt32                                          dummyControl;
        !          2546:        int                                                     i, p, q, z;
        !          2547:        OHCIEndpointDescriptorPtr       pED, pIsochHead;        
        !          2548:        
        !          2549:        
        !          2550:        pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
        !          2551:        pInterruptHead = pOHCIUIMData->pInterruptHead;
        !          2552:        
        !          2553:        // create UInt32 with same dword0 for use with searching and tracking, skip should be set, and open area shouldbe marked
        !          2554:        dummyControl = kOHCIEDControl_K;
        !          2555:        dummyControl |= 0;   //should be kOHCIFakeED
        !          2556:        dummyControl = EndianSwap32Bit (dummyControl);
        !          2557:        pIsochHead = (OHCIEndpointDescriptorPtr) pOHCIUIMData->pIsochHead;
        !          2558:        
        !          2559:        //do 31 times
        !          2560:        // change to 65 and make isoch head the last one.?????
        !          2561:        for (i = 0; i < 63; i++)
        !          2562:        { 
        !          2563:                //allocate Endpoint descriptor
        !          2564:                pED = OHCIUIMAllocateED();
        !          2565:                if (pED == nil){
        !          2566:                        status = -1;
        !          2567:                        return (status);
        !          2568:                }
        !          2569:                //mark skipped,some how mark as a False endpoint zzzzz
        !          2570:                else {
        !          2571: 
        !          2572:                        pED->dWord0 = dummyControl;
        !          2573:                        pInterruptHead[i].pHead = pED;
        !          2574:                        pInterruptHead[i].pHeadPhysical = pED->pPhysical;
        !          2575:                        pInterruptHead[i].nodeBandwidth = 0;
        !          2576:                }
        !          2577:                if ( i < 32)
        !          2578:                        ((UInt32 *)pOHCIUIMData->pHCCA)[i] = (UInt32) EndianSwap32Bit ((UInt32) pInterruptHead[i].pHeadPhysical);
        !          2579: 
        !          2580:        }
        !          2581:        
        !          2582:        p = 0;
        !          2583:        q = 32;
        !          2584:        //
        !          2585:        for (i = 0; i < (32 +16 + 8 + 4 + 2); i++)
        !          2586:        {
        !          2587:                if (i < q/2+p)
        !          2588:                        z = i + q;
        !          2589:                else
        !          2590:                        z = i + q/2;
        !          2591:                if (i == p+q-1)
        !          2592:                {
        !          2593:                        p = p + q;
        !          2594:                        q = q/2;
        !          2595:                }
        !          2596:                //point endpoint descriptor to corresponding 8ms descriptor
        !          2597:                pED = pInterruptHead[i].pHead;
        !          2598:                pED->dWord3 =  EndianSwap32Bit (pInterruptHead[z].pHeadPhysical);
        !          2599:                pED->pVirtualNext = (UInt32) pInterruptHead[z].pHead;
        !          2600:                pInterruptHead[i].pTail = (OHCIEndpointDescriptorPtr) pED->pVirtualNext;
        !          2601: 
        !          2602:        }
        !          2603:        i = 62;
        !          2604:        pED = pInterruptHead[i].pHead;
        !          2605:        pED->dWord3 = EndianSwap32Bit (pIsochHead->pPhysical);
        !          2606:        pED->pVirtualNext = (UInt32) pOHCIUIMData->pIsochHead;
        !          2607:        pInterruptHead[i].pTail = (OHCIEndpointDescriptorPtr) pED->pVirtualNext;
        !          2608: 
        !          2609:        // point Isochronous head to last endpoint 
        !          2610: 
        !          2611:                
        !          2612:        return (status);
        !          2613: }
        !          2614: 
        !          2615: /*
        !          2616: // determines the best fit for the interrupt  ED
        !          2617: OSStatus OHCIUIMInterruptschedule()
        !          2618: {
        !          2619: }
        !          2620: 
        !          2621: 
        !          2622: //determines whether or not the ED can fit
        !          2623: OSStatus OHCIUIMInterruptfits()
        !          2624: {
        !          2625: }
        !          2626: 
        !          2627: // determines the worst and best bandwidth
        !          2628: // for use with scheduling periodic ed's
        !          2629: OSStatus OHCIUIMInterruptBandwidthCheck()
        !          2630: 
        !          2631: {
        !          2632: }
        !          2633: 
        !          2634: //Finds an ED in the interrupt queue
        !          2635: OSStatus OHCIUIMInterruptFindED()
        !          2636: {
        !          2637: }
        !          2638: */
        !          2639: //Allocate 
        !          2640: OSStatus OHCIUIMAllocateMemory (
        !          2641:        int                                                             num_of_TDs,
        !          2642:        int                                                                     num_of_EDs,
        !          2643:        int                                                                     num_of_ITDs)
        !          2644: {      
        !          2645:        OSStatus                                                        status;
        !          2646:        Ptr                                                                     p;
        !          2647:        UInt32                                                          physical;
        !          2648:        int                                                                     tdsPage,pagesTD,edsPage,pagesED, itdsPage, pagesITD;
        !          2649:        UInt32                                                          pageSize;
        !          2650:        OHCIEndpointDescriptorPtr                       FreeED, FreeEDCurrent;
        !          2651:        OHCIGeneralTransferDescriptorPtr        FreeTD, FreeTDCurrent;
        !          2652:        OHCIIsochTransferDescriptorPtr          FreeITD, FreeITDCurrent;
        !          2653:        int                                                                     i,j;
        !          2654:        
        !          2655:        
        !          2656:        pageSize = pOHCIUIMData->pageSize;
        !          2657: kprintf("pgsize=%d,sizes=%d,%d,%d\n",pageSize,sizeof(OHCIGeneralTransferDescriptor),sizeof(OHCIEndpointDescriptor),sizeof(OHCIIsochTransferDescriptor));
        !          2658: 
        !          2659: 
        !          2660:        tdsPage = pageSize/sizeof (OHCIGeneralTransferDescriptor);
        !          2661:        pagesTD = num_of_TDs /tdsPage +1;
        !          2662:        edsPage = pageSize/sizeof (OHCIEndpointDescriptor);
        !          2663:        pagesED = num_of_EDs/edsPage +1;
        !          2664:        itdsPage = pageSize/sizeof (OHCIIsochTransferDescriptor);
        !          2665:        pagesITD = num_of_ITDs /itdsPage +1;
        !          2666: 
        !          2667:        // use pool allocate to allocate a large sum of memory  zzzzz why plus 3???
        !          2668: 
        !          2669: kprintf("trying to allocate %d+%d+%d+1 * %d\n",pagesED,pagesTD,pagesITD,pageSize);      
        !          2670: p = Desc_Buffer_Usb;
        !          2671: 
        !          2672: kprintf("kalloc p=0x%x\n",p);
        !          2673: 
        !          2674: //naga         pOHCIUIMData->pDataAllocation = p;
        !          2675:        //page align and 16 byte align(page align automagically makes it 16 byte aligned)
        !          2676:        p = (Ptr) (((UInt32) p + (pageSize - 1)) & ~(pageSize - 1));    // page-align
        !          2677: 
        !          2678:        // use prepare mem for IO to find physical address
        !          2679:        physical = OHCIUIMGetPhysicalAddress((UInt32) p, pagesED+pagesTD+pagesITD);
        !          2680: 
        !          2681:        // create a list of unused ED's, filling in Virtual address, physicaladdress and virtual next
        !          2682:        // physical next.
        !          2683:        FreeED = (OHCIEndpointDescriptorPtr) p;
        !          2684:        FreeEDCurrent = FreeED;
        !          2685:        pOHCIUIMData->pFreeED = FreeED;
        !          2686: 
        !          2687:        
        !          2688:        for (i = 0;i<pagesED;i++)
        !          2689:        {
        !          2690:                for (j = 0; j < edsPage; j++)
        !          2691:                {
        !          2692:                        //create EDs
        !          2693:                        FreeEDCurrent[j].pPhysical = physical + (j *sizeof (OHCIEndpointDescriptor));
        !          2694:                        FreeEDCurrent[j].pVirtualNext = (UInt32) (&FreeEDCurrent[j+1]);
        !          2695:                }
        !          2696:                if (i != (pagesED - 1)){
        !          2697:                        FreeEDCurrent[j-1].pVirtualNext =  ((UInt32) FreeEDCurrent + pageSize);
        !          2698:                } else {
        !          2699:                        FreeEDCurrent[j-1].pVirtualNext = nil;
        !          2700:                        pOHCIUIMData->pLastFreeED = &FreeEDCurrent[j-1];
        !          2701:                }
        !          2702:                        
        !          2703:                // goto next page
        !          2704:                FreeEDCurrent = (OHCIEndpointDescriptorPtr) ((UInt32) FreeEDCurrent + pageSize);
        !          2705:                physical += pageSize;
        !          2706:        }
        !          2707:        FreeTD = (OHCIGeneralTransferDescriptorPtr) FreeEDCurrent;
        !          2708:        FreeTDCurrent = FreeTD;
        !          2709:        pOHCIUIMData->pFreeTD = FreeTD;
        !          2710:        for (i = 0;i<pagesTD;i++)
        !          2711:        {
        !          2712:                for (j = 0; j < tdsPage; j++)
        !          2713:                {
        !          2714:                        //create TDs
        !          2715:                        FreeTDCurrent[j].pPhysical = physical + (j * sizeof (OHCIGeneralTransferDescriptor));
        !          2716:                        FreeTDCurrent[j].pVirtualNext = (UInt32) (&FreeTDCurrent[j+1]);
        !          2717: 
        !          2718:                }
        !          2719:                if (i != (pagesTD - 1)){ 
        !          2720:                        FreeTDCurrent[j-1].pVirtualNext = ((UInt32) FreeTDCurrent + pageSize);
        !          2721:                } else {
        !          2722:                        FreeTDCurrent[j-1].pVirtualNext = nil;
        !          2723:                        pOHCIUIMData->pLastFreeTD = &FreeTDCurrent[j-1];
        !          2724:                }
        !          2725:                        
        !          2726:                // goto next page
        !          2727:                FreeTDCurrent = (OHCIGeneralTransferDescriptorPtr) ((UInt32) FreeTDCurrent + pageSize);
        !          2728:                physical += pageSize;
        !          2729: 
        !          2730:        }
        !          2731:        
        !          2732:        
        !          2733:        // set up freeitd queue
        !          2734:        FreeITD = (OHCIIsochTransferDescriptorPtr) FreeTDCurrent;
        !          2735:        FreeITDCurrent = FreeITD;
        !          2736:        pOHCIUIMData->pFreeITD = FreeITD;
        !          2737:        for (i = 0;i<pagesTD;i++)
        !          2738:        {
        !          2739:                for (j = 0; j < tdsPage; j++)
        !          2740:                {
        !          2741:                        //create TDs
        !          2742:                        FreeITDCurrent[j].pPhysical = physical + (j * sizeof (OHCIIsochTransferDescriptor));
        !          2743:                        FreeITDCurrent[j].pVirtualNext = (UInt32) (&FreeITDCurrent[j+1]);
        !          2744: 
        !          2745:                }
        !          2746:                if (i != (pagesITD - 1)){ 
        !          2747:                        FreeITDCurrent[j-1].pVirtualNext = ((UInt32) FreeITDCurrent + pageSize);
        !          2748:                } else {
        !          2749:                        FreeITDCurrent[j-1].pVirtualNext = nil;
        !          2750:                        pOHCIUIMData->pLastFreeITD = &FreeITDCurrent[j-1];
        !          2751:                }
        !          2752:                        
        !          2753:                // goto next page
        !          2754:                FreeITDCurrent = (OHCIIsochTransferDescriptorPtr) ((UInt32) FreeITDCurrent + pageSize);
        !          2755:                physical += pageSize;
        !          2756: 
        !          2757:        }
        !          2758:                
        !          2759:        // create a list of unused buffers?????
        !          2760:        
        !          2761:        return (status);
        !          2762:        
        !          2763: }
        !          2764: 
        !          2765: OHCIIsochTransferDescriptorPtr OHCIUIMAllocateITD()
        !          2766: 
        !          2767: {
        !          2768:        OHCIIsochTransferDescriptorPtr temp, FreeTD;
        !          2769:        
        !          2770: // pop a TD off of FreeTD list
        !          2771: //if FreeTD == NIL return nil
        !          2772: // should we check if ED is full and if not access that????
        !          2773:        temp = FreeTD = pOHCIUIMData->pFreeITD;
        !          2774: 
        !          2775:        if (FreeTD != nil)
        !          2776:        {        
        !          2777:                pOHCIUIMData->pFreeITD = (OHCIIsochTransferDescriptorPtr) FreeTD->pVirtualNext;
        !          2778:        } else {
        !          2779:                AssertDebugStr("OHCIUIM: Out of Transfer Descriptors!  ");
        !          2780:        }
        !          2781:        
        !          2782:        /* BT, I think I need to do this here */
        !          2783:        temp->pType = kOHCIIsochronousType;
        !          2784: 
        !          2785:        return (temp);
        !          2786: 
        !          2787: }
        !          2788: 
        !          2789: OHCIGeneralTransferDescriptorPtr OHCIUIMAllocateTD()
        !          2790: 
        !          2791: {
        !          2792:        OHCIGeneralTransferDescriptorPtr temp, FreeTD;
        !          2793:        
        !          2794: // pop a TD off of FreeTD list
        !          2795: //if FreeTD == NIL return nil
        !          2796: // should we check if ED is full and if not access that????
        !          2797:        temp = FreeTD = pOHCIUIMData->pFreeTD;
        !          2798: 
        !          2799:        if (FreeTD != nil)
        !          2800:        {        
        !          2801:                pOHCIUIMData->pFreeTD = (OHCIGeneralTransferDescriptorPtr) FreeTD->pVirtualNext;
        !          2802:                temp->pVirtualNext = nil;
        !          2803:        } else {
        !          2804:                AssertDebugStr("OHCIUIM: Out of Transfer Descriptors!  ");
        !          2805:        }
        !          2806:        return (temp);
        !          2807: 
        !          2808: }
        !          2809: 
        !          2810: OHCIEndpointDescriptorPtr OHCIUIMAllocateED()
        !          2811: {
        !          2812:        OHCIEndpointDescriptorPtr temp, FreeED;
        !          2813:        
        !          2814: 
        !          2815:        // Pop a ED off the FreeED list
        !          2816:        // If FreeED == nil return Error
        !          2817:        temp = FreeED = (OHCIEndpointDescriptorPtr) pOHCIUIMData->pFreeED;
        !          2818: 
        !          2819:        if (pOHCIUIMData->pFreeED != nil)
        !          2820:        {        
        !          2821:                pOHCIUIMData->pFreeED = (OHCIEndpointDescriptorPtr) FreeED->pVirtualNext;
        !          2822:                temp->pVirtualNext = nil;
        !          2823:        } else {
        !          2824:                AssertDebugStr("OHCIUIM: Out of Endpoint Descriptors!  ");
        !          2825:        }
        !          2826:        return (temp);
        !          2827: }
        !          2828: 
        !          2829: OSStatus OHCIUIMDeallocateITD (
        !          2830:        OHCIIsochTransferDescriptorPtr pTD)
        !          2831: {
        !          2832:        UInt32                                                          physical;
        !          2833: 
        !          2834:        //zero out all unnecessary fields
        !          2835:        physical = pTD->pPhysical;
        !          2836:        BlockZero(pTD, sizeof(*pTD));
        !          2837:        pTD->pPhysical = physical;
        !          2838:        pTD->pType = kOHCIIsochronousType;
        !          2839:        if (pOHCIUIMData->pFreeITD){
        !          2840:                pOHCIUIMData->pLastFreeITD->pVirtualNext = (UInt32)pTD;
        !          2841:                pOHCIUIMData->pLastFreeITD = pTD;
        !          2842:        } else {
        !          2843:                // list is currently empty
        !          2844:                pOHCIUIMData->pLastFreeITD = pTD;
        !          2845:                pOHCIUIMData->pFreeITD = pTD;
        !          2846:        }
        !          2847:        return (0);
        !          2848: }
        !          2849: 
        !          2850: 
        !          2851: OSStatus OHCIUIMDeallocateTD (
        !          2852:        OHCIGeneralTransferDescriptorPtr pTD)
        !          2853: {
        !          2854:        UInt32                                          physical;
        !          2855: 
        !          2856:        //zero out all unnecessary fields
        !          2857:        physical = pTD->pPhysical;
        !          2858:        BlockZero(pTD, sizeof(*pTD));
        !          2859:        pTD->pPhysical = physical;
        !          2860:        
        !          2861:        if (pOHCIUIMData->pFreeTD){
        !          2862:                pOHCIUIMData->pLastFreeTD->pVirtualNext = (UInt32)pTD;
        !          2863:                pOHCIUIMData->pLastFreeTD = pTD;
        !          2864:        } else {
        !          2865:                // list is currently empty
        !          2866:                pOHCIUIMData->pLastFreeTD = pTD;
        !          2867:                pOHCIUIMData->pFreeTD = pTD;
        !          2868:        }
        !          2869:        return (0);
        !          2870: }
        !          2871: 
        !          2872: OSStatus OHCIUIMDeallocateED (
        !          2873:        OHCIEndpointDescriptorPtr pED)
        !          2874: {
        !          2875:        UInt32                                          physical;
        !          2876: 
        !          2877:        //zero out all unnecessary fields
        !          2878:        physical = pED->pPhysical;
        !          2879:        BlockZero(pED, sizeof(*pED));
        !          2880:        pED->pPhysical = physical;
        !          2881: 
        !          2882:        if (pOHCIUIMData->pFreeED){
        !          2883:                pOHCIUIMData->pLastFreeED->pVirtualNext = (UInt32)pED;
        !          2884:                pOHCIUIMData->pLastFreeED = pED;
        !          2885:        } else {
        !          2886:                // list is currently empty
        !          2887:                pOHCIUIMData->pLastFreeED = pED;
        !          2888:                pOHCIUIMData->pFreeED = pED;
        !          2889:        }
        !          2890:        return (0);
        !          2891: }
        !          2892: /*
        !          2893:        
        !          2894: OSStatus OHCIUIMAllocateBuffer()
        !          2895: {}
        !          2896: */
        !          2897: 
        !          2898: 
        !          2899: ////////////////////////////////////////////////////////////////////////////////
        !          2900: //
        !          2901: //             UInt32 OHCIUIMGetLogicalAddress
        !          2902: //             Given the physical address, return the virtual address
        !          2903: //
        !          2904: 
        !          2905: UInt32 OHCIUIMGetLogicalAddress (
        !          2906:        UInt32                          pPhysicalAddress)
        !          2907: {
        !          2908:        OHCIPhysicalLogicalPtr          pPhysicalLogical;
        !          2909:        UInt32                                          LogicalAddress = nil;
        !          2910:                
        !          2911:        if (pPhysicalAddress == 0)
        !          2912:                return(0);
        !          2913: 
        !          2914:        pPhysicalLogical = pOHCIUIMData->pPhysicalLogical;
        !          2915:                
        !          2916:        while (pPhysicalLogical != nil) {
        !          2917:                if (pPhysicalAddress <= pPhysicalLogical->PhysicalEnd 
        !          2918:                                && pPhysicalAddress >= pPhysicalLogical->PhysicalStart) 
        !          2919:                {
        !          2920:                        LogicalAddress = pPhysicalLogical->LogicalStart + (pPhysicalAddress - pPhysicalLogical->PhysicalStart);
        !          2921:                        pPhysicalLogical = nil;
        !          2922:                } else {
        !          2923:                        pPhysicalLogical = (OHCIPhysicalLogicalPtr) pPhysicalLogical->pNext;
        !          2924:                }
        !          2925:        }
        !          2926:        
        !          2927:        if ( LogicalAddress == nil) 
        !          2928:                AssertDebugStr("OHCIUIM: LogicalAddress == nil !");
        !          2929: 
        !          2930:        return (LogicalAddress);
        !          2931: 
        !          2932: }
        !          2933:                
        !          2934: 
        !          2935: UInt32 OHCIUIMGetPhysicalAddress(
        !          2936:        UInt32                                          LogicalAddress,
        !          2937:        UInt32                                          count)
        !          2938: {
        !          2939:        OHCIPhysicalLogicalPtr          pPhysicalLogical;
        !          2940:        UInt32                                          PhysicalAddress = nil;
        !          2941:                
        !          2942:        if (LogicalAddress == 0)
        !          2943:                return(0);
        !          2944: 
        !          2945:        pPhysicalLogical = pOHCIUIMData->pPhysicalLogical;
        !          2946:                
        !          2947:        while (pPhysicalLogical != nil) {
        !          2948:                if (LogicalAddress <= pPhysicalLogical->LogicalEnd 
        !          2949:                                && LogicalAddress >= pPhysicalLogical->LogicalStart) 
        !          2950:                {
        !          2951:                        PhysicalAddress = pPhysicalLogical->PhysicalStart + (LogicalAddress - pPhysicalLogical->LogicalStart);
        !          2952:                        pPhysicalLogical = nil;
        !          2953:                } else {
        !          2954:                        pPhysicalLogical = (OHCIPhysicalLogicalPtr) pPhysicalLogical->pNext;
        !          2955:                }
        !          2956:        }
        !          2957: 
        !          2958:        if (PhysicalAddress == nil)
        !          2959:                PhysicalAddress = OHCIUIMCreatePhysicalAddress(LogicalAddress, count);
        !          2960:                
        !          2961:        return (PhysicalAddress);
        !          2962: }
        !          2963:                
        !          2964: UInt32 OHCIUIMCreatePhysicalAddress(
        !          2965:        UInt32                                          pLogicalAddress,
        !          2966:        UInt32                                          count)
        !          2967: 
        !          2968: {
        !          2969:        UInt32                                          pageSize;
        !          2970:        PhysicalMappingTablePtr         physicalAddressTable;
        !          2971:        OHCIPhysicalLogicalPtr          pPhysicalLogical;
        !          2972:        IOPreparationTable                      *ioPrep;
        !          2973:        IOPreparationTable                      IOPrep;
        !          2974:        OSStatus                                        status;
        !          2975:        OHCIPhysicalLogicalPtr          p;
        !          2976:        
        !          2977:        pPhysicalLogical = pOHCIUIMData->pPhysicalLogical;
        !          2978:        pageSize = pOHCIUIMData->pageSize;
        !          2979:        
        !          2980:        // zzzzz - revisit this regarding the size of the table  do we deallocate this?
        !          2981:        physicalAddressTable = (PhysicalMappingTablePtr)PoolAllocateResident((count)*sizeof(UInt32), false);
        !          2982: 
        !          2983:        // zzz do we deallocate this?
        !          2984:        p = (OHCIPhysicalLogicalPtr) PoolAllocateResident (sizeof (OHCIPhysicalLogical), true);
        !          2985: 
        !          2986:        p->LogicalStart =  pLogicalAddress;
        !          2987:        p->PhysicalStart = kvtophys((vm_offset_t)pLogicalAddress);
        !          2988:        p->LogicalEnd = p->LogicalStart + count*pageSize-1;
        !          2989:        p->PhysicalEnd = p->PhysicalStart + count*pageSize-1;
        !          2990:        p->pNext = nil;
        !          2991: 
        !          2992:        //now put it all in a table 
        !          2993:        if (pPhysicalLogical == nil) 
        !          2994:        {
        !          2995:                pPhysicalLogical = p;
        !          2996:        } else {
        !          2997:                //traverse Queue
        !          2998:                while (pPhysicalLogical->pNext != nil) 
        !          2999:                {
        !          3000:                        pPhysicalLogical = (OHCIPhysicalLogicalPtr) pPhysicalLogical->pNext;
        !          3001:                }
        !          3002:                pPhysicalLogical->pNext = (UInt32) p;
        !          3003:        }
        !          3004:        pOHCIUIMData->pPhysicalLogical = pPhysicalLogical;
        !          3005: 
        !          3006:        return (p->PhysicalStart);
        !          3007: }
        !          3008: 
        !          3009: 
        !          3010: 
        !          3011: static void returnTransactions(OHCIGeneralTransferDescriptor *transaction, UInt32 tail)
        !          3012: {
        !          3013:        UInt32                                                  physicalAddress;
        !          3014:        OHCIGeneralTransferDescriptor   *nextTransaction;
        !          3015:        
        !          3016:        while(transaction->pPhysical != tail)
        !          3017:        {
        !          3018:                if(transaction == nil)
        !          3019:                {
        !          3020:                        AssertDebugStr("Return queue broken");
        !          3021:                        break;
        !          3022:                }
        !          3023:                else
        !          3024:                {
        !          3025:                        if (transaction->preparationID)
        !          3026:                                CheckpointIO(transaction->preparationID, nil);
        !          3027:                        transaction->preparationID = nil;
        !          3028: 
        !          3029:                        if (transaction->CallBack) {
        !          3030:                                CallBackFuncPtr pCallBack;
        !          3031:                                // zero out callback first than call it
        !          3032:                                pCallBack = transaction->CallBack;
        !          3033:                                transaction->CallBack = nil;
        !          3034:                                (*pCallBack) (transaction->refcon, returnedErr, 0);
        !          3035:                        }
        !          3036:                        /* walk the physically-addressed list */
        !          3037:                        physicalAddress = (UInt32) EndianSwap32Bit(transaction->dWord2) & kOHCIHeadPMask;
        !          3038:                        nextTransaction = (OHCIGeneralTransferDescriptorPtr) OHCIUIMGetLogicalAddress (physicalAddress);
        !          3039:                        OHCIUIMDeallocateTD(transaction);
        !          3040:                        transaction = nextTransaction;
        !          3041:                }
        !          3042:        }
        !          3043: }
        !          3044: 
        !          3045: 
        !          3046: OSStatus OHCIUIMClearEndPointStall(
        !          3047:        short                                           functionNumber,
        !          3048:        short                                           endpointNumber,
        !          3049:        short                                           direction)
        !          3050: {
        !          3051:        OHCIRegistersPtr                        pOHCIRegisters;
        !          3052:        OSStatus                                        status = noErr;
        !          3053:        OHCIEndpointDescriptorPtr       pEDQueueBack, pED;
        !          3054:        OHCIGeneralTransferDescriptor    *transaction;
        !          3055:        UInt32 tail, controlMask;
        !          3056: 
        !          3057: 
        !          3058:        if (pOHCIUIMData->rootHubFuncAddress == functionNumber) 
        !          3059:                return (status);
        !          3060: 
        !          3061:        if (direction == kUSBOut)
        !          3062:                direction = kOHCIEDDirectionOut;
        !          3063:        else if (direction == kUSBIn) 
        !          3064:                direction = kOHCIEDDirectionIn;
        !          3065:        else
        !          3066:                direction = kOHCIEDDirectionTD;
        !          3067: 
        !          3068:        pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
        !          3069:        
        !          3070:        transaction = nil;
        !          3071:        tail = nil;
        !          3072: kprintf("OHCIUIMClear EPS:calling FindEndpoint\n");
        !          3073:        if((pED = FindEndpoint (functionNumber, endpointNumber, direction, &pEDQueueBack, &controlMask)) == nil)
        !          3074:                return(kUSBNotFound);
        !          3075: 
        !          3076:        if (pED != nil) {
        !          3077:                tail = EndianSwap32Bit(pED->dWord1);
        !          3078:                transaction = (void *)OHCIUIMGetLogicalAddress(EndianSwap32Bit(pED->dWord2) & kOHCIHeadPMask);
        !          3079:                pED->dWord2 = pED->dWord1;      /* unlink all transactions at once (this also clears the halted bit) */
        !          3080:                pED->pVirtualHeadP = pED->pVirtualTailP; 
        !          3081:        }       
        !          3082: 
        !          3083:        if (transaction != nil){
        !          3084:                returnTransactions(transaction, tail);
        !          3085:        }
        !          3086:        return (status);
        !          3087: }
        !          3088: 
        !          3089: OHCIEndpointDescriptorPtr FindControlEndpoint (
        !          3090:        short                                           functionNumber, 
        !          3091:        short                                           endpointNumber, 
        !          3092:        OHCIEndpointDescriptorPtr   *pEDBack)
        !          3093: {
        !          3094:        UInt32                                          unique;
        !          3095:        OHCIEndpointDescriptorPtr       pEDQueue;
        !          3096:        OHCIEndpointDescriptorPtr       pEDQueueBack;
        !          3097: 
        !          3098:        
        !          3099:        //search for endpoint descriptor
        !          3100:        unique = (UInt32) ((((UInt32) endpointNumber) << kOHCIEndpointNumberOffset) | ((UInt32) functionNumber));
        !          3101:        pEDQueueBack = (OHCIEndpointDescriptorPtr) pOHCIUIMData->pControlHead;
        !          3102:        pEDQueue = (OHCIEndpointDescriptorPtr) pEDQueueBack->pVirtualNext;
        !          3103: //kprintf("FindControlEp:pOHCIUIMData->pControlHead=0x%x,pEDQ=pOHCIUIMData->pControlHead->pVirtualNext=0x%x,pOHCIUIMData->pControlTail=0x%x\n",pEDQueueBack,pEDQueue,pOHCIUIMData->pControlTail);
        !          3104: 
        !          3105:        while ((UInt32) pEDQueue != pOHCIUIMData->pControlTail) 
        !          3106:        {
        !          3107: //kprintf("FindControlEp:searching for %d(unique),dword0=%d\n",unique, (EndianSwap32Bit(pEDQueue->dWord0) & kUniqueNumNoDirMask));
        !          3108:                if ( (EndianSwap32Bit(pEDQueue->dWord0) & kUniqueNumNoDirMask) == unique) {
        !          3109:                        *pEDBack = pEDQueueBack;
        !          3110:                        return (pEDQueue);
        !          3111:                } else {
        !          3112:                        pEDQueueBack = pEDQueue;
        !          3113:                        pEDQueue = (OHCIEndpointDescriptorPtr) pEDQueue->pVirtualNext;
        !          3114:                }
        !          3115:        }
        !          3116:        if (pOHCIUIMData->OptiOn) {
        !          3117:                pEDQueue = FindBulkEndpoint (functionNumber, endpointNumber, kOHCIEDDirectionTD, &pEDQueueBack);
        !          3118:                *pEDBack = pEDQueueBack;
        !          3119:                return (pEDQueue);
        !          3120:        }
        !          3121:        return (nil);
        !          3122: }
        !          3123: 
        !          3124: 
        !          3125: OHCIEndpointDescriptorPtr FindBulkEndpoint (
        !          3126:        short                                           functionNumber, 
        !          3127:        short                                           endpointNumber,
        !          3128:        short                                           direction,
        !          3129:        OHCIEndpointDescriptorPtr   *pEDBack)
        !          3130: {
        !          3131: 
        !          3132:        UInt32                                          unique;
        !          3133:        UInt32                                          myEndPointDirection;
        !          3134:        OHCIEndpointDescriptorPtr       pEDQueue;
        !          3135:        OHCIEndpointDescriptorPtr       pEDQueueBack;
        !          3136: 
        !          3137:        
        !          3138:        //search for endpoint descriptor
        !          3139:        myEndPointDirection = ((UInt32) direction) << kOHCIEndpointDirectionOffset;
        !          3140:        unique = (UInt32) ((((UInt32) endpointNumber) << kOHCIEndpointNumberOffset) | ((UInt32) functionNumber) 
        !          3141:                                                                                        | myEndPointDirection);
        !          3142:        pEDQueueBack = (OHCIEndpointDescriptorPtr) pOHCIUIMData->pBulkHead;
        !          3143:        pEDQueue = (OHCIEndpointDescriptorPtr) pEDQueueBack->pVirtualNext;
        !          3144:        while (((UInt32) pEDQueue) != pOHCIUIMData->pBulkTail ) {
        !          3145:                if ( (EndianSwap32Bit(pEDQueue->dWord0) & kUniqueNumMask) == unique) {
        !          3146:                        *pEDBack = pEDQueueBack;
        !          3147:                        return (pEDQueue);
        !          3148:                } else {
        !          3149:                        pEDQueueBack = pEDQueue;
        !          3150:                        pEDQueue = (OHCIEndpointDescriptorPtr) pEDQueue->pVirtualNext;
        !          3151:                        
        !          3152:                }
        !          3153:        }
        !          3154:        return (nil);
        !          3155: 
        !          3156: }
        !          3157: 
        !          3158: 
        !          3159: OHCIEndpointDescriptorPtr FindEndpoint (
        !          3160:        short                                           functionNumber, 
        !          3161:        short                                           endpointNumber,
        !          3162:        short                                           direction, 
        !          3163:        OHCIEndpointDescriptorPtr       *pEDQueueBack, 
        !          3164:        UInt32                                          *controlMask)
        !          3165: {
        !          3166:        OHCIEndpointDescriptorPtr pED, pEDBack;
        !          3167:        
        !          3168: //     DebugStr("OHCIUIM: FindEndpoint");
        !          3169: kprintf("FindEndPoint:Calling FindControlEndpoint fn=%d,ep=%d\n",functionNumber,endpointNumber);
        !          3170:        if ((pED = FindControlEndpoint (functionNumber, endpointNumber, &pEDBack)) != nil) 
        !          3171:        {
        !          3172:                *pEDQueueBack = pEDBack;
        !          3173:                *controlMask = kOHCIHcControl_CLE;
        !          3174:                return (pED);
        !          3175:        }
        !          3176:        if ((pED = FindBulkEndpoint (functionNumber, endpointNumber, direction, &pEDBack)) != nil)
        !          3177:        {
        !          3178:                *pEDQueueBack = pEDBack;
        !          3179: 
        !          3180:                *controlMask = kOHCIHcControl_BLE;
        !          3181:                //zzzz Opti Bug
        !          3182:                if(pOHCIUIMData->OptiOn)
        !          3183:                        *controlMask = kOHCIHcControl_CLE;
        !          3184:                return (pED);
        !          3185:        }
        !          3186:        
        !          3187:        if ((pED = FindInterruptEndpoint (functionNumber, endpointNumber, &pEDBack)) != nil)
        !          3188:        {
        !          3189:                *pEDQueueBack = pEDBack;
        !          3190:                *controlMask = 0;
        !          3191:                return (pED);   
        !          3192:        }
        !          3193:        
        !          3194:        pED = FindIsochronousEndpoint(functionNumber, endpointNumber, direction, &pEDBack);
        !          3195:        *pEDQueueBack = pEDBack;
        !          3196:        *controlMask = 0;
        !          3197:        return (pED);   
        !          3198: }
        !          3199: 
        !          3200: 
        !          3201: OHCIEndpointDescriptorPtr FindIsochronousEndpoint(
        !          3202:        short                                           functionNumber,
        !          3203:        short                                           endpointNumber,
        !          3204:        short                                           direction, 
        !          3205:        OHCIEndpointDescriptorPtr       *pEDBack)
        !          3206: {
        !          3207:        UInt32                                          myEndPointDirection;
        !          3208:        UInt32                                          unique;
        !          3209:        OHCIEndpointDescriptorPtr       pEDQueue, pEDQueueBack;
        !          3210: 
        !          3211:        //search for endpoint descriptor
        !          3212:        myEndPointDirection = ((UInt32) direction) << kOHCIEndpointDirectionOffset;
        !          3213:        unique = (UInt32) ((((UInt32) endpointNumber) << kOHCIEndpointNumberOffset) | ((UInt32) functionNumber) 
        !          3214:                                                                                        | myEndPointDirection);
        !          3215: 
        !          3216:        pEDQueueBack = (OHCIEndpointDescriptorPtr) pOHCIUIMData->pIsochHead;
        !          3217:        pEDQueue = (OHCIEndpointDescriptorPtr) pEDQueueBack->pVirtualNext;
        !          3218:        while (((UInt32) pEDQueue) != pOHCIUIMData->pIsochTail ) {
        !          3219:                if ( (EndianSwap32Bit(pEDQueue->dWord0) & kUniqueNumMask) == unique) {
        !          3220:                        *pEDBack = pEDQueueBack;
        !          3221:                        return (pEDQueue);
        !          3222:                } else {
        !          3223:                        pEDQueueBack = pEDQueue;
        !          3224:                        pEDQueue = (OHCIEndpointDescriptorPtr) pEDQueue->pVirtualNext;
        !          3225:                        
        !          3226:                }
        !          3227:        }
        !          3228:        return (nil);
        !          3229: 
        !          3230: }
        !          3231: 
        !          3232: 
        !          3233: OHCIEndpointDescriptorPtr FindInterruptEndpoint(
        !          3234:        short                                           functionNumber,
        !          3235:        short                                           endpointNumber,
        !          3236:        OHCIEndpointDescriptorPtr       *pEDBack)
        !          3237: {
        !          3238:        OHCIRegistersPtr                        pOHCIRegisters;
        !          3239:        UInt32                                          unique;
        !          3240:        OHCIEndpointDescriptorPtr       pEDQueue;
        !          3241:        OHCIIntHeadPtr                          pInterruptHead;
        !          3242:        int                                                     i;
        !          3243:        UInt32                                          temp;
        !          3244:        
        !          3245: 
        !          3246:        
        !          3247:        pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
        !          3248:        pInterruptHead = pOHCIUIMData->pInterruptHead;
        !          3249: 
        !          3250:        //search for endpoint descriptor
        !          3251:        unique = (UInt32) ((((UInt32) endpointNumber) << kOHCIEDControl_ENPhase) | (((UInt32) functionNumber) << kOHCIEDControl_FAPhase));
        !          3252: //                                     sprintf (debugStr, "FindInterruptEndpoint unique %d", unique);
        !          3253: //                             DebugStr ((ConstStr255Param) c2pstr (debugStr));
        !          3254: 
        !          3255:        
        !          3256:        for (i = 0; i < 63; i++) 
        !          3257:        {
        !          3258:                pEDQueue = pInterruptHead[i].pHead;
        !          3259:                *pEDBack = pEDQueue;
        !          3260:                /* BT do this first, or you find the dummy endpoint all this is hanging off. It matches 0,0 */
        !          3261:                pEDQueue = (OHCIEndpointDescriptorPtr) pEDQueue->pVirtualNext;
        !          3262:                while (pEDQueue != pInterruptHead[i].pTail)
        !          3263:                {
        !          3264:                        temp = (EndianSwap32Bit (pEDQueue->dWord0)) & kUniqueNumNoDirMask;
        !          3265: 
        !          3266:                        if ( temp == unique) 
        !          3267:                        {
        !          3268:                                return(pEDQueue);
        !          3269:                        } 
        !          3270:                        *pEDBack = pEDQueue;
        !          3271:                        pEDQueue = (OHCIEndpointDescriptorPtr) pEDQueue->pVirtualNext;
        !          3272:                }
        !          3273:        }
        !          3274:        return(nil);
        !          3275: 
        !          3276: }
        !          3277: 
        !          3278: int GetEDType(
        !          3279:        OHCIEndpointDescriptorPtr pED)
        !          3280: {
        !          3281:        return ((EndianSwap32Bit(pED->dWord0) & kOHCIEDControl_F)  >> kOHCIEDControl_FPhase);
        !          3282: }
        !          3283: 
        !          3284: 
        !          3285: static OSStatus RemoveAllTDs (OHCIEndpointDescriptorPtr pED)
        !          3286: {
        !          3287:        RemoveTDs(pED);
        !          3288:        
        !          3289:        if (GetEDType(pED) == kOHCIEDFormatGeneralTD) {
        !          3290:                // remove the last "dummy" TD
        !          3291:                OHCIUIMDeallocateTD((OHCIGeneralTransferDescriptorPtr) pED->pVirtualTailP);
        !          3292:        } else {
        !          3293:                OHCIUIMDeallocateITD((OHCIIsochTransferDescriptorPtr) pED->pVirtualTailP);
        !          3294:        }
        !          3295:        pED->pVirtualHeadP = nil;
        !          3296: 
        !          3297:        return (0);
        !          3298: }
        !          3299: 
        !          3300: 
        !          3301: //removes all but the last of the TDs
        !          3302: static OSStatus RemoveTDs (OHCIEndpointDescriptorPtr pED)
        !          3303: {
        !          3304:        OHCIGeneralTransferDescriptorPtr                pCurrentTD, lastTD;
        !          3305:        UInt32                                                                  bufferSizeRemaining = 0;
        !          3306:        OHCIIsochTransferDescriptorPtr                  pITD, pITDLast;
        !          3307:        
        !          3308:        if (GetEDType(pED) == kOHCIEDFormatGeneralTD) {
        !          3309:                //process and deallocate GTD's
        !          3310:                pCurrentTD = (OHCIGeneralTransferDescriptorPtr) (EndianSwap32Bit(pED->dWord2) & kOHCIHeadPMask);
        !          3311:                pCurrentTD = (OHCIGeneralTransferDescriptorPtr) OHCIUIMGetLogicalAddress ((UInt32) pCurrentTD);
        !          3312:        
        !          3313:                lastTD = (OHCIGeneralTransferDescriptorPtr) pED->pVirtualTailP;
        !          3314:                pED->pVirtualHeadP = pED->pVirtualTailP;
        !          3315:        
        !          3316:                while (pCurrentTD != lastTD) 
        !          3317:                {
        !          3318:                        if (pCurrentTD == nil)
        !          3319:                                return (-1);
        !          3320:                                
        !          3321:                        //take out TD from list
        !          3322:                        pED->dWord2 = pCurrentTD->dWord2;
        !          3323:                        pED->pVirtualHeadP = pCurrentTD->pVirtualNext;  
        !          3324: 
        !          3325:                        if (pCurrentTD->preparationID)
        !          3326:                                CheckpointIO(pCurrentTD->preparationID, nil);
        !          3327:                        pCurrentTD->preparationID = nil;
        !          3328:                        
        !          3329:                        bufferSizeRemaining += findBufferRemaining(pCurrentTD);
        !          3330: 
        !          3331:                        if (pCurrentTD->CallBack){
        !          3332:                                CallBackFuncPtr pCallBack;
        !          3333:                                // zero out callback first than call it
        !          3334:                                pCallBack = pCurrentTD->CallBack;
        !          3335:                                pCurrentTD->CallBack = nil;
        !          3336:                                (*pCallBack) (pCurrentTD->refcon, EDDeleteErr, bufferSizeRemaining);
        !          3337:                                bufferSizeRemaining = 0;
        !          3338:                        }
        !          3339:                        
        !          3340:                        OHCIUIMDeallocateTD(pCurrentTD);
        !          3341:                        pCurrentTD = (OHCIGeneralTransferDescriptorPtr) pED->pVirtualHeadP;             
        !          3342:                }               
        !          3343:        } else {
        !          3344:                pITD = (OHCIIsochTransferDescriptorPtr) (EndianSwap32Bit(pED->dWord2) & kOHCIHeadPMask);
        !          3345:                pITD = (OHCIIsochTransferDescriptorPtr) OHCIUIMGetLogicalAddress ((UInt32) pITD);
        !          3346:                pITDLast = (OHCIIsochTransferDescriptorPtr) pED->pVirtualTailP;
        !          3347:                
        !          3348:                while (pITD != pITDLast) {
        !          3349:                        if (pITD == nil)
        !          3350:                                return (-1);
        !          3351:                        ProcessCompletedITD (pITD);
        !          3352:                        pITD = (OHCIIsochTransferDescriptorPtr) pITD->pVirtualNext;
        !          3353:                }
        !          3354:        }
        !          3355: 
        !          3356:        return (0);
        !          3357: }
        !          3358: 
        !          3359: void ProcessCompletedITD (OHCIIsochTransferDescriptorPtr pITD) {
        !          3360: 
        !          3361:        USBIsocFrame                    *pFrames;
        !          3362:        int                                             i;
        !          3363:        
        !          3364:        SwapIsoc (pITD);
        !          3365:        pFrames = (USBIsocFrame *) pITD->pIsocFrame;
        !          3366: 
        !          3367:        for (i=0; i <= ((pITD->dWord0 & kOHCIITDControl_FC) >> kOHCIITDControl_FCPhase); i++) {
        !          3368:                if ( ((pITD->offset[i] & kOHCIITDPSW_CCNA) >> kOHCIITDPSW_CCNAPhase) == kOHCIITDConditionNotAccessed) {
        !          3369:                        pFrames[pITD->frameNum + i].frActCount = 0;
        !          3370:                        pFrames[pITD->frameNum + i].frStatus = kOHCIITDConditionNotAccessedReturn;
        !          3371:                } else {
        !          3372:                        pFrames[pITD->frameNum + i].frStatus = 
        !          3373:                                                                        (pITD->offset[i] & kOHCIITDPSW_CC) >> kOHCIITDOffset_CCPhase;
        !          3374:                        pFrames[pITD->frameNum + i].frActCount = pITD->offset[i] & kOHCIITDPSW_Size;
        !          3375:                }
        !          3376:        }
        !          3377:        // call callback
        !          3378:        if (pITD->handler){
        !          3379:                IsocCallBackFuncPtr pHandler;
        !          3380:                pHandler = pITD->handler;
        !          3381:                pITD->handler = nil;
        !          3382:                //zero out handler first than call it
        !          3383:                (*pHandler) (pITD->refcon, noErr, pFrames);
        !          3384:        }
        !          3385: }
        !          3386: 
        !          3387: /*
        !          3388:   This table contains the list of errata that are necessary for known problems with particular silicon
        !          3389:   The format is vendorID, revisionID, lowest revisionID needing errata, highest rev needing errata, errataBits
        !          3390:   The result of all matches is ORed together, so more than one entry may match.  Typically for a given errata a
        !          3391:   list of chips revisions that this applies to is supplied.
        !          3392: */
        !          3393: static ErrataListEntry errataList[] = {
        !          3394:        {0x1095, 0x670, 0, 0xffff, kErrataCMDDisableTestMode | kErrataOnlySinglePageTransfers | kErrataRetryBufferUnderruns}, // CMD 670
        !          3395:        {0x1045, 0xc861, 0, 0xffff, kErrataLSHSOpti}, // Opti 1045
        !          3396: };
        !          3397: 
        !          3398: #define errataListLength (sizeof(errataList)/sizeof(ErrataListEntry))
        !          3399: 
        !          3400: static UInt32 GetErrataBits (RegEntryIDPtr regEntryIDPtr)
        !          3401: {
        !          3402:        UInt32                          vendID, deviceID, revisionID;
        !          3403:        UInt32                          vLen = sizeof(vendID), dLen = sizeof(deviceID), rLen = sizeof(revisionID);
        !          3404:        ErrataListEntry         *entryPtr;
        !          3405:        UInt32                          i, errata = 0;
        !          3406:        
        !          3407:        extern int  cmd_pci_errata;  //global needed to fix errata for Caps Lock 
        !          3408:                                                                //LED support.  In usbcmd.m.
        !          3409: 
        !          3410:        if (cmd_pci_errata == 1)
        !          3411:        {
        !          3412:                return 0;  //This allows PowerSurge with CMD card to work with Caps Lock LED
        !          3413:        }
        !          3414: 
        !          3415:        // get this chips vendID, deviceID, revisionID
        !          3416:        RegistryPropertyGet(regEntryIDPtr, "vendor-id", &vendID, &vLen);
        !          3417:        RegistryPropertyGet(regEntryIDPtr, "device-id", &deviceID, &dLen);
        !          3418:        RegistryPropertyGet(regEntryIDPtr, "revision-id", &revisionID, &rLen);
        !          3419:        for(i=0, entryPtr = errataList; i<errataListLength; i++, entryPtr++){
        !          3420:                if (vendID == entryPtr->vendID && deviceID == entryPtr->deviceID &&
        !          3421:                        revisionID >= entryPtr->revisionLo && revisionID <= entryPtr->revisionHi){
        !          3422:                                errata |= entryPtr->errata;  // we match, add this errata to our list
        !          3423:                }
        !          3424:        }
        !          3425:        return(errata);
        !          3426: }
        !          3427: 
        !          3428: 
        !          3429: void DoOptiFix(OHCIEndpointDescriptorPtr pIsochHead)
        !          3430: {
        !          3431:        OHCIEndpointDescriptorPtr pED;
        !          3432:        OHCIGeneralTransferDescriptorPtr pTD;
        !          3433:        int i = 0;
        !          3434:        int j = 0;
        !          3435:        
        !          3436: //     DebugStr ((ConstStr255Param) "DoOptiFix");
        !          3437:        
        !          3438:        for (i=0; i<20; i++) {
        !          3439:                // allocate ED
        !          3440:                pED = OHCIUIMAllocateED();
        !          3441:                pED->pVirtualNext = nil;
        !          3442:                // make ED and FA = 0
        !          3443:                pTD = OHCIUIMAllocateTD();
        !          3444:                pED->dWord2 = EndianSwap32Bit ((UInt32) pTD->pPhysical);
        !          3445:                pTD->dWord2 = pED->dWord1;
        !          3446:                pTD->pEndpoint = (UInt32) pED;
        !          3447:                pTD->pType = kOHCIOptiLSBug;
        !          3448:                pED->dWord1 = EndianSwap32Bit ((UInt32) pTD->pPhysical);
        !          3449: 
        !          3450: /*
        !          3451:                for (j=0; j<0; j++) {
        !          3452:                        // allocate 4 TDs
        !          3453:                        pTD = OHCIUIMAllocateTD();
        !          3454:                        pTD->dWord2 = pED->dWord2;
        !          3455:                        pED->dWord2 = EndianSwap32Bit ((UInt32) pTD->pPhysical);
        !          3456:                        // leave 1 all zeros
        !          3457:                        // make other all zeros except next TD
        !          3458:                        // mark each to indicate that its this type
        !          3459:                        pTD->pType = kOHCIOptiLSBug;
        !          3460:                }
        !          3461: */
        !          3462:                pED->dWord3 = pIsochHead->dWord3;
        !          3463:                pIsochHead->dWord3 = EndianSwap32Bit((UInt32) pED->pPhysical);
        !          3464:                pIsochHead = pED;
        !          3465:        }
        !          3466: }
        !          3467: 
        !          3468: 
        !          3469: 
        !          3470: OSStatus OptiLSHSFix()
        !          3471: {
        !          3472: 
        !          3473: //  Do Opti Errata stuff here!!!!!!
        !          3474:        int i;
        !          3475:        OHCIIntHeadPtr                          pInterruptHead;
        !          3476:        OHCIEndpointDescriptorPtr   pControlED;
        !          3477:        OHCIRegistersPtr                        pOHCIRegisters;
        !          3478:        OSStatus                                        status = noErr;
        !          3479: 
        !          3480:        pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
        !          3481: 
        !          3482:        pOHCIUIMData->OptiOn = 1;
        !          3483: 
        !          3484:        //Turn off list processing
        !          3485:        pOHCIRegisters->hcControl =
        !          3486:                EndianSwapImm32Bit
        !          3487:                        (kOHCIFunctionalState_Operational << kOHCIHcControl_HCFSPhase);
        !          3488:        
        !          3489:        // wait a millisecond
        !          3490:        DelayForHardware(DurationToAbsolute(1*durationMillisecond));    
        !          3491:                
        !          3492:        pInterruptHead = pOHCIUIMData->pInterruptHead;
        !          3493:                
        !          3494:        // add dummy EDs to 8ms interrupts
        !          3495:        for ( i = 0; i< 8; i++)
        !          3496:                DoOptiFix(pInterruptHead[48 + i].pHead);
        !          3497: //     DoOptiFix((OHCIEndpointDescriptorPtr) pOHCIUIMData->pIsochHead);
        !          3498: 
        !          3499:        //Assign Tail of Control to point to head of Bulk
        !          3500: 
        !          3501:        pControlED = (OHCIEndpointDescriptorPtr) pOHCIUIMData->pControlTail;
        !          3502:        pControlED->dWord3 = pOHCIRegisters->hcBulkHeadED;
        !          3503:        
        !          3504:        // add dummy EDs to end of Control
        !          3505:        DoOptiFix( (OHCIEndpointDescriptorPtr) pOHCIUIMData->pControlTail);
        !          3506:                
        !          3507:        // turn on only control and periodic
        !          3508:        pOHCIRegisters->hcControl =
        !          3509:                EndianSwapImm32Bit
        !          3510:                        ((kOHCIFunctionalState_Operational << kOHCIHcControl_HCFSPhase) |
        !          3511:                         kOHCIHcControl_CLE | kOHCIHcControl_PLE | kOHCIHcControl_IE);
        !          3512: 
        !          3513:        //End of Opti Fix
        !          3514:        return (status);
        !          3515: }
        !          3516: 
        !          3517: 
        !          3518: 
        !          3519: 
        !          3520: 
        !          3521: 
        !          3522: /*******************************************************************
        !          3523: Function:              AmIThisMachine()
        !          3524: Purpose:               check to see if we're the machine that's name is passed in
        !          3525: Params:                        Name of computer to check for
        !          3526: Returns:               Returns back true if this machine's name is that which is 
        !          3527: passed in.
        !          3528: *******************************************************************/
        !          3529: Boolean AmIThisMachine(Str255 inMachineNameStr)
        !          3530: {
        !          3531:        RegEntryID                              foundEntry;
        !          3532:        RegPropertyName*                propertyName = "model";
        !          3533:        RegPropertyName*                realPropertyName = "compatible";
        !          3534:        Str31                                   kiMacMachineName = "iMac,1";
        !          3535:        RegPropertyValueSize    propertySize;
        !          3536:        Ptr                                             modelNamePropertyStrPtr;
        !          3537:        OSStatus                                result;
        !          3538:        long                                    nameRegistryVersion;
        !          3539:        OSErr                                   theErr;
        !          3540:        Boolean                                 isThatMachine = false;
        !          3541:        
        !          3542:        
        !          3543:        
        !          3544:        // Does the name registry exist?
        !          3545:        //naga theErr = Gestalt(gestaltNameRegistryVersion, &nameRegistryVersion);
        !          3546:        if( theErr == noErr )
        !          3547:        {
        !          3548:                // Can we find the "root" node of the device-tree?
        !          3549:                theErr = RegistryCStrEntryLookup(nil, "Devices:device-tree", 
        !          3550: &foundEntry);
        !          3551:        }
        !          3552:        
        !          3553:        if( theErr == noErr )
        !          3554:        {
        !          3555:                if( CompareString(inMachineNameStr, kiMacMachineName, NULL) == 0 )
        !          3556:                {
        !          3557:                        // Does the "model" property exist?  And if so, how big is it?
        !          3558:                        result = RegistryPropertyGetSize(&foundEntry, propertyName, &propertySize);
        !          3559: 
        !          3560:                        if( result == noErr )
        !          3561:                        {
        !          3562:                                modelNamePropertyStrPtr = usb_NewPtr(propertySize);
        !          3563:                                if( modelNamePropertyStrPtr )
        !          3564:                                {
        !          3565:                                        result = RegistryPropertyGet(&foundEntry, propertyName, 
        !          3566: modelNamePropertyStrPtr, &propertySize);
        !          3567:                                                
        !          3568:                                        if( result == noErr )
        !          3569:                                        {
        !          3570:                                                c2pstr( modelNamePropertyStrPtr );
        !          3571:                                                if( CompareString( inMachineNameStr, (unsigned char 
        !          3572: *)modelNamePropertyStrPtr, NULL ) == 0 )
        !          3573:                                                        isThatMachine = true;
        !          3574:                                        }
        !          3575:                                        usb_DisposePtr( modelNamePropertyStrPtr );
        !          3576:                                }
        !          3577:                        }
        !          3578:                }
        !          3579:                else
        !          3580:                {
        !          3581:        
        !          3582:                        // Does the "compatible" property exist?  And if so, how big is it?
        !          3583:                        result = RegistryPropertyGetSize(&foundEntry, realPropertyName, &propertySize);
        !          3584: 
        !          3585:                        if( result == noErr )
        !          3586:                        {
        !          3587:                                modelNamePropertyStrPtr = usb_NewPtr(propertySize);
        !          3588:                                if( modelNamePropertyStrPtr )
        !          3589:                                {
        !          3590:                                        result = RegistryPropertyGet(&foundEntry, realPropertyName, modelNamePropertyStrPtr, &propertySize);
        !          3591:                                                
        !          3592:                                        if( result == noErr )
        !          3593:                                        {
        !          3594:                                                c2pstr( modelNamePropertyStrPtr );
        !          3595:                                                if( CompareString( inMachineNameStr, (unsigned char *)modelNamePropertyStrPtr, NULL ) == 0 )
        !          3596:                                                        isThatMachine = true;
        !          3597:                                                else
        !          3598:                                                {
        !          3599:                                                        UInt16 modelNameLength = modelNamePropertyStrPtr[0];
        !          3600:                                                        c2pstr( &(modelNamePropertyStrPtr[++modelNameLength]) );
        !          3601:                                                        if( modelNamePropertyStrPtr[modelNameLength] != 0 )
        !          3602:                                                                if( CompareString(      inMachineNameStr, (unsigned char *)&(modelNamePropertyStrPtr[ modelNameLength ]), NULL ) == 0 )
        !          3603:                                                                        isThatMachine = true;
        !          3604:                                                }
        !          3605:                                        }
        !          3606:                                        usb_DisposePtr( modelNamePropertyStrPtr );
        !          3607:                                }
        !          3608:                        }
        !          3609:                }
        !          3610:                
        !          3611: 
        !          3612:                if ((result = RegistryEntryIDDispose(&foundEntry)) != noErr)
        !          3613:                        return(false);
        !          3614:        }
        !          3615:        
        !          3616:        return(isThatMachine);
        !          3617: }

unix.superglobalmegacorp.com

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