📄 hpt366.c
字号:
hpt370_tune_chipset(drive, speed, 0); } else { hpt366_tune_chipset(drive, speed, 0); } drive->current_speed = speed; return ((int) ide_config_drive_speed(drive, speed));}static void config_chipset_for_pio (ide_drive_t *drive){ unsigned short eide_pio_timing[6] = {960, 480, 240, 180, 120, 90}; unsigned short xfer_pio = drive->id->eide_pio_modes; byte timing, speed, pio; pio = ide_get_best_pio_mode(drive, 255, 5, NULL); if (xfer_pio> 4) xfer_pio = 0; if (drive->id->eide_pio_iordy > 0) { for (xfer_pio = 5; xfer_pio>0 && drive->id->eide_pio_iordy>eide_pio_timing[xfer_pio]; xfer_pio--); } else { xfer_pio = (drive->id->eide_pio_modes & 4) ? 0x05 : (drive->id->eide_pio_modes & 2) ? 0x04 : (drive->id->eide_pio_modes & 1) ? 0x03 : (drive->id->tPIO & 2) ? 0x02 : (drive->id->tPIO & 1) ? 0x01 : xfer_pio; } timing = (xfer_pio >= pio) ? xfer_pio : pio; switch(timing) { case 4: speed = XFER_PIO_4;break; case 3: speed = XFER_PIO_3;break; case 2: speed = XFER_PIO_2;break; case 1: speed = XFER_PIO_1;break; default: speed = (!drive->id->tPIO) ? XFER_PIO_0 : XFER_PIO_SLOW; break; } (void) hpt3xx_tune_chipset(drive, speed);}static void hpt3xx_tune_drive (ide_drive_t *drive, byte pio){ byte speed; switch(pio) { case 4: speed = XFER_PIO_4;break; case 3: speed = XFER_PIO_3;break; case 2: speed = XFER_PIO_2;break; case 1: speed = XFER_PIO_1;break; default: speed = XFER_PIO_0;break; } (void) hpt3xx_tune_chipset(drive, speed);}#ifdef CONFIG_BLK_DEV_IDEDMA/* * This allows the configuration of ide_pci chipset registers * for cards that learn about the drive's UDMA, DMA, PIO capabilities * after the drive is reported by the OS. Initally for designed for * HPT366 UDMA chipset by HighPoint|Triones Technologies, Inc. * * check_in_drive_lists(drive, bad_ata66_4) * check_in_drive_lists(drive, bad_ata66_3) * check_in_drive_lists(drive, bad_ata33) * */static int config_chipset_for_dma (ide_drive_t *drive){ struct hd_driveid *id = drive->id; byte speed = 0x00; byte ultra66 = eighty_ninty_three(drive); int rval; if ((drive->media != ide_disk) && (speed < XFER_SW_DMA_0)) return ((int) ide_dma_off_quietly); if ((id->dma_ultra & 0x0020) && (!check_in_drive_lists(drive, bad_ata100_5)) && (HPT370_ALLOW_ATA100_5) && (pci_rev_check_hpt3xx(HWIF(drive)->pci_dev)) && (ultra66)) { speed = XFER_UDMA_5; } else if ((id->dma_ultra & 0x0010) && (!check_in_drive_lists(drive, bad_ata66_4)) && (HPT366_ALLOW_ATA66_4) && (ultra66)) { speed = XFER_UDMA_4; } else if ((id->dma_ultra & 0x0008) && (!check_in_drive_lists(drive, bad_ata66_3)) && (HPT366_ALLOW_ATA66_3) && (ultra66)) { speed = XFER_UDMA_3; } else if (id->dma_ultra && (!check_in_drive_lists(drive, bad_ata33))) { if (id->dma_ultra & 0x0004) { speed = XFER_UDMA_2; } else if (id->dma_ultra & 0x0002) { speed = XFER_UDMA_1; } else if (id->dma_ultra & 0x0001) { speed = XFER_UDMA_0; } } else if (id->dma_mword & 0x0004) { speed = XFER_MW_DMA_2; } else if (id->dma_mword & 0x0002) { speed = XFER_MW_DMA_1; } else if (id->dma_mword & 0x0001) { speed = XFER_MW_DMA_0; } else { return ((int) ide_dma_off_quietly); } (void) hpt3xx_tune_chipset(drive, speed); rval = (int)( ((id->dma_ultra >> 11) & 7) ? ide_dma_on : ((id->dma_ultra >> 8) & 7) ? ide_dma_on : ((id->dma_mword >> 8) & 7) ? ide_dma_on : ide_dma_off_quietly); return rval;}int hpt3xx_quirkproc (ide_drive_t *drive){ return ((int) check_in_drive_lists(drive, quirk_drives));}void hpt3xx_intrproc (ide_drive_t *drive){ if (drive->quirk_list) { /* drives in the quirk_list may not like intr setups/cleanups */ } else { OUT_BYTE((drive)->ctl|2, HWIF(drive)->io_ports[IDE_CONTROL_OFFSET]); }}void hpt3xx_maskproc (ide_drive_t *drive, int mask){ if (drive->quirk_list) { if (pci_rev_check_hpt3xx(HWIF(drive)->pci_dev)) { byte reg5a = 0; pci_read_config_byte(HWIF(drive)->pci_dev, 0x5a, ®5a); if (((reg5a & 0x10) >> 4) != mask) pci_write_config_byte(HWIF(drive)->pci_dev, 0x5a, mask ? (reg5a | 0x10) : (reg5a & ~0x10)); } else { if (mask) { disable_irq(HWIF(drive)->irq); } else { enable_irq(HWIF(drive)->irq); } } } else { if (IDE_CONTROL_REG) OUT_BYTE(mask ? (drive->ctl | 2) : (drive->ctl & ~2), IDE_CONTROL_REG); }}void hpt370_rw_proc (ide_drive_t *drive, ide_dma_action_t func){ if ((func != ide_dma_write) || (func != ide_dma_read)) return; hpt370_tune_chipset(drive, drive->current_speed, (func == ide_dma_write));}static int config_drive_xfer_rate (ide_drive_t *drive){ struct hd_driveid *id = drive->id; ide_dma_action_t dma_func = ide_dma_on; if (id && (id->capability & 1) && HWIF(drive)->autodma) { /* Consult the list of known "bad" drives */ if (ide_dmaproc(ide_dma_bad_drive, drive)) { dma_func = ide_dma_off; goto fast_ata_pio; } dma_func = ide_dma_off_quietly; if (id->field_valid & 4) { if (id->dma_ultra & 0x002F) { /* Force if Capable UltraDMA */ dma_func = config_chipset_for_dma(drive); if ((id->field_valid & 2) && (dma_func != ide_dma_on)) goto try_dma_modes; } } else if (id->field_valid & 2) {try_dma_modes: if (id->dma_mword & 0x0007) { /* Force if Capable regular DMA modes */ dma_func = config_chipset_for_dma(drive); if (dma_func != ide_dma_on) goto no_dma_set; } } else if (ide_dmaproc(ide_dma_good_drive, drive)) { if (id->eide_dma_time > 150) { goto no_dma_set; } /* Consult the list of known "good" drives */ dma_func = config_chipset_for_dma(drive); if (dma_func != ide_dma_on) goto no_dma_set; } else { goto fast_ata_pio; } } else if ((id->capability & 8) || (id->field_valid & 2)) {fast_ata_pio: dma_func = ide_dma_off_quietly;no_dma_set: config_chipset_for_pio(drive); } return HWIF(drive)->dmaproc(dma_func, drive);}/* * hpt366_dmaproc() initiates/aborts (U)DMA read/write operations on a drive. * * This is specific to the HPT366 UDMA bios chipset * by HighPoint|Triones Technologies, Inc. */int hpt366_dmaproc (ide_dma_action_t func, ide_drive_t *drive){ byte reg50h = 0, reg52h = 0, reg5ah = 0, dma_stat = 0; unsigned long dma_base = HWIF(drive)->dma_base; switch (func) { case ide_dma_check: return config_drive_xfer_rate(drive); case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */ dma_stat = inb(dma_base+2); return (dma_stat & 4) == 4; /* return 1 if INTR asserted */ case ide_dma_lostirq: pci_read_config_byte(HWIF(drive)->pci_dev, 0x50, ®50h); pci_read_config_byte(HWIF(drive)->pci_dev, 0x52, ®52h); pci_read_config_byte(HWIF(drive)->pci_dev, 0x5a, ®5ah); printk("%s: (%s) reg50h=0x%02x, reg52h=0x%02x, reg5ah=0x%02x\n", drive->name, ide_dmafunc_verbose(func), reg50h, reg52h, reg5ah); if (reg5ah & 0x10) pci_write_config_byte(HWIF(drive)->pci_dev, 0x5a, reg5ah & ~0x10); break; case ide_dma_timeout: default: break; } return ide_dmaproc(func, drive); /* use standard DMA stuff */}int hpt370_dmaproc (ide_dma_action_t func, ide_drive_t *drive){ switch (func) { case ide_dma_check: return config_drive_xfer_rate(drive); default: break; } return ide_dmaproc(func, drive); /* use standard DMA stuff */}#endif /* CONFIG_BLK_DEV_IDEDMA */unsigned int __init pci_init_hpt366 (struct pci_dev *dev, const char *name){ byte test = 0; if (dev->resource[PCI_ROM_RESOURCE].start) pci_write_config_byte(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &test);#if 0 if (test != 0x08) pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 0x08);#else if (test != (L1_CACHE_BYTES / 4)) pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4));#endif pci_read_config_byte(dev, PCI_LATENCY_TIMER, &test); if (test != 0x78) pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78); pci_read_config_byte(dev, PCI_MIN_GNT, &test); if (test != 0x08) pci_write_config_byte(dev, PCI_MIN_GNT, 0x08); pci_read_config_byte(dev, PCI_MAX_LAT, &test); if (test != 0x08) pci_write_config_byte(dev, PCI_MAX_LAT, 0x08);#if defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS) if (!hpt366_proc) { hpt366_proc = 1; bmide_dev = dev; if (pci_rev_check_hpt3xx(dev)) bmide2_dev = dev; hpt366_display_info = &hpt366_get_info; } if ((hpt366_proc) && ((dev->devfn - bmide_dev->devfn) == 1)) { bmide2_dev = dev; }#endif /* DISPLAY_HPT366_TIMINGS && CONFIG_PROC_FS */ return dev->irq;}unsigned int __init ata66_hpt366 (ide_hwif_t *hwif){ byte ata66 = 0; pci_read_config_byte(hwif->pci_dev, 0x5a, &ata66);#ifdef DEBUG printk("HPT366: reg5ah=0x%02x ATA-%s Cable Port%d\n", ata66, (ata66 & 0x02) ? "33" : "66", PCI_FUNC(hwif->pci_dev->devfn));#endif /* DEBUG */ return ((ata66 & 0x02) ? 0 : 1);}void __init ide_init_hpt366 (ide_hwif_t *hwif){ hwif->tuneproc = &hpt3xx_tune_drive; hwif->speedproc = &hpt3xx_tune_chipset; hwif->quirkproc = &hpt3xx_quirkproc; hwif->intrproc = &hpt3xx_intrproc; hwif->maskproc = &hpt3xx_maskproc; if (pci_rev2_check_hpt3xx(hwif->pci_dev)) { /* do nothing now but will split device types */ }#ifdef CONFIG_BLK_DEV_IDEDMA if (hwif->dma_base) { if (pci_rev_check_hpt3xx(hwif->pci_dev)) { byte reg5ah = 0; pci_read_config_byte(hwif->pci_dev, 0x5a, ®5ah); if (reg5ah & 0x10) /* interrupt force enable */ pci_write_config_byte(hwif->pci_dev, 0x5a, reg5ah & ~0x10); hwif->dmaproc = &hpt370_dmaproc; hwif->rwproc = &hpt370_rw_proc; } else { hwif->dmaproc = &hpt366_dmaproc; } if (!noautodma) hwif->autodma = 1; else hwif->autodma = 0; } else { hwif->autodma = 0; hwif->drives[0].autotune = 1; hwif->drives[1].autotune = 1; }#else /* !CONFIG_BLK_DEV_IDEDMA */ hwif->drives[0].autotune = 1; hwif->drives[1].autotune = 1; hwif->autodma = 0;#endif /* CONFIG_BLK_DEV_IDEDMA */}void __init ide_dmacapable_hpt366 (ide_hwif_t *hwif, unsigned long dmabase){ byte masterdma = 0, slavedma = 0; byte dma_new = 0, dma_old = inb(dmabase+2); byte primary = hwif->channel ? 0x4b : 0x43; byte secondary = hwif->channel ? 0x4f : 0x47; unsigned long flags; __save_flags(flags); /* local CPU only */ __cli(); /* local CPU only */ dma_new = dma_old; pci_read_config_byte(hwif->pci_dev, primary, &masterdma); pci_read_config_byte(hwif->pci_dev, secondary, &slavedma); if (masterdma & 0x30) dma_new |= 0x20; if (slavedma & 0x30) dma_new |= 0x40; if (dma_new != dma_old) outb(dma_new, dmabase+2); __restore_flags(flags); /* local CPU only */ ide_setup_dma(hwif, dmabase, 8);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -