Annotation of drvEIDE/EIDE.drvproj/EIDE.lksproj/IdeKernel.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.0 (the 'License').  You may not use this file
        !            10:  * except in compliance with the License.  Please obtain a copy of the
        !            11:  * License at http://www.apple.com/publicsource and read it before using
        !            12:  * this file.
        !            13:  * 
        !            14:  * The Original Code and all software distributed under the License are
        !            15:  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            19:  * License for the specific language governing rights and limitations
        !            20:  * under the License."
        !            21:  * 
        !            22:  * @APPLE_LICENSE_HEADER_END@
        !            23:  */
        !            24: /*
        !            25:  * Copyright 1997-1998 by Apple Computer, Inc., All rights reserved.
        !            26:  * Copyright 1994-1997 NeXT Software, Inc., All rights reserved.
        !            27:  *
        !            28:  * IdeKern.m - UNIX front end for kernel IDE Disk driver.
        !            29:  *
        !            30:  * HISTORY 
        !            31:  * 07-Jul-1994  Rakesh Dubey at NeXT
        !            32:  *     Created from original driver written by David Somayajulu.
        !            33:  * 19-Jun-97   Dieter Siegmund at Apple
        !            34:  *     Updated to use the BSD4.4 ioctl interface that copies user
        !            35:  *     buffer in/out of kernel automatically.
        !            36:  */
        !            37:  
        !            38: #if (IO_DRIVERKIT_VERSION == 400)
        !            39: #define _POSIX_SOURCE
        !            40: #endif
        !            41: 
        !            42: /*
        !            43:  * Note that this file builds with KERNEL_PRIVATE and !MACH_USER_API.
        !            44:  */
        !            45: #import <sys/types.h>
        !            46: #import <sys/ttycom.h>
        !            47: #import <sys/ucred.h>
        !            48: #import <driverkit/kernelDiskMethods.h> 
        !            49: #import <driverkit/generalFuncs.h>
        !            50: #import "IdeCnt.h"
        !            51: #import "IdeDiskInternal.h"
        !            52: #import "IdeDisk.h"
        !            53: #import <driverkit/kernelDriver.h>
        !            54: #import <driverkit/IODiskPartition.h>
        !            55: #import <sys/buf.h>
        !            56: #import <sys/uio.h>
        !            57: #import <bsd/dev/ldd.h>
        !            58: #import <sys/errno.h>
        !            59: #import <sys/proc.h>
        !            60: #if (IO_DRIVERKIT_VERSION == 330)
        !            61: #import <vm/vm_kern.h>
        !            62: #endif
        !            63: #import <sys/fcntl.h>
        !            64: #import <sys/systm.h>
        !            65: #import "IdeKernel.h"
        !            66: 
        !            67: #if (IO_DRIVERKIT_VERSION != 330)
        !            68: extern struct vm_map *kernel_map;
        !            69: #endif
        !            70: 
        !            71: IONamedValue iderValues[] = {
        !            72: 
        !            73:        {IDER_SUCCESS,          "Success"                       },
        !            74:        {IDER_TIMEOUT,          "Timeout occured"               },
        !            75:        {IDER_MEMALLOC,         "Couldn't allocate memory"      },
        !            76:        {IDER_MEMFAIL,          "Memory transfer error"         },
        !            77:        {IDER_REJECT,           "Bad field in ide_ioreq"        },
        !            78:        {IDER_BADDRV,           "Drive not present"             },
        !            79:        {IDER_CMD_ERROR,        "Command Failed"                },
        !            80:        {IDER_VOLUNAVAIL,       "Requested Volume not available"},
        !            81:        {IDER_SPURIOUS,         "Spurious Interrupt"            },
        !            82:        {IDER_CNTRL_REJECT,     "Controller Reject"             },
        !            83:        {0,                     NULL                            },
        !            84: };
        !            85: 
        !            86: 
        !            87: /*
        !            88:  * dev-to-id map array. Instances of DiskObject register their IDs in
        !            89:  * this array via registerUnixDisk:.
        !            90:  */
        !            91: IODevAndIdInfo IdeIdMap[NUM_IDE_DEV];
        !            92: 
        !            93: /*
        !            94:  * Private per-unit data.
        !            95:  */
        !            96: static Ide_dev_t ide_dev[NUM_IDE_DEV] = {
        !            97:        {NULL},
        !            98:        {NULL},
        !            99:        {NULL},
        !           100:        {NULL},
        !           101: };
        !           102: 
        !           103: /*
        !           104:  * Indices of our entries in devsw's.
        !           105:  */
        !           106: static int ide_block_major;
        !           107: static int ide_raw_major;
        !           108: 
        !           109: /*
        !           110:  * prototypes for internal functions
        !           111:  */
        !           112: static unsigned ideminphys(struct buf *bp); 
        !           113: static id ide_dev_to_id(dev_t dev);
        !           114: 
        !           115: /*
        !           116:  * Initialize id map and Ide_dev. Currently invoked by Ide probe:.
        !           117:  */
        !           118: __private_extern__ void ide_init_idmap(id self)
        !           119: {
        !           120:     IODevAndIdInfo *idMap = IdeIdMap;
        !           121:     Ide_dev_t *ide_devp = ide_dev;
        !           122:     int unit;
        !           123:     
        !           124:     /* 
        !           125:      * figure out our major device numbers.
        !           126:      */
        !           127:     ide_block_major = [self blockMajor];
        !           128:     ide_raw_major = [self characterMajor];
        !           129: 
        !           130:     bzero((char *)idMap, sizeof(IODevAndIdInfo) * NUM_IDE_DEV);
        !           131:     for (unit = 0; unit < NUM_IDE_DEV; unit++) {
        !           132:        idMap->rawDev   = makedev(ide_raw_major, (unit << 3));
        !           133:        idMap->blockDev = makedev(ide_block_major, (unit << 3));
        !           134:        idMap++;
        !           135:        ide_devp->physbuf = (struct buf *)IOMalloc(sizeof(struct buf));
        !           136:        ide_devp->physbuf->b_flags = 0;
        !           137:        ide_devp++;
        !           138:     }
        !           139: }
        !           140: 
        !           141: __private_extern__ IODevAndIdInfo *ide_idmap()
        !           142: {
        !           143:     return IdeIdMap;
        !           144: }
        !           145: 
        !           146: __private_extern__ int
        !           147: ideopen(dev_t dev, int flag, int devtype, struct proc * pp)
        !           148: {
        !           149:     id diskObj = ide_dev_to_id(dev);
        !           150:     
        !           151:     if(diskObj == nil)
        !           152:        return(ENXIO);
        !           153: 
        !           154:     if([diskObj isDiskReady:NO])
        !           155:        return(ENXIO);
        !           156:                
        !           157:     /*
        !           158:      * Register this 'Unix-level open' event for IODiskPartitions.
        !           159:      */
        !           160:     if(IO_DISK_PART(dev) != IDE_LIVE_PART) {
        !           161:        if(major(dev) == ide_block_major) {
        !           162:            [diskObj setBlockDeviceOpen:YES];
        !           163:        }
        !           164:        else {
        !           165:            [diskObj setRawDeviceOpen:YES];
        !           166:        }
        !           167:     }
        !           168:     return(0)        !           169: } /* ideopen() */
        !           170: 
        !           171: __private_extern__ int
        !           172: ideclose(dev_t dev, int flag, int devtype, struct proc * pp)
        !           173: {
        !           174:     id diskObj = ide_dev_to_id(dev);
        !           175:     
        !           176:     if(diskObj == nil)
        !           177:        return(ENXIO);
        !           178:     if(IO_DISK_PART(dev) == IDE_LIVE_PART) { 
        !           179:        return 0;
        !           180:     } else     {
        !           181:        if(![diskObj isInstanceOpen])
        !           182:            return(ENXIO);
        !           183:     }
        !           184:            
        !           185:     /*
        !           186:      * Register this 'Unix-level close' event. We won't be called unless
        !           187:      * this is the last close.
        !           188:      */
        !           189:     if(major(dev) == ide_block_major) {
        !           190:        [diskObj setBlockDeviceOpen:NO];
        !           191:     }
        !           192:     else {
        !           193:        [diskObj setRawDeviceOpen:NO];
        !           194:     }
        !           195:     
        !           196:     return(0)        !           197: } /* ideclose() */
        !           198: 
        !           199: /*
        !           200:  * Raw I/O uses standard UNIX physio routine, resulting in async I/O requests
        !           201:  * via idestrategy().
        !           202:  */
        !           203: 
        !           204: __private_extern__ int
        !           205: ideread(dev_t dev, struct uio *uiop, int ioflag)
        !           206: {
        !           207:     id                 diskObj = ide_dev_to_id(dev);
        !           208:     int        unit = IO_DISK_UNIT(dev);
        !           209:     int        rtn;
        !           210: 
        !           211:     if(diskObj == nil) {
        !           212:        return(ENXIO);
        !           213:     }
        !           214: 
        !           215: 
        !           216:     rtn = physio(idestrategy, 
        !           217:        ide_dev[unit].physbuf, 
        !           218:        dev, 
        !           219:        B_READ, 
        !           220:        ideminphys, 
        !           221:        uiop, 
        !           222:        [diskObj blockSize]);
        !           223:            
        !           224:     return rtn;
        !           225: } /* ideread() */
        !           226: 
        !           227: __private_extern__ int
        !           228: idewrite(dev_t dev, struct uio *uiop, int ioflag)
        !           229: {
        !           230:     id                 diskObj = ide_dev_to_id(dev);
        !           231:     int        unit = IO_DISK_UNIT(dev);
        !           232:     int        rtn;
        !           233:            
        !           234:     if(diskObj == nil)
        !           235:        return(ENXIO);
        !           236:     
        !           237: 
        !           238:     rtn = physio(idestrategy, 
        !           239:        ide_dev[unit].physbuf, 
        !           240:        dev, 
        !           241:        B_WRITE, 
        !           242:        ideminphys, 
        !           243:        uiop, 
        !           244:        [diskObj blockSize]);
        !           245:            
        !           246:     return rtn;
        !           247: } /* idewrite() */
        !           248: 
        !           249: __private_extern__ void
        !           250: idestrategy(struct buf *bp)
        !           251: {
        !           252:     id diskObj = ide_dev_to_id(bp->b_dev);
        !           253:     u_int offset;
        !           254:     u_int bytes_req;
        !           255:     void *bufp;
        !           256:     u_int block_size;
        !           257:     IOReturn rtn;
        !           258:     vm_task_t client;
        !           259:        
        !           260:     if(diskObj == nil) {
        !           261:        bp->b_error = ENXIO;
        !           262:        goto bad;
        !           263:     }
        !           264:     
        !           265:     if((bp->b_flags & (B_PHYS|B_KERNSPACE)) == B_PHYS) {
        !           266:        /*
        !           267:         * Physical I/O to user space.
        !           268:         */
        !           269:        client = IOVmTaskForBuf(bp);
        !           270:     }
        !           271:     else {
        !           272:        /*
        !           273:         * Either block I/O (always kernel space) or physical I/O
        !           274:         * to kernel space (e.g., loadable file system).
        !           275:         */
        !           276:        client = IOVmTaskSelf();
        !           277:     }
        !           278:     
        !           279:     block_size = [diskObj blockSize];
        !           280:     if (block_size == 0) {
        !           281:        bp->b_error = ENXIO;
        !           282:        goto bad;
        !           283:     }
        !           284:     offset = bp->b_blkno;
        !           285:     bytes_req = bp->b_bcount;
        !           286:     bufp = bp->b_un.b_addr;
        !           287: 
        !           288:     if (bp->b_flags & B_READ) {
        !           289:        rtn = [diskObj readAsyncAt:offset
        !           290:                length:bytes_req
        !           291:                buffer:bufp
        !           292:                pending:bp
        !           293:                client:client];
        !           294:     }
        !           295:     else {
        !           296:        rtn = [diskObj writeAsyncAt:offset
        !           297:                length:bytes_req
        !           298:                buffer:bufp
        !           299:                pending:bp
        !           300:                client:client];
        !           301:     }
        !           302: 
        !           303:     if (rtn) {
        !           304:        bp->b_error = [diskObj errnoFromReturn:rtn];
        !           305:        goto bad;
        !           306:     }
        !           307:     return;
        !           308: 
        !           309: bad:
        !           310:     bp->b_flags |= B_ERROR;
        !           311:     biodone(bp);
        !           312: } /* fdstrategy() */
        !           313: 
        !           314: /*
        !           315:  * Ops which are common to all IODiskPartitions are done on the raw device; 
        !           316:  * Ide-specific ioctls are done directly to the live Ide object.
        !           317:  */
        !           318: __private_extern__ int
        !           319: ideioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc * pp)
        !           320: {
        !           321:     int     unit = IO_DISK_UNIT(dev);
        !           322:     id      diskObj;
        !           323:     IODevAndIdInfo *idmap;
        !           324:     int     rtn = 0;
        !           325:     IOReturn irtn = IO_R_SUCCESS;
        !           326:     struct ucred cred;
        !           327:     u_short acflags;
        !           328: 
        !           329:     // user src/dest
        !           330:     int     i;
        !           331:     int     nblk;
        !           332:     ideIoReq_t *ideIoReq;
        !           333:     int     error;
        !           334:     void   *userPtr;
        !           335: 
        !           336:     // in ideIoReq_t
        !           337:     BOOL wrFlag = NO;
        !           338:     unsigned bSize = 0;
        !           339:     unsigned char *alignedPtr;
        !           340: 
        !           341:     if (unit > NUM_IDE_DEV)
        !           342:        return (ENXIO);
        !           343: #if 0
        !           344:     if ((major(dev) != ide_raw_major) ||
        !           345:        (IO_DISK_PART(dev) >= NUM_IDE_PART)) {
        !           346:        return (ENXIO);
        !           347:     }
        !           348: #endif
        !           349: 
        !           350:     idmap = &IdeIdMap[unit];
        !           351: 
        !           352:     /*
        !           353:      * First verify valid device. 
        !           354:      */
        !           355:     switch (cmd) {
        !           356:       case DKIOCSFORMAT:
        !           357:       case DKIOCGFORMAT:
        !           358:       case DKIOCGLABEL:
        !           359:       case DKIOCSLABEL:
        !           360: 
        !           361:        /*
        !           362:         * Raw device, whatever the caller asked for. 
        !           363:         */
        !           364:        diskObj = idmap->partitionId[0];
        !           365:        break;
        !           366: 
        !           367:       case IDEDIOCREQ:
        !           368:       case IDEDIOCINFO:
        !           369:       case DKIOCINFO:
        !           370:       case DKIOCBLKSIZE:
        !           371:       case DKIOCNUMBLKS:
        !           372: 
        !           373:        diskObj = idmap->liveId;
        !           374:        break;
        !           375: 
        !           376:       default:
        !           377:        return (EINVAL);
        !           378:     }
        !           379:     if (diskObj == nil)
        !           380:        goto nodev;
        !           381: 
        !           382:     switch (cmd) {
        !           383:       case DKIOCSFORMAT:
        !           384: 
        !           385:        /*
        !           386:         * This can fail if block devices attached to this disk are open. 
        !           387:         */
        !           388:        irtn = [diskObj setFormatted:(*(u_int *) data)];
        !           389:        break;
        !           390: 
        !           391:       case DKIOCGFORMAT:
        !           392:        {
        !           393:            *(int *)data = [diskObj isFormatted];
        !           394:            break;
        !           395:        }
        !           396: 
        !           397:       case DKIOCGLABEL:
        !           398:        {
        !           399:            struct disk_label *labelp;
        !           400: 
        !           401:            labelp = (struct disk_label *)IOMalloc(sizeof(*labelp));
        !           402:            irtn = [diskObj readLabel:labelp];
        !           403:            if (irtn == IO_R_SUCCESS) {
        !           404:                *(struct disk_label *)data = *labelp;
        !           405:            }
        !           406:            IOFree(labelp, sizeof(*labelp));
        !           407:            break;
        !           408:        }
        !           409: 
        !           410:       case DKIOCSLABEL:
        !           411:        {
        !           412:            struct disk_label *labelp;
        !           413: 
        !           414:                //IOLog("DKIOCSLABEL called\n");
        !           415: 
        !           416:            labelp = (struct disk_label *)IOMalloc(sizeof(*labelp));
        !           417:            *labelp = *(struct disk_label *)data;
        !           418:            irtn = [diskObj writeLabel:labelp];
        !           419:            IOFree(labelp, sizeof(*labelp));
        !           420:            break;
        !           421:        }
        !           422: 
        !           423:       case DKIOCINFO:
        !           424:        {
        !           425:            struct drive_info info;
        !           426: 
        !           427:            bzero(&info, sizeof(info));
        !           428:            strcpy(info.di_name,[diskObj driveName]);
        !           429:            info.di_devblklen = [diskObj blockSize];
        !           430:            info.di_maxbcount = IDE_MAX_PHYS_IO;
        !           431:            if (info.di_devblklen) {
        !           432:                nblk = howmany(sizeof(struct disk_label),
        !           433:                               info.di_devblklen);
        !           434:            } else {
        !           435:                nblk = 0;
        !           436:            }
        !           437:            for (i = 0; i < NLABELS; i++)
        !           438:                info.di_label_blkno[i] = nblk * i;
        !           439:            *(struct drive_info *) data = info;
        !           440:            break;
        !           441:        }
        !           442: 
        !           443:       case DKIOCBLKSIZE:
        !           444:        *(int *)data = [diskObj blockSize];
        !           445:        break;
        !           446: 
        !           447:       case DKIOCNUMBLKS:
        !           448:        *(int *)data = [diskObj diskSize];
        !           449:        break;
        !           450: 
        !           451:       case IDEDIOCREQ:
        !           452: 
        !           453:        /*
        !           454:         * Perform specified I/O.
        !           455:         */
        !           456:        ideIoReq = (ideIoReq_t *) data;
        !           457: //     if (!suser() && (ideIoReq->cmd != IDE_IDENTIFY_DRIVE))
        !           458:        if (!suser(&cred, &acflags) && (ideIoReq->cmd != IDE_IDENTIFY_DRIVE))   {
        !           459: //         return (u.u_error);
        !           460:            return (EINVAL);
        !           461:        }
        !           462:        
        !           463:        if ((ideIoReq->cmd == IDE_WRITE_DMA) ||
        !           464:            (ideIoReq->cmd == IDE_READ_DMA)) {
        !           465:            if ([[diskObj cntrlr] isDmaSupported:[diskObj driveNum]] != TRUE)
        !           466:                return (EINVAL);
        !           467:        }
        !           468:         if (ideIoReq->cmd == IDE_IDENTIFY_DRIVE)
        !           469:            ideIoReq->blkcnt = 1;
        !           470: 
        !           471:        userPtr = (void *)ideIoReq->addr;
        !           472: 
        !           473:        alignedPtr = ideIoReq->addr;
        !           474:        if ((ideIoReq->cmd == IDE_WRITE) ||
        !           475:            (ideIoReq->cmd == IDE_READ) ||
        !           476:            (ideIoReq->cmd == IDE_READ_MULTIPLE) ||
        !           477:            (ideIoReq->cmd == IDE_WRITE_MULTIPLE) ||
        !           478:            (ideIoReq->cmd == IDE_READ_DMA) ||
        !           479:            (ideIoReq->cmd == IDE_WRITE_DMA) ||
        !           480:            (ideIoReq->cmd == IDE_IDENTIFY_DRIVE)) {
        !           481:            if (ideIoReq->blkcnt != 0) {
        !           482:                bSize = [diskObj blockSize];
        !           483:                wrFlag = ((ideIoReq->cmd == IDE_WRITE) ||
        !           484:                          (ideIoReq->cmd == IDE_WRITE_MULTIPLE) ||
        !           485:                          (ideIoReq->cmd == IDE_WRITE_DMA));
        !           486: 
        !           487:                alignedPtr = (unsigned char *)
        !           488:                    IOMalloc(ideIoReq->blkcnt * bSize);
        !           489:                if (alignedPtr == 0) {
        !           490:                    ideIoReq->status = IDER_MEMALLOC;
        !           491:                    return (ENOMEM);
        !           492:                }
        !           493:                if (wrFlag) {
        !           494:                    error = copyin(ideIoReq->addr,
        !           495:                                   alignedPtr,
        !           496:                                   ideIoReq->blkcnt * bSize);
        !           497:                    if (error) {
        !           498:                        ideIoReq->status = IDER_MEMFAIL;
        !           499:                        goto err_exit;
        !           500:                    }
        !           501:                }
        !           502:            }
        !           503:            ideIoReq->addr = (caddr_t) alignedPtr;
        !           504:            ideIoReq->map = (struct vm_map *)IOVmTaskSelf();
        !           505:        }
        !           506: 
        !           507: 
        !           508:        [diskObj ideXfrIoReq:ideIoReq];
        !           509: 
        !           510:        /*
        !           511:         * Note if we got this far, we'll return 0; any errors are in
        !           512:         * ideIoReq->status. 
        !           513:         */
        !           514:        if ((ideIoReq->cmd == IDE_WRITE) ||
        !           515:            (ideIoReq->cmd == IDE_READ) ||
        !           516:            (ideIoReq->cmd == IDE_READ_MULTIPLE) ||
        !           517:            (ideIoReq->cmd == IDE_WRITE_MULTIPLE) ||
        !           518:            (ideIoReq->cmd == IDE_READ_DMA) ||
        !           519:            (ideIoReq->cmd == IDE_WRITE_DMA) ||
        !           520:            (ideIoReq->cmd == IDE_IDENTIFY_DRIVE)) {
        !           521: 
        !           522:            ideIoReq->addr = userPtr;
        !           523:            if (((ideIoReq->cmd == IDE_READ) ||
        !           524:                 (ideIoReq->cmd == IDE_READ_MULTIPLE) ||
        !           525:                 (ideIoReq->cmd == IDE_IDENTIFY_DRIVE) ||
        !           526:                 (ideIoReq->cmd == IDE_READ_DMA)) &&
        !           527:                (ideIoReq->blocks_xfered != 0)) {
        !           528:                error = copyout(alignedPtr,
        !           529:                                userPtr,
        !           530:                                ideIoReq->blocks_xfered * bSize);
        !           531:                if (error) {
        !           532:                    ideIoReq->status = IDER_MEMFAIL;
        !           533:                }
        !           534:            }
        !           535:     err_exit:
        !           536: 
        !           537:            /*
        !           538:             * if we malloc'd any memory, free it. 
        !           539:             */
        !           540:            if (ideIoReq->blkcnt != 0)
        !           541:                IOFree(alignedPtr, ideIoReq->blkcnt * bSize);
        !           542:        }
        !           543:        break;
        !           544: 
        !           545:       case IDEDIOCINFO:
        !           546:        {
        !           547:            ideDriveInfo_t *idep = (ideDriveInfo_t *) data;
        !           548: 
        !           549:            *idep = (ideDriveInfo_t)[diskObj ideGetDriveInfo];
        !           550:            break;
        !           551:        }
        !           552:       default:
        !           553:        return (EINVAL);
        !           554:     }
        !           555: 
        !           556:     if (irtn)
        !           557:        rtn = [diskObj errnoFromReturn:irtn];
        !           558:     return (rtn);
        !           559: 
        !           560: nodev:
        !           561:     return (ENXIO);
        !           562: 
        !           563: } /* ideioctl() */
        !           564: 
        !           565: /*
        !           566:  * Obtain physical block size.
        !           567:  */
        !           568: __private_extern__ int
        !           569: idesize(dev_t dev)
        !           570: {
        !           571:     id diskObj = ide_dev_to_id(dev);
        !           572:     
        !           573:     if(diskObj == nil) {
        !           574:        return -1;
        !           575:     }
        !           576:     return [diskObj blockSize];
        !           577: }
        !           578: 
        !           579: /*
        !           580:  * Returns block and char major nums. This is used so that the PostLoad
        !           581:  * program can create block and character nodes for IDE. 
        !           582:  */
        !           583: __private_extern__ void
        !           584: ide_block_char_majors(int *blockmajor, int *charmajor)
        !           585: {
        !           586:     *blockmajor = ide_block_major;
        !           587:     *charmajor = ide_raw_major;
        !           588: }
        !           589: 
        !           590: static unsigned ideminphys(struct buf *bp)
        !           591: {
        !           592:     if (bp->b_bcount > IDE_MAX_PHYS_IO)
        !           593:        bp->b_bcount = IDE_MAX_PHYS_IO;
        !           594:     return(bp->b_bcount);
        !           595: }
        !           596: 
        !           597: /*
        !           598:  * Map dev_t to id. A nil return indicates ENXIO.
        !           599:  */
        !           600: static id ide_dev_to_id(dev_t dev)
        !           601: {
        !           602:     id rtn;
        !           603:     int unit = IO_DISK_UNIT(dev);
        !           604:     IODevAndIdInfo *idmap;
        !           605:     int part = IO_DISK_PART(dev);
        !           606:     
        !           607:     if((unit >= NUM_IDE_DEV) || (part >= NUM_IDE_PART)) {
        !           608:        return nil;
        !           609:     }
        !           610:     idmap = &IdeIdMap[unit];
        !           611:     if(part == IDE_LIVE_PART) {
        !           612:        if(major(dev) == ide_block_major) {
        !           613:            rtn = nil;  
        !           614:        }
        !           615:        else {
        !           616:            rtn = idmap->liveId;
        !           617:        }
        !           618:     }
        !           619:     else {
        !           620:        rtn = idmap->partitionId[part];
        !           621:     }
        !           622:     return rtn;
        !           623: }
        !           624: 
        !           625: /* end of IdeKern.m */

unix.superglobalmegacorp.com

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