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