Annotation of kernel/bsd/dev/ppc/drvUSBCMD/ohciuim.c, revision 1.1.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.