Annotation of kernel/bsd/dev/ppc/drvUSBCMD/Library/uslUIMInterface.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:           uslUIMInterface.c
                     27: 
                     28:        Contains:       Interface between UIM and USL
                     29: 
                     30:        Version:        Neptune 1.0
                     31: 
                     32:        Copyright:      � 1997-1998 by Apple Computer, Inc., all rights reserved.
                     33: 
                     34:        File Ownership:
                     35: 
                     36:                DRI:                            Barry Twycross
                     37: 
                     38:                Other Contact:          xxx put other contact here xxx
                     39: 
                     40:                Technology:                     USB
                     41: 
                     42:        Writers:
                     43: 
                     44:                (DRF)   Dave Falkenburg
                     45:                (bwm)   bruce merritt
                     46:                (TC)    Tom Clark
                     47:                (CSS)   Chas Spillar
                     48:                (GG)    Guillermo Gallegos
                     49:                (DF)    David Ferguson
                     50:                (DKF)   David Ferguson
                     51:                (CJK)   Craig Keithley
                     52:                (BT)    Barry Twycross
                     53: 
                     54:        Change History (most recent first):
                     55: 
                     56:         <USB81>        11/13/98        BT              Delete hub device when removing bus.
                     57:         <USB80>        11/11/98        DRF             (CJK) Make sure to check ALL UIMs when polling before returning.
                     58:                                                                        Allows us to type in Macsbug on the 3rd or 4th USB port.
                     59:         <USB79>        10/22/98        BT              Fix wrong status for deleted devices.
                     60:         <USB78>        10/21/98        DF              make probeEndpoint reentrant
                     61:         <USB77>         10/5/98        BT              Add root hub to probeendpoint
                     62:         <USB76>         9/29/98        bwm             BT: Fix UInt64 problems.
                     63:         <USB75>         9/29/98        BT              Use real frame timing
                     64:         <USB74>         9/10/98        DF              When removing a bus, clear all references to that bus.
                     65:         <USB73>          9/9/98        BT              Fix Isoc
                     66:         <USB72>          9/9/98        BT              Use correct number of frames calcing Isoc act count
                     67:         <USB71>          9/3/98        BT              Return immediate errors, fix param order
                     68:         <USB70>          9/3/98        GG              Changed Isoc interface to conform to dispatchtable interface.
                     69:         <USB69>          9/1/98        BT              FIx passing wrong parameter to UIM. Supermario compiler didn't
                     70:                                                                        like it.
                     71:         <USB68>         8/31/98        BT              Add isoc pipes
                     72:         <USB67>         8/25/98        BT              Isoc name changes
                     73:         <USB66>         8/24/98        BT              Cope without #define for reserved4
                     74:         <USB65>         8/13/98        BT              Add multibus support
                     75:         <USB64>         8/12/98        BT              Move root hub into UIM again.
                     76:         <USB63>         8/12/98        DF              (for BT) Finally fix fix
                     77:         <USB62+>        8/12/98        DF              (for BT) Finally fix fix
                     78:         <USB62>         8/11/98        BT              Issue bad UIM version status message
                     79:         <USB61>         8/11/98        BT              Fix check
                     80:         <USB60>         8/11/98        BT              Check UIM version
                     81:         <USB59>          8/7/98        GG              Tweaked interface to USL to be consistent with direction
                     82:                                                                        parameter.
                     83:         <USB58>         7/23/98        BT              Don't corrupt flags if control failes
                     84:         <USB57>         7/10/98        TC              Back out previous revision - it was breaking Yosemite.
                     85:         <USB56>         6/30/98        BT              Move Root hub sim into UIM
                     86:         <USB55>         6/24/98        DF              fix problem that kept the UIM's suspend change reset proc from
                     87:                                                                        being called.
                     88:         <USB54>         6/14/98        DF              Bad integration, left out the Check_UIM change.
                     89:         <USB53>         6/14/98        DF              Do a little more in USBRemoveBus, eliminate UIM moved checks
                     90:         <USB52>          6/5/98        GG              Changed uxbusref to USBBusRef.  Changed GetFrameNumberImmediate
                     91:                                                                        to return a UInt64 zero.
                     92:         <USB51>          6/5/98        CSS             Forgot to include Math64.h.
                     93:         <USB50>          6/5/98        CSS             Update to use U64Max() instead of -1 for the maximum 64 bit
                     94:                                                                        value.
                     95:         <USB49>          6/5/98        BT              Use UIM time
                     96:         <USB48>         5/20/98        BT              Eliminate PB0
                     97:         <USB47>          5/5/98        GG              Change Buffersize from short to unsigned long in BulkTransfer.
                     98:         <USB46>          5/4/98        BT              Fix pipe stall errors
                     99:         <USB45>         4/30/98        BT              Add real interrupt driven timer
                    100:         <USB44>         4/29/98        BT              Move common defines to USBpriv
                    101:         <USB43>         4/28/98        BT              Add bulk performance monitoring.
                    102:         <USB42>         4/26/98        BT              Add pipe state control
                    103:         <USB41>         4/23/98        BT              Add reset portsuspend change
                    104:         <USB40>         4/22/98        DF              Make USBAddBus return gracefully if more than one bus is
                    105:                                                                        attached.
                    106:         <USB39>         4/20/98        BT              Add abort pipe
                    107:         <USB38>         4/16/98        BT              Fix unused variable
                    108:         <USB37>         4/15/98        BT              Add over current change reset
                    109:         <USB36>         4/14/98        DF              Add UIM polling for debugger support
                    110:         <USB35>         4/14/98        BT              Use EDDelete
                    111:         <USB34>          4/9/98        BT              Use USB.h
                    112:                <33>      4/7/98        BT              Fix act count in control transactions
                    113:                <32>      4/6/98        BT              Change w names
                    114:                <31>      4/6/98        BT              New param block names
                    115:                <30>      4/2/98        BT              eliminate obsolete function
                    116:                <29>     3/24/98        BT              Swap parameter order in open Int ED
                    117:                <28>     3/18/98        BT              Add reset enable change to root hub.
                    118:                <27>     3/18/98        BT              Add clear port enable change feature (Disabled waiting UIM
                    119:                                                                        support)
                    120:                <26>     3/11/98        BT              Int simulation for root hub. More debugs for moving UIM.
                    121:                <25>      3/5/98        BT              track down changing UIM
                    122:                <24>      3/5/98        BT              Add interrupt pipe
                    123:                <23>     2/23/98        BT              Fix error recovery
                    124:                <22>     2/19/98        BT              Cut out call to process done Queue in UIM.
                    125:                <21>     2/16/98        BT              Fix calling processdone queue and timer too often.
                    126:         <USB20>         2/11/98        DKF             Add back in ProcessDoneQueue if we're at task time
                    127:                <19>      2/8/98        BT              Take out process done q in send control.
                    128:                <18>      2/4/98        BT              Fix uslControlPacket to have errors. Add mnore support for
                    129:                                                                        usbProbe
                    130:                <17>      2/2/98        BT              Add bulk stuff
                    131:                <16>     1/29/98        BT              Use symbols for the flags fields used
                    132:                <15>     1/26/98        BT              Mangle names after design review, finish up
                    133:                <14>     1/26/98        BT              Mangle names after design review
                    134:                <13>     1/26/98        BT              Hack in clear enpoint stall
                    135:                <12>     1/21/98        BT              Change hardware status codes
                    136:                <11>     1/20/98        BT              Unwrapping root hub
                    137:                <10>     1/19/98        BT              More root hub sim
                    138:                 <9>     1/15/98        BT              Do root hub simulation.
                    139:                 <8>     1/15/98        CJK             Change include of USL.h to USBServicesLib.h
                    140:                 <7>     1/14/98        BT              Implimenting Interrupt transactions
                    141:                 <6>     1/13/98        BT              Change uslPacket to uslControlPacket
                    142:                 <5>    12/22/97        BT              StartRootHub moving to USL
                    143:                 <4>    12/19/97        BT              TAking out dependancy on UIM
                    144:                 <3>    12/19/97        BT              UIM now a Shared lib
                    145: */
                    146: 
                    147: #include "../USB.h"
                    148: #include "../USBpriv.h"
                    149: //#include <Math64.h"
                    150: 
                    151: #include "../uimpriv.h"
                    152: #include "uslpriv.h"
                    153: //#include "../MonaUSBPriv.h"
                    154: 
                    155: 
                    156: 
                    157: enum{
                    158:        kSetupSent  = 0x01,
                    159:        kDataSent       = 0x02,
                    160:        kStatusSent = 0x04,
                    161:        kSetupBack  = 0x10,
                    162:        kDataBack       = 0x20,
                    163:        kStatusBack = 0x40
                    164:        };
                    165: 
                    166: enum{
                    167:        kMaxBus = 16
                    168:        };
                    169: static struct UIMPluginDispatchTable *UIMPlugIn[kMaxBus], *pending[kMaxBus];
                    170: static USBBusRef UIMBus[kMaxBus];
                    171: static USBDeviceRef rootHubRefs[kMaxBus];
                    172: 
                    173: 
                    174: void UIMSetRootHubRef(UInt32 bus, USBDeviceRef ref)
                    175: {
                    176:        if(UIMPlugIn[bus] == nil)
                    177:        {
                    178:                USBExpertStatus(0,"USL - Bad bus passed to root hub ref", 0);
                    179:        }
                    180:        else
                    181:        {
                    182:                rootHubRefs[bus] = ref;
                    183:        }
                    184: }
                    185: 
                    186: #define CHECK_UIM 0
                    187: #if CHECK_UIM
                    188: static void checkUIMMoved(UInt32 bus, void ***UIM,void  **UIM1,void  **current)
                    189: {
                    190: 
                    191: static void *UIMp;
                    192: 
                    193:        if(UIMPlugIn[bus] != nil)
                    194:        {
                    195:                if(UIMp == nil)
                    196:                {
                    197:                        UIMp = (void *)UIMPlugIn[bus];
                    198:                }
                    199:                else
                    200:                {
                    201:                        if(UIMp != (void *)UIMPlugIn[bus])
                    202:                        {
                    203:                                //DebugStr("UIM Pointer changed, tell barry, you're hosed");
                    204:                                USBExpertStatus(0,"USL - UIM Pointer changed, tell barry, you're hosed", 0);
                    205:                        }
                    206:                }
                    207: 
                    208:                if(*UIM == nil)
                    209:                {
                    210:                        *UIM = (void *)*current;
                    211:                        *UIM1 = **UIM;
                    212:                }
                    213:                else
                    214:                {
                    215:                        if(*UIM != (void *)*current)
                    216:                        {
                    217:                                //DebugStr("UIM moved, tell barry, you're hosed");
                    218:                                USBExpertStatus(0,"USL - UIM moved, tell barry, you're hosed", 0);
                    219:                        }
                    220:                        
                    221:                        if(*UIM1 != **UIM)
                    222:                        {
                    223:                                //DebugStr("UIM 1 moved, tell barry, you're hosed");
                    224:                                USBExpertStatus(0,"USL - UIM 1 moved, tell barry, you're hosed", 0);
                    225:                        }
                    226:                }
                    227:        }
                    228:        else
                    229:        {
                    230:                SysDebugStr("Bad bus");
                    231:                USBExpertStatus(0,"USL - bad bus passed to UIM interface", bus);
                    232:        }
                    233: }
                    234: #endif
                    235: 
                    236: OSStatus USBAddBus(    
                    237:                void *regEntry,
                    238:                void *UIM,      /* GG to specifiy */
                    239:                USBBusRef inBus)                                        /* from TC */
                    240: {
                    241: 
                    242: UInt32 bus=
                    243: #if CHECK_UIM
                    244:                        5
                    245: #else
                    246:                        0
                    247: #endif
                    248:                         ;
                    249: 
                    250:        regEntry = 0;   /* not used */
                    251: 
                    252: printf("USBAddBus:Adding bus=%d\n",bus);
                    253:        while( (UIMPlugIn[bus] != nil) || (pending[bus] != nil) )
                    254:        {
                    255:                if(bus++ >= kMaxBus)
                    256:                {
                    257:                        return(-1);
                    258:                }
                    259:        }
                    260:        USBExpertStatus(-1, "USL - Adding bus index:", bus);
                    261:        pending[bus] = UIM;
                    262:        if(pending[bus]->pluginVersion != kUIMPluginTableVersion)
                    263:        {
                    264:                USBExpertStatus(-1, "UIM is wrong versions, bus not added", pending[bus]->pluginVersion);
                    265:                pending[bus] = nil;
                    266:                return(kUSBPBVersionError);
                    267:        }
                    268: 
                    269: 
                    270:        UIMBus[bus] = inBus;
                    271: 
                    272: printf("USBAddBus:starting roothub\n");
                    273:        StartRootHub(bus);
                    274: printf("USBAddBus:roothub complete\n");
                    275:        return(noErr);
                    276: }
                    277: 
                    278: OSStatus UIMResetRootHub(UInt32 bus)
                    279: {
                    280:        if(pending[bus] == nil)
                    281:        {
                    282:                SysDebugStr("Bad bus for reset");
                    283:                USBExpertStatus(0,"USL - bad bus passed to reset", bus);        
                    284:        }
                    285:        
                    286:        if(pending[bus] != nil)
                    287:        {
                    288:        OSStatus ret;
                    289:                ret = (*pending[bus]->uimResetRootHubProc)(UIMBus[bus]);
                    290:                if(ret != noErr)
                    291:                {
                    292:                        return(ret);
                    293:                }
                    294:                UIMPlugIn[bus] = pending[bus];
                    295:                pending[bus] = nil;
                    296:        }
                    297:        return(-1);
                    298: }
                    299: 
                    300: OSStatus USBRemoveBus(
                    301:                USBBusRef inBus)                                        /* from TC */
                    302: {
                    303: UInt32 bus = 0;
                    304: USBPB pb;
                    305: 
                    306:        while(inBus != UIMBus[bus])
                    307:        {
                    308:                if(bus++ >= kMaxBus)
                    309:                {
                    310:                        return(kUSBNotFound);
                    311:                }
                    312:        }
                    313:        USBExpertStatus(-1, "USL - Removing bus index:", bus);
                    314: 
                    315:        pb.pbLength = sizeof(pb);
                    316:        pb.pbVersion = kUSBCurrentHubPB;
                    317:        pb.usbStatus = noErr;
                    318:        pb.usbFlags = 0;
                    319:        pb.usbReference = rootHubRefs[bus];
                    320:        pb.usbCompletion = kUSBNoCallBack;
                    321: 
                    322:        if(immediateError(USBHubDeviceRemoved(&pb)))
                    323:        {
                    324:                USBExpertStatus(pb.usbReference, "USL - remove bus, Failed to remove root hub", pb.usbReference);
                    325:        }
                    326:        USBExpertRemoveDeviceDriver(rootHubRefs[bus]);
                    327:        rootHubRefs[bus] = 0;
                    328: 
                    329:        UIMPlugIn[bus] = nil;
                    330:        UIMBus[bus] = 0;
                    331:        pending[bus] = nil;
                    332:        
                    333:        return(noErr);
                    334: }
                    335: 
                    336: void UIMPollRootHubSim(void)
                    337: {
                    338: #if CHECK_UIM
                    339: static void **UIM, *UIM1;
                    340: #endif
                    341: UInt32 bus = 0;
                    342: 
                    343:        for(bus = 0; bus<kMaxBus; bus++)
                    344:        {
                    345:                if(UIMPlugIn[bus] != nil)
                    346:                {
                    347: #if CHECK_UIM
                    348:        checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimPollRootHubSim);
                    349: #endif
                    350: 
                    351:                        (*UIMPlugIn[bus]->uimPollRootHubSim)(UIMBus[bus]);
                    352:                }
                    353:        }
                    354: }
                    355: 
                    356: OSStatus USLPolledProcessDoneQueue(void)
                    357: {
                    358: #if CHECK_UIM
                    359: static void **UIM, *UIM1;
                    360: #endif
                    361: UInt32 bus = 0;
                    362: OSStatus myErr;
                    363: 
                    364:        for(bus = 0; bus<kMaxBus; bus++)
                    365:        {
                    366:                if(UIMPlugIn[bus] != nil)
                    367:                {
                    368: #if CHECK_UIM
                    369: static void **UIM, *UIM1;
                    370:        checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimProcessDoneQueueProc);
                    371: #endif
                    372:                        myErr = (*UIMPlugIn[bus]->uimProcessDoneQueueProc)();
                    373:                }
                    374:        }
                    375:        return(noErr);
                    376: }
                    377: 
                    378: 
                    379:        
                    380: 
                    381: UInt64 UIMGetCurrentFrame(UInt32 bus)
                    382: {
                    383: #if CHECK_UIM
                    384: static void **UIM, *UIM1;
                    385:        checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimGetCurrentFrameNumberProc);
                    386: #endif
                    387: 
                    388:        if(UIMPlugIn[bus] != nil)
                    389:        {
                    390:                return(*UIMPlugIn[bus]->uimGetCurrentFrameNumberProc)();
                    391:        }
                    392:        return(U64SetU(0));
                    393: }
                    394: 
                    395: UInt32 UIMGetAFrame(void)
                    396: {
                    397: union{
                    398:        UInt64 u;
                    399:        UnsignedWide s;
                    400:        }frame;
                    401: static UInt32 bus = 0;
                    402: 
                    403:        if(UIMPlugIn[bus] != nil)
                    404:        {
                    405:                frame.u = (*UIMPlugIn[bus]->uimGetCurrentFrameNumberProc)();
                    406:                return(frame.s.lo);
                    407:        }
                    408: 
                    409:        for(bus = 0; bus<kMaxBus; bus++)
                    410:        {
                    411:                if(UIMPlugIn[bus] != nil)
                    412:                {
                    413:                        frame.u = (*UIMPlugIn[bus]->uimGetCurrentFrameNumberProc)();
                    414:                        return(frame.s.lo);
                    415:                }
                    416:        }
                    417:        return(0);
                    418: }
                    419: 
                    420: 
                    421: OSStatus UIMControlEDCreate(
                    422:        UInt32 bus,
                    423:        UInt8                                           functionNumber,
                    424:        UInt8                                           endpointNumber,
                    425:        UInt16                                          maxPacketSize,
                    426:        UInt8                                           speed)
                    427: {
                    428: #if CHECK_UIM
                    429: static void **UIM, *UIM1;
                    430:        checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimCreateControlEndpointProc);
                    431: #endif
                    432: 
                    433:        if(UIMPlugIn[bus] != nil)
                    434:        {
                    435:                return(*UIMPlugIn[bus]->uimCreateControlEndpointProc)(
                    436:                                functionNumber, 
                    437:                                endpointNumber,
                    438:                                maxPacketSize, 
                    439:                                speed);
                    440:        }
                    441:        return(-1);
                    442: }
                    443: 
                    444: OSStatus UIMInterruptEDCreate(
                    445:        UInt32 bus,
                    446:        UInt8                                           functionNumber,
                    447:        UInt8                                           endpointNumber,
                    448:        UInt16                                          maxPacketSize,
                    449:        UInt8                                           speed)
                    450: {
                    451: #if CHECK_UIM
                    452: static void **UIM, *UIM1;
                    453:        checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimCreateInterruptEndpointProc);
                    454: #endif
                    455: 
                    456:        if(UIMPlugIn[bus] != nil)
                    457:        {
                    458:                return(*UIMPlugIn[bus]->uimCreateInterruptEndpointProc)(
                    459:                                functionNumber, 
                    460:                                endpointNumber,
                    461:                                speed,
                    462:                                maxPacketSize, 
                    463:                                8,      // Polling rate
                    464:                                0);     // Reserve bandwidth?? 
                    465:        }
                    466:        return(-1);
                    467: }
                    468: 
                    469: OSStatus UIMIsocEDCreate(
                    470:        UInt32 bus,
                    471:        UInt8                                           functionNumber,
                    472:        UInt8                                           endpointNumber,
                    473:        UInt8                                           direction,      
                    474:        UInt16                                          maxPacketSize)
                    475: {
                    476: #if CHECK_UIM
                    477: static void **UIM, *UIM1;
                    478:        checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimCreateIsochEndpointProc);
                    479: #endif
                    480: 
                    481:        if(UIMPlugIn[bus] != nil)
                    482:        {
                    483:                return(*UIMPlugIn[bus]->uimCreateIsochEndpointProc)(
                    484:                                functionNumber, 
                    485:                                endpointNumber,
                    486:                                maxPacketSize, 
                    487:                                direction); 
                    488:        }
                    489:        return(-1);
                    490: }
                    491: 
                    492: 
                    493: OSStatus UIMBulkEDCreate(
                    494:        UInt32 bus,
                    495:        UInt8                                           functionNumber,
                    496:        UInt8                                           endpointNumber,
                    497:        UInt8                                           direction,      
                    498:        UInt8                                           maxPacketSize)
                    499: {
                    500: #if CHECK_UIM
                    501: static void **UIM, *UIM1;
                    502:        checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimCreateBulkEndpointProc);
                    503: #endif
                    504: 
                    505:        if(UIMPlugIn[bus] != nil)
                    506:        {
                    507:                return(*UIMPlugIn[bus]->uimCreateBulkEndpointProc)(
                    508:                                functionNumber, 
                    509:                                endpointNumber,
                    510:                                direction,
                    511:                                maxPacketSize);
                    512:        }
                    513:        return(-1);
                    514: }
                    515: 
                    516: OSStatus UIMControlTransfer(
                    517:        UInt32 bus,
                    518:        UInt32                                          refcon,
                    519:        CallBackFuncPtr                         handler,
                    520:        UInt32                                          CBP,
                    521:        Boolean                                         bufferRounding,
                    522:        short                                           functionNumber,
                    523:        short                                           endpointNumber,
                    524:        short                                           bufferSize,
                    525:        short                                           direction)
                    526: {
                    527: #if CHECK_UIM
                    528: static void **UIM, *UIM1;
                    529:        checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimCreateControlTransferProc);
                    530: #endif
                    531: 
                    532:        if(UIMPlugIn[bus] != nil)
                    533:        {
                    534:                return(*UIMPlugIn[bus]->uimCreateControlTransferProc)(
                    535:                refcon,
                    536:                handler,
                    537:                CBP,
                    538:                bufferRounding,
                    539:                functionNumber,
                    540:                endpointNumber,
                    541:                bufferSize,
                    542:                direction);
                    543:        }
                    544:        return(-1);
                    545: }
                    546: 
                    547: #if 0
                    548: #include "TextUtils.h"
                    549: static void AddNum(UInt8 *s1, UInt32 num)
                    550: {
                    551: UInt8 number[20];
                    552:        NumToString(num, number);
                    553:        AddString(s1, number);
                    554: }
                    555: 
                    556: static void AddString(UInt8 *s1, UInt8 *s2)
                    557: {
                    558: int count;
                    559:        count = 255-*s1;
                    560:        if(count == 0)
                    561:        {       
                    562:                return;
                    563:        }
                    564:        if(count > *s2)
                    565:        {
                    566:                count = *s2;
                    567:        }
                    568:        usb_BlockMoveData(&s2[1], &s1[*s1]+1, s2[0]);
                    569:        *s1+=*s2;
                    570: }
                    571: 
                    572: static void DebugNum(UInt8 *str, UInt32 num, Boolean stop)
                    573: {
                    574: UInt8 strBuf[256];
                    575: 
                    576:        AddString(strBuf, str);
                    577:        AddString(strBuf, " : ");
                    578:        AddNum(strBuf, num);
                    579:        AddString(strBuf, " 100;g");
                    580:        DebugStr(strBuf);
                    581:        if(stop)
                    582:        {
                    583:                SysDebugStr("This seems bad, tell barry about it, cmd-g to continue");  
                    584:        }
                    585: }
                    586: #endif
                    587: OSStatus UIMControlEDDelete(
                    588:        UInt32 bus,
                    589:        short                                           functionNumber,
                    590:        short                                           endpointNumber)
                    591: {
                    592: #if CHECK_UIM
                    593: static void **UIM, *UIM1;
                    594:        checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimDeleteControlEndpointProc);
                    595: #endif
                    596: 
                    597:        if(UIMPlugIn[bus] != nil)
                    598:        {
                    599:                return(*UIMPlugIn[bus]->uimDeleteControlEndpointProc)(functionNumber, endpointNumber);
                    600:        }
                    601:        else
                    602:        {
                    603:                USBExpertStatus(0,"USL -control ED delete failed", bus);                
                    604:        }
                    605:        return(-1);
                    606: }
                    607: 
                    608: OSStatus UIMEDDelete(
                    609:        UInt32 bus,
                    610:        short                                           functionNumber,
                    611:        short                                           endpointNumber,
                    612:        short                                           direction)
                    613: {
                    614: #if CHECK_UIM
                    615: static void **UIM, *UIM1;
                    616:        checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimDeleteEndpointProc);
                    617: #endif
                    618: 
                    619:        if(UIMPlugIn[bus] != nil)
                    620:        {
                    621:                return(*UIMPlugIn[bus]->uimDeleteEndpointProc)(functionNumber, endpointNumber, direction);
                    622:        }
                    623:        return(-1);
                    624: }
                    625: 
                    626: OSStatus UIMBulkTransfer(
                    627:        UInt32 bus,
                    628:        UInt32                                          refcon,
                    629:        CallBackFuncPtr                         handler,
                    630:        UInt32                                          CBP,
                    631:        Boolean                                         bufferRounding,
                    632:        short                                           functionNumber,
                    633:        short                                           endpointNumber,
                    634:        UInt32                                          bufferSize,
                    635:        short                                           direction)
                    636: {
                    637: #if CHECK_UIM
                    638: static void **UIM, *UIM1;
                    639:        checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimCreateBulkTransferProc);
                    640: #endif
                    641: 
                    642:        if(UIMPlugIn[bus] != nil)
                    643:        {
                    644:                return(*UIMPlugIn[bus]->uimCreateBulkTransferProc)(
                    645:                refcon,
                    646:                handler,
                    647:                CBP,
                    648:                bufferRounding,
                    649:                functionNumber,
                    650:                endpointNumber,
                    651:                bufferSize,
                    652:                                direction);
                    653:        }
                    654:        return(-1);
                    655: }
                    656: 
                    657: OSStatus UIMIntTransfer(
                    658:        UInt32 bus,
                    659:        short                                           functionNumber,
                    660:        short                                           endpointNumber,
                    661:        UInt32                                          refcon,
                    662:        CallBackFuncPtr                         handler,
                    663:        UInt32                                          CBP,
                    664:        Boolean                                         bufferRounding,
                    665:        short                                           bufferSize)
                    666: {
                    667: #if CHECK_UIM
                    668: static void **UIM, *UIM1;
                    669:        checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimCreateInterruptTransferProc);
                    670: #endif
                    671: 
                    672:        if(UIMPlugIn[bus] != nil)
                    673:        {
                    674:                return(*UIMPlugIn[bus]->uimCreateInterruptTransferProc)(
                    675:                functionNumber,
                    676:                endpointNumber,
                    677:                refcon,
                    678:                handler,
                    679:                CBP,
                    680:                bufferRounding,
                    681:                bufferSize);
                    682:        }
                    683:        return(-1);
                    684: }
                    685: 
                    686: OSStatus UIMIsocTransfer(
                    687:        UInt32 bus,
                    688:        short                                           functionNumber,
                    689:        short                                           endpointNumber,
                    690:        short                                           direction,
                    691:        UInt32                                          frameStart, 
                    692:        UInt32                                          refcon,
                    693:        IsocCallBackFuncPtr                     handler,
                    694:        void                                            *buffer,
                    695:        UInt32                                          numFrames,
                    696:        USBIsocFrame                            *frames)
                    697: {
                    698: #if CHECK_UIM
                    699: static void **UIM, *UIM1;
                    700:        checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimCreateIsochTransferProc);
                    701: #endif
                    702: union{
                    703:        UInt64 u;
                    704:        UnsignedWide s;
                    705:        }startFrame;
                    706: 
                    707:        if(UIMPlugIn[bus] != nil)
                    708:        {
                    709:                startFrame.u = UIMGetCurrentFrame(bus);
                    710:                startFrame.s.lo = frameStart; /* this needs to be more sophisticated */
                    711:        
                    712:                return(*UIMPlugIn[bus]->uimCreateIsochTransferProc)(
                    713:                functionNumber,
                    714:                endpointNumber,
                    715:                refcon,
                    716:                direction,
                    717:                handler,
                    718:                startFrame.u,
                    719:                (UInt32)buffer,
                    720:                numFrames,
                    721:                frames);
                    722:        }
                    723:        return(-1);
                    724: }
                    725: /*
                    726: typedef CALLBACK_API_C( OSStatus , UIMCreateIsochTransferProcPtr )(
                    727: short functionAddress, 
                    728: short endpointNumber, 
                    729: UInt8 direction, 
                    730: short refcon, 
                    731: UInt32 pIsochHandler, 
                    732: UInt64 frameStart, 
                    733: UInt32 pBufferStart, 
                    734: UInt32 frameCount, 
                    735: USBIsocFrame *pFrames, 
                    736: UInt32 pStatus);
                    737: */
                    738: OSStatus UIMClearEndPointStall(
                    739:        UInt32 bus,
                    740:        short                                           functionNumber,
                    741:        short                                           endpointNumber,
                    742:        short                                           direction)
                    743: {
                    744: #if CHECK_UIM
                    745: static void **UIM, *UIM1;
                    746:        checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimClearEndPointStallProc);
                    747: #endif
                    748: 
                    749:        if(UIMPlugIn[bus] != nil)
                    750:        {
                    751:                return(*UIMPlugIn[bus]->uimClearEndPointStallProc)(functionNumber, endpointNumber, direction);
                    752:        }
                    753:        return(-1);
                    754: }
                    755: 
                    756: OSStatus UIMAbortEndpoint(
                    757:        UInt32 bus,
                    758:        short                                           functionNumber,
                    759:        short                                           endpointNumber,
                    760:        short                                           direction)
                    761: {
                    762: #if CHECK_UIM
                    763: static void **UIM, *UIM1;
                    764:        checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimAbortEndpointProc);
                    765: #endif
                    766: 
                    767:        if(UIMPlugIn[bus] != nil)
                    768:        {
                    769:                return(*UIMPlugIn[bus]->uimAbortEndpointProc)(
                    770:                                functionNumber, 
                    771:                                endpointNumber,
                    772:                                direction);
                    773:        }
                    774:        return(-1);
                    775: }
                    776: 
                    777: 
                    778: static OSStatus doUSLStatus(OSStatus status, USBReference ref)
                    779: {
                    780:        if(status != noErr)
                    781:        {
                    782:                if(status == EDDeleteErr)
                    783:                {
                    784:                        status = kUSBAbortedError;
                    785:                }
                    786:                else if(status == bandWidthFullErr)
                    787:                {
                    788:                        status = kUSBNoBandwidthError;
                    789:                }
                    790:                else if(status == returnedErr)
                    791:                {
                    792:                        status = kUSBAbortedError;
                    793:                }
                    794:                else
                    795:                {
                    796:                        if( (status > 0) && (status < 16))
                    797:                        {
                    798:                                /* As ferg points out all host contoller errors stall the pipe */
                    799:                                uslSetPipeStall(ref);                   
                    800:                        }
                    801:                        status = kUSBLinkErr+status;
                    802: #if 0
                    803:                        if( (status == kUSBCRCErr) ||
                    804:                                (status == kUSBBitstufErr) ||
                    805:                                (status == kUSBDataToggleErr) ||
                    806:                                (status == kUSBEndpointStallErr) ||
                    807:                                (status == kUSBNotRespondingErr) ||
                    808:                                (status == kUSBPIDCheckErr) ||
                    809:                                (status == kUSBWrongPIDErr) )
                    810:                        {
                    811:                                uslSetPipeStall(ref);
                    812:                        }
                    813: #endif
                    814:                }
                    815:        }
                    816:        return(status);
                    817: }
                    818: 
                    819: 
                    820: static void intPktHandler(long refCon, OSStatus status, short shortfall)
                    821: {
                    822: USBPB *pb;
                    823: 
                    824:        if(refCon == 0)
                    825:        {
                    826:                return;
                    827:        }
                    828: 
                    829:        pb = (void *)refCon;
                    830: 
                    831:        status = doUSLStatus(status, pb->usbReference);
                    832: 
                    833:        pb->usbStatus = status;
                    834:        pb->usbActCount = pb->usbReqCount - shortfall;
                    835:        if (pb->usbCompletion && (pb->usbCompletion != kUSBNoCallBack))
                    836:                (*pb->usbCompletion)(pb);
                    837: }
                    838: 
                    839: static void bulkPktHandler(long refCon, OSStatus status, short shortfall)
                    840: {
                    841: USBPB *pb;
                    842: 
                    843:        if(refCon == 0)
                    844:        {
                    845:                return;
                    846:        }
                    847: 
                    848:        pb = (void *)refCon;
                    849: 
                    850:        status = doUSLStatus(status, pb->usbReference);
                    851: 
                    852:        pb->usbStatus = status;
                    853:        if(shortfall > pb->usbReqCount)
                    854:        {
                    855:                pb->usbActCount = 0;
                    856:        }
                    857:        else
                    858:        {
                    859:                pb->usbActCount = pb->usbReqCount - shortfall;
                    860:        }
                    861: 
                    862:        if(pb->usbFlags)
                    863:        {
                    864:                resolvePerformance(pb);
                    865:        }
                    866: 
                    867:        if (pb->usbCompletion && (pb->usbCompletion != kUSBNoCallBack))
                    868:                (*pb->usbCompletion)(pb);
                    869: }
                    870: 
                    871: static void isocPktHandler(long refCon, OSStatus status, USBIsocFrame *pFrames)
                    872: {
                    873: USBPB *pb;
                    874: OSStatus aggregate = noErr;
                    875: UInt32 actCount = 0, frame;
                    876: 
                    877:        if(refCon == 0)
                    878:        {
                    879:                return;
                    880:        }
                    881: 
                    882:        pb = (void *)refCon;
                    883: 
                    884:        actCount = 0;
                    885:        for(frame = 0; frame < pb->usb.isoc.NumFrames; frame++)
                    886:        {
                    887:                actCount += pFrames[frame].frActCount;
                    888:                if(pFrames[frame].frStatus != noErr)
                    889:                {
                    890:                        aggregate = pFrames[frame].frStatus;
                    891:                }
                    892:        }
                    893:        pb->usbActCount = actCount;
                    894:        
                    895:        if(status == noErr)
                    896:        {
                    897:                pb->usbStatus = aggregate;
                    898:        }
                    899:        else
                    900:        {
                    901:                pb->usbStatus = status;
                    902:        }
                    903:        if(pb->usbStatus != noErr)
                    904:        {
                    905:                pb->usbStatus = kUSBLinkErr+pb->usbStatus;
                    906:        }
                    907: 
                    908:        if ( (pb->usbCompletion != nil) && (pb->usbCompletion != kUSBNoCallBack))
                    909:        {
                    910:                (*pb->usbCompletion)(pb);
                    911:        }
                    912: }
                    913: 
                    914: static void ctlPktHandler(long refCon, OSStatus status, short shortfall)
                    915: {
                    916: UInt8 sent, back, todo;
                    917: USBPB *pb;
                    918: Boolean callBackTIme;
                    919: UInt32 bus;
                    920: 
                    921:        if(refCon == 0)
                    922:        {
                    923:                return;
                    924:        }
                    925: 
                    926: 
                    927:        pb = (void *)(refCon & ~1);
                    928:        callBackTIme = ((refCon & 1) != 0);
                    929: 
                    930:        sent = (pb->reserved1 &0xf) << 4;
                    931:        back = pb->reserved1 &0xf0;
                    932:        todo = sent ^ back;     /* thats xor */
                    933:        
                    934:        if((todo & kSetupBack) != 0)
                    935:        {
                    936:                pb->reserved1 |= kSetupBack;
                    937: 
                    938:        }
                    939:        else if((todo & kDataBack) != 0)
                    940:        {       /* This is the data transport phase, so this is the interesting one */
                    941:                pb->reserved1 |= kDataBack;
                    942:                pb->usbActCount = pb->usbReqCount - shortfall;  
                    943:        }
                    944:        else if((todo & kStatusBack) != 0)
                    945:        {
                    946:                pb->reserved1 |= kStatusBack;
                    947:                
                    948:        }
                    949:        else
                    950:        {
                    951:                USBExpertStatus(-1, "Spare transactions, This seems to be harmless", 0);
                    952:        }
                    953: 
                    954:        back = pb->reserved1 &0xf0;
                    955:        todo = sent ^ back;     /* thats xor */
                    956: 
                    957:        if( (status != noErr) && (status != returnedErr) )
                    958:        {
                    959:        UInt8 addr, endpt;
                    960:                addr = ( (pb->usbFlags) &kUSLAddrMask) >> kUSLAddrShift;
                    961:                endpt = ( (pb->usbFlags &kUSLEndpMask) >> kUSLEndpShift);
                    962:                bus = ( (pb->usbFlags &kUSLBusMask) >> kUSLBusShift);
                    963: 
                    964:                pb->usbStatus = doUSLStatus(status, pb->usbReference);
                    965:                if(endpt == 0)
                    966:                {
                    967:                        UIMClearEndPointStall(bus, addr, endpt, 0);
                    968:                }
                    969:                
                    970:        }
                    971: 
                    972: 
                    973:        if( callBackTIme || (todo == 0) )
                    974:        {
                    975:                if( !callBackTIme || (todo != 0) )      /* One but not the other */
                    976:                {
                    977:                        USBExpertStatus(-1, "UIM Interface odd completion", 0);
                    978:                }
                    979:                pb->usbFlags &= ~(kUSLAddrMask|kUSLEndpMask|kUSLBusMask);
                    980: 
                    981:                if(status == noErr)
                    982:                {
                    983:                        if(pb->usbStatus != kUSBPending)
                    984:                        {
                    985:                                USBExpertStatus(-1, "UIM Interface odd status", 0);
                    986:                        }
                    987:                        pb->usbStatus = noErr;
                    988:                }
                    989:                
                    990:                pb->usb.cntl.WIndex = USBToHostWord(pb->usb.cntl.WIndex);
                    991:                pb->usb.cntl.WValue = USBToHostWord(pb->usb.cntl.WValue);
                    992:                if (pb->usbCompletion && (pb->usbCompletion != kUSBNoCallBack))
                    993:                        (*pb->usbCompletion)(pb); 
                    994:        }
                    995: }
                    996: 
                    997: OSStatus usbIsocPacket(UInt32 bus, USBPB *pb, UInt8 address, UInt8 endpoint, UInt8 direction)
                    998: {
                    999: OSStatus err;
                   1000: 
                   1001:        pb->usbStatus = noErr;
                   1002:        
                   1003:        err = UIMIsocTransfer(bus,
                   1004:                                                address /* address */,
                   1005:                                                endpoint /* endpoint */,
                   1006:                                                direction /* in or out */,
                   1007:                                                pb->usbFrame /* starting frame */,
                   1008:                                                (UInt32)pb /* refcon */, 
                   1009:                                                isocPktHandler,
                   1010:                                                pb->usbBuffer /* buffer */, 
                   1011:                                                pb->usb.isoc.NumFrames,
                   1012:                                                pb->usb.isoc.FrameList
                   1013:                                                );
                   1014: 
                   1015: #if 0
                   1016:        if(err != noErr)
                   1017:        {
                   1018:                isocPktHandler((UInt32)pb, err, pb->usb.isoc.FrameList);
                   1019:        }
                   1020: #else
                   1021:        return(err);
                   1022: #endif
                   1023: 
                   1024: }
                   1025: 
                   1026: OSStatus usbIntPacket(UInt32 bus, USBPB *pb, UInt8 address, UInt8 endpoint, UInt8 direction)
                   1027: {
                   1028: OSStatus err;
                   1029:        direction = 0;  /* Not used */
                   1030: 
                   1031:        pb->usbStatus = noErr;
                   1032: kprintf("usbIntPacket:Calling UIMIntTransfer:addr=%d,ep=%d,reqcount=%d\n",address,endpoint,pb->usbReqCount);
                   1033:        err = UIMIntTransfer(bus,
                   1034:                                                address,
                   1035:                                                endpoint,
                   1036:                                                (UInt32)pb /* refcon */, 
                   1037:                                                intPktHandler,
                   1038:                                                (UInt32)pb->usbBuffer /* buffer */, 
                   1039:                                                true /* short packets OK */,
                   1040:                                                pb->usbReqCount /* buffer size */);
                   1041: kprintf("usbIntPacket:UIMTransfer returned err=%d\n",err);
                   1042: 
                   1043:        return(err);
                   1044: }
                   1045: 
                   1046: 
                   1047: OSStatus usbBulkPacket(UInt32 bus, USBPB *pb, UInt8 address, UInt8 endpoint, UInt8 direction)
                   1048: {
                   1049: OSStatus err;
                   1050: 
                   1051:        pb->usbStatus = noErr;
                   1052:        
                   1053:        err = UIMBulkTransfer(bus,
                   1054:                                                (UInt32)pb /* refcon */, 
                   1055:                                                bulkPktHandler,
                   1056:                                                (UInt32)pb->usbBuffer /* buffer */, 
                   1057:                                                true /* short packets OK */,
                   1058:                                                address /* address */,
                   1059:                                                endpoint /* endpoint */,
                   1060:                                                pb->usbReqCount /* buffer size */,
                   1061:                                                direction /* in or out */);
                   1062: 
                   1063:        return(err);
                   1064: }
                   1065: 
                   1066: #define kUSBSetup kUSBNone
                   1067: 
                   1068: OSStatus usbControlPacket(UInt32 bus, USBPB *pb, UInt8 address, UInt8 endpoint)
                   1069: {
                   1070: OSStatus err;
                   1071: short dirn;
                   1072:        
                   1073: 
                   1074:        if( ((UInt32)pb &1) != 0)
                   1075:        {
                   1076:                USBExpertStatus(-1, "Missaligned PB", 0);
                   1077:        }
                   1078: 
                   1079:        /* Remeber address and endpoint here for later */
                   1080:        pb->usbFlags |= (address << kUSLAddrShift)+(endpoint << kUSLEndpShift)+(bus << kUSLBusShift);
                   1081: 
                   1082:        do{
                   1083:        pb->reserved1 = 0;      /* stage pointer */
                   1084:        pb->usbStatus = kUSBPending;
                   1085:        pb->usbActCount = 0;
                   1086:        
                   1087:        pb->reserved1 |= kSetupSent;
                   1088: //kprintf("usbControlPacket:addr=%d,ep=%d\n",address,endpoint);
                   1089:        err = UIMControlTransfer(bus,
                   1090:                                                        (UInt32)pb/* refcon */,
                   1091:                                                        ctlPktHandler,
                   1092:                                                        (UInt32)&pb->usb.cntl.BMRequestType /* packet */, 
                   1093:                                                        true /* short packets OK */,
                   1094:                                                        address /* address */,
                   1095:                                                        endpoint /* endpoint */,
                   1096:                                                        8 /* packet size */,
                   1097:                                                        kUSBSetup /* setup */);
                   1098: //kprintf("usbControlPacket:After first call refcon(pb)=0x%x,err=%d\n",pb,err);
                   1099:        if(err != noErr)
                   1100:        {
                   1101:                pb->usbFlags  = 0;
                   1102:                USBExpertStatus(-1, "Control packet 1 error", err);
                   1103:                break;
                   1104:        }
                   1105:        
                   1106:        dirn = ((pb->usb.cntl.BMRequestType & 0x80) == 0)?kUSBOut:kUSBIn;
                   1107:        if(pb->usb.cntl.reserved4 != 0)
                   1108:        {
                   1109:                pb->reserved1 |= kDataSent;
                   1110:                err = UIMControlTransfer(bus,
                   1111:                                                        (UInt32)pb /* refcon */, 
                   1112:                                                        ctlPktHandler,
                   1113:                                                        (UInt32)pb->usbBuffer /* buffer */, 
                   1114:                                                        true /* short packets OK */,
                   1115:                                                        address /* address */,
                   1116:                                                        endpoint /* endpoint */,
                   1117:                                                        pb->usbReqCount /* buffer size */,
                   1118:                                                        dirn /* in or out */);
                   1119:                if(err != noErr)
                   1120:                {
                   1121:                        USBExpertStatus(-1, "Control packet 2 error", err);
                   1122:                        break;
                   1123:                }
                   1124: //kprintf("usbControlPacket:After second(data phase)call refcon(pb)=0x%x,err=%d\n",pb,err);
                   1125: 
                   1126:        }
                   1127: 
                   1128:        dirn = kUSBOut+kUSBIn - dirn;
                   1129: 
                   1130:        pb->reserved1 |= kStatusSent;
                   1131:        err = UIMControlTransfer(bus,
                   1132:                                                (UInt32)pb | 1 /* refcon, with marker */, 
                   1133:                                                ctlPktHandler,
                   1134:                                                0 /* buffer, for no data transfer */, 
                   1135:                                                true /* short packets OK */,
                   1136:                                                address /* address */,
                   1137:                                                endpoint /* endpoint */,
                   1138:                                                0 /* buffer size */,
                   1139:                                                dirn /* in or out */);
                   1140: 
                   1141: //kprintf("usbControlPacket:After third(status phase)call refcon(pb)=0x%x,err=%d\n",(UInt32)pb | 1,err);
                   1142:        if(err != noErr)
                   1143:        {
                   1144:                USBExpertStatus(-1, "Control packet 3 error", err);
                   1145:        }
                   1146: 
                   1147:        }while(0);
                   1148: 
                   1149:        return(err);
                   1150: }
                   1151: 
                   1152: OSStatus uslProbeEndpoint(USBPB *pb, UInt8 address, UInt8 endpoint);
                   1153: 
                   1154: OSStatus uslProbeEndpoint(USBPB *pb, UInt8 address, UInt8 endpoint)
                   1155: {
                   1156: OSStatus err;
                   1157: UInt32  bus;
                   1158: 
                   1159:        if      (address > 127)
                   1160:        {       
                   1161:                if(rootHubRefs[255-address] == 0)
                   1162:                {
                   1163:                        return(kUSBUnknownDeviceErr);
                   1164:                }
                   1165:                address = rootHubRefs[255-address] & 0x7f;
                   1166:        }
                   1167:        
                   1168:        if ((bus = uslDeviceAddrToBus(address)) >= kMaxBus)
                   1169:        {
                   1170:                return(kUSBUnknownDeviceErr);
                   1171:        }
                   1172:        
                   1173:        pb->usbStatus = kUSBPending;
                   1174:        err = usbControlPacket(bus, pb, address, endpoint);
                   1175:        
                   1176:        return(err);
                   1177: }
                   1178: 
                   1179: 
                   1180: 
                   1181: 
                   1182: 

unix.superglobalmegacorp.com

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