]> git.saurik.com Git - apple/xnu.git/blame - iokit/Drivers/ata/drvAppleUltra33ATA/AppleUltra33ATA.cpp
xnu-123.5.tar.gz
[apple/xnu.git] / iokit / Drivers / ata / drvAppleUltra33ATA / AppleUltra33ATA.cpp
CommitLineData
1c79356b
A
1/*
2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22/*
23 *
24 * AppleUltra33ATA.cpp
25 *
26 */
27#include "AppleUltra33ATA.h"
28
29#include <IOKit/IODeviceTreeSupport.h>
30
31#undef super
32#define super IOATAStandardDriver
33
34extern pmap_t kernel_pmap;
35
36OSDefineMetaClassAndStructors( AppleUltra33ATA, IOATAStandardDriver )
37
38
39static struct
40{
41 UInt32 minDataAccess;
42 UInt32 minDataCycle;
43} pioModes[] =
44{
45 { 165, 600 }, /* Mode 0 */
46 { 125, 383 }, /* 1 */
47 { 100, 240 }, /* 2 */
48 { 80, 180 }, /* 3 */
49 { 70, 120 } /* 4 */
50};
51
52
53/*
54 *
55 *
56 */
57bool AppleUltra33ATA::configure( IOService *forProvider, ATAControllerInfo *controllerInfo )
58{
59
60 provider = (IOPCIDevice *)forProvider;
61
62 busNum = 0;
63
64 ioMapATA[0] = provider->mapDeviceMemoryWithRegister( 0x10 + busNum * 8 + 0 );
65 if ( ioMapATA[0] == NULL ) return false;
66 ioBaseATA[0] = (volatile UInt32 *)ioMapATA[0]->getVirtualAddress();
67
68 ioMapATA[1] = provider->mapDeviceMemoryWithRegister( 0x10 + busNum * 8 + 4 );
69 if ( ioMapATA[1] == NULL ) return false;
70 ioBaseATA[1] = (volatile UInt32 *)ioMapATA[1]->getVirtualAddress();
71
72 pciWriteLong( 0x04, 0x05 );
73
74 dmaDescriptors = (Ultra646Descriptor *)kalloc(page_size);
75 if ( dmaDescriptors == 0 )
76 {
77 return false;
78 }
79
80 dmaDescriptorsPhys = (UInt32) pmap_extract(kernel_pmap, (vm_offset_t) dmaDescriptors);
81
82 if ( (UInt32)dmaDescriptors & (page_size - 1) )
83 {
84 IOLog("AppleUltra33ATA::%s() - DMA Descriptor memory not page aligned!!", __FUNCTION__);
85 return false;
86 }
87
88 bzero( dmaDescriptors, page_size );
89
90 numDescriptors = page_size/sizeof(Ultra646Descriptor);
91
92 dmaMemoryCursor = IOBigMemoryCursor::withSpecification( 64*1024-2, 0xffffffff );
93 if ( dmaMemoryCursor == NULL )
94 {
95 return false;
96 }
97
98 bitBucketAddr = IOMalloc(32);
99 if ( bitBucketAddr == 0 )
100 {
101 return false;
102 }
103 bitBucketAddrPhys = (UInt32) pmap_extract(kernel_pmap, (vm_offset_t) (((UInt32)bitBucketAddr + 0xf) & ~0x0f));
104
105 interruptEventSource = IOInterruptEventSource::interruptEventSource( (OSObject *) this,
106 (IOInterruptEventAction) &AppleUltra33ATA::interruptOccurred,
107 (IOService *) provider,
108 (int) 0 );
109
110 if ( interruptEventSource == NULL )
111 {
112 return false;
113 }
114
115 disableControllerInterrupts();
116
117 getWorkLoop()->addEventSource( interruptEventSource );
118
119 controllerInfo->maxDevicesSupported = 2;
120 controllerInfo->devicePrivateDataSize = 0;
121 controllerInfo->commandPrivateDataSize = 0;
122 controllerInfo->disableCancelCommands = false;
123
124 return true;
125}
126
127/*
128 *
129 *
130 */
131bool AppleUltra33ATA::calculateTiming( UInt32 unit, ATATiming *pTiming )
132{
133 bool rc = false;
134
135 ideTimingRegs[unit].arttimReg = 0x40;
136 ideTimingRegs[unit].cmdtimReg = 0xA9;
137
138 switch ( pTiming->timingProtocol )
139 {
140 case kATATimingPIO:
141 rc = calculatePIOTiming( unit, pTiming );
142 break;
143
144 case kATATimingDMA:
145 rc = calculateDMATiming( unit, pTiming );
146 break;
147
148 case kATATimingUltraDMA33:
149 rc = calculateUltraDMATiming( unit, pTiming );
150 break;
151
152
153 default:
154 ;
155 }
156
157 return rc;
158}
159
160/*
161 *
162 *
163 */
164bool AppleUltra33ATA::calculatePIOTiming( UInt32 unit, ATATiming *pTiming )
165{
166 UInt32 accessTime;
167 UInt32 drwActClks, drwRecClks;
168 UInt32 drwActTime, drwRecTime;
169
170 accessTime = pioModes[pTiming->mode].minDataAccess;
171
172 drwActClks = accessTime / IDE_SYSCLK_NS;
173 drwActClks += (accessTime % IDE_SYSCLK_NS) ? 1 : 0;
174 drwActTime = drwActClks * IDE_SYSCLK_NS;
175
176 drwRecTime = pioModes[pTiming->mode].minDataCycle - drwActTime;
177 drwRecClks = drwRecTime / IDE_SYSCLK_NS;
178 drwRecClks += (drwRecTime % IDE_SYSCLK_NS) ? 1 : 0;
179
180 if ( drwRecClks >= 16 )
181 drwRecClks = 1;
182 else if ( drwRecClks <= 1 )
183 drwRecClks = 16;
184
185 ideTimingRegs[unit].drwtimRegPIO = ((drwActClks & 0x0f) << 4) | ((drwRecClks-1) & 0x0f);
186
187 return true;
188}
189
190
191/*
192 *
193 *
194 */
195bool AppleUltra33ATA::calculateDMATiming( UInt32 unit, ATATiming *pTiming )
196{
197 UInt32 accessTime;
198 UInt32 drwActClks, drwRecClks;
199 UInt32 drwActTime, drwRecTime;
200
201 ideTimingRegs[unit].udidetcrReg = 0;
202
203 accessTime = pTiming->minDataAccess;
204
205 drwActClks = accessTime / IDE_SYSCLK_NS;
206 drwActClks += (accessTime % IDE_SYSCLK_NS) ? 1 : 0;
207 drwActTime = drwActClks * IDE_SYSCLK_NS;
208
209 drwRecTime = pTiming->minDataCycle - drwActTime;
210 drwRecClks = drwRecTime / IDE_SYSCLK_NS;
211 drwRecClks += (drwRecTime % IDE_SYSCLK_NS) ? 1 : 0;
212
213 if ( drwRecClks >= 16 )
214 drwRecClks = 1;
215 else if ( drwRecClks <= 1 )
216 drwRecClks = 16;
217
218 ideTimingRegs[unit].drwtimRegDMA = ((drwActClks & 0x0f) << 4) | ((drwRecClks-1) & 0x0f);
219
220 return true;
221}
222
223/*
224 *
225 *
226 */
227bool AppleUltra33ATA::calculateUltraDMATiming( UInt32 unit, ATATiming *pTiming )
228{
229 UInt32 cycleClks;
230 UInt32 cycleTime;
231
232 cycleTime = pTiming->minDataCycle;
233
234 cycleClks = cycleTime / IDE_SYSCLK_NS;
235 cycleClks += (cycleTime % IDE_SYSCLK_NS) ? 1 : 0;
236
237 ideTimingRegs[unit].udidetcrReg = (0x01 << unit) | ((cycleClks-1) << ((!unit) ? 4 : 6)) ;
238
239 return true;
240}
241
242/*
243 *
244 *
245 */
246void AppleUltra33ATA::newDeviceSelected( IOATADevice *newDevice )
247{
248}
249
250
251/*
252 *
253 *
254 */
255bool AppleUltra33ATA::selectTiming( UInt32 unit, ATATimingProtocol timingProtocol )
256{
257 Ultra646Regs *cfgRegs;
258 UInt32 cfgByte;
259
260 cfgRegs = &ideTimingRegs[unit];
261
262 if ( busNum == 0 )
263 {
264 pciWriteByte( kUltra646CMDTIM, cfgRegs->cmdtimReg );
265
266 if ( unit == 0 )
267 {
268 pciWriteByte( kUltra646ARTTIM0, cfgRegs->arttimReg );
269
270 if ( timingProtocol == kATATimingPIO )
271 {
272 cfgByte = pciReadByte( kUltra646CNTRL );
273 cfgByte &= ~kUltra646CNTRL_Drive0ReadAhead;
274 cfgByte |= cfgRegs->cntrlReg;
275 pciWriteByte( kUltra646CNTRL, cfgByte );
276
277 pciWriteByte( kUltra646DRWTIM0, cfgRegs->drwtimRegPIO );
278 }
279 else if ( timingProtocol == kATATimingDMA )
280 {
281 pciWriteByte( kUltra646DRWTIM0, cfgRegs->drwtimRegDMA );
282 }
283 else if ( timingProtocol == kATATimingUltraDMA33 )
284 {
285 cfgByte = pciReadByte( kUltra646UDIDETCR0 );
286 cfgByte &= ~(kUltra646UDIDETCR0_Drive0UDMACycleTime | kUltra646UDIDETCR0_Drive0UDMAEnable);
287 cfgByte |= cfgRegs->udidetcrReg;
288 pciWriteByte( kUltra646UDIDETCR0, cfgByte );
289 }
290 }
291 else
292 {
293 pciWriteByte( kUltra646ARTTIM1, cfgRegs->arttimReg );
294
295 if ( timingProtocol == kATATimingPIO )
296 {
297 cfgByte = pciReadByte( kUltra646CNTRL );
298 cfgByte &= ~kUltra646CNTRL_Drive1ReadAhead;
299 cfgByte |= cfgRegs->cntrlReg;
300 pciWriteByte( kUltra646CNTRL, cfgByte );
301
302 pciWriteByte( kUltra646DRWTIM1, cfgRegs->drwtimRegPIO );
303 }
304 else if ( timingProtocol == kATATimingDMA )
305 {
306 pciWriteByte( kUltra646DRWTIM1, cfgRegs->drwtimRegDMA );
307 }
308 else if ( timingProtocol == kATATimingUltraDMA33 )
309 {
310 cfgByte = pciReadByte( kUltra646UDIDETCR0 );
311 cfgByte &= ~(kUltra646UDIDETCR0_Drive1UDMACycleTime | kUltra646UDIDETCR0_Drive1UDMAEnable);
312 cfgByte |= cfgRegs->udidetcrReg;
313 pciWriteByte( kUltra646UDIDETCR0, cfgByte );
314 }
315 }
316 }
317 else
318 {
319 pciWriteByte( kUltra646CMDTIM, cfgRegs->cmdtimReg );
320
321 if ( unit == 0 )
322 {
323 cfgByte = pciReadByte( kUltra646ARTTIM23 );
324 cfgByte &= ~(kUltra646ARTTIM23_Drive2ReadAhead | kUltra646ARTTIM23_AddrSetup);
325 cfgByte |= (cfgRegs->cntrlReg >> 4) | cfgRegs->arttimReg;
326 pciWriteByte( kUltra646ARTTIM23, cfgByte );
327
328 if ( timingProtocol == kATATimingPIO )
329 {
330 pciWriteByte( kUltra646DRWTIM2, cfgRegs->drwtimRegPIO );
331 }
332 else if ( timingProtocol == kATATimingDMA )
333 {
334 pciWriteByte( kUltra646DRWTIM1, cfgRegs->drwtimRegDMA );
335 }
336 else if ( timingProtocol == kATATimingUltraDMA33 )
337 {
338 cfgByte = pciReadByte( kUltra646UDIDETCR1 );
339 cfgByte &= ~(kUltra646UDIDETCR1_Drive2UDMACycleTime | kUltra646UDIDETCR1_Drive2UDMAEnable);
340 cfgByte |= cfgRegs->udidetcrReg;
341 pciWriteByte( kUltra646UDIDETCR1, cfgByte );
342 }
343 }
344 else
345 {
346 cfgByte = pciReadByte( kUltra646ARTTIM23 );
347 cfgByte &= ~(kUltra646ARTTIM23_Drive3ReadAhead | kUltra646ARTTIM23_AddrSetup);
348 cfgByte |= (cfgRegs->cntrlReg >> 4) | cfgRegs->arttimReg;
349 pciWriteByte( kUltra646ARTTIM23, cfgByte );
350
351 if ( timingProtocol == kATATimingPIO )
352 {
353 pciWriteByte( kUltra646DRWTIM3, cfgRegs->drwtimRegPIO );
354 }
355 else if ( timingProtocol == kATATimingDMA )
356 {
357 pciWriteByte( kUltra646DRWTIM3, cfgRegs->drwtimRegDMA );
358 }
359 else if ( timingProtocol == kATATimingUltraDMA33 )
360 {
361 cfgByte = pciReadByte( kUltra646UDIDETCR1 );
362 cfgByte &= ~(kUltra646UDIDETCR1_Drive3UDMACycleTime | kUltra646UDIDETCR1_Drive3UDMAEnable);
363 cfgByte |= cfgRegs->udidetcrReg;
364 pciWriteByte( kUltra646UDIDETCR1, cfgByte );
365 }
366 }
367 }
368
369 return true;
370}
371
372
373/*
374 *
375 *
376 */
377void AppleUltra33ATA::interruptOccurred()
378{
379 UInt32 intReg;
380 UInt32 cfgReg;
381
382 intReg = (busNum == 0) ? kUltra646CFR : kUltra646ARTTIM23;
383 cfgReg = pciReadByte( intReg );
384 pciWriteByte( intReg, cfgReg );
385
386 intReg = (busNum == 0) ? kUltra646BMIDESR0 : kUltra646BMIDESR1;
387 cfgReg = pciReadByte( intReg );
388 pciWriteByte( intReg, cfgReg );
389
390 super::interruptOccurred();
391
392 enableControllerInterrupts();
393}
394
395/*
396 *
397 *
398 */
399bool AppleUltra33ATA::programDma( IOATAStandardCommand *cmd )
400{
401 IOMemoryDescriptor *memoryDesc;
402 IOPhysicalSegment physSeg;
403 IOByteCount offset;
404 UInt32 i;
405 UInt32 bytesLeft;
406 UInt32 len;
407 Ultra646Descriptor *dmaDesc;
408 UInt32 startSeg, endSeg;
409
410 cmd->getPointers( &memoryDesc, &dmaReqLength, &dmaIsWrite );
411
412 if ( dmaReqLength == 0 )
413 {
414 return true;
415 }
416
417 offset = 0;
418
419 dmaDesc = dmaDescriptors;
420
421 bytesLeft = dmaReqLength;
422
423 for (i = 0; i < numDescriptors-1; i++, dmaDesc++ )
424 {
425 if ( dmaMemoryCursor->getPhysicalSegments( memoryDesc, offset, &physSeg, 1 ) != 1 )
426 {
427 break;
428 }
429
430 startSeg = (physSeg.location & ~0xffff);
431 endSeg = (physSeg.location + physSeg.length - 1) & ~0xffff;
432
433 OSWriteSwapInt32( &dmaDesc->start, 0, physSeg.location);
434
435 if ( startSeg == endSeg )
436 {
437 OSWriteSwapInt32( &dmaDesc->length, 0, physSeg.length );
438 }
439 else
440 {
441 len = (-physSeg.location & 0xffff);
442 OSWriteSwapInt32( &dmaDesc->length, 0, len );
443 dmaDesc++;
444 i++;
445 OSWriteSwapInt32( &dmaDesc->start, 0, physSeg.location + len );
446 OSWriteSwapInt32( &dmaDesc->length, 0, physSeg.length - len );
447 }
448
449 bytesLeft -= physSeg.length;
450 offset += physSeg.length;
451 }
452
453 if ( bytesLeft != 0 )
454 {
455 return false;
456 }
457
458 /*
459 * Note: ATAPI always transfers even byte-counts. Send the extra byte to/from the bit-bucket
460 * if the requested transfer length is odd.
461 */
462 if ( dmaReqLength & 1 )
463 {
464 if ( i == numDescriptors ) return false;
465
466 dmaDesc++;
467 OSWriteSwapInt32( &dmaDesc->start, 0, bitBucketAddrPhys );
468 OSWriteSwapInt32( &dmaDesc->length, 0, 1 );
469 }
470
471
472 dmaDesc--;
473 dmaDesc->length |= 0x80;
474
475 pciWriteLong( ((busNum == 0) ? kUltra646DTPR0 : kUltra646DTPR1), dmaDescriptorsPhys );
476
477 return true;
478}
479
480/*
481 *
482 *
483 */
484bool AppleUltra33ATA::startDma( IOATAStandardCommand * )
485{
486 UInt32 reg;
487 UInt32 cfgReg;
488 UInt32 startMask;
489 UInt32 writeMask;
490
491 if ( dmaReqLength != 0 )
492 {
493 reg = (busNum == 0) ? kUltra646BMIDECR0 : kUltra646BMIDECR1;
494 startMask = (busNum == 0) ? kUltra646BMIDECR0_StartDMAPRI : kUltra646BMIDECR1_StartDMASDY;
495 writeMask = (busNum == 0) ? kUltra646BMIDECR0_PCIWritePRI : kUltra646BMIDECR1_PCIWriteSDY;
496 cfgReg = pciReadByte( reg );
497 cfgReg &= ~writeMask;
498 cfgReg |= startMask | ((dmaIsWrite == false) ? writeMask : 0);
499 pciWriteByte( reg, cfgReg );
500 }
501 return true;
502}
503
504/*
505 *
506 *
507 */
508bool AppleUltra33ATA::stopDma( IOATAStandardCommand *, UInt32 *transferCount )
509{
510 UInt32 reg;
511 UInt32 cfgReg;
512 UInt32 startMask;
513
514 *transferCount = 0;
515
516 if ( dmaReqLength == 0 )
517 {
518 return true;
519 }
520
521 reg = (busNum == 0) ? kUltra646BMIDECR0 : kUltra646BMIDECR1;
522 startMask = (busNum == 0) ? kUltra646BMIDECR0_StartDMAPRI : kUltra646BMIDECR1_StartDMASDY;
523 cfgReg = pciReadByte( reg );
524 cfgReg &= ~startMask;
525 pciWriteByte( reg, cfgReg );
526
527 *transferCount = dmaReqLength;
528
529 return true;
530}
531
532/*
533 *
534 *
535 */
536bool AppleUltra33ATA::checkDmaActive()
537{
538 UInt32 reg;
539 UInt32 cfgReg;
540 UInt32 activeMask;
541
542 reg = (busNum == 0) ? kUltra646BMIDESR0 : kUltra646BMIDESR1;
543 activeMask = (busNum == 0) ? kUltra646BMIDESR0_DMAActivePRI : kUltra646BMIDESR1_DMAActiveSDY;
544
545 cfgReg = pciReadByte( reg );
546
547 return ((cfgReg & activeMask) != 0);
548}
549
550/*
551 *
552 *
553 */
554bool AppleUltra33ATA::resetDma()
555{
556 UInt32 reg;
557 UInt32 cfgReg;
558 UInt32 startMask;
559
560 reg = (busNum == 0) ? kUltra646BMIDECR0 : kUltra646BMIDECR1;
561 startMask = (busNum == 0) ? kUltra646BMIDECR0_StartDMAPRI : kUltra646BMIDECR1_StartDMASDY;
562
563 cfgReg = pciReadByte( reg );
564 cfgReg &= ~startMask;
565 pciWriteByte( reg, cfgReg );
566
567 return true;
568}
569
570/*
571 *
572 *
573 */
574void AppleUltra33ATA::disableControllerInterrupts()
575{
576 interruptEventSource->disable();
577}
578
579/*
580 *
581 *
582 */
583void AppleUltra33ATA::enableControllerInterrupts()
584{
585 interruptEventSource->enable();
586}
587
588/*
589 *
590 *
591 */
592void AppleUltra33ATA::free()
593{
594 UInt32 i;
595
596 if ( interruptEventSource != 0 )
597 {
598 interruptEventSource->disable();
599 interruptEventSource->release();
600 }
601
602 for (i = 0; i < 2; i++ )
603 {
604 if ( ioMapATA[i] != 0 ) ioMapATA[i]->release();
605 }
606
607 if ( dmaDescriptors != 0 )
608 {
609 kfree( (vm_offset_t)dmaDescriptors, page_size );
610 }
611}
612
613/*
614 *
615 *
616 */
617void AppleUltra33ATA::writeATAReg( UInt32 regIndex, UInt32 regValue )
618{
619 if ( regIndex == 0 )
620 {
621 *(volatile UInt16 *)ioBaseATA[0] = regValue;
622 }
623 else if ( regIndex < kATARegDeviceControl )
624 {
625 *((volatile UInt8 *)ioBaseATA[0] + regIndex) = regValue;
626 }
627 else
628 {
629 *((volatile UInt8 *)ioBaseATA[1] + regIndex - kATARegDeviceControl + 2) = regValue;
630 }
631 eieio();
632}
633
634UInt32 AppleUltra33ATA::readATAReg( UInt32 regIndex )
635{
636 if ( regIndex == 0 )
637 {
638 return *(volatile UInt16 *)ioBaseATA[0];
639 }
640 else if ( regIndex < kATARegDeviceControl )
641 {
642 return *((volatile UInt8 *)ioBaseATA[0] + regIndex);
643 }
644
645 return *((volatile UInt8 *)ioBaseATA[1] + regIndex - kATARegDeviceControl + 2);
646}
647
648/*
649 *
650 *
651 */
652UInt32 AppleUltra33ATA::pciReadByte( UInt32 reg )
653{
654 volatile union
655 {
656 unsigned long word;
657 unsigned char byte[4];
658 } data;
659
660 data.word = provider->configRead32( reg );
661 return data.byte[3 - (reg & 0x03)];
662}
663
664void AppleUltra33ATA::pciWriteByte( UInt32 reg, UInt32 value )
665{
666 volatile union
667 {
668 unsigned long word;
669 unsigned char byte[4];
670 } data;
671
672 UInt32 regWord;
673
674 regWord = reg & ~0x03;
675
676 data.word = provider->configRead32( regWord );
677 data.word = OSReadSwapInt32( &data.word, 0 );
678
679 switch (regWord)
680 {
681 case kUltra646CFR:
682 data.byte[kUltra646CFR & 0x03] &= ~kUltra646CFR_IDEIntPRI;
683 break;
684 case kUltra646DRWTIM0:
685 data.byte[kUltra646ARTTIM23 & 0x03] &= ~kUltra646ARTTIM23_IDEIntSDY;
686 break;
687 case kUltra646BMIDECR0:
688 data.byte[kUltra646MRDMODE & 0x03 ] &= ~(kUltra646MRDMODE_IDEIntPRI | kUltra646MRDMODE_IDEIntSDY);
689 data.byte[kUltra646BMIDESR0 & 0x03] &= ~(kUltra646BMIDESR0_DMAIntPRI | kUltra646BMIDESR0_DMAErrorPRI);
690 break;
691 case kUltra646BMIDECR1:
692 data.byte[kUltra646BMIDESR1 & 0x03] &= ~(kUltra646BMIDESR1_DMAIntSDY | kUltra646BMIDESR1_DMAErrorSDY);
693 break;
694 }
695 data.byte[reg & 0x03] = value;
696
697 data.word = OSReadSwapInt32(&data.word, 0);
698
699 provider->configWrite32( regWord, data.word );
700}
701
702UInt32 AppleUltra33ATA::pciReadLong( UInt32 reg )
703{
704 return provider->configRead32( reg );
705}
706
707void AppleUltra33ATA::pciWriteLong( UInt32 reg, UInt32 value )
708{
709 provider->configWrite32( reg, value );
710}
711
712/* These overrides take care of OpenFirmware referring to the controller
713 * as a child of the PCI device, "ata-4" */
714
715bool AppleUltra33ATA::attach( IOService * provider )
716{
717 if ( super::attach(provider) )
718 {
719 // assumes the first child determines the path OF uses to reference the controller
720 pathProvider = OSDynamicCast(IOService, provider->getChildEntry(gIODTPlane));
721
722 if ( pathProvider )
723 {
724 setLocation(pathProvider->getLocation(gIODTPlane), gIODTPlane);
725 setName(pathProvider->getName(gIODTPlane), gIODTPlane);
726 attachToParent(provider, gIODTPlane);
727 pathProvider->retain();
728 pathProvider->detachFromParent(provider, gIODTPlane);
729 }
730
731 return true;
732 }
733
734 return false;
735}
736
737void AppleUltra33ATA::detach( IOService * provider )
738{
739 if ( pathProvider )
740 {
741 detachFromParent(provider, gIODTPlane);
742 pathProvider->attachToParent(provider, gIODTPlane);
743 pathProvider->release();
744 }
745
746 super::detach(provider);
747}