📄 aec62xx.c
字号:
/* * linux/drivers/ide/pci/aec62xx.c Version 0.11 March 27, 2002 * * Copyright (C) 1999-2002 Andre Hedrick <andre@linux-ide.org> * */#include <linux/module.h>#include <linux/config.h>#include <linux/types.h>#include <linux/pci.h>#include <linux/delay.h>#include <linux/hdreg.h>#include <linux/ide.h>#include <linux/init.h>#include <asm/io.h>#include "ide_modes.h"#include "aec62xx.h"#if defined(DISPLAY_AEC62XX_TIMINGS) && defined(CONFIG_PROC_FS)#include <linux/stat.h>#include <linux/proc_fs.h>static u8 aec62xx_proc = 0;#define AEC_MAX_DEVS 5static struct pci_dev *aec_devs[AEC_MAX_DEVS];static int n_aec_devs;#undef DEBUG_AEC_REGSstatic int aec62xx_get_info (char *buffer, char **addr, off_t offset, int count){ char *p = buffer; char *chipset_nums[] = {"error", "error", "error", "error", "error", "error", "850UF", "860", "860R", "865", "865R", "error" }; int len; int i; for (i = 0; i < n_aec_devs; i++) { struct pci_dev *dev = aec_devs[i]; unsigned long iobase = pci_resource_start(dev, 4); u8 c0 = 0, c1 = 0, art = 0;#ifdef DEBUG_AEC_REGS u8 uart = 0;#endif /* DEBUG_AEC_REGS */ c0 = inb(iobase + 0x02); c1 = inb(iobase + 0x0a); p += sprintf(p, "\nController: %d\n", i); p += sprintf(p, "Chipset: AEC%s\n", chipset_nums[dev->device]); p += sprintf(p, "--------------- Primary Channel " "---------------- Secondary Channel " "-------------\n"); (void) pci_read_config_byte(dev, 0x4a, &art); p += sprintf(p, " %sabled ", (art&0x02)?" en":"dis"); p += sprintf(p, " %sabled\n", (art&0x04)?" en":"dis"); p += sprintf(p, "--------------- drive0 --------- drive1 " "-------- drive0 ---------- drive1 ------\n"); p += sprintf(p, "DMA enabled: %s %s ", (c0&0x20)?"yes":"no ",(c0&0x40)?"yes":"no "); p += sprintf(p, " %s %s\n", (c1&0x20)?"yes":"no ",(c1&0x40)?"yes":"no "); if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) { (void) pci_read_config_byte(dev, 0x54, &art); p += sprintf(p, "DMA Mode: %s(%s)", (c0&0x20)?((art&0x03)?"UDMA":" DMA"):" PIO", (art&0x02)?"2":(art&0x01)?"1":"0"); p += sprintf(p, " %s(%s)", (c0&0x40)?((art&0x0c)?"UDMA":" DMA"):" PIO", (art&0x08)?"2":(art&0x04)?"1":"0"); p += sprintf(p, " %s(%s)", (c1&0x20)?((art&0x30)?"UDMA":" DMA"):" PIO", (art&0x20)?"2":(art&0x10)?"1":"0"); p += sprintf(p, " %s(%s)\n", (c1&0x40)?((art&0xc0)?"UDMA":" DMA"):" PIO", (art&0x80)?"2":(art&0x40)?"1":"0");#ifdef DEBUG_AEC_REGS (void) pci_read_config_byte(dev, 0x40, &art); p += sprintf(p, "Active: 0x%02x", art); (void) pci_read_config_byte(dev, 0x42, &art); p += sprintf(p, " 0x%02x", art); (void) pci_read_config_byte(dev, 0x44, &art); p += sprintf(p, " 0x%02x", art); (void) pci_read_config_byte(dev, 0x46, &art); p += sprintf(p, " 0x%02x\n", art); (void) pci_read_config_byte(dev, 0x41, &art); p += sprintf(p, "Recovery: 0x%02x", art); (void) pci_read_config_byte(dev, 0x43, &art); p += sprintf(p, " 0x%02x", art); (void) pci_read_config_byte(dev, 0x45, &art); p += sprintf(p, " 0x%02x", art); (void) pci_read_config_byte(dev, 0x47, &art); p += sprintf(p, " 0x%02x\n", art);#endif /* DEBUG_AEC_REGS */ } else { /* * case PCI_DEVICE_ID_ARTOP_ATP860: * case PCI_DEVICE_ID_ARTOP_ATP860R: * case PCI_DEVICE_ID_ARTOP_ATP865: * case PCI_DEVICE_ID_ARTOP_ATP865R: */ (void) pci_read_config_byte(dev, 0x44, &art); p += sprintf(p, "DMA Mode: %s(%s)", (c0&0x20)?((art&0x07)?"UDMA":" DMA"):" PIO", ((art&0x07)==0x07)?"6": ((art&0x06)==0x06)?"5": ((art&0x05)==0x05)?"4": ((art&0x04)==0x04)?"3": ((art&0x03)==0x03)?"2": ((art&0x02)==0x02)?"1": ((art&0x01)==0x01)?"0":"?"); p += sprintf(p, " %s(%s)", (c0&0x40)?((art&0x70)?"UDMA":" DMA"):" PIO", ((art&0x70)==0x70)?"6": ((art&0x60)==0x60)?"5": ((art&0x50)==0x50)?"4": ((art&0x40)==0x40)?"3": ((art&0x30)==0x30)?"2": ((art&0x20)==0x20)?"1": ((art&0x10)==0x10)?"0":"?"); (void) pci_read_config_byte(dev, 0x45, &art); p += sprintf(p, " %s(%s)", (c1&0x20)?((art&0x07)?"UDMA":" DMA"):" PIO", ((art&0x07)==0x07)?"6": ((art&0x06)==0x06)?"5": ((art&0x05)==0x05)?"4": ((art&0x04)==0x04)?"3": ((art&0x03)==0x03)?"2": ((art&0x02)==0x02)?"1": ((art&0x01)==0x01)?"0":"?"); p += sprintf(p, " %s(%s)\n", (c1&0x40)?((art&0x70)?"UDMA":" DMA"):" PIO", ((art&0x70)==0x70)?"6": ((art&0x60)==0x60)?"5": ((art&0x50)==0x50)?"4": ((art&0x40)==0x40)?"3": ((art&0x30)==0x30)?"2": ((art&0x20)==0x20)?"1": ((art&0x10)==0x10)?"0":"?");#ifdef DEBUG_AEC_REGS (void) pci_read_config_byte(dev, 0x40, &art); p += sprintf(p, "Active: 0x%02x", HIGH_4(art)); (void) pci_read_config_byte(dev, 0x41, &art); p += sprintf(p, " 0x%02x", HIGH_4(art)); (void) pci_read_config_byte(dev, 0x42, &art); p += sprintf(p, " 0x%02x", HIGH_4(art)); (void) pci_read_config_byte(dev, 0x43, &art); p += sprintf(p, " 0x%02x\n", HIGH_4(art)); (void) pci_read_config_byte(dev, 0x40, &art); p += sprintf(p, "Recovery: 0x%02x", LOW_4(art)); (void) pci_read_config_byte(dev, 0x41, &art); p += sprintf(p, " 0x%02x", LOW_4(art)); (void) pci_read_config_byte(dev, 0x42, &art); p += sprintf(p, " 0x%02x", LOW_4(art)); (void) pci_read_config_byte(dev, 0x43, &art); p += sprintf(p, " 0x%02x\n", LOW_4(art)); (void) pci_read_config_byte(dev, 0x49, &uart); p += sprintf(p, "reg49h = 0x%02x ", uart); (void) pci_read_config_byte(dev, 0x4a, &uart); p += sprintf(p, "reg4ah = 0x%02x\n", uart);#endif /* DEBUG_AEC_REGS */ } } /* p - buffer must be less than 4k! */ len = (p - buffer) - offset; *addr = buffer + offset; return len > count ? count : len;}#endif /* defined(DISPLAY_AEC62xx_TIMINGS) && defined(CONFIG_PROC_FS) *//* * TO DO: active tuning and correction of cards without a bios. */static u8 pci_bus_clock_list (u8 speed, struct chipset_bus_clock_list_entry * chipset_table){ for ( ; chipset_table->xfer_speed ; chipset_table++) if (chipset_table->xfer_speed == speed) { return chipset_table->chipset_settings; } return chipset_table->chipset_settings;}static u8 pci_bus_clock_list_ultra (u8 speed, struct chipset_bus_clock_list_entry * chipset_table){ for ( ; chipset_table->xfer_speed ; chipset_table++) if (chipset_table->xfer_speed == speed) { return chipset_table->ultra_settings; } return chipset_table->ultra_settings;}static u8 aec62xx_ratemask (ide_drive_t *drive){ ide_hwif_t *hwif = HWIF(drive); u8 mode; switch(hwif->pci_dev->device) { case PCI_DEVICE_ID_ARTOP_ATP865: case PCI_DEVICE_ID_ARTOP_ATP865R:#if 0 mode = (hwif->INB(hwif->dma_master) & 0x10) ? 4 : 3;#else mode = (hwif->INB(((hwif->channel) ? hwif->mate->dma_status : hwif->dma_status)) & 0x10) ? 4 : 3;#endif break; case PCI_DEVICE_ID_ARTOP_ATP860: case PCI_DEVICE_ID_ARTOP_ATP860R: mode = 2; break; case PCI_DEVICE_ID_ARTOP_ATP850UF: default: return 1; } if (!eighty_ninty_three(drive)) mode = min(mode, (u8)1); return mode;}static int aec6210_tune_chipset (ide_drive_t *drive, u8 xferspeed){ ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; u16 d_conf = 0; u8 speed = ide_rate_filter(aec62xx_ratemask(drive), xferspeed); u8 ultra = 0, ultra_conf = 0; u8 tmp0 = 0, tmp1 = 0, tmp2 = 0; unsigned long flags; local_irq_save(flags); pci_read_config_word(dev, 0x40|(2*drive->dn), &d_conf); tmp0 = pci_bus_clock_list(speed, BUSCLOCK(dev)); SPLIT_BYTE(tmp0,tmp1,tmp2); MAKE_WORD(d_conf,tmp1,tmp2); pci_write_config_word(dev, 0x40|(2*drive->dn), d_conf); tmp1 = 0x00; tmp2 = 0x00; pci_read_config_byte(dev, 0x54, &ultra); tmp1 = ((0x00 << (2*drive->dn)) | (ultra & ~(3 << (2*drive->dn)))); ultra_conf = pci_bus_clock_list_ultra(speed, BUSCLOCK(dev)); tmp2 = ((ultra_conf << (2*drive->dn)) | (tmp1 & ~(3 << (2*drive->dn)))); pci_write_config_byte(dev, 0x54, tmp2); local_irq_restore(flags); return(ide_config_drive_speed(drive, speed));}static int aec6260_tune_chipset (ide_drive_t *drive, u8 xferspeed){ ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; u8 speed = ide_rate_filter(aec62xx_ratemask(drive), xferspeed); u8 unit = (drive->select.b.unit & 0x01); u8 tmp1 = 0, tmp2 = 0; u8 ultra = 0, drive_conf = 0, ultra_conf = 0; unsigned long flags; local_irq_save(flags); pci_read_config_byte(dev, 0x40|drive->dn, &drive_conf); drive_conf = pci_bus_clock_list(speed, BUSCLOCK(dev)); pci_write_config_byte(dev, 0x40|drive->dn, drive_conf); pci_read_config_byte(dev, (0x44|hwif->channel), &ultra); tmp1 = ((0x00 << (4*unit)) | (ultra & ~(7 << (4*unit)))); ultra_conf = pci_bus_clock_list_ultra(speed, BUSCLOCK(dev)); tmp2 = ((ultra_conf << (4*unit)) | (tmp1 & ~(7 << (4*unit)))); pci_write_config_byte(dev, (0x44|hwif->channel), tmp2); local_irq_restore(flags); return(ide_config_drive_speed(drive, speed));}static int aec62xx_tune_chipset (ide_drive_t *drive, u8 speed)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -