diff options
Diffstat (limited to 'drivers/ide/pci/piix.c')
-rw-r--r-- | drivers/ide/pci/piix.c | 171 |
1 files changed, 87 insertions, 84 deletions
diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c index f04738d14a6..d63f9fdca76 100644 --- a/drivers/ide/pci/piix.c +++ b/drivers/ide/pci/piix.c @@ -48,12 +48,13 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/pci.h> -#include <linux/hdreg.h> #include <linux/ide.h> #include <linux/init.h> #include <asm/io.h> +#define DRV_NAME "piix" + static int no_piix_dma; /** @@ -198,13 +199,12 @@ static void piix_set_dma_mode(ide_drive_t *drive, const u8 speed) /** * init_chipset_ich - set up the ICH chipset * @dev: PCI device to set up - * @name: Name of the device * * Initialize the PCI device as required. For the ICH this turns * out to be nice and simple. */ -static unsigned int __devinit init_chipset_ich(struct pci_dev *dev, const char *name) +static unsigned int init_chipset_ich(struct pci_dev *dev) { u32 extra = 0; @@ -215,21 +215,30 @@ static unsigned int __devinit init_chipset_ich(struct pci_dev *dev, const char * } /** - * piix_dma_clear_irq - clear BMDMA status - * @drive: IDE drive to clear + * ich_clear_irq - clear BMDMA status + * @drive: IDE drive * - * Called from ide_intr() for PIO interrupts - * to clear BMDMA status as needed by ICHx + * ICHx contollers set DMA INTR no matter DMA or PIO. + * BMDMA status might need to be cleared even for + * PIO interrupts to prevent spurious/lost IRQ. */ -static void piix_dma_clear_irq(ide_drive_t *drive) +static void ich_clear_irq(ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); u8 dma_stat; + /* + * ide_dma_end() needs BMDMA status for error checking. + * So, skip clearing BMDMA status here and leave it + * to ide_dma_end() if this is DMA interrupt. + */ + if (drive->waiting_for_dma || hwif->dma_base == 0) + return; + /* clear the INTR & ERROR bits */ - dma_stat = inb(hwif->dma_status); + dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS); /* Should we force the bit as well ? */ - outb(dma_stat, hwif->dma_status); + outb(dma_stat, hwif->dma_base + ATA_DMA_STATUS); } struct ich_laptop { @@ -249,13 +258,14 @@ static const struct ich_laptop ich_laptop[] = { { 0x27DF, 0x1025, 0x0110 }, /* ICH7 on Acer 3682WLMi */ { 0x27DF, 0x1043, 0x1267 }, /* ICH7 on Asus W5F */ { 0x27DF, 0x103C, 0x30A1 }, /* ICH7 on HP Compaq nc2400 */ + { 0x27DF, 0x1071, 0xD221 }, /* ICH7 on Hercules EC-900 */ { 0x24CA, 0x1025, 0x0061 }, /* ICH4 on Acer Aspire 2023WLMi */ { 0x2653, 0x1043, 0x82D8 }, /* ICH6M on Asus Eee 701 */ /* end marker */ { 0, } }; -static u8 __devinit piix_cable_detect(ide_hwif_t *hwif) +static u8 piix_cable_detect(ide_hwif_t *hwif) { struct pci_dev *pdev = to_pci_dev(hwif->dev); const struct ich_laptop *lap = &ich_laptop[0]; @@ -293,30 +303,28 @@ static void __devinit init_hwif_piix(ide_hwif_t *hwif) hwif->ultra_mask = hwif->mwdma_mask = hwif->swdma_mask = 0; } -static void __devinit init_hwif_ich(ide_hwif_t *hwif) -{ - init_hwif_piix(hwif); - - /* ICHx need to clear the BMDMA status for all interrupts */ - if (hwif->dma_base) - hwif->ide_dma_clear_irq = &piix_dma_clear_irq; -} - static const struct ide_port_ops piix_port_ops = { .set_pio_mode = piix_set_pio_mode, .set_dma_mode = piix_set_dma_mode, .cable_detect = piix_cable_detect, }; +static const struct ide_port_ops ich_port_ops = { + .set_pio_mode = piix_set_pio_mode, + .set_dma_mode = piix_set_dma_mode, + .clear_irq = ich_clear_irq, + .cable_detect = piix_cable_detect, +}; + #ifndef CONFIG_IA64 #define IDE_HFLAGS_PIIX IDE_HFLAG_LEGACY_IRQS #else #define IDE_HFLAGS_PIIX 0 #endif -#define DECLARE_PIIX_DEV(name_str, udma) \ +#define DECLARE_PIIX_DEV(udma) \ { \ - .name = name_str, \ + .name = DRV_NAME, \ .init_hwif = init_hwif_piix, \ .enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, \ .port_ops = &piix_port_ops, \ @@ -327,13 +335,13 @@ static const struct ide_port_ops piix_port_ops = { .udma_mask = udma, \ } -#define DECLARE_ICH_DEV(name_str, udma) \ +#define DECLARE_ICH_DEV(udma) \ { \ - .name = name_str, \ + .name = DRV_NAME, \ .init_chipset = init_chipset_ich, \ - .init_hwif = init_hwif_ich, \ + .init_hwif = init_hwif_piix, \ .enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, \ - .port_ops = &piix_port_ops, \ + .port_ops = &ich_port_ops, \ .host_flags = IDE_HFLAGS_PIIX, \ .pio_mask = ATA_PIO4, \ .swdma_mask = ATA_SWDMA2_ONLY, \ @@ -342,45 +350,31 @@ static const struct ide_port_ops piix_port_ops = { } static const struct ide_port_info piix_pci_info[] __devinitdata = { - /* 0 */ DECLARE_PIIX_DEV("PIIXa", 0x00), /* no udma */ - /* 1 */ DECLARE_PIIX_DEV("PIIXb", 0x00), /* no udma */ - - /* 2 */ + /* 0: MPIIX */ { /* * MPIIX actually has only a single IDE channel mapped to * the primary or secondary ports depending on the value * of the bit 14 of the IDETIM register at offset 0x6c */ - .name = "MPIIX", + .name = DRV_NAME, .enablebits = {{0x6d,0xc0,0x80}, {0x6d,0xc0,0xc0}}, .host_flags = IDE_HFLAG_ISA_PORTS | IDE_HFLAG_NO_DMA | IDE_HFLAGS_PIIX, .pio_mask = ATA_PIO4, /* This is a painful system best to let it self tune for now */ }, - - /* 3 */ DECLARE_PIIX_DEV("PIIX3", 0x00), /* no udma */ - /* 4 */ DECLARE_PIIX_DEV("PIIX4", ATA_UDMA2), - /* 5 */ DECLARE_ICH_DEV("ICH0", ATA_UDMA2), - /* 6 */ DECLARE_PIIX_DEV("PIIX4", ATA_UDMA2), - /* 7 */ DECLARE_ICH_DEV("ICH", ATA_UDMA4), - /* 8 */ DECLARE_PIIX_DEV("PIIX4", ATA_UDMA4), - /* 9 */ DECLARE_PIIX_DEV("PIIX4", ATA_UDMA2), - /* 10 */ DECLARE_ICH_DEV("ICH2", ATA_UDMA5), - /* 11 */ DECLARE_ICH_DEV("ICH2M", ATA_UDMA5), - /* 12 */ DECLARE_ICH_DEV("ICH3M", ATA_UDMA5), - /* 13 */ DECLARE_ICH_DEV("ICH3", ATA_UDMA5), - /* 14 */ DECLARE_ICH_DEV("ICH4", ATA_UDMA5), - /* 15 */ DECLARE_ICH_DEV("ICH5", ATA_UDMA5), - /* 16 */ DECLARE_ICH_DEV("C-ICH", ATA_UDMA5), - /* 17 */ DECLARE_ICH_DEV("ICH4", ATA_UDMA5), - /* 18 */ DECLARE_ICH_DEV("ICH5-SATA", ATA_UDMA5), - /* 19 */ DECLARE_ICH_DEV("ICH5", ATA_UDMA5), - /* 20 */ DECLARE_ICH_DEV("ICH6", ATA_UDMA5), - /* 21 */ DECLARE_ICH_DEV("ICH7", ATA_UDMA5), - /* 22 */ DECLARE_ICH_DEV("ICH4", ATA_UDMA5), - /* 23 */ DECLARE_ICH_DEV("ESB2", ATA_UDMA5), - /* 24 */ DECLARE_ICH_DEV("ICH8M", ATA_UDMA5), + /* 1: PIIXa/PIIXb/PIIX3 */ + DECLARE_PIIX_DEV(0x00), /* no udma */ + /* 2: PIIX4 */ + DECLARE_PIIX_DEV(ATA_UDMA2), + /* 3: ICH0 */ + DECLARE_ICH_DEV(ATA_UDMA2), + /* 4: ICH */ + DECLARE_ICH_DEV(ATA_UDMA4), + /* 5: PIIX4 */ + DECLARE_PIIX_DEV(ATA_UDMA4), + /* 6: ICH[2-7]/ICH[2-3]M/C-ICH/ICH5-SATA/ESB2/ICH8M */ + DECLARE_ICH_DEV(ATA_UDMA5), }; /** @@ -394,7 +388,7 @@ static const struct ide_port_info piix_pci_info[] __devinitdata = { static int __devinit piix_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - return ide_setup_pci_device(dev, &piix_pci_info[id->driver_data]); + return ide_pci_init_one(dev, &piix_pci_info[id->driver_data], NULL); } /** @@ -421,56 +415,65 @@ static void __devinit piix_check_450nx(void) no_piix_dma = 2; } if(no_piix_dma) - printk(KERN_WARNING "piix: 450NX errata present, disabling IDE DMA.\n"); + printk(KERN_WARNING DRV_NAME ": 450NX errata present, disabling IDE DMA.\n"); if(no_piix_dma == 2) - printk(KERN_WARNING "piix: A BIOS update may resolve this.\n"); + printk(KERN_WARNING DRV_NAME ": A BIOS update may resolve this.\n"); } static const struct pci_device_id piix_pci_tbl[] = { - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82371FB_0), 0 }, - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82371FB_1), 1 }, - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82371MX), 2 }, - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82371SB_1), 3 }, - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82371AB), 4 }, - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801AB_1), 5 }, - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82443MX_1), 6 }, - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801AA_1), 7 }, - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82372FB_1), 8 }, - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82451NX), 9 }, - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801BA_9), 10 }, - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801BA_8), 11 }, - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801CA_10), 12 }, - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801CA_11), 13 }, - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801DB_11), 14 }, - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801EB_11), 15 }, - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801E_11), 16 }, - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801DB_10), 17 }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82371FB_0), 1 }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82371FB_1), 1 }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82371MX), 0 }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82371SB_1), 1 }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82371AB), 2 }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801AB_1), 3 }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82443MX_1), 2 }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801AA_1), 4 }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82372FB_1), 5 }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82451NX), 2 }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801BA_9), 6 }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801BA_8), 6 }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801CA_10), 6 }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801CA_11), 6 }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801DB_11), 6 }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801EB_11), 6 }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801E_11), 6 }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801DB_10), 6 }, #ifdef CONFIG_BLK_DEV_IDE_SATA - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801EB_1), 18 }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801EB_1), 6 }, #endif - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ESB_2), 19 }, - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ICH6_19), 20 }, - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ICH7_21), 21 }, - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801DB_1), 22 }, - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ESB2_18), 23 }, - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ICH8_6), 24 }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ESB_2), 6 }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ICH6_19), 6 }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ICH7_21), 6 }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801DB_1), 6 }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ESB2_18), 6 }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ICH8_6), 6 }, { 0, }, }; MODULE_DEVICE_TABLE(pci, piix_pci_tbl); -static struct pci_driver driver = { +static struct pci_driver piix_pci_driver = { .name = "PIIX_IDE", .id_table = piix_pci_tbl, .probe = piix_init_one, + .remove = ide_pci_remove, + .suspend = ide_pci_suspend, + .resume = ide_pci_resume, }; static int __init piix_ide_init(void) { piix_check_450nx(); - return ide_pci_register_driver(&driver); + return ide_pci_register_driver(&piix_pci_driver); +} + +static void __exit piix_ide_exit(void) +{ + pci_unregister_driver(&piix_pci_driver); } module_init(piix_ide_init); +module_exit(piix_ide_exit); MODULE_AUTHOR("Andre Hedrick, Andrzej Krzysztofowicz"); MODULE_DESCRIPTION("PCI driver module for Intel PIIX IDE"); |