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