|
|
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: * ATADisk.m - Exported methods for IDE/ATA Disk device class. ! 30: * ! 31: * HISTORY ! 32: * 07-Jul-1994 Rakesh Dubey at NeXT ! 33: * Created from original driver written by David Somayajulu. ! 34: */ ! 35: ! 36: #import <driverkit/return.h> ! 37: #import <driverkit/driverTypes.h> ! 38: #import <driverkit/devsw.h> ! 39: #import <driverkit/generalFuncs.h> ! 40: #import <driverkit/kernelDiskMethods.h> ! 41: #import <driverkit/IODevice.h> ! 42: #import <machkit/NXLock.h> ! 43: #import <sys/systm.h> ! 44: ! 45: #import "ATADisk.h" ! 46: #import "ATADiskInternal.h" ! 47: #import "ATADiskKernel.h" ! 48: ! 49: //#define DEBUG ! 50: ! 51: static int diskUnit = 0; ! 52: static BOOL switchTableInited = NO; ! 53: ! 54: /* ! 55: * List of controllers that have been already probed. We need this since each ! 56: * Instance table lists ATADisk as well as IdeController classes. And we need ! 57: * to create instances of disks attached to each controller only once. ! 58: */ ! 59: static int probedControllerCount = 0; ! 60: static id probedControllers[MAX_IDE_CONTROLLERS]; ! 61: ! 62: @implementation ATADisk ! 63: ! 64: static Protocol *protocols[] = { ! 65: @protocol(IdeControllerPublic), ! 66: nil ! 67: }; ! 68: ! 69: + (Protocol **)requiredProtocols ! 70: { ! 71: return protocols; ! 72: } ! 73: ! 74: + (IODeviceStyle)deviceStyle ! 75: { ! 76: return IO_IndirectDevice; ! 77: } ! 78: ! 79: /* ! 80: * IDE drives come with a built in controller on each drive. Hence we can ! 81: * have just one object per controller-disk pair. Probe is invoked at load ! 82: * time. It determines what drives are on the bus and alloc's and init:'s an ! 83: * instance of this class for each one. ! 84: * ! 85: */ ! 86: ! 87: + (BOOL)probe : deviceDescription ! 88: { ! 89: id diskId; ! 90: IODevAndIdInfo *idMap = ide_idmap(); ! 91: int unit, i; ! 92: id controllerId = [deviceDescription directDevice]; ! 93: ! 94: #ifdef DEBUG ! 95: IOLog("ATADisk probed with controller id %x\n", controllerId); ! 96: #endif DEBUG ! 97: ! 98: for (i = 0; i < probedControllerCount; i++) { ! 99: if (probedControllers[i] == controllerId) { ! 100: IOLog("ATADisk already probed for controller %x\n", controllerId); ! 101: return YES; ! 102: } ! 103: } ! 104: probedControllers[probedControllerCount++] = controllerId; ! 105: ! 106: for (unit = 0; unit < MAX_IDE_DRIVES; unit++) { ! 107: ! 108: diskId = [[ATADisk alloc] initFromDeviceDescription:deviceDescription]; ! 109: [diskId initResources:controllerId]; ! 110: [diskId setDevAndIdInfo:&(idMap[diskUnit])]; ! 111: ! 112: if ([diskId ideDiskInit:diskUnit target:unit] == NO) { ! 113: [diskId free]; ! 114: continue; ! 115: } ! 116: ! 117: if (([self hd_devsw_init:deviceDescription]) == NO) { ! 118: [diskId free]; ! 119: IOLog("ATADisk: failed to add to devsw tables.\n"); ! 120: return NO; ! 121: } ! 122: ! 123: /* ! 124: * Success; we initialized a drive. Have DiskObject superclass take ! 125: * care of the rest. ! 126: */ ! 127: [diskId setDeviceKind:"ATADisk"]; ! 128: [diskId setIsPhysical:YES]; ! 129: [diskId registerDevice]; ! 130: diskUnit += 1; ! 131: } ! 132: ! 133: return YES; ! 134: } ! 135: ! 136: ! 137: - getDevicePath:(char *)path maxLength:(int)maxLen useAlias:(BOOL)doAlias ! 138: { ! 139: if( [super getDevicePath:path maxLength:maxLen useAlias:doAlias]) { ! 140: ! 141: char unitStr[ 12 ]; ! 142: int len = maxLen - strlen( path); ! 143: ! 144: sprintf( unitStr, "/@%x", [self driveNum]); ! 145: len -= strlen( unitStr); ! 146: if( len < 0) ! 147: return( nil); ! 148: strcat( path, unitStr); ! 149: return( self); ! 150: } ! 151: return( nil); ! 152: } ! 153: ! 154: - (char *) matchDevicePath:(char *)matchPath ! 155: { ! 156: BOOL matches = NO; ! 157: char * unitStr; ! 158: extern long int strtol(const char *nptr, char **endptr, int base); ! 159: ! 160: unitStr = [super matchDevicePath:matchPath]; ! 161: if( unitStr) { ! 162: unitStr = strchr( unitStr, '@'); ! 163: if( unitStr) { ! 164: matches = ([self driveNum] == strtol( unitStr + 1, &unitStr, 16)); ! 165: } ! 166: } ! 167: if( matches) ! 168: return( unitStr); ! 169: else ! 170: return( NULL); ! 171: } ! 172: ! 173: - property_IOUnit:(char *)result length:(unsigned int *)maxLen ! 174: { ! 175: sprintf( result, "%d", [self driveNum]); ! 176: } ! 177: ! 178: ! 179: /* ! 180: * Add our entry to the device switch tables. ! 181: */ ! 182: + (BOOL)hd_devsw_init:deviceDescription ! 183: { ! 184: extern int seltrue(); ! 185: ! 186: /* ! 187: * We get called once for each IDE controller in the system; we ! 188: * only have to call IOAddToCdevsw() once. ! 189: */ ! 190: if (switchTableInited == YES) { ! 191: return YES; ! 192: } ! 193: ! 194: #if 0 ! 195: if ([self addToCdevswFromDescription: deviceDescription ! 196: open: (IOSwitchFunc) ideopen ! 197: close: (IOSwitchFunc) ideclose ! 198: read: (IOSwitchFunc) ideread ! 199: write: (IOSwitchFunc) idewrite ! 200: ioctl: (IOSwitchFunc) ideioctl ! 201: stop: (IOSwitchFunc) eno_stop ! 202: reset: (IOSwitchFunc) nulldev ! 203: select: (IOSwitchFunc) seltrue ! 204: mmap: (IOSwitchFunc) eno_mmap ! 205: getc: (IOSwitchFunc) eno_getc ! 206: putc: (IOSwitchFunc) eno_putc] != YES) ! 207: { ! 208: return NO; ! 209: } ! 210: ! 211: if ([self addToBdevswFromDescription: deviceDescription ! 212: open: (IOSwitchFunc) ideopen ! 213: close: (IOSwitchFunc) ideclose ! 214: strategy: (IOSwitchFunc) idestrategy ! 215: ioctl: (IOSwitchFunc) ideioctl ! 216: dump: (IOSwitchFunc) eno_dump ! 217: psize: (IOSwitchFunc) idesize ! 218: isTape: FALSE] != YES) ! 219: { ! 220: return NO; ! 221: } ! 222: #endif ! 223: ! 224: if ( IOAddToCdevswAt( 15, ! 225: (IOSwitchFunc) ideopen, ! 226: (IOSwitchFunc) ideclose, ! 227: (IOSwitchFunc) ideread, ! 228: (IOSwitchFunc) idewrite, ! 229: (IOSwitchFunc) ideioctl, ! 230: (IOSwitchFunc) eno_stop, ! 231: (IOSwitchFunc) nulldev, ! 232: (IOSwitchFunc) seltrue, ! 233: (IOSwitchFunc) eno_mmap, ! 234: (IOSwitchFunc) eno_getc, ! 235: (IOSwitchFunc) eno_putc) < 0 ) ! 236: { ! 237: return NO; ! 238: } ! 239: [self setCharacterMajor: 15]; ! 240: ! 241: if ( IOAddToBdevswAt( 3, ! 242: (IOSwitchFunc) ideopen, ! 243: (IOSwitchFunc) ideclose, ! 244: (IOSwitchFunc) idestrategy, ! 245: (IOSwitchFunc) ideioctl, ! 246: (IOSwitchFunc) eno_dump, ! 247: (IOSwitchFunc) idesize, ! 248: FALSE ) < 0 ) ! 249: { ! 250: return NO; ! 251: } ! 252: [self setBlockMajor: 3]; ! 253: ! 254: ide_init_idmap(self); ! 255: ! 256: switchTableInited = YES; ! 257: ! 258: //#ifdef undef ! 259: IOLog("IDE: block major %d, character major %d\n", ! 260: [self blockMajor], [self characterMajor]); ! 261: //#endif undef ! 262: ! 263: return YES; ! 264: } ! 265: ! 266: ! 267: /* ! 268: * Common read/write methods. These are used directly in the kernel; user-level ! 269: * methods using remote objects as defined in IODevice.h in turn call these. ! 270: */ ! 271: - (IOReturn) readAt : (unsigned)offset ! 272: length : (unsigned)length ! 273: buffer : (unsigned char *)buffer ! 274: actualLength : (unsigned *)actualLength ! 275: client : (vm_task_t)client ! 276: { ! 277: IOReturn rtn; ! 278: ! 279: rtn = [self deviceRwCommon : IDEC_READ ! 280: block : offset ! 281: length : length ! 282: buffer : buffer ! 283: client: client ! 284: pending : NULL ! 285: actualLength : actualLength]; ! 286: return(rtn); ! 287: } ! 288: ! 289: - (IOReturn) readAsyncAt : (unsigned)offset ! 290: length : (unsigned)length ! 291: buffer : (unsigned char *)buffer ! 292: pending : (void *)pending ! 293: client : (vm_task_t)client ! 294: { ! 295: IOReturn rtn; ! 296: ! 297: rtn = [self deviceRwCommon : IDEC_READ ! 298: block : offset ! 299: length : length ! 300: buffer : buffer ! 301: client : client ! 302: pending : (void *)pending ! 303: actualLength : NULL]; ! 304: return(rtn); ! 305: } ! 306: ! 307: - (IOReturn) writeAt : (unsigned)offset ! 308: length : (unsigned)length ! 309: buffer : (unsigned char *)buffer ! 310: actualLength : (unsigned *)actualLength ! 311: client : (vm_task_t)client ! 312: { ! 313: IOReturn rtn; ! 314: ! 315: rtn = [self deviceRwCommon : IDEC_WRITE ! 316: block : offset ! 317: length : length ! 318: buffer : buffer ! 319: client: client ! 320: pending : NULL ! 321: actualLength : actualLength]; ! 322: ! 323: return(rtn); ! 324: } ! 325: ! 326: - (IOReturn) writeAsyncAt : (unsigned)offset ! 327: length : (unsigned)length ! 328: buffer : (unsigned char *)buffer ! 329: pending : (void *)pending ! 330: client : (vm_task_t)client ! 331: { ! 332: IOReturn rtn; ! 333: ! 334: rtn = [self deviceRwCommon : IDEC_WRITE ! 335: block : offset ! 336: length : length ! 337: buffer : buffer ! 338: client : client ! 339: pending : (void *)pending ! 340: actualLength : NULL]; ! 341: return(rtn); ! 342: } ! 343: ! 344: - (IOReturn)updatePhysicalParameters ! 345: { ! 346: // we have got everything we need during initialization ! 347: ! 348: return(IO_R_SUCCESS); ! 349: } ! 350: ! 351: - (void)abortRequest ! 352: { ! 353: ideBuf_t *ideBuf; ! 354: IOReturn rtn; ! 355: ! 356: ideBuf = [self allocIdeBuf:NULL]; ! 357: ideBuf->command = IDEC_ABORT; ! 358: ideBuf->buf = NULL; ! 359: ideBuf->needsDisk = 0; ! 360: ideBuf->oneWay = 0; ! 361: rtn = [self enqueueIdeBuf:ideBuf]; ! 362: [self freeIdeBuf:ideBuf]; ! 363: } ! 364: ! 365: - (void)diskBecameReady ! 366: { ! 367: [_ioQLock lock]; ! 368: [_ioQLock unlockWith:WORK_AVAILABLE]; ! 369: } ! 370: ! 371: - (IOReturn)isDiskReady : (BOOL)prompt ! 372: { ! 373: return(IO_R_SUCCESS); ! 374: } ! 375: ! 376: - (IODiskReadyState)updateReadyState ! 377: { ! 378: return([self lastReadyState]); ! 379: } ! 380: ! 381: - (IOReturn) ejectPhysical ! 382: { ! 383: return(IO_R_UNSUPPORTED); ! 384: } ! 385: ! 386: - (int)deviceOpen:(u_int)intentions ! 387: { ! 388: return(0); ! 389: } ! 390: ! 391: - (void)deviceClose ! 392: { ! 393: return; ! 394: } ! 395: ! 396: - (ideDriveInfo_t)ideGetDriveInfo ! 397: { ! 398: return(_ideInfo); ! 399: } ! 400: ! 401: - (id)cntrlr ! 402: { ! 403: return _cntrlr; ! 404: } ! 405: ! 406: - (unsigned)driveNum ! 407: { ! 408: return _driveNum; ! 409: } ! 410: ! 411: - (IOReturn)getIntValues:(unsigned int *)values ! 412: forParameter:(IOParameterName)parameter ! 413: count:(unsigned int *)count ! 414: { ! 415: int maxCount = *count; ! 416: int blockMajor, characterMajor; ! 417: ! 418: if (maxCount == 0) { ! 419: maxCount = IO_MAX_PARAMETER_ARRAY_LENGTH; ! 420: } ! 421: ! 422: if (strcmp(parameter, "BlockMajor") == 0) { ! 423: ide_block_char_majors(&blockMajor, &characterMajor); ! 424: values[0] = blockMajor; ! 425: *count = 1; ! 426: return IO_R_SUCCESS; ! 427: } ! 428: if (strcmp(parameter, "CharacterMajor") == 0) { ! 429: ide_block_char_majors(&blockMajor, &characterMajor); ! 430: values[0] = characterMajor; ! 431: *count = 1; ! 432: return IO_R_SUCCESS; ! 433: } ! 434: ! 435: /* ! 436: * Pass to superclass what we can't handle. ! 437: */ ! 438: return [super getIntValues:values forParameter:parameter ! 439: count:&maxCount]; ! 440: } ! 441: ! 442: @end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.