Annotation of driverkit/libDriver/volCheck.m, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
        !             7:  * Reserved.  This file contains Original Code and/or Modifications of
        !             8:  * Original Code as defined in and that are subject to the Apple Public
        !             9:  * Source License Version 1.1 (the "License").  You may not use this file
        !            10:  * except in compliance with the License.  Please obtain a copy of the
        !            11:  * License at http://www.apple.com/publicsource and read it before using
        !            12:  * this file.
        !            13:  * 
        !            14:  * The Original Code and all software distributed under the License are
        !            15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
        !            19:  * License for the specific language governing rights and limitations
        !            20:  * under the License.
        !            21:  * 
        !            22:  * @APPLE_LICENSE_HEADER_END@
        !            23:  */
        !            24: /*     Copyright (c) 1991 NeXT Computer, Inc.  All rights reserved. 
        !            25:  *
        !            26:  * volCheck.m - common volume check logic for all DiskObjects.
        !            27:  *
        !            28:  * This only does useful work in the kernel, since it relies heavily
        !            29:  * on the vol driver functionality. Someday we'll have to come up 
        !            30:  * with a new interface bewteen WS and a user-level version of this.
        !            31:  *
        !            32:  * HISTORY
        !            33:  * 07-May-91    Doug Mitchell at NeXT
        !            34:  *      Created.
        !            35:  */
        !            36: #import <driverkit/IODisk.h>
        !            37: #import <driverkit/IODiskPartition.h>
        !            38: #import <machkit/NXLock.h>
        !            39: #import <kernserv/queue.h>
        !            40: #import <driverkit/generalFuncs.h>
        !            41: #import <driverkit/Device_ddm.h>
        !            42: #import <driverkit/IODeviceDescription.h>
        !            43: #import <bsd/dev/disk.h>
        !            44: 
        !            45: #undef DRIVER_PRIVATE
        !            46: #define DRIVER_PRIVATE
        !            47: 
        !            48: #ifdef KERNEL
        !            49: #import <kernserv/prototypes.h>
        !            50: #import <bsd/dev/voldev.h>
        !            51: #else  KERNEL
        !            52: #import <bsd/libc.h>
        !            53: #import "volDriver.h"
        !            54: #endif KERNEL
        !            55: 
        !            56: #import <driverkit/volCheck.h>
        !            57: #import "volCheckPrivate.h"
        !            58: 
        !            59: /*
        !            60:  * Static data.
        !            61:  */
        !            62: /*
        !            63:  * Queue of volCheckEntry_t's. One per removable disk drive. It's not
        !            64:  * protected with a lock; all accesses to this queue are by the 
        !            65:  * volCheckThread.
        !            66:  */
        !            67: static queue_head_t volCheckEntryQ;
        !            68: 
        !            69: /*
        !            70:  * Input queue. Commands are queued here by public routines to ensure 
        !            71:  * single-threaded response to change in device state.
        !            72:  */
        !            73: static queue_head_t volCheckCmdQ;
        !            74: static id volCheckCmdLock;
        !            75:  
        !            76: /*
        !            77:  * Prototypes of static functions.
        !            78:  */
        !            79: static void volCheckThread(void *foo);
        !            80: static void volCheckResponse(void *param, 
        !            81:        int tag, 
        !            82:        int response_value);
        !            83: static volCheckEntry_t *getVCEntry(id diskObj);
        !            84: static void vcEnqueueCmd(volCheckOp_t op,
        !            85:        id diskObj,
        !            86:        int diskType,
        !            87:        dev_t blockDev,
        !            88:        dev_t rawDev);
        !            89: static void volCheckCmdHandler();
        !            90: static void volDriverNotify(id diskObj,
        !            91:        dev_t blockDev,
        !            92:        dev_t rawDev);
        !            93: 
        !            94: /*
        !            95:  * Public functions.
        !            96:  */
        !            97:  
        !            98: /*
        !            99:  * One-time only initialization.
        !           100:  */
        !           101: void volCheckInit()
        !           102: {
        !           103:        volCheckCmdLock = [NXSpinLock new];
        !           104:        queue_init(&volCheckEntryQ);
        !           105:        queue_init(&volCheckCmdQ);
        !           106:        
        !           107:        /*
        !           108:         * FIXME - only start up a thread when we get the first 
        !           109:         * volCheckRegister().
        !           110:         */
        !           111:        IOForkThread((IOThreadFunc)volCheckThread, NULL);
        !           112: #ifndef        KERNEL
        !           113:        volDriverInit();
        !           114: #endif KERNEL
        !           115: }
        !           116: 
        !           117: /*
        !           118:  * These public routines queue up a command on volCheckCmdQ to ensure
        !           119:  * single-threaded handling of lastReadyState transitions.
        !           120:  */
        !           121: /*
        !           122:  * Register a removable media drive. This should be called once for the
        !           123:  * physical disk object, not for any LogicalDisks which sit on top of it.
        !           124:  */
        !           125: void volCheckRegister(id diskObj,
        !           126:        dev_t blockDev,
        !           127:        dev_t rawDev)
        !           128: {      
        !           129:        xpr_vc("volCheckRegister: disk %s\n", [diskObj name], 2,3,4,5);
        !           130:        if(![diskObj isPhysical]) {
        !           131:                IOLog("volCheckRegister: %s is not a physical device\n",
        !           132:                        [diskObj name]);
        !           133:                return;
        !           134:        }
        !           135:        vcEnqueueCmd(VC_REGISTER,
        !           136:                diskObj,
        !           137:                0,
        !           138:                blockDev,
        !           139:                rawDev);
        !           140: }
        !           141: 
        !           142: /*
        !           143:  * Unregister a removable media drive. This probably should never happen,
        !           144:  * at least not in the kernel...
        !           145:  */
        !           146: void volCheckUnregister(id diskObj)
        !           147: {
        !           148:        xpr_vc("volCheckUnregister: disk %s\n", 
        !           149:                [diskObj name], 2,3,4,5);
        !           150:        vcEnqueueCmd(VC_UNREGISTER,
        !           151:                diskObj,
        !           152:                0,
        !           153:                0,
        !           154:                0);
        !           155: }
        !           156: 
        !           157: /*
        !           158:  * Request a "please insert disk" panel. Called by physDevice DiskObject.
        !           159:  *
        !           160:  * For now, we don't have a connection with WS unless we're in the 
        !           161:  * kernel.
        !           162:  */
        !           163: void volCheckRequest(id diskObj,               // requestor
        !           164:        int diskType)                           // PR_DRIVE_FLOPPY, etc.
        !           165: {
        !           166:        xpr_vc("volCheckRequest: disk %s\n", 
        !           167:                [diskObj name], 2,3,4,5);
        !           168:        vcEnqueueCmd(VC_REQUEST,
        !           169:                diskObj,
        !           170:                diskType,
        !           171:                0,
        !           172:                0);
        !           173: }
        !           174: 
        !           175: /*
        !           176:  * Notify volCheck that specified device is in a "disk ejecting" state.
        !           177:  * Called by physDevice DiskObject in ejectPhysical:. Only necessary 
        !           178:  * for drives which may not respond to autoeject. Thus floppy drivers shouldn't
        !           179:  * have to call this.
        !           180:  *
        !           181:  * NOTE: we force the low-level driver to pass in diskType in this call
        !           182:  * and in volCheckRequest() to avoid having DiskObject know this 
        !           183:  * detail at registerDisk: time...
        !           184:  */
        !           185: void volCheckEjecting(id diskObj,
        !           186:        int diskType)                           // PR_DRIVE_FLOPPY, etc.
        !           187: {
        !           188:        xpr_vc("volCheckEjecting: disk %s\n", [diskObj name], 2,3,4,5);
        !           189:        
        !           190:        vcEnqueueCmd(VC_EJECTING,
        !           191:                diskObj,
        !           192:                diskType,
        !           193:                0,
        !           194:                0);
        !           195: }
        !           196: 
        !           197: /*
        !           198:  * Notify volCheck that disk has gone not ready. Typically called on
        !           199:  * gross error detection.
        !           200:  */
        !           201: void volCheckNotReady(id diskObj)
        !           202: {
        !           203:        xpr_vc("volCheckNotReady: disk %s\n", [diskObj name], 2,3,4,5);
        !           204:        vcEnqueueCmd(VC_NOTREADY,
        !           205:                diskObj,
        !           206:                0,
        !           207:                0,
        !           208:                0);
        !           209: }
        !           210: 
        !           211: /*
        !           212:  * Private functions.
        !           213:  */
        !           214: /*
        !           215:  * Get the volCheckEntry_t for specified DiskObject id.
        !           216:  */
        !           217: static volCheckEntry_t *getVCEntry(id diskObj)
        !           218: {
        !           219:        volCheckEntry_t *vcEntry;
        !           220:        
        !           221:        vcEntry = (volCheckEntry_t *)queue_first(&volCheckEntryQ);
        !           222:        while(!queue_end(&volCheckEntryQ, (queue_t)vcEntry)) {
        !           223:                if(vcEntry->diskObj == diskObj)
        !           224:                        return(vcEntry);
        !           225:                vcEntry = (volCheckEntry_t *)vcEntry->link.next;
        !           226:        }
        !           227:        xpr_err("getVCEntry: ENTRY NOT FOUND\n", 1,2,3,4,5);
        !           228:        return(NULL);
        !           229: }
        !           230: 
        !           231: /*
        !           232:  * Enqueue a command on volCheckCmdQ. Called by public routines.
        !           233:  */
        !           234: static void vcEnqueueCmd(volCheckOp_t op,
        !           235:                id diskObj,
        !           236:                int diskType,
        !           237:                dev_t blockDev,
        !           238:                dev_t rawDev)
        !           239: {
        !           240:        volCheckCmd_t *vcCmd;
        !           241:        
        !           242:        vcCmd           = IOMalloc(sizeof(*vcCmd));
        !           243:        vcCmd->op       = op;
        !           244:        vcCmd->diskObj  = diskObj;
        !           245:        vcCmd->diskType = diskType;
        !           246:        vcCmd->blockDev = blockDev;
        !           247:        vcCmd->rawDev   = rawDev;
        !           248:        [volCheckCmdLock lock];
        !           249:        queue_enter(&volCheckCmdQ,
        !           250:                vcCmd,
        !           251:                volCheckCmd_t *,
        !           252:                link);
        !           253:        [volCheckCmdLock unlock];
        !           254: }
        !           255: 
        !           256: /*
        !           257:  * Called by vol driver upon reception of panel response. The only 
        !           258:  * response we know about is an abort...do we need others? All we do
        !           259:  * is forward this notification to the appropriate DiskObject.
        !           260:  */
        !           261: static void volCheckResponse(void *param,      
        !           262:        int tag, 
        !           263:        int response_value)
        !           264: {
        !           265:        id diskObj = (id)param;
        !           266:        
        !           267:        xpr_vc("volCheckResponse disk %s\n", [diskObj name], 2,3,4,5);
        !           268:        vcEnqueueCmd(VC_RESPONSE,
        !           269:                diskObj,
        !           270:                0,
        !           271:                0,
        !           272:                0);
        !           273: }
        !           274: 
        !           275: /*
        !           276:  * volCheck thread function. Max of two per system (one in the kernel,
        !           277:  * one in user space).
        !           278:  */
        !           279: static void volCheckThread(void *foo)
        !           280: {
        !           281: 
        !           282:        volCheckEntry_t *vcEntry;
        !           283:        IODiskReadyState lastReadyState;
        !           284:        IODiskReadyState newReadyState = IO_NotReady;   // damned compiler!
        !           285:        const char *devname;
        !           286:        id diskObj;
        !           287:        int manualPoll;
        !           288:        
        !           289:        while(1) {
        !           290:        
        !           291:            /*
        !           292:             * First handle any queued commands.
        !           293:             */
        !           294:            volCheckCmdHandler();
        !           295:            
        !           296:            /*
        !           297:             * Process each registered disk.
        !           298:             */
        !           299:            vcEntry = (volCheckEntry_t *)queue_first(&volCheckEntryQ);
        !           300:            manualPoll = vol_check_manual_poll();
        !           301:            while(!queue_end(&volCheckEntryQ, (queue_t)vcEntry)) {
        !           302:            
        !           303:                devname = [vcEntry->diskObj name];
        !           304:                diskObj = vcEntry->diskObj;
        !           305:                lastReadyState = [diskObj lastReadyState];
        !           306:                if(lastReadyState != IO_Ready) {
        !           307:                        /*
        !           308:                         * Poll for transition if:
        !           309:                         * -- this is a normal once-per-second polling 
        !           310:                         *    drive, or
        !           311:                         * -- vol driver tells us it's time to poll, or
        !           312:                         * -- ready state is Ejecting
        !           313:                         */
        !           314:                        if(![vcEntry->diskObj needsManualPolling] ||
        !           315:                                        manualPoll ||
        !           316:                                        (lastReadyState == IO_Ejecting)) {
        !           317:                                newReadyState = [diskObj updateReadyState];
        !           318:                        }
        !           319:                        else {
        !           320:                                /*
        !           321:                                 * Don't poll; assume state unchanged.
        !           322:                                 */
        !           323:                                newReadyState = lastReadyState;
        !           324:                        }   
        !           325:                }
        !           326:                switch(lastReadyState) {
        !           327:                    case IO_Ready:
        !           328:                        break;          // nothing to do here
        !           329:                        
        !           330:                    case IO_Ejecting:
        !           331:                        /*
        !           332:                         * We hope to see a transition to not ready or
        !           333:                         * no disk...when we see "ready" enough times,
        !           334:                         * we'll ask the WS to put up a "please eject disk"
        !           335:                         * panel.
        !           336:                         */
        !           337:                        if(newReadyState == IO_Ready) {
        !           338:                            if(--vcEntry->ejectCounter == 0) {
        !           339:                                xpr_vc("volCheck: requesting disk eject"
        !           340:                                    " panel for disk %s\n", devname,
        !           341:                                    2,3,4,5);
        !           342:                                vol_panel_request(NULL,     // no callback
        !           343:                                    PR_RT_EJECT_REQ,
        !           344:                                    PR_RT_CANCEL,           // leave up 'til
        !           345:                                                            // we take it
        !           346:                                                            // down
        !           347:                                    0,                      // p1, not used
        !           348:                                    vcEntry->diskType,      // p2
        !           349:                                    [diskObj unit],         // p3
        !           350:                                    0,                      // p4, not used
        !           351:                                    "",                     // string1
        !           352:                                    "",                     // string2
        !           353:                                    NULL,                   // no callback
        !           354:                                    &vcEntry->tag);
        !           355:                                vcEntry->ejectRequestPending = YES;
        !           356:                                
        !           357:                            }           /* counter 0 */
        !           358:                        }               /* still ready */
        !           359:                        else {
        !           360:                        
        !           361:                            /*
        !           362:                             * Allright! It went not ready. Remove 
        !           363:                             * eject request panel if present.
        !           364:                             */
        !           365:                            xpr_vc("volCheck: %s: Eject Complete\n",
        !           366:                                    devname, 2,3,4,5);
        !           367:                            [diskObj setLastReadyState:IO_NoDisk];
        !           368:                            if(vcEntry->ejectRequestPending) {
        !           369:                                vcEntry->ejectRequestPending  = NO;
        !           370:                                vol_panel_remove(vcEntry->tag);
        !           371:                            }
        !           372:                        }               /* not ready/not present */
        !           373:                        break;          /* from case IO_Ejecting */
        !           374:                                                
        !           375:                    case IO_NotReady:
        !           376:                    case IO_NoDisk:
        !           377:                        /*
        !           378:                         * The drive wasn't ready the last time we checked.
        !           379:                         * We're interested in transitions to a ready state,
        !           380:                         * indicating disk insertion. 
        !           381:                         */
        !           382:                        if(newReadyState == IO_Ready) {
        !           383:                            
        !           384:                            id descr;
        !           385:                            
        !           386:                            [diskObj setLastReadyState:IO_Ready];
        !           387:                            if(vcEntry->diskRequestPending) {
        !           388:                                /*
        !           389:                                 * Cancel the panel.
        !           390:                                 */
        !           391:                                xpr_vc("volCheck: cancelling request panel"
        !           392:                                    " for %s\n", devname, 2,3,4,5);
        !           393:                                vol_panel_remove(vcEntry->tag);
        !           394:                            }
        !           395:                        
        !           396:                           /* 
        !           397:                            * Have the driver get other physical parameters.
        !           398:                            */
        !           399:                           [diskObj updatePhysicalParameters];
        !           400: 
        !           401:                            /*
        !           402:                             * Notify driver whether or not we think it
        !           403:                             * is waiting for this disk to cover race 
        !           404:                             * conditions between panels and insertions. 
        !           405:                             * Then take care of layering some 
        !           406:                             * IODiskPartitions on top of this new disk.
        !           407:                             * We have to do this before a possible 
        !           408:                             * vol_notify_dev().
        !           409:                             */
        !           410:                            [diskObj diskBecameReady];
        !           411:                            descr = [IODeviceDescription new];
        !           412:                            [descr setDirectDevice:diskObj];
        !           413:                            if(![IODiskPartition probe:descr]) {
        !           414:                                    [descr free];
        !           415:                            }
        !           416: 
        !           417:                            if(vcEntry->diskRequestPending) {
        !           418:                                vcEntry->diskRequestPending = NO;
        !           419:                            }
        !           420:                            else {
        !           421:                                /*
        !           422:                                 * Unexpected disk insertion. Notify WS.
        !           423:                                 * We are the one to determine whether it has
        !           424:                                 * a valid label. We also have to gather
        !           425:                                 * other cruft like write protect for use by
        !           426:                                 * WS.
        !           427:                                 */
        !           428:                                volDriverNotify(diskObj, vcEntry->blockDev,
        !           429:                                        vcEntry->rawDev);
        !           430:                                        
        !           431:                            }   /* new disk insertion */
        !           432:                        }       /* new state == ready */
        !           433:                                /* else no action (wasn't ready, still 
        !           434:                                 * isn't) */
        !           435:                        break;  /* from case not ready/no disk */
        !           436:                }               /* switch lastReadyState */
        !           437: 
        !           438:                /*
        !           439:                 * Next disk.
        !           440:                 */
        !           441:                vcEntry = (volCheckEntry_t *)vcEntry->link.next;
        !           442:            }
        !           443:            
        !           444:            /*
        !           445:             * OK, sleep a while.
        !           446:             */
        !           447:            IOSleep(1000);
        !           448:            
        !           449:        } /* while 1 */
        !           450:        
        !           451:        /* NOT REACHED */
        !           452:         
        !           453: }
        !           454: 
        !           455: /*
        !           456:  * Handle queued commands.
        !           457:  */
        !           458: static void volCheckCmdHandler()
        !           459: {
        !           460:        volCheckCmd_t *vcCmd;
        !           461:        volCheckEntry_t *vcEntry = NULL;
        !           462:        id diskObj;
        !           463:        IODiskReadyState readyState;
        !           464:        
        !           465:        [volCheckCmdLock lock];
        !           466:        while(!queue_empty(&volCheckCmdQ)) {
        !           467:                vcCmd = (volCheckCmd_t *)queue_first(&volCheckCmdQ);
        !           468:                queue_remove(&volCheckCmdQ,
        !           469:                        vcCmd,
        !           470:                        volCheckCmd_t *,
        !           471:                        link);
        !           472:                [volCheckCmdLock unlock];
        !           473:                diskObj = vcCmd->diskObj;
        !           474:                if(vcCmd->op != VC_REGISTER) {
        !           475:                        vcEntry = getVCEntry(diskObj);
        !           476:                        if(vcEntry == NULL) {
        !           477:                                IOLog("volCheck: disk %s not "
        !           478:                                        "registered, cmd = %d\n",
        !           479:                                        [diskObj name], vcCmd->op);
        !           480:                                goto freeCmd;
        !           481:                        }
        !           482: 
        !           483:                }
        !           484:                switch(vcCmd->op) {
        !           485:                    case VC_REGISTER:
        !           486:                        xpr_vc("volCheck: registering disk %s\n", 
        !           487:                                [diskObj name], 2,3,4,5);
        !           488: #if 1
        !           489:                        /*
        !           490:                         * We should use the current state since that
        !           491:                         * indicates whether or the disk has been probed
        !           492:                         * at registration. It may have come ready after
        !           493:                         * probe, but before we get here.
        !           494:                         */
        !           495:                        readyState = [diskObj lastReadyState];
        !           496: #else
        !           497:                        readyState = [diskObj updateReadyState];
        !           498:                        /* 
        !           499:                         * IODiskPartition does this too, but we have to do
        !           500:                         * it here as well in case we run before 
        !           501:                         * IODiskPartition does this.
        !           502:                         */
        !           503:                        [diskObj setLastReadyState:readyState];
        !           504: #endif
        !           505:                        
        !           506:                        /* 
        !           507:                         * If ready now, go ahead and notify vol driver. 
        !           508:                         */
        !           509:                        if(readyState == IO_Ready) {
        !           510:                                /*
        !           511:                                 * If this disk is not removable and 
        !           512:                                 * it's currently ready, we have no 
        !           513:                                 * reason to do anything other than 
        !           514:                                 * the initial notify.
        !           515:                                 */
        !           516:                                volDriverNotify(diskObj, vcCmd->blockDev, 
        !           517:                                                vcCmd->rawDev);
        !           518:                                        
        !           519: 
        !           520:                                if(![diskObj isRemovable]) {
        !           521:                                        /* 
        !           522:                                         * If ready now, go ahead and 
        !           523:                                         * notify vol driver. 
        !           524:                                         */
        !           525:                                        break;
        !           526:                                };
        !           527:                        }
        !           528:                        
        !           529:                        vcEntry = IOMalloc(sizeof(*vcEntry));
        !           530:                        vcEntry->diskObj             = diskObj;
        !           531:                        vcEntry->blockDev            = vcCmd->blockDev;
        !           532:                        vcEntry->rawDev              = vcCmd->rawDev;
        !           533:                        vcEntry->ejectCounter        = 0;
        !           534:                        vcEntry->ejectRequestPending = NO;
        !           535:                        vcEntry->diskRequestPending  = NO;
        !           536:                        vcEntry->diskType            = vcCmd->diskType;
        !           537:                        queue_enter(&volCheckEntryQ, 
        !           538:                                vcEntry, 
        !           539:                                volCheckEntry_t *, 
        !           540:                                link);
        !           541:                        break;
        !           542: 
        !           543:                    case VC_UNREGISTER:
        !           544:                        xpr_vc("volCheck: unregistering disk %s\n", 
        !           545:                                [vcCmd->diskObj name], 2,3,4,5);
        !           546:                        queue_remove(&volCheckEntryQ, 
        !           547:                                vcEntry, 
        !           548:                                volCheckEntry_t *, 
        !           549:                                link);
        !           550:                        IOFree(vcEntry, sizeof(*vcEntry));
        !           551:                        break;
        !           552:                        
        !           553:                    case VC_REQUEST:
        !           554:                        /*
        !           555:                         * Panel request.
        !           556:                         */
        !           557:                    {
        !           558:                        kern_return_t krtn;
        !           559:                        int unit = [diskObj unit];
        !           560:                        
        !           561:                        xpr_vc("volCheck VC_REQUEST: disk %s\n", 
        !           562:                                [diskObj name], 2,3,4,5);
        !           563:                        
        !           564:                        /*
        !           565:                         * If there is already a panel up for this drive, 
        !           566:                         * this is a nop.
        !           567:                         */
        !           568:                        if(vcEntry->diskRequestPending) {
        !           569:                                xpr_vc("volCheckRequest: Panel already "
        !           570:                                    "pending\n", 1,2,3,4,5);
        !           571:                                break;
        !           572:                        }
        !           573:                        if([diskObj lastReadyState] == IO_Ready) {
        !           574:                                /*
        !           575:                                 * This can be the result of a call to
        !           576:                                 * volCheckRequest() follwed by immediate
        !           577:                                 * insertion of the desired disk.
        !           578:                                 * No error. No panel.
        !           579:                                 */
        !           580:                                xpr_vc("volCheckRequest: Panel Not "
        !           581:                                        "Necessary\n", 1,2,3,4,5);
        !           582:                                break;
        !           583:                        }
        !           584:                        krtn = vol_panel_disk_num(volCheckResponse,
        !           585:                                0,                      // volume number
        !           586:                                vcCmd->diskType,
        !           587:                                unit,                   // drive number
        !           588:                                diskObj,                // param for callback
        !           589:                                NO,                     // wrong disk
        !           590:                                &vcEntry->tag);
        !           591:                        /* 
        !           592:                         * Record this request in *vcEntry.
        !           593:                         */
        !           594:                        vcEntry->diskRequestPending = YES;
        !           595:                        break;
        !           596:                    }               
        !           597:                    
        !           598:                    case VC_EJECTING:
        !           599:                        xpr_vc("volCheck VC_EJECTING: disk %s\n", 
        !           600:                                [diskObj name], 2,3,4,5);
        !           601:                        [diskObj setLastReadyState:IO_Ejecting];
        !           602: #if i386
        !           603:                        /*
        !           604:                         * FIXME - this should only be done for 
        !           605:                         * i386 *floppy* drives!
        !           606:                         */
        !           607:                        vcEntry->ejectCounter        = 1;
        !           608: #else
        !           609:                        vcEntry->ejectCounter        = VC_EJECT_DELAY;
        !           610: #endif
        !           611:                        vcEntry->ejectRequestPending = NO;
        !           612:                        vcEntry->diskType = vcCmd->diskType;
        !           613:                        break;
        !           614:                                            
        !           615:                    case VC_NOTREADY:
        !           616:                        xpr_vc("volCheck VC_NOTREADY: disk %s\n", 
        !           617:                                [diskObj name], 2,3,4,5);
        !           618:                        [diskObj setLastReadyState:IO_NotReady];
        !           619:                        break;
        !           620:                        
        !           621:                    case VC_RESPONSE:
        !           622:                        /* 
        !           623:                         * This comes from the vol driver - it's a panel 
        !           624:                         * response, which can only mean "disk not available".
        !           625:                         */
        !           626:                        xpr_vc("volCheck VC_RESPONSE: disk %s\n", 
        !           627:                                [diskObj name], 2,3,4,5);
        !           628:                        if(!vcEntry->diskRequestPending) {
        !           629:                                /*
        !           630:                                 * This can happen if the disk is inserted 
        !           631:                                 * at around the same time as the user hit 
        !           632:                                 * "cancel".
        !           633:                                 */
        !           634:                                break;
        !           635:                        }
        !           636:                        vcEntry->diskRequestPending = NO;
        !           637:                        [diskObj abortRequest];
        !           638:                        break;
        !           639: 
        !           640:                } /* switch op */
        !           641:                
        !           642: freeCmd:
        !           643:                IOFree(vcCmd, sizeof(*vcCmd));
        !           644:                
        !           645:                /*
        !           646:                 * We need to hold this lock at the top of the loop, and
        !           647:                 * we'll hold it when we drop out.
        !           648:                 */
        !           649:                [volCheckCmdLock lock];
        !           650:        }         /* for each cmd */
        !           651:        
        !           652:        [volCheckCmdLock unlock];
        !           653:        xpr_vc("volCheckCmdHandler: done\n", 1,2,3,4,5);
        !           654: }
        !           655: 
        !           656: /*
        !           657:  * Common means by which vol driver is notified of presence of disk, either
        !           658:  * at disk insertion time or at volCheckRegister() time.
        !           659:  */
        !           660: static void volDriverNotify(id diskObj,
        !           661:        dev_t blockDev,
        !           662:        dev_t rawDev)
        !           663: {
        !           664:        struct disk_label *label = IOMalloc(sizeof(struct disk_label));
        !           665:        int vol_state;
        !           666:        int flags;
        !           667:        id logicalDisk;
        !           668:        IOReturn rtn;
        !           669:                
        !           670:        xpr_vc("volDriverNotify: dev=%s\n", [diskObj name], 2,3,4,5);
        !           671:        if([diskObj isRemovable]) {
        !           672:                flags = IND_FLAGS_REMOVABLE;
        !           673:        }
        !           674:        else {
        !           675:                flags = IND_FLAGS_FIXED;
        !           676:        }
        !           677:        logicalDisk = [diskObj nextLogicalDisk];
        !           678:        if(logicalDisk != nil) {
        !           679:                rtn = [logicalDisk readLabel:label];
        !           680:        }
        !           681:        else {
        !           682:                /*
        !           683:                 * This is pretty weird. IODiskPartitionProbe:
        !           684:                 * should have created an IODiskPartition object as partition
        !           685:                 * 0's raw device...
        !           686:                 */
        !           687:                IOLog("volCheck: physDev with no logicalDisk!!\n");
        !           688:                rtn = IO_R_NO_LABEL;
        !           689:        }
        !           690:        if(rtn == IO_R_SUCCESS) {
        !           691:                vol_state = IND_VS_LABEL;
        !           692:        }
        !           693:        else {
        !           694:                if([diskObj isFormatted]) {
        !           695:                        vol_state = IND_VS_FORMATTED;
        !           696:                }
        !           697:                else {
        !           698:                        vol_state = IND_VS_UNFORMATTED;
        !           699:                }
        !           700:        }
        !           701:        if([diskObj isWriteProtected]) {
        !           702:                flags |= IND_FLAGS_WP;
        !           703:        }
        !           704:        vol_notify_dev(blockDev,
        !           705:                rawDev,
        !           706:                "",                     // form_type - what was this for
        !           707:                                        //    again???
        !           708:                vol_state,
        !           709:                [diskObj name],         // "sd0", etc.
        !           710:                flags);                 // WP, removable
        !           711:        
        !           712:        IOFree(label, sizeof(struct disk_label));
        !           713: }

unix.superglobalmegacorp.com

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