Annotation of kernel/bsd/dev/ppc/drvATADisk/ATADiskKernel.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: 
        !            25: /*
        !            26:  * Copyright 1997-1998 by Apple Computer, Inc., All rights reserved.
        !            27:  * Copyright 1994-1997 NeXT Software, Inc., All rights reserved.
        !            28:  *
        !            29:  * ATADiskKernel.m - UNIX front end for kernel IDE/ATA Disk driver.
        !            30:  *
        !            31:  * HISTORY 
        !            32:  * 07-Jul-1994  Rakesh Dubey at NeXT
        !            33:  *     Created from original driver written by David Somayajulu.
        !            34:  * 19-Jun-97   Dieter Siegmund at Apple
        !            35:  *     Updated to use the BSD4.4 ioctl interface that copies user
        !            36:  *     buffer in/out of kernel automatically.
        !            37:  * 21-Feb-98   Brent Knight at Apple
        !            38:  *  Added support for HFS partitions.  Radar 2204950, 2004660
        !            39:  */
        !            40:  
        !            41: #if (IO_DRIVERKIT_VERSION == 400)
        !            42: #define _POSIX_SOURCE
        !            43: #endif
        !            44: 
        !            45: /*
        !            46:  * Note that this file builds with KERNEL_PRIVATE and !MACH_USER_API.
        !            47:  */
        !            48: #import <sys/types.h>
        !            49: #import <sys/ttycom.h>
        !            50: #import <sys/ucred.h>
        !            51: #import <driverkit/kernelDiskMethods.h> 
        !            52: #import <driverkit/generalFuncs.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 "ATADiskInternal.h"
        !            66: #import "ATADisk.h"
        !            67: #import "ATADiskKernel.h"
        !            68: 
        !            69: #if (IO_DRIVERKIT_VERSION != 330)
        !            70: extern struct vm_map *kernel_map;
        !            71: #endif
        !            72: 
        !            73: #ifdef ppc //bknight - 2/21/98 - Radar 2204950, 2004660
        !            74: #define GROK_APPLE 1
        !            75: #endif //bknight - 2/21/98 - Radar 2204950, 2004660
        !            76: 
        !            77: #ifdef GROK_APPLE //bknight - 2/21/98 - Radar 2204950, 2004660
        !            78: /*
        !            79:  * For consistency with bsd/dev/SCSIDiskKern.m, we use the most
        !            80:  * significant bit of the 8-bit minor device number to flag HFS
        !            81:  * partitions.  For SCSI devices, this meant that there could be
        !            82:  * 16 (= 4 bits) SCSI disks, each with 8 (= 3 bits) partitions,
        !            83:  * either UFS or HFS (= 1 bit).
        !            84:  *
        !            85:  * In SCSIDiskKern.h, NUM_SD_DEV is defined to be 16, which is
        !            86:  * just the right constant for checking that high bit of the
        !            87:  * Unit number and that's what I used in SCSIDiskKern.m.
        !            88:  *
        !            89:  * Unfortunately, we can't just use NUM_IDE_DEV here, because
        !            90:  * it is defined in IdeDiskInternal.h to be only 4.  And since
        !            91:  * it seems inappropriate to include SCSIDiskKern.h here in
        !            92:  * IdeKernel.m, I am instead making this definition, which might
        !            93:  * some day migrate out into IdeDiskInternal.h, or which might
        !            94:  * be made obsolete by the forthcoming IOKit design.
        !            95:  */
        !            96: #define MAX_IDE_UNIT 16
        !            97: #endif GROK_APPLE //bknight - 2/21/98 - Radar 2204950, 2004660
        !            98: 
        !            99: IONamedValue iderValues[] = {
        !           100: 
        !           101:        {IDER_SUCCESS,          "Success"                       },
        !           102:        {IDER_TIMEOUT,          "Timeout occured"               },
        !           103:        {IDER_MEMALLOC,         "Couldn't allocate memory"      },
        !           104:        {IDER_MEMFAIL,          "Memory transfer error"         },
        !           105:        {IDER_REJECT,           "Bad field in ide_ioreq"        },
        !           106:        {IDER_BADDRV,           "Drive not present"             },
        !           107:        {IDER_CMD_ERROR,        "Command Failed"                },
        !           108:        {IDER_VOLUNAVAIL,       "Requested Volume not available"},
        !           109:        {IDER_SPURIOUS,         "Spurious Interrupt"            },
        !           110:        {IDER_CNTRL_REJECT,     "Controller Reject"             },
        !           111:        {0,                     NULL                            },
        !           112: };
        !           113: 
        !           114: static int ideOpenCount = 0;
        !           115: 
        !           116: /*
        !           117:  * dev-to-id map array. Instances of DiskObject register their IDs in
        !           118:  * this array via registerUnixDisk:.
        !           119:  */
        !           120: IODevAndIdInfo IdeIdMap[NUM_IDE_DEV];
        !           121: 
        !           122: /*
        !           123:  * Private per-unit data.
        !           124:  */
        !           125: static Ide_dev_t ide_dev[NUM_IDE_DEV] = {
        !           126:        {NULL},
        !           127:        {NULL},
        !           128:        {NULL},
        !           129:        {NULL},
        !           130: };
        !           131: 
        !           132: /*
        !           133:  * Indices of our entries in devsw's.
        !           134:  */
        !           135: static int ide_block_major;
        !           136: static int ide_raw_major;
        !           137: 
        !           138: /*
        !           139:  * prototypes for internal functions
        !           140:  */
        !           141: static unsigned ideminphys(struct buf *bp); 
        !           142: static id ide_dev_to_id(dev_t dev);
        !           143: 
        !           144: /*
        !           145:  * Initialize id map and Ide_dev. Currently invoked by Ide probe:.
        !           146:  */
        !           147: __private_extern__ void ide_init_idmap(id self)
        !           148: {
        !           149:     IODevAndIdInfo *idMap = IdeIdMap;
        !           150:     Ide_dev_t *ide_devp = ide_dev;
        !           151:     int unit;
        !           152:     
        !           153:     /* 
        !           154:      * figure out our major device numbers.
        !           155:      */
        !           156:     ide_block_major = [self blockMajor];
        !           157:     ide_raw_major = [self characterMajor];
        !           158: 
        !           159:     bzero((char *)idMap, sizeof(IODevAndIdInfo) * NUM_IDE_DEV);
        !           160:     for (unit = 0; unit < NUM_IDE_DEV; unit++) {
        !           161:        idMap->rawDev   = makedev(ide_raw_major, (unit << 3));
        !           162:        idMap->blockDev = makedev(ide_block_major, (unit << 3));
        !           163:        idMap++;
        !           164:        ide_devp->physbuf = (struct buf *)IOMalloc(sizeof(struct buf));
        !           165:        ide_devp->physbuf->b_flags = 0;
        !           166:        ide_devp++;
        !           167:     }
        !           168: }
        !           169: 
        !           170: __private_extern__ IODevAndIdInfo *ide_idmap()
        !           171: {
        !           172:     return IdeIdMap;
        !           173: }
        !           174: 
        !           175: __private_extern__ int
        !           176: ideopen(dev_t dev, int flag, int devtype, struct proc * pp)
        !           177: {
        !           178:     id diskObj = ide_dev_to_id(dev);
        !           179:     
        !           180:     if(diskObj == nil)
        !           181:        return(ENXIO);
        !           182: 
        !           183:     if([diskObj isDiskReady:NO])
        !           184:        return(ENXIO);
        !           185:                
        !           186:     /*
        !           187:      * Register this 'Unix-level open' event for IODiskPartitions.
        !           188:      */
        !           189:     if(IO_DISK_PART(dev) != IDE_LIVE_PART) {
        !           190:        if(major(dev) == ide_block_major) {
        !           191:            [diskObj setBlockDeviceOpen:YES];
        !           192:             ideOpenCount++;
        !           193:        }
        !           194:        else {
        !           195:            [diskObj setRawDeviceOpen:YES];
        !           196:        }
        !           197:     }
        !           198:     return(0)        !           199: } /* ideopen() */
        !           200: 
        !           201: __private_extern__ int
        !           202: ideclose(dev_t dev, int flag, int devtype, struct proc * pp)
        !           203: {
        !           204:     id diskObj = ide_dev_to_id(dev);
        !           205:     
        !           206:     if(diskObj == nil)
        !           207:        return(ENXIO);
        !           208:     if(IO_DISK_PART(dev) == IDE_LIVE_PART) { 
        !           209:        return 0;
        !           210:     } else     {
        !           211:        if(![diskObj isInstanceOpen])
        !           212:            return(ENXIO);
        !           213:     }
        !           214:            
        !           215:     /*
        !           216:      * Register this 'Unix-level close' event. We won't be called unless
        !           217:      * this is the last close.
        !           218:      */
        !           219:     if(major(dev) == ide_block_major) {
        !           220:        [diskObj setBlockDeviceOpen:NO];
        !           221:         if ( ideOpenCount )
        !           222:         {
        !           223:             if ( !--ideOpenCount )
        !           224:             {
        !           225:                 IOSleep(1000);
        !           226:             }
        !           227:         }
        !           228:     }
        !           229:     else {
        !           230:        [diskObj setRawDeviceOpen:NO];
        !           231:     }
        !           232:     
        !           233:     return(0)        !           234: } /* ideclose() */
        !           235: 
        !           236: /*
        !           237:  * Raw I/O uses standard UNIX physio routine, resulting in async I/O requests
        !           238:  * via idestrategy().
        !           239:  */
        !           240: 
        !           241: __private_extern__ int
        !           242: ideread(dev_t dev, struct uio *uiop, int ioflag)
        !           243: {
        !           244:     id                 diskObj = ide_dev_to_id(dev);
        !           245:     int        unit = IO_DISK_UNIT(dev);
        !           246:     int        rtn;
        !           247: 
        !           248:     if(diskObj == nil) {
        !           249:        return(ENXIO);
        !           250:     }
        !           251: 
        !           252: 
        !           253:     rtn = physio(idestrategy, 
        !           254:        ide_dev[unit].physbuf, 
        !           255:        dev, 
        !           256:        B_READ, 
        !           257:        ideminphys, 
        !           258:        uiop, 
        !           259:        [diskObj blockSize]);
        !           260:            
        !           261:     return rtn;
        !           262: } /* ideread() */
        !           263: 
        !           264: __private_extern__ int
        !           265: idewrite(dev_t dev, struct uio *uiop, int ioflag)
        !           266: {
        !           267:     id                 diskObj = ide_dev_to_id(dev);
        !           268:     int        unit = IO_DISK_UNIT(dev);
        !           269:     int        rtn;
        !           270:            
        !           271:     if(diskObj == nil)
        !           272:        return(ENXIO);
        !           273:     
        !           274: 
        !           275:     rtn = physio(idestrategy, 
        !           276:        ide_dev[unit].physbuf, 
        !           277:        dev, 
        !           278:        B_WRITE, 
        !           279:        ideminphys, 
        !           280:        uiop, 
        !           281:        [diskObj blockSize]);
        !           282:            
        !           283:     return rtn;
        !           284: } /* idewrite() */
        !           285: 
        !           286: __private_extern__ void
        !           287: idestrategy(struct buf *bp)
        !           288: {
        !           289:     id diskObj = ide_dev_to_id(bp->b_dev);
        !           290:     u_int offset;
        !           291:     u_int bytes_req;
        !           292:     void *bufp;
        !           293:     u_int block_size;
        !           294:     IOReturn rtn;
        !           295:     vm_task_t client;
        !           296:        
        !           297:     if(diskObj == nil) {
        !           298:        bp->b_error = ENXIO;
        !           299:        goto bad;
        !           300:     }
        !           301:     
        !           302:     if((bp->b_flags & (B_PHYS|B_KERNSPACE)) == B_PHYS) {
        !           303:        /*
        !           304:         * Physical I/O to user space.
        !           305:         */
        !           306:        client = IOVmTaskForBuf(bp);
        !           307:     }
        !           308:     else {
        !           309:        /*
        !           310:         * Either block I/O (always kernel space) or physical I/O
        !           311:         * to kernel space (e.g., loadable file system).
        !           312:         */
        !           313:        client = IOVmTaskSelf();
        !           314:     }
        !           315:     
        !           316:     block_size = [diskObj blockSize];
        !           317:     if (block_size == 0) {
        !           318:        bp->b_error = ENXIO;
        !           319:        goto bad;
        !           320:     }
        !           321:     offset = bp->b_blkno;
        !           322:     bytes_req = bp->b_bcount;
        !           323:     bufp = bp->b_un.b_addr;
        !           324: 
        !           325:     if (bp->b_flags & B_READ) {
        !           326:        rtn = [diskObj readAsyncAt:offset
        !           327:                length:bytes_req
        !           328:                buffer:bufp
        !           329:                pending:bp
        !           330:                client:client];
        !           331:     }
        !           332:     else {
        !           333:        rtn = [diskObj writeAsyncAt:offset
        !           334:                length:bytes_req
        !           335:                buffer:bufp
        !           336:                pending:bp
        !           337:                client:client];
        !           338:     }
        !           339: 
        !           340:     if (rtn) {
        !           341:        bp->b_error = [diskObj errnoFromReturn:rtn];
        !           342:        goto bad;
        !           343:     }
        !           344:     return(0);
        !           345:     
        !           346: bad:
        !           347:     bp->b_flags |= B_ERROR;
        !           348:     rtn = -1;
        !           349:     biodone(bp);
        !           350:     
        !           351:     return(rtn);
        !           352: } /* fdstrategy() */
        !           353: 
        !           354: /*
        !           355:  * Ops which are common to all IODiskPartitions are done on the raw device; 
        !           356:  * Ide-specific ioctls are done directly to the live Ide object.
        !           357:  */
        !           358: __private_extern__ int
        !           359: ideioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc * pp)
        !           360: {
        !           361:     int     unit = IO_DISK_UNIT(dev);
        !           362: #ifdef GROK_APPLE //bknight - 2/21/98 - Radar 2204950, 2004660
        !           363:     int     part = IO_DISK_PART(dev);
        !           364: #endif GROK_APPLE //bknight - 2/21/98 - Radar 2204950, 2004660
        !           365:     id      diskObj;
        !           366:     IODevAndIdInfo *idmap;
        !           367:     int     rtn = 0;
        !           368:     IOReturn irtn = IO_R_SUCCESS;
        !           369:     struct ucred cred;
        !           370:     u_short acflags;
        !           371: 
        !           372:     // user src/dest
        !           373:     int     i;
        !           374:     int     nblk;
        !           375:     ideIoReq_t *ideIoReq;
        !           376:     int     error;
        !           377:     void   *userPtr;
        !           378: 
        !           379:     // in ideIoReq_t
        !           380:     BOOL wrFlag = NO;
        !           381:     unsigned bSize = 0;
        !           382:     unsigned char *alignedPtr;
        !           383: 
        !           384: 
        !           385: #ifdef GROK_APPLE //bknight - 2/21/98 - Radar 2204950, 2004660
        !           386: 
        !           387:        if ( ! ( unit < MAX_IDE_UNIT ) )
        !           388:        {
        !           389:                unit -= MAX_IDE_UNIT;
        !           390:                part += NUM_IDE_PART;
        !           391:        }
        !           392: 
        !           393: #endif GROK_APPLE //bknight - 2/21/98 - Radar 2204950, 2004660
        !           394:     if (unit > NUM_IDE_DEV)
        !           395:        return (ENXIO);
        !           396: #if 0
        !           397: #ifdef GROK_APPLE //bknight - 2/21/98 - Radar 2204950, 2004660
        !           398: 
        !           399:     if ((major(dev) != ide_raw_major) || (part >= 2*NUM_IDE_PART)) {
        !           400: 
        !           401: #else GROK_APPLE //bknight - 2/21/98 - Radar 2204950, 2004660
        !           402: 
        !           403:     if ((major(dev) != ide_raw_major) || (part >= NUM_IDE_PART)) {
        !           404: 
        !           405: #endif GROK_APPLE //bknight - 2/21/98 - Radar 2204950, 2004660
        !           406:        return (ENXIO);
        !           407:     }
        !           408: #endif
        !           409: 
        !           410:     idmap = &IdeIdMap[unit];
        !           411: 
        !           412: #ifdef GROK_APPLE //bknight - 2/21/98 - Radar 2204950, 2004660
        !           413: 
        !           414:        /*
        !           415:         * Special cases for HFS partitions.
        !           416:         * DKIOCNUMBLKS - return # blocks on partition, not the whole device
        !           417:         * DKIOCSFORMAT - not permitted
        !           418:         * DKIOCGFORMAT - not permitted
        !           419:         * DKIOCGLABEL - not permitted
        !           420:         * DKIOCSLABEL - not permitted
        !           421:         */
        !           422: 
        !           423:        /* Is it an HFS partition ? */
        !           424: 
        !           425:        if ( ! ( part < NPART ) )
        !           426:        {
        !           427:                switch ( cmd )
        !           428:                {
        !           429:                        case DKIOCNUMBLKS:
        !           430:                                /*
        !           431:                                 * For an HFS partition, return the # of blocks in the
        !           432:                                 * partition, rather than # of blocks on the whole device.
        !           433:                                 */
        !           434:                        
        !           435:                                diskObj = idmap->partitionId[part];
        !           436:                                *(int *)data = [diskObj diskSize];
        !           437:                                return (0);
        !           438:                                
        !           439:                        break;
        !           440: 
        !           441:                    case DKIOCSFORMAT:
        !           442:                    case DKIOCGFORMAT:
        !           443:                    case DKIOCGLABEL:
        !           444:                    case DKIOCSLABEL:
        !           445:                        return(EINVAL);
        !           446:                    break;
        !           447:                }
        !           448:        }
        !           449:        
        !           450: #endif GROK_APPLE //bknight - 2/21/98 - Radar 2204950, 2004660
        !           451: 
        !           452:     /*
        !           453:      * First verify valid device. 
        !           454:      */
        !           455:     switch (cmd) {
        !           456:       case DKIOCSFORMAT:
        !           457:       case DKIOCGFORMAT:
        !           458:       case DKIOCGLABEL:
        !           459:       case DKIOCSLABEL:
        !           460: 
        !           461:        /*
        !           462:         * Raw device, whatever the caller asked for. 
        !           463:         */
        !           464:        diskObj = idmap->partitionId[0];
        !           465:        break;
        !           466: 
        !           467:       case DKIOCGLOCATION:
        !           468:         diskObj = idmap->partitionId[part];
        !           469:        break;
        !           470: 
        !           471:       case IDEDIOCREQ:
        !           472:       case IDEDIOCINFO:
        !           473:       case DKIOCINFO:
        !           474:       case DKIOCBLKSIZE:
        !           475:       case DKIOCNUMBLKS:
        !           476: 
        !           477:        diskObj = idmap->liveId;
        !           478:        break;
        !           479: 
        !           480:       default:
        !           481:        return (EINVAL);
        !           482:     }
        !           483:     if (diskObj == nil)
        !           484:        goto nodev;
        !           485: 
        !           486:     switch (cmd) {
        !           487:       case DKIOCSFORMAT:
        !           488: 
        !           489:        /*
        !           490:         * This can fail if block devices attached to this disk are open. 
        !           491:         */
        !           492:        irtn = [diskObj setFormatted:(*(u_int *) data)];
        !           493:        break;
        !           494: 
        !           495:       case DKIOCGFORMAT:
        !           496:        {
        !           497:            *(int *)data = [diskObj isFormatted];
        !           498:            break;
        !           499:        }
        !           500: 
        !           501:       case DKIOCGLABEL:
        !           502:        {
        !           503:            struct disk_label *labelp;
        !           504: 
        !           505:            labelp = (struct disk_label *)IOMalloc(sizeof(*labelp));
        !           506:            irtn = [diskObj readLabel:labelp];
        !           507:            if (irtn == IO_R_SUCCESS) {
        !           508:                *(struct disk_label *)data = *labelp;
        !           509:            }
        !           510:            IOFree(labelp, sizeof(*labelp));
        !           511:            break;
        !           512:        }
        !           513: 
        !           514:       case DKIOCSLABEL:
        !           515:        {
        !           516:            struct disk_label *labelp;
        !           517: 
        !           518:            labelp = (struct disk_label *)IOMalloc(sizeof(*labelp));
        !           519:            *labelp = *(struct disk_label *)data;
        !           520:            irtn = [diskObj writeLabel:labelp];
        !           521:            IOFree(labelp, sizeof(*labelp));
        !           522:            break;
        !           523:        }
        !           524: 
        !           525:       case DKIOCINFO:
        !           526:        {
        !           527:            struct drive_info info;
        !           528: 
        !           529:            bzero(&info, sizeof(info));
        !           530:            strcpy(info.di_name,[diskObj driveName]);
        !           531:            info.di_devblklen = [diskObj blockSize];
        !           532:            info.di_maxbcount = IDE_MAX_PHYS_IO;
        !           533:            if (info.di_devblklen) {
        !           534:                nblk = howmany(sizeof(struct disk_label),
        !           535:                               info.di_devblklen);
        !           536:            } else {
        !           537:                nblk = 0;
        !           538:            }
        !           539:            for (i = 0; i < NLABELS; i++)
        !           540:                info.di_label_blkno[i] = nblk * i;
        !           541:            *(struct drive_info *) data = info;
        !           542:            break;
        !           543:        }
        !           544: 
        !           545:       case DKIOCBLKSIZE:
        !           546:        *(int *)data = [diskObj blockSize];
        !           547:        break;
        !           548: 
        !           549:       case DKIOCNUMBLKS:
        !           550:        *(int *)data = [diskObj diskSize];
        !           551:        break;
        !           552: 
        !           553:       case DKIOCGLOCATION:
        !           554:         if( nil == [diskObj getDevicePath:((struct drive_location *)data)->location
        !           555:                     maxLength:sizeof(((struct drive_location *)data)->location)
        !           556:                    useAlias:YES]       )
        !           557:                 irtn = IO_R_NO_MEMORY;
        !           558:         break;
        !           559: 
        !           560:       case IDEDIOCREQ:
        !           561: 
        !           562:        /*
        !           563:         * Perform specified I/O.
        !           564:         */
        !           565:        ideIoReq = (ideIoReq_t *) data;
        !           566: //     if (!suser() && (ideIoReq->cmd != IDE_IDENTIFY_DRIVE))
        !           567:        if (suser(pp->p_ucred, &pp->p_acflag) &&
        !           568:                (ideIoReq->cmd != IDE_IDENTIFY_DRIVE)) {
        !           569: //         return (u.u_error);
        !           570:            return (EINVAL);
        !           571:        }
        !           572: 
        !           573:        if ((ideIoReq->cmd == IDE_WRITE_DMA) ||
        !           574:            (ideIoReq->cmd == IDE_READ_DMA)) {
        !           575:            if ([[diskObj cntrlr] isDmaSupported:[diskObj driveNum]] != TRUE)
        !           576:                return (EINVAL);
        !           577:        }
        !           578:        
        !           579:        if (ideIoReq->cmd == IDE_IDENTIFY_DRIVE)
        !           580:            ideIoReq->blkcnt = 1;
        !           581: 
        !           582:        userPtr = (void *)ideIoReq->addr;
        !           583: 
        !           584:        alignedPtr = ideIoReq->addr;
        !           585:        if ((ideIoReq->cmd == IDE_WRITE) ||
        !           586:            (ideIoReq->cmd == IDE_READ) ||
        !           587:            (ideIoReq->cmd == IDE_READ_MULTIPLE) ||
        !           588:            (ideIoReq->cmd == IDE_WRITE_MULTIPLE) ||
        !           589:            (ideIoReq->cmd == IDE_READ_DMA) ||
        !           590:            (ideIoReq->cmd == IDE_WRITE_DMA) ||
        !           591:            (ideIoReq->cmd == IDE_IDENTIFY_DRIVE)) {
        !           592:            if (ideIoReq->blkcnt != 0) {
        !           593:                bSize = [diskObj blockSize];
        !           594:                wrFlag = ((ideIoReq->cmd == IDE_WRITE) ||
        !           595:                          (ideIoReq->cmd == IDE_WRITE_MULTIPLE) ||
        !           596:                          (ideIoReq->cmd == IDE_WRITE_DMA));
        !           597: 
        !           598:                alignedPtr = (unsigned char *)
        !           599:                    IOMalloc(ideIoReq->blkcnt * bSize);
        !           600:                if (alignedPtr == 0) {
        !           601:                    ideIoReq->status = IDER_MEMALLOC;
        !           602:                    return (ENOMEM);
        !           603:                }
        !           604:                if (wrFlag) {
        !           605:                    error = copyin(ideIoReq->addr,
        !           606:                                   alignedPtr,
        !           607:                                   ideIoReq->blkcnt * bSize);
        !           608:                    if (error) {
        !           609:                        ideIoReq->status = IDER_MEMFAIL;
        !           610:                        goto err_exit;
        !           611:                    }
        !           612:                }
        !           613:            }
        !           614:            ideIoReq->addr = (caddr_t) alignedPtr;
        !           615:            ideIoReq->map = (struct vm_map *)IOVmTaskSelf();
        !           616:        }
        !           617: 
        !           618: 
        !           619:        [diskObj ideXfrIoReq:ideIoReq];
        !           620: 
        !           621:        /*
        !           622:         * Note if we got this far, we'll return 0; any errors are in
        !           623:         * ideIoReq->status. 
        !           624:         */
        !           625:        if ((ideIoReq->cmd == IDE_WRITE) ||
        !           626:            (ideIoReq->cmd == IDE_READ) ||
        !           627:            (ideIoReq->cmd == IDE_READ_MULTIPLE) ||
        !           628:            (ideIoReq->cmd == IDE_WRITE_MULTIPLE) ||
        !           629:            (ideIoReq->cmd == IDE_READ_DMA) ||
        !           630:            (ideIoReq->cmd == IDE_WRITE_DMA) ||
        !           631:            (ideIoReq->cmd == IDE_IDENTIFY_DRIVE)) {
        !           632: 
        !           633:            ideIoReq->addr = userPtr;
        !           634:            if (((ideIoReq->cmd == IDE_READ) ||
        !           635:                 (ideIoReq->cmd == IDE_READ_MULTIPLE) ||
        !           636:                 (ideIoReq->cmd == IDE_IDENTIFY_DRIVE) ||
        !           637:                 (ideIoReq->cmd == IDE_READ_DMA)) &&
        !           638:                (ideIoReq->blocks_xfered != 0)) {
        !           639:                error = copyout(alignedPtr,
        !           640:                                userPtr,
        !           641:                                ideIoReq->blocks_xfered * bSize);
        !           642:                if (error) {
        !           643:                    ideIoReq->status = IDER_MEMFAIL;
        !           644:                }
        !           645:            }
        !           646:     err_exit:
        !           647: 
        !           648:            /*
        !           649:             * if we malloc'd any memory, free it. 
        !           650:             */
        !           651:            if (ideIoReq->blkcnt != 0)
        !           652:                IOFree(alignedPtr, ideIoReq->blkcnt * bSize);
        !           653:        }
        !           654:        break;
        !           655: 
        !           656:       case IDEDIOCINFO:
        !           657:        {
        !           658:            ideDriveInfo_t *idep = (ideDriveInfo_t *) data;
        !           659: 
        !           660:            *idep = (ideDriveInfo_t)[diskObj ideGetDriveInfo];
        !           661:            break;
        !           662:        }
        !           663:       default:
        !           664:        return (EINVAL);
        !           665:     }
        !           666: 
        !           667:     if (irtn)
        !           668:        rtn = [diskObj errnoFromReturn:irtn];
        !           669:     return (rtn);
        !           670: 
        !           671: nodev:
        !           672:     return (ENXIO);
        !           673: 
        !           674: } /* ideioctl() */
        !           675: 
        !           676: /*
        !           677:  * Obtain physical block size.
        !           678:  */
        !           679: __private_extern__ int
        !           680: idesize(dev_t dev)
        !           681: {
        !           682:     id diskObj = ide_dev_to_id(dev);
        !           683:     
        !           684:     if(diskObj == nil) {
        !           685:        return -1;
        !           686:     }
        !           687:     return [diskObj blockSize];
        !           688: }
        !           689: 
        !           690: /*
        !           691:  * Returns block and char major nums. This is used so that the PostLoad
        !           692:  * program can create block and character nodes for IDE. 
        !           693:  */
        !           694: __private_extern__ void
        !           695: ide_block_char_majors(int *blockmajor, int *charmajor)
        !           696: {
        !           697:     *blockmajor = ide_block_major;
        !           698:     *charmajor = ide_raw_major;
        !           699: }
        !           700: 
        !           701: static unsigned ideminphys(struct buf *bp)
        !           702: {
        !           703:     if (bp->b_bcount > IDE_MAX_PHYS_IO)
        !           704:        bp->b_bcount = IDE_MAX_PHYS_IO;
        !           705:     return(bp->b_bcount);
        !           706: }
        !           707: 
        !           708: /*
        !           709:  * Map dev_t to id. A nil return indicates ENXIO.
        !           710:  */
        !           711: static id ide_dev_to_id(dev_t dev)
        !           712: {
        !           713:     id rtn;
        !           714:     int unit = IO_DISK_UNIT(dev);
        !           715:     int part = IO_DISK_PART(dev);
        !           716:     IODevAndIdInfo *idmap;
        !           717: 
        !           718: #ifdef GROK_APPLE //bknight - 2/21/98 - Radar 2204950, 2004660
        !           719: 
        !           720:        if ( ! ( unit < MAX_IDE_UNIT ) )
        !           721:        {
        !           722:                /* Modify the unit # under the assumption that it is an HFS device. */
        !           723: 
        !           724:                unit -= MAX_IDE_UNIT;
        !           725:                
        !           726:                /* Is it an HFS device? */
        !           727: 
        !           728:                if ( ! ( unit < MAX_IDE_UNIT ) ) {
        !           729:                        rtn = nil;
        !           730:                        goto Return;
        !           731:                }
        !           732: 
        !           733:                /* Yes, it is an HFS device. */
        !           734:                
        !           735:                /* But it doesn't have a raw variant. */
        !           736:                
        !           737:                if ( major(dev) == ide_raw_major ) {
        !           738:                        rtn = nil;
        !           739:                        goto Return;
        !           740:                }
        !           741: 
        !           742:                /* Modify the partition # to indicate an HFS partition and then proceed. */
        !           743: 
        !           744:                part += NUM_IDE_PART;
        !           745: 
        !           746:        }
        !           747: 
        !           748: #else GROK_APPLE //bknight - 2/21/98 - Radar 2204950, 2004660
        !           749: 
        !           750:     if((unit >= NUM_IDE_DEV) || (part >= NUM_IDE_PART)) {
        !           751:                return nil;
        !           752:     }
        !           753: 
        !           754: #endif GROK_APPLE //bknight - 2/21/98 - Radar 2204950, 2004660
        !           755: 
        !           756:     idmap = &IdeIdMap[unit];
        !           757:     
        !           758:     if(part == IDE_LIVE_PART) {
        !           759:                if(major(dev) == ide_block_major) {
        !           760:                    rtn = nil;  
        !           761:                }
        !           762:                else {
        !           763:                    rtn = idmap->liveId;
        !           764:                }
        !           765:     }
        !           766:     else {
        !           767:                rtn = idmap->partitionId[part];
        !           768:     }
        !           769: Return:
        !           770:     return rtn;
        !           771: }
        !           772: 
        !           773: /* 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.