|
|
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.