?? sis5513.c
字號:
default: p += sprintf(p, "133+ ?"); break; } p += sprintf(p, "\n"); }/* Data Active */ p += sprintf(p, " Data Active Time "); switch(chipset_family) { case ATA_00: case ATA_16: /* confirmed */ case ATA_33: case ATA_66: case ATA_100a: p += sprintf(p, active_time[reg01 & 0x07]); break; case ATA_100: case ATA_133a: p += sprintf(p, active_time[(reg00 & 0x70) >> 4]); break; case ATA_133: default: p += sprintf(p, "133+ ?"); break; } p += sprintf(p, " \t Data Active Time "); switch(chipset_family) { case ATA_00: case ATA_16: case ATA_33: case ATA_66: case ATA_100a: p += sprintf(p, active_time[reg11 & 0x07]); break; case ATA_100: case ATA_133a: p += sprintf(p, active_time[(reg10 & 0x70) >> 4]); break; case ATA_133: default: p += sprintf(p, "133+ ?"); break; } p += sprintf(p, "\n");/* Data Recovery */ /* warning: may need (reg&0x07) for pre ATA66 chips */ if (chipset_family < ATA_133) { p += sprintf(p, " Data Recovery Time %s \t Data Recovery Time %s\n", recovery_time[reg00 & 0x0f], recovery_time[reg10 & 0x0f]); } return p;}static char* get_masters_info(char* buffer){ return get_drives_info(buffer, 0);}static char* get_slaves_info(char* buffer){ return get_drives_info(buffer, 1);}/* Main get_info, called on /proc/ide/sis reads */static int sis_get_info (char *buffer, char **addr, off_t offset, int count){ char *p = buffer; int len; u8 reg; u16 reg2, reg3; p += sprintf(p, "\nSiS 5513 "); switch(chipset_family) { case ATA_00: p += sprintf(p, "Unknown???"); break; case ATA_16: p += sprintf(p, "DMA 16"); break; case ATA_33: p += sprintf(p, "Ultra 33"); break; case ATA_66: p += sprintf(p, "Ultra 66"); break; case ATA_100a: case ATA_100: p += sprintf(p, "Ultra 100"); break; case ATA_133a: case ATA_133: p += sprintf(p, "Ultra 133"); break; default: p+= sprintf(p, "Unknown???"); break; } p += sprintf(p, " chipset\n"); p += sprintf(p, "--------------- Primary Channel " "---------------- Secondary Channel " "-------------\n");/* Status */ pci_read_config_byte(bmide_dev, 0x4a, ®); if (chipset_family == ATA_133) { pci_read_config_word(bmide_dev, 0x50, ®2); pci_read_config_word(bmide_dev, 0x52, ®3); } p += sprintf(p, "Channel Status: "); if (chipset_family < ATA_66) { p += sprintf(p, "%s \t \t \t \t %s\n", (reg & 0x04) ? "On" : "Off", (reg & 0x02) ? "On" : "Off"); } else if (chipset_family < ATA_133) { p += sprintf(p, "%s \t \t \t \t %s \n", (reg & 0x02) ? "On" : "Off", (reg & 0x04) ? "On" : "Off"); } else { /* ATA_133 */ p += sprintf(p, "%s \t \t \t \t %s \n", (reg2 & 0x02) ? "On" : "Off", (reg3 & 0x02) ? "On" : "Off"); }/* Operation Mode */ pci_read_config_byte(bmide_dev, 0x09, ®); p += sprintf(p, "Operation Mode: %s \t \t \t %s \n", (reg & 0x01) ? "Native" : "Compatible", (reg & 0x04) ? "Native" : "Compatible");/* 80-pin cable ? */ if (chipset_family >= ATA_133) { p += sprintf(p, "Cable Type: %s \t \t \t %s\n", (reg2 & 0x01) ? cable_type[1] : cable_type[0], (reg3 & 0x01) ? cable_type[1] : cable_type[0]); } else if (chipset_family > ATA_33) { pci_read_config_byte(bmide_dev, 0x48, ®); p += sprintf(p, "Cable Type: %s \t \t \t %s\n", (reg & 0x10) ? cable_type[1] : cable_type[0], (reg & 0x20) ? cable_type[1] : cable_type[0]); }/* Prefetch Count */ if (chipset_family < ATA_133) { pci_read_config_word(bmide_dev, 0x4c, ®2); pci_read_config_word(bmide_dev, 0x4e, ®3); p += sprintf(p, "Prefetch Count: %d \t \t \t \t %d\n", reg2, reg3); } p = get_masters_info(p); p = get_slaves_info(p); len = (p - buffer) - offset; *addr = buffer + offset; return len > count ? count : len;}#endif /* defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS) */static u8 sis5513_ratemask (ide_drive_t *drive){#if 0 u8 rates[] = { 0, 0, 1, 2, 3, 3, 4, 4 }; u8 mode = rates[chipset_family];#else u8 mode; switch(chipset_family) { case ATA_133: case ATA_133a: mode = 4; break; case ATA_100: case ATA_100a: mode = 3; break; case ATA_66: mode = 2; break; case ATA_33: return 1; case ATA_16: case ATA_00: default: return 0; }#endif if (!eighty_ninty_three(drive)) mode = min(mode, (u8)1); return mode;}/* * Configuration functions *//* Enables per-drive prefetch and postwrite */static void config_drive_art_rwp (ide_drive_t *drive){ ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; u8 reg4bh = 0; u8 rw_prefetch = (0x11 << drive->dn);#ifdef DEBUG printk("SIS5513: config_drive_art_rwp, drive %d\n", drive->dn); sis5513_load_verify_registers(dev, "config_drive_art_rwp start");#endif if (drive->media != ide_disk) return; pci_read_config_byte(dev, 0x4b, ®4bh); if ((reg4bh & rw_prefetch) != rw_prefetch) pci_write_config_byte(dev, 0x4b, reg4bh|rw_prefetch);#ifdef DEBUG sis5513_load_verify_registers(dev, "config_drive_art_rwp end");#endif}/* Set per-drive active and recovery time */static void config_art_rwp_pio (ide_drive_t *drive, u8 pio){ ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; u8 timing, drive_pci, test1, test2; u16 eide_pio_timing[6] = {600, 390, 240, 180, 120, 90}; u16 xfer_pio = drive->id->eide_pio_modes;#ifdef DEBUG sis5513_load_verify_registers(dev, "config_drive_art_rwp_pio start");#endif config_drive_art_rwp(drive); pio = ide_get_best_pio_mode(drive, 255, pio, 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 : xfer_pio; } timing = (xfer_pio >= pio) ? xfer_pio : pio;#ifdef DEBUG printk("SIS5513: config_drive_art_rwp_pio, " "drive %d, pio %d, timing %d\n", drive->dn, pio, timing);#endif /* In pre ATA_133 case, drives sit at 0x40 + 4*drive->dn */ drive_pci = 0x40; /* In SiS962 case drives sit at (0x40 or 0x70) + 8*drive->dn) */ if (chipset_family >= ATA_133) { u32 reg54h; pci_read_config_dword(dev, 0x54, ®54h); if (reg54h & 0x40000000) drive_pci = 0x70; drive_pci += ((drive->dn)*0x4); } else { drive_pci += ((drive->dn)*0x2); } /* register layout changed with newer ATA100 chips */ if (chipset_family < ATA_100) { pci_read_config_byte(dev, drive_pci, &test1); pci_read_config_byte(dev, drive_pci+1, &test2); /* Clear active and recovery timings */ test1 &= ~0x0F; test2 &= ~0x07; switch(timing) { case 4: test1 |= 0x01; test2 |= 0x03; break; case 3: test1 |= 0x03; test2 |= 0x03; break; case 2: test1 |= 0x04; test2 |= 0x04; break; case 1: test1 |= 0x07; test2 |= 0x06; break; default: break; } pci_write_config_byte(dev, drive_pci, test1); pci_write_config_byte(dev, drive_pci+1, test2); } else if (chipset_family < ATA_133) { switch(timing) { /* active recovery v v */ case 4: test1 = 0x30|0x01; break; case 3: test1 = 0x30|0x03; break; case 2: test1 = 0x40|0x04; break; case 1: test1 = 0x60|0x07; break; default: break; } pci_write_config_byte(dev, drive_pci, test1); } else { /* ATA_133 */ u32 test3; pci_read_config_dword(dev, drive_pci, &test3); test3 &= 0xc0c00fff; if (test3 & 0x08) { test3 |= (unsigned long)ini_time_value[ATA_133-ATA_00][timing] << 12; test3 |= (unsigned long)act_time_value[ATA_133-ATA_00][timing] << 16; test3 |= (unsigned long)rco_time_value[ATA_133-ATA_00][timing] << 24; } else { test3 |= (unsigned long)ini_time_value[ATA_100-ATA_00][timing] << 12; test3 |= (unsigned long)act_time_value[ATA_100-ATA_00][timing] << 16; test3 |= (unsigned long)rco_time_value[ATA_100-ATA_00][timing] << 24; } pci_write_config_dword(dev, drive_pci, test3); }#ifdef DEBUG sis5513_load_verify_registers(dev, "config_drive_art_rwp_pio start");#endif}static int config_chipset_for_pio (ide_drive_t *drive, u8 pio){#if 0 config_art_rwp_pio(drive, pio); return ide_config_drive_speed(drive, (XFER_PIO_0 + pio));#else u8 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; } config_art_rwp_pio(drive, pio); return ide_config_drive_speed(drive, speed);#endif}static int sis5513_tune_chipset (ide_drive_t *drive, u8 xferspeed){ ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; u8 drive_pci, reg, speed; u32 regdw;#ifdef DEBUG sis5513_load_verify_registers(dev, "sis5513_tune_chipset start");#endif#ifdef BROKEN_LEVEL#ifdef DEBUG printk("SIS5513: BROKEN_LEVEL activated, speed=%d -> speed=%d\n", xferspeed, BROKEN_LEVEL);#endif if (xferspeed > BROKEN_LEVEL) xferspeed = BROKEN_LEVEL;#endif speed = ide_rate_filter(sis5513_ratemask(drive), xferspeed);#ifdef DEBUG printk("SIS5513: sis5513_tune_chipset, drive %d, speed %d\n", drive->dn, xferspeed);#endif /* See config_art_rwp_pio for drive pci config registers */ drive_pci = 0x40; if (chipset_family >= ATA_133) { u32 reg54h; pci_read_config_dword(dev, 0x54, ®54h); if (reg54h & 0x40000000) drive_pci = 0x70; drive_pci += ((drive->dn)*0x4); pci_read_config_dword(dev, (unsigned long)drive_pci, ®dw); /* Disable UDMA bit for non UDMA modes on UDMA chips */ if (speed < XFER_UDMA_0) { regdw &= 0xfffffffb; pci_write_config_dword(dev, (unsigned long)drive_pci, regdw); } } else { drive_pci += ((drive->dn)*0x2); pci_read_config_byte(dev, drive_pci+1, ®); /* Disable UDMA bit for non UDMA modes on UDMA chips */ if ((speed < XFER_UDMA_0) && (chipset_family > ATA_16)) { reg &= 0x7F; pci_write_config_byte(dev, drive_pci+1, reg); } } /* Config chip for mode */ switch(speed) {
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -