Annotation of kernel/bsd/dev/ppc/drvATADisk/ATADiskKernel.m, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
                      7:  * Reserved.  This file contains Original Code and/or Modifications of
                      8:  * Original Code as defined in and that are subject to the Apple Public
                      9:  * Source License Version 1.1 (the "License").  You may not use this file
                     10:  * except in compliance with the License.  Please obtain a copy of the
                     11:  * License at http://www.apple.com/publicsource and read it before using
                     12:  * this file.
                     13:  * 
                     14:  * The Original Code and all software distributed under the License are
                     15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     19:  * License for the specific language governing rights and limitations
                     20:  * under the License.
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     24: 
                     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.