static void __devinit init_hwif_siimage(ide_hwif_t *hwif) { hwif->autodma = 0; hwif->resetproc = &siimage_reset; hwif->speedproc = &siimage_tune_chipset; hwif->tuneproc = &siimage_tuneproc; hwif->reset_poll = &siimage_reset_poll; hwif->pre_reset = &siimage_pre_reset; if(is_sata(hwif)) { static int first = 1; hwif->busproc = &siimage_busproc; if (first) { printk(KERN_INFO "siimage: For full SATA support you should use the libata sata_sil module.\n"); first = 0; } } if (!hwif->dma_base) { hwif->drives[0].autotune = 1; hwif->drives[1].autotune = 1; return; } hwif->ultra_mask = 0x7f; hwif->mwdma_mask = 0x07; hwif->swdma_mask = 0x07; if (!is_sata(hwif)) hwif->atapi_dma = 1; hwif->ide_dma_check = &siimage_config_drive_for_dma; if (!(hwif->udma_four)) hwif->udma_four = ata66_siimage(hwif); if (hwif->mmio) { hwif->ide_dma_test_irq = &siimage_mmio_ide_dma_test_irq; } else { hwif->ide_dma_test_irq = & siimage_io_ide_dma_test_irq; } /* * The BIOS often doesn't set up DMA on this controller * so we always do it. */ hwif->autodma = 1; hwif->drives[0].autodma = hwif->autodma; hwif->drives[1].autodma = hwif->autodma; }
static void __init init_hwif_siimage (ide_hwif_t *hwif) { hwif->autodma = 0; hwif->resetproc = &siimage_reset; hwif->speedproc = &siimage_tune_chipset; hwif->tuneproc = &siimage_tuneproc; hwif->reset_poll = &siimage_reset_poll; hwif->pre_reset = &siimage_pre_reset; if(is_sata(hwif)) { hwif->busproc = &siimage_busproc; hwif->sata = 1; } if (!hwif->dma_base) { hwif->drives[0].autotune = 1; hwif->drives[1].autotune = 1; return; } hwif->ultra_mask = 0x7f; hwif->mwdma_mask = 0x07; hwif->swdma_mask = 0x07; if (!is_sata(hwif)) hwif->atapi_dma = 1; hwif->ide_dma_check = &siimage_config_drive_for_dma; if (!(hwif->udma_four)) hwif->udma_four = ata66_siimage(hwif); if (hwif->mmio) { hwif->ide_dma_count = &siimage_mmio_ide_dma_count; hwif->ide_dma_test_irq = &siimage_mmio_ide_dma_test_irq; hwif->ide_dma_verbose = &siimage_mmio_ide_dma_verbose; } else { hwif->ide_dma_test_irq = & siimage_io_ide_dma_test_irq; } /* * The BIOS often doesn't set up DMA on this controller * so we always do it. */ hwif->autodma = 1; hwif->drives[0].autodma = hwif->autodma; hwif->drives[1].autodma = hwif->autodma; }
static byte siimage_ratemask (ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); u8 mode = 0, scsc = 0; unsigned long base = (unsigned long) hwif->hwif_data; if (hwif->mmio) scsc = hwif->INB(base + 0x4A); else pci_read_config_byte(hwif->pci_dev, 0x8A, &scsc); if(is_sata(hwif)) { if(strstr(drive->id->model, "Maxtor")) return 3; return 4; } if ((scsc & 0x30) == 0x10) /* 133 */ mode = 4; else if ((scsc & 0x30) == 0x20) /* 2xPCI */ mode = 4; else if ((scsc & 0x30) == 0x00) /* 100 */ mode = 3; else /* Disabled ? */ BUG(); if (!eighty_ninty_three(drive)) mode = min(mode, (u8)1); return mode; }
static void sil_quirkproc(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; if (!is_sata(hwif) || !is_dev_seagate_sata(drive)) hwif->rqsize = 128; }
static void __devinit sil_quirkproc(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; /* Try and rise the rqsize */ if (!is_sata(hwif) || !is_dev_seagate_sata(drive)) hwif->rqsize = 128; }
static void sil_set_dma_mode(ide_drive_t *drive, const u8 speed) { u8 ultra6[] = { 0x0F, 0x0B, 0x07, 0x05, 0x03, 0x02, 0x01 }; u8 ultra5[] = { 0x0C, 0x07, 0x05, 0x04, 0x02, 0x01 }; u16 dma[] = { 0x2208, 0x10C2, 0x10C1 }; ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = to_pci_dev(hwif->dev); u16 ultra = 0, multi = 0; u8 mode = 0, unit = drive->select.b.unit; unsigned long base = (unsigned long)hwif->hwif_data; u8 scsc = 0, addr_mask = ((hwif->channel) ? ((hwif->mmio) ? 0xF4 : 0x84) : ((hwif->mmio) ? 0xB4 : 0x80)); unsigned long ma = siimage_seldev(drive, 0x08); unsigned long ua = siimage_seldev(drive, 0x0C); if (hwif->mmio) { scsc = hwif->INB(base + 0x4A); mode = hwif->INB(base + addr_mask); multi = hwif->INW(ma); ultra = hwif->INW(ua); } else { pci_read_config_byte(dev, 0x8A, &scsc); pci_read_config_byte(dev, addr_mask, &mode); pci_read_config_word(dev, ma, &multi); pci_read_config_word(dev, ua, &ultra); } mode &= ~((unit) ? 0x30 : 0x03); ultra &= ~0x3F; scsc = ((scsc & 0x30) == 0x00) ? 0 : 1; scsc = is_sata(hwif) ? 1 : scsc; if (speed >= XFER_UDMA_0) { multi = dma[2]; ultra |= (scsc ? ultra6[speed - XFER_UDMA_0] : ultra5[speed - XFER_UDMA_0]); mode |= (unit ? 0x30 : 0x03); } else { multi = dma[speed - XFER_MW_DMA_0]; mode |= (unit ? 0x20 : 0x02); } if (hwif->mmio) { hwif->OUTB(mode, base + addr_mask); hwif->OUTW(multi, ma); hwif->OUTW(ultra, ua); } else { pci_write_config_byte(dev, addr_mask, mode); pci_write_config_word(dev, ma, multi); pci_write_config_word(dev, ua, ultra); } }
static void siimage_pre_reset (ide_drive_t *drive) { if (drive->media != ide_disk) return; if (is_sata(HWIF(drive))) { drive->special.b.set_geometry = 0; drive->special.b.recalibrate = 0; } }
static void __init init_iops_siimage (ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; u32 class_rev = 0; pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); class_rev &= 0xff; hwif->hwif_data = 0; hwif->rqsize = 128; if (is_sata(hwif)) hwif->rqsize = 15; if (pci_get_drvdata(dev) == NULL) return; init_mmio_iops_siimage(hwif); }
static void sil_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive) { static const u8 ultra6[] = { 0x0F, 0x0B, 0x07, 0x05, 0x03, 0x02, 0x01 }; static const u8 ultra5[] = { 0x0C, 0x07, 0x05, 0x04, 0x02, 0x01 }; static const u16 dma[] = { 0x2208, 0x10C2, 0x10C1 }; struct pci_dev *dev = to_pci_dev(hwif->dev); unsigned long base = (unsigned long)hwif->hwif_data; u16 ultra = 0, multi = 0; u8 mode = 0, unit = drive->dn & 1; u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; u8 scsc = 0, addr_mask = hwif->channel ? (mmio ? 0xF4 : 0x84) : (mmio ? 0xB4 : 0x80); unsigned long ma = siimage_seldev(drive, 0x08); unsigned long ua = siimage_seldev(drive, 0x0C); const u8 speed = drive->dma_mode; scsc = sil_ioread8 (dev, base + (mmio ? 0x4A : 0x8A)); mode = sil_ioread8 (dev, base + addr_mask); multi = sil_ioread16(dev, ma); ultra = sil_ioread16(dev, ua); mode &= ~(unit ? 0x30 : 0x03); ultra &= ~0x3F; scsc = ((scsc & 0x30) == 0x00) ? 0 : 1; scsc = is_sata(hwif) ? 1 : scsc; if (speed >= XFER_UDMA_0) { multi = dma[2]; ultra |= scsc ? ultra6[speed - XFER_UDMA_0] : ultra5[speed - XFER_UDMA_0]; mode |= unit ? 0x30 : 0x03; } else { multi = dma[speed - XFER_MW_DMA_0]; mode |= unit ? 0x20 : 0x02; } sil_iowrite8 (dev, mode, base + addr_mask); sil_iowrite16(dev, multi, ma); sil_iowrite16(dev, ultra, ua); }
static void __devinit init_hwif_siimage(ide_hwif_t *hwif) { u8 sata = is_sata(hwif); hwif->set_pio_mode = &sil_set_pio_mode; hwif->set_dma_mode = &sil_set_dma_mode; hwif->quirkproc = &sil_quirkproc; if (sata) { static int first = 1; hwif->busproc = &sil_sata_busproc; hwif->reset_poll = &sil_sata_reset_poll; hwif->pre_reset = &sil_sata_pre_reset; hwif->udma_filter = &sil_sata_udma_filter; if (first) { printk(KERN_INFO "siimage: For full SATA support you should use the libata sata_sil module.\n"); first = 0; } } else hwif->udma_filter = &sil_pata_udma_filter; hwif->cable_detect = ata66_siimage; if (hwif->dma_base == 0) return; if (sata) hwif->host_flags |= IDE_HFLAG_NO_ATAPI_DMA; if (hwif->mmio) { hwif->ide_dma_test_irq = &siimage_mmio_ide_dma_test_irq; } else { hwif->ide_dma_test_irq = & siimage_io_ide_dma_test_irq; } }
static void __init init_mmio_iops_siimage (ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; void *addr = pci_get_drvdata(dev); u8 ch = hwif->channel; hw_regs_t hw; unsigned long base; /* * Fill in the basic HWIF bits */ default_hwif_mmiops(hwif); hwif->hwif_data = addr; /* * Now set up the hw. We have to do this ourselves as * the MMIO layout isnt the same as the the standard port * based I/O */ memset(&hw, 0, sizeof(hw_regs_t)); hw.priv = addr; base = (unsigned long)addr; if(ch) base += 0xC0; else base += 0x80; /* * The buffered task file doesn't have status/control * so we can't currently use it sanely since we want to * use LBA48 mode. */ // base += 0x10; // hwif->addressing = 1; hw.io_ports[IDE_DATA_OFFSET] = base; hw.io_ports[IDE_ERROR_OFFSET] = base + 1; hw.io_ports[IDE_NSECTOR_OFFSET] = base + 2; hw.io_ports[IDE_SECTOR_OFFSET] = base + 3; hw.io_ports[IDE_LCYL_OFFSET] = base + 4; hw.io_ports[IDE_HCYL_OFFSET] = base + 5; hw.io_ports[IDE_SELECT_OFFSET] = base + 6; hw.io_ports[IDE_STATUS_OFFSET] = base + 7; hw.io_ports[IDE_CONTROL_OFFSET] = base + 10; hw.io_ports[IDE_IRQ_OFFSET] = 0; if (pdev_is_sata(dev)) { base = (unsigned long) addr; if(ch) base += 0x80; hw.sata_scr[SATA_STATUS_OFFSET] = base + 0x104; hw.sata_scr[SATA_ERROR_OFFSET] = base + 0x108; hw.sata_scr[SATA_CONTROL_OFFSET]= base + 0x100; hw.sata_misc[SATA_MISC_OFFSET] = base + 0x140; hw.sata_misc[SATA_PHY_OFFSET] = base + 0x144; hw.sata_misc[SATA_IEN_OFFSET] = base + 0x148; } hw.irq = hwif->pci_dev->irq; memcpy(&hwif->hw, &hw, sizeof(hw)); memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->hw.io_ports)); if (is_sata(hwif)) { memcpy(hwif->sata_scr, hwif->hw.sata_scr, sizeof(hwif->hw.sata_scr)); memcpy(hwif->sata_misc, hwif->hw.sata_misc, sizeof(hwif->hw.sata_misc)); } hwif->irq = hw.irq; base = (unsigned long) addr; #ifdef SIIMAGE_LARGE_DMA /* Watch the brackets - even Ken and Dennis get some language design wrong */ hwif->dma_base = base + (ch ? 0x18 : 0x10); hwif->dma_base2 = base + (ch ? 0x08 : 0x00); hwif->dma_prdtable = hwif->dma_base2 + 4; #else /* ! SIIMAGE_LARGE_DMA */ hwif->dma_base = base + (ch ? 0x08 : 0x00); hwif->dma_base2 = base + (ch ? 0x18 : 0x10); #endif /* SIIMAGE_LARGE_DMA */ hwif->mmio = 2; }
static int siimage_tune_chipset (ide_drive_t *drive, byte xferspeed) { u8 ultra6[] = { 0x0F, 0x0B, 0x07, 0x05, 0x03, 0x02, 0x01 }; u8 ultra5[] = { 0x0C, 0x07, 0x05, 0x04, 0x02, 0x01 }; u16 dma[] = { 0x2208, 0x10C2, 0x10C1 }; ide_hwif_t *hwif = HWIF(drive); u16 ultra = 0, multi = 0; u8 mode = 0, unit = drive->select.b.unit; u8 speed = ide_rate_filter(siimage_ratemask(drive), xferspeed); unsigned long base = (unsigned long)hwif->hwif_data; u8 scsc = 0, addr_mask = ((hwif->channel) ? ((hwif->mmio) ? 0xF4 : 0x84) : ((hwif->mmio) ? 0xB4 : 0x80)); unsigned long ma = siimage_seldev(drive, 0x08); unsigned long ua = siimage_seldev(drive, 0x0C); if (hwif->mmio) { scsc = hwif->INB(base + 0x4A); mode = hwif->INB(base + addr_mask); multi = hwif->INW(ma); ultra = hwif->INW(ua); } else { pci_read_config_byte(hwif->pci_dev, 0x8A, &scsc); pci_read_config_byte(hwif->pci_dev, addr_mask, &mode); pci_read_config_word(hwif->pci_dev, ma, &multi); pci_read_config_word(hwif->pci_dev, ua, &ultra); } mode &= ~((unit) ? 0x30 : 0x03); ultra &= ~0x3F; scsc = ((scsc & 0x30) == 0x00) ? 0 : 1; scsc = is_sata(hwif) ? 1 : scsc; switch(speed) { case XFER_PIO_4: case XFER_PIO_3: case XFER_PIO_2: case XFER_PIO_1: case XFER_PIO_0: siimage_tuneproc(drive, (speed - XFER_PIO_0)); mode |= ((unit) ? 0x10 : 0x01); break; case XFER_MW_DMA_2: case XFER_MW_DMA_1: case XFER_MW_DMA_0: multi = dma[speed - XFER_MW_DMA_0]; mode |= ((unit) ? 0x20 : 0x02); config_siimage_chipset_for_pio(drive, 0); break; case XFER_UDMA_6: case XFER_UDMA_5: case XFER_UDMA_4: case XFER_UDMA_3: case XFER_UDMA_2: case XFER_UDMA_1: case XFER_UDMA_0: multi = dma[2]; ultra |= ((scsc) ? (ultra6[speed - XFER_UDMA_0]) : (ultra5[speed - XFER_UDMA_0])); mode |= ((unit) ? 0x30 : 0x03); config_siimage_chipset_for_pio(drive, 0); break; default: return 1; } if (hwif->mmio) { hwif->OUTB(mode, base + addr_mask); hwif->OUTW(multi, ma); hwif->OUTW(ultra, ua); } else { pci_write_config_byte(hwif->pci_dev, addr_mask, mode); pci_write_config_word(hwif->pci_dev, ma, multi); pci_write_config_word(hwif->pci_dev, ua, ultra); } return (ide_config_drive_speed(drive, speed)); }
static void __devinit siimage_fixup(ide_hwif_t *hwif) { /* Try and raise the rqsize */ if (!is_sata(hwif) || !is_dev_seagate_sata(&hwif->drives[0])) hwif->rqsize = 128; }