|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.1 (the "License"). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License. ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: /* Copyright (c) 1991 NeXT Computer, Inc. All rights reserved. ! 25: * ! 26: * IODiskPartition.m - implementation of NeXT-style logical disk. ! 27: * ! 28: * HISTORY ! 29: * 22-Jan-98 radar 1669467 - ISO 9660 CD support - jwc ! 30: * 15-Dec-92 Sam Streeper (sam) at NeXT ! 31: * Added support for a NeXT disk on a MS-DOS partition ! 32: * 01-May-91 Doug Mitchell at NeXT ! 33: * Created. ! 34: */ ! 35: ! 36: #define DRIVER_PRIVATE 1 ! 37: ! 38: #import <driverkit/return.h> ! 39: #import <driverkit/IODiskPartition.h> ! 40: #import <driverkit/generalFuncs.h> ! 41: #import <bsd/dev/disk_label.h> ! 42: #import <bsd/sys/disktab.h> ! 43: #ifdef KERNEL ! 44: #import <kernserv/prototypes.h> ! 45: #import <driverkit/kernelDiskMethods.h> ! 46: #import <driverkit/kernelDiskMethodsPrivate.h> ! 47: #import <driverkit/kernelDriver.h> ! 48: #import <machkit/NXLock.h> ! 49: #else KERNEL ! 50: #import <bsd/libc.h> ! 51: #endif KERNEL ! 52: #import <kern/time_stamp.h> ! 53: #import <driverkit/Device_ddm.h> ! 54: #import <mach/vm_param.h> ! 55: #import <driverkit/disk_label.h> ! 56: #import <driverkit/diskstruct.h> ! 57: #ifdef i386 ! 58: #import <bsd/dev/i386/disk.h> ! 59: #endif i386 ! 60: #import <architecture/byte_order.h> ! 61: #import "label_subr.h" ! 62: #import <driverkit/IODeviceDescription.h> ! 63: #import <bsd/dev/voldev.h> ! 64: #ifdef ppc ! 65: #import <bsd/dev/ppc/disk.h> ! 66: #endif ! 67: ! 68: /* Define GROK_DOS if scsi driver is to understand MS-DOS partitions. ! 69: * It only finds the partition with the NeXT name. Live partition is ! 70: * not affected. -sam ! 71: * ! 72: * define GROK_APPLE if we want to look to a Rhapsody partition on a ! 73: * Apple Partitioned disk ! 74: */ ! 75: #ifdef i386 ! 76: #define GROK_DOS ! 77: #endif ! 78: ! 79: #ifdef ppc ! 80: #define GROK_APPLE 1 ! 81: #endif ! 82: ! 83: // seconds to wait for disk ready at probe time ! 84: #define DELAY_AT_PROBE 0 ! 85: ! 86: #ifdef GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 87: ! 88: #define HFS_PART_TYPE "Apple_HFS" ! 89: ! 90: #endif //bknight - 12/3/97 - Radar #2004660 ! 91: ! 92: ! 93: @interface IODiskPartition(Private) ! 94: ! 95: /* ! 96: * Private methods. ! 97: */ ! 98: /* ! 99: * Examine a known good label, initialize LogicalDisk parameters for the ! 100: * raw device (on which this method is invoked) and create block devices ! 101: * as appropriate. ! 102: * ! 103: * Invoked by LogicalDisk +probe, upon disk insertion, and when a new label ! 104: * is written. ! 105: */ ! 106: - (void) _probeLabel : (disk_label_t *)labelp; ! 107: ! 108: /* ! 109: * Assign logical disk parameters for a partition instance. ! 110: */ ! 111: - (void)_initPartition : (int)partNum ! 112: physicalPartition : (int)physNum ! 113: disktab : (struct disktab *)dtp; ! 114: ! 115: /* ! 116: * Free all partition instances other than partition 0. ! 117: */ ! 118: - (IOReturn)_freePartitions; ! 119: ! 120: /* ! 121: * Determine if any block devices in the logicalDisk chain are open. ! 122: */ ! 123: - (BOOL)isAnyBlockDevOpen; ! 124: ! 125: /* ! 126: * Verify that it's safe to do an operation which will result in a call ! 127: * to _freePartitions. ! 128: */ ! 129: - (IOReturn)checkSafeConfig : (const char *)op; ! 130: ! 131: #ifdef GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 132: ! 133: /* ! 134: * IODiskPartition knows how to ! 135: * Create HFS Devices From Apple Partition Map. ! 136: */ ! 137: + (void)CreateHFSDevicesFromApplePartitionMap : (id)physicalDisk; ! 138: ! 139: /* ! 140: * Assign logical disk parameters for a partition instance. ! 141: */ ! 142: ! 143: - (void) _initHFSPartition : (int) partitionNum ! 144: physicalPartNum : (int) physNum ! 145: diskSize : (int) diskSize ! 146: partitionBase : (int) partitionBase; ! 147: ! 148: #endif GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 149: ! 150: @end ! 151: ! 152: ! 153: @implementation IODiskPartition ! 154: ! 155: + (IODeviceStyle)deviceStyle ! 156: { ! 157: return IO_IndirectDevice; ! 158: } ! 159: ! 160: /* ! 161: * The protocol we need as an indirect device. ! 162: */ ! 163: static Protocol *protocols[] = { ! 164: @protocol(IOPhysicalDiskMethods), ! 165: @protocol(IODiskReadingAndWriting), ! 166: nil ! 167: }; ! 168: ! 169: + (Protocol **)requiredProtocols ! 170: { ! 171: return protocols; ! 172: } ! 173: ! 174: /* ! 175: * Attempt to read label of physical device. If valid label, create an ! 176: * instance of LogicalDisk for each valid partition as well as for the ! 177: * Unix raw device. Returns YES if any instances were created. ! 178: */ ! 179: + (BOOL)probe : deviceDescription ! 180: { ! 181: id physDisk = [deviceDescription directDevice]; ! 182: int try; ! 183: IODiskReadyState ready; ! 184: IOReturn rtn; ! 185: disk_label_t *labelp = NULL; ! 186: IODiskPartition *part0p; ! 187: BOOL frtn = YES; // when would this be NO? ! 188: char name[30]; ! 189: id ld; ! 190: const char *physName = [physDisk name]; ! 191: unsigned physBlockSize = 0; ! 192: unsigned physDiskSize = 0; ! 193: unsigned formattedFlag; ! 194: BOOL logParams = NO; ! 195: BOOL logLabel = NO; ! 196: IODiskReadyState oldReady; ! 197: ! 198: xpr_disk("IODiskPartition probe\n", 1,2,3,4,5); ! 199: /* ! 200: * First of all, we're only interested in physical disks. ! 201: * (Shouldn't this be covered by our requiredProtocols values?) ! 202: */ ! 203: if(![physDisk isPhysical]) { ! 204: return NO; ! 205: } ! 206: ! 207: /* ! 208: * Create a partition 0 instance if there isn't already one; attach ! 209: * it to physDisk. There will already be a partition 0 instance if ! 210: * this probe is in response to a disk insertion as opposed to ! 211: * initial device configuration. ! 212: */ ! 213: ld = [physDisk nextLogicalDisk]; ! 214: if(ld != nil) { ! 215: part0p = (IODiskPartition *)ld; ! 216: ! 217: /* ! 218: * Update physical parameters. ! 219: */ ! 220: [part0p connectToPhysicalDisk:physDisk]; ! 221: part0p->_labelValid = 0; ! 222: part0p->_physicalPartition = 0; ! 223: ! 224: #ifdef GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 225: part0p->_hfsValid = 0; ! 226: #endif GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 227: part0p->_blockDeviceOpen = 0; ! 228: part0p->_rawDeviceOpen = 0; ! 229: IOLog("\n"); ! 230: } ! 231: else { ! 232: part0p = [IODiskPartition new]; ! 233: sprintf(name, "%sa", physName); ! 234: [part0p setName:name]; ! 235: [part0p setDeviceKind:"IODiskPartition"]; ! 236: [part0p setDriveName:"IODiskPartition Partition"]; ! 237: [part0p setLocation:NULL]; ! 238: part0p->_partitionWaitLock = [[NXConditionLock alloc] init]; ! 239: IOGetTimestamp( &part0p->_probeTime); ! 240: [part0p init]; ! 241: [part0p connectToPhysicalDisk:physDisk]; ! 242: [part0p setDeviceDescription:deviceDescription]; ! 243: [physDisk setLogicalDisk:part0p]; ! 244: part0p->_labelValid = 0; ! 245: #ifdef GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 246: part0p->_hfsValid = 0; ! 247: #endif GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 248: part0p->_blockDeviceOpen = 0; ! 249: part0p->_rawDeviceOpen = 0; ! 250: ! 251: #ifdef KERNEL ! 252: /* ! 253: * Register both physDisk and partition 0 with Unix ! 254: * level owner. ! 255: */ ! 256: [physDisk registerUnixDisk:0]; ! 257: [part0p registerUnixDisk:0]; ! 258: #endif KERNEL ! 259: } ! 260: ! 261: /* ! 262: * Give the drive a chance to spin up. ! 263: */ ! 264: oldReady = [physDisk lastReadyState]; ! 265: ! 266: #if DELAY_AT_PROBE ! 267: if( (physName[0] == 'f') && (physName[1] == 'd')) ! 268: ready = [physDisk updateReadyState]; ! 269: else { ! 270: for(try = 0; try < DELAY_AT_PROBE; try++) { ! 271: ready = [physDisk updateReadyState]; ! 272: switch(ready) { ! 273: case IO_Ready: ! 274: goto goOn; /* go for it */ ! 275: case IO_NotReady: ! 276: break; /* try again */ ! 277: case IO_NoDisk: ! 278: if (try > 0) ! 279: IOLog("\n"); ! 280: goto done; /* forget it */ ! 281: case IO_Ejecting: ! 282: break; /* try again */ ! 283: } ! 284: if(try == 0) ! 285: IOLog("%s: Waiting for drive to come ready", physName); ! 286: else ! 287: IOLog("."); ! 288: IOSleep(1000); ! 289: } ! 290: goOn: ! 291: if (try > 0) ! 292: IOLog("\n"); ! 293: } ! 294: #else ! 295: ready = [physDisk updateReadyState]; ! 296: #endif ! 297: [physDisk setLastReadyState:ready]; ! 298: if(ready != IO_Ready) { ! 299: IOLog("%s: Disk Not Ready\n", physName); ! 300: xpr_disk("IODiskPartition probe: Disk Not Ready\n", 1,2,3,4,5); ! 301: goto done; ! 302: } ! 303: ! 304: /* ! 305: * If the disk just came ready, have driver update its physical ! 306: * parameters. ! 307: */ ! 308: if(oldReady != IO_Ready) { ! 309: [physDisk updatePhysicalParameters]; ! 310: } ! 311: ! 312: /* ! 313: * If disk is not formatted, forget the rest of this. ! 314: */ ! 315: formattedFlag = [physDisk isFormatted]; ! 316: if(!formattedFlag) { ! 317: IOLog("%s: Disk Unformatted\n", physName); ! 318: xpr_disk("IODiskPartitionProbe: physDisk %s not formatted\n", ! 319: physName, 2,3,4,5); ! 320: goto done; ! 321: } ! 322: ! 323: physDiskSize = [physDisk diskSize]; ! 324: physBlockSize = [physDisk blockSize]; ! 325: ! 326: [part0p setPhysicalBlockSize:physBlockSize]; ! 327: ! 328: logParams = YES; ! 329: ! 330: /* ! 331: * Try to read a label. ! 332: */ ! 333: labelp = IOMalloc(sizeof(disk_label_t)); ! 334: rtn = [part0p readLabel:labelp]; ! 335: if(rtn) { ! 336: xpr_disk("IODiskPartition probe: No Label\n", 1,2,3,4,5); ! 337: IOLog("%s: No Valid Disk Label\n", physName); ! 338: ! 339: /* ! 340: * Set up blockSize and diskSize of partition A ! 341: * to be the same as our physicalDisk's for now. ! 342: */ ! 343: [part0p setBlockSize:physBlockSize]; ! 344: [part0p setDiskSize:[physDisk diskSize]]; ! 345: ! 346: /* Remember to reset the partition base to zero, ! 347: * since we don't yet have any recognizable ! 348: * partitioning information. ! 349: */ ! 350: [part0p setPartitionBase:0]; ! 351: } ! 352: else { ! 353: logLabel = YES; ! 354: ! 355: /* ! 356: * Initialize remaining device parameters and create ! 357: * additional partition instances as appropriate. ! 358: */ ! 359: [part0p _probeLabel:labelp]; ! 360: } ! 361: ! 362: #ifdef GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 363: ! 364: [self CreateHFSDevicesFromApplePartitionMap:deviceDescription]; ! 365: ! 366: #endif GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 367: ! 368: if( part0p->_partitionWaitLock) { ! 369: [part0p->_partitionWaitLock lock]; ! 370: [part0p->_partitionWaitLock unlockWith:YES]; ! 371: } ! 372: done: ! 373: if(logParams) { ! 374: unsigned kbytes; ! 375: ! 376: IOLog("%s: Device Block Size: %u bytes\n", ! 377: physName, physBlockSize); ! 378: kbytes = (physDiskSize / 1024) * physBlockSize; ! 379: if(kbytes > (10 * 1024)) { ! 380: IOLog("%s: Device Capacity: %u MB\n", ! 381: physName, kbytes / 1024); ! 382: } ! 383: else { ! 384: IOLog("%s: Device Capacity: %u KB\n", ! 385: physName, physDiskSize * physBlockSize / ! 386: 1024); ! 387: } ! 388: } ! 389: if(logLabel) { ! 390: IOLog("%s: Disk Label: %s\n", ! 391: physName, labelp->dl_label); ! 392: } ! 393: if(labelp != NULL) { ! 394: IOFree(labelp, sizeof(disk_label_t)); ! 395: } ! 396: ! 397: if(ld == nil) ! 398: [part0p registerDevice]; ! 399: ! 400: return(frtn); ! 401: } ! 402: ! 403: #ifdef GROK_DOS ! 404: /* returns the offset to the NeXT partition of an MSDOS partitioned ! 405: * hard disk (0 if it isn't a DOS disk), or a (negative) IOReturn. ! 406: */ ! 407: - (int) NeXTpartitionOffset ! 408: { ! 409: IOReturn frtn = 0; ! 410: IOReturn rtn; ! 411: unsigned bytesXfr; ! 412: id physDisk = [self physicalDisk]; ! 413: /* ! 414: * Force page alignment... ! 415: */ ! 416: unsigned char *blk= IOMalloc(PAGE_SIZE); ! 417: struct disk_blk0 *blk0; ! 418: struct fdisk_part *fd; ! 419: int n; ! 420: BOOL validPart = NO; ! 421: ! 422: if ([self physicalBlockSize] != DISK_BLK0SZ) { ! 423: frtn = 0; ! 424: goto out; ! 425: } ! 426: // fixme - can I really transfer to unwired, unaligned buffer? ! 427: rtn = [[super class] commonReadWrite ! 428: : physDisk ! 429: : YES /* read */ ! 430: : (unsigned long long)DISK_BLK0 * [physDisk blockSize] ! 431: : DISK_BLK0SZ /* bytes */ ! 432: : blk ! 433: : IOVmTaskSelf() ! 434: : (void *)NULL ! 435: : &bytesXfr]; ! 436: ! 437: if (rtn) { ! 438: frtn = IO_R_NO_BLOCK_ZERO; ! 439: goto out; ! 440: } ! 441: ! 442: // Check for a valid DOS boot block. ! 443: blk0 = (struct disk_blk0 *)blk; ! 444: if (blk0->signature != DISK_SIGNATURE) { ! 445: goto out; ! 446: } ! 447: ! 448: // Check to see if the disk has been partitioned with FDISK ! 449: // to allow DOS and ufs filesystems to exist on the same disk ! 450: fd = (struct fdisk_part *)blk0->parts; ! 451: for (n = 0; n < FDISK_NPART; n++, fd++) { ! 452: switch(fd->systid) { ! 453: case 0: ! 454: /* ! 455: * Not valid partition, meaningless. ! 456: */ ! 457: break; ! 458: case FDISK_NEXTNAME: ! 459: /* ! 460: * Valid NeXT partition. ! 461: */ ! 462: frtn = fd->relsect; ! 463: _physicalPartition = n; ! 464: goto out; ! 465: default: ! 466: /* ! 467: * Not what we're looking for, but this means that ! 468: * we can't use partition 0. ! 469: */ ! 470: validPart = YES; ! 471: break; ! 472: } ! 473: } ! 474: if(validPart) { ! 475: frtn = IO_R_NO_NEXT_PART; ! 476: } ! 477: else { ! 478: /* ! 479: * No valid partitions; treat same as "no valid block 0". ! 480: */ ! 481: } ! 482: out: ! 483: IOFree(blk, PAGE_SIZE); ! 484: return frtn; ! 485: } ! 486: #endif GROK_DOS ! 487: ! 488: #ifdef GROK_APPLE ! 489: /* ! 490: * Check for an apple partition: ! 491: * ! 492: */ ! 493: #define BLOCKSIZE_512_BYTES 512 ! 494: ! 495: - (int) NeXTpartitionOffset ! 496: { ! 497: unsigned char * blk; ! 498: Block0 * blk0; ! 499: unsigned long blocksize = [self physicalBlockSize]; ! 500: unsigned bytesXfr; ! 501: IOReturn frtn = 0; ! 502: id physDisk = [self physicalDisk]; ! 503: IOReturn rtn; ! 504: ! 505: blk = IOMalloc(PAGE_SIZE); /* force page alignment */ ! 506: blk0 = (Block0 *)blk; ! 507: ! 508: /* check block 0 for valid Apple partition signature */ ! 509: ! 510: rtn = [[super class] commonReadWrite ! 511: : physDisk ! 512: : YES /* read */ ! 513: : (unsigned long long)0 /* byte offset */ ! 514: : PAGE_SIZE /* bytes */ ! 515: : blk ! 516: : IOVmTaskSelf() ! 517: : (void *)NULL ! 518: : &bytesXfr]; ! 519: ! 520: /* scan for the rhapsody apple ufs partition */ ! 521: if (rtn) ! 522: frtn = IO_R_NO_BLOCK_ZERO; ! 523: else { ! 524: unsigned int block = 1; ! 525: unsigned int entry_within_block = 0; ! 526: int n; ! 527: unsigned int nentries_per_block = 1; ! 528: unsigned int numPartBlocks; ! 529: DPME * partEntry; ! 530: int physNum; ! 531: ! 532: /* check if there is a valid map at 512 offset */ ! 533: partEntry = (DPME *)(blk + BLOCKSIZE_512_BYTES); ! 534: if (blocksize > BLOCKSIZE_512_BYTES) { ! 535: if (NXSwapBigShortToHost(partEntry->dpme_signature) ! 536: == DPME_SIGNATURE) { ! 537: /* there is a valid map, and the device blocksize ! 538: * is > 512, which means we probably have a CDROM ! 539: * using 2K, but having valid 512 map ! 540: */ ! 541: block = 0; ! 542: nentries_per_block = blocksize / BLOCKSIZE_512_BYTES; ! 543: entry_within_block = 1; ! 544: } ! 545: else ! 546: partEntry = (DPME *)(blk + blocksize); ! 547: } ! 548: if (NXSwapBigShortToHost(partEntry->dpme_signature) == DPME_SIGNATURE) { ! 549: numPartBlocks = NXSwapBigLongToHost(partEntry->dpme_map_entries); ! 550: #ifdef PRINT_APT ! 551: IOLog("Apple Partition table (%d entries)...\n", numPartBlocks); ! 552: #endif PRINT_APT ! 553: ! 554: physNum = 1; ! 555: for (n = 0; n < numPartBlocks; n++) { ! 556: int ufs_partition_set = 0; ! 557: ! 558: if (NXSwapBigShortToHost(partEntry->dpme_signature) ! 559: != DPME_SIGNATURE) { ! 560: break; ! 561: } ! 562: if (strcmp(partEntry->dpme_type, RHAPSODY_PART_TYPE) == 0 ! 563: && ufs_partition_set == 0) { ! 564: unsigned long part_offset; ! 565: ! 566: part_offset ! 567: = NXSwapBigLongToHost(partEntry->dpme_pblock_start); ! 568: if ((part_offset / nentries_per_block * nentries_per_block) ! 569: != part_offset) { ! 570: IOLog("IODiskPartition: " RHAPSODY_PART_TYPE ! 571: " partition base (%ld x 512) is not" ! 572: " a multiple of the devblksize %ld\n", ! 573: part_offset, blocksize); ! 574: frtn = IO_R_NO_NEXT_PART; ! 575: break; ! 576: } ! 577: ! 578: part_offset = part_offset / nentries_per_block; ! 579: #ifdef PRINT_APT ! 580: IOLog("%s: UFS partition at offset %ld\n", ! 581: [physDisk name], part_offset); ! 582: #endif PRINT_APT ! 583: frtn = (IOReturn)part_offset; ! 584: ufs_partition_set = 1; ! 585: _physicalPartition = physNum; ! 586: } ! 587: #ifdef PRINT_APT ! 588: IOLog("Apple Partition entry %d:\n", n + 1); ! 589: IOLog(" Name: %s, Type %s, size: %d\n", ! 590: partEntry->dpme_name, partEntry->dpme_type, ! 591: partEntry->dpme_pblocks); ! 592: IOLog("block %d entry %d (of %d) blocksize %d\n", ! 593: block, entry_within_block + 1, ! 594: nentries_per_block, blocksize); ! 595: #endif PRINT_APT ! 596: partEntry++; ! 597: physNum++; ! 598: if (++entry_within_block == nentries_per_block) { ! 599: block++; ! 600: entry_within_block = 0; ! 601: partEntry = (DPME *)blk; ! 602: ! 603: rtn = [[super class] commonReadWrite ! 604: : physDisk ! 605: : YES /* read */ ! 606: : (unsigned long long)block * blocksize /* byte offset */ ! 607: : blocksize /* bytes */ ! 608: : blk ! 609: : IOVmTaskSelf() ! 610: : (void *)NULL ! 611: : &bytesXfr]; ! 612: ! 613: if (rtn) { ! 614: frtn = IO_R_NO_NEXT_PART; ! 615: break; ! 616: } ! 617: } ! 618: } ! 619: } /* DPME signature validation */ ! 620: } /* scan for Apple rhapsody ufs partitions */ ! 621: IOFree(blk, PAGE_SIZE); ! 622: return frtn; ! 623: } ! 624: ! 625: - getDevicePath:(char *)path maxLength:(int)maxLen useAlias:(BOOL)doAlias ! 626: { ! 627: if( [[self physicalDisk] ! 628: getDevicePath:path maxLength:maxLen useAlias:doAlias]) { ! 629: ! 630: char partStr[ 12 ]; ! 631: ! 632: sprintf( partStr, ":%x", _physicalPartition); ! 633: strcat( path, partStr); ! 634: return( self); ! 635: } ! 636: return( nil); ! 637: } ! 638: ! 639: #endif GROK_APPLE ! 640: ! 641: /* ! 642: * Read disk label. label_p must does not have to be aligned; we do a ! 643: * page-aligned read to satisfy any possible DMA requirements. ! 644: * ! 645: * This is only invoked on the raw device. This can be invoked on a ! 646: * drive with no disk present; we'll do a 'isDiskReady:YES" to get a ! 647: * disk if necessary. ! 648: * ! 649: * This reads labels as raw m68k disk_label_t's. On successful return, ! 650: * *label_p contains a label which is valid for the current architecture; ! 651: * the transformation is performed per the API in <driverkit/disk_label.h>. ! 652: */ ! 653: ! 654: - (IOReturn) readLabel : (disk_label_t *)label_p ! 655: { ! 656: int label_num; ! 657: IOReturn rtn; ! 658: int found = 0; ! 659: int blocksInLabel; ! 660: int bytesInLabel; ! 661: unsigned bytesXfr; ! 662: char *raw_label; ! 663: int labelBufSize; ! 664: id physDisk = [self physicalDisk]; ! 665: unsigned physBlockSize = [self physicalBlockSize]; ! 666: unsigned physFormatted; ! 667: unsigned blocksize; ! 668: const char *disk_name = [self name]; ! 669: /* offset of NeXT disk on dos or Apple partition */ ! 670: int part_offset = 0; ! 671: ! 672: xpr_disk("IODiskPartition readLabel\n", 1,2,3,4,5); ! 673: ! 674: /* ! 675: * Note we have to 'fault in' a possible non-present disk in ! 676: * order to get its physical parameters... ! 677: */ ! 678: rtn = [physDisk isDiskReady:YES]; ! 679: switch(rtn) { ! 680: case IO_R_SUCCESS: ! 681: break; ! 682: case IO_R_NO_DISK: ! 683: xpr_err("%s readLabel: disk not present\n", disk_name, ! 684: 2,3,4,5); ! 685: return(rtn); ! 686: default: ! 687: IOLog("%s readLabel: bogus return from isDiskReady (%s)\n", ! 688: disk_name, [self stringFromReturn:rtn]); ! 689: return(rtn); ! 690: } ! 691: ! 692: physFormatted = [physDisk isFormatted]; ! 693: if((physBlockSize == 0) || !physFormatted) { ! 694: xpr_err("%s readLabel: physDisk UNFORMATTED\n", ! 695: disk_name, 2,3,4,5); ! 696: return(IO_R_UNFORMATTED); ! 697: } ! 698: ! 699: #if defined(GROK_DOS) || defined(GROK_APPLE) ! 700: part_offset = [self NeXTpartitionOffset]; ! 701: if (part_offset < 0) { ! 702: return part_offset; ! 703: } ! 704: #ifdef DEBUG ! 705: if (part_offset > 0) { ! 706: printf("found NeXT disk partition at offset" ! 707: ", offset = %d sectors\n", part_offset); ! 708: } ! 709: #endif DEBUG ! 710: #endif defined(GROK_DOS) || defined(GROK_APPLE) ! 711: ! 712: /* ! 713: * Careful, we're reading in an m68k-style label... ! 714: */ ! 715: blocksInLabel = howmany(SIZEOF_DISK_LABEL_T, physBlockSize); ! 716: bytesInLabel = blocksInLabel * physBlockSize; ! 717: labelBufSize = round_page(bytesInLabel); ! 718: ! 719: /* ! 720: * This assumes that the memory allocator used by IOMalloc will ! 721: * return one physically contiguous page if we ask it for one ! 722: * page...should be OK, right? ! 723: * This used to be vm_allocate(), but can't DMA to IOTask's ! 724: * virtual memory. ! 725: */ ! 726: raw_label = IOMalloc(labelBufSize); ! 727: for(label_num=0; label_num<NLABELS; label_num++) { ! 728: ! 729: /* To read a disk label, we *should* use the blocksize of the ! 730: * enclosing partition, but we don't know what that is. ! 731: * ! 732: * As a workaround, we can use the *physical* blocksize. By ! 733: * doing so, we will always compute the proper offset for ! 734: * fixed disks using Mac, FDISK, or *no* partitioning scheme, ! 735: * since all these schemes assume a 512 byte blocksize. ! 736: * (It is possible for a Mac partition map to imply a non-512 ! 737: * blocksize, but in practice this is rare). ! 738: * ! 739: * Using the physical blocksize would not iterate properly ! 740: * through all four labels on a Mac-partitioned CD-ROM, because ! 741: * we'd be using 2K blocks instead of the Mac partition's 512. ! 742: * This, however, *still* luckily works because the first label ! 743: * is at offset zero: offset zero is always the same no matter ! 744: * what you're multiplying by to get that zero! ! 745: * ! 746: * Once we find a valid label (often the one at offset zero), ! 747: * we immediately reset our logical blocksize, so after that ! 748: * point things work normally. ! 749: */ ! 750: ! 751: blocksize = [physDisk blockSize]; ! 752: ! 753: rtn = [[super class] commonReadWrite ! 754: : physDisk ! 755: : YES /* read */ ! 756: : ((unsigned long long)part_offset + ! 757: (label_num * blocksInLabel)) ! 758: * blocksize /* byte offset */ ! 759: : bytesInLabel /* bytes */ ! 760: : raw_label ! 761: : IOVmTaskSelf() ! 762: : (void *)NULL ! 763: : &bytesXfr]; ! 764: if((rtn == IO_R_SUCCESS) && ! 765: (bytesXfr == bytesInLabel)) { ! 766: ! 767: /* ! 768: * Is it a valid disk label? ! 769: */ ! 770: const char *rtn; ! 771: ! 772: rtn = check_label(raw_label, ! 773: part_offset + (label_num*blocksInLabel)); ! 774: if(rtn == NULL) { ! 775: found++; ! 776: break; ! 777: } ! 778: #ifdef DEBUG ! 779: else { ! 780: IOLog("%s\n", rtn); ! 781: } ! 782: #endif DEBUG ! 783: } ! 784: ! 785: /* ! 786: * there is one fatal error here - disk not present. ! 787: */ ! 788: if(rtn == IO_R_NO_DISK) ! 789: break; ! 790: } ! 791: ! 792: if(found) { ! 793: /* ! 794: * Success. ! 795: */ ! 796: xpr_disk("readLabel: Valid Label\n", 1,2,3,4,5); ! 797: _labelValid = 1; ! 798: #ifdef GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 799: _hfsValid = 0; // bek - 12/14/97 - Is this redundant? ! 800: #endif GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 801: get_disk_label(raw_label, label_p); ! 802: rtn = IO_R_SUCCESS; ! 803: } ! 804: else { ! 805: xpr_disk("readLabel: NO LABEL\n", 1,2,3,4,5); ! 806: if(rtn != IO_R_NO_DISK) ! 807: rtn = IO_R_NO_LABEL; ! 808: } ! 809: IOFree(raw_label, labelBufSize); ! 810: return(rtn); ! 811: } ! 812: ! 813: /* ! 814: * Write disk label. Label is passed in as an actual native label per ! 815: * current architecture and is written as an m68k-style label. ! 816: */ ! 817: ! 818: static inline void put_short(unsigned short s, void *dest) ! 819: { ! 820: *((unsigned short *)dest) = NXSwapHostShortToBig(s); ! 821: } ! 822: ! 823: - (IOReturn) writeLabel : (disk_label_t *)label_p ! 824: { ! 825: unsigned size; ! 826: unsigned short *cksum_p; ! 827: unsigned short cksum; ! 828: ns_time_t timestamp; ! 829: int label_num; ! 830: unsigned bytesXfr; ! 831: int goodLabel = 0; ! 832: IOReturn rtn; ! 833: int blocksInLabel; ! 834: int bytesInLabel; ! 835: id physDisk = [self physicalDisk]; ! 836: unsigned physBlockSize = [self physicalBlockSize]; ! 837: char *raw_label = NULL; ! 838: int labelBufSize = 0; /* compiler quirk */ ! 839: unsigned formattedFlag = 0; ! 840: const char *lrtn; ! 841: int cksum_offset; ! 842: /* offset of NeXT disk on dos or Apple partition */ ! 843: int part_offset = 0; ! 844: #ifdef i386 ! 845: /* ! 846: * Avoid writing first label over block 0. ! 847: */ ! 848: int firstLabel = 1; ! 849: #else i386 ! 850: int firstLabel = 0; ! 851: #endif i386 ! 852: ! 853: xpr_disk("IODiskPartition writeLabel\n", 1,2,3,4,5); ! 854: ! 855: /* ! 856: * We can't do this if any block devices, or any other logical disk, ! 857: * are currently open. Also, we can only do this on partition 0 ! 858: * because we're going to blow away all IODiskPartitions other than the ! 859: * one for partition 0 before we're thru. ! 860: */ ! 861: rtn = [self checkSafeConfig:"writeLabel"]; ! 862: if(rtn) { ! 863: return rtn; ! 864: } ! 865: ! 866: /* ! 867: * Lock out similar destructive actions... ! 868: */ ! 869: [physDisk lockLogicalDisks]; ! 870: ! 871: formattedFlag = [physDisk isFormatted]; ! 872: if(!formattedFlag) { ! 873: xpr_disk("IODiskPartition writeLabel: UNFORMATTED DISK\n", ! 874: 1,2,3,4,5); ! 875: rtn = IO_R_IO; ! 876: goto done; ! 877: } ! 878: ! 879: /* ! 880: * OK, here we go. All other partitions are now invalid. Let's ! 881: * get rid of them. ! 882: */ ! 883: [self _freePartitions]; ! 884: _labelValid = 0; // until we're thru ! 885: #ifdef GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 886: _hfsValid = 0; // until we're thru ! 887: #endif GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 888: ! 889: if(label_p->dl_version == DL_V1 || label_p->dl_version == DL_V2) { ! 890: size = SIZEOF_DISK_LABEL_T; ! 891: cksum_p = &label_p->dl_checksum; ! 892: cksum_offset = DISK_LABEL_DL_CHECKSUM; ! 893: } else if(label_p->dl_version == DL_V3) { ! 894: size = SIZEOF_DISK_LABEL_T - SIZEOF_DL_UN_T; ! 895: cksum_p = &label_p->dl_v3_checksum; ! 896: cksum_offset = DISK_LABEL_DL_UN; ! 897: } ! 898: else { ! 899: IOLog("%s writeLabel: BAD LABEL\n", [self name]); ! 900: rtn = IO_R_INVALID_ARG; ! 901: goto done; ! 902: } ! 903: ! 904: /* ! 905: * tag label with time. ! 906: */ ! 907: IOGetTimestamp(×tamp); ! 908: label_p->dl_tag = (unsigned)timestamp; ! 909: ! 910: /* ! 911: * prepare to validate (before converting to m68k-style label). ! 912: */ ! 913: label_p->dl_label_blkno = 0; ! 914: *cksum_p = 0; ! 915: ! 916: /* ! 917: * Get an m68k-style label for validation (and which we'll eventually ! 918: * write to disk). We do page alignment here to satisfy the most ! 919: * stringent DMA requirements downstream. ! 920: */ ! 921: blocksInLabel = howmany(SIZEOF_DISK_LABEL_T, physBlockSize); ! 922: bytesInLabel = blocksInLabel * physBlockSize; ! 923: labelBufSize = round_page(bytesInLabel); ! 924: raw_label = IOMalloc(labelBufSize); ! 925: put_disk_label(label_p, raw_label); ! 926: ! 927: /* ! 928: * Get checksum and validate. Careful, put the checksum in the ! 929: * raw m68k-style label in a machine-independent manner... ! 930: */ ! 931: cksum = checksum16((unsigned short *)raw_label, size >> 1); ! 932: put_short(cksum, raw_label + cksum_offset); ! 933: if(lrtn = check_label(raw_label, 0)) { ! 934: IOLog("%s writeLabel: BAD LABEL : %s\n", ! 935: [self name], lrtn); ! 936: rtn = IO_R_INVALID_ARG; ! 937: goto done; ! 938: } ! 939: ! 940: #if defined(GROK_DOS) || defined(GROK_APPLE) ! 941: part_offset = [self NeXTpartitionOffset]; ! 942: if (part_offset < 0) { ! 943: rtn = part_offset; ! 944: goto done; ! 945: } ! 946: #endif defined(GROK_DOS) || defined(GROK_APPLE) ! 947: ! 948: /* ! 949: * OK, the caller gave us a good label. Write NLABEL copies. ! 950: */ ! 951: for(label_num=firstLabel; label_num<NLABELS; label_num++) { ! 952: *(int *)(raw_label + DISK_LABEL_DL_LABEL_BLKNO ) = ! 953: NXSwapHostIntToBig(part_offset + ! 954: (label_num * blocksInLabel)); ! 955: ! 956: rtn = [[super class] commonReadWrite ! 957: : physDisk ! 958: : NO /* write */ ! 959: : ((unsigned long long)part_offset + ! 960: (label_num * blocksInLabel)) ! 961: * physBlockSize /* byte offset */ ! 962: : bytesInLabel /* bytes */ ! 963: : raw_label ! 964: : IOVmTaskSelf() ! 965: : (void *)NULL ! 966: : &bytesXfr]; ! 967: ! 968: if((rtn == IO_R_SUCCESS) && (bytesXfr == bytesInLabel)) { ! 969: goodLabel++; ! 970: } ! 971: /* ! 972: * there is one fatal error here - disk not present. ! 973: */ ! 974: if(rtn == IO_R_NO_DISK) ! 975: break; ! 976: } ! 977: if(goodLabel) { ! 978: _labelValid = 1; ! 979: #ifdef GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 980: _hfsValid = 0; // bek - 12/14/97 - Is this redundant? ! 981: #endif GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 982: rtn = IO_R_SUCCESS; ! 983: } ! 984: else { ! 985: xpr_disk("IODiskPartition writeLabel: Couldn\'t write label\n", ! 986: 1,2,3,4,5); ! 987: if(rtn != IO_R_NO_DISK) ! 988: rtn = IO_R_IO; ! 989: goto done; ! 990: } ! 991: ! 992: /* ! 993: * One more thing - update our own parameters and see if we ! 994: * need to create any block devices. ! 995: */ ! 996: [self _probeLabel: label_p]; ! 997: done: ! 998: [physDisk unlockLogicalDisks]; ! 999: if(raw_label) { ! 1000: IOFree(raw_label, labelBufSize); ! 1001: } ! 1002: return(rtn); ! 1003: } ! 1004: ! 1005: ! 1006: /* ! 1007: * Before we die, tell owner about this. LogicalDisk takes care of freeing ! 1008: * chained logicalDisks. ! 1009: */ ! 1010: - free ! 1011: { ! 1012: #ifdef KERNEL ! 1013: [self unregisterUnixDisk: _partition]; ! 1014: #endif KERNEL ! 1015: ! 1016: if( _partitionWaitLock) { ! 1017: [_partitionWaitLock free]; ! 1018: _partitionWaitLock = nil; ! 1019: } ! 1020: return([super free]); ! 1021: } ! 1022: ! 1023: /* ! 1024: * Handle Disk Eject request. Overrides IODisk's method of same name. ! 1025: * Invoked upon the partition 0 instance by DiskObject's eject. This ! 1026: * will be rejected at the DiskObject level if any block devices are open. ! 1027: * We require this to be done only on partition 0 since we're going to blow ! 1028: * away all of the other partitions. ! 1029: */ ! 1030: - (IOReturn)eject ! 1031: { ! 1032: IOReturn rtn; ! 1033: id phys = [self physicalDisk]; ! 1034: ! 1035: xpr_disk("IODiskPartition eject\n", 1,2,3,4,5); ! 1036: ! 1037: /* ! 1038: * We can't do this if any block devices, or any other logical disk, ! 1039: * are currently open. Also, we can only do this on partition 0 ! 1040: * because we're going to blow away all IODiskPartitions other than the ! 1041: * one for partition 0 before we're thru. ! 1042: */ ! 1043: rtn = [self checkSafeConfig:"eject"]; ! 1044: if(rtn) { ! 1045: return rtn; ! 1046: } ! 1047: ! 1048: /* ! 1049: * Kill all other partitions. Have IODisk clear our ! 1050: * "formatted" flag. ! 1051: */ ! 1052: [self _freePartitions]; ! 1053: _labelValid = 0; ! 1054: #ifdef GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 1055: _hfsValid = 0; ! 1056: #endif GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 1057: [super setFormattedInternal:0]; ! 1058: ! 1059: /* ! 1060: * Cancel possible outstanding "manual poll" request. This covers ! 1061: * the case in which the open() performed immediately preceeding ! 1062: * this eject command did an implied vol_check_set_poll() in the ! 1063: * driver's open() routine. ! 1064: */ ! 1065: if([phys needsManualPolling]) { ! 1066: vol_check_manual_poll(); ! 1067: } ! 1068: ! 1069: /* ! 1070: * Pass this down to physDisk using the internal versions to avoid ! 1071: * getting callbacks. ! 1072: */ ! 1073: return([phys ejectPhysical]); ! 1074: } ! 1075: ! 1076: - (IOReturn) requestRelease ! 1077: { ! 1078: IOReturn rtn; ! 1079: ! 1080: /* ! 1081: * We can't do this if any block devices, or any other logical disk, ! 1082: * are currently open. Also, we can only do this on partition 0 ! 1083: * because we're going to blow away all IODiskPartitions other than the ! 1084: * one for partition 0 before we're thru. ! 1085: */ ! 1086: ! 1087: rtn = [self checkSafeConfig:"disown"]; ! 1088: if(rtn) { ! 1089: return rtn; ! 1090: } ! 1091: ! 1092: /* ! 1093: * Kill all other partitions. Have IODisk clear our ! 1094: * "formatted" flag. ! 1095: */ ! 1096: [self _freePartitions]; ! 1097: _labelValid = 0; ! 1098: #ifdef GROK_APPLE ! 1099: _hfsValid = 0; ! 1100: #endif GROK_APPLE ! 1101: [super setFormattedInternal:0]; ! 1102: ! 1103: return(rtn); ! 1104: } ! 1105: ! 1106: /* ! 1107: * read/write methods. These are illegal if _labelValid is false, otherwise ! 1108: * they're just passed up to LogicalDisk. ! 1109: */ ! 1110: #ifdef KERNEL ! 1111: - (IOReturn) readAt : (unsigned)offset ! 1112: length : (unsigned)length ! 1113: buffer : (unsigned char *)buffer ! 1114: actualLength : (out unsigned *)actualLength ! 1115: client : (vm_task_t)client ! 1116: { ! 1117: xpr_disk("IODiskPartition read\n", 1,2,3,4,5); ! 1118: ! 1119: #if 0 // radar 1669467 - ISO 9660 CD support ! 1120: // Read is NOT illegal if _labelValid is false - ISO 9660 CDs do not have ! 1121: // standard disk label. In order to get read-only ISO 9660 CDROM support ! 1122: // working, we have disabled the check for a valid label on the read path ! 1123: // only. However, the ISO 9660 file system will not attempt to write to ! 1124: // the device and no other client should be able to open the device for ! 1125: // writing while the file system has it open, so the above scenario should ! 1126: // not occur. bknight. ! 1127: // ! 1128: #ifdef GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 1129: if( ! ( _labelValid || _hfsValid ) ) { ! 1130: #else GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 1131: if( ! _labelValid ) { ! 1132: #endif GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 1133: IOLog("%s: Read attempt with no valid label\n", ! 1134: [self name]); ! 1135: return(IO_R_INVALID_ARG); ! 1136: } ! 1137: #endif // radar 1669467 - ISO 9660 CD support ! 1138: ! 1139: return([super readAt : offset ! 1140: length : length ! 1141: buffer : buffer ! 1142: actualLength : actualLength ! 1143: client : client]); ! 1144: } ! 1145: ! 1146: - (IOReturn) readAsyncAt : (unsigned)offset ! 1147: length : (unsigned)length ! 1148: buffer : (unsigned char *)buffer ! 1149: pending : (void *)pending ! 1150: client : (vm_task_t)client ! 1151: { ! 1152: xpr_disk("IODiskPartition readAsync\n", 1,2,3,4,5); ! 1153: #if 0 // radar 1669467 - ISO 9660 CD support ! 1154: // Read is NOT illegal if _labelValid is false - ISO 9660 CDs do not have ! 1155: // standard disk label. In order to get read-only ISO 9660 CDROM support ! 1156: // working, we have disabled the check for a valid label on the read path ! 1157: // only. However, the ISO 9660 file system will not attempt to write to ! 1158: // the device and no other client should be able to open the device for ! 1159: // writing while the file system has it open, so the above scenario should ! 1160: // not occur. bknight. ! 1161: // ! 1162: #ifdef GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 1163: if( ! ( _labelValid || _hfsValid ) ) { ! 1164: #else GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 1165: if( ! _labelValid ) { ! 1166: #endif GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 1167: IOLog("%s: Read attempt with no valid label\n", ! 1168: [self name]); ! 1169: return(IO_R_INVALID_ARG); ! 1170: } ! 1171: #endif // radar 1669467 - ISO 9660 CD support ! 1172: ! 1173: return([super readAsyncAt : offset ! 1174: length : length ! 1175: buffer : buffer ! 1176: pending: pending ! 1177: client : client]); ! 1178: } ! 1179: ! 1180: - (IOReturn) writeAt : (unsigned)offset ! 1181: length : (unsigned)length ! 1182: buffer : (unsigned char *)buffer ! 1183: actualLength : (out unsigned *)actualLength ! 1184: client : (vm_task_t)client ! 1185: { ! 1186: xpr_disk("IODiskPartition writeAt\n", 1,2,3,4,5); ! 1187: #ifdef GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 1188: if( ! ( _labelValid || _hfsValid ) ) { ! 1189: #else GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 1190: if( ! _labelValid ) { ! 1191: #endif GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 1192: IOLog("%s: Write attempt with no valid label\n", ! 1193: [self name]); ! 1194: return(IO_R_INVALID_ARG); ! 1195: } ! 1196: return([super writeAt : offset ! 1197: length : length ! 1198: buffer : buffer ! 1199: actualLength : actualLength ! 1200: client : client]); ! 1201: } ! 1202: ! 1203: - (IOReturn) writeAsyncAt : (unsigned)offset ! 1204: length : (unsigned)length ! 1205: buffer : (unsigned char *)buffer ! 1206: pending : (void *)pending ! 1207: client : (vm_task_t)client ! 1208: { ! 1209: xpr_disk("IODiskPartition writeAsync\n", 1,2,3,4,5); ! 1210: #ifdef GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 1211: if( ! ( _labelValid || _hfsValid ) ) { ! 1212: #else GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 1213: if( ! _labelValid ) { ! 1214: #endif GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 1215: IOLog("%s: Write attempt with no valid label\n", ! 1216: [self name]); ! 1217: return(IO_R_INVALID_ARG); ! 1218: } ! 1219: return([super writeAsyncAt : offset ! 1220: length : length ! 1221: buffer : buffer ! 1222: pending: pending ! 1223: client : client]); ! 1224: } ! 1225: ! 1226: #else KERNEL ! 1227: ! 1228: - (IOReturn) readAt : (unsigned)offset ! 1229: length : (unsigned)length ! 1230: buffer : (unsigned char *)buffer ! 1231: actualLength : (out unsigned *)actualLength ! 1232: { ! 1233: xpr_disk("IODiskPartition read\n", 1,2,3,4,5); ! 1234: #ifdef GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 1235: if( ! ( _labelValid || _hfsValid ) ) { ! 1236: #else GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 1237: if( ! _labelValid ) { ! 1238: #endif GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 1239: IOLog("%s: Read attempt with no valid label\n", ! 1240: [self name]); ! 1241: return(IO_R_INVALID_ARG); ! 1242: } ! 1243: return([super readAt : offset ! 1244: length : length ! 1245: buffer : buffer ! 1246: actualLength : actualLength]); ! 1247: } ! 1248: ! 1249: - (IOReturn) readAsyncAt : (unsigned)offset ! 1250: length : (unsigned)length ! 1251: buffer : (unsigned char *)buffer ! 1252: pending : (void *)pending ! 1253: { ! 1254: xpr_disk("IODiskPartition readAsync\n", 1,2,3,4,5); ! 1255: #ifdef GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 1256: if( ! ( _labelValid || _hfsValid ) ) { ! 1257: #else GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 1258: if( ! _labelValid ) { ! 1259: #endif GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 1260: IOLog("%s: Read attempt with no valid label\n", ! 1261: [self name]); ! 1262: return(IO_R_INVALID_ARG); ! 1263: } ! 1264: return([super readAsyncAt : offset ! 1265: length : length ! 1266: buffer : buffer ! 1267: pending: pending]); ! 1268: } ! 1269: ! 1270: - (IOReturn) writeAt : (unsigned)offset ! 1271: length : (unsigned)length ! 1272: buffer : (unsigned char *)buffer ! 1273: actualLength : (unsigned *)actualLength ! 1274: { ! 1275: xpr_disk("IODiskPartition writeAt\n", 1,2,3,4,5); ! 1276: #ifdef GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 1277: if( ! ( _labelValid || _hfsValid ) ) { ! 1278: #else GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 1279: if( ! _labelValid ) { ! 1280: #endif GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 1281: IOLog("%s: Write attempt with no valid label\n", ! 1282: [self name]); ! 1283: return(IO_R_INVALID_ARG); ! 1284: } ! 1285: return([super writeAt : offset ! 1286: length : length ! 1287: buffer : buffer ! 1288: actualLength : actualLength]); ! 1289: } ! 1290: ! 1291: - (IOReturn) writeAsyncAt : (unsigned)offset ! 1292: length : (unsigned)length ! 1293: buffer : (unsigned char *)buffer ! 1294: pending : (void *)pending ! 1295: { ! 1296: xpr_disk("IODiskPartition writeAsync\n", 1,2,3,4,5); ! 1297: #ifdef GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 1298: if( ! ( _labelValid || _hfsValid ) ) { ! 1299: #else GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 1300: if( ! _labelValid ) { ! 1301: #endif GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 1302: IOLog("%s: Write attempt with no valid label\n", ! 1303: [self name]); ! 1304: return(IO_R_INVALID_ARG); ! 1305: } ! 1306: return([super writeAsyncAt : offset ! 1307: length : length ! 1308: buffer : buffer ! 1309: pending: pending]); ! 1310: } ! 1311: #endif KERNEL ! 1312: ! 1313: /* ! 1314: * Public setFormatted, overrides the same method in IODisk. ! 1315: * This is the normal way a setFormatted operation is done in a ! 1316: * Unix environment. ! 1317: */ ! 1318: - (IOReturn)setFormatted : (BOOL)formattedFlag ! 1319: { ! 1320: id physDisk; ! 1321: IOReturn rtn; ! 1322: ! 1323: /* ! 1324: * We can't do this if any block devices, or any other logical disk, ! 1325: * are currently open. Also, we can only do this on partition 0 ! 1326: * because we're going to blow away all IODiskPartitions other than the ! 1327: * one for partition 0 before we're thru. ! 1328: */ ! 1329: rtn = [self checkSafeConfig:"setFormatted"]; ! 1330: if(rtn) { ! 1331: return rtn; ! 1332: } ! 1333: ! 1334: /* ! 1335: * Pass this down to physDisk using the internal versions to avoid ! 1336: * getting callbacks. ! 1337: */ ! 1338: physDisk = [self physicalDisk]; ! 1339: [physDisk setFormattedInternal:formattedFlag]; ! 1340: if(formattedFlag) { ! 1341: /* ! 1342: * Going to a newly formatted state; have physical ! 1343: * device update block size and so forth. ! 1344: */ ! 1345: [physDisk updatePhysicalParameters]; ! 1346: } ! 1347: ! 1348: /* ! 1349: * Strange, but we'll set the internal formatted flag again in case ! 1350: * physical device driver disagrees with what our caller is saying. ! 1351: * The caller wins in this case. ! 1352: */ ! 1353: [physDisk setFormattedInternal:formattedFlag]; ! 1354: [self setFormattedInternal:formattedFlag]; ! 1355: return IO_R_SUCCESS; ! 1356: } ! 1357: ! 1358: /* ! 1359: * internal setFormatted - avoids logical disk interaction. Called by ! 1360: * the exported setFormatted method both here (for normal Unix use) and ! 1361: * from physicalDisk. ! 1362: */ ! 1363: - (void)setFormattedInternal:(BOOL)formattedFlag ! 1364: { ! 1365: xpr_disk("%s: setFormattedInternal %d\n", [self name], ! 1366: formattedFlag, 3,4,5); ! 1367: [self _freePartitions]; ! 1368: _labelValid = 0; ! 1369: ! 1370: /* ! 1371: * Finally, the low-impact "just set the flag" method in ! 1372: * IODisk... ! 1373: */ ! 1374: [super setFormattedInternal:formattedFlag]; ! 1375: } ! 1376: ! 1377: ! 1378: /* ! 1379: * Get/set "device open" flags. ! 1380: */ ! 1381: - (BOOL)isBlockDeviceOpen ! 1382: { ! 1383: return _blockDeviceOpen; ! 1384: } ! 1385: ! 1386: - (void)setBlockDeviceOpen : (BOOL)openFlag ! 1387: { ! 1388: _blockDeviceOpen = openFlag ? YES : NO; ! 1389: [self setInstanceOpen: (_blockDeviceOpen || _rawDeviceOpen)]; ! 1390: } ! 1391: ! 1392: - (BOOL)isRawDeviceOpen ! 1393: { ! 1394: return _rawDeviceOpen; ! 1395: } ! 1396: ! 1397: - (void)setRawDeviceOpen : (BOOL)openFlag ! 1398: { ! 1399: _rawDeviceOpen = openFlag ? YES : NO; ! 1400: [self setInstanceOpen: (_blockDeviceOpen || _rawDeviceOpen)]; ! 1401: } ! 1402: ! 1403: - waitForProbe:(int) seconds ! 1404: { ! 1405: int attempts; ! 1406: BOOL ready; ! 1407: ns_time_t now; ! 1408: ! 1409: if( nil == _partitionWaitLock) ! 1410: return( nil); ! 1411: ! 1412: [_partitionWaitLock lock]; ! 1413: ready = [_partitionWaitLock condition]; ! 1414: [_partitionWaitLock unlock]; ! 1415: ! 1416: if( NO == ready) do { ! 1417: IOGetTimestamp( &now); ! 1418: attempts = seconds - (int)((now - _probeTime) / 1000 / 1000 / 1000); ! 1419: if( attempts <= 0) ! 1420: continue; ! 1421: ! 1422: IOLog( "%s: Waiting for drive to come ready", [self name]); ! 1423: for( ; (NO == ready) && attempts; attempts--) { ! 1424: IOLog( "."); ! 1425: IOSleep( 1000); ! 1426: [_partitionWaitLock lock]; ! 1427: ready = [_partitionWaitLock condition]; ! 1428: [_partitionWaitLock unlock]; ! 1429: } ! 1430: IOLog( "\n"); ! 1431: if( NO == ready) ! 1432: IOLog( "%s: Disk Not Ready\n", [self name]); ! 1433: ! 1434: } while( NO); ! 1435: ! 1436: return( ready ? self : nil); ! 1437: } ! 1438: ! 1439: @end ! 1440: ! 1441: @implementation IODiskPartition(Private) ! 1442: ! 1443: ! 1444: /* ! 1445: * Examine a known good label, initialize LogicalDisk parameters for the ! 1446: * partition '0' instance (on which this method is invoked) and create ! 1447: * additional partition instances as appropriate. ! 1448: * ! 1449: * Invoked by LogicalDisk +probe, upon disk insertion, and when a new label ! 1450: * is written. ! 1451: */ ! 1452: - (void) _probeLabel : (disk_label_t *)labelp ! 1453: { ! 1454: IODiskPartition *partInst; ! 1455: int part; ! 1456: struct partition *partition_p; ! 1457: id physDisk = [self physicalDisk]; ! 1458: id lastIODiskPartition = self; ! 1459: ! 1460: xpr_disk("IODiskPartition _probeLabel\n", 1,2,3,4,5); ! 1461: ! 1462: if(_partition != 0) { ! 1463: IOLog("%s: _probeLabel on partition != 0\n", ! 1464: [self name]); ! 1465: return; ! 1466: } ! 1467: ! 1468: /* ! 1469: * Update internal state for partition 0. ! 1470: */ ! 1471: [self _initPartition:0 ! 1472: physicalPartition:_physicalPartition ! 1473: disktab:&labelp->dl_dt]; ! 1474: ! 1475: /* ! 1476: * Create & init an additional IODiskPartition instance per valid ! 1477: * partition. Partition NPART-1 is never used by convention (it's ! 1478: * the live partition). ! 1479: */ ! 1480: for(part=1; part<NPART-1; part++) { ! 1481: partition_p = &labelp->dl_dt.d_partitions[part]; ! 1482: if(partition_p->p_size > 0) { ! 1483: ! 1484: /* ! 1485: * A valid logical disk partition. ! 1486: */ ! 1487: partInst = [IODiskPartition new]; ! 1488: [partInst connectToPhysicalDisk:physDisk]; ! 1489: [partInst _initPartition : part ! 1490: physicalPartition: _physicalPartition ! 1491: disktab : &labelp->dl_dt]; ! 1492: [partInst init]; ! 1493: [partInst registerDevice]; ! 1494: ! 1495: /* ! 1496: * Link to logical disk chain, and notify ! 1497: * physDisk as well. ! 1498: */ ! 1499: [lastIODiskPartition setLogicalDisk:partInst]; ! 1500: [[self physicalDisk] setLogicalDisk:partInst]; ! 1501: lastIODiskPartition = partInst; ! 1502: } ! 1503: } ! 1504: return; ! 1505: } ! 1506: ! 1507: /* ! 1508: * Assign logical disk parameters for an IODiskPartition instance based on ! 1509: * specified partition number on disktab. Caller must have already ! 1510: * done a connectToPhysicalDisk on this instance, and specified partition ! 1511: * is known to be valid. ! 1512: */ ! 1513: - (void)_initPartition : (int)partNum ! 1514: physicalPartition : (int)physNum ! 1515: disktab : (struct disktab *)dtp; ! 1516: { ! 1517: struct partition *pp = &dtp->d_partitions[partNum]; ! 1518: int partBase; ! 1519: char name[30]; ! 1520: id physDisk = [self physicalDisk]; ! 1521: ! 1522: /* ! 1523: * Set IODevice-class instance variables. ! 1524: */ ! 1525: sprintf(name, "%s%c", [physDisk name], 'a' + partNum); ! 1526: [self setName:name]; ! 1527: [self setDriveName:"IODiskPartition Partition"]; ! 1528: [self setLocation:NULL]; ! 1529: xpr_disk("%s: _initPartition\n", IOCopyString(name), 2,3,4,5); ! 1530: [self setDiskSize:pp->p_size]; ! 1531: [self setBlockSize:dtp->d_secsize]; ! 1532: [self setUnit:[physDisk unit]]; // probably unnecessary ! 1533: ! 1534: // Ensure partition 0 always has the correct value ! 1535: // for this instance variable, since connectToPhysicalDisk ! 1536: // is only called once for that partition. ! 1537: [self setWriteProtected:[physDisk isWriteProtected]]; ! 1538: ! 1539: /* ! 1540: * LogicalDisk instance variables are taken care of in ! 1541: * connectToPhysicalDisk. ! 1542: * Set up local instance variables. ! 1543: * ! 1544: * Careful, partitionBase is not necessarily in physical blocksize; ! 1545: * for old disks, it's in d_secsize (usually DEV_BSIZE) from ! 1546: * disktab... ! 1547: */ ! 1548: partBase = pp->p_base + dtp->d_front; ! 1549: partBase *= dtp->d_secsize / [self physicalBlockSize]; ! 1550: [self setPartitionBase:partBase]; ! 1551: _partition = partNum; ! 1552: _physicalPartition = physNum; ! 1553: ! 1554: /* ! 1555: * The low-impact "just set the flag" method in IODisk...Our ! 1556: * override of this method frees partitions. ! 1557: */ ! 1558: [super setFormattedInternal:1]; ! 1559: _labelValid = 1; ! 1560: #ifdef GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 1561: _hfsValid = 0; // bek - 12/14/97 - Is this redundant? ! 1562: #endif GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 1563: ! 1564: #ifdef KERNEL ! 1565: /* ! 1566: * Let Unix layer know about us. ! 1567: */ ! 1568: [self registerUnixDisk : partNum]; ! 1569: #endif KERNEL ! 1570: return; ! 1571: } ! 1572: ! 1573: /* ! 1574: * Free all partition instances other than partition 0. The others must ! 1575: * not be open, and this must be invoked on partition 0. ! 1576: */ ! 1577: - (IOReturn)_freePartitions; ! 1578: { ! 1579: id nextPart = [self nextLogicalDisk]; ! 1580: ! 1581: if(_partition != 0) { ! 1582: IOLog("%s: _freePartitions on partition != 0\n", ! 1583: [self name]); ! 1584: return IO_R_BUSY; ! 1585: } ! 1586: if(nextPart == nil) ! 1587: return IO_R_SUCCESS; ! 1588: if([nextPart isOpen]) { ! 1589: /* ! 1590: * this shouldn't happen - this was already checked ! 1591: * in checkSafeConfig. ! 1592: */ ! 1593: IOLog("%s: _freePartitions with open partitions\n", ! 1594: [self name]); ! 1595: return IO_R_BUSY; ! 1596: } ! 1597: [nextPart free]; ! 1598: [self setLogicalDisk:nil]; ! 1599: return IO_R_SUCCESS; ! 1600: } ! 1601: ! 1602: /* ! 1603: * Determine if any block devices in the logicalDisk chain are open. ! 1604: */ ! 1605: - (BOOL)isAnyBlockDevOpen ! 1606: { ! 1607: id logDisk = [[self physicalDisk] nextLogicalDisk]; ! 1608: ! 1609: while(logDisk) { ! 1610: if([logDisk isBlockDeviceOpen]) { ! 1611: return YES; ! 1612: } ! 1613: logDisk = [logDisk nextLogicalDisk]; ! 1614: } ! 1615: return NO; ! 1616: } ! 1617: ! 1618: ! 1619: /* ! 1620: * Verify that it's safe to do an operation which will result in a call ! 1621: * to _freePartitions. ! 1622: */ ! 1623: - (IOReturn)checkSafeConfig : (const char *)op ! 1624: { ! 1625: if(_partition != 0) { ! 1626: return IO_R_BUSY; ! 1627: } ! 1628: if([self isAnyBlockDevOpen]) { ! 1629: return IO_R_BUSY; ! 1630: } ! 1631: if([self isAnyOtherOpen]) { ! 1632: return IO_R_BUSY; ! 1633: } ! 1634: return IO_R_SUCCESS; ! 1635: } ! 1636: ! 1637: ! 1638: #ifdef GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 1639: ! 1640: /* ! 1641: * Check for an apple partition: ! 1642: * ! 1643: */ ! 1644: #define BLOCKSIZE_512_BYTES 512 ! 1645: ! 1646: + (void)CreateHFSDevicesFromApplePartitionMap: (id) devDesc ! 1647: { ! 1648: id physicalDisk = [devDesc directDevice]; ! 1649: unsigned char * blk; ! 1650: Block0 * blk0; ! 1651: unsigned long blocksize; ! 1652: unsigned bytesXfr; ! 1653: IOReturn rtn; ! 1654: ! 1655: unsigned int block = 1; ! 1656: unsigned int entry_within_block = 0; ! 1657: int n; ! 1658: unsigned int nentries_per_block = 1; ! 1659: unsigned int numPartBlocks; ! 1660: DPME * partEntry; ! 1661: int physNum; ! 1662: ! 1663: IODiskPartition * partitionInstance; ! 1664: IODiskPartition * lastIODiskPartition = nil; // mandatory initialization ! 1665: unsigned part = 0; ! 1666: ! 1667: blocksize = 512; ! 1668: ! 1669: blk = IOMalloc(PAGE_SIZE); /* force page alignment */ ! 1670: blk0 = (Block0 *)blk; ! 1671: ! 1672: /* check block 0 for valid Apple partition signature */ ! 1673: ! 1674: rtn = [[super class] commonReadWrite ! 1675: : physicalDisk ! 1676: : YES /* read */ ! 1677: : (unsigned long long)0 /* byte offset */ ! 1678: : PAGE_SIZE /* bytes */ ! 1679: : blk ! 1680: : IOVmTaskSelf() ! 1681: : (void *)NULL ! 1682: : &bytesXfr]; ! 1683: ! 1684: if (rtn) ! 1685: { ! 1686: goto Return; ! 1687: } ! 1688: ! 1689: /* scan for apple hfs partitions */ ! 1690: ! 1691: /* check if there is a valid map at 512 offset */ ! 1692: ! 1693: partEntry = (DPME *)(blk + BLOCKSIZE_512_BYTES); ! 1694: ! 1695: if (blocksize > BLOCKSIZE_512_BYTES) ! 1696: { ! 1697: if (NXSwapBigShortToHost(partEntry->dpme_signature) == DPME_SIGNATURE) ! 1698: { ! 1699: /* there is a valid map, and the device blocksize ! 1700: * is > 512, which means we probably have a CDROM ! 1701: * using 2K, but having valid 512 map ! 1702: */ ! 1703: block = 0; ! 1704: nentries_per_block = blocksize / BLOCKSIZE_512_BYTES; ! 1705: entry_within_block = 1; ! 1706: } ! 1707: else ! 1708: { ! 1709: partEntry = (DPME *)(blk + blocksize); ! 1710: } ! 1711: } ! 1712: ! 1713: if (NXSwapBigShortToHost(partEntry->dpme_signature) != DPME_SIGNATURE) ! 1714: { ! 1715: #if 1 // bknight - 7/2/98 - Radar #2240631 ! 1716: /* Make a single giant "_hfs_a" partition to support floppies, DOS disks, ISO9660 CDs. */ ! 1717: ! 1718: partitionInstance = [IODiskPartition new]; ! 1719: [partitionInstance connectToPhysicalDisk: physicalDisk]; ! 1720: [partitionInstance setDeviceDescription: devDesc]; ! 1721: [partitionInstance _initHFSPartition: 0 ! 1722: physicalPartNum: 0 // bknight - intentionally illegal phys part num ! 1723: diskSize: ( [physicalDisk diskSize] * ([physicalDisk blockSize] / BLOCKSIZE_512_BYTES) ) ! 1724: partitionBase: 0]; ! 1725: [partitionInstance init]; //bknight - [super init] all the way up to Object ! 1726: [partitionInstance registerDevice]; //bknight - doesn't do anything since (!_isPhysical) ! 1727: ! 1728: /* No need to link onto the end of nonexistent chain of logical partitions. ! 1729: Just notify the physical disk. */ ! 1730: ! 1731: [physicalDisk setLogicalDisk: partitionInstance]; //bknight - doesn't override if already set ! 1732: #endif // bknight - 7/2/98 - Radar #2240631 ! 1733: goto Return; ! 1734: } ! 1735: ! 1736: numPartBlocks = NXSwapBigLongToHost(partEntry->dpme_map_entries); ! 1737: physNum = 1; ! 1738: for (n = 0; n < numPartBlocks; n++) ! 1739: { ! 1740: if (NXSwapBigShortToHost(partEntry->dpme_signature) != DPME_SIGNATURE) ! 1741: { ! 1742: break; ! 1743: } ! 1744: ! 1745: if ( strcmp(partEntry->dpme_type, HFS_PART_TYPE) == 0 ) ! 1746: { ! 1747: /* ! 1748: * Mount HFS volume only if this isn't "MOSX_OF3_Booter" partition. ! 1749: */ ! 1750: if ( strcmp(partEntry->dpme_name, "MOSX_OF3_Booter") != 0 ) ! 1751: { ! 1752: unsigned long part_offset; ! 1753: ! 1754: part_offset = NXSwapBigLongToHost(partEntry->dpme_pblock_start); ! 1755: if ((part_offset / nentries_per_block * nentries_per_block) != part_offset) ! 1756: { ! 1757: IOLog("IODiskPartition: " HFS_PART_TYPE ! 1758: " partition base (%ld x 512) is not" ! 1759: " a multiple of the devblksize %ld\n", ! 1760: part_offset, blocksize); ! 1761: break; ! 1762: } ! 1763: ! 1764: part_offset = part_offset / nentries_per_block; ! 1765: ! 1766: /* A valid logical disk partition. */ ! 1767: ! 1768: partitionInstance = [IODiskPartition new]; ! 1769: [partitionInstance connectToPhysicalDisk: physicalDisk]; ! 1770: [partitionInstance setDeviceDescription:devDesc]; ! 1771: [partitionInstance ! 1772: _initHFSPartition: part ! 1773: physicalPartNum: physNum ! 1774: diskSize: partEntry->dpme_pblocks ! 1775: partitionBase: partEntry->dpme_pblock_start]; ! 1776: [partitionInstance init]; //bknight - [super init] all the way up to Object ! 1777: [partitionInstance registerDevice]; //bknight - doesn't do anything since (!_isPhysical) ! 1778: ! 1779: /* Link to logical disk chain, and notify the physicalDisk. */ ! 1780: ! 1781: if ( lastIODiskPartition != nil ) ! 1782: { ! 1783: [lastIODiskPartition setLogicalDisk: partitionInstance]; ! 1784: } ! 1785: lastIODiskPartition = partitionInstance; ! 1786: [physicalDisk setLogicalDisk: partitionInstance]; //bknight - doesn't override if already set ! 1787: ! 1788: /* Increment our partition counter. */ ! 1789: ! 1790: part++; ! 1791: } // if not "MOSX_OF3_Booter" partition flag set ! 1792: } // if HFS_PART_TYPE ! 1793: ! 1794: physNum++; ! 1795: partEntry++; ! 1796: if (++entry_within_block == nentries_per_block) ! 1797: { ! 1798: block++; ! 1799: entry_within_block = 0; ! 1800: partEntry = (DPME *)blk; ! 1801: rtn = [[super class] commonReadWrite ! 1802: : physicalDisk ! 1803: : YES /* read */ ! 1804: : (unsigned long long)block * blocksize /* byte offset */ ! 1805: : blocksize /* bytes */ ! 1806: : blk ! 1807: : IOVmTaskSelf() ! 1808: : (void *)NULL ! 1809: : &bytesXfr]; ! 1810: if (rtn) ! 1811: { ! 1812: break; ! 1813: } ! 1814: ! 1815: } // if ! 1816: ! 1817: } // for ! 1818: ! 1819: Return: ! 1820: ! 1821: IOFree(blk, PAGE_SIZE); ! 1822: return; ! 1823: ! 1824: } // CreateHFSDevicesFromApplePartitionMap ! 1825: ! 1826: #endif GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 1827: ! 1828: #if GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 1829: ! 1830: /* ! 1831: * Assign logical disk parameters for an IODiskPartition instance based on ! 1832: * specified partition number on disktab. Caller must have already ! 1833: * done a connectToPhysicalDisk on this instance, and specified partition ! 1834: * is known to be valid. ! 1835: */ ! 1836: - (void) _initHFSPartition : (int) partitionNum ! 1837: physicalPartNum : (int) physNum ! 1838: diskSize : (int) diskSize ! 1839: partitionBase : (int) partitionBase; ! 1840: { ! 1841: int hfsPartitionNum = partitionNum + NPART; ! 1842: char name[30]; //bknight - hardcoded ! 1843: id physicalDisk = [self physicalDisk]; ! 1844: ! 1845: /* IODevice initialization */ ! 1846: ! 1847: sprintf(name, "%s_hfs_%c", [physicalDisk name], 'a' + partitionNum); ! 1848: [self setUnit: [physicalDisk unit]]; // IODevice //bknight - probably unnecessary ??? ! 1849: [self setName: name]; ! 1850: [self setLocation: NULL]; ! 1851: ! 1852: /* IODisk initialization */ ! 1853: ! 1854: [self setDriveName: "IODiskPartition Partition"]; ! 1855: ! 1856: // always measured in 512-byte blocks, regardless of the device block size ! 1857: ! 1858: [self setDiskSize: diskSize]; //bknight - in 512-byte blocks ! 1859: ! 1860: // hardcoded per Radar #2211264 ! 1861: ! 1862: [self setBlockSize: 512]; ! 1863: ! 1864: /* bknight - WHAT DOES THIS COMMENT / LINE MEAN ??? */ ! 1865: ! 1866: // Ensure partition 0 always has the correct value ! 1867: // for this instance variable, since connectToPhysicalDisk ! 1868: // is only called once for that partition. ! 1869: [self setWriteProtected:[physicalDisk isWriteProtected]]; ! 1870: ! 1871: /* ! 1872: * IOLogicalDisk instance variables are taken care of in connectToPhysicalDisk. ! 1873: * Set up IODiskPartition instance variables. ! 1874: * ! 1875: */ ! 1876: [self setPartitionBase: partitionBase]; ! 1877: _partition = hfsPartitionNum; ! 1878: _physicalPartition = physNum; ! 1879: ! 1880: /* ! 1881: * The low-impact "just set the flag" method in IODisk...Our ! 1882: * override of this method frees partitions. ! 1883: */ ! 1884: [super setFormattedInternal:1]; ! 1885: _hfsValid = 1; ! 1886: _labelValid = 0; ! 1887: ! 1888: #ifdef KERNEL ! 1889: /* ! 1890: * Let Unix layer know about us. ! 1891: */ ! 1892: [self registerUnixDisk: hfsPartitionNum]; ! 1893: #endif KERNEL ! 1894: ! 1895: Return: ! 1896: ! 1897: return; ! 1898: ! 1899: } // _initHFSPartition ! 1900: ! 1901: #endif GROK_APPLE //bknight - 12/3/97 - Radar #2004660 ! 1902: ! 1903: - property_IODeviceType:(char *)types length:(unsigned int *)maxLen ! 1904: { ! 1905: #if GROK_APPLE ! 1906: if( _hfsValid) ! 1907: strcat( types, " "IOTypeHFS); ! 1908: else ! 1909: #endif GROK_APPLE ! 1910: strcat( types, " "IOTypeUFS); ! 1911: return( self); ! 1912: } ! 1913: ! 1914: - property_IODeviceClass:(char *)classes length:(unsigned int *)maxLen ! 1915: { ! 1916: [super property_IODeviceClass:classes length:maxLen]; ! 1917: strcat( classes, " "IOClassDiskPartition); ! 1918: return( self); ! 1919: } ! 1920: ! 1921: - property_IOPartitionNumber:(char *)result length:(unsigned int *)maxLen ! 1922: { ! 1923: sprintf( result, "0x%x", _physicalPartition); ! 1924: return( self); ! 1925: } ! 1926: ! 1927: - registerLoudly ! 1928: { ! 1929: return( nil); ! 1930: } ! 1931: ! 1932: @end ! 1933: ! 1934: #ifndef KERNEL ! 1935: /* ! 1936: * Ripped off from kernel's next/checksum16.c ! 1937: */ ! 1938: #define ADDCARRY(x) (x > 65535 ? x -= 65535 : x) ! 1939: #define REDUCE { \ ! 1940: l_util.l = sum; \ ! 1941: sum = l_util.s[0] + l_util.s[1]; \ ! 1942: ADDCARRY(sum); \ ! 1943: } ! 1944: ! 1945: u_short checksum_16(u_short *wp, int num_shorts) ! 1946: { ! 1947: int sum = 0; ! 1948: union { ! 1949: u_short s[2]; ! 1950: long l; ! 1951: } l_util; ! 1952: ! 1953: while (num_shorts--) ! 1954: sum += *wp++; ! 1955: REDUCE; ! 1956: return (sum); ! 1957: } ! 1958: #endif KERNEL
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.