Annotation of driverkit/libDriver/IODisk.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:  * IODisk.m - implementation of generic disk object.
        !            27:  *
        !            28:  * HISTORY
        !            29:  * 31-Jan-91    Doug Mitchell at NeXT
        !            30:  *      Created.
        !            31:  */
        !            32: 
        !            33: #import <bsd/sys/types.h>
        !            34: #import <driverkit/return.h>
        !            35: #import <mach/kern_return.h>
        !            36: #import <driverkit/IODisk.h>
        !            37: #import <driverkit/Device_ddm.h>
        !            38: #ifdef KERNEL
        !            39: #import <kernserv/prototypes.h>
        !            40: #import <mach/mach_interface.h>
        !            41: #else  KERNEL
        !            42: #import <mach/mach.h>
        !            43: #import <bsd/libc.h>
        !            44: #endif KERNEL
        !            45: #import <driverkit/IOLogicalDisk.h> 
        !            46: #import <driverkit/IODiskPartition.h>
        !            47: #import <driverkit/volCheck.h>
        !            48: #import <machkit/NXLock.h>
        !            49: #import <driverkit/generalFuncs.h>
        !            50: #import <bsd/sys/errno.h>
        !            51: #import <driverkit/IODeviceDescription.h>
        !            52: 
        !            53: #ifdef ppc //bknight - 12/16/97 - Radar #2004660
        !            54: #define GROK_APPLE 1
        !            55: #endif //bknight - 12/16/97 - Radar #2004660
        !            56: 
        !            57: /*
        !            58:  * For stringFromReturn:.
        !            59:  */
        !            60: static IONamedValue diskIoReturnValues[] = { 
        !            61:         {IO_R_NO_LABEL,                "No Label"              },
        !            62:         {IO_R_UNFORMATTED,     "Disk Not Formatted"    },
        !            63:        {IO_R_NO_DISK,          "Disk Not Present"      },
        !            64:        {IO_R_NO_BLOCK_ZERO,    "Can\'t Read Block 0"   },
        !            65:        {IO_R_NO_NEXT_PART,     "No NeXT partition"     },
        !            66:        {0,                     NULL                    }
        !            67: };
        !            68: 
        !            69: #ifdef DDM_DEBUG
        !            70: /*
        !            71:  * For xpr's.
        !            72:  */
        !            73: IONamedValue readyStateValues[] = { 
        !            74:         {IO_Ready,             "Ready"         },
        !            75:        {IO_NotReady,           "Not Ready"     },
        !            76:        {IO_NoDisk,             "No Disk"       },
        !            77:        {IO_Ejecting,           "Ejecting"      },
        !            78:        {0,                     NULL            }
        !            79: };
        !            80: #endif DDM_DEBUG
        !            81: 
        !            82: @implementation IODisk
        !            83: 
        !            84: /*
        !            85:  * Public methods.
        !            86:  */
        !            87: 
        !            88: /*
        !            89:  * Public methods to get and set disk parameters. May be overridden by
        !            90:  * subclass.
        !            91:  */
        !            92:  
        !            93: - (unsigned)diskSize
        !            94: {
        !            95:        return(_diskSize);
        !            96: }
        !            97: 
        !            98: - (unsigned)blockSize
        !            99: {
        !           100:        return(_blockSize);
        !           101: }
        !           102: 
        !           103: - (IOReturn)setFormatted : (BOOL)formattedFlag
        !           104: {
        !           105:        
        !           106:        /*
        !           107:         * This is illegal if any attached logicalDisks are open. 
        !           108:         * In the Unix world, this is normally only done on the raw
        !           109:         * device, an IODiskPartition, which overrides this method. 
        !           110:         */
        !           111: #ifdef KERNEL
        !           112:        IOPanic("setFormatted: on IODisk");
        !           113: #else  KERNEL
        !           114:        id targ = (id)self;
        !           115: 
        !           116:        xpr_disk("DiskObject %s: setFormatted flag = %d\n",
        !           117:                [self name], formattedFlag, 3,4,5);
        !           118:                
        !           119:        if(_nextLogicalDisk && [_nextLogicalDisk isOpen]) {
        !           120:                xpr_err("%s: setFormatted with logicalDisk open\n",
        !           121:                        [self name], 2,3,4,5);
        !           122:                return(IO_R_BUSY);
        !           123:        }
        !           124:        if(formattedFlag) {
        !           125:                /*
        !           126:                 * Update our internal device parameters.
        !           127:                 * FIXME - maybe check for respondsTo:.
        !           128:                 */
        !           129:                [targ updatePhysicalParameters];
        !           130:                _formatted = 1;
        !           131:        }
        !           132:        else
        !           133:                _formatted = 0;
        !           134:        /*
        !           135:         * Let any attached logical disks know about this, using the internal
        !           136:         * version of setFormatted to avoid having our setFormattedInternal:
        !           137:         * being called back..
        !           138:         */
        !           139:        if(_nextLogicalDisk)
        !           140:                [_nextLogicalDisk setFormattedInternal:formattedFlag];
        !           141: #endif KERNEL
        !           142:        return(IO_R_SUCCESS);
        !           143: }
        !           144: 
        !           145: - (BOOL)isFormatted
        !           146: {
        !           147:        return(_formatted);
        !           148: }
        !           149: 
        !           150: - (BOOL)isRemovable
        !           151: {
        !           152:        return(_removable);
        !           153: }
        !           154: 
        !           155: - (const char *)driveName
        !           156: {
        !           157:        return(_driveName);
        !           158: }
        !           159: 
        !           160: - (BOOL)isPhysical
        !           161: {
        !           162:        return(_isPhysical);
        !           163: }
        !           164: 
        !           165: - (BOOL)isWriteProtected
        !           166: {
        !           167:        return(_writeProtected);
        !           168: }
        !           169: 
        !           170: /*
        !           171:  * Eject current disk.
        !           172:  */
        !           173: - (IOReturn) eject
        !           174: {
        !           175:        
        !           176: #ifdef KERNEL
        !           177:        IOPanic("IODisk eject in kernel illegal\n");
        !           178:        return(IO_R_UNSUPPORTED);
        !           179: #else  KERNEL
        !           180: 
        !           181:        id targ = (id)self;
        !           182: 
        !           183:        if(!_removable)
        !           184:                return(IO_R_UNSUPPORTED);
        !           185:        xpr_disk("DiskObject %s eject:\n", [self name], 2,3,4,5);
        !           186:        
        !           187:        /*
        !           188:         * We can't allow this if any logical disks are attached. 
        !           189:         * Normally in the Unix world, eject is invoked on an IODiskPartition,
        !           190:         * which overrides this method and ends up calling physDev's
        !           191:         * ejectPhysical. If we're here, that means we must be a
        !           192:         * physical device.
        !           193:         */
        !           194:        if(_nextLogicalDisk) {
        !           195:                xpr_disk("DiskObject eject: Logical Disk(s)"
        !           196:                        " Attached\n", 1,2,3,4,5);
        !           197:                IOLog("%s: Eject attempt with attached logical disks", 
        !           198:                        [self name]);
        !           199:                return(IO_R_OPEN);
        !           200:        }
        !           201:        
        !           202:        /*
        !           203:         * We know nothing about this disk...
        !           204:         */
        !           205:        _formatted = 0;
        !           206:        
        !           207:        /* 
        !           208:         * Can't send this method to self, it's in IOPhysicalDiskMethods 
        !           209:         * protocol.
        !           210:         * FIXME - probably should check for respondsTo:.
        !           211:         */
        !           212:        return([targ ejectPhysical]);
        !           213: #endif KERNEL
        !           214: }
        !           215: 
        !           216: /*
        !           217:  * Get/set parameters used only by subclasses.
        !           218:  */                    
        !           219: - (void)setDiskSize    : (unsigned)size
        !           220: {
        !           221:        _diskSize = size;
        !           222: }
        !           223: 
        !           224: - (void)setBlockSize : (unsigned)size
        !           225: {
        !           226:        _blockSize = size;
        !           227: }
        !           228: 
        !           229: - (void)setIsPhysical : (BOOL)isPhysFlag
        !           230: {
        !           231:        _isPhysical = isPhysFlag ? YES : NO;
        !           232: }
        !           233: 
        !           234: - nextLogicalDisk
        !           235: {
        !           236:        return(_nextLogicalDisk);
        !           237: }
        !           238: 
        !           239: - (void) setRemovable : (BOOL)removableFlag
        !           240: {
        !           241:        _removable = removableFlag ? YES : NO;
        !           242:        return;
        !           243: }
        !           244: 
        !           245: - (void)setDriveName   : (const char *)name
        !           246: {
        !           247:        int len;
        !           248:        
        !           249:        len = strlen((char *)name);
        !           250:        if(len >= MAXDNMLEN)
        !           251:                len = MAXDNMLEN - 1;
        !           252:        strncpy(_driveName, name, len);
        !           253:        _driveName[MAXDNMLEN - 1] = '\0';               
        !           254: }
        !           255: 
        !           256: - (IODiskReadyState)lastReadyState
        !           257: {
        !           258:        return(_lastReadyState);
        !           259: }
        !           260: 
        !           261: - (void)setLastReadyState : (IODiskReadyState)readyState
        !           262: {
        !           263:        _lastReadyState = readyState;
        !           264: }
        !           265: 
        !           266: - (void)setWriteProtected      : (BOOL)writeProtectedFlag
        !           267: {
        !           268:        _writeProtected = writeProtectedFlag ? YES : NO;
        !           269: }
        !           270: 
        !           271: 
        !           272: /*
        !           273:  * internal setFormatted - avoids logical disk interaction.
        !           274:  */
        !           275: - (void)setFormattedInternal:(BOOL)formattedFlag
        !           276: {
        !           277:        xpr_disk("DiskObject %s: setFormattedInternal flag = %d\n",
        !           278:                [self name], formattedFlag, 3,4,5);
        !           279:        _formatted = formattedFlag ? YES : NO;
        !           280: }
        !           281: 
        !           282: /*
        !           283:  * Statistics support.
        !           284:  */
        !           285: - (void)addToBytesRead  : (unsigned)bytesRead
        !           286:                    totalTime : (ns_time_t)totalTime
        !           287:                    latentTime : (ns_time_t)latentTime
        !           288: {
        !           289:        unsigned long long ms_ll;
        !           290:        
        !           291:        _readOps++;
        !           292:        _bytesRead += bytesRead;
        !           293:        ms_ll = totalTime / (1000 * 1000);
        !           294:        _readTotalTime += ms_ll;
        !           295:        ms_ll = latentTime / (1000 * 1000);
        !           296:        _readLatentTime += ms_ll;
        !           297: }
        !           298: 
        !           299: - (void)addToBytesWritten : (unsigned)bytesWritten
        !           300:                     totalTime : (ns_time_t)totalTime
        !           301:                     latentTime : (ns_time_t)latentTime
        !           302: {
        !           303:        unsigned long long ms_ll;
        !           304:        
        !           305:        _writeOps++;
        !           306:        _bytesWritten += bytesWritten;
        !           307:        ms_ll = totalTime / (1000 * 1000);
        !           308:        _writeTotalTime += ms_ll;
        !           309:        ms_ll = latentTime / (1000 * 1000);
        !           310:        _writeLatentTime += ms_ll;
        !           311: }
        !           312: 
        !           313: - (void)incrementReadRetries
        !           314: {
        !           315:        _readRetries++;
        !           316: }
        !           317: 
        !           318: - (void)incrementReadErrors
        !           319: {      
        !           320:        _readErrors++;
        !           321: }
        !           322: 
        !           323: - (void)incrementWriteRetries
        !           324: {
        !           325:        _writeRetries++;
        !           326: }
        !           327: 
        !           328: - (void)incrementWriteErrors
        !           329: {      
        !           330:        _writeErrors++;
        !           331: }
        !           332: 
        !           333: - (void)incrementOtherRetries
        !           334: {
        !           335:        _otherRetries++;
        !           336: }
        !           337: 
        !           338: - (void)incrementOtherErrors
        !           339: {      
        !           340:        _otherErrors++;
        !           341: }
        !           342: 
        !           343: 
        !           344: /*
        !           345:  * For gathering cumulative statistics.
        !           346:  */
        !           347: - (IOReturn)getIntValues               : (unsigned *)parameterArray
        !           348:                           forParameter : (IOParameterName)parameterName
        !           349:                                  count : (unsigned *)count;    // in/out
        !           350: {
        !           351:        unsigned int paramArray[IO_DISK_STAT_ARRAY_SIZE];
        !           352:        int i;
        !           353:        int maxCount = *count;
        !           354:        
        !           355:        if(maxCount == 0) {
        !           356:                maxCount = IO_MAX_PARAMETER_ARRAY_LENGTH;
        !           357:        }
        !           358:        if(strcmp(parameterName, IO_DISK_STATS) == 0) {
        !           359:                paramArray[IO_Reads]            = _readOps;
        !           360:                paramArray[IO_BytesRead]        = _bytesRead;
        !           361:                paramArray[IO_TotalReadTime]    = _readTotalTime;
        !           362:                paramArray[IO_LatentReadTime]   = _readLatentTime;
        !           363:                paramArray[IO_ReadRetries]      = _readRetries;
        !           364:                paramArray[IO_ReadErrors]       = _readErrors;
        !           365:                paramArray[IO_Writes]           = _writeOps;
        !           366:                paramArray[IO_BytesWritten]     = _bytesWritten;
        !           367:                paramArray[IO_TotalWriteTime]   = _writeTotalTime;
        !           368:                paramArray[IO_LatentWriteTime]  = _writeLatentTime;
        !           369:                paramArray[IO_WriteRetries]     = _writeRetries;
        !           370:                paramArray[IO_WriteErrors]      = _writeErrors;
        !           371:                paramArray[IO_OtherRetries]     = _otherRetries;
        !           372:                paramArray[IO_OtherErrors]      = _otherErrors;
        !           373:                
        !           374:                *count = 0;
        !           375:                for(i=0; i<IO_DISK_STAT_ARRAY_SIZE; i++) {
        !           376:                        if(*count == maxCount)
        !           377:                                break;
        !           378:                        parameterArray[i] = paramArray[i];
        !           379:                        (*count)++;
        !           380:                }
        !           381:                return IO_R_SUCCESS;
        !           382:        }
        !           383:        else if(strcmp(parameterName, IO_IS_A_DISK) == 0) {
        !           384:                /*
        !           385:                 * No data; just let caller know we're a disk.
        !           386:                 */
        !           387:                *count = 0;
        !           388:                return IO_R_SUCCESS;
        !           389:        }
        !           390:        else if(strcmp(parameterName, IO_IS_A_PHYSICAL_DISK) == 0) {
        !           391:                *count = 1;
        !           392:                parameterArray[0] = _isPhysical ? 1 : 0;
        !           393:                return IO_R_SUCCESS;
        !           394:        }
        !           395:        else {
        !           396:                return [super getIntValues : parameterArray
        !           397:                        forParameter : parameterName
        !           398:                        count : count];
        !           399: 
        !           400:        }
        !           401: }                                      
        !           402: 
        !           403: /*
        !           404:  * Register a connection with LogicalDisk. If we already have a logicalDisk,
        !           405:  * this is a nop - subclasses might override this method to perform 
        !           406:  * other operations in that case. 
        !           407:  */
        !           408: - (void) setLogicalDisk        : diskId
        !           409: {
        !           410:        xpr_disk("setLogicalDisk: log %s self %s oldLog %s\n",
        !           411:                (diskId ? [diskId name] : "nil"), 
        !           412:                [self name], 
        !           413:                (_nextLogicalDisk ? [_nextLogicalDisk name] : "nil"), 4,5);
        !           414: #ifdef GROK_APPLE //bknight - 12/16/97 - Radar #2004660
        !           415:        /*
        !           416:         * bknight - 12/16/97 - This was changed in order to prevent a
        !           417:         * space leak caused by IODiskPartition instances for HFS partitions
        !           418:         * on disks that get ejected.  It changes the meaning of this call
        !           419:         * to be either "set to nil" or "insert at the end of the list beginning
        !           420:         * at", depending on the value of the argument.  With this change,
        !           421:         * it becomes important that the _nextLogicalDisk field gets set to nil
        !           422:         * before being used - including being used by this routine, which means
        !           423:         * that it must be set to nil before setting it to a non-nil value.
        !           424:         * Otherwise, there would be a use-before-definition bug.  Anyhow, it
        !           425:         * it appears that all the callers do a setLogicalDisk:nil before
        !           426:         * ever calling it with a non-nil argument, so this is safe.
        !           427:         * However, if new call sites are added, this needs to be taken into
        !           428:         * account, or we need to split it into two methods each having the
        !           429:         * appropriate functionality: either "set the field" or "add to the list".
        !           430:         */
        !           431:        if( ! diskId ) {
        !           432:                _nextLogicalDisk = diskId;
        !           433:        }
        !           434:        else if ( ! _nextLogicalDisk && self != diskId ) {
        !           435:                _nextLogicalDisk = diskId;
        !           436:        }
        !           437:        else if ( _nextLogicalDisk ) {
        !           438:                [_nextLogicalDisk setLogicalDisk: diskId];
        !           439:        }
        !           440: #else GROK_APPLE //bknight - 12/16/97 - Radar #2004660
        !           441:        if(_nextLogicalDisk == nil) {
        !           442:                _nextLogicalDisk = diskId;
        !           443:        }
        !           444: #endif GROK_APPLE //bknight - 12/16/97 - Radar #2004660
        !           445: 
        !           446: }
        !           447: 
        !           448: /*
        !           449:  * Invoked by instance of subclass upon completion of device initialization.
        !           450:  * The code here is only executed for physical disks.
        !           451:  *
        !           452:  * All device parameters (_diskSize, _blockSize, _formatted, _removable,
        !           453:  * _lastReadyState) must be valid at this time.
        !           454:  */
        !           455: #define ALWAYS_VCREGISTER      1
        !           456: 
        !           457: - registerDevice
        !           458: {
        !           459:        id targ = (id)self;     // IODisk doesn't implement updateReadyState
        !           460:        id ret;
        !           461:        
        !           462:        xpr_disk("DiskObject registerDisk\n", 1,2,3,4,5);
        !           463:        if(!_isPhysical) {
        !           464:                 ret = [super registerDevice];
        !           465:                goto out;
        !           466:        }
        !           467:        
        !           468:        /*
        !           469:         * Do some trivial initialization.
        !           470:         */
        !           471: 
        !           472:        _nextLogicalDisk = nil;
        !           473:        _LogicalDiskLock = [NXLock new];
        !           474:                
        !           475:        _readOps         = 0;
        !           476:        _bytesRead       = 0;
        !           477:        _readTotalTime   = 0;
        !           478:        _readLatentTime  = 0;
        !           479:        _readRetries     = 0;
        !           480:        _readErrors      = 0;
        !           481:        _writeOps        = 0;
        !           482:        _bytesWritten    = 0;
        !           483:        _writeTotalTime  = 0;
        !           484:        _writeLatentTime = 0;
        !           485:        _writeRetries    = 0;
        !           486:        _writeErrors     = 0;
        !           487:        _otherRetries    = 0;
        !           488:        _otherErrors     = 0;
        !           489:        
        !           490:        /*
        !           491:         * For physical disks, this will cause probes of IODiskPartition.
        !           492:         */
        !           493:        ret = [super registerDevice];
        !           494: 
        !           495:        /*
        !           496:         * sign up for disk insertion/ready detect notification.
        !           497:         */
        !           498:        if(ret != nil && (
        !           499:           ALWAYS_VCREGISTER || 
        !           500:           _removable || 
        !           501:           ([targ updateReadyState] != IO_Ready))) {
        !           502:                /*
        !           503:                 * Make sure the disk conforms to the appropriate protocol.
        !           504:                 */
        !           505:                if(! [[self class] 
        !           506:                    conformsTo:@protocol(IOPhysicalDiskMethods)] ) {
        !           507:                        IOLog("Warning: %s, class %s, does not conform to "
        !           508:                                "IOPhysicalDiskMethods\n",
        !           509:                                [self name], [[self class] name]);
        !           510:                        goto out;       
        !           511:                } 
        !           512: #ifdef KERNEL
        !           513:                volCheckRegister(self,
        !           514:                        _devAndIdInfo->blockDev,
        !           515:                        _devAndIdInfo->rawDev);
        !           516: #else  KERNEL
        !           517:                volCheckRegister(self, 0, 0);
        !           518: #endif KERNEL
        !           519:        }
        !           520:        
        !           521: out:
        !           522:        return ret;
        !           523: }
        !           524: 
        !           525: /*
        !           526:  * Lock/Unlock device for LogicalDisk-specific methods. Invoked only by
        !           527:  * LogicalDisks which are attached to this device.
        !           528:  */
        !           529: - (void)lockLogicalDisks
        !           530: {
        !           531:        [_LogicalDiskLock lock];
        !           532: }
        !           533: 
        !           534: - (void)unlockLogicalDisks
        !           535: {
        !           536:        [_LogicalDiskLock unlock];
        !           537: }
        !           538: 
        !           539: /*
        !           540:  * Convert an IOReturn to text. Overrides superclass's method of same name
        !           541:  * to allow for additional IOReturn's defined in IODisk.h.
        !           542:  */
        !           543: - (const char *)stringFromReturn       : (IOReturn)rtn
        !           544: {
        !           545:        IONamedValue *valArray = diskIoReturnValues;
        !           546:        
        !           547:        for( ; valArray->name; valArray++) {
        !           548:                if(valArray->value == rtn)
        !           549:                        return(valArray->name);
        !           550:        }
        !           551:        /* 
        !           552:         * Not found here. Pass up to superclass.
        !           553:         */
        !           554:        return([super stringFromReturn:rtn]);
        !           555: }
        !           556: 
        !           557: /*
        !           558:  * Convert an IOReturn to an errno.
        !           559:  */
        !           560: - (int)errnoFromReturn : (IOReturn)rtn
        !           561: {
        !           562:        switch(rtn) {
        !           563:            case IO_R_NO_DISK:
        !           564:                return(ENXIO);
        !           565:            case IO_R_NO_LABEL:
        !           566:                return(ENXIO);          // ???
        !           567:            case IO_R_UNFORMATTED:
        !           568:                return(EINVAL);
        !           569:            default:
        !           570:                /* 
        !           571:                 * Not found here. Pass up to superclass.
        !           572:                 */
        !           573:                return([super errnoFromReturn:rtn]);
        !           574: 
        !           575:        }
        !           576: }
        !           577: 
        !           578: /* 
        !           579:  * volCheck module support.
        !           580:  */
        !           581:  
        !           582: static inline int 
        !           583: diskTypeToPR(IODiskType diskType)
        !           584: {
        !           585:        switch(diskType) {
        !           586:            case IO_SCSI:
        !           587:                return PR_DRIVE_SCSI;
        !           588:            case IO_Floppy:
        !           589:                return PR_DRIVE_FLOPPY;
        !           590:            case IO_Other:
        !           591:                return -1;
        !           592:        }
        !           593: }
        !           594: 
        !           595: /*
        !           596:  * Request a "please insert disk" panel.
        !           597:  */
        !           598: - (void)requestInsertionPanelForDiskType : (IODiskType)diskType
        !           599: {
        !           600:        volCheckRequest(self, diskTypeToPR(diskType));
        !           601: }
        !           602: 
        !           603: /*
        !           604:  * Notify volCheck thread that specified device is in a "disk ejecting" state.
        !           605:  */
        !           606: - (void)diskIsEjecting : (IODiskType)diskType
        !           607: {
        !           608:        volCheckEjecting(self, diskTypeToPR(diskType));
        !           609: 
        !           610: }
        !           611: 
        !           612: /*
        !           613:  * Notify volCheck that disk has gone not ready. Typically called on
        !           614:  * gross error detection.
        !           615:  */
        !           616: - (void)diskNotReady
        !           617: {
        !           618:        volCheckNotReady(self);
        !           619: }
        !           620: 
        !           621: /*
        !           622:  * To be optionally overridden by subclass. IODisk version returns NO.
        !           623:  * If subclass's version returns NO, and the drive is a removable media 
        !           624:  * drive, the drive will not be polled once per second while ready state
        !           625:  * is IO_NotReady or IO_NoDisk; instead; polling will only occur when
        !           626:  * an DKIOCCHECKINSERT ioctl is executed on the vol driver.
        !           627:  */
        !           628: - (BOOL)needsManualPolling
        !           629: {
        !           630:        return NO;
        !           631: }      
        !           632: 
        !           633: - property_IODeviceType:(char *)types length:(unsigned int *)maxLen
        !           634: {
        !           635:     if( [self isRemovable])
        !           636:         strcat( types, " "IOTypeRemovableDisk);
        !           637:     if( [self isWriteProtected])
        !           638:         strcat( types, " "IOTypeWriteProtectedDisk);
        !           639: 
        !           640:     return( self);
        !           641: }
        !           642: 
        !           643: - property_IODeviceClass:(char *)classes length:(unsigned int *)maxLen
        !           644: {
        !           645:     strcpy( classes, IOClassBlock);
        !           646:     if( [self isPhysical])
        !           647:         strcat( classes, " "IOClassDisk);
        !           648:     return( self);
        !           649: }
        !           650: 
        !           651: @end

unix.superglobalmegacorp.com

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