]> git.saurik.com Git - apple/xnu.git/blame - iokit/Drivers/ata/drvApplePIIXATA/AppleATAPIIX.cpp
xnu-201.42.3.tar.gz
[apple/xnu.git] / iokit / Drivers / ata / drvApplePIIXATA / AppleATAPIIX.cpp
CommitLineData
1c79356b
A
1/*
2 * Copyright (c) 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 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
24 *
25 * AppleATAPIIX.cpp - ATA controller driver for Intel PIIX/PIIX3/PIIX4.
26 *
27 * HISTORY
28 *
29 */
30
31#include <architecture/i386/pio.h>
32#include <IOKit/IOService.h>
33#include <IOKit/assert.h>
34#include "AppleATAPIIX.h"
35#include "AppleATAPIIXTiming.h"
36
37extern pmap_t kernel_pmap; // for pmap_extract()
38
39// Resources shared between the two IDE channels are protected
40// by this mutex.
41//
42static IOLock * gPIIXLock = 0;
43#define PIIX_LOCK IOLockLock(gPIIXLock)
44#define PIIX_UNLOCK IOLockUnlock(gPIIXLock)
45
46#define IOREG(x) (ioBMRange + PIIX_IO_ ## x)
47
48#define CHECK_UNIT(drv) assert(drv < 2)
49
50#ifdef DEBUG_XXX
51#define DLOG(fmt, args...) IOLog(fmt, ## args)
52#else
53#define DLOG(fmt, args...)
54#endif
55
56//--------------------------------------------------------------------------
57// Metaclass macro.
58//
59#undef super
60#define super IOATAStandardDriver
61
62OSDefineMetaClassAndStructorsWithInit( AppleATAPIIX, IOATAStandardDriver,
63 AppleATAPIIX::initialize() )
64
65//--------------------------------------------------------------------------
66// PIIX class initializer.
67//
68void AppleATAPIIX::initialize()
69{
70 gPIIXLock = IOLockAlloc();
71 assert(gPIIXLock);
72}
73
74//--------------------------------------------------------------------------
75// Defines a table of supported PIIX device types, listing their
76// PCI ID, and a name string. Also supply some utility functions
77// to locate a table entry based on an arbitrary PCI ID.
78//
79static struct {
80 UInt32 CFID;
81 const char * name;
82} piixDeviceTable[] = {{ PCI_ID_PIIX, "PIIX" },
83 { PCI_ID_PIIX3, "PIIX3" },
84 { PCI_ID_PIIX4, "PIIX4" },
85 { PCI_ID_ICH, "ICH" },
86 { PCI_ID_ICH0, "ICH0" },
87 { PCI_ID_ICH2_M, "ICH2-M" },
88 { PCI_ID_ICH2, "ICH2" },
89 { PCI_ID_NONE, NULL }};
90
91static const char *
92PIIXGetName(UInt32 pciID)
93{
94 for (int i = 0; piixDeviceTable[i].name; i++) {
95 if (piixDeviceTable[i].CFID == pciID)
96 return piixDeviceTable[i].name;
97 }
98 return 0;
99}
100
101static bool
102PIIXVerifyID(UInt32 pciID)
103{
104 return (PIIXGetName(pciID) == 0) ? false : true;
105}
106
107//--------------------------------------------------------------------------
108// A hack to modify our PCI nub to have two interrupts.
109// This code was borrowed from the setupIntelPIC() function
110// in iokit/Families/IOPCIBus/IOPCIBridge.cpp.
111//
112static void setupProviderInterrupts(IOPCIDevice * nub, long irq_p, long irq_s)
113{
114 OSArray * controller;
115 OSArray * specifier;
116 OSData * tmpData;
117 extern OSSymbol * gIntelPICName;
118
119 do {
120 // Create the interrupt specifer array.
121 specifier = OSArray::withCapacity(2);
122 if (!specifier)
123 break;
124
125 tmpData = OSData::withBytes(&irq_p, sizeof(irq_p));
126 if (tmpData) {
127 specifier->setObject(tmpData);
128 tmpData->release();
129 }
130 tmpData = OSData::withBytes(&irq_s, sizeof(irq_s));
131 if (tmpData) {
132 specifier->setObject(tmpData);
133 tmpData->release();
134 }
135
136 controller = OSArray::withCapacity(2);
137 if (controller) {
138 controller->setObject(gIntelPICName);
139 controller->setObject(gIntelPICName);
140
141 // Put the two arrays into the property table.
142 nub->setProperty(gIOInterruptControllersKey, controller);
143 controller->release();
144 }
145 nub->setProperty(gIOInterruptSpecifiersKey, specifier);
146 specifier->release();
147
148 } while( false );
149}
150
151//--------------------------------------------------------------------------
152// A static member function that returns the IDE channel for the
153// current driver instance, and also registers the interrupts in
154// the IOPCIDevice nub.
155//
156int AppleATAPIIX::PIIXGetChannel(IOPCIDevice * provider)
157{
158 static bool primaryRegistered = false;
159 int rc;
160 extern OSSymbol * gIntelPICName;
161
162 PIIX_LOCK;
163
164 if (primaryRegistered == false) {
165 rc = PIIX_CHANNEL_PRIMARY;
166 primaryRegistered = true;
167
168 // Is this necessary?
169 waitForService(resourceMatching(gIntelPICName));
170
171 setupProviderInterrupts(provider, PIIX_P_IRQ, PIIX_S_IRQ);
172 }
173 else {
174 rc = PIIX_CHANNEL_SECONDARY;
175 }
176
177 PIIX_UNLOCK;
178
179 if (rc == PIIX_CHANNEL_SECONDARY) IOSleep(20);
180
181 return rc;
182}
183
184//--------------------------------------------------------------------------
185// Private function: _getIDERanges
186//
187// Setup the variables that stores the start of the Command and Control
188// block in I/O space. The variable 'channel' must have been previously
189// set. These ISA I/O ranges are implicit and does not show up in PCI
190// config space.
191//
192bool AppleATAPIIX::_getIDERanges(IOPCIDevice * provider)
193{
194 ioCmdRange = (channel == PIIX_CHANNEL_PRIMARY) ?
195 PIIX_P_CMD_ADDR : PIIX_S_CMD_ADDR;
196
197 ioCtlRange = (channel == PIIX_CHANNEL_PRIMARY) ?
198 PIIX_P_CTL_ADDR : PIIX_S_CTL_ADDR;
199
200 DLOG("%s: ioCmdRange - %04x\n", getName(), ioCmdRange);
201 DLOG("%s: ioCtlRange - %04x\n", getName(), ioCtlRange);
202
203 return true;
204}
205
206//--------------------------------------------------------------------------
207// Private function: _getBMRange
208//
209// Determine the start of the I/O mapped Bus-Master registers.
210// This range is defined by PCI config space register PIIX_PCI_BMIBA.
211//
212bool AppleATAPIIX::_getBMRange(IOPCIDevice * provider)
213{
214 UInt32 bmiba;
215
216 bmiba = provider->configRead32(PIIX_PCI_BMIBA);
217 if ((bmiba & PIIX_PCI_BMIBA_RTE) == 0) {
218 IOLog("%s: PCI memory range 0x%02x (0x%08lx) is not an I/O range\n",
219 getName(), PIIX_PCI_BMIBA, bmiba);
220 return false;
221 }
222
223 bmiba &= PIIX_PCI_BMIBA_MASK; // get the address portion
224
225 // If bmiba is zero, it is likely that the user has elected to
226 // turn off PCI IDE support in the BIOS.
227 //
228 if (bmiba == 0)
229 return false;
230
231 if (channel == PIIX_CHANNEL_SECONDARY)
232 bmiba += PIIX_IO_BM_OFFSET;
233
234 ioBMRange = (UInt16) bmiba;
235
236 DLOG("%s: ioBMRange - %04x\n", getName(), ioBMRange);
237
238 return true;
239}
240
241//--------------------------------------------------------------------------
242// Private function: _resetTimings()
243//
244// Reset all timing registers to the slowest (most compatible) timing.
245// UDMA modes are disabled. We take a lock to prevent the other IDE
246// channel from modifying the shared PCI config space.
247//
248bool AppleATAPIIX::_resetTimings()
249{
250 union {
251 UInt32 b32;
252 struct {
253 UInt16 pri;
254 UInt16 sec;
255 } b16;
256 } timing;
257
258 UInt32 udmaControl;
259
260 PIIX_LOCK;
261
262 timing.b32 = provider->configRead32(PIIX_PCI_IDETIM);
263 udmaControl = provider->configRead32(PIIX_PCI_UDMACTL);
264
265 // Set slowest timing, and disable UDMA. Only modify the flags
266 // associated with the local channel.
267 //
268 switch (channel) {
269 case PIIX_CHANNEL_PRIMARY:
270 timing.b16.pri &= PIIX_PCI_IDETIM_IDE;
271 udmaControl &= ~(PIIX_PCI_UDMACTL_PSDE0 | PIIX_PCI_UDMACTL_PSDE1);
272 break;
273
274 case PIIX_CHANNEL_SECONDARY:
275 timing.b16.sec &= PIIX_PCI_IDETIM_IDE;
276 udmaControl &= ~(PIIX_PCI_UDMACTL_SSDE0 | PIIX_PCI_UDMACTL_SSDE1);
277 break;
278 }
279
280 provider->configWrite32(PIIX_PCI_UDMACTL, udmaControl);
281 provider->configWrite32(PIIX_PCI_IDETIM, timing.b32);
282
283 // FIXME
284 // No support for ATA/66 or ATA/100 modes. Set this register
285 // to 0 (new in ICH2) to disable those faster timings.
286 //
287 provider->configWrite32(PIIX_PCI_IDECONFIG, 0);
288
289 PIIX_UNLOCK;
290
291 return true;
292}
293
294//--------------------------------------------------------------------------
295// Private function: _allocatePRDTable()
296//
297// Allocate the physical region descriptor (PRD) table. The physical
298// address of this table is stored in 'prdTablePhys'. Look at Intel
299// documentation for the alignment requirements.
300//
301bool AppleATAPIIX::_allocatePRDTable()
302{
303 prdTable = (prdEntry_t *) IOMallocAligned(PRD_TABLE_SIZE, PAGE_SIZE);
304 if (!prdTable)
305 return false;
306
307 prdTablePhys = (UInt32) pmap_extract(kernel_pmap, (vm_offset_t) prdTable);
308
309 bzero(prdTable, PRD_TABLE_SIZE);
310
311 return true;
312}
313
314//--------------------------------------------------------------------------
315// Private function: _deallocatePRDTable()
316//
317void AppleATAPIIX::_deallocatePRDTable()
318{
319 IOFreeAligned(prdTable, PRD_TABLE_SIZE);
320 prdTable = NULL;
321 prdTablePhys = 0;
322}
323
324//--------------------------------------------------------------------------
325// Function inherited from IOATAController.
326//
327// Configure the driver/controller. This is the first function called by
328// our superclass, in its start() function, to initialize the controller
329// hardware.
330//
331bool
332AppleATAPIIX::configure(IOService * forProvider,
333 ATAControllerInfo * controllerInfo)
334{
335 UInt32 reg;
336
337// IOSleep(1000);
338
0b4e3aa0 339 provider = (IOPCIDevice *)forProvider->metaCast("IOPCIDevice");
1c79356b
A
340 if (!provider)
341 return false;
342
343 // Superclass performs an exclusive open on the provider, we close
344 // it to allow more than one instance of this driver to attach to
345 // the same PCI nub. We should maintain an non-exclusive open on
346 // the provider.
347 //
348 provider->close(this);
349
350 // Determine the type of PIIX controller. Save the controller's
351 // PCI ID in pciCFID.
352 //
353 pciCFID = provider->configRead32(PIIX_PCI_CFID);
354 if (PIIXVerifyID(pciCFID) == false) {
355 IOLog("%s: Unknown PCI IDE controller (0x%08lx)\n",
356 getName(),
357 pciCFID);
358 return false;
359 }
360
361 // Determine our IDE channel, primary or secondary.
362 //
363 channel = PIIXGetChannel(provider);
364
365 _getIDERanges(provider);
366
367 IOLog("%s: %s %s IDE controller, 0x%x, irq %d\n",
368 getName(),
369 (channel == PIIX_CHANNEL_PRIMARY) ? "Primary" : "Secondary",
370 PIIXGetName(pciCFID),
371 ioCmdRange,
372 (channel == PIIX_CHANNEL_PRIMARY) ? PIIX_P_IRQ : PIIX_S_IRQ);
373
374 // Check the I/O Space Enable bit in the PCI command register.
375 // This is the master enable bit for the PIIX controller.
376 // Each IDE channel also has its own enable bit, which is
377 // checked later.
378 //
379 reg = provider->configRead32(PIIX_PCI_PCICMD);
380 if ((reg & PIIX_PCI_PCICMD_IOSE) == 0) {
381 IOLog("%s: PCI IDE controller is not enabled\n", getName());
382 return false;
383 }
384
385 // Set BME bit to enable bus-master.
386 //
387 if ((reg & PIIX_PCI_PCICMD_BME) == 0) {
388 reg |= PIIX_PCI_PCICMD_BME;
389 PIIX_LOCK;
390 provider->configWrite32(PIIX_PCI_PCICMD, reg);
391 PIIX_UNLOCK;
392 }
393
394 // Fetch the corresponding primary/secondary IDETIM register and
395 // check the individual channel enable bit.
396 //
397 reg = provider->configRead32(PIIX_PCI_IDETIM);
398 if (channel == PIIX_CHANNEL_SECONDARY)
399 reg >>= 16; // PIIX_PCI_IDETIM + 2 for secondary channel
400
401 if ((reg & PIIX_PCI_IDETIM_IDE) == 0) {
402 IOLog("%s: %s PCI IDE channel is not enabled\n",
403 getName(),
404 (channel == PIIX_CHANNEL_PRIMARY) ? "Primary" : "Secondary");
405 return false;
406 }
407
408 // Locate and add the I/O mapped bus-master registers to
409 // ioRange[] array.
410 //
411 if (_getBMRange(provider) == false) {
412 IOLog("%s: Bus master I/O range is invalid\n", getName());
413 return false;
414 }
415
416 // Allocate page-aligned memory for the PRD table.
417 //
418 if (_allocatePRDTable() == false) {
419 IOLog("%s: unable to allocate descriptor table\n", getName());
420 return false;
421 }
422
423 // Allocate a cursor object to generate the scatter-gather list
424 // for each transfer request. Maximum segment size is set to 64K.
425 // However, there is no way to indicate our requirement that each
426 // memory segment cannot cross a 64K boundary. We have to do this
427 // manually.
428 //
429 prdCursor = IOLittleMemoryCursor::withSpecification(64 * 1024, 0xffffffff);
430 if (prdCursor == 0)
431 return false;
432
433 // Attach an interruptEventSource to handle HW interrupts.
434 // Must do this after PIIXGetChannel(), since thats where the
435 // provider's interrupt property is set by setupProviderInterrupts().
436
437 interruptEventSource = IOInterruptEventSource::interruptEventSource(
438 (OSObject *) this,
439 (IOInterruptEventAction) &AppleATAPIIX::interruptOccurred,
440 (IOService *) provider,
441 (channel == PIIX_CHANNEL_PRIMARY) ? 0 : 1);
442 if (interruptEventSource == 0) {
443 IOLog("%s: unable to create an IOInterruptEventSource object\n",
444 getName());
445 return false;
446 }
447
448 disableControllerInterrupts();
449
450 getWorkLoop()->addEventSource(interruptEventSource);
451
452 // Revert to default (compatible) timing.
453 //
454 _resetTimings();
455
456 controllerInfo->maxDevicesSupported = 2;
457 controllerInfo->devicePrivateDataSize = 0;
458 controllerInfo->commandPrivateDataSize = 0;
459 controllerInfo->disableCancelCommands = false;
460
461
462 DLOG("AppleATAPIIX::%s() completed successfully\n", __FUNCTION__);
463
464 return true;
465}
466
467//--------------------------------------------------------------------------
468//
469//
470bool AppleATAPIIX::provideProtocols(enum ATAProtocol * protocolsSupported)
471{
472 return false;
473}
474
475//--------------------------------------------------------------------------
476//
477//
478bool AppleATAPIIX::provideTimings(UInt32 * numTimings,
479 ATATiming * timingsSupported)
480{
481 return false;
482}
483
484//--------------------------------------------------------------------------
485// Determine the timing selection based on the ATATiming structure given.
486//
487bool AppleATAPIIX::calculateTiming(UInt32 unit, ATATiming * pTiming)
488{
489 int i;
490 PIIXProtocol protocol = ataToPIIXProtocol(pTiming->timingProtocol);
491
492 DLOG("AppleATAPIIX::%s() - unit:%ld protocol:%d minCycles:%ld\n",
493 __FUNCTION__, unit, protocol, pTiming->minDataCycle);
494
495 CHECK_UNIT(unit);
496
497 timings[unit].validTimings[protocol] = 0;
498
499 switch (protocol) {
500
501 case kPIIXProtocolPIO:
502
503 for (i = 0; i < PIIXPIOTimingTableSize; i++)
504 {
505 if (PIIXPIOTimingTable[i].pioMode == _NVM_)
506 continue;
507
508 if (PIIXPIOTimingTable[i].cycle < pTiming->minDataCycle)
509 break;
510
511 timings[unit].validTimings[protocol] = i;
512 }
513 break;
514
515 case kPIIXProtocolDMA:
516
517 for (i = 0; i < PIIXPIOTimingTableSize; i++)
518 {
519 if (PIIXPIOTimingTable[i].mwDMAMode == _NVM_)
520 continue;
521
522 if (PIIXPIOTimingTable[i].cycle < pTiming->minDataCycle)
523 break;
524
525 timings[unit].validTimings[protocol] = i;
526 }
527 break;
528
529 case kPIIXProtocolUDMA33:
530
531 for (i = 0; i < PIIXUDMATimingTableSize; i++)
532 {
533 if (PIIXUDMATimingTable[i].strobe < pTiming->minDataCycle)
534 break;
535
536 timings[unit].validTimings[protocol] = i;
537 }
538 break;
539
540 default:
541 return false;
542 }
543
544 timings[unit].validFlag |= (1 << protocol);
545
546 return true;
547}
548
549//--------------------------------------------------------------------------
550// Setup the timing register for the given timing protocol.
551//
552bool AppleATAPIIX::selectTiming(UInt32 unit,
553 ATATimingProtocol timingProtocol)
554{
555 bool ret = false;
556 UInt8 pciConfig[256];
557 PIIXProtocol protocol = ataToPIIXProtocol(timingProtocol);
558
559 DLOG("AppleATAPIIX::%s() - unit:%ld protocol:%d\n",
560 __FUNCTION__, unit, protocol);
561
562 CHECK_UNIT(unit);
563
564 PIIX_LOCK;
565
566 do {
567 if (protocol >= kPIIXProtocolLast)
568 break;
569
570 if (PIIX_PROTOCOL_IS_VALID(protocol) == 0) {
571
572 // superclass error, calculateTiming() was not called
573 // before calling selectTiming().
574
575 IOLog("%s: timing protocol selected is invalid\n", getName());
576 break;
577 }
578
579 if (!_readPCIConfigSpace(pciConfig) ||
580 !_selectTiming(unit, protocol, pciConfig) ||
581 !_writePCIConfigSpace(pciConfig))
582 break;
583
584 ret = true;
585 }
586 while (0);
587
588 PIIX_UNLOCK;
589
590 return ret;
591}
592
593//--------------------------------------------------------------------------
594// Setup the timing registers.
595//
596bool AppleATAPIIX::_selectTiming(UInt32 unit,
597 PIIXProtocol protocol,
598 UInt8 * pciConfig)
599{
600 UInt8 isp, rtc;
601 UInt8 index, dma, pio;
602 bool dmaActive;
603 bool pioActive;
604 bool useCompatiblePIOTiming = false;
605 bool ret = true;
606 UInt16 * idetim;
607 UInt8 * sidetim = (UInt8 *) &pciConfig[PIIX_PCI_SIDETIM];
608 UInt8 * udmactl = (UInt8 *) &pciConfig[PIIX_PCI_UDMACTL];
609 UInt16 * udmatim = (UInt16 *) &pciConfig[PIIX_PCI_UDMATIM];
610
611 idetim = (channel == PIIX_CHANNEL_PRIMARY) ?
612 (UInt16 *) &pciConfig[PIIX_PCI_IDETIM] :
613 (UInt16 *) &pciConfig[PIIX_PCI_IDETIM_S];
614
615 switch (protocol) {
616 case kPIIXProtocolUDMA66:
617 // Not yet!
618 return false;
619
620 case kPIIXProtocolUDMA33:
621 if ((pciCFID == PCI_ID_PIIX) || (pciCFID == PCI_ID_PIIX3)) {
622 // Only PIIX4 (and newer devices) supports UDMA.
623 return false;
624 }
625 PIIX_DEACTIVATE_PROTOCOL(kPIIXProtocolDMA);
626 break;
627
628 case kPIIXProtocolDMA:
629 PIIX_DEACTIVATE_PROTOCOL(kPIIXProtocolUDMA33);
630 break;
631
632 case kPIIXProtocolPIO:
633 break;
634
635 default:
636 IOLog("%s: PIIX protocol not handled (%d)\n", getName(),
637 protocol);
638 return false;
639 }
640 PIIX_ACTIVATE_PROTOCOL(protocol);
641
642
643 if (PIIX_PROTOCOL_IS_ACTIVE(kPIIXProtocolUDMA33)) {
644
645 index = PIIX_GET_ACTIVE_TIMING(kPIIXProtocolUDMA33);
646
647 if (unit == 0) {
648 if (channel == PIIX_CHANNEL_PRIMARY) {
649 *udmactl |= PIIX_PCI_UDMACTL_PSDE0;
650 SET_REG_FIELD(*udmatim, PIIX_PCI_UDMATIM_PCT0,
651 PIIXUDMATimingTable[index].bits);
652 }
653 else {
654 *udmactl |= PIIX_PCI_UDMACTL_SSDE0;
655 SET_REG_FIELD(*udmatim, PIIX_PCI_UDMATIM_SCT0,
656 PIIXUDMATimingTable[index].bits);
657 }
658 }
659 else {
660 if (channel == PIIX_CHANNEL_PRIMARY) {
661 *udmactl |= PIIX_PCI_UDMACTL_PSDE1;
662 SET_REG_FIELD(*udmatim, PIIX_PCI_UDMATIM_PCT1,
663 PIIXUDMATimingTable[index].bits);
664 }
665 else {
666 *udmactl |= PIIX_PCI_UDMACTL_SSDE1;
667 SET_REG_FIELD(*udmatim, PIIX_PCI_UDMATIM_SCT1,
668 PIIXUDMATimingTable[index].bits);
669 }
670 }
671 }
672 else {
673 if (unit == 0) {
674 if (channel == PIIX_CHANNEL_PRIMARY) {
675 *udmactl &= ~PIIX_PCI_UDMACTL_PSDE0;
676 }
677 else {
678 *udmactl &= ~PIIX_PCI_UDMACTL_SSDE0;
679 }
680 }
681 else {
682 if (channel == PIIX_CHANNEL_PRIMARY) {
683 *udmactl &= ~PIIX_PCI_UDMACTL_PSDE1;
684 }
685 else {
686 *udmactl &= ~PIIX_PCI_UDMACTL_SSDE1;
687 }
688 }
689 }
690
691 dmaActive = PIIX_PROTOCOL_IS_ACTIVE(kPIIXProtocolDMA);
692 pioActive = PIIX_PROTOCOL_IS_ACTIVE(kPIIXProtocolPIO);
693
694 if (dmaActive || pioActive) {
695
696 dma = PIIX_GET_ACTIVE_TIMING(kPIIXProtocolDMA);
697 pio = PIIX_GET_ACTIVE_TIMING(kPIIXProtocolPIO);
698
699 // Early PIIX devices does not have a slave timing register.
700 // Rather than switching timing registers whenever a new
701 // drive was selected, We program in a (slower) timing that
702 // is acceptable for both drive0 and drive1.
703
704 if (pciCFID == PCI_ID_PIIX) {
705
706 unit = (unit ^ 1) & 1; // unit <- other drive unit
707
708 if (PIIX_PROTOCOL_IS_ACTIVE(kPIIXProtocolPIO)) {
709 if (!pioActive ||
710 (PIIX_GET_ACTIVE_TIMING(kPIIXProtocolPIO) < pio)) {
711 pio = PIIX_GET_ACTIVE_TIMING(kPIIXProtocolPIO);
712 }
713 pioActive = true;
714 }
715
716 if (PIIX_PROTOCOL_IS_ACTIVE(kPIIXProtocolDMA)) {
717 if (!dmaActive ||
718 (PIIX_GET_ACTIVE_TIMING(kPIIXProtocolDMA) < dma)) {
719 dma = PIIX_GET_ACTIVE_TIMING(kPIIXProtocolDMA);
720 }
721 dmaActive = true;
722 }
723
724 *idetim &= ~PIIX_PCI_IDETIM_SITRE; // disable slave timing
725 unit = 0;
726 }
727 else {
728 *idetim |= PIIX_PCI_IDETIM_SITRE; // enable slave timing
729 }
730
731 // Pick an index to the PIIXPIOTimingTable[] for the new
732 // timing selection.
733 //
734 if (dmaActive && pioActive) {
735
736 // Both PIO and DMA are active, select DMA timing to
737 // optimize DMA transfer.
738
739 index = dma; // pick DMA timing
740
741 if (pio < dma)
742 useCompatiblePIOTiming = true;
743 }
744 else if (dmaActive) {
745 index = dma;
746 }
747 else {
748 index = pio;
749 }
750
751 isp = PIIX_CLK_TO_ISP(PIIXPIOTimingTable[index].isp);
752 rtc = PIIX_CLK_TO_RTC(PIIXPIOTimingTable[index].rtc);
753
754 if (unit == 0) {
755 SET_REG_FIELD(*idetim, PIIX_PCI_IDETIM_ISP, isp);
756 SET_REG_FIELD(*idetim, PIIX_PCI_IDETIM_RTC, rtc);
757 if (useCompatiblePIOTiming)
758 *idetim |= PIIX_PCI_IDETIM_DTE0;
759 else
760 *idetim &= ~PIIX_PCI_IDETIM_DTE0;
761
762 if (pciCFID == PCI_ID_PIIX) {
763 if (useCompatiblePIOTiming)
764 *idetim |= PIIX_PCI_IDETIM_DTE1;
765 else
766 *idetim &= ~PIIX_PCI_IDETIM_DTE1;
767 }
768 }
769 else {
770 if (channel == PIIX_CHANNEL_PRIMARY) {
771 SET_REG_FIELD(*sidetim, PIIX_PCI_SIDETIM_PISP1, isp);
772 SET_REG_FIELD(*sidetim, PIIX_PCI_SIDETIM_PRTC1, rtc);
773 }
774 else {
775 SET_REG_FIELD(*sidetim, PIIX_PCI_SIDETIM_SISP1, isp);
776 SET_REG_FIELD(*sidetim, PIIX_PCI_SIDETIM_SRTC1, rtc);
777 }
778 if (useCompatiblePIOTiming)
779 *idetim |= PIIX_PCI_IDETIM_DTE1;
780 else
781 *idetim &= ~PIIX_PCI_IDETIM_DTE1;
782 }
783
784 *idetim |= (PIIX_PCI_IDETIM_TIME0 |
785 PIIX_PCI_IDETIM_PPE0 |
786 PIIX_PCI_IDETIM_IE0 |
787 PIIX_PCI_IDETIM_TIME1 |
788 PIIX_PCI_IDETIM_PPE1 |
789 PIIX_PCI_IDETIM_IE1);
790 }
791
792#ifdef DEBUG_XXX
793 IOLog("\n%s: %s channel\n", getName(),
794 (channel == PIIX_CHANNEL_PRIMARY) ? "Primary" : "Secondary");
795 IOLog("%s: IDETIM : %04x\n", getName(), *idetim);
796 IOLog("%s: SIDETIM: %02x\n", getName(), *sidetim);
797 IOLog("%s: UDMACTL: %02x\n", getName(), *udmactl);
798 IOLog("%s: UDMATIM: %04x\n", getName(), *udmatim);
799 IOLog("%s: Active : %04lx\n", getName(), timings[unit].activeFlag);
800 IOLog("%s: Valid : %04lx\n", getName(), timings[unit].validFlag);
801 IOLog("%s: PIO:%d DMA:%d UDMA:%d\n\n", getName(),
802 timings[unit].activeTimings[kPIIXProtocolPIO],
803 timings[unit].activeTimings[kPIIXProtocolDMA],
804 timings[unit].activeTimings[kPIIXProtocolUDMA33]);
805#endif /* DEBUG */
806
807 return ret;
808}
809
810//--------------------------------------------------------------------------
811// Setup the descriptor table to perform the transfer indicated by the
812// IOMemoryDescriptor in the IOATACommand object provided.
813//
814bool AppleATAPIIX::programDma(IOATAStandardCommand * cmd)
815{
816 IOPhysicalSegment physSeg;
817 IOByteCount offset = 0;
818 IOMemoryDescriptor * memDesc;
819 prdEntry_t * prd = prdTable;
820 UInt32 startSeg;
821 UInt32 endSeg;
822 UInt32 partialCount;
823 UInt32 bytesLeft;
824
825 cmd->getPointers(&memDesc, &dmaReqLength, &dmaIsWrite);
826
827 if (dmaReqLength == 0)
828 return true;
829
830 bytesLeft = dmaReqLength;
831
832 // Setup the PRD entries in the descriptor table in memory.
833 //
834 for (UInt32 i = 0; i < (PRD_ENTRIES - 1); i++, prd++)
835 {
836 if (prdCursor->getPhysicalSegments(memDesc, offset, &physSeg, 1) != 1)
837 break;
838
839 startSeg = (physSeg.location & ~0xffff);
840 endSeg = (physSeg.location + physSeg.length - 1) & ~0xffff;
841
842 prd->base = physSeg.location;
843 prd->flags = 0;
844
845 if (startSeg == endSeg) {
846 prd->count = PRD_COUNT(physSeg.length);
847 }
848 else {
849 partialCount = (-physSeg.location & 0xffff);
850 prd->count = PRD_COUNT(partialCount);
851 prd++;
852 i++;
853 prd->base = physSeg.location + partialCount;
854 prd->count = physSeg.length - partialCount;
855 prd->flags = 0;
856 }
857
858 bytesLeft -= physSeg.length;
859 offset += physSeg.length;
860 }
861 if (bytesLeft != 0)
862 return false;
863
864 // Set the 'end-of-table' bit on the last PRD entry.
865 //
866 prd--;
867 prd->flags = PRD_FLAG_EOT;
868
869 /*
870 * Provide the starting address of the PRD table by loading the
871 * PRD Table Pointer Register.
872 */
873 outl(IOREG(BMIDTPX), prdTablePhys);
874
875 return true;
876}
877
878//--------------------------------------------------------------------------
879// Start the DMA engine.
880//
881bool AppleATAPIIX::startDma(IOATAStandardCommand * cmd)
882{
883 /*
884 * Clear interrupt and error bits in the Status Register.
885 */
886 outb(IOREG(BMISX), PIIX_IO_BMISX_ERROR |
887 PIIX_IO_BMISX_IDEINTS |
888 PIIX_IO_BMISX_DMA0CAP |
889 PIIX_IO_BMISX_DMA1CAP);
890
891 /*
892 * Engage the bus master by writing 1 to the start bit in the
893 * Command Register. Also set the RWCON bit for the direction
894 * of the data transfer.
895 */
896 outb(IOREG(BMICX), (dmaIsWrite ? 0 : PIIX_IO_BMICX_RWCON) |
897 PIIX_IO_BMICX_SSBM);
898
899 return true;
900}
901
902//--------------------------------------------------------------------------
903// Stop the DMA engine.
904//
905bool AppleATAPIIX::stopDma(IOATAStandardCommand * cmd, UInt32 * transferCount)
906{
907 UInt8 bmisx;
908
909 *transferCount = 0;
910
911 if (dmaReqLength == 0)
912 return true;
913
914 outb(IOREG(BMICX), 0); // stop the bus-master
915
916 bmisx = inb(IOREG(BMISX));
917
918 if ((bmisx & PIIX_IO_BMISX_STATUS) != PIIX_IO_BMISX_IDEINTS) {
919 IOLog("AppleATAPIIX::%s() DMA error (0x%02x)\n", __FUNCTION__, bmisx);
920 return false;
921 }
922
923 *transferCount = dmaReqLength;
924
925 return true;
926}
927
928//--------------------------------------------------------------------------
929// Perform a write to the ATA block registers.
930//
931void AppleATAPIIX::writeATAReg(UInt32 regIndex, UInt32 regValue)
932{
933 if (regIndex == 0) {
934 outw(ioCmdRange, (UInt16) regValue);
935 }
936 else if (regIndex < kATARegDeviceControl) {
937 outb(ioCmdRange + regIndex, (UInt8) regValue);
938 }
939 else {
940 outb(ioCtlRange + regIndex - kATARegDeviceControl + 2,
941 (UInt8) regValue);
942 }
943}
944
945//--------------------------------------------------------------------------
946// Perform a read from the ATA block registers.
947//
948UInt32 AppleATAPIIX::readATAReg( UInt32 regIndex )
949{
950 if (regIndex == 0) {
951 return inw(ioCmdRange);
952 }
953 else if (regIndex < kATARegDeviceControl) {
954 return inb(ioCmdRange + regIndex);
955 }
956 return inb(ioCtlRange + regIndex - kATARegDeviceControl + 2);
957}
958
959//--------------------------------------------------------------------------
960// Frees the drivers instance. Make sure all objects allocated during
961// our initialization are freed.
962//
963void AppleATAPIIX::free()
964{
965 if (interruptEventSource) {
966 interruptEventSource->disable();
967 interruptEventSource->release();
968 }
969
970 if (prdCursor)
971 prdCursor->release();
972
973 if (prdTable != 0)
974 _deallocatePRDTable();
975
976 return super::free();
977}
978
979//--------------------------------------------------------------------------
980// This function is called when our interruptEventSource receives an
981// interrupt. Simply pass the action to our superclass to advance its
982// state machine.
983//
984void AppleATAPIIX::interruptOccurred()
985{
986 super::interruptOccurred();
987}
988
989//--------------------------------------------------------------------------
990// This function is called by our superclass to disable controller
991// interrupts.
992//
993void AppleATAPIIX::disableControllerInterrupts()
994{
995 interruptEventSource->disable();
996}
997
998//--------------------------------------------------------------------------
999// This function is called by our superclass to enable controller
1000// interrupts.
1001//
1002void AppleATAPIIX::enableControllerInterrupts()
1003{
1004 interruptEventSource->enable();
1005}
1006
1007//--------------------------------------------------------------------------
1008// Private function: _readPCIConfigSpace
1009//
1010// Read the entire PCI config space and stores it to the buffer
1011// pointed by 'configSpace'.
1012//
1013bool AppleATAPIIX::_readPCIConfigSpace(UInt8 * configSpace)
1014{
1015 UInt32 * dwordPtr = (UInt32 *) configSpace;
1016
1017 for (int i = 0; i < 64; i++, dwordPtr++)
1018 *dwordPtr = provider->configRead32(i * 4);
1019
1020 return true;
1021}
1022
1023//--------------------------------------------------------------------------
1024// Private function: _writePCIConfigSpace
1025//
1026// Write the entire PCI config space from the buffer pointed
1027// by 'configSpace'.
1028//
1029bool AppleATAPIIX::_writePCIConfigSpace(UInt8 * configSpace)
1030{
1031 UInt32 * dwordPtr = (UInt32 *) configSpace;
1032
1033 for (int i = 0; i < 64; i++, dwordPtr++)
1034 provider->configWrite32(i * 4, *dwordPtr);
1035
1036 return true;
1037}