📄 triton.c
字号:
/* Consult the list of known "good" drives */ list = good_dma_drives; while (*list) { if (!strcmp(*list++,id->model)) { drive->using_dma = 1; return 0; /* DMA enabled */ } } } return 1; /* DMA not enabled */}/* * triton_dmaproc() initiates/aborts DMA read/write operations on a drive. * * The caller is assumed to have selected the drive and programmed the drive's * sector address using CHS or LBA. All that remains is to prepare for DMA * and then issue the actual read/write DMA/PIO command to the drive. * * For ATAPI devices, we just prepare for DMA and return. The caller should * then issue the packet command to the drive and call us again with * ide_dma_begin afterwards. * * Returns 0 if all went well. * Returns 1 if DMA read/write could not be started, in which case * the caller should revert to PIO for the current request. */static int triton_dmaproc (ide_dma_action_t func, ide_drive_t *drive){ unsigned long dma_base = HWIF(drive)->dma_base; unsigned int reading = (1 << 3); switch (func) { case ide_dma_abort: outb(inb(dma_base)&~1, dma_base); /* stop DMA */ return 0; case ide_dma_check: return config_drive_for_dma (drive); case ide_dma_write: reading = 0; case ide_dma_read: break; case ide_dma_status_bad: return ((inb(dma_base+2) & 7) != 4); /* verify good DMA status */ case ide_dma_transferred:#if 0 return (number of bytes actually transferred);#else return (0);#endif case ide_dma_begin: outb(inb(dma_base)|1, dma_base); /* begin DMA */ return 0; default: printk("triton_dmaproc: unsupported func: %d\n", func); return 1; } if (build_dmatable (drive)) return 1; outl(virt_to_bus (HWIF(drive)->dmatable), dma_base + 4); /* PRD table */ outb(reading, dma_base); /* specify r/w */ outb(inb(dma_base+2)|0x06, dma_base+2); /* clear status bits */#ifdef CONFIG_BLK_DEV_IDEATAPI if (drive->media != ide_disk) return 0;#endif /* CONFIG_BLK_DEV_IDEATAPI */ ide_set_handler(drive, &dma_intr, WAIT_CMD); /* issue cmd to drive */ OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG); outb(inb(dma_base)|1, dma_base); /* begin DMA */ return 0;}#ifdef DISPLAY_TRITON_TIMINGS/* * print_triton_drive_flags() displays the currently programmed options * in the i82371 (Triton) for a given drive. * * If fastDMA is "no", then slow ISA timings are used for DMA data xfers. * If fastPIO is "no", then slow ISA timings are used for PIO data xfers. * If IORDY is "no", then IORDY is assumed to always be asserted. * If PreFetch is "no", then data pre-fetch/post are not used. * * When "fastPIO" and/or "fastDMA" are "yes", then faster PCI timings and * back-to-back 16-bit data transfers are enabled, using the sample_CLKs * and recovery_CLKs (PCI clock cycles) timing parameters for that interface. */static void print_triton_drive_flags (unsigned int unit, byte flags){ printk(" %s ", unit ? "slave :" : "master:"); printk( "fastDMA=%s", (flags&9) ? "on " : "off"); printk(" PreFetch=%s", (flags&4) ? "on " : "off"); printk(" IORDY=%s", (flags&2) ? "on " : "off"); printk(" fastPIO=%s\n", ((flags&9)==1) ? "on " : "off");}#endif /* DISPLAY_TRITON_TIMINGS */static void init_triton_dma (ide_hwif_t *hwif, unsigned short base){ static unsigned long dmatable = 0; printk(" %s: BM-DMA at 0x%04x-0x%04x", hwif->name, base, base+7); if (check_region(base, 8)) { printk(" -- ERROR, PORTS ALREADY IN USE"); } else { request_region(base, 8, "IDE DMA"); hwif->dma_base = base; if (!dmatable) { /* * The BM-DMA uses a full 32-bits, so we can * safely use __get_free_page() here instead * of __get_dma_pages() -- no ISA limitations. */ dmatable = __get_free_pages(GFP_KERNEL, 1, 0); } if (dmatable) { hwif->dmatable = (unsigned long *) dmatable; dmatable += (PRD_ENTRIES * PRD_BYTES); outl(virt_to_bus(hwif->dmatable), base + 4); hwif->dmaproc = &triton_dmaproc; } } printk("\n");}/* * ide_init_triton() prepares the IDE driver for DMA operation. * This routine is called once, from ide.c during driver initialization, * for each triton chipset which is found (unlikely to be more than one). */void ide_init_triton (byte bus, byte fn){ int rc = 0, h; int dma_enabled = 0; unsigned short pcicmd; unsigned int bmiba, timings; printk("ide: i82371 PIIX (Triton) on PCI bus %d function %d\n", bus, fn); /* * See if IDE and BM-DMA features are enabled: */ if ((rc = pcibios_read_config_word(bus, fn, 0x04, &pcicmd))) goto quit; if ((pcicmd & 1) == 0) { printk("ide: ports are not enabled (BIOS)\n"); goto quit; } if ((pcicmd & 4) == 0) { printk("ide: BM-DMA feature is not enabled (BIOS)\n"); } else { /* * Get the bmiba base address */ int try_again = 1; do { if ((rc = pcibios_read_config_dword(bus, fn, 0x20, &bmiba))) goto quit; bmiba &= 0xfff0; /* extract port base address */ if (bmiba) { dma_enabled = 1; break; } else { printk("ide: BM-DMA base register is invalid (0x%04x, PnP BIOS problem)\n", bmiba); if (inb(DEFAULT_BMIBA) != 0xff || !try_again) break; printk("ide: setting BM-DMA base register to 0x%04x\n", DEFAULT_BMIBA); if ((rc = pcibios_write_config_word(bus, fn, 0x04, pcicmd&~1))) goto quit; rc = pcibios_write_config_dword(bus, fn, 0x20, DEFAULT_BMIBA|1); if (pcibios_write_config_word(bus, fn, 0x04, pcicmd|5) || rc) goto quit; } } while (try_again--); } /* * See if ide port(s) are enabled */ if ((rc = pcibios_read_config_dword(bus, fn, 0x40, &timings))) goto quit; if (!(timings & 0x80008000)) { printk("ide: neither port is enabled\n"); goto quit; } /* * Save the dma_base port addr for each interface */ for (h = 0; h < MAX_HWIFS; ++h) {#ifdef DISPLAY_TRITON_TIMINGS byte s_clks, r_clks; unsigned short devid;#endif /* DISPLAY_TRITON_TIMINGS */ ide_hwif_t *hwif = &ide_hwifs[h]; unsigned short time; if (hwif->io_base == 0x1f0) { time = timings & 0xffff; if ((time & 0x8000) == 0) /* interface enabled? */ continue; hwif->chipset = ide_triton; if (dma_enabled) init_triton_dma(hwif, bmiba); } else if (hwif->io_base == 0x170) { time = timings >> 16; if ((time & 0x8000) == 0) /* interface enabled? */ continue; hwif->chipset = ide_triton; if (dma_enabled) init_triton_dma(hwif, bmiba + 8); } else continue;#ifdef DISPLAY_TRITON_TIMINGS s_clks = ((~time >> 12) & 3) + 2; r_clks = ((~time >> 8) & 3) + 1; printk(" %s timing: (0x%04x) sample_CLKs=%d, recovery_CLKs=%d\n", hwif->name, time, s_clks, r_clks); if ((time & 0x40) && !pcibios_read_config_word(bus, fn, 0x02, &devid) && devid == PCI_DEVICE_ID_INTEL_82371SB_1) { byte stime; if (pcibios_read_config_byte(bus, fn, 0x44, &stime)) { if (hwif->io_base == 0x1f0) { s_clks = ~stime >> 6; r_clks = ~stime >> 4; } else { s_clks = ~stime >> 2; r_clks = ~stime; } s_clks = (s_clks & 3) + 2; r_clks = (r_clks & 3) + 1; printk(" slave: sample_CLKs=%d, recovery_CLKs=%d\n", s_clks, r_clks); } } print_triton_drive_flags (0, time & 0xf); print_triton_drive_flags (1, (time >> 4) & 0xf);#endif /* DISPLAY_TRITON_TIMINGS */ }quit: if (rc) printk("ide: pcibios access failed - %s\n", pcibios_strerror(rc));}void ide_init_promise (byte bus, byte fn, ide_hwif_t *hwif0, ide_hwif_t *hwif1, unsigned short dma){ int rc; unsigned short pcicmd; unsigned int bmiba = 0; printk("ide: Enabling DMA for Promise Technology IDE Ultra-DMA 33 on PCI bus %d function %d, port 0x%04x\n", bus, fn, dma); if ((rc = pcibios_read_config_word(bus, fn, 0x04, &pcicmd)) || (pcicmd & 1) == 0 || (pcicmd & 4) == 0) goto abort; if ((rc = pcibios_read_config_dword(bus, fn, 0x20, &bmiba))) goto abort; bmiba &= 0xfff0; /* extract port base address */ if (bmiba != dma || !bmiba) goto abort; hwif0->chipset = ide_promise_udma; hwif1->chipset = ide_promise_udma; init_triton_dma(hwif0, bmiba); init_triton_dma(hwif1, bmiba + 0x08); return;abort: printk(KERN_WARNING "ide: Promise/33 not configured correctly (BIOS)\n");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -