|
|
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 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.