📄 ide-pmac.c
字号:
case XFER_UDMA_4: drive->id->dma_ultra |= 0x1010; break; case XFER_UDMA_3: drive->id->dma_ultra |= 0x0808; break; case XFER_UDMA_2: drive->id->dma_ultra |= 0x0404; break; case XFER_UDMA_1: drive->id->dma_ultra |= 0x0202; break; case XFER_UDMA_0: drive->id->dma_ultra |= 0x0101; break; case XFER_MW_DMA_2: drive->id->dma_mword |= 0x0404; break; case XFER_MW_DMA_1: drive->id->dma_mword |= 0x0202; break; case XFER_MW_DMA_0: drive->id->dma_mword |= 0x0101; break; case XFER_SW_DMA_2: drive->id->dma_1word |= 0x0404; break; case XFER_SW_DMA_1: drive->id->dma_1word |= 0x0202; break; case XFER_SW_DMA_0: drive->id->dma_1word |= 0x0101; break; default: break; } } enable_irq(hwif->irq); return result;}/* Calculate PIO timings */static void __pmacpmac_ide_tuneproc(ide_drive_t *drive, byte pio){ ide_pio_data_t d; int i; u32 *timings; unsigned accessTicks, recTicks; unsigned accessTime, recTime; i = pmac_ide_find(drive); if (i < 0) return; pio = ide_get_best_pio_mode(drive, pio, 4, &d); accessTicks = SYSCLK_TICKS(ide_pio_timings[pio].active_time); if (drive->select.b.unit & 0x01) timings = &pmac_ide[i].timings[1]; else timings = &pmac_ide[i].timings[0]; recTime = d.cycle_time - ide_pio_timings[pio].active_time - ide_pio_timings[pio].setup_time; recTime = max(recTime, 150U); accessTime = ide_pio_timings[pio].active_time; accessTime = max(accessTime, 150U); if (pmac_ide[i].kind == controller_kl_ata4 || pmac_ide[i].kind == controller_kl_ata4_80) { /* 66Mhz cell */ accessTicks = SYSCLK_TICKS_66(accessTime); accessTicks = min(accessTicks, 0x1fU); recTicks = SYSCLK_TICKS_66(recTime); recTicks = min(recTicks, 0x1fU); *timings = ((*timings) & ~TR_66_PIO_MASK) | (accessTicks << TR_66_PIO_ACCESS_SHIFT) | (recTicks << TR_66_PIO_RECOVERY_SHIFT); } else { /* 33Mhz cell */ int ebit = 0; accessTicks = SYSCLK_TICKS(accessTime); accessTicks = min(accessTicks, 0x1fU); accessTicks = max(accessTicks, 4U); recTicks = SYSCLK_TICKS(recTime); recTicks = min(recTicks, 0x1fU); recTicks = max(recTicks, 5U) - 4; if (recTicks > 9) { recTicks--; /* guess, but it's only for PIO0, so... */ ebit = 1; } *timings = ((*timings) & ~TR_33_PIO_MASK) | (accessTicks << TR_33_PIO_ACCESS_SHIFT) | (recTicks << TR_33_PIO_RECOVERY_SHIFT); if (ebit) *timings |= TR_33_PIO_E; }#ifdef IDE_PMAC_DEBUG printk(KERN_ERR "ide_pmac: Set PIO timing for mode %d, reg: 0x%08x\n", pio, *timings);#endif if (drive->select.all == IN_BYTE(IDE_SELECT_REG)) pmac_ide_selectproc(drive);}#ifdef CONFIG_BLK_DEV_IDEDMA_PMACstatic int __pmacset_timings_udma(u32 *timings, byte speed){ unsigned rdyToPauseTicks, wrDataSetupTicks, addrTicks; rdyToPauseTicks = SYSCLK_TICKS_66(udma_timings[speed & 0xf].rdy2pause); wrDataSetupTicks = SYSCLK_TICKS_66(udma_timings[speed & 0xf].wrDataSetup); addrTicks = SYSCLK_TICKS_66(udma_timings[speed & 0xf].addrSetup); *timings = ((*timings) & ~(TR_66_UDMA_MASK | TR_66_MDMA_MASK)) | (wrDataSetupTicks << TR_66_UDMA_WRDATASETUP_SHIFT) | (rdyToPauseTicks << TR_66_UDMA_RDY2PAUS_SHIFT) | (addrTicks <<TR_66_UDMA_ADDRSETUP_SHIFT) | TR_66_UDMA_EN;#ifdef IDE_PMAC_DEBUG printk(KERN_ERR "ide_pmac: Set UDMA timing for mode %d, reg: 0x%08x\n", speed & 0xf, *timings);#endif return 0;}static int __pmacset_timings_mdma(int intf_type, u32 *timings, byte speed, int drive_cycle_time){ int cycleTime, accessTime, recTime; unsigned accessTicks, recTicks; struct mdma_timings_t* tm; int i; /* Get default cycle time for mode */ switch(speed & 0xf) { case 0: cycleTime = 480; break; case 1: cycleTime = 150; break; case 2: cycleTime = 120; break; default: return -1; } /* Adjust for drive */ if (drive_cycle_time && drive_cycle_time > cycleTime) cycleTime = drive_cycle_time; /* OHare limits according to some old Apple sources */ if ((intf_type == controller_ohare) && (cycleTime < 150)) cycleTime = 150; /* Get the proper timing array for this controller */ switch(intf_type) { case controller_kl_ata4: case controller_kl_ata4_80: tm = mdma_timings_66; break; case controller_kl_ata3: tm = mdma_timings_33k; break; default: tm = mdma_timings_33; break; } /* Lookup matching access & recovery times */ i = -1; for (;;) { if (tm[i+1].cycleTime < cycleTime) break; i++; } if (i < 0) return -1; cycleTime = tm[i].cycleTime; accessTime = tm[i].accessTime; recTime = tm[i].recoveryTime;#ifdef IDE_PMAC_DEBUG printk(KERN_ERR "ide_pmac: MDMA, cycleTime: %d, accessTime: %d, recTime: %d\n", cycleTime, accessTime, recTime);#endif if (intf_type == controller_kl_ata4 || intf_type == controller_kl_ata4_80) { /* 66Mhz cell */ accessTicks = SYSCLK_TICKS_66(accessTime); accessTicks = min(accessTicks, 0x1fU); accessTicks = max(accessTicks, 0x1U); recTicks = SYSCLK_TICKS_66(recTime); recTicks = min(recTicks, 0x1fU); recTicks = max(recTicks, 0x3U); /* Clear out mdma bits and disable udma */ *timings = ((*timings) & ~(TR_66_MDMA_MASK | TR_66_UDMA_MASK)) | (accessTicks << TR_66_MDMA_ACCESS_SHIFT) | (recTicks << TR_66_MDMA_RECOVERY_SHIFT); } else if (intf_type == controller_kl_ata3) { /* 33Mhz cell on KeyLargo */ accessTicks = SYSCLK_TICKS(accessTime); accessTicks = max(accessTicks, 1U); accessTicks = min(accessTicks, 0x1fU); accessTime = accessTicks * IDE_SYSCLK_NS; recTicks = SYSCLK_TICKS(recTime); recTicks = max(recTicks, 1U); recTicks = min(recTicks, 0x1fU); *timings = ((*timings) & ~TR_33_MDMA_MASK) | (accessTicks << TR_33_MDMA_ACCESS_SHIFT) | (recTicks << TR_33_MDMA_RECOVERY_SHIFT); } else { /* 33Mhz cell on others */ int halfTick = 0; int origAccessTime = accessTime; int origRecTime = recTime; accessTicks = SYSCLK_TICKS(accessTime); accessTicks = max(accessTicks, 1U); accessTicks = min(accessTicks, 0x1fU); accessTime = accessTicks * IDE_SYSCLK_NS; recTicks = SYSCLK_TICKS(recTime); recTicks = max(recTicks, 2U) - 1; recTicks = min(recTicks, 0x1fU); recTime = (recTicks + 1) * IDE_SYSCLK_NS; if ((accessTicks > 1) && ((accessTime - IDE_SYSCLK_NS/2) >= origAccessTime) && ((recTime - IDE_SYSCLK_NS/2) >= origRecTime)) { halfTick = 1; accessTicks--; } *timings = ((*timings) & ~TR_33_MDMA_MASK) | (accessTicks << TR_33_MDMA_ACCESS_SHIFT) | (recTicks << TR_33_MDMA_RECOVERY_SHIFT); if (halfTick) *timings |= TR_33_MDMA_HALFTICK; }#ifdef IDE_PMAC_DEBUG printk(KERN_ERR "ide_pmac: Set MDMA timing for mode %d, reg: 0x%08x\n", speed & 0xf, *timings);#endif return 0;}#endif /* #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC *//* You may notice we don't use this function on normal operation, * our, normal mdma function is supposed to be more precise */static int __pmacpmac_ide_tune_chipset (ide_drive_t *drive, byte speed){ int intf = pmac_ide_find(drive); int unit = (drive->select.b.unit & 0x01); int ret = 0; u32 *timings; if (intf < 0) return 1; timings = &pmac_ide[intf].timings[unit]; switch(speed) {#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC case XFER_UDMA_4: case XFER_UDMA_3: if (pmac_ide[intf].kind != controller_kl_ata4_80) return 1; case XFER_UDMA_2: case XFER_UDMA_1: case XFER_UDMA_0: if (pmac_ide[intf].kind != controller_kl_ata4 && pmac_ide[intf].kind != controller_kl_ata4_80) return 1; ret = set_timings_udma(timings, speed); break; case XFER_MW_DMA_2: case XFER_MW_DMA_1: case XFER_MW_DMA_0: ret = set_timings_mdma(pmac_ide[intf].kind, timings, speed, 0); break; case XFER_SW_DMA_2: case XFER_SW_DMA_1: case XFER_SW_DMA_0: return 1;#endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ case XFER_PIO_4: case XFER_PIO_3: case XFER_PIO_2: case XFER_PIO_1: case XFER_PIO_0: pmac_ide_tuneproc(drive, speed & 0x07); break; default: ret = 1; } if (ret) return ret; ret = pmac_ide_do_setfeature(drive, speed); if (ret) return ret; pmac_ide_selectproc(drive); drive->current_speed = speed; return 0;}static void __pmacsanitize_timings(int i){ unsigned value; switch(pmac_ide[i].kind) { case controller_kl_ata4: case controller_kl_ata4_80: value = 0x0008438c; break; case controller_kl_ata3: value = 0x00084526; break; case controller_heathrow: case controller_ohare: default: value = 0x00074526; break; } pmac_ide[i].timings[0] = pmac_ide[i].timings[1] = value;}ide_ioreg_t __pmacpmac_ide_get_base(int index){ return pmac_ide[index].regbase;}int __pmacpmac_ide_check_base(ide_ioreg_t base){ int ix; for (ix = 0; ix < MAX_HWIFS; ++ix) if (base == pmac_ide[ix].regbase) return ix; return -1;}int __pmacpmac_ide_get_irq(ide_ioreg_t base){ int ix; for (ix = 0; ix < MAX_HWIFS; ++ix) if (base == pmac_ide[ix].regbase) return pmac_ide[ix].irq; return 0;}static int ide_majors[] __pmacdata = { 3, 22, 33, 34, 56, 57 };kdev_t __initpmac_find_ide_boot(char *bootdevice, int n){ int i; /* * Look through the list of IDE interfaces for this one. */ for (i = 0; i < pmac_ide_count; ++i) { char *name; if (!pmac_ide[i].node || !pmac_ide[i].node->full_name) continue; name = pmac_ide[i].node->full_name; if (memcmp(name, bootdevice, n) == 0 && name[n] == 0) { /* XXX should cope with the 2nd drive as well... */ return MKDEV(ide_majors[i], 0); } } return 0;}void __initpmac_ide_probe(void){ struct device_node *np; int i; struct device_node *atas; struct device_node *p, **pp, *removables, **rp; unsigned long base; int irq, big_delay; ide_hwif_t *hwif; if (_machine != _MACH_Pmac) return; pp = &atas; rp = &removables; p = find_devices("ATA"); if (p == NULL) p = find_devices("IDE"); if (p == NULL) p = find_type_devices("ide"); if (p == NULL) p = find_type_devices("ata"); /* Move removable devices such as the media-bay CDROM on the PB3400 to the end of the list. */ for (; p != NULL; p = p->next) { if (p->parent && p->parent->type && strcasecmp(p->parent->type, "media-bay") == 0) { *rp = p; rp = &p->next; } else { *pp = p; pp = &p->next; } } *rp = NULL; *pp = removables; big_delay = 0; for (i = 0, np = atas; i < MAX_HWIFS && np != NULL; np = np->next) { struct device_node *tp; struct pmac_ide_hwif* pmhw; int *bidp; int in_bay = 0; u8 pbus, pid; struct pci_dev *pdev = NULL; /* * If this node is not under a mac-io or dbdma node, * leave it to the generic PCI driver. */ for (tp = np->parent; tp != 0; tp = tp->parent) if (tp->type && (strcmp(tp->type, "mac-io") == 0 || strcmp(tp->type, "dbdma") == 0)) break; if (tp == 0) continue; if (np->n_addrs == 0) { printk(KERN_WARNING "ide: no address for device %s\n", np->full_name); continue; } /* We need to find the pci_dev of the mac-io holding the * IDE interface */ if (pci_device_from_OF_node(tp, &pbus, &pid) == 0) pdev = pci_find_slot(pbus, pid); if (pdev == NULL) printk(KERN_WARNING "ide: no PCI host for device %s, DMA disabled\n", np->full_name); /* * If this slot is taken (e.g. by ide-pci.c) try the next one. */ while (i < MAX_HWIFS && ide_hwifs[i].io_ports[IDE_DATA_OFFSET] != 0) ++i; if (i >= MAX_HWIFS) break; pmhw = &pmac_ide[i]; /* * Some older OFs have bogus sizes, causing request_OF_resource * to fail. We fix them up here */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -