📄 cmd64x.c
字号:
default: speedt = 0x328A; break; } pci_write_config_word(dev, drive_pci, speedt);}static void config_cmd64x_chipset_for_pio (ide_drive_t *drive, byte set_speed){ byte speed = 0x00; byte set_pio = ide_get_best_pio_mode(drive, 4, 5, NULL); cmd64x_tuneproc(drive, set_pio); speed = XFER_PIO_0 + set_pio; if (set_speed) (void) ide_config_drive_speed(drive, speed);}static void config_cmd680_chipset_for_pio (ide_drive_t *drive, byte set_speed){ ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; u8 unit = (drive->select.b.unit & 0x01); u8 addr_mask = (hwif->channel) ? 0x84 : 0x80; u8 speed = 0x00; u8 mode_pci = 0x00; u8 channel_timings = cmd680_taskfile_timing(hwif); u8 set_pio = ide_get_best_pio_mode(drive, 4, 5, NULL); pci_read_config_byte(dev, addr_mask, &mode_pci); mode_pci &= ~((unit) ? 0x30 : 0x03); /* WARNING PIO timing mess is going to happen b/w devices, argh */ if ((channel_timings != set_pio) && (set_pio > channel_timings)) set_pio = channel_timings; cmd680_tuneproc(drive, set_pio); speed = XFER_PIO_0 + set_pio; if (set_speed) { (void) ide_config_drive_speed(drive, speed); drive->current_speed = speed; }}static void config_chipset_for_pio (ide_drive_t *drive, byte set_speed){ if (HWIF(drive)->pci_dev->device == PCI_DEVICE_ID_CMD_680) { config_cmd680_chipset_for_pio(drive, set_speed); } else { config_cmd64x_chipset_for_pio(drive, set_speed); }}static int cmd64x_tune_chipset (ide_drive_t *drive, byte speed){#ifdef CONFIG_BLK_DEV_IDEDMA ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; int err = 0; u8 unit = (drive->select.b.unit & 0x01); u8 pciU = (hwif->channel) ? UDIDETCR1 : UDIDETCR0; u8 pciD = (hwif->channel) ? BMIDESR1 : BMIDESR0; u8 regU = 0; u8 regD = 0; if ((drive->media != ide_disk) && (speed < XFER_SW_DMA_0)) return 1; (void) pci_read_config_byte(dev, pciD, ®D); (void) pci_read_config_byte(dev, pciU, ®U); regD &= ~(unit ? 0x40 : 0x20); regU &= ~(unit ? 0xCA : 0x35); (void) pci_write_config_byte(dev, pciD, regD); (void) pci_write_config_byte(dev, pciU, regU); (void) pci_read_config_byte(dev, pciD, ®D); (void) pci_read_config_byte(dev, pciU, ®U); switch(speed) { case XFER_UDMA_5: regU |= (unit ? 0x0A : 0x05); break; case XFER_UDMA_4: regU |= (unit ? 0x4A : 0x15); break; case XFER_UDMA_3: regU |= (unit ? 0x8A : 0x25); break; case XFER_UDMA_2: regU |= (unit ? 0x42 : 0x11); break; case XFER_UDMA_1: regU |= (unit ? 0x82 : 0x21); break; case XFER_UDMA_0: regU |= (unit ? 0xC2 : 0x31); break; case XFER_MW_DMA_2: regD |= (unit ? 0x40 : 0x10); break; case XFER_MW_DMA_1: regD |= (unit ? 0x80 : 0x20); break; case XFER_MW_DMA_0: regD |= (unit ? 0xC0 : 0x30); break; case XFER_SW_DMA_2: regD |= (unit ? 0x40 : 0x10); break; case XFER_SW_DMA_1: regD |= (unit ? 0x80 : 0x20); break; case XFER_SW_DMA_0: regD |= (unit ? 0xC0 : 0x30); break;#else int err = 0; switch(speed) {#endif /* CONFIG_BLK_DEV_IDEDMA */ case XFER_PIO_4: cmd64x_tuneproc(drive, 4); break; case XFER_PIO_3: cmd64x_tuneproc(drive, 3); break; case XFER_PIO_2: cmd64x_tuneproc(drive, 2); break; case XFER_PIO_1: cmd64x_tuneproc(drive, 1); break; case XFER_PIO_0: cmd64x_tuneproc(drive, 0); break; default: return 1; }#ifdef CONFIG_BLK_DEV_IDEDMA (void) pci_write_config_byte(dev, pciU, regU);#endif /* CONFIG_BLK_DEV_IDEDMA */ err = ide_config_drive_speed(drive, speed); drive->current_speed = speed;#ifdef CONFIG_BLK_DEV_IDEDMA regD |= (unit ? 0x40 : 0x20); (void) pci_write_config_byte(dev, pciD, regD);#endif /* CONFIG_BLK_DEV_IDEDMA */ return err;}static int cmd680_tune_chipset (ide_drive_t *drive, byte speed){ ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; u8 addr_mask = (hwif->channel) ? 0x84 : 0x80; u8 unit = (drive->select.b.unit & 0x01); u8 dma_pci = 0; u8 udma_pci = 0; u8 mode_pci = 0; u8 scsc = 0; u16 ultra = 0; u16 multi = 0; int err = 0; pci_read_config_byte(dev, addr_mask, &mode_pci); pci_read_config_byte(dev, 0x8A, &scsc); switch (drive->dn) { case 0: dma_pci = 0xA8; udma_pci = 0xAC; break; case 1: dma_pci = 0xAA; udma_pci = 0xAE; break; case 2: dma_pci = 0xB8; udma_pci = 0xBC; break; case 3: dma_pci = 0xBA; udma_pci = 0xBE; break; default: return 1; } pci_read_config_byte(dev, addr_mask, &mode_pci); mode_pci &= ~((unit) ? 0x30 : 0x03); pci_read_config_word(dev, dma_pci, &multi); pci_read_config_word(dev, udma_pci, &ultra); if ((speed == XFER_UDMA_6) && (scsc & 0x30) == 0x00) { pci_write_config_byte(dev, 0x8A, scsc|0x01); pci_read_config_byte(dev, 0x8A, &scsc); } switch(speed) {#ifdef CONFIG_BLK_DEV_IDEDMA case XFER_UDMA_6: if ((scsc & 0x30) == 0x00) goto speed_break; multi = 0x10C1; ultra &= ~0x3F; ultra |= 0x01; break;speed_break : speed = XFER_UDMA_5; case XFER_UDMA_5: multi = 0x10C1; ultra &= ~0x3F; ultra |= (((scsc & 0x30) == 0x00) ? 0x01 : 0x02); break; case XFER_UDMA_4: multi = 0x10C1; ultra &= ~0x3F; ultra |= (((scsc & 0x30) == 0x00) ? 0x02 : 0x03); break; case XFER_UDMA_3: multi = 0x10C1; ultra &= ~0x3F; ultra |= (((scsc & 0x30) == 0x00) ? 0x04 : 0x05); break; case XFER_UDMA_2: multi = 0x10C1; ultra &= ~0x3F; ultra |= (((scsc & 0x30) == 0x00) ? 0x05 : 0x07); break; case XFER_UDMA_1: multi = 0x10C1; ultra &= ~0x3F; ultra |= (((scsc & 0x30) == 0x00) ? 0x07 : 0x0B); break; case XFER_UDMA_0: multi = 0x10C1; ultra &= ~0x3F; ultra |= (((scsc & 0x30) == 0x00) ? 0x0C : 0x0F); break; case XFER_MW_DMA_2: multi = 0x10C1; break; case XFER_MW_DMA_1: multi = 0x10C2; break; case XFER_MW_DMA_0: multi = 0x2208; break;#endif /* CONFIG_BLK_DEV_IDEDMA */ case XFER_PIO_4: cmd680_tuneproc(drive, 4); break; case XFER_PIO_3: cmd680_tuneproc(drive, 3); break; case XFER_PIO_2: cmd680_tuneproc(drive, 2); break; case XFER_PIO_1: cmd680_tuneproc(drive, 1); break; case XFER_PIO_0: cmd680_tuneproc(drive, 0); break; default: return 1; } if (speed >= XFER_MW_DMA_0) config_cmd680_chipset_for_pio(drive, 0); if (speed >= XFER_UDMA_0) mode_pci |= ((unit) ? 0x30 : 0x03); else if (speed >= XFER_MW_DMA_0) mode_pci |= ((unit) ? 0x20 : 0x02); else mode_pci |= ((unit) ? 0x10 : 0x01); pci_write_config_byte(dev, addr_mask, mode_pci); pci_write_config_word(dev, dma_pci, multi); pci_write_config_word(dev, udma_pci, ultra); err = ide_config_drive_speed(drive, speed); drive->current_speed = speed; return err;}#ifdef CONFIG_BLK_DEV_IDEDMAstatic int config_cmd64x_chipset_for_dma (ide_drive_t *drive, unsigned int rev, byte ultra_66){ struct hd_driveid *id = drive->id; ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; byte speed = 0x00; byte set_pio = 0x00; byte udma_33 = ((rev >= 0x05) || (ultra_66)) ? 1 : 0; byte udma_66 = eighty_ninty_three(drive); byte udma_100 = 0; int rval; switch(dev->device) { case PCI_DEVICE_ID_CMD_649: udma_100 = 1; break; case PCI_DEVICE_ID_CMD_648: case PCI_DEVICE_ID_CMD_646: case PCI_DEVICE_ID_CMD_643: default: break; } if (drive->media != ide_disk) { cmdprintk("CMD64X: drive->media != ide_disk at double check, inital check failed!!\n"); return ((int) ide_dma_off); } /* UltraDMA only supported on PCI646U and PCI646U2, * which correspond to revisions 0x03, 0x05 and 0x07 respectively. * Actually, although the CMD tech support people won't * tell me the details, the 0x03 revision cannot support * UDMA correctly without hardware modifications, and even * then it only works with Quantum disks due to some * hold time assumptions in the 646U part which are fixed * in the 646U2. * So we only do UltraDMA on revision 0x05 and 0x07 chipsets. */ if ((id->dma_ultra & 0x0020) && (udma_100) && (udma_66) && (udma_33)) { speed = XFER_UDMA_5; } else if ((id->dma_ultra & 0x0010) && (udma_66) && (udma_33)) { speed = XFER_UDMA_4; } else if ((id->dma_ultra & 0x0008) && (udma_66) && (udma_33)) { speed = XFER_UDMA_3; } else if ((id->dma_ultra & 0x0004) && (udma_33)) { speed = XFER_UDMA_2; } else if ((id->dma_ultra & 0x0002) && (udma_33)) { speed = XFER_UDMA_1; } else if ((id->dma_ultra & 0x0001) && (udma_33)) { 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 if (id->dma_1word & 0x0004) { speed = XFER_SW_DMA_2; } else if (id->dma_1word & 0x0002) { speed = XFER_SW_DMA_1; } else if (id->dma_1word & 0x0001) { speed = XFER_SW_DMA_0; } else { set_pio = 1; } if (!drive->init_speed) drive->init_speed = speed; config_chipset_for_pio(drive, set_pio); if (set_pio) return ((int) ide_dma_off_quietly); if (cmd64x_tune_chipset(drive, speed)) return ((int) ide_dma_off); 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 : ((id->dma_1word >> 8) & 7) ? ide_dma_on : ide_dma_off_quietly); return rval;}static int config_cmd680_chipset_for_dma (ide_drive_t *drive){ struct hd_driveid *id = drive->id; byte udma_66 = eighty_ninty_three(drive); byte speed = 0x00; byte set_pio = 0x00; int rval; if ((id->dma_ultra & 0x0040) && (udma_66)) speed = XFER_UDMA_6; else if ((id->dma_ultra & 0x0020) && (udma_66)) speed = XFER_UDMA_5; else if ((id->dma_ultra & 0x0010) && (udma_66)) speed = XFER_UDMA_4; else if ((id->dma_ultra & 0x0008) && (udma_66)) speed = XFER_UDMA_3; else 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 { set_pio = 1; } if (!drive->init_speed) drive->init_speed = speed; config_chipset_for_pio(drive, set_pio); if (set_pio) return ((int) ide_dma_off_quietly); if (cmd680_tune_chipset(drive, speed)) return ((int) ide_dma_off); rval = (int)( ((id->dma_ultra >> 14) & 3) ? ide_dma_on : ((id->dma_ultra >> 11) & 7) ? ide_dma_on : ((id->dma_ultra >> 8) & 7) ? ide_dma_on : ((id->dma_mword >> 8) & 7) ? ide_dma_on : ((id->dma_1word >> 8) & 7) ? ide_dma_on : ide_dma_off_quietly); return rval;}static int config_chipset_for_dma (ide_drive_t *drive, unsigned int rev, byte ultra_66){ if (HWIF(drive)->pci_dev->device == PCI_DEVICE_ID_CMD_680) return (config_cmd680_chipset_for_dma(drive)); return (config_cmd64x_chipset_for_dma(drive, rev, ultra_66));}static int cmd64x_config_drive_for_dma (ide_drive_t *drive){ struct hd_driveid *id = drive->id; ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; unsigned int class_rev = 0; byte can_ultra_33 = 0; byte can_ultra_66 = 0; byte can_ultra_100 = 0; byte can_ultra_133 = 0; ide_dma_action_t dma_func = ide_dma_on; pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); class_rev &= 0xff; switch(dev->device) { case PCI_DEVICE_ID_CMD_680: can_ultra_133 = 1; case PCI_DEVICE_ID_CMD_649:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -