|
|
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: * IdeCntInit.m - ATA controller initialization module. ! 29: * ! 30: * 1-Feb-1998 Joe Liu at Apple ! 31: * Added "new style" device overrides, and matching inspector. ! 32: * Report the transfer mode set for both drives. ! 33: * Set PIO transfer mode for ATAPI drives as well. ! 34: * getTransferModeFromCycleTime method now deals with Multiword DMA cases. ! 35: * ! 36: * 04-Mar-1997 Scott Vail at NeXT ! 37: * Fixes made for modifications in ideDriveInfo_t struct. ! 38: * ! 39: * 04-Sep-1996 Becky Divinski at NeXT ! 40: * Added code to ideControllerInit method handle Dual EIDE personality case. ! 41: * ! 42: * 3-Sept-1996 Becky Divinski at NeXT ! 43: * Changed name of controllerPrersent method to ! 44: * controllerPresent. ! 45: * ! 46: * 30-Jan-1996 Rakesh Dubey at NeXT ! 47: * Added forced device detection to fix PIONEER bug. ! 48: * ! 49: * 13-Jul-1995 Rakesh Dubey at NeXT ! 50: * Improved device detection. ! 51: * ! 52: * 11-Aug-1994 Rakesh Dubey at NeXT ! 53: * Created. ! 54: */ ! 55: ! 56: #import "IdeCnt.h" ! 57: #import "IdeCntInit.h" ! 58: #import "IdeCntCmds.h" ! 59: #import "IdePIIX.h" ! 60: #import "AtapiCntCmds.h" ! 61: #import "IdeShared.h" ! 62: #import <driverkit/kernelDriver.h> ! 63: #import <driverkit/interruptMsg.h> ! 64: #if (IO_DRIVERKIT_VERSION != 330) ! 65: #import <machdep/machine/pmap.h> // XXX get rid of this ! 66: #endif ! 67: #import <mach/mach_interface.h> ! 68: #import <driverkit/IODevice.h> ! 69: #import <driverkit/align.h> ! 70: #import <machkit/NXLock.h> ! 71: #import "IdeDDM.h" ! 72: #import <machdep/i386/io_inline.h> ! 73: #import "DualEide.h" ! 74: #import <driverkit/return.h> ! 75: #import <mach/port.h> ! 76: #import <stdlib.h> ! 77: ! 78: ! 79: //#define DEBUG ! 80: ! 81: /* ! 82: * The controller at base address 0x1f0-0x1f7 is always the first controller ! 83: * no matter when it gets probed, so we start the counter at 1. ! 84: */ ! 85: static unsigned char controllerNum = 1; ! 86: ! 87: /* ! 88: * There is no standard for channels 3 and 4 (channel 2 is almost there). We ! 89: * should stick to the following base address/IRQ pairings: 1F0/14, 170/15, ! 90: * 1E8/11, 168/10. ! 91: */ ! 92: static __inline__ ! 93: unsigned int ! 94: assignRegisterAddresses(ideRegsAddrs_t *ideRegsAddrs, ! 95: unsigned int baseAddress1) ! 96: { ! 97: unsigned int baseAddress2; ! 98: unsigned char cntNum; ! 99: ! 100: switch (baseAddress1) { ! 101: case 0x1f0: ! 102: cntNum = 0; /* primary, always controller 0 */ ! 103: break; ! 104: default: ! 105: cntNum = controllerNum++; ! 106: break; ! 107: } ! 108: ! 109: baseAddress2 = baseAddress1 + 0x206; ! 110: ! 111: ideRegsAddrs->data = baseAddress1; ! 112: ideRegsAddrs->error = baseAddress1 + 1; ! 113: ideRegsAddrs->features = baseAddress1 + 1; ! 114: ideRegsAddrs->sectCnt = baseAddress1 + 2; ! 115: ideRegsAddrs->sectNum = baseAddress1 + 3; ! 116: ideRegsAddrs->cylLow = baseAddress1 + 4; ! 117: ideRegsAddrs->cylHigh = baseAddress1 + 5; ! 118: ideRegsAddrs->drHead = baseAddress1 + 6; ! 119: ideRegsAddrs->status = baseAddress1 + 7; ! 120: ideRegsAddrs->command = baseAddress1 + 7; ! 121: ! 122: ideRegsAddrs->deviceControl = baseAddress2; ! 123: ideRegsAddrs->altStatus = baseAddress2; ! 124: ! 125: return cntNum; ! 126: } ! 127: ! 128: /* ! 129: * Function: ata_mode_to_num ! 130: * ! 131: * Convert ata_mode_t into a value. i.e. ! 132: * 0x01 ==> 0 ! 133: * 0x02 ==> 1 ! 134: */ ! 135: extern unsigned char ! 136: ata_mode_to_num(ata_mode_t mode) ! 137: { ! 138: unsigned char tmp = 0; ! 139: if (mode == ATA_MODE_NONE) { ! 140: // IOLog("bad argument to ata_mode_to_num()\n"); ! 141: return (0); ! 142: } ! 143: while (mode != 0x01) { ! 144: mode >>= 1; ! 145: tmp++; ! 146: } ! 147: return (tmp); ! 148: } ! 149: ! 150: /* ! 151: * Function: ata_mask_to_mode ! 152: * ! 153: * Return the most significant bit in a ata_mask_t mask. i.e. ! 154: * 0x03 ==> 0x02 ! 155: * 0x07 ==> 0x04 ! 156: */ ! 157: extern ata_mode_t ! 158: ata_mask_to_mode(ata_mask_t mask) ! 159: { ! 160: int i; ! 161: if (mask == 0) ! 162: return ATA_MODE_NONE; ! 163: for (i = 7; i >= 0; i--) { ! 164: if ((1 << i) & mask) ! 165: return (1 << i); ! 166: } ! 167: return ATA_MODE_NONE; ! 168: } ! 169: ! 170: /* ! 171: * Function: ata_mode_to_mask ! 172: * ! 173: * Convert from a mode to a mask such that all less significant bits, ! 174: * including the mode bit is set. ! 175: */ ! 176: extern ata_mask_t ! 177: ata_mode_to_mask(ata_mode_t mode) ! 178: { ! 179: return ((mode == ATA_MODE_NONE) ? mode : (mode | (mode - 1))); ! 180: } ! 181: ! 182: @implementation IdeController(Initialize) ! 183: ! 184: ! 185: #define ATAPI_SIGNATURE_LOW 0x14 ! 186: #define ATAPI_SIGNATURE_HIGH 0xeb ! 187: ! 188: #define ATA_SIGNATURE_LOW 0x00 ! 189: #define ATA_SIGNATURE_HIGH 0x00 ! 190: ! 191: /* ! 192: * This is called just after resetting the drives connected to this ! 193: * controller. We read the drive registers to figure out if it is an ATAPI ! 194: * drive. If it is then we make a note of it and return YES. ! 195: */ ! 196: - (BOOL)controllerPresent ! 197: { ! 198: unsigned char dh; ! 199: unsigned char unit; ! 200: ! 201: unit = 0; ! 202: ! 203: dh = _drives[unit].addressMode; ! 204: ! 205: dh |= (unit ? SEL_DRIVE1 : SEL_DRIVE0); ! 206: outb(_ideRegsAddrs.drHead, dh); ! 207: ! 208: /* ! 209: * Test with some data. ! 210: */ ! 211: ! 212: if (unit == 0) { ! 213: outb(_ideRegsAddrs.cylLow, 0xaa); ! 214: outb(_ideRegsAddrs.cylHigh, 0xbb); ! 215: } else { ! 216: outb(_ideRegsAddrs.cylLow, 0xba); ! 217: outb(_ideRegsAddrs.cylHigh, 0xbe); ! 218: } ! 219: ! 220: if (unit == 0) { ! 221: if ((inb(_ideRegsAddrs.cylLow) != 0xaa) || ! 222: (inb(_ideRegsAddrs.cylHigh) != 0xbb)) { ! 223: return NO; ! 224: } ! 225: } else { ! 226: if ((inb(_ideRegsAddrs.cylLow) != 0xba) || ! 227: (inb(_ideRegsAddrs.cylHigh) != 0xbe)) { ! 228: return NO; ! 229: } ! 230: } ! 231: ! 232: return YES; ! 233: } ! 234: ! 235: /* ! 236: * One-time only init. Returns NO on failure. ! 237: */ ! 238: - (BOOL)ideControllerInit:(IODeviceDescription *)deviceDescription ! 239: { ! 240: int unit; ! 241: int drivesPresent = 0; ! 242: const char *params; ! 243: const char *addressingMode, *multisectorMode; ! 244: IOEISADeviceDescription *eisaDeviceDescription = ! 245: (IOEISADeviceDescription *)deviceDescription; ! 246: IOConfigTable *configTable = [deviceDescription configTable]; ! 247: int override[MAX_IDE_DRIVES]; ! 248: ! 249: #if 0 ! 250: _printWaitForNotBusy = NO; ! 251: #endif 0 ! 252: ! 253: if (dualEide) { ! 254: if (instanceNum) ! 255: [super setDeviceDescription:deviceDescription]; ! 256: } ! 257: ! 258: if ([self enableAllInterrupts]) { ! 259: IOLog("ideControllerInit: failed enableAllInterrupts\n"); ! 260: return NO; ! 261: } ! 262: ! 263: if ((_ideCmdLock = [NXLock new]) == NULL) { ! 264: IOLog("ideControllerInit: failed _ideCmdLock\n"); ! 265: return NO; ! 266: } ! 267: ! 268: /* ! 269: * We don't want to execute any IDE commands from Disk until ! 270: * initialization is complete. ! 271: */ ! 272: [self ideCntrlrLock]; ! 273: ! 274: /* ! 275: * Initialize the register address values. ! 276: */ ! 277: _controllerNum = assignRegisterAddresses(&_ideRegsAddrs, ! 278: [eisaDeviceDescription portRangeList][0].start); ! 279: ! 280: for (unit = 0; unit < MAX_IDE_DRIVES; unit++) { ! 281: _drives[unit].atapiDevice = NO; ! 282: } ! 283: ! 284: /* ! 285: * We have to test here if the controller is present or else we will ! 286: * block looking for a drive (in ideReset). ! 287: */ ! 288: if ([self controllerPresent] == NO) { ! 289: IOLog("%s: no devices detected at port 0x%0x\n", [self name], ! 290: _ideRegsAddrs.data); ! 291: [self ideCntrlrUnLock]; ! 292: return NO; ! 293: } else { ! 294: IOLog("%s: device detected at port 0x%x irq %d\n", [self name], ! 295: _ideRegsAddrs.data, [deviceDescription interrupt]); ! 296: } ! 297: ! 298: _ideInterruptPort = [self interruptPort]; ! 299: _ideDevicePort = [deviceDescription devicePort]; ! 300: ! 301: [self setInterruptTimeOut:IDE_INTR_TIMEOUT]; ! 302: ! 303: _multiSectorRequested = NO; ! 304: multisectorMode = [configTable valueForStringKey:MULTIPLE_SECTORS_ENABLE]; ! 305: if (multisectorMode) { ! 306: if ((*multisectorMode == 'Y') || (*multisectorMode == 'y')) ! 307: _multiSectorRequested = YES; ! 308: [configTable freeString:multisectorMode]; ! 309: } ! 310: ! 311: /* ! 312: * Select mode for addressing drives. The driver will fall back to CHS ! 313: * mode if LBA is unsupported by the drive. ! 314: */ ! 315: addressingMode = [[deviceDescription configTable] ! 316: valueForStringKey: ADDRESS_MODE]; ! 317: for (unit = 0; unit < MAX_IDE_DRIVES; unit++) { ! 318: if ((addressingMode == NULL) || (strcmp(addressingMode, "LBA") != 0)){ ! 319: _drives[unit].addressMode = ADDRESS_MODE_CHS; ! 320: } else { ! 321: _drives[unit].addressMode = ADDRESS_MODE_LBA; ! 322: } ! 323: } ! 324: if (addressingMode) [configTable freeString:addressingMode]; ! 325: ! 326: #ifdef DEBUG ! 327: if (_addressMode[0] == ADDRESS_MODE_LBA) { ! 328: IOLog("%s: Using Logical address mode..\n", [self name]); ! 329: } ! 330: #endif DEBUG ! 331: ! 332: /* ! 333: * Find out from config table if we are not using BIOS parameters. ! 334: * Default is to use stored values in CMOS/BIOS. ! 335: */ ! 336: params = [[deviceDescription configTable] ! 337: valueForStringKey: DRIVE_PARAMETERS]; ! 338: for (unit = 0; unit < MAX_IDE_DRIVES; unit++) { ! 339: if ((params == NULL) || ((*params != 'Y') && (*params != 'y'))) ! 340: _drives[unit].biosGeometry = YES; ! 341: else ! 342: _drives[unit].biosGeometry = NO; ! 343: } ! 344: if (params) [configTable freeString:params]; ! 345: ! 346: /* ! 347: * Same as DRIVE_PARAMETERS. See comment above. ! 348: */ ! 349: params = [[deviceDescription configTable] ! 350: valueForStringKey: USE_DISK_GEOMETRY]; ! 351: for (unit = 0; unit < MAX_IDE_DRIVES; unit++) { ! 352: if (params && ((*params == 'Y') || (*params == 'y'))) ! 353: _drives[unit].biosGeometry = NO; ! 354: } ! 355: if (params) [configTable freeString:params]; ! 356: ! 357: /* ! 358: * Are we supporting ATAPI? ! 359: */ ! 360: _EIDESupport = YES; ! 361: params = [[deviceDescription configTable] ! 362: valueForStringKey: EIDE_SUPPORT]; ! 363: if (params) { ! 364: if ((*params == 'N') || (*params == 'n')) ! 365: _EIDESupport = NO; ! 366: [configTable freeString:params]; ! 367: } ! 368: ! 369: /* ! 370: * Obtain the transfer type/mode mask. A user may have disabled ! 371: * certain type of transfer modes. ! 372: */ ! 373: for (unit = 0; unit < MAX_IDE_DRIVES; unit++) { ! 374: char *key; ! 375: _drives[unit].driveMasks.modes = 0x000000ff; // enable all PIO modes ! 376: ! 377: if (dualEide && instanceNum) { ! 378: if (unit) ! 379: key = MODES_MASK_SLAVE_SEC; ! 380: else ! 381: key = MODES_MASK_MASTER_SEC; ! 382: } ! 383: else { ! 384: if (unit) ! 385: key = MODES_MASK_SLAVE; ! 386: else ! 387: key = MODES_MASK_MASTER; ! 388: } ! 389: ! 390: params = [[deviceDescription configTable] ! 391: valueForStringKey:key]; ! 392: if (params) { ! 393: // Read the mask set by the user, however we assume that ! 394: // PIO modes 0 is always available. ! 395: unsigned int mask = strtoul(params, NULL, 16); ! 396: _drives[unit].driveMasks.modes = mask | ! 397: ata_mode_to_mask(ATA_MODE_0); ! 398: [configTable freeString:params]; ! 399: } ! 400: } ! 401: ! 402: #if 0 ! 403: /* ! 404: * Does the host support IOCHRDY? There is no way for the driver to find ! 405: * this out. The user has to set this flag. ! 406: */ ! 407: params = [[deviceDescription configTable] ! 408: valueForStringKey: HOST_IORDY_SUPPORT]; ! 409: ! 410: if ((params == NULL) || (strcmp(params, "Yes") != 0)) ! 411: _IOCHRDYSupport = NO; ! 412: else ! 413: _IOCHRDYSupport = YES; ! 414: #endif /* 0 */ ! 415: ! 416: _transferWidth = IDE_TRANSFER_16_BIT; ! 417: ! 418: /* ! 419: * We acquire the disk geometry from either the BIOS or the disk itself. ! 420: * If we are using bios we get the values from it. If we are not using ! 421: * BIOS then we just determine presence of disk here. The actual geometry ! 422: * will be read later. However if the user has chosen "disk geometry" ! 423: * option and disk 0 is not detected then we fall back to BIOS for ! 424: * geometry. This is intended to save the user from getting hosed in case ! 425: * the disk does not support Identify drive command. ! 426: */ ! 427: ! 428: /* ! 429: * FIXME: This recovery strategy needs to thought over. ! 430: */ ! 431: ! 432: _driveNum = unit; ! 433: ! 434: for (unit = 0; unit < MAX_IDE_DRIVES; unit++) ! 435: override[unit] = DEVICE_AUTO; ! 436: ! 437: // Old-style overrides remain here for compatibility ! 438: { ! 439: const char *tmp; ! 440: tmp = [configTable valueForStringKey:ATA_LOCATION]; ! 441: if (tmp) { ! 442: if (strcmp(tmp, "Master")==0) ! 443: override[0]=DEVICE_ATA; ! 444: else if (strcmp(tmp, "Slave")==0) ! 445: override[1]=DEVICE_ATA; ! 446: [configTable freeString:tmp]; ! 447: } ! 448: tmp = [configTable valueForStringKey:ATAPI_LOCATION]; ! 449: if (tmp) { ! 450: if (strcmp(tmp, "Master")==0) ! 451: override[0]=DEVICE_ATAPI; ! 452: else if (strcmp(tmp, "Slave")==0) ! 453: override[1]=DEVICE_ATAPI; ! 454: [configTable freeString:tmp]; ! 455: } ! 456: } ! 457: ! 458: // New-style overrides take precidence over Old-style overrides ! 459: for (unit = 0; unit < MAX_IDE_DRIVES; unit++) { ! 460: const char *tmp; ! 461: ! 462: if (dualEide && instanceNum) ! 463: tmp = [configTable valueForStringKey: ! 464: (unit ? IDE_SLAVE_KEY_SEC : IDE_MASTER_KEY_SEC)]; ! 465: else ! 466: tmp = [configTable valueForStringKey: ! 467: (unit ? IDE_SLAVE_KEY : IDE_MASTER_KEY)]; ! 468: ! 469: if (tmp == NULL) ! 470: continue; ! 471: ! 472: if ( (strcmp(tmp, "")==0) || ! 473: (strcmp(tmp, overrideTable[DEVICE_AUTO])==0) ) ! 474: override[unit] = DEVICE_AUTO; ! 475: else if (strcmp(tmp, overrideTable[DEVICE_NONE])==0) ! 476: override[unit] = DEVICE_NONE; ! 477: else if ( (strcmp(tmp, overrideTable[DEVICE_ATA])==0) || ! 478: (strcmp(tmp, "IDE")==0) || (strcmp(tmp, "EIDE")==0) ) ! 479: override[unit] = DEVICE_ATA; ! 480: else if ( (strcmp(tmp, overrideTable[DEVICE_ATAPI])==0) || ! 481: (strcmp(tmp, "CD")==0) || (strcmp(tmp, "CDROM")==0) ) ! 482: override[unit] = DEVICE_ATAPI; ! 483: [configTable freeString:tmp]; ! 484: } ! 485: ! 486: for (unit = 0; unit < MAX_IDE_DRIVES; unit++) { ! 487: switch (override[unit]) { ! 488: case DEVICE_NONE: ! 489: IOLog("%s: Drive %d scan will be skipped due to override.\n", ! 490: [self name], unit); ! 491: break; ! 492: case DEVICE_ATA: ! 493: IOLog("%s: Drive %d forced to ATA by override.\n", ! 494: [self name], unit); ! 495: break; ! 496: case DEVICE_ATAPI: ! 497: IOLog("%s: Drive %d forced to ATAPI by override.\n", ! 498: [self name], unit); ! 499: break; ! 500: default : ! 501: break; ! 502: } ! 503: bzero(&(_drives[unit].ideInfo), sizeof(ideDriveInfo_t)); ! 504: ! 505: [self ideReset]; ! 506: ! 507: /* ! 508: * We need to use the disk geometry (and override user selection) if ! 509: * the BIOS reports more than 16 heads. ! 510: */ ! 511: if (_drives[unit].biosGeometry == YES) { ! 512: _drives[unit].ideInfo = [self getIdeInfoFromBIOS:unit]; ! 513: if ((_drives[unit].ideInfo.type != 0) && ! 514: (_drives[unit].ideInfo.heads > 16)) { ! 515: _drives[unit].biosGeometry = NO; ! 516: _drives[unit].ideInfo.type = 0; ! 517: IOLog("%s: WARNING: using disk geometry for drive %d.\n", ! 518: [self name], unit); ! 519: } ! 520: } ! 521: ! 522: /* ! 523: * If IDE_IDENTIFY_DRIVE command fails then we will override user ! 524: * selection and use BIOS geometry if this is the boot disk (first ! 525: * disk on first controller). ! 526: */ ! 527: if ((override[unit] == DEVICE_AUTO) || (override[unit] == DEVICE_ATA)) { ! 528: if (_drives[unit].biosGeometry == NO) { ! 529: if ([self ideDetectDrive:unit override:override[unit]] == YES) { ! 530: _drives[unit].ideInfo.type = 255; ! 531: } else if ((_controllerNum == 0) && (unit == 0)) { ! 532: _drives[unit].ideInfo = [self getIdeInfoFromBIOS:unit]; ! 533: if (_drives[unit].ideInfo.type != 0) { ! 534: _drives[unit].biosGeometry = YES; ! 535: IOLog("%s: WARNING: using BIOS geometry for drive %d.\n", ! 536: [self name], unit); ! 537: } ! 538: } ! 539: } ! 540: } ! 541: ! 542: /* ! 543: * If we didn't find ATA drive then look for ATAPI device. ! 544: */ ! 545: if ((override[unit] == DEVICE_AUTO) || (override[unit] == DEVICE_ATAPI)) { ! 546: if ((_drives[unit].ideInfo.type == 0) && (_EIDESupport == YES) && ! 547: ([self ideDetectATAPIDevice:unit override:override[unit]] == YES)){ ! 548: _drives[unit].ideInfo.type = 127; ! 549: } ! 550: } ! 551: ! 552: if (_drives[unit].ideInfo.type != 0) ! 553: drivesPresent += 1 ; ! 554: } ! 555: ! 556: if (drivesPresent == 0) { ! 557: [self ideCntrlrUnLock]; ! 558: IOLog("ideControllerInit: failed drivesPresent\n"); ! 559: return NO; ! 560: } ! 561: ! 562: /* ! 563: * Initialization was successful. We should release the lock so that the ! 564: * controller can now execute commands from disk objects. ! 565: */ ! 566: ! 567: [self resetAndInit]; ! 568: ! 569: #ifdef DDM_DEBUG ! 570: IOInitDDM(IDE_NUM_DDM_BUFS); ! 571: #endif DDM_DEBUG ! 572: ! 573: /* ! 574: * Set drive power state to active. ! 575: */ ! 576: for (unit = 0; unit < MAX_IDE_DRIVES; unit++) { ! 577: if (_drives[unit].ideInfo.type != 0) ! 578: [self setDrivePowerState:IDE_PM_ACTIVE]; ! 579: } ! 580: ! 581: _driveSleepRequest = NO; ! 582: [self enableInterrupts]; ! 583: [self ideCntrlrUnLock]; ! 584: return YES; ! 585: } ! 586: ! 587: /* ! 588: * Method: getControllerCapability ! 589: * ! 590: * Query the controller's transfer mode capability and record them ! 591: * to _controllerModes. ! 592: * ! 593: * Note that _controllerModes fields contain the mask of all modes that it ! 594: * supports. Not just the highest possible mode. ! 595: */ ! 596: - (void) getControllerCapability ! 597: { ! 598: /* ! 599: * Set default values. ! 600: */ ! 601: _controllerModes.mode.pio = ATA_MODE_0; ! 602: _controllerModes.mode.swdma = ATA_MODE_NONE; ! 603: _controllerModes.mode.mwdma = ATA_MODE_NONE; ! 604: _controllerModes.mode.udma = ATA_MODE_NONE; ! 605: ! 606: if (_controllerID != PCI_ID_NONE) ! 607: [self getPCIControllerCapabilities:(txferModes_t *)&_controllerModes]; ! 608: else { ! 609: // Assume all IDE controllers are capable of PIO Mode 4 ! 610: // ! 611: _controllerModes.mode.pio = ata_mode_to_mask(ATA_MODE_4); ! 612: } ! 613: } ! 614: ! 615: #define ATA_RESET_DELAY 1500 /* milliseconds */ ! 616: ! 617: /* ! 618: * Determine the presence and type of drive (IDE/ATAPI) attached to this ! 619: * controller. We use this only if we are not using the info from CMOS/BIOS. ! 620: * ! 621: * Even though this is an optional command it is safe to use since all ATA ! 622: * disks support it. Vey old disks may not support it and they can be used ! 623: * by the "Use BIOS Geometry" option. ! 624: * ! 625: * Note Well: Some drives bail out immediately and return with ERR bit set in ! 626: * the status register. Some bail out after a minute and set ERR bit. However ! 627: * some simply return zero in the status register. I am sure there are other ! 628: * variants. Hence we check for DRQ (success) bit. Note that we would not get ! 629: * an interrupt since -registerDevice has not been called yet. This routine ! 630: * probably needs some more thinking. It is very important that this routine ! 631: * never detect ATAPI drives as ATA. ! 632: */ ! 633: ! 634: /* ! 635: * In Micron machine, if there is one ATAPI CD-ROM, it returns 78 or 7a in the ! 636: * status register. Completely bogus. ! 637: */ ! 638: -(BOOL)ideDetectDrive:(unsigned int)unit override:(int)override ! 639: { ! 640: unsigned char dh = _drives[unit].addressMode; ! 641: int i; ! 642: unsigned char status; ! 643: BOOL found = NO; ! 644: ! 645: if ((override != DEVICE_AUTO) && (override != DEVICE_ATA)) ! 646: return NO; ! 647: ! 648: IOLog("%s: Checking for ATA drive %d... ", [self name], unit); ! 649: #ifdef DEBUG ! 650: IOLog("\n"); ! 651: #endif DEBUG ! 652: ! 653: [self disableInterrupts]; ! 654: ! 655: dh |= (unit ? SEL_DRIVE1 : SEL_DRIVE0); ! 656: outb(_ideRegsAddrs.drHead, dh); ! 657: ! 658: outb(_ideRegsAddrs.command, IDE_IDENTIFY_DRIVE); ! 659: ! 660: for (i = 0; i < (ATA_RESET_DELAY * 100); i++) { ! 661: IODelay(10); ! 662: status = inb(_ideRegsAddrs.status); ! 663: ! 664: if (status & BUSY) ! 665: continue; ! 666: ! 667: if (status & ERROR) { ! 668: break; /* certain failure */ ! 669: } ! 670: if (unit && (status & WRITE_FAULT)) { ! 671: break; /* failure as well */ ! 672: } ! 673: if (status & DREQUEST) { ! 674: found = YES; /* success */ ! 675: break; ! 676: } ! 677: } ! 678: #ifdef DEBUG ! 679: IOLog("%s: ideDetectDrive: status %x\n", [self name], status); ! 680: #endif DEBUG ! 681: ! 682: if (found) { ! 683: IOLog("Detected\n"); ! 684: return YES; ! 685: } ! 686: ! 687: /* ! 688: * If we got here this means that the ATA device is not present or was ! 689: * not detected. Check if the user has told us that the drive is present. ! 690: */ ! 691: ! 692: if (override == DEVICE_ATA) { ! 693: IOLog("Not detected but proceeding\n"); ! 694: return YES; ! 695: } ! 696: ! 697: IOLog("\n"); ! 698: return NO; ! 699: } ! 700: ! 701: /* ! 702: * We send the device ATAPI soft reset command and check for signature. This ! 703: * is the first command that ATAPI devices need. ! 704: */ ! 705: -(BOOL)ideDetectATAPIDevice:(unsigned int)unit override:(int)override ! 706: { ! 707: unsigned char low, high; ! 708: // const char *location; ! 709: BOOL found = NO; ! 710: ! 711: if ((override != DEVICE_AUTO) && (override != DEVICE_ATAPI)) ! 712: return NO; ! 713: ! 714: IOLog("%s: Checking for ATAPI drive %d... ", [self name], unit); ! 715: #ifdef DEBUG ! 716: IOLog("\n"); ! 717: #endif DEBUG ! 718: ! 719: [self atapiSoftReset:unit]; ! 720: ! 721: low = inb(_ideRegsAddrs.cylLow); ! 722: high = inb(_ideRegsAddrs.cylHigh); ! 723: ! 724: if ((low == ATAPI_SIGNATURE_LOW) && (high == ATAPI_SIGNATURE_HIGH)) { ! 725: _drives[unit].atapiDevice = YES; ! 726: #ifdef undef ! 727: IOLog("%s: ATAPI drive %d detected.\n", [self name], unit); ! 728: #endif undef ! 729: found = YES; ! 730: } else if (_ide_debug) { ! 731: IOLog("%s: No ATAPI drive %d, low = %x high = %x\n", ! 732: [self name], unit, low, high); ! 733: } ! 734: ! 735: if (found) { ! 736: IOLog("Detected\n"); ! 737: return YES; ! 738: } ! 739: ! 740: /* ! 741: * If we got here this means that the ATAPI device is not present or was ! 742: * not detected. Check if the user has told us that the device is ! 743: * present. This will probably fail later but succeeds in case of some ! 744: * drives (like PIONEER DR-124X 1.02). It is definitely lame to work ! 745: * around firmware bugs in the driver but there seems to be no ! 746: * alternative.. ! 747: */ ! 748: if (override == DEVICE_ATAPI) { ! 749: _drives[unit].atapiDevice = YES; ! 750: IOLog("Not detected but proceeding\n"); ! 751: return YES; ! 752: } ! 753: ! 754: IOLog("\n"); ! 755: return NO; ! 756: } ! 757: ! 758: ! 759: -(ideDriveInfo_t)getIdeDriveInfo:(unsigned int)unit ! 760: { ! 761: return _drives[unit].ideInfo; ! 762: } ! 763: ! 764: #define MAX_RESET_ATTEMPTS 2 ! 765: ! 766: - (void)ideReset ! 767: { ! 768: int count; ! 769: int delay; ! 770: unsigned char status; ! 771: ! 772: #ifdef DEBUG_TRACE ! 773: IOLog("%s: ideReset\n", [self name]); ! 774: #endif DEBUG_TRACE ! 775: ! 776: for (count = 0; count < MAX_RESET_ATTEMPTS; count++) { ! 777: ! 778: outb(_ideRegsAddrs.deviceControl, DISK_RESET_ENABLE); ! 779: IODelay(100); /* spec >= 25 us */ ! 780: outb(_ideRegsAddrs.deviceControl, 0x0); ! 781: ! 782: [self enableInterrupts]; ! 783: ! 784: delay = 31 * 1000 * 1000; /* thirty one seconds */ ! 785: ! 786: IOSleep(1000); /* Enough time to assert busy */ ! 787: ! 788: while (delay > 0) { ! 789: ! 790: status = inb(_ideRegsAddrs.status); ! 791: if (!(status & BUSY)) { ! 792: return; ! 793: } ! 794: ! 795: IOSleep(1); ! 796: delay -= 1000; ! 797: } ! 798: ! 799: IOLog("%s: Reset failed, retrying..\n", [self name]); ! 800: IOSleep(2000); ! 801: } ! 802: ! 803: /* FIXME: I don't think we should panic */ ! 804: if (count == MAX_RESET_ATTEMPTS) { ! 805: IOLog("%s: can not reset.\n", [self name]); ! 806: IOPanic("IDE Reset"); ! 807: /* NOT REACHED */ ! 808: } ! 809: } ! 810: ! 811: /* ! 812: * Initialize the IDE interface. Find about drive capabilities (by ! 813: * IDE_IDENTIFY_DRIVE command) and configure drive. We either use CMOS/BIOS ! 814: * settings to program the drive or bypass CMOS/BIOS and use the values ! 815: * returned by the drive depending upon biosGeometry flag. By the time we ! 816: * enter this routine we know about all devices connected to this controller. ! 817: */ ! 818: - (void)resetAndInit ! 819: { ! 820: int i; ! 821: unsigned char unit; ! 822: ide_return_t rtn; ! 823: BOOL ataDevicePresent; ! 824: BOOL retry; ! 825: ! 826: /* ! 827: * Determine what transfer modes the controller is capable of. ! 828: */ ! 829: [self getControllerCapability]; ! 830: ! 831: /* Qualify the default mask for each drive with the ! 832: * controller's mask. ! 833: */ ! 834: for (i = 0; i < MAX_IDE_DRIVES; i++) { ! 835: _drives[i].driveMasks.modes &= _controllerModes.modes; ! 836: } ! 837: ! 838: /* ! 839: * Loops through one cycle of the configuration process: ! 840: * ! 841: * 0. Get controller capability. ! 842: * 1. Revert controller back to compatibility timing. ! 843: * 2. Reset ATA/ATAPI. ! 844: * 3. Determine drive(s) capabilities. ! 845: * 4. Set drive(s) feature according to controller & drive capability. ! 846: * 5. Set controller timing and mode. (UDMA, PIO, etc...) ! 847: * 6. If DMA or Multisector mode, perform test. ! 848: * 7. If test failed, mask out the current mode, goto step 1. ! 849: */ ! 850: ! 851: do { ! 852: ! 853: /* ! 854: * Reset the IDE controller to stop any transfer in progress, and ! 855: * revert back to the slowest timing settings. ! 856: */ ! 857: [self resetController]; ! 858: ! 859: retry = NO; ! 860: IOLog("%s: Resetting drives...\n", [self name]); ! 861: ! 862: /* ! 863: * If there is at least one ATA drive connected to this controller then ! 864: * is is necessary to (ATA style) reset them. Otherwise, We use the ATAPI ! 865: * reset instead (in setATAPIDriveCapabilities: method below). ! 866: */ ! 867: ataDevicePresent = NO; ! 868: for (i = 0; i < MAX_IDE_DRIVES; i++) { ! 869: if ((_drives[i].ideInfo.type != 0) && ([self isAtapiDevice:i] == NO)){ ! 870: ataDevicePresent = YES; ! 871: break; ! 872: } ! 873: } ! 874: if (ataDevicePresent == YES) { ! 875: #ifdef DEBUG ! 876: IOLog("%s: ATA device present on this controller\n", [self name]); ! 877: #endif DEBUG ! 878: [self ideReset]; ! 879: } ! 880: ! 881: /* ! 882: * Send the controller necessary commands to set capabilities and then ! 883: * set drive parameters. It is necessary to set drive parameters before ! 884: * any data I/O can be done from the disk. ! 885: */ ! 886: for (unit = 0; unit < MAX_IDE_DRIVES; unit++) { ! 887: ! 888: if (_drives[unit].ideInfo.type == 0) { ! 889: //IOLog("%s: Drive %d not present.\n", [self name], unit); ! 890: continue; ! 891: } ! 892: ! 893: /* Set default values. ! 894: */ ! 895: _drives[unit].multiSector = 0; ! 896: _drives[unit].transferType = IDE_TRANSFER_PIO; ! 897: _drives[unit].transferMode = ATA_MODE_0; ! 898: ! 899: /* ! 900: * ATAPI devices. ! 901: */ ! 902: if ([self isAtapiDevice:unit] == YES) { ! 903: rtn = [self setATAPIDriveCapabilities:unit]; ! 904: if (rtn != IDER_SUCCESS) { ! 905: IOLog("%s: ATAPI drive %d is not present.\n", ! 906: [self name], unit); ! 907: _drives[unit].ideInfo.type = 0; ! 908: _drives[unit].atapiDevice = NO; ! 909: } ! 910: continue; ! 911: } ! 912: ! 913: /* ! 914: * ATA devices. ! 915: */ ! 916: if (_drives[unit].biosGeometry == YES) { ! 917: rtn = [self setATADriveCapabilities:unit withBIOSInfo:YES]; ! 918: } else { ! 919: rtn = [self setATADriveCapabilities:unit withBIOSInfo:NO]; ! 920: if (rtn != IDER_SUCCESS) { ! 921: IOLog("%s: ATA drive %d is not present.\n", [self name], unit); ! 922: _drives[unit].ideInfo.type = 0; ! 923: continue; ! 924: } ! 925: } ! 926: } ! 927: ! 928: /* ! 929: * Set IDE controller capabilities. This must be done after the disks are ! 930: * configured. ! 931: */ ! 932: [self setControllerCapabilities]; ! 933: ! 934: /* ! 935: * Report the transfer mode set for both drives. ! 936: */ ! 937: if (_controllerID != PCI_ID_NONE) { ! 938: const char *mode_string[] = ! 939: {"PIO", "Single-word DMA", "Multiword DMA", "Ultra DMA"}; ! 940: for (unit = 0; unit < MAX_IDE_DRIVES; unit++) { ! 941: if (_drives[unit].ideInfo.type == 0) ! 942: continue; ! 943: if (_drives[unit].multiSector) ! 944: IOLog("%s: Drive %d: %s Mode %d (%d sectors)\n", ! 945: [self name], unit, mode_string[_drives[unit].transferType], ! 946: ata_mode_to_num(_drives[unit].transferMode), ! 947: _drives[unit].multiSector); ! 948: else ! 949: IOLog("%s: Drive %d: %s Mode %d\n", ! 950: [self name], unit, mode_string[_drives[unit].transferType], ! 951: ata_mode_to_num(_drives[unit].transferMode)); ! 952: } ! 953: } ! 954: ! 955: /* ! 956: * After the drives and the controller are setup, we perform a read ! 957: * and make sure everything is OK. We do not perform this test for ! 958: * ATAPI or removable ATA devices (if they become supported). ! 959: * ! 960: * FIXME: perhaps instead of reading a block from the disk, we should ! 961: * consider using DMA on non-media commands. This will be needed when ! 962: * DMA is supported on removable media drives. Do those commands exist? ! 963: * It seems that ATA-3 defined a IDENTIFY DEVICE DMA command, but they ! 964: * no longer exist in ATA-4. Did they get dropped? ! 965: */ ! 966: for (unit = 0; unit < MAX_IDE_DRIVES; unit++) { ! 967: ! 968: _driveNum = unit; ! 969: ! 970: // Don't test ATAPI devices. ! 971: // ! 972: if ([self isAtapiDevice:unit]) ! 973: continue; ! 974: ! 975: // Test DMA reads. ! 976: // ! 977: if ((_drives[unit].ideInfo.type != 0) && ! 978: (_drives[unit].transferType != IDE_TRANSFER_PIO) && ! 979: ([self performDMATest] != IDER_SUCCESS)) { ! 980: IOLog("%s: Drive %d: DMA read test FAILED\n", [self name], unit); ! 981: /* Failure, mask out the current mode */ ! 982: _drives[unit].driveMasks.array.mode[_drives[unit].transferType] &= ! 983: ~_drives[unit].transferMode; ! 984: retry = YES; ! 985: } ! 986: ! 987: // Test PIO multisector reads. ! 988: // ! 989: // FIXME - Test Fast PIO modes as well? ! 990: // ! 991: if ((_drives[unit].ideInfo.type != 0) && ! 992: (_drives[unit].transferType == IDE_TRANSFER_PIO) && ! 993: (_drives[unit].multiSector)) { ! 994: ! 995: ideRegsVal_t ideRegs; ! 996: char *buf; ! 997: ! 998: ideRegs = [self logToPhys:0 numOfBlocks:_drives[unit].multiSector]; ! 999: buf = IOMalloc(_drives[unit].multiSector * IDE_SECTOR_SIZE); ! 1000: if ([self ideReadMultiple:&ideRegs ! 1001: client:(struct vm_map *)IOVmTaskSelf() ! 1002: addr:buf] != IDER_SUCCESS) { ! 1003: IOLog("%s: Drive %d: Read Multiple test FAILED\n", ! 1004: [self name], unit); ! 1005: _multiSectorRequested = NO; ! 1006: retry = YES; ! 1007: } ! 1008: IOFree(buf, _drives[unit].multiSector * IDE_SECTOR_SIZE); ! 1009: } ! 1010: } ! 1011: ! 1012: } while (retry); ! 1013: } ! 1014: ! 1015: /* ! 1016: * Method: resetController ! 1017: * ! 1018: * Reset the controller on the HOST side. ! 1019: */ ! 1020: - (void)resetController ! 1021: { ! 1022: /* ! 1023: * Return the controller to the compatible timing mode. ! 1024: */ ! 1025: [self resetPCIController]; ! 1026: } ! 1027: ! 1028: /* ! 1029: * Method: getBestTransferMode ! 1030: * ! 1031: * Find the "best" mode given the txferModes_t structure for both the drive ! 1032: * and the controller. Recall that the txferModes_t type encodes all the ! 1033: * transfer modes that a device can attain. Certain modes may also be masked ! 1034: * so that they will never be used. This mask is stored in the driveMasks. ! 1035: */ ! 1036: -(void)getBestTransferMode:(ata_mode_t *)mode type:(ideTransferType_t *)type ! 1037: forUnit:(unsigned int)unit ! 1038: { ! 1039: txferModes_t m; // store all the possible modes. ! 1040: ! 1041: m.modes = _drives[unit].driveModes.modes & _drives[unit].driveMasks.modes & ! 1042: _controllerModes.modes; ! 1043: ! 1044: /* ! 1045: * Test in the order of "best" to "worst" modes. ! 1046: */ ! 1047: if (m.mode.udma) { ! 1048: *type = IDE_TRANSFER_ULTRA_DMA; ! 1049: *mode = ata_mask_to_mode(m.mode.udma); ! 1050: } ! 1051: else if (m.mode.mwdma) { ! 1052: *type = IDE_TRANSFER_MW_DMA; ! 1053: *mode = ata_mask_to_mode(m.mode.mwdma); ! 1054: } ! 1055: else if (m.mode.swdma) { ! 1056: *type = IDE_TRANSFER_SW_DMA; ! 1057: *mode = ata_mask_to_mode(m.mode.swdma); ! 1058: } ! 1059: else if (m.mode.pio) { ! 1060: *type = IDE_TRANSFER_PIO; ! 1061: *mode = ata_mask_to_mode(m.mode.pio); ! 1062: } ! 1063: else { ! 1064: *type = IDE_TRANSFER_PIO; ! 1065: *mode = ATA_MODE_0; ! 1066: } ! 1067: } ! 1068: ! 1069: /* ! 1070: * Method: getTransferModes:fromInfo: ! 1071: * ! 1072: * Purpose: ! 1073: * Given an infoPtr which points to information from the IDE Identify Drive ! 1074: * command, determine the transfer modes that the drive is capable of. ! 1075: * ! 1076: */ ! 1077: - (void)getTransferModes:(txferModes_t *)modes ! 1078: fromInfo:(ideIdentifyInfo_t *)infoPtr ! 1079: { ! 1080: unsigned char n; ! 1081: ata_mode_t m = ATA_MODE_0; ! 1082: int i; ! 1083: ! 1084: /* ! 1085: * For PIO, check if we support the ATA-2 additions. ! 1086: */ ! 1087: if (infoPtr->fieldValidity & IDE_WORDS64_TO_70_SUPPORTED) { ! 1088: if (infoPtr->fcPioDataTransferCyleTimingMode & ! 1089: IDE_FC_PIO_MODE_5_SUPPORTED) ! 1090: m = ATA_MODE_5; ! 1091: else if (infoPtr->fcPioDataTransferCyleTimingMode & ! 1092: IDE_FC_PIO_MODE_4_SUPPORTED) ! 1093: m = ATA_MODE_4; ! 1094: else if (infoPtr->fcPioDataTransferCyleTimingMode & ! 1095: IDE_FC_PIO_MODE_3_SUPPORTED) ! 1096: m = ATA_MODE_3; ! 1097: } ! 1098: else { ! 1099: n = (infoPtr->pioDataTransferCyleTimingMode & ! 1100: IDE_PIO_TIMING_MODE_MASK) >> 8; ! 1101: if (n >= 2) n = 2; ! 1102: m = (1 << n); // convert number to mode ! 1103: } ! 1104: ! 1105: /* For mode 2 and above, IORDY must be supported. */ ! 1106: if ((m > ATA_MODE_2) && ! 1107: !(infoPtr->capabilities & IDE_CAP_IORDY_SUPPORTED)) ! 1108: m = ATA_MODE_2; ! 1109: ! 1110: /* ! 1111: * A drive supporting a certain mode must also support slower modes ! 1112: * of the same transfer type. ! 1113: */ ! 1114: modes->mode.pio = ata_mode_to_mask(m); ! 1115: ! 1116: /* ! 1117: * Drive must indicate that it supports DMA in Word 49 before ! 1118: * continuing. ! 1119: */ ! 1120: if (!(infoPtr->capabilities & IDE_CAP_DMA_SUPPORTED)) { ! 1121: modes->mode.swdma = ATA_MODE_NONE; ! 1122: modes->mode.mwdma = ATA_MODE_NONE; ! 1123: modes->mode.udma = ATA_MODE_NONE; ! 1124: return; ! 1125: } ! 1126: ! 1127: /* ! 1128: * Single word DMA. Read from Word 52. ! 1129: */ ! 1130: n = (infoPtr->dmaDataTransferCyleTimingMode & ! 1131: IDE_DMA_TIMING_MODE_MASK) >> 8; ! 1132: if (n >= 2) ! 1133: n = 2; ! 1134: m = (1 << n); ! 1135: modes->mode.swdma = ata_mode_to_mask(m); ! 1136: ! 1137: /* ! 1138: * Multiword DMA. Read Word 63. ! 1139: */ ! 1140: m = ATA_MODE_NONE; ! 1141: for (i = 2; i >= 0; i--) { ! 1142: if (infoPtr->mwDma & (1 << i)) { ! 1143: m = (1 << i); ! 1144: break; ! 1145: } ! 1146: } ! 1147: /* Can't be Multiword DMA mode 1 and above and NOT support ! 1148: * Words 64 through 70. ! 1149: */ ! 1150: if ((m >= ATA_MODE_1) && ! 1151: !(infoPtr->fieldValidity & IDE_WORDS64_TO_70_SUPPORTED)) { ! 1152: m = ATA_MODE_0; ! 1153: } ! 1154: modes->mode.mwdma = ata_mode_to_mask(m); ! 1155: ! 1156: /* ! 1157: * Ultra DMA. Read capability from Word 88. ! 1158: */ ! 1159: m = ATA_MODE_NONE; ! 1160: if (infoPtr->fieldValidity & IDE_WORD88_SUPPORTED) { ! 1161: for (i = 2; i >= 0; i--) { ! 1162: if (infoPtr->UDma & (1 << i)) { ! 1163: m = (1 << i); ! 1164: break; ! 1165: } ! 1166: } ! 1167: } ! 1168: modes->mode.udma = ata_mode_to_mask(m); ! 1169: ! 1170: return; ! 1171: } ! 1172: ! 1173: /* ! 1174: * We do host dependent hardware initialization here. ! 1175: */ ! 1176: - (BOOL) setControllerCapabilities ! 1177: { ! 1178: if (_controllerID != PCI_ID_NONE) { ! 1179: if ([self setPCIControllerCapabilitiesForDrives:_drives] == NO) ! 1180: return NO; ! 1181: _transferWidth = [self getPIOTransferWidth]; ! 1182: return YES; ! 1183: } ! 1184: return YES; ! 1185: } ! 1186: ! 1187: /* ! 1188: * Method: setATADriveCapabilities ! 1189: * ! 1190: * Send the Set Parameters command to the drive and set multi-sector mode ! 1191: * etc. if the drive supports them. If biosInfo is YES, then we are using ! 1192: * drive geometry information from the BIOS else we use Identify command to ! 1193: * get this. ! 1194: */ ! 1195: - (ide_return_t)setATADriveCapabilities:(unsigned int)unit ! 1196: withBIOSInfo:(BOOL)biosInfo ! 1197: { ! 1198: ideRegsVal_t ideRegs; ! 1199: unsigned char nSectors; ! 1200: ide_return_t rtn; ! 1201: ideIdentifyInfo_t *infoPtr = _drives[unit].ideIdentifyInfo; ! 1202: ! 1203: _drives[unit].ideIdentifyInfoSupported = YES; ! 1204: bzero(infoPtr, sizeof(ideIdentifyInfo_t)); ! 1205: ! 1206: _driveNum = unit; ! 1207: ! 1208: /* ! 1209: * Remember this command is optional. Failure means that either this ! 1210: * command is not supported or the drive is not present. ! 1211: */ ! 1212: if ([self ideReadGetInfoCommon:&ideRegs ! 1213: client:(struct vm_map *)IOVmTaskSelf() ! 1214: addr:(unsigned char *)infoPtr ! 1215: command:IDE_IDENTIFY_DRIVE] != IDER_SUCCESS) { ! 1216: _drives[unit].ideIdentifyInfoSupported = NO; ! 1217: if (_ide_debug) ! 1218: IOLog("ATA: ideReadGetInfoCommon failed.\n"); ! 1219: /* ! 1220: * FIXME: If this is a slave device and we perform a reset. The ! 1221: * master device will lose its configuration state. ! 1222: */ ! 1223: [self ideReset]; /* necessary */ ! 1224: return IDER_CMD_ERROR; ! 1225: } ! 1226: ! 1227: /* ! 1228: * Fill in this struct similar to which we would have gotten from CMOS. ! 1229: */ ! 1230: if (biosInfo == NO) { ! 1231: ideDriveInfo_t *ip = &(_drives[unit].ideInfo); ! 1232: ! 1233: ip->cylinders = _drives[unit].ideIdentifyInfo->cylinders; ! 1234: ip->heads = _drives[unit].ideIdentifyInfo->heads; ! 1235: ip->control_byte = 0; ! 1236: ip->landing_zone = 0; ! 1237: ip->sectors_per_trk = _drives[unit].ideIdentifyInfo->sectorsPerTrack; ! 1238: ip->bytes_per_sector = IDE_SECTOR_SIZE; ! 1239: if ([IODevice driverKitVersion] > 410) { ! 1240: ip->total_sectors = ip->sectors_per_trk * ! 1241: ip->heads * ! 1242: ip->cylinders; ! 1243: ! 1244: /* If disk supports LBA, and Words (61:60) indicates that the ! 1245: * user-addressable logical sectors is larger than the number ! 1246: * of sectors computed through CHS translation, then use the ! 1247: * larger value. This will be needed for disks with more than ! 1248: * 16,514,064 sectors. (16383 C x 16 H x 63 S) ! 1249: */ ! 1250: if ((infoPtr->capabilities & IDE_CAP_LBA_SUPPORTED) && ! 1251: (infoPtr->userAddressableSectors > ip->total_sectors)) ! 1252: ip->total_sectors = infoPtr->userAddressableSectors; ! 1253: } ! 1254: else { ! 1255: // fake capacity for backward compatibility. ! 1256: ip->total_sectors = ip->sectors_per_trk * ip->heads * ! 1257: ip->cylinders * ip->bytes_per_sector; ! 1258: } ! 1259: } ! 1260: ! 1261: /* ! 1262: * Set address mode. The only case in which we need to override user ! 1263: * selection if the user chooses LBA and the drive supports only CHS. ! 1264: */ ! 1265: if (((infoPtr->capabilities & IDE_CAP_LBA_SUPPORTED) == 0x0) && ! 1266: (_drives[unit].addressMode == ADDRESS_MODE_LBA)) { ! 1267: #ifdef DEBUG ! 1268: IOLog("%s: WARNING: LBA mode is not supported by drive %d.\n", ! 1269: [self name], unit); ! 1270: #endif DEBUG ! 1271: _drives[unit].addressMode = ADDRESS_MODE_CHS; ! 1272: } ! 1273: ! 1274: /* ! 1275: * Set disk parameters (Initialize Device Parameters command). ! 1276: */ ! 1277: [self ideSetParams:_drives[unit].ideInfo.sectors_per_trk ! 1278: numHeads:_drives[unit].ideInfo.heads ForDrive:unit]; ! 1279: ! 1280: /* ! 1281: * Determine the best transfer mode. ! 1282: */ ! 1283: [self getTransferModes:&_drives[unit].driveModes fromInfo:infoPtr]; ! 1284: [self getBestTransferMode:&_drives[unit].transferMode ! 1285: type:&_drives[unit].transferType ! 1286: forUnit:unit]; ! 1287: ! 1288: /* ! 1289: * Determine the number of sectors for each Multiple Read/Write. ! 1290: */ ! 1291: nSectors = infoPtr->multipleSectors & IDE_MULTI_SECTOR_MASK; ! 1292: if ((_drives[unit].transferType == IDE_TRANSFER_PIO) && ! 1293: (nSectors) && (_multiSectorRequested == YES)) { ! 1294: if ([self ideSetMultiSectorMode:&ideRegs numSectors:nSectors] == ! 1295: IDER_SUCCESS) { ! 1296: _drives[unit].multiSector = nSectors; ! 1297: } ! 1298: } ! 1299: ! 1300: #if 0 ! 1301: IOLog("Drive modes: %08x\n", _driveModes[unit].modes); ! 1302: IOLog("Controller modes: %08x\n", _controllerModes.modes); ! 1303: IOLog("drive %d: MODE:0x%02x TYPE:%d\n", unit, _transferMode[unit], ! 1304: _transferType[unit]); ! 1305: #endif ! 1306: ! 1307: /* ! 1308: * Set drive feature. ! 1309: */ ! 1310: rtn = [self ideSetDriveFeature:FEATURE_SET_TRANSFER_MODE ! 1311: value:_drives[unit].transferMode ! 1312: transferType:_drives[unit].transferType]; ! 1313: ! 1314: if (rtn != IDER_SUCCESS) { ! 1315: IOLog("%s: Drive %d: set transfer mode failed\n", [self name], unit); ! 1316: _drives[unit].transferType = IDE_TRANSFER_PIO; ! 1317: _drives[unit].transferMode = ATA_MODE_0; ! 1318: } ! 1319: ! 1320: return IDER_SUCCESS; ! 1321: } ! 1322: ! 1323: /* ! 1324: * Method: setATAPIDriveCapabilities ! 1325: * ! 1326: * Identify the ATAPI device and set its transfer type/mode. ! 1327: */ ! 1328: - (ide_return_t)setATAPIDriveCapabilities:(unsigned int)unit ! 1329: { ! 1330: atapi_return_t rtn; ! 1331: ! 1332: _driveNum = unit; ! 1333: ! 1334: [self atapiSoftReset:unit]; ! 1335: ! 1336: /* ! 1337: * We have to do this test because of "task file shadow" bug ! 1338: * present in many ATAPI CD-ROMs. ! 1339: */ ! 1340: rtn = [self atapiIdentifyDevice:(struct vm_map *)IOVmTaskSelf() ! 1341: addr:(unsigned char *)_drives[unit].ideIdentifyInfo unit:unit]; ! 1342: ! 1343: /* Too bad.. */ ! 1344: if (rtn != IDER_SUCCESS) ! 1345: return rtn; ! 1346: ! 1347: [self printAtapiInfo:_drives[unit].ideIdentifyInfo Device:unit]; ! 1348: [self atapiInitParameters:_drives[unit].ideIdentifyInfo Device:unit]; ! 1349: ! 1350: _drives[unit].addressMode = ADDRESS_MODE_LBA; ! 1351: ! 1352: [self getTransferModes:&_drives[unit].driveModes ! 1353: fromInfo:_drives[unit].ideIdentifyInfo]; ! 1354: [self getBestTransferMode:&_drives[unit].transferMode ! 1355: type:&_drives[unit].transferType forUnit:unit]; ! 1356: ! 1357: rtn = [self ideSetDriveFeature:FEATURE_SET_TRANSFER_MODE ! 1358: value:_drives[unit].transferMode ! 1359: transferType:_drives[unit].transferType]; ! 1360: if (rtn != IDER_SUCCESS) { ! 1361: IOLog("%s: Drive %d: set transfer mode failed\n", ! 1362: [self name], unit); ! 1363: _drives[unit].transferMode = ATA_MODE_0; ! 1364: _drives[unit].transferType = IDE_TRANSFER_PIO; ! 1365: } ! 1366: ! 1367: return IDER_SUCCESS; ! 1368: } ! 1369: ! 1370: -(ideIdentifyInfo_t *)getIdeIdentifyInfo:(unsigned int)unit ! 1371: { ! 1372: return _drives[unit].ideIdentifyInfoSupported ? ! 1373: _drives[unit].ideIdentifyInfo : NULL; ! 1374: } ! 1375: ! 1376: -(BOOL)isDiskGeometry:(unsigned int)unit ! 1377: { ! 1378: return (_drives[unit].biosGeometry == YES) ? NO : YES; ! 1379: } ! 1380: ! 1381: ! 1382: - (ideDriveInfo_t)getIdeInfoFromBIOS:(unsigned)unit ! 1383: { ! 1384: caddr_t hdtbl; ! 1385: ideDriveInfo_t hdInfo; ! 1386: ! 1387: hdInfo.type = [self getIdeTypeFromCMOS:unit]; ! 1388: if ((hdInfo.type == 0) || (hdInfo.type < MIN_CMOS_IDETYPE) || ! 1389: (hdInfo.type > MAX_CMOS_IDETYPE)) { ! 1390: hdInfo.type = 0; ! 1391: return (hdInfo); ! 1392: } ! 1393: ! 1394: /* ! 1395: * Drive info (the drive characteristic table) for drive 0 is located at ! 1396: * INT41h and for drive 1 it is located at INT46h. ! 1397: */ ! 1398: if (unit == 0) { ! 1399: hdtbl = (caddr_t) (*(unsigned short *)(0x41 << 2) + ! 1400: (*(unsigned short *)((0x41 << 2) + 2) << 4)); ! 1401: } else if (unit == 1) { ! 1402: hdtbl = (caddr_t) (*(unsigned short *)(0x46 << 2) + ! 1403: (*(unsigned short *)((0x46 << 2) + 2) << 4)); ! 1404: } else { ! 1405: hdInfo.type = 0; ! 1406: return (hdInfo); ! 1407: } ! 1408: ! 1409: if (hdtbl == 0) { ! 1410: IOLog("%s: drive %d, type %d, using geometry from CMOS.\n", ! 1411: [self name], unit, hdInfo.type); ! 1412: } else { ! 1413: IOLog("%s: drive %d, type %d, using geometry from INT table.\n", ! 1414: [self name], unit, hdInfo.type); ! 1415: } ! 1416: ! 1417: if (hdtbl == 0) { ! 1418: hdtbl = (caddr_t) pmap_phys_to_kern(CMOS_IDE_TABLE); ! 1419: hdtbl += ((hdInfo.type - 1) * SIZE_OF_IDE_TABLE); ! 1420: } ! 1421: ! 1422: hdInfo.cylinders = *(unsigned short *)hdtbl; ! 1423: hdInfo.heads = *(hdtbl + 2); ! 1424: hdInfo.precomp = *(unsigned short *)(hdtbl + 5); ! 1425: hdInfo.control_byte = *(hdtbl + 8); ! 1426: hdInfo.landing_zone = *(unsigned short *)(hdtbl + 12); ! 1427: hdInfo.sectors_per_trk = *(hdtbl + 14); ! 1428: hdInfo.bytes_per_sector = IDE_SECTOR_SIZE; ! 1429: if([IODevice driverKitVersion] > 410) { ! 1430: hdInfo.total_sectors = hdInfo.sectors_per_trk * ! 1431: hdInfo.heads * hdInfo.cylinders; ! 1432: } ! 1433: else { ! 1434: // fake capacity for backward compatibility. ! 1435: hdInfo.total_sectors = hdInfo.sectors_per_trk * ! 1436: hdInfo.heads * hdInfo.cylinders * hdInfo.bytes_per_sector; ! 1437: } ! 1438: ! 1439: #ifdef DEBUG ! 1440: /* ! 1441: * FIXME: This is for testing only. Remove later. ! 1442: */ ! 1443: IOLog("%s: drive %d, %d cylinders, %d heads, %d sectors (BIOS).\n", ! 1444: [self name], unit, hdInfo.cylinders, hdInfo.heads, ! 1445: hdInfo.sectors_per_trk); ! 1446: #endif DEBUG ! 1447: ! 1448: return hdInfo; ! 1449: } ! 1450: ! 1451: - (unsigned)getIdeTypeFromCMOS:(int)unit ! 1452: { ! 1453: unsigned int hdtype; ! 1454: ! 1455: outb(CMOSADDR, HDTYPE); ! 1456: IODelay(10); ! 1457: hdtype = inb(CMOSDATA); ! 1458: ! 1459: if (unit == 0) { ! 1460: hdtype = hdtype >> 4; ! 1461: if (hdtype != 0xf) { ! 1462: return hdtype; ! 1463: } else { ! 1464: outb(CMOSADDR, HD0_EXTTYPE); ! 1465: IODelay(10); ! 1466: hdtype = inb(CMOSDATA); ! 1467: } ! 1468: } else { ! 1469: hdtype = hdtype & 0x0f; ! 1470: if (hdtype != 0xf) { ! 1471: return hdtype; ! 1472: } else { ! 1473: outb(CMOSADDR, HD1_EXTTYPE); ! 1474: IODelay(10); ! 1475: hdtype = inb(CMOSDATA); ! 1476: } ! 1477: } ! 1478: ! 1479: ! 1480: return hdtype; ! 1481: } ! 1482: ! 1483: @end ! 1484:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.