diff options
Diffstat (limited to 'drivers/ide/pci')
-rw-r--r-- | drivers/ide/pci/atiixp.c | 18 | ||||
-rw-r--r-- | drivers/ide/pci/piix.c | 66 | ||||
-rw-r--r-- | drivers/ide/pci/slc90e66.c | 20 | ||||
-rw-r--r-- | drivers/ide/pci/via82cxxx.c | 138 |
4 files changed, 101 insertions, 141 deletions
diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c index ffdffb6379e..524e65de439 100644 --- a/drivers/ide/pci/atiixp.c +++ b/drivers/ide/pci/atiixp.c @@ -46,6 +46,8 @@ static atiixp_ide_timing mdma_timing[] = { static int save_mdma_mode[4]; +static DEFINE_SPINLOCK(atiixp_lock); + /** * atiixp_ratemask - compute rate mask for ATIIXP IDE * @drive: IDE drive to compute for @@ -105,7 +107,7 @@ static int atiixp_ide_dma_host_on(ide_drive_t *drive) unsigned long flags; u16 tmp16; - spin_lock_irqsave(&ide_lock, flags); + spin_lock_irqsave(&atiixp_lock, flags); pci_read_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, &tmp16); if (save_mdma_mode[drive->dn]) @@ -114,7 +116,7 @@ static int atiixp_ide_dma_host_on(ide_drive_t *drive) tmp16 |= (1 << drive->dn); pci_write_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, tmp16); - spin_unlock_irqrestore(&ide_lock, flags); + spin_unlock_irqrestore(&atiixp_lock, flags); return __ide_dma_host_on(drive); } @@ -125,13 +127,13 @@ static int atiixp_ide_dma_host_off(ide_drive_t *drive) unsigned long flags; u16 tmp16; - spin_lock_irqsave(&ide_lock, flags); + spin_lock_irqsave(&atiixp_lock, flags); pci_read_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, &tmp16); tmp16 &= ~(1 << drive->dn); pci_write_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, tmp16); - spin_unlock_irqrestore(&ide_lock, flags); + spin_unlock_irqrestore(&atiixp_lock, flags); return __ide_dma_host_off(drive); } @@ -152,7 +154,7 @@ static void atiixp_tuneproc(ide_drive_t *drive, u8 pio) u32 pio_timing_data; u16 pio_mode_data; - spin_lock_irqsave(&ide_lock, flags); + spin_lock_irqsave(&atiixp_lock, flags); pci_read_config_word(dev, ATIIXP_IDE_PIO_MODE, &pio_mode_data); pio_mode_data &= ~(0x07 << (drive->dn * 4)); @@ -165,7 +167,7 @@ static void atiixp_tuneproc(ide_drive_t *drive, u8 pio) (pio_timing[pio].command_width << (timing_shift + 4)); pci_write_config_dword(dev, ATIIXP_IDE_PIO_TIMING, pio_timing_data); - spin_unlock_irqrestore(&ide_lock, flags); + spin_unlock_irqrestore(&atiixp_lock, flags); } /** @@ -189,7 +191,7 @@ static int atiixp_speedproc(ide_drive_t *drive, u8 xferspeed) speed = ide_rate_filter(atiixp_ratemask(drive), xferspeed); - spin_lock_irqsave(&ide_lock, flags); + spin_lock_irqsave(&atiixp_lock, flags); save_mdma_mode[drive->dn] = 0; if (speed >= XFER_UDMA_0) { @@ -208,7 +210,7 @@ static int atiixp_speedproc(ide_drive_t *drive, u8 xferspeed) } } - spin_unlock_irqrestore(&ide_lock, flags); + spin_unlock_irqrestore(&atiixp_lock, flags); if (speed >= XFER_SW_DMA_0) pio = atiixp_dma_2_pio(speed); diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c index b1e9a8eba6b..edb37f3d558 100644 --- a/drivers/ide/pci/piix.c +++ b/drivers/ide/pci/piix.c @@ -1,13 +1,14 @@ /* - * linux/drivers/ide/pci/piix.c Version 0.44 March 20, 2003 + * linux/drivers/ide/pci/piix.c Version 0.45 May 12, 2006 * * Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> * Copyright (C) 2003 Red Hat Inc <alan@redhat.com> + * Copyright (C) 2006 MontaVista Software, Inc. <source@mvista.com> * * May be copied or modified under the terms of the GNU General Public License * - * PIO mode setting function for Intel chipsets. + * PIO mode setting function for Intel chipsets. * For use instead of BIOS settings. * * 40-41 @@ -25,7 +26,7 @@ * sitre = word42 & 0x4000; secondary * * 44 8421|8421 hdd|hdb - * + * * 48 8421 hdd|hdc|hdb|hda udma enabled * * 0001 hda @@ -353,56 +354,24 @@ static int piix_tune_chipset (ide_drive_t *drive, u8 xferspeed) } /** - * piix_faulty_dma0 - check for DMA0 errata - * @hwif: IDE interface to check - * - * If an ICH/ICH0/ICH2 interface is is operating in multi-word - * DMA mode with 600nS cycle time the IDE PIO prefetch buffer will - * inadvertently provide an extra piece of secondary data to the primary - * device resulting in data corruption. - * - * With such a device this test function returns true. This allows - * our tuning code to follow Intel recommendations and use PIO on - * such devices. - */ - -static int piix_faulty_dma0(ide_hwif_t *hwif) -{ - switch(hwif->pci_dev->device) - { - case PCI_DEVICE_ID_INTEL_82801AA_1: /* ICH */ - case PCI_DEVICE_ID_INTEL_82801AB_1: /* ICH0 */ - case PCI_DEVICE_ID_INTEL_82801BA_8: /* ICH2 */ - case PCI_DEVICE_ID_INTEL_82801BA_9: /* ICH2 */ - return 1; - } - return 0; -} - -/** * piix_config_drive_for_dma - configure drive for DMA * @drive: IDE drive to configure * * Set up a PIIX interface channel for the best available speed. - * We prefer UDMA if it is available and then MWDMA. If DMA is - * not available we switch to PIO and return 0. + * We prefer UDMA if it is available and then MWDMA. If DMA is + * not available we switch to PIO and return 0. */ static int piix_config_drive_for_dma (ide_drive_t *drive) { u8 speed = ide_dma_speed(drive, piix_ratemask(drive)); - - /* Some ICH devices cannot support DMA mode 0 */ - if(speed == XFER_MW_DMA_0 && piix_faulty_dma0(HWIF(drive))) - speed = 0; - - /* If no DMA speed was available or the chipset has DMA bugs - then disable DMA and use PIO */ - - if (!speed || no_piix_dma) { - u8 tspeed = ide_get_best_pio_mode(drive, 255, 5, NULL); - speed = piix_dma_2_pio(XFER_PIO_0 + tspeed); - } + + /* + * If no DMA speed was available or the chipset has DMA bugs + * then disable DMA and use PIO + */ + if (!speed || no_piix_dma) + return 0; (void) piix_tune_chipset(drive, speed); return ide_dma_enable(drive); @@ -425,17 +394,16 @@ static int piix_config_drive_xfer_rate (ide_drive_t *drive) if ((id->capability & 1) && drive->autodma) { - if (ide_use_dma(drive)) { - if (piix_config_drive_for_dma(drive)) - return hwif->ide_dma_on(drive); - } + if (ide_use_dma(drive) && piix_config_drive_for_dma(drive)) + return hwif->ide_dma_on(drive); goto fast_ata_pio; } else if ((id->capability & 8) || (id->field_valid & 2)) { fast_ata_pio: /* Find best PIO mode. */ - hwif->tuneproc(drive, 255); + (void) hwif->speedproc(drive, XFER_PIO_0 + + ide_get_best_pio_mode(drive, 255, 4, NULL)); return hwif->ide_dma_off_quietly(drive); } /* IORDY not supported */ diff --git a/drivers/ide/pci/slc90e66.c b/drivers/ide/pci/slc90e66.c index 4a1853af3bb..9be7e49cba0 100644 --- a/drivers/ide/pci/slc90e66.c +++ b/drivers/ide/pci/slc90e66.c @@ -1,9 +1,10 @@ /* - * linux/drivers/ide/pci/slc90e66.c Version 0.11 September 11, 2002 + * linux/drivers/ide/pci/slc90e66.c Version 0.12 May 12, 2006 * * Copyright (C) 2000-2002 Andre Hedrick <andre@linux-ide.org> + * Copyright (C) 2006 MontaVista Software, Inc. <source@mvista.com> * - * This a look-a-like variation of the ICH0 PIIX4 Ultra-66, + * This is a look-alike variation of the ICH0 PIIX4 Ultra-66, * but this keeps the ISA-Bridge and slots alive. * */ @@ -158,10 +159,8 @@ static int slc90e66_config_drive_for_dma (ide_drive_t *drive) { u8 speed = ide_dma_speed(drive, slc90e66_ratemask(drive)); - if (!(speed)) { - u8 tspeed = ide_get_best_pio_mode(drive, 255, 5, NULL); - speed = slc90e66_dma_2_pio(XFER_PIO_0 + tspeed); - } + if (!speed) + return 0; (void) slc90e66_tune_chipset(drive, speed); return ide_dma_enable(drive); @@ -176,16 +175,15 @@ static int slc90e66_config_drive_xfer_rate (ide_drive_t *drive) if (id && (id->capability & 1) && drive->autodma) { - if (ide_use_dma(drive)) { - if (slc90e66_config_drive_for_dma(drive)) - return hwif->ide_dma_on(drive); - } + if (ide_use_dma(drive) && slc90e66_config_drive_for_dma(drive)) + return hwif->ide_dma_on(drive); goto fast_ata_pio; } else if ((id->capability & 8) || (id->field_valid & 2)) { fast_ata_pio: - hwif->tuneproc(drive, 5); + (void) hwif->speedproc(drive, XFER_PIO_0 + + ide_get_best_pio_mode(drive, 255, 4, NULL)); return hwif->ide_dma_off_quietly(drive); } /* IORDY not supported */ diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c index 61f1a9665a7..381cc6f101c 100644 --- a/drivers/ide/pci/via82cxxx.c +++ b/drivers/ide/pci/via82cxxx.c @@ -123,7 +123,7 @@ struct via82cxxx_dev static void via_set_speed(ide_hwif_t *hwif, u8 dn, struct ide_timing *timing) { struct pci_dev *dev = hwif->pci_dev; - struct via82cxxx_dev *vdev = ide_get_hwifdata(hwif); + struct via82cxxx_dev *vdev = pci_get_drvdata(hwif->pci_dev); u8 t; if (~vdev->via_config->flags & VIA_BAD_AST) { @@ -162,7 +162,7 @@ static void via_set_speed(ide_hwif_t *hwif, u8 dn, struct ide_timing *timing) static int via_set_drive(ide_drive_t *drive, u8 speed) { ide_drive_t *peer = HWIF(drive)->drives + (~drive->dn & 1); - struct via82cxxx_dev *vdev = ide_get_hwifdata(drive->hwif); + struct via82cxxx_dev *vdev = pci_get_drvdata(drive->hwif->pci_dev); struct ide_timing t, p; unsigned int T, UT; @@ -225,7 +225,7 @@ static void via82cxxx_tune_drive(ide_drive_t *drive, u8 pio) static int via82cxxx_ide_dma_check (ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); - struct via82cxxx_dev *vdev = ide_get_hwifdata(hwif); + struct via82cxxx_dev *vdev = pci_get_drvdata(hwif->pci_dev); u16 w80 = hwif->udma_four; u16 speed = ide_find_best_mode(drive, @@ -262,6 +262,53 @@ static struct via_isa_bridge *via_config_find(struct pci_dev **isa) return via_config; } +/* + * Check and handle 80-wire cable presence + */ +static void __devinit via_cable_detect(struct via82cxxx_dev *vdev, u32 u) +{ + int i; + + switch (vdev->via_config->flags & VIA_UDMA) { + case VIA_UDMA_66: + for (i = 24; i >= 0; i -= 8) + if (((u >> (i & 16)) & 8) && + ((u >> i) & 0x20) && + (((u >> i) & 7) < 2)) { + /* + * 2x PCI clock and + * UDMA w/ < 3T/cycle + */ + vdev->via_80w |= (1 << (1 - (i >> 4))); + } + break; + + case VIA_UDMA_100: + for (i = 24; i >= 0; i -= 8) + if (((u >> i) & 0x10) || + (((u >> i) & 0x20) && + (((u >> i) & 7) < 4))) { + /* BIOS 80-wire bit or + * UDMA w/ < 60ns/cycle + */ + vdev->via_80w |= (1 << (1 - (i >> 4))); + } + break; + + case VIA_UDMA_133: + for (i = 24; i >= 0; i -= 8) + if (((u >> i) & 0x10) || + (((u >> i) & 0x20) && + (((u >> i) & 7) < 6))) { + /* BIOS 80-wire bit or + * UDMA w/ < 60ns/cycle + */ + vdev->via_80w |= (1 << (1 - (i >> 4))); + } + break; + } +} + /** * init_chipset_via82cxxx - initialization handler * @dev: PCI device @@ -274,14 +321,22 @@ static struct via_isa_bridge *via_config_find(struct pci_dev **isa) static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const char *name) { struct pci_dev *isa = NULL; + struct via82cxxx_dev *vdev; struct via_isa_bridge *via_config; u8 t, v; - unsigned int u; + u32 u; + + vdev = kzalloc(sizeof(*vdev), GFP_KERNEL); + if (!vdev) { + printk(KERN_ERR "VP_IDE: out of memory :(\n"); + return -ENOMEM; + } + pci_set_drvdata(dev, vdev); /* * Find the ISA bridge to see how good the IDE is. */ - via_config = via_config_find(&isa); + vdev->via_config = via_config = via_config_find(&isa); /* We checked this earlier so if it fails here deeep badness is involved */ @@ -289,16 +344,17 @@ static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const BUG_ON(!via_config->id); /* - * Setup or disable Clk66 if appropriate + * Detect cable and configure Clk66 */ + pci_read_config_dword(dev, VIA_UDMA_TIMING, &u); + + via_cable_detect(vdev, u); if ((via_config->flags & VIA_UDMA) == VIA_UDMA_66) { /* Enable Clk66 */ - pci_read_config_dword(dev, VIA_UDMA_TIMING, &u); pci_write_config_dword(dev, VIA_UDMA_TIMING, u|0x80008); } else if (via_config->flags & VIA_BAD_CLK66) { /* Would cause trouble on 596a and 686 */ - pci_read_config_dword(dev, VIA_UDMA_TIMING, &u); pci_write_config_dword(dev, VIA_UDMA_TIMING, u & ~0x80008); } @@ -367,75 +423,11 @@ static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const return 0; } -/* - * Check and handle 80-wire cable presence - */ -static void __devinit via_cable_detect(struct pci_dev *dev, struct via82cxxx_dev *vdev) -{ - unsigned int u; - int i; - pci_read_config_dword(dev, VIA_UDMA_TIMING, &u); - - switch (vdev->via_config->flags & VIA_UDMA) { - - case VIA_UDMA_66: - for (i = 24; i >= 0; i -= 8) - if (((u >> (i & 16)) & 8) && - ((u >> i) & 0x20) && - (((u >> i) & 7) < 2)) { - /* - * 2x PCI clock and - * UDMA w/ < 3T/cycle - */ - vdev->via_80w |= (1 << (1 - (i >> 4))); - } - break; - - case VIA_UDMA_100: - for (i = 24; i >= 0; i -= 8) - if (((u >> i) & 0x10) || - (((u >> i) & 0x20) && - (((u >> i) & 7) < 4))) { - /* BIOS 80-wire bit or - * UDMA w/ < 60ns/cycle - */ - vdev->via_80w |= (1 << (1 - (i >> 4))); - } - break; - - case VIA_UDMA_133: - for (i = 24; i >= 0; i -= 8) - if (((u >> i) & 0x10) || - (((u >> i) & 0x20) && - (((u >> i) & 7) < 6))) { - /* BIOS 80-wire bit or - * UDMA w/ < 60ns/cycle - */ - vdev->via_80w |= (1 << (1 - (i >> 4))); - } - break; - - } -} - static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif) { - struct via82cxxx_dev *vdev = kmalloc(sizeof(struct via82cxxx_dev), - GFP_KERNEL); - struct pci_dev *isa = NULL; + struct via82cxxx_dev *vdev = pci_get_drvdata(hwif->pci_dev); int i; - if (vdev == NULL) { - printk(KERN_ERR "VP_IDE: out of memory :(\n"); - return; - } - - memset(vdev, 0, sizeof(struct via82cxxx_dev)); - ide_set_hwifdata(hwif, vdev); - - vdev->via_config = via_config_find(&isa); - via_cable_detect(hwif->pci_dev, vdev); - hwif->autodma = 0; hwif->tuneproc = &via82cxxx_tune_drive; |