Annotation of driverkit/libDriver/volCheck.m, 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: /*     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.