diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2007-10-13 05:27:47 +0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2007-10-13 05:27:47 +0400 |
commit | b981d8b3f5e008ff10d993be633ad00564fc22cd (patch) | |
tree | e292dc07b22308912cf6a58354a608b9e5e8e1fd /drivers/ide/pci | |
parent | b11d2127c4893a7315d1e16273bc8560049fa3ca (diff) | |
parent | 2b9e0aae1d50e880c58d46788e5e3ebd89d75d62 (diff) | |
download | linux-b981d8b3f5e008ff10d993be633ad00564fc22cd.tar.xz |
Merge master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts:
drivers/macintosh/adbhid.c
Diffstat (limited to 'drivers/ide/pci')
34 files changed, 824 insertions, 1097 deletions
diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c index e5d09367627e..0d5f62c5dfae 100644 --- a/drivers/ide/pci/aec62xx.c +++ b/drivers/ide/pci/aec62xx.c @@ -87,12 +87,11 @@ static u8 pci_bus_clock_list_ultra (u8 speed, struct chipset_bus_clock_list_entr return chipset_table->ultra_settings; } -static int aec6210_tune_chipset (ide_drive_t *drive, u8 xferspeed) +static int aec6210_tune_chipset(ide_drive_t *drive, const u8 speed) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; u16 d_conf = 0; - u8 speed = ide_rate_filter(drive, xferspeed); u8 ultra = 0, ultra_conf = 0; u8 tmp0 = 0, tmp1 = 0, tmp2 = 0; unsigned long flags; @@ -115,11 +114,10 @@ static int aec6210_tune_chipset (ide_drive_t *drive, u8 xferspeed) return(ide_config_drive_speed(drive, speed)); } -static int aec6260_tune_chipset (ide_drive_t *drive, u8 xferspeed) +static int aec6260_tune_chipset(ide_drive_t *drive, const u8 speed) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; - u8 speed = ide_rate_filter(drive, xferspeed); u8 unit = (drive->select.b.unit & 0x01); u8 tmp1 = 0, tmp2 = 0; u8 ultra = 0, drive_conf = 0, ultra_conf = 0; @@ -140,9 +138,8 @@ static int aec6260_tune_chipset (ide_drive_t *drive, u8 xferspeed) return(ide_config_drive_speed(drive, speed)); } -static void aec62xx_tune_drive (ide_drive_t *drive, u8 pio) +static void aec_set_pio_mode(ide_drive_t *drive, const u8 pio) { - pio = ide_get_best_pio_mode(drive, pio, 4, NULL); (void) HWIF(drive)->speedproc(drive, pio + XFER_PIO_0); } @@ -152,7 +149,7 @@ static int aec62xx_config_drive_xfer_rate (ide_drive_t *drive) return 0; if (ide_use_fast_pio(drive)) - aec62xx_tune_drive(drive, 255); + ide_set_max_pio(drive); return -1; } @@ -174,12 +171,6 @@ static unsigned int __devinit init_chipset_aec62xx(struct pci_dev *dev, const ch { int bus_speed = system_bus_clock(); - if (dev->resource[PCI_ROM_RESOURCE].start) { - pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); - printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", name, - (unsigned long)dev->resource[PCI_ROM_RESOURCE].start); - } - if (bus_speed <= 33) pci_set_drvdata(dev, (void *) aec6xxx_33_base); else @@ -209,7 +200,7 @@ static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif) u8 reg54 = 0, mask = hwif->channel ? 0xf0 : 0x0f; unsigned long flags; - hwif->tuneproc = &aec62xx_tune_drive; + hwif->set_pio_mode = &aec_set_pio_mode; if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) { if(hwif->mate) @@ -271,48 +262,48 @@ static ide_pci_device_t aec62xx_chipsets[] __devinitdata = { .init_setup = init_setup_aec62xx, .init_chipset = init_chipset_aec62xx, .init_hwif = init_hwif_aec62xx, - .channels = 2, .autodma = AUTODMA, .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, .bootable = OFF_BOARD, + .pio_mask = ATA_PIO4, .udma_mask = 0x07, /* udma0-2 */ },{ /* 1 */ .name = "AEC6260", .init_setup = init_setup_aec62xx, .init_chipset = init_chipset_aec62xx, .init_hwif = init_hwif_aec62xx, - .channels = 2, .autodma = NOAUTODMA, .bootable = OFF_BOARD, + .pio_mask = ATA_PIO4, .udma_mask = 0x1f, /* udma0-4 */ },{ /* 2 */ .name = "AEC6260R", .init_setup = init_setup_aec62xx, .init_chipset = init_chipset_aec62xx, .init_hwif = init_hwif_aec62xx, - .channels = 2, .autodma = AUTODMA, .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, .bootable = NEVER_BOARD, + .pio_mask = ATA_PIO4, .udma_mask = 0x1f, /* udma0-4 */ },{ /* 3 */ .name = "AEC6280", .init_setup = init_setup_aec6x80, .init_chipset = init_chipset_aec62xx, .init_hwif = init_hwif_aec62xx, - .channels = 2, .autodma = AUTODMA, .bootable = OFF_BOARD, + .pio_mask = ATA_PIO4, .udma_mask = 0x3f, /* udma0-5 */ },{ /* 4 */ .name = "AEC6280R", .init_setup = init_setup_aec6x80, .init_chipset = init_chipset_aec62xx, .init_hwif = init_hwif_aec62xx, - .channels = 2, .autodma = AUTODMA, .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, .bootable = OFF_BOARD, + .pio_mask = ATA_PIO4, .udma_mask = 0x3f, /* udma0-5 */ } }; diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c index ba0fb92b0417..d04b966b4347 100644 --- a/drivers/ide/pci/alim15x3.c +++ b/drivers/ide/pci/alim15x3.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/alim15x3.c Version 0.25 Jun 9 2007 + * linux/drivers/ide/pci/alim15x3.c Version 0.26 Jul 14 2007 * * Copyright (C) 1998-2000 Michel Aubry, Maintainer * Copyright (C) 1998-2000 Andrzej Krzysztofowicz, Maintainer @@ -283,19 +283,15 @@ static int ali_get_info (char *buffer, char **addr, off_t offset, int count) #endif /* defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_IDE_PROC_FS) */ /** - * ali15x3_tune_pio - set up chipset for PIO mode - * @drive: drive to tune - * @pio: desired mode + * ali_tune_pio - set host controller for PIO mode + * @drive: drive + * @pio: PIO mode number * - * Select the best PIO mode for the drive in question. - * Then program the controller for this mode. - * - * Returns the PIO mode programmed. + * Program the controller for the given PIO mode. */ - -static u8 ali15x3_tune_pio (ide_drive_t *drive, u8 pio) + +static void ali_tune_pio(ide_drive_t *drive, const u8 pio) { - ide_pio_data_t d; ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; int s_time, a_time, c_time; @@ -307,7 +303,6 @@ static u8 ali15x3_tune_pio (ide_drive_t *drive, u8 pio) u8 cd_dma_fifo = 0; int unit = drive->select.b.unit & 1; - pio = ide_get_best_pio_mode(drive, pio, 5, &d); s_time = ide_pio_timings[pio].setup_time; a_time = ide_pio_timings[pio].active_time; if ((s_clc = (s_time * bus_speed + 999) / 1000) >= 8) @@ -360,22 +355,20 @@ static u8 ali15x3_tune_pio (ide_drive_t *drive, u8 pio) * { 25, 70, 25 }, PIO Mode 4 with IORDY ns * { 20, 50, 30 } PIO Mode 5 with IORDY (nonstandard) */ - - return pio; } /** - * ali15x3_tune_drive - set up drive for PIO mode + * ali_set_pio_mode - set up drive for PIO mode * @drive: drive to tune * @pio: desired mode * - * Program the controller with the best PIO timing for the given drive. + * Program the controller with the desired PIO timing for the given drive. * Then set up the drive itself. */ -static void ali15x3_tune_drive (ide_drive_t *drive, u8 pio) +static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio) { - pio = ali15x3_tune_pio(drive, pio); + ali_tune_pio(drive, pio); (void) ide_config_drive_speed(drive, XFER_PIO_0 + pio); } @@ -410,22 +403,24 @@ static u8 ali_udma_filter(ide_drive_t *drive) /** * ali15x3_tune_chipset - set up chipset/drive for new speed * @drive: drive to configure for - * @xferspeed: desired speed + * @speed: desired speed * * Configure the hardware for the desired IDE transfer mode. * We also do the needed drive configuration through helpers */ - -static int ali15x3_tune_chipset (ide_drive_t *drive, u8 xferspeed) + +static int ali15x3_tune_chipset(ide_drive_t *drive, const u8 speed) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; - u8 speed = ide_rate_filter(drive, xferspeed); u8 speed1 = speed; u8 unit = (drive->select.b.unit & 0x01); u8 tmpbyte = 0x00; int m5229_udma = (hwif->channel) ? 0x57 : 0x56; + if (speed < XFER_PIO_0) + return 1; + if (speed == XFER_UDMA_6) speed1 = 0x47; @@ -438,8 +433,9 @@ static int ali15x3_tune_chipset (ide_drive_t *drive, u8 xferspeed) tmpbyte &= ultra_enable; pci_write_config_byte(dev, m5229_udma, tmpbyte); - if (speed < XFER_SW_DMA_0) - (void) ali15x3_tune_pio(drive, speed - XFER_PIO_0); + /* + * FIXME: Oh, my... DMA timings are never set. + */ } else { pci_read_config_byte(dev, m5229_udma, &tmpbyte); tmpbyte &= (0x0f << ((1-unit) << 2)); @@ -472,7 +468,7 @@ static int ali15x3_config_drive_for_dma(ide_drive_t *drive) if (ide_tune_dma(drive)) return 0; - ali15x3_tune_drive(drive, 255); + ide_set_max_pio(drive); return -1; } @@ -589,12 +585,19 @@ out: * Cable special cases */ -static struct dmi_system_id cable_dmi_table[] = { +static const struct dmi_system_id cable_dmi_table[] = { { .ident = "HP Pavilion N5430", .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_BOARD_NAME, "OmniBook N32N-736"), + DMI_MATCH(DMI_BOARD_VERSION, "OmniBook N32N-736"), + }, + }, + { + .ident = "Toshiba Satellite S1800-814", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "S1800-814"), }, }, { } @@ -695,7 +698,7 @@ static u8 __devinit ata66_ali15x3(ide_hwif_t *hwif) static void __devinit init_hwif_common_ali15x3 (ide_hwif_t *hwif) { hwif->autodma = 0; - hwif->tuneproc = &ali15x3_tune_drive; + hwif->set_pio_mode = &ali_set_pio_mode; hwif->speedproc = &ali15x3_tune_chipset; hwif->udma_filter = &ali_udma_filter; @@ -817,9 +820,9 @@ static ide_pci_device_t ali15x3_chipset __devinitdata = { .init_chipset = init_chipset_ali15x3, .init_hwif = init_hwif_ali15x3, .init_dma = init_dma_ali15x3, - .channels = 2, .autodma = AUTODMA, .bootable = ON_BOARD, + .pio_mask = ATA_PIO5, }; /** diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c index 8d30b99a54d8..513205e52ad2 100644 --- a/drivers/ide/pci/amd74xx.c +++ b/drivers/ide/pci/amd74xx.c @@ -1,5 +1,5 @@ /* - * Version 2.20 + * Version 2.22 * * AMD 755/756/766/8111 and nVidia nForce/2/2s/3/3s/CK804/MCP04 * IDE driver for Linux. @@ -234,7 +234,7 @@ static void amd_set_speed(struct pci_dev *dev, unsigned char dn, struct ide_timi * by upper layers. */ -static int amd_set_drive(ide_drive_t *drive, u8 speed) +static int amd_set_drive(ide_drive_t *drive, const u8 speed) { ide_drive_t *peer = HWIF(drive)->drives + (~drive->dn & 1); struct ide_timing t, p; @@ -266,32 +266,21 @@ static int amd_set_drive(ide_drive_t *drive, u8 speed) } /* - * amd74xx_tune_drive() is a callback from upper layers for - * PIO-only tuning. + * amd_set_pio_mode() is a callback from upper layers for PIO-only tuning. */ -static void amd74xx_tune_drive(ide_drive_t *drive, u8 pio) +static void amd_set_pio_mode(ide_drive_t *drive, const u8 pio) { - if (pio == 255) { - amd_set_drive(drive, ide_find_best_pio_mode(drive)); - return; - } - - amd_set_drive(drive, XFER_PIO_0 + min_t(byte, pio, 5)); + amd_set_drive(drive, XFER_PIO_0 + pio); } static int amd74xx_ide_dma_check(ide_drive_t *drive) { - u8 speed = ide_max_dma_mode(drive); - - if (speed == 0) - speed = ide_find_best_pio_mode(drive); - - amd_set_drive(drive, speed); - - if (drive->autodma && (speed & XFER_MODE) != XFER_PIO) + if (ide_tune_dma(drive)) return 0; + ide_set_max_pio(drive); + return -1; } @@ -409,7 +398,7 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif) hwif->autodma = 0; - hwif->tuneproc = &amd74xx_tune_drive; + hwif->set_pio_mode = &amd_set_pio_mode; hwif->speedproc = &amd_set_drive; for (i = 0; i < 2; i++) { @@ -448,10 +437,12 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif) .name = name_str, \ .init_chipset = init_chipset_amd74xx, \ .init_hwif = init_hwif_amd74xx, \ - .channels = 2, \ .autodma = AUTODMA, \ .enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, \ .bootable = ON_BOARD, \ + .host_flags = IDE_HFLAG_PIO_NO_BLACKLIST \ + | IDE_HFLAG_PIO_NO_DOWNGRADE, \ + .pio_mask = ATA_PIO5, \ } #define DECLARE_NV_DEV(name_str) \ @@ -459,10 +450,12 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif) .name = name_str, \ .init_chipset = init_chipset_amd74xx, \ .init_hwif = init_hwif_amd74xx, \ - .channels = 2, \ .autodma = AUTODMA, \ .enablebits = {{0x50,0x02,0x02}, {0x50,0x01,0x01}}, \ .bootable = ON_BOARD, \ + .host_flags = IDE_HFLAG_PIO_NO_BLACKLIST \ + | IDE_HFLAG_PIO_NO_DOWNGRADE, \ + .pio_mask = ATA_PIO5, \ } static ide_pci_device_t amd74xx_chipsets[] __devinitdata = { diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c index 2761510309b3..178876a3afca 100644 --- a/drivers/ide/pci/atiixp.c +++ b/drivers/ide/pci/atiixp.c @@ -1,9 +1,8 @@ /* - * linux/drivers/ide/pci/atiixp.c Version 0.01-bart2 Feb. 26, 2004 + * linux/drivers/ide/pci/atiixp.c Version 0.02 Jun 16 2007 * * Copyright (C) 2003 ATI Inc. <hyu@ati.com> - * Copyright (C) 2004 Bartlomiej Zolnierkiewicz - * + * Copyright (C) 2004,2007 Bartlomiej Zolnierkiewicz */ #include <linux/types.h> @@ -123,14 +122,14 @@ static void atiixp_dma_host_off(ide_drive_t *drive) } /** - * atiixp_tune_drive - tune a drive attached to a ATIIXP + * atiixp_tune_pio - tune a drive attached to a ATIIXP * @drive: drive to tune * @pio: desired PIO mode * * Set the interface PIO mode. */ -static void atiixp_tuneproc(ide_drive_t *drive, u8 pio) +static void atiixp_tune_pio(ide_drive_t *drive, u8 pio) { struct pci_dev *dev = drive->hwif->pci_dev; unsigned long flags; @@ -154,26 +153,30 @@ static void atiixp_tuneproc(ide_drive_t *drive, u8 pio) spin_unlock_irqrestore(&atiixp_lock, flags); } +static void atiixp_set_pio_mode(ide_drive_t *drive, const u8 pio) +{ + atiixp_tune_pio(drive, pio); + (void)ide_config_drive_speed(drive, XFER_PIO_0 + pio); +} + /** * atiixp_tune_chipset - tune a ATIIXP interface * @drive: IDE drive to tune - * @xferspeed: speed to configure + * @speed: speed to configure * * Set a ATIIXP interface channel to the desired speeds. This involves * requires the right timing data into the ATIIXP configuration space * then setting the drive parameters appropriately */ -static int atiixp_speedproc(ide_drive_t *drive, u8 xferspeed) +static int atiixp_speedproc(ide_drive_t *drive, const u8 speed) { struct pci_dev *dev = drive->hwif->pci_dev; unsigned long flags; int timing_shift = (drive->dn & 2) ? 16 : 0 + (drive->dn & 1) ? 0 : 8; u32 tmp32; u16 tmp16; - u8 speed, pio; - - speed = ide_rate_filter(drive, xferspeed); + u8 pio; spin_lock_irqsave(&atiixp_lock, flags); @@ -201,7 +204,7 @@ static int atiixp_speedproc(ide_drive_t *drive, u8 xferspeed) else pio = speed - XFER_PIO_0; - atiixp_tuneproc(drive, pio); + atiixp_tune_pio(drive, pio); return ide_config_drive_speed(drive, speed); } @@ -216,18 +219,13 @@ static int atiixp_speedproc(ide_drive_t *drive, u8 xferspeed) static int atiixp_dma_check(ide_drive_t *drive) { - u8 tspeed, speed; - drive->init_speed = 0; if (ide_tune_dma(drive)) return 0; - if (ide_use_fast_pio(drive)) { - tspeed = ide_get_best_pio_mode(drive, 255, 5, NULL); - speed = atiixp_dma_2_pio(XFER_PIO_0 + tspeed) + XFER_PIO_0; - atiixp_speedproc(drive, speed); - } + if (ide_use_fast_pio(drive)) + ide_set_max_pio(drive); return -1; } @@ -250,7 +248,7 @@ static void __devinit init_hwif_atiixp(ide_hwif_t *hwif) hwif->irq = ch ? 15 : 14; hwif->autodma = 0; - hwif->tuneproc = &atiixp_tuneproc; + hwif->set_pio_mode = &atiixp_set_pio_mode; hwif->speedproc = &atiixp_speedproc; hwif->drives[0].autotune = 1; hwif->drives[1].autotune = 1; @@ -285,17 +283,18 @@ static ide_pci_device_t atiixp_pci_info[] __devinitdata = { { /* 0 */ .name = "ATIIXP", .init_hwif = init_hwif_atiixp, - .channels = 2, .autodma = AUTODMA, .enablebits = {{0x48,0x01,0x00}, {0x48,0x08,0x00}}, .bootable = ON_BOARD, + .pio_mask = ATA_PIO4, },{ /* 1 */ .name = "SB600_PATA", .init_hwif = init_hwif_atiixp, - .channels = 1, .autodma = AUTODMA, .enablebits = {{0x48,0x01,0x00}, {0x00,0x00,0x00}}, .bootable = ON_BOARD, + .host_flags = IDE_HFLAG_SINGLE, + .pio_mask = ATA_PIO4, }, }; @@ -318,7 +317,7 @@ static struct pci_device_id atiixp_pci_tbl[] = { { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, - { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { 0, }, }; MODULE_DEVICE_TABLE(pci, atiixp_pci_tbl); diff --git a/drivers/ide/pci/cmd640.c b/drivers/ide/pci/cmd640.c index dc43f009acab..f369645e4d16 100644 --- a/drivers/ide/pci/cmd640.c +++ b/drivers/ide/pci/cmd640.c @@ -628,50 +628,42 @@ static void cmd640_set_mode (unsigned int index, u8 pio_mode, unsigned int cycle program_drive_counts (index); } -/* - * Drive PIO mode selection: - */ -static void cmd640_tune_drive (ide_drive_t *drive, u8 mode_wanted) +static void cmd640_set_pio_mode(ide_drive_t *drive, const u8 pio) { + unsigned int index = 0, cycle_time; u8 b; - ide_pio_data_t d; - unsigned int index = 0; while (drive != cmd_drives[index]) { if (++index > 3) { - printk("%s: bad news in cmd640_tune_drive\n", drive->name); + printk(KERN_ERR "%s: bad news in %s\n", + drive->name, __FUNCTION__); return; } } - switch (mode_wanted) { + switch (pio) { case 6: /* set fast-devsel off */ case 7: /* set fast-devsel on */ - mode_wanted &= 1; b = get_cmd640_reg(CNTRL) & ~0x27; - if (mode_wanted) + if (pio & 1) b |= 0x27; put_cmd640_reg(CNTRL, b); - printk("%s: %sabled cmd640 fast host timing (devsel)\n", drive->name, mode_wanted ? "en" : "dis"); + printk("%s: %sabled cmd640 fast host timing (devsel)\n", drive->name, (pio & 1) ? "en" : "dis"); return; case 8: /* set prefetch off */ case 9: /* set prefetch on */ - mode_wanted &= 1; - set_prefetch_mode(index, mode_wanted); - printk("%s: %sabled cmd640 prefetch\n", drive->name, mode_wanted ? "en" : "dis"); + set_prefetch_mode(index, pio & 1); + printk("%s: %sabled cmd640 prefetch\n", drive->name, (pio & 1) ? "en" : "dis"); return; } - (void) ide_get_best_pio_mode (drive, mode_wanted, 5, &d); - cmd640_set_mode (index, d.pio_mode, d.cycle_time); + cycle_time = ide_pio_cycle_time(drive, pio); + cmd640_set_mode(index, pio, cycle_time); + + printk("%s: selected cmd640 PIO mode%d (%dns)", + drive->name, pio, cycle_time); - printk ("%s: selected cmd640 PIO mode%d (%dns)%s", - drive->name, - d.pio_mode, - d.cycle_time, - d.overridden ? " (overriding vendor mode)" : ""); display_clocks(index); - return; } #endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */ @@ -769,7 +761,10 @@ int __init ide_probe_for_cmd640x (void) cmd_hwif0->name, 'a' + cmd640_chip_version - 1, bus_type, cfr); cmd_hwif0->chipset = ide_cmd640; #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED - cmd_hwif0->tuneproc = &cmd640_tune_drive; + cmd_hwif0->host_flags = IDE_HFLAG_ABUSE_PREFETCH | + IDE_HFLAG_ABUSE_FAST_DEVSEL; + cmd_hwif0->pio_mask = ATA_PIO5; + cmd_hwif0->set_pio_mode = &cmd640_set_pio_mode; #endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */ /* @@ -824,7 +819,10 @@ int __init ide_probe_for_cmd640x (void) cmd_hwif1->mate = cmd_hwif0; cmd_hwif1->channel = 1; #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED - cmd_hwif1->tuneproc = &cmd640_tune_drive; + cmd_hwif1->host_flags = IDE_HFLAG_ABUSE_PREFETCH | + IDE_HFLAG_ABUSE_FAST_DEVSEL; + cmd_hwif1->pio_mask = ATA_PIO5; + cmd_hwif1->set_pio_mode = &cmd640_set_pio_mode; #endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */ } printk(KERN_INFO "%s: %sserialized, secondary interface %s\n", cmd_hwif1->name, diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c index 1e89dd6e5bbf..0b568c60f926 100644 --- a/drivers/ide/pci/cmd64x.c +++ b/drivers/ide/pci/cmd64x.c @@ -214,27 +214,25 @@ static void program_cycle_times (ide_drive_t *drive, int cycle_time, int active_ } /* - * This routine selects drive's best PIO mode and writes into the chipset - * registers setup/active/recovery timings. + * This routine writes into the chipset registers + * PIO setup/active/recovery timings. */ -static u8 cmd64x_tune_pio (ide_drive_t *drive, u8 mode_wanted) +static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; - ide_pio_data_t pio; - u8 pio_mode, setup_count, arttim = 0; + unsigned int cycle_time; + u8 setup_count, arttim = 0; + static const u8 setup_values[] = {0x40, 0x40, 0x40, 0x80, 0, 0xc0}; static const u8 arttim_regs[4] = {ARTTIM0, ARTTIM1, ARTTIM23, ARTTIM23}; - pio_mode = ide_get_best_pio_mode(drive, mode_wanted, 5, &pio); - cmdprintk("%s: PIO mode wanted %d, selected %d (%d ns)%s\n", - drive->name, mode_wanted, pio_mode, pio.cycle_time, - pio.overridden ? " (overriding vendor mode)" : ""); + cycle_time = ide_pio_cycle_time(drive, pio); - program_cycle_times(drive, pio.cycle_time, - ide_pio_timings[pio_mode].active_time); + program_cycle_times(drive, cycle_time, + ide_pio_timings[pio].active_time); - setup_count = quantize_timing(ide_pio_timings[pio_mode].setup_time, + setup_count = quantize_timing(ide_pio_timings[pio].setup_time, 1000 / system_bus_clock()); /* @@ -265,16 +263,14 @@ static u8 cmd64x_tune_pio (ide_drive_t *drive, u8 mode_wanted) arttim |= setup_values[setup_count]; (void) pci_write_config_byte(dev, arttim_regs[drive->dn], arttim); cmdprintk("Write 0x%02x to reg 0x%x\n", arttim, arttim_regs[drive->dn]); - - return pio_mode; } /* * Attempts to set drive's PIO mode. - * Special cases are 8: prefetch off, 9: prefetch on (both never worked), - * and 255: auto-select best mode (used at boot time). + * Special cases are 8: prefetch off, 9: prefetch on (both never worked) */ -static void cmd64x_tune_drive (ide_drive_t *drive, u8 pio) + +static void cmd64x_set_pio_mode(ide_drive_t *drive, const u8 pio) { /* * Filter out the prefetch control values @@ -283,19 +279,17 @@ static void cmd64x_tune_drive (ide_drive_t *drive, u8 pio) if (pio == 8 || pio == 9) return; - pio = cmd64x_tune_pio(drive, pio); + cmd64x_tune_pio(drive, pio); (void) ide_config_drive_speed(drive, XFER_PIO_0 + pio); } -static int cmd64x_tune_chipset (ide_drive_t *drive, u8 speed) +static int cmd64x_tune_chipset(ide_drive_t *drive, const u8 speed) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; u8 unit = drive->dn & 0x01; u8 regU = 0, pciU = hwif->channel ? UDIDETCR1 : UDIDETCR0; - speed = ide_rate_filter(drive, speed); - if (speed >= XFER_SW_DMA_0) { (void) pci_read_config_byte(dev, pciU, ®U); regU &= ~(unit ? 0xCA : 0x35); @@ -329,14 +323,6 @@ static int cmd64x_tune_chipset (ide_drive_t *drive, u8 speed) case XFER_MW_DMA_0: program_cycle_times(drive, 480, 215); break; - case XFER_PIO_5: - case XFER_PIO_4: - case XFER_PIO_3: - case XFER_PIO_2: - case XFER_PIO_1: - case XFER_PIO_0: - (void) cmd64x_tune_pio(drive, speed - XFER_PIO_0); - break; default: return 1; } @@ -353,7 +339,7 @@ static int cmd64x_config_drive_for_dma (ide_drive_t *drive) return 0; if (ide_use_fast_pio(drive)) - cmd64x_tune_drive(drive, 255); + ide_set_max_pio(drive); return -1; } @@ -474,11 +460,11 @@ static unsigned int __devinit init_chipset_cmd64x(struct pci_dev *dev, const cha switch (rev) { case 0x07: case 0x05: - printk("%s: UltraDMA capable", name); + printk("%s: UltraDMA capable\n", name); break; case 0x03: default: - printk("%s: MultiWord DMA force limited", name); + printk("%s: MultiWord DMA force limited\n", name); break; case 0x01: printk("%s: MultiWord DMA limited, " @@ -537,7 +523,7 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif) pci_read_config_byte(dev, PCI_REVISION_ID, &rev); - hwif->tuneproc = &cmd64x_tune_drive; + hwif->set_pio_mode = &cmd64x_set_pio_mode; hwif->speedproc = &cmd64x_tune_chipset; hwif->drives[0].autotune = hwif->drives[1].autotune = 1; @@ -618,40 +604,44 @@ static ide_pci_device_t cmd64x_chipsets[] __devinitdata = { .init_setup = init_setup_cmd64x, .init_chipset = init_chipset_cmd64x, .init_hwif = init_hwif_cmd64x, - .channels = 2, .autodma = AUTODMA, .enablebits = {{0x00,0x00,0x00}, {0x51,0x08,0x08}}, .bootable = ON_BOARD, + .host_flags = IDE_HFLAG_ABUSE_PREFETCH, + .pio_mask = ATA_PIO5, .udma_mask = 0x00, /* no udma */ },{ /* 1 */ .name = "CMD646", .init_setup = init_setup_cmd646, .init_chipset = init_chipset_cmd64x, .init_hwif = init_hwif_cmd64x, - .channels = 2, .autodma = AUTODMA, .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, .bootable = ON_BOARD, + .host_flags = IDE_HFLAG_ABUSE_PREFETCH, + .pio_mask = ATA_PIO5, .udma_mask = 0x07, /* udma0-2 */ },{ /* 2 */ .name = "CMD648", .init_setup = init_setup_cmd64x, .init_chipset = init_chipset_cmd64x, .init_hwif = init_hwif_cmd64x, - .channels = 2, .autodma = AUTODMA, .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, .bootable = ON_BOARD, + .host_flags = IDE_HFLAG_ABUSE_PREFETCH, + .pio_mask = ATA_PIO5, .udma_mask = 0x1f, /* udma0-4 */ },{ /* 3 */ .name = "CMD649", .init_setup = init_setup_cmd64x, .init_chipset = init_chipset_cmd64x, .init_hwif = init_hwif_cmd64x, - .channels = 2, .autodma = AUTODMA, .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, .bootable = ON_BOARD, + .host_flags = IDE_HFLAG_ABUSE_PREFETCH, + .pio_mask = ATA_PIO5, .udma_mask = 0x3f, /* udma0-5 */ } }; diff --git a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c index 3b88a3a56116..1217d2a747fb 100644 --- a/drivers/ide/pci/cs5520.c +++ b/drivers/ide/pci/cs5520.c @@ -66,32 +66,13 @@ static struct pio_clocks cs5520_pio_clocks[]={ {1, 2, 1} }; -static int cs5520_tune_chipset(ide_drive_t *drive, u8 xferspeed) +static void cs5520_set_pio_mode(ide_drive_t *drive, const u8 pio) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *pdev = hwif->pci_dev; - u8 speed = min((u8)XFER_PIO_4, xferspeed); - int pio = speed; - u8 reg; int controller = drive->dn > 1 ? 1 : 0; - int error; - - switch(speed) - { - case XFER_PIO_4: - case XFER_PIO_3: - case XFER_PIO_2: - case XFER_PIO_1: - case XFER_PIO_0: - pio -= XFER_PIO_0; - break; - default: - pio = 0; - printk(KERN_ERR "cs55x0: bad ide timing.\n"); - } - - printk("PIO clocking = %d\n", pio); - + u8 reg; + /* FIXME: if DMA = 1 do we need to set the DMA bit here ? */ /* 8bit CAT/CRT - 8bit command timing for channel */ @@ -115,25 +96,28 @@ static int cs5520_tune_chipset(ide_drive_t *drive, u8 xferspeed) reg = inb(hwif->dma_base + 0x02 + 8*controller); reg |= 1<<((drive->dn&1)+5); outb(reg, hwif->dma_base + 0x02 + 8*controller); - - error = ide_config_drive_speed(drive, speed); - /* ATAPI is harder so leave it for now */ - if(!error && drive->media == ide_disk) - error = hwif->ide_dma_on(drive); - return error; -} - -static void cs5520_tune_drive(ide_drive_t *drive, u8 pio) + (void)ide_config_drive_speed(drive, XFER_PIO_0 + pio); +} + +static int cs5520_tune_chipset(ide_drive_t *drive, const u8 speed) { - pio = ide_get_best_pio_mode(drive, pio, 4, NULL); - cs5520_tune_chipset(drive, (XFER_PIO_0 + pio)); + printk(KERN_ERR "cs55x0: bad ide timing.\n"); + + cs5520_set_pio_mode(drive, 0); + + /* + * FIXME: this is incorrect to return zero here but + * since all users of ide_set_xfer_rate() ignore + * the return value it is not a problem currently + */ + return 0; } static int cs5520_config_drive_xfer_rate(ide_drive_t *drive) { /* Tune the drive for PIO modes up to PIO 4 */ - cs5520_tune_drive(drive, 4); + ide_set_max_pio(drive); /* Then tell the core to use DMA operations */ return 0; @@ -165,7 +149,7 @@ static int cs5520_dma_on(ide_drive_t *drive) static void __devinit init_hwif_cs5520(ide_hwif_t *hwif) { - hwif->tuneproc = &cs5520_tune_drive; + hwif->set_pio_mode = &cs5520_set_pio_mode; hwif->speedproc = &cs5520_tune_chipset; hwif->ide_dma_check = &cs5520_config_drive_xfer_rate; hwif->ide_dma_on = &cs5520_dma_on; @@ -179,7 +163,8 @@ static void __devinit init_hwif_cs5520(ide_hwif_t *hwif) hwif->drives[1].autotune = 1; return; } - + + /* ATAPI is harder so leave it for now */ hwif->atapi_dma = 0; hwif->ultra_mask = 0; hwif->swdma_mask = 0; @@ -194,10 +179,10 @@ static void __devinit init_hwif_cs5520(ide_hwif_t *hwif) .name = name_str, \ .init_setup_dma = cs5520_init_setup_dma, \ .init_hwif = init_hwif_cs5520, \ - .channels = 2, \ .autodma = AUTODMA, \ .bootable = ON_BOARD, \ - .flags = IDEPCI_FLAG_ISA_PORTS, \ + .host_flags = IDE_HFLAG_ISA_PORTS, \ + .pio_mask = ATA_PIO4, \ } static ide_pci_device_t cyrix_chipsets[] __devinitdata = { diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c index b5c00d15a704..741507b4cd93 100644 --- a/drivers/ide/pci/cs5530.c +++ b/drivers/ide/pci/cs5530.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/cs5530.c Version 0.73 Mar 10 2007 + * linux/drivers/ide/pci/cs5530.c Version 0.74 Jul 28 2007 * * Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org> * Copyright (C) 2000 Mark Lord <mlord@pobox.com> @@ -71,19 +71,18 @@ static void cs5530_tunepio(ide_drive_t *drive, u8 pio) } /** - * cs5530_tuneproc - select/set PIO modes + * cs5530_set_pio_mode - set PIO mode + * @drive: drive + * @pio: PIO mode number * - * cs5530_tuneproc() handles selection/setting of PIO modes - * for both the chipset and drive. + * Handles setting of PIO mode for both the chipset and drive. * - * The ide_init_cs5530() routine guarantees that all drives + * The init_hwif_cs5530() routine guarantees that all drives * will have valid default PIO timings set up before we get here. */ -static void cs5530_tuneproc (ide_drive_t *drive, u8 pio) /* pio=255 means "autotune" */ +static void cs5530_set_pio_mode(ide_drive_t *drive, const u8 pio) { - pio = ide_get_best_pio_mode(drive, pio, 4, NULL); - if (cs5530_set_xfer_mode(drive, XFER_PIO_0 + pio) == 0) cs5530_tunepio(drive, pio); } @@ -143,13 +142,11 @@ static int cs5530_config_dma(ide_drive_t *drive) return 1; } -static int cs5530_tune_chipset(ide_drive_t *drive, u8 mode) +static int cs5530_tune_chipset(ide_drive_t *drive, const u8 mode) { unsigned long basereg; unsigned int reg, timings = 0; - mode = ide_rate_filter(drive, mode); - /* * Tell the drive to switch to the new mode; abort on failure. */ @@ -166,13 +163,6 @@ static int cs5530_tune_chipset(ide_drive_t *drive, u8 mode) case XFER_MW_DMA_0: timings = 0x00077771; break; case XFER_MW_DMA_1: timings = 0x00012121; break; case XFER_MW_DMA_2: timings = 0x00002020; break; - case XFER_PIO_4: - case XFER_PIO_3: - case XFER_PIO_2: - case XFER_PIO_1: - case XFER_PIO_0: - cs5530_tunepio(drive, mode - XFER_PIO_0); - return 0; default: BUG(); break; @@ -207,6 +197,9 @@ static unsigned int __devinit init_chipset_cs5530 (struct pci_dev *dev, const ch struct pci_dev *master_0 = NULL, *cs5530_0 = NULL; unsigned long flags; + if (pci_resource_start(dev, 4) == 0) + return -EFAULT; + dev = NULL; while ((dev = pci_get_device(PCI_VENDOR_ID_CYRIX, PCI_ANY_ID, dev)) != NULL) { switch (dev->device) { @@ -305,7 +298,7 @@ static void __devinit init_hwif_cs5530 (ide_hwif_t *hwif) if (hwif->mate) hwif->serialized = hwif->mate->serialized = 1; - hwif->tuneproc = &cs5530_tuneproc; + hwif->set_pio_mode = &cs5530_set_pio_mode; hwif->speedproc = &cs5530_tune_chipset; basereg = CS5530_BASEREG(hwif); @@ -325,6 +318,9 @@ static void __devinit init_hwif_cs5530 (ide_hwif_t *hwif) /* needs autotuning later */ } + if (hwif->dma_base == 0) + return; + hwif->atapi_dma = 1; hwif->ultra_mask = 0x07; hwif->mwdma_mask = 0x07; @@ -341,9 +337,9 @@ static ide_pci_device_t cs5530_chipset __devinitdata = { .name = "CS5530", .init_chipset = init_chipset_cs5530, .init_hwif = init_hwif_cs5530, - .channels = 2, .autodma = AUTODMA, .bootable = ON_BOARD, + .pio_mask = ATA_PIO4, }; static int __devinit cs5530_init_one(struct pci_dev *dev, const struct pci_device_id *id) diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/pci/cs5535.c index 10f61f38243c..383b7eccbcbb 100644 --- a/drivers/ide/pci/cs5535.c +++ b/drivers/ide/pci/cs5535.c @@ -2,6 +2,7 @@ * linux/drivers/ide/pci/cs5535.c * * Copyright (C) 2004-2005 Advanced Micro Devices, Inc. + * Copyright (C) 2007 Bartlomiej Zolnierkiewicz * * History: * 09/20/2005 - Jaya Kumar <jayakumar.ide@gmail.com> @@ -74,7 +75,7 @@ static unsigned int cs5535_udma_timings[5] = * * cs5535_set_speed() configures the chipset to a new speed. */ -static void cs5535_set_speed(ide_drive_t *drive, u8 speed) +static void cs5535_set_speed(ide_drive_t *drive, const u8 speed) { u32 reg = 0, dummy; @@ -83,14 +84,17 @@ static void cs5535_set_speed(ide_drive_t *drive, u8 speed) /* Set the PIO timings */ if ((speed & XFER_MODE) == XFER_PIO) { - u8 pioa; - u8 piob; - u8 cmd; + ide_drive_t *pair = &drive->hwif->drives[drive->dn ^ 1]; + u8 cmd, pioa; - pioa = speed - XFER_PIO_0; - piob = ide_get_best_pio_mode(&(drive->hwif->drives[!unit]), - 255, 4, NULL); - cmd = pioa < piob ? pioa : piob; + cmd = pioa = speed - XFER_PIO_0; + + if (pair->present) { + u8 piob = ide_get_best_pio_mode(pair, 255, 4); + + if (piob < cmd) + cmd = piob; + } /* Write the speed of the current drive */ reg = (cs5535_pio_cmd_timings[cmd] << 16) | @@ -116,7 +120,7 @@ static void cs5535_set_speed(ide_drive_t *drive, u8 speed) reg &= 0x80000000UL; /* Preserve the PIO format bit */ - if (speed >= XFER_UDMA_0 && speed <= XFER_UDMA_7) + if (speed >= XFER_UDMA_0 && speed <= XFER_UDMA_4) reg |= cs5535_udma_timings[speed - XFER_UDMA_0]; else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2) reg |= cs5535_mwdma_timings[speed - XFER_MW_DMA_0]; @@ -137,46 +141,35 @@ static void cs5535_set_speed(ide_drive_t *drive, u8 speed) */ static int cs5535_set_drive(ide_drive_t *drive, u8 speed) { - speed = ide_rate_filter(drive, speed); ide_config_drive_speed(drive, speed); cs5535_set_speed(drive, speed); return 0; } -/**** - * cs5535_tuneproc - PIO setup - * @drive: drive to set up - * @pio: mode to use (255 for 'best possible') +/** + * cs5535_set_pio_mode - PIO setup + * @drive: drive + * @pio: PIO mode number * * A callback from the upper layers for PIO-only tuning. */ -static void cs5535_tuneproc(ide_drive_t *drive, u8 xferspeed) + +static void cs5535_set_pio_mode(ide_drive_t *drive, const u8 pio) { - u8 modes[] = { XFER_PIO_0, XFER_PIO_1, XFER_PIO_2, XFER_PIO_3, - XFER_PIO_4 }; - - /* cs5535 max pio is pio 4, best_pio will check the blacklist. - i think we don't need to rate_filter the incoming xferspeed - since we know we're only going to choose pio */ - xferspeed = ide_get_best_pio_mode(drive, xferspeed, 4, NULL); - ide_config_drive_speed(drive, modes[xferspeed]); - cs5535_set_speed(drive, xferspeed); + ide_config_drive_speed(drive, XFER_PIO_0 + pio); + cs5535_set_speed(drive, XFER_PIO_0 + pio); } static int cs5535_dma_check(ide_drive_t *drive) { - u8 speed; - drive->init_speed = 0; if (ide_tune_dma(drive)) return 0; - if (ide_use_fast_pio(drive)) { - speed = ide_get_best_pio_mode(drive, 255, 4, NULL); - cs5535_set_drive(drive, speed); - } + if (ide_use_fast_pio(drive)) + ide_set_max_pio(drive); return -1; } @@ -205,7 +198,7 @@ static void __devinit init_hwif_cs5535(ide_hwif_t *hwif) hwif->autodma = 0; - hwif->tuneproc = &cs5535_tuneproc; + hwif->set_pio_mode = &cs5535_set_pio_mode; hwif->speedproc = &cs5535_set_drive; hwif->ide_dma_check = &cs5535_dma_check; @@ -228,9 +221,10 @@ static void __devinit init_hwif_cs5535(ide_hwif_t *hwif) static ide_pci_device_t cs5535_chipset __devinitdata = { .name = "CS5535", .init_hwif = init_hwif_cs5535, - .channels = 1, .autodma = AUTODMA, .bootable = ON_BOARD, + .host_flags = IDE_HFLAG_SINGLE, + .pio_mask = ATA_PIO4, }; static int __devinit cs5535_init_one(struct pci_dev *dev, diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c index 103b9db97853..dc278025d318 100644 --- a/drivers/ide/pci/cy82c693.c +++ b/drivers/ide/pci/cy82c693.c @@ -97,9 +97,6 @@ #define CY82_INDEX_CHANNEL1 0x31 #define CY82_INDEX_TIMEOUT 0x32 -/* the max PIO mode - from datasheet */ -#define CY82C693_MAX_PIO 4 - /* the min and max PCI bus speed in MHz - from datasheet */ #define CY82C963_MIN_BUS_SPEED 25 #define CY82C963_MAX_BUS_SPEED 33 @@ -148,9 +145,6 @@ static void compute_clocks (u8 pio, pio_clocks_t *p_pclk) * so you can play with the idebus=xx parameter */ - if (pio > CY82C693_MAX_PIO) - pio = CY82C693_MAX_PIO; - /* let's calc the address setup time clocks */ p_pclk->address_time = (u8)calc_clk(ide_pio_timings[pio].setup_time, bus_speed); @@ -269,10 +263,7 @@ static int cy82c693_ide_dma_on (ide_drive_t *drive) return __ide_dma_on(drive); } -/* - * tune ide drive - set PIO mode - */ -static void cy82c693_tune_drive (ide_drive_t *drive, u8 pio) +static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; @@ -329,13 +320,6 @@ static void cy82c693_tune_drive (ide_drive_t *drive, u8 pio) addrCtrl, pclk.time_16r, pclk.time_16w, pclk.time_8); #endif /* CY82C693_DEBUG_LOGS */ - /* first let's calc the pio modes */ - pio = ide_get_best_pio_mode(drive, pio, CY82C693_MAX_PIO, NULL); - -#if CY82C693_DEBUG_INFO - printk (KERN_INFO "%s: Selected PIO mode %d\n", drive->name, pio); -#endif /* CY82C693_DEBUG_INFO */ - /* let's calc the values for this PIO mode */ compute_clocks(pio, &pclk); @@ -447,7 +431,7 @@ static void __devinit init_hwif_cy82c693(ide_hwif_t *hwif) hwif->autodma = 0; hwif->chipset = ide_cy82c693; - hwif->tuneproc = &cy82c693_tune_drive; + hwif->set_pio_mode = &cy82c693_set_pio_mode; if (!hwif->dma_base) { hwif->drives[0].autotune = 1; @@ -483,9 +467,10 @@ static ide_pci_device_t cy82c693_chipset __devinitdata = { .init_chipset = init_chipset_cy82c693, .init_iops = init_iops_cy82c693, .init_hwif = init_hwif_cy82c693, - .channels = 1, .autodma = AUTODMA, .bootable = ON_BOARD, + .host_flags = IDE_HFLAG_SINGLE, + .pio_mask = ATA_PIO4, }; static int __devinit cy82c693_init_one(struct pci_dev *dev, const struct pci_device_id *id) diff --git a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c index 0d51a11e81da..48caa468b762 100644 --- a/drivers/ide/pci/generic.c +++ b/drivers/ide/pci/generic.c @@ -95,92 +95,77 @@ static ide_pci_device_t generic_chipsets[] __devinitdata = { { /* 0 */ .name = "Unknown", .init_hwif = init_hwif_generic, - .channels = 2, .autodma = AUTODMA, .bootable = ON_BOARD, },{ /* 1 */ .name = "NS87410", .init_hwif = init_hwif_generic, - .channels = 2, .autodma = AUTODMA, .enablebits = {{0x43,0x08,0x08}, {0x47,0x08,0x08}}, .bootable = ON_BOARD, },{ /* 2 */ .name = "SAMURAI", .init_hwif = init_hwif_generic, - .channels = 2, .autodma = AUTODMA, .bootable = ON_BOARD, },{ /* 3 */ .name = "HT6565", .init_hwif = init_hwif_generic, - .channels = 2, .autodma = AUTODMA, .bootable = ON_BOARD, },{ /* 4 */ .name = "UM8673F", .init_hwif = init_hwif_generic, - .channels = 2, .autodma = NODMA, .bootable = ON_BOARD, },{ /* 5 */ .name = "UM8886A", .init_hwif = init_hwif_generic, - .channels = 2, .autodma = NODMA, .bootable = ON_BOARD, },{ /* 6 */ .name = "UM8886BF", .init_hwif = init_hwif_generic, - .channels = 2, .autodma = NODMA, .bootable = ON_BOARD, },{ /* 7 */ .name = "HINT_IDE", .init_hwif = init_hwif_generic, - .channels = 2, .autodma = AUTODMA, .bootable = ON_BOARD, },{ /* 8 */ .name = "VIA_IDE", .init_hwif = init_hwif_generic, - .channels = 2, .autodma = NOAUTODMA, .bootable = ON_BOARD, },{ /* 9 */ .name = "OPTI621V", .init_hwif = init_hwif_generic, - .channels = 2, .autodma = NOAUTODMA, .bootable = ON_BOARD, },{ /* 10 */ .name = "VIA8237SATA", .init_hwif = init_hwif_generic, - .channels = 2, .autodma = AUTODMA, .bootable = OFF_BOARD, },{ /* 11 */ .name = "Piccolo0102", .init_hwif = init_hwif_generic, - .channels = 2, .autodma = NOAUTODMA, .bootable = ON_BOARD, },{ /* 12 */ .name = "Piccolo0103", .init_hwif = init_hwif_generic, - .channels = 2, .autodma = NOAUTODMA, .bootable = ON_BOARD, },{ /* 13 */ .name = "Piccolo0105", .init_hwif = init_hwif_generic, - .channels = 2, .autodma = NOAUTODMA, .bootable = ON_BOARD, },{ /* 14 */ .name = "Revolution", .init_hwif = init_hwif_generic, - .channels = 2, .autodma = AUTODMA, .bootable = OFF_BOARD, } diff --git a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c index 2c24c3de8846..a1bb10188fe5 100644 --- a/drivers/ide/pci/hpt34x.c +++ b/drivers/ide/pci/hpt34x.c @@ -43,10 +43,9 @@ #define HPT343_DEBUG_DRIVE_INFO 0 -static int hpt34x_tune_chipset (ide_drive_t *drive, u8 xferspeed) +static int hpt34x_tune_chipset(ide_drive_t *drive, const u8 speed) { struct pci_dev *dev = HWIF(drive)->pci_dev; - u8 speed = ide_rate_filter(drive, xferspeed); u32 reg1= 0, tmp1 = 0, reg2 = 0, tmp2 = 0; u8 hi_speed, lo_speed; @@ -78,9 +77,8 @@ static int hpt34x_tune_chipset (ide_drive_t *drive, u8 xferspeed) return(ide_config_drive_speed(drive, speed)); } -static void hpt34x_tune_drive (ide_drive_t *drive, u8 pio) +static void hpt34x_set_pio_mode(ide_drive_t *drive, const u8 pio) { - pio = ide_get_best_pio_mode(drive, pio, 5, NULL); (void) hpt34x_tune_chipset(drive, (XFER_PIO_0 + pio)); } @@ -89,14 +87,10 @@ static int hpt34x_config_drive_xfer_rate (ide_drive_t *drive) drive->init_speed = 0; if (ide_tune_dma(drive)) -#ifndef CONFIG_HPT34X_AUTODMA return -1; -#else - return 0; -#endif if (ide_use_fast_pio(drive)) - hpt34x_tune_drive(drive, 255); + ide_set_max_pio(drive); return -1; } @@ -120,17 +114,10 @@ static unsigned int __devinit init_chipset_hpt34x(struct pci_dev *dev, const cha pci_write_config_byte(dev, HPT34X_PCI_INIT_REG, 0x00); pci_read_config_word(dev, PCI_COMMAND, &cmd); - if (cmd & PCI_COMMAND_MEMORY) { - if (pci_resource_start(dev, PCI_ROM_RESOURCE)) { - pci_write_config_dword(dev, PCI_ROM_ADDRESS, - dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); - printk(KERN_INFO "HPT345: ROM enabled at 0x%08lx\n", - (unsigned long)dev->resource[PCI_ROM_RESOURCE].start); - } + if (cmd & PCI_COMMAND_MEMORY) pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xF0); - } else { + else pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20); - } /* * Since 20-23 can be assigned and are R/W, we correct them. @@ -157,7 +144,7 @@ static void __devinit init_hwif_hpt34x(ide_hwif_t *hwif) hwif->autodma = 0; - hwif->tuneproc = &hpt34x_tune_drive; + hwif->set_pio_mode = &hpt34x_set_pio_mode; hwif->speedproc = &hpt34x_tune_chipset; hwif->drives[0].autotune = 1; hwif->drives[1].autotune = 1; @@ -167,9 +154,11 @@ static void __devinit init_hwif_hpt34x(ide_hwif_t *hwif) if (!hwif->dma_base) return; +#ifdef CONFIG_HPT34X_AUTODMA hwif->ultra_mask = 0x07; hwif->mwdma_mask = 0x07; hwif->swdma_mask = 0x07; +#endif hwif->ide_dma_check = &hpt34x_config_drive_xfer_rate; if (!noautodma) @@ -182,10 +171,10 @@ static ide_pci_device_t hpt34x_chipset __devinitdata = { .name = "HPT34X", .init_chipset = init_chipset_hpt34x, .init_hwif = init_hwif_hpt34x, - .channels = 2, .autodma = NOAUTODMA, .bootable = NEVER_BOARD, - .extra = 16 + .extra = 16, + .pio_mask = ATA_PIO5, }; static int __devinit hpt34x_init_one(struct pci_dev *dev, const struct pci_device_id *id) diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c index e9b07a97c340..0e7d3b60d43c 100644 --- a/drivers/ide/pci/hpt366.c +++ b/drivers/ide/pci/hpt366.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/hpt366.c Version 1.10 Jun 29, 2007 + * linux/drivers/ide/pci/hpt366.c Version 1.13 Sep 29, 2007 * * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> * Portions Copyright (C) 2001 Sun Microsystems, Inc. @@ -68,7 +68,8 @@ * HPT37x chip family; save space by introducing the separate transfer mode * table in which the mode lookup is done * - use f_CNT value saved by the HighPoint BIOS as reading it directly gives - * the wrong PCI frequency since DPLL has already been calibrated by BIOS + * the wrong PCI frequency since DPLL has already been calibrated by BIOS; + * read it only from the function 0 of HPT374 chips * - fix the hotswap code: it caused RESET- to glitch when tristating the bus, * and for HPT36x the obsolete HDIO_TRISTATE_HWIF handler was called instead * - pass to init_chipset() handlers a copy of the IDE PCI device structure as @@ -113,6 +114,7 @@ * unify HPT36x/37x timing setup code and the speedproc handlers by joining * the register setting lists into the table indexed by the clock selected * - set the correct hwif->ultra_mask for each individual chip + * - add Ultra and MW DMA mode filtering for the HPT37[24] based SATA cards * Sergei Shtylyov, <sshtylyov@ru.mvista.com> or <source@mvista.com> */ @@ -517,47 +519,67 @@ static int check_in_drive_list(ide_drive_t *drive, const char **list) } /* - * Note for the future; the SATA hpt37x we must set - * either PIO or UDMA modes 0,4,5 + * The Marvell bridge chips used on the HighPoint SATA cards do not seem + * to support the UltraDMA modes 1, 2, and 3 as well as any MWDMA modes... */ static u8 hpt3xx_udma_filter(ide_drive_t *drive) { - struct hpt_info *info = pci_get_drvdata(HWIF(drive)->pci_dev); - u8 mask; + ide_hwif_t *hwif = HWIF(drive); + struct hpt_info *info = pci_get_drvdata(hwif->pci_dev); + u8 mask = hwif->ultra_mask; switch (info->chip_type) { - case HPT370A: - if (!HPT370_ALLOW_ATA100_5 || - check_in_drive_list(drive, bad_ata100_5)) - return 0x1f; - else - return 0x3f; - case HPT370: - if (!HPT370_ALLOW_ATA100_5 || - check_in_drive_list(drive, bad_ata100_5)) - mask = 0x1f; - else - mask = 0x3f; - break; case HPT36x: if (!HPT366_ALLOW_ATA66_4 || check_in_drive_list(drive, bad_ata66_4)) - mask = 0x0f; - else - mask = 0x1f; + mask = ATA_UDMA3; if (!HPT366_ALLOW_ATA66_3 || check_in_drive_list(drive, bad_ata66_3)) - mask = 0x07; + mask = ATA_UDMA2; + break; + case HPT370: + if (!HPT370_ALLOW_ATA100_5 || + check_in_drive_list(drive, bad_ata100_5)) + mask = ATA_UDMA4; break; + case HPT370A: + if (!HPT370_ALLOW_ATA100_5 || + check_in_drive_list(drive, bad_ata100_5)) + return ATA_UDMA4; + case HPT372 : + case HPT372A: + case HPT372N: + case HPT374 : + if (ide_dev_is_sata(drive->id)) + mask &= ~0x0e; + /* Fall thru */ default: - return 0x7f; + return mask; } return check_in_drive_list(drive, bad_ata33) ? 0x00 : mask; } +static u8 hpt3xx_mdma_filter(ide_drive_t *drive) +{ + ide_hwif_t *hwif = HWIF(drive); + struct hpt_info *info = pci_get_drvdata(hwif->pci_dev); + + switch (info->chip_type) { + case HPT372 : + case HPT372A: + case HPT372N: + case HPT374 : + if (ide_dev_is_sata(drive->id)) + return 0x00; + /* Fall thru */ + default: + return 0x07; + } +} + static u32 get_speed_setting(u8 speed, struct hpt_info *info) { int i; @@ -578,20 +600,15 @@ static u32 get_speed_setting(u8 speed, struct hpt_info *info) return (*info->settings)[i]; } -static int hpt36x_tune_chipset(ide_drive_t *drive, u8 xferspeed) +static int hpt36x_tune_chipset(ide_drive_t *drive, const u8 speed) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; struct hpt_info *info = pci_get_drvdata(dev); - u8 speed = ide_rate_filter(drive, xferspeed); u8 itr_addr = drive->dn ? 0x44 : 0x40; u32 old_itr = 0; u32 itr_mask, new_itr; - /* TODO: move this to ide_rate_filter() [ check ->atapi_dma ] */ - if (drive->media != ide_disk) - speed = min_t(u8, speed, XFER_PIO_4); - itr_mask = speed < XFER_MW_DMA_0 ? 0x30070000 : (speed < XFER_UDMA_0 ? 0xc0070000 : 0xc03800ff); @@ -610,20 +627,15 @@ static int hpt36x_tune_chipset(ide_drive_t *drive, u8 xferspeed) return ide_config_drive_speed(drive, speed); } -static int hpt37x_tune_chipset(ide_drive_t *drive, u8 xferspeed) +static int hpt37x_tune_chipset(ide_drive_t *drive, const u8 speed) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; struct hpt_info *info = pci_get_drvdata(dev); - u8 speed = ide_rate_filter(drive, xferspeed); u8 itr_addr = 0x40 + (drive->dn * 4); u32 old_itr = 0; u32 itr_mask, new_itr; - /* TODO: move this to ide_rate_filter() [ check ->atapi_dma ] */ - if (drive->media != ide_disk) - speed = min_t(u8, speed, XFER_PIO_4); - itr_mask = speed < XFER_MW_DMA_0 ? 0x303c0000 : (speed < XFER_UDMA_0 ? 0xc03c0000 : 0xc1c001ff); @@ -650,9 +662,8 @@ static int hpt3xx_tune_chipset(ide_drive_t *drive, u8 speed) return hpt36x_tune_chipset(drive, speed); } -static void hpt3xx_tune_drive(ide_drive_t *drive, u8 pio) +static void hpt3xx_set_pio_mode(ide_drive_t *drive, const u8 pio) { - pio = ide_get_best_pio_mode(drive, pio, 4, NULL); (void) hpt3xx_tune_chipset (drive, XFER_PIO_0 + pio); } @@ -714,7 +725,7 @@ static int hpt366_config_drive_xfer_rate(ide_drive_t *drive) return 0; if (ide_use_fast_pio(drive)) - hpt3xx_tune_drive(drive, 255); + ide_set_max_pio(drive); return -1; } @@ -981,6 +992,7 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha struct hpt_info *info = kmalloc(sizeof(struct hpt_info), GFP_KERNEL); unsigned long io_base = pci_resource_start(dev, 4); u8 pci_clk, dpll_clk = 0; /* PCI and DPLL clock in MHz */ + u8 chip_type; enum ata_clock clock; if (info == NULL) { @@ -992,15 +1004,8 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha * Copy everything from a static "template" structure * to just allocated per-chip hpt_info structure. */ - *info = *(struct hpt_info *)pci_get_drvdata(dev); - - /* - * FIXME: Not portable. Also, why do we enable the ROM in the first place? - * We don't seem to be using it. - */ - if (dev->resource[PCI_ROM_RESOURCE].start) - pci_write_config_dword(dev, PCI_ROM_ADDRESS, - dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); + memcpy(info, pci_get_drvdata(dev), sizeof(struct hpt_info)); + chip_type = info->chip_type; pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4)); pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78); @@ -1010,7 +1015,7 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha /* * First, try to estimate the PCI clock frequency... */ - if (info->chip_type >= HPT370) { + if (chip_type >= HPT370) { u8 scr1 = 0; u16 f_cnt = 0; u32 temp = 0; @@ -1024,7 +1029,7 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha * HighPoint does this for HPT372A. * NOTE: This register is only writeable via I/O space. */ - if (info->chip_type == HPT372A) + if (chip_type == HPT372A) outb(0x0e, io_base + 0x9c); /* @@ -1042,13 +1047,28 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha * First try reading the register in which the HighPoint BIOS * saves f_CNT value before reprogramming the DPLL from its * default setting (which differs for the various chips). - * NOTE: This register is only accessible via I/O space. * - * In case the signature check fails, we'll have to resort to - * reading the f_CNT register itself in hopes that nobody has - * touched the DPLL yet... + * NOTE: This register is only accessible via I/O space; + * HPT374 BIOS only saves it for the function 0, so we have to + * always read it from there -- no need to check the result of + * pci_get_slot() for the function 0 as the whole device has + * been already "pinned" (via function 1) in init_setup_hpt374() + */ + if (chip_type == HPT374 && (PCI_FUNC(dev->devfn) & 1)) { + struct pci_dev *dev1 = pci_get_slot(dev->bus, + dev->devfn - 1); + unsigned long io_base = pci_resource_start(dev1, 4); + + temp = inl(io_base + 0x90); + pci_dev_put(dev1); + } else + temp = inl(io_base + 0x90); + + /* + * In case the signature check fails, we'll have to + * resort to reading the f_CNT register itself in hopes + * that nobody has touched the DPLL yet... */ - temp = inl(io_base + 0x90); if ((temp & 0xFFFFF000) != 0xABCDE000) { int i; @@ -1128,7 +1148,7 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha * We also don't like using the DPLL because this causes glitches * on PRST-/SRST- when the state engine gets reset... */ - if (info->chip_type >= HPT374 || info->settings[clock] == NULL) { + if (chip_type >= HPT374 || info->settings[clock] == NULL) { u16 f_low, delta = pci_clk < 50 ? 2 : 4; int adjust; @@ -1198,7 +1218,7 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha /* Point to this chip's own instance of the hpt_info structure. */ pci_set_drvdata(dev, info); - if (info->chip_type >= HPT370) { + if (chip_type >= HPT370) { u8 mcr1, mcr4; /* @@ -1217,7 +1237,7 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha * the MISC. register to stretch the UltraDMA Tss timing. * NOTE: This register is only writeable via I/O space. */ - if (info->chip_type == HPT371N && clock == ATA_CLOCK_66MHZ) + if (chip_type == HPT371N && clock == ATA_CLOCK_66MHZ) outb(inb(io_base + 0x9c) | 0x04, io_base + 0x9c); @@ -1226,25 +1246,25 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha static void __devinit init_hwif_hpt366(ide_hwif_t *hwif) { - struct pci_dev *dev = hwif->pci_dev; - struct hpt_info *info = pci_get_drvdata(dev); - int serialize = HPT_SERIALIZE_IO; - u8 scr1 = 0, ata66 = hwif->channel ? 0x01 : 0x02; - u8 chip_type = info->chip_type; - u8 new_mcr, old_mcr = 0; + struct pci_dev *dev = hwif->pci_dev; + struct hpt_info *info = pci_get_drvdata(dev); + int serialize = HPT_SERIALIZE_IO; + u8 scr1 = 0, ata66 = hwif->channel ? 0x01 : 0x02; + u8 chip_type = info->chip_type; + u8 new_mcr, old_mcr = 0; /* Cache the channel's MISC. control registers' offset */ - hwif->select_data = hwif->channel ? 0x54 : 0x50; + hwif->select_data = hwif->channel ? 0x54 : 0x50; - hwif->tuneproc = &hpt3xx_tune_drive; - hwif->speedproc = &hpt3xx_tune_chipset; - hwif->quirkproc = &hpt3xx_quirkproc; - hwif->intrproc = &hpt3xx_intrproc; - hwif->maskproc = &hpt3xx_maskproc; - hwif->busproc = &hpt3xx_busproc; + hwif->set_pio_mode = &hpt3xx_set_pio_mode; + hwif->speedproc = &hpt3xx_tune_chipset; + hwif->quirkproc = &hpt3xx_quirkproc; + hwif->intrproc = &hpt3xx_intrproc; + hwif->maskproc = &hpt3xx_maskproc; + hwif->busproc = &hpt3xx_busproc; - if (chip_type <= HPT370A) - hwif->udma_filter = &hpt3xx_udma_filter; + hwif->udma_filter = &hpt3xx_udma_filter; + hwif->mdma_filter = &hpt3xx_mdma_filter; /* * HPT3xxN chips have some complications: @@ -1491,22 +1511,22 @@ static int __devinit init_setup_hpt366(struct pci_dev *dev, ide_pci_device_t *d) * to both functions -- really stupid design decision... :-( * Bit 4 is for the primary channel, bit 5 for the secondary. */ - d->channels = 1; + d->host_flags |= IDE_HFLAG_SINGLE; d->enablebits[0].mask = d->enablebits[0].val = 0x10; - d->udma_mask = HPT366_ALLOW_ATA66_3 ? - (HPT366_ALLOW_ATA66_4 ? 0x1f : 0x0f) : 0x07; + d->udma_mask = HPT366_ALLOW_ATA66_3 ? (HPT366_ALLOW_ATA66_4 ? + ATA_UDMA4 : ATA_UDMA3) : ATA_UDMA2; break; case 3: case 4: - d->udma_mask = HPT370_ALLOW_ATA100_5 ? 0x3f : 0x1f; + d->udma_mask = HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4; break; default: rev = 6; /* fall thru */ case 5: case 6: - d->udma_mask = HPT372_ALLOW_ATA133_6 ? 0x7f : 0x3f; + d->udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5; break; } @@ -1554,71 +1574,71 @@ static ide_pci_device_t hpt366_chipsets[] __devinitdata = { .init_chipset = init_chipset_hpt366, .init_hwif = init_hwif_hpt366, .init_dma = init_dma_hpt366, - .channels = 2, .autodma = AUTODMA, .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}}, .bootable = OFF_BOARD, - .extra = 240 + .extra = 240, + .pio_mask = ATA_PIO4, },{ /* 1 */ .name = "HPT372A", .init_setup = init_setup_hpt372a, .init_chipset = init_chipset_hpt366, .init_hwif = init_hwif_hpt366, .init_dma = init_dma_hpt366, - .channels = 2, .autodma = AUTODMA, .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}}, - .udma_mask = HPT372_ALLOW_ATA133_6 ? 0x7f : 0x3f, + .udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, .bootable = OFF_BOARD, - .extra = 240 + .extra = 240, + .pio_mask = ATA_PIO4, },{ /* 2 */ .name = "HPT302", .init_setup = init_setup_hpt302, .init_chipset = init_chipset_hpt366, .init_hwif = init_hwif_hpt366, .init_dma = init_dma_hpt366, - .channels = 2, .autodma = AUTODMA, .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}}, - .udma_mask = HPT302_ALLOW_ATA133_6 ? 0x7f : 0x3f, + .udma_mask = HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, .bootable = OFF_BOARD, - .extra = 240 + .extra = 240, + .pio_mask = ATA_PIO4, },{ /* 3 */ .name = "HPT371", .init_setup = init_setup_hpt371, .init_chipset = init_chipset_hpt366, .init_hwif = init_hwif_hpt366, .init_dma = init_dma_hpt366, - .channels = 2, .autodma = AUTODMA, .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}}, - .udma_mask = HPT371_ALLOW_ATA133_6 ? 0x7f : 0x3f, + .udma_mask = HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, .bootable = OFF_BOARD, - .extra = 240 + .extra = 240, + .pio_mask = ATA_PIO4, },{ /* 4 */ .name = "HPT374", .init_setup = init_setup_hpt374, .init_chipset = init_chipset_hpt366, .init_hwif = init_hwif_hpt366, .init_dma = init_dma_hpt366, - .channels = 2, /* 4 */ .autodma = AUTODMA, .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}}, - .udma_mask = 0x3f, + .udma_mask = ATA_UDMA5, .bootable = OFF_BOARD, - .extra = 240 + .extra = 240, + .pio_mask = ATA_PIO4, },{ /* 5 */ .name = "HPT372N", .init_setup = init_setup_hpt372n, .init_chipset = init_chipset_hpt366, .init_hwif = init_hwif_hpt366, .init_dma = init_dma_hpt366, - .channels = 2, /* 4 */ .autodma = AUTODMA, .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}}, - .udma_mask = HPT372_ALLOW_ATA133_6 ? 0x7f : 0x3f, + .udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, .bootable = OFF_BOARD, - .extra = 240 + .extra = 240, + .pio_mask = ATA_PIO4, } }; diff --git a/drivers/ide/pci/it8213.c b/drivers/ide/pci/it8213.c index ff48c23e571e..76e91ff9420b 100644 --- a/drivers/ide/pci/it8213.c +++ b/drivers/ide/pci/it8213.c @@ -21,7 +21,7 @@ * it8213_dma_2_pio - return the PIO mode matching DMA * @xfer_rate: transfer speed * - * Returns the nearest equivalent PIO timing for the PIO or DMA + * Returns the nearest equivalent PIO timing for the DMA * mode requested by the controller. */ @@ -35,34 +35,28 @@ static u8 it8213_dma_2_pio (u8 xfer_rate) { case XFER_UDMA_1: case XFER_UDMA_0: case XFER_MW_DMA_2: - case XFER_PIO_4: return 4; case XFER_MW_DMA_1: - case XFER_PIO_3: return 3; case XFER_SW_DMA_2: - case XFER_PIO_2: return 2; case XFER_MW_DMA_0: case XFER_SW_DMA_1: case XFER_SW_DMA_0: - case XFER_PIO_1: - case XFER_PIO_0: - case XFER_PIO_SLOW: default: return 0; } } /* - * it8213_tuneproc - tune a drive + * it8213_tune_pio - tune a drive * @drive: drive to tune * @pio: desired PIO mode * * Set the interface PIO mode. */ -static void it8213_tuneproc (ide_drive_t *drive, u8 pio) +static void it8213_tune_pio(ide_drive_t *drive, const u8 pio) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; @@ -82,8 +76,6 @@ static void it8213_tuneproc (ide_drive_t *drive, u8 pio) { 2, 1 }, { 2, 3 }, }; - pio = ide_get_best_pio_mode(drive, pio, 4, NULL); - spin_lock_irqsave(&tune_lock, flags); pci_read_config_word(dev, master_port, &master_data); @@ -113,23 +105,25 @@ static void it8213_tuneproc (ide_drive_t *drive, u8 pio) spin_unlock_irqrestore(&tune_lock, flags); } +static void it8213_set_pio_mode(ide_drive_t *drive, const u8 pio) +{ + it8213_tune_pio(drive, pio); + ide_config_drive_speed(drive, XFER_PIO_0 + pio); +} + /** * it8213_tune_chipset - set controller timings * @drive: Drive to set up - * @xferspeed: speed we want to achieve + * @speed: speed we want to achieve * - * Tune the ITE chipset for the desired mode. If we can't achieve - * the desired mode then tune for a lower one, but ultimately - * make the thing work. + * Tune the ITE chipset for the desired mode. */ -static int it8213_tune_chipset (ide_drive_t *drive, u8 xferspeed) +static int it8213_tune_chipset(ide_drive_t *drive, const u8 speed) { - ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; u8 maslave = 0x40; - u8 speed = ide_rate_filter(drive, xferspeed); int a_speed = 3 << (drive->dn * 4); int u_flag = 1 << drive->dn; int v_flag = 0x01 << drive->dn; @@ -157,12 +151,6 @@ static int it8213_tune_chipset (ide_drive_t *drive, u8 xferspeed) case XFER_MW_DMA_1: case XFER_SW_DMA_2: break; - case XFER_PIO_4: - case XFER_PIO_3: - case XFER_PIO_2: - case XFER_PIO_1: - case XFER_PIO_0: - break; default: return -1; } @@ -193,7 +181,9 @@ static int it8213_tune_chipset (ide_drive_t *drive, u8 xferspeed) if (reg55 & w_flag) pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag); } - it8213_tuneproc(drive, it8213_dma_2_pio(speed)); + + it8213_tune_pio(drive, it8213_dma_2_pio(speed)); + return ide_config_drive_speed(drive, speed); } @@ -209,13 +199,10 @@ static int it8213_tune_chipset (ide_drive_t *drive, u8 xferspeed) static int it8213_config_drive_for_dma (ide_drive_t *drive) { - u8 pio; - if (ide_tune_dma(drive)) return 0; - pio = ide_get_best_pio_mode(drive, 255, 4, NULL); - it8213_tune_chipset(drive, XFER_PIO_0 + pio); + ide_set_max_pio(drive); return -1; } @@ -234,7 +221,7 @@ static void __devinit init_hwif_it8213(ide_hwif_t *hwif) u8 reg42h = 0; hwif->speedproc = &it8213_tune_chipset; - hwif->tuneproc = &it8213_tuneproc; + hwif->set_pio_mode = &it8213_set_pio_mode; hwif->autodma = 0; @@ -272,10 +259,11 @@ static void __devinit init_hwif_it8213(ide_hwif_t *hwif) { \ .name = name_str, \ .init_hwif = init_hwif_it8213, \ - .channels = 1, \ .autodma = AUTODMA, \ .enablebits = {{0x41,0x80,0x80}}, \ .bootable = ON_BOARD, \ + .host_flags = IDE_HFLAG_SINGLE, \ + .pio_mask = ATA_PIO4, \ } static ide_pci_device_t it8213_chipsets[] __devinitdata = { diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c index 8197b653ba1e..758a98230cc5 100644 --- a/drivers/ide/pci/it821x.c +++ b/drivers/ide/pci/it821x.c @@ -255,7 +255,7 @@ static int it821x_tunepio(ide_drive_t *drive, u8 set_pio) * on the cable. */ if (pair) { - u8 pair_pio = ide_get_best_pio_mode(pair, 255, 4, NULL); + u8 pair_pio = ide_get_best_pio_mode(pair, 255, 4); /* trim PIO to the slowest of the master/slave */ if (pair_pio < set_pio) set_pio = pair_pio; @@ -274,9 +274,8 @@ static int it821x_tunepio(ide_drive_t *drive, u8 set_pio) return ide_config_drive_speed(drive, XFER_PIO_0 + set_pio); } -static void it821x_tuneproc(ide_drive_t *drive, u8 pio) +static void it821x_set_pio_mode(ide_drive_t *drive, const u8 pio) { - pio = ide_get_best_pio_mode(drive, pio, 4, NULL); (void)it821x_tunepio(drive, pio); } @@ -405,32 +404,19 @@ static int it821x_dma_end(ide_drive_t *drive) return ret; } - /** * it821x_tune_chipset - set controller timings * @drive: Drive to set up - * @xferspeed: speed we want to achieve + * @speed: speed we want to achieve * - * Tune the ITE chipset for the desired mode. If we can't achieve - * the desired mode then tune for a lower one, but ultimately - * make the thing work. + * Tune the ITE chipset for the desired mode. */ -static int it821x_tune_chipset (ide_drive_t *drive, byte xferspeed) +static int it821x_tune_chipset(ide_drive_t *drive, const u8 speed) { ide_hwif_t *hwif = drive->hwif; struct it821x_dev *itdev = ide_get_hwifdata(hwif); - u8 speed = ide_rate_filter(drive, xferspeed); - - switch (speed) { - case XFER_PIO_4: - case XFER_PIO_3: - case XFER_PIO_2: - case XFER_PIO_1: - case XFER_PIO_0: - return it821x_tunepio(drive, speed - XFER_PIO_0); - } if (itdev->smart == 0) { switch (speed) { @@ -477,7 +463,7 @@ static int it821x_config_drive_for_dma (ide_drive_t *drive) if (ide_tune_dma(drive)) return 0; - it821x_tuneproc(drive, 255); + ide_set_max_pio(drive); return -1; } @@ -644,7 +630,7 @@ static void __devinit init_hwif_it821x(ide_hwif_t *hwif) } hwif->speedproc = &it821x_tune_chipset; - hwif->tuneproc = &it821x_tuneproc; + hwif->set_pio_mode = &it821x_set_pio_mode; /* MWDMA/PIO clock switching for pass through mode */ if(!idev->smart) { @@ -718,10 +704,10 @@ static unsigned int __devinit init_chipset_it821x(struct pci_dev *dev, const cha .name = name_str, \ .init_chipset = init_chipset_it821x, \ .init_hwif = init_hwif_it821x, \ - .channels = 2, \ .autodma = AUTODMA, \ .bootable = ON_BOARD, \ - .fixup = it821x_fixups \ + .fixup = it821x_fixups, \ + .pio_mask = ATA_PIO4, \ } static ide_pci_device_t it821x_chipsets[] __devinitdata = { diff --git a/drivers/ide/pci/jmicron.c b/drivers/ide/pci/jmicron.c index a6008f63e71e..d379fbaf6743 100644 --- a/drivers/ide/pci/jmicron.c +++ b/drivers/ide/pci/jmicron.c @@ -83,39 +83,22 @@ static u8 __devinit ata66_jmicron(ide_hwif_t *hwif) return ATA_CBL_PATA80; } -static void jmicron_tuneproc (ide_drive_t *drive, byte mode_wanted) +static void jmicron_set_pio_mode(ide_drive_t *drive, const u8 pio) { - return; -} - -/** - * config_jmicron_chipset_for_pio - set drive timings - * @drive: drive to tune - * @speed we want - * - */ - -static void config_jmicron_chipset_for_pio (ide_drive_t *drive, byte set_speed) -{ - u8 speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL); - if (set_speed) - (void) ide_config_drive_speed(drive, speed); + ide_config_drive_speed(drive, XFER_PIO_0 + pio); } /** * jmicron_tune_chipset - set controller timings * @drive: Drive to set up - * @xferspeed: speed we want to achieve + * @speed: speed we want to achieve * * As the JMicron snoops for timings all we actually need to do is - * make sure we don't set an invalid mode. We do need to honour - * the cable detect here. + * set the transfer mode on the device. */ -static int jmicron_tune_chipset (ide_drive_t *drive, byte xferspeed) +static int jmicron_tune_chipset(ide_drive_t *drive, const u8 speed) { - u8 speed = ide_rate_filter(drive, xferspeed); - return ide_config_drive_speed(drive, speed); } @@ -132,7 +115,7 @@ static int jmicron_config_drive_for_dma (ide_drive_t *drive) if (ide_tune_dma(drive)) return 0; - config_jmicron_chipset_for_pio(drive, 1); + ide_set_max_pio(drive); return -1; } @@ -147,7 +130,7 @@ static int jmicron_config_drive_for_dma (ide_drive_t *drive) static void __devinit init_hwif_jmicron(ide_hwif_t *hwif) { hwif->speedproc = &jmicron_tune_chipset; - hwif->tuneproc = &jmicron_tuneproc; + hwif->set_pio_mode = &jmicron_set_pio_mode; hwif->drives[0].autotune = 1; hwif->drives[1].autotune = 1; @@ -173,22 +156,13 @@ fallback: return; } -#define DECLARE_JMB_DEV(name_str) \ - { \ - .name = name_str, \ - .init_hwif = init_hwif_jmicron, \ - .channels = 2, \ - .autodma = AUTODMA, \ - .bootable = ON_BOARD, \ - .enablebits = { {0x40, 1, 1}, {0x40, 0x10, 0x10} }, \ - } - -static ide_pci_device_t jmicron_chipsets[] __devinitdata = { - /* 0 */ DECLARE_JMB_DEV("JMB361"), - /* 1 */ DECLARE_JMB_DEV("JMB363"), - /* 2 */ DECLARE_JMB_DEV("JMB365"), - /* 3 */ DECLARE_JMB_DEV("JMB366"), - /* 4 */ DECLARE_JMB_DEV("JMB368"), +static ide_pci_device_t jmicron_chipset __devinitdata = { + .name = "JMB", + .init_hwif = init_hwif_jmicron, + .autodma = AUTODMA, + .bootable = ON_BOARD, + .enablebits = { { 0x40, 0x01, 0x01 }, { 0x40, 0x10, 0x10 } }, + .pio_mask = ATA_PIO5, }; /** @@ -202,35 +176,29 @@ static ide_pci_device_t jmicron_chipsets[] __devinitdata = { static int __devinit jmicron_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - ide_setup_pci_device(dev, &jmicron_chipsets[id->driver_data]); + ide_setup_pci_device(dev, &jmicron_chipset); return 0; } -/* If libata is configured, jmicron PCI quirk will configure it such - * that the SATA ports are in AHCI function while the PATA ports are - * in a separate IDE function. In such cases, match device class and - * attach only to IDE. If libata isn't configured, keep the old - * behavior for backward compatibility. +/* All JMB PATA controllers have and will continue to have the same + * interface. Matching vendor and device class is enough for all + * current and future controllers if the controller is programmed + * properly. + * + * If libata is configured, jmicron PCI quirk programs the controller + * into the correct mode. If libata isn't configured, match known + * device IDs too to maintain backward compatibility. */ -#if defined(CONFIG_ATA) || defined(CONFIG_ATA_MODULE) -#define JMB_CLASS PCI_CLASS_STORAGE_IDE << 8 -#define JMB_CLASS_MASK 0xffff00 -#else -#define JMB_CLASS 0 -#define JMB_CLASS_MASK 0 -#endif - static struct pci_device_id jmicron_pci_tbl[] = { - { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361, - PCI_ANY_ID, PCI_ANY_ID, JMB_CLASS, JMB_CLASS_MASK, 0}, - { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, - PCI_ANY_ID, PCI_ANY_ID, JMB_CLASS, JMB_CLASS_MASK, 1}, - { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, - PCI_ANY_ID, PCI_ANY_ID, JMB_CLASS, JMB_CLASS_MASK, 2}, - { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, - PCI_ANY_ID, PCI_ANY_ID, JMB_CLASS, JMB_CLASS_MASK, 3}, - { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, - PCI_ANY_ID, PCI_ANY_ID, JMB_CLASS, JMB_CLASS_MASK, 4}, +#if !defined(CONFIG_ATA) && !defined(CONFIG_ATA_MODULE) + { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB361) }, + { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB363) }, + { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB365) }, + { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB366) }, + { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB368) }, +#endif + { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, + PCI_CLASS_STORAGE_IDE << 8, 0xffff00, 0 }, { 0, }, }; diff --git a/drivers/ide/pci/ns87415.c b/drivers/ide/pci/ns87415.c index b310c4f51077..465c935fdf25 100644 --- a/drivers/ide/pci/ns87415.c +++ b/drivers/ide/pci/ns87415.c @@ -187,14 +187,6 @@ static int ns87415_ide_dma_setup(ide_drive_t *drive) return 1; } -static int ns87415_ide_dma_check (ide_drive_t *drive) -{ - if (drive->media != ide_disk) - return -1; - - return __ide_dma_check(drive); -} - static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; @@ -266,7 +258,6 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif) outb(0x60, hwif->dma_status); hwif->dma_setup = &ns87415_ide_dma_setup; - hwif->ide_dma_check = &ns87415_ide_dma_check; hwif->ide_dma_end = &ns87415_ide_dma_end; if (!noautodma) @@ -281,7 +272,6 @@ static ide_pci_device_t ns87415_chipset __devinitdata = { .init_iops = init_iops_ns87415, #endif .init_hwif = init_hwif_ns87415, - .channels = 2, .autodma = AUTODMA, .bootable = ON_BOARD, }; diff --git a/drivers/ide/pci/opti621.c b/drivers/ide/pci/opti621.c index aede7eee9246..9fa06393469a 100644 --- a/drivers/ide/pci/opti621.c +++ b/drivers/ide/pci/opti621.c @@ -47,7 +47,7 @@ * The main problem with OPTi is that some timings for master * and slave must be the same. For example, if you have master * PIO 3 and slave PIO 0, driver have to set some timings of - * master for PIO 0. Second problem is that opti621_tune_drive + * master for PIO 0. Second problem is that opti621_set_pio_mode * got only one drive to set, but have to set both drives. * This is solved in compute_pios. If you don't set * the second drive, compute_pios use ide_get_best_pio_mode @@ -103,7 +103,7 @@ #include <asm/io.h> -#define OPTI621_MAX_PIO 3 +//#define OPTI621_MAX_PIO 3 /* In fact, I do not have any PIO 4 drive * (address: 25 ns, data: 70 ns, recovery: 35 ns), * but OPTi 82C621 is programmable and it can do (minimal values): @@ -136,8 +136,8 @@ static int reg_base; #define PIO_NOT_EXIST 254 #define PIO_DONT_KNOW 255 -/* there are stored pio numbers from other calls of opti621_tune_drive */ -static void compute_pios(ide_drive_t *drive, u8 pio) +/* there are stored pio numbers from other calls of opti621_set_pio_mode */ +static void compute_pios(ide_drive_t *drive, const u8 pio) /* Store values into drive->drive_data * second_contr - 0 for primary controller, 1 for secondary * slave_drive - 0 -> pio is for master, 1 -> pio is for slave @@ -147,12 +147,13 @@ static void compute_pios(ide_drive_t *drive, u8 pio) int d; ide_hwif_t *hwif = HWIF(drive); - drive->drive_data = ide_get_best_pio_mode(drive, pio, OPTI621_MAX_PIO, NULL); + drive->drive_data = pio; + for (d = 0; d < 2; ++d) { drive = &hwif->drives[d]; if (drive->present) { if (drive->drive_data == PIO_DONT_KNOW) - drive->drive_data = ide_get_best_pio_mode(drive, 255, OPTI621_MAX_PIO, NULL); + drive->drive_data = ide_get_best_pio_mode(drive, 255, 3); #ifdef OPTI621_DEBUG printk("%s: Selected PIO mode %d\n", drive->name, drive->drive_data); @@ -240,8 +241,7 @@ static void compute_clocks(int pio, pio_clocks_t *clks) } -/* Main tune procedure, called from tuneproc. */ -static void opti621_tune_drive (ide_drive_t *drive, u8 pio) +static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio) { /* primary and secondary drives share some registers, * so we have to program both drives @@ -331,7 +331,8 @@ static void __devinit init_hwif_opti621 (ide_hwif_t *hwif) hwif->autodma = 0; hwif->drives[0].drive_data = PIO_DONT_KNOW; hwif->drives[1].drive_data = PIO_DONT_KNOW; - hwif->tuneproc = &opti621_tune_drive; + + hwif->set_pio_mode = &opti621_set_pio_mode; if (!(hwif->dma_base)) return; @@ -350,17 +351,17 @@ static ide_pci_device_t opti621_chipsets[] __devinitdata = { { /* 0 */ .name = "OPTI621", .init_hwif = init_hwif_opti621, - .channels = 2, .autodma = AUTODMA, .enablebits = {{0x45,0x80,0x00}, {0x40,0x08,0x00}}, .bootable = ON_BOARD, + .pio_mask = ATA_PIO3, },{ /* 1 */ .name = "OPTI621X", .init_hwif = init_hwif_opti621, - .channels = 2, .autodma = AUTODMA, .enablebits = {{0x45,0x80,0x00}, {0x40,0x08,0x00}}, .bootable = ON_BOARD, + .pio_mask = ATA_PIO3, } }; diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c index ee5020df005d..5fb1eedc8194 100644 --- a/drivers/ide/pci/pdc202xx_new.c +++ b/drivers/ide/pci/pdc202xx_new.c @@ -9,7 +9,7 @@ * Split from: * linux/drivers/ide/pdc202xx.c Version 0.35 Mar. 30, 2002 * Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org> - * Copyright (C) 2005-2006 MontaVista Software, Inc. + * Copyright (C) 2005-2007 MontaVista Software, Inc. * Portions Copyright (C) 1999 Promise Technology, Inc. * Author: Frank Tiernan (frankt@promise.com) * Released under terms of General Public License @@ -146,14 +146,12 @@ static struct udma_timing { { 0x1a, 0x01, 0xcb }, /* UDMA mode 6 */ }; -static int pdcnew_tune_chipset(ide_drive_t *drive, u8 speed) +static int pdcnew_tune_chipset(ide_drive_t *drive, const u8 speed) { ide_hwif_t *hwif = HWIF(drive); u8 adj = (drive->dn & 1) ? 0x08 : 0x00; int err; - speed = ide_rate_filter(drive, speed); - /* * Issue SETFEATURES_XFER to the drive first. PDC202xx hardware will * automatically set the timing registers based on 100 MHz PLL output. @@ -217,9 +215,8 @@ static int pdcnew_tune_chipset(ide_drive_t *drive, u8 speed) return err; } -static void pdcnew_tune_drive(ide_drive_t *drive, u8 pio) +static void pdcnew_set_pio_mode(ide_drive_t *drive, const u8 pio) { - pio = ide_get_best_pio_mode(drive, pio, 4, NULL); (void)pdcnew_tune_chipset(drive, XFER_PIO_0 + pio); } @@ -239,7 +236,7 @@ static int pdcnew_config_drive_xfer_rate(ide_drive_t *drive) return 0; if (ide_use_fast_pio(drive)) - pdcnew_tune_drive(drive, 255); + ide_set_max_pio(drive); return -1; } @@ -341,7 +338,7 @@ static long __devinit detect_pll_input_clock(unsigned long dma_base) */ usec_elapsed = (end_time.tv_sec - start_time.tv_sec) * 1000000 + (end_time.tv_usec - start_time.tv_usec); - pll_input = ((start_count - end_count) & 0x3ffffff) / 10 * + pll_input = ((start_count - end_count) & 0x3fffffff) / 10 * (10000000 / usec_elapsed); DBG("start[%ld] end[%ld]\n", start_count, end_count); @@ -378,12 +375,8 @@ static unsigned int __devinit init_chipset_pdcnew(struct pci_dev *dev, const cha int f, r; u8 pll_ctl0, pll_ctl1; - if (dev->resource[PCI_ROM_RESOURCE].start) { - pci_write_config_dword(dev, PCI_ROM_ADDRESS, - dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); - printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", name, - (unsigned long)dev->resource[PCI_ROM_RESOURCE].start); - } + if (dma_base == 0) + return -EFAULT; #ifdef CONFIG_PPC_PMAC apple_kiwi_init(dev); @@ -496,20 +489,24 @@ static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif) { hwif->autodma = 0; - hwif->tuneproc = &pdcnew_tune_drive; + hwif->set_pio_mode = &pdcnew_set_pio_mode; + hwif->quirkproc = &pdcnew_quirkproc; hwif->speedproc = &pdcnew_tune_chipset; hwif->resetproc = &pdcnew_reset; + hwif->err_stops_fifo = 1; + hwif->drives[0].autotune = hwif->drives[1].autotune = 1; + if (hwif->dma_base == 0) + return; + hwif->atapi_dma = 1; hwif->ultra_mask = hwif->cds->udma_mask; hwif->mwdma_mask = 0x07; - hwif->err_stops_fifo = 1; - hwif->ide_dma_check = &pdcnew_config_drive_xfer_rate; if (hwif->cbl != ATA_CBL_PATA40_SHORT) @@ -525,43 +522,52 @@ static int __devinit init_setup_pdcnew(struct pci_dev *dev, ide_pci_device_t *d) return ide_setup_pci_device(dev, d); } -static int __devinit init_setup_pdc20270(struct pci_dev *dev, - ide_pci_device_t *d) +static int __devinit init_setup_pdc20270(struct pci_dev *dev, ide_pci_device_t *d) { - struct pci_dev *findev = NULL; - int ret; + struct pci_dev *bridge = dev->bus->self; + + if (bridge != NULL && + bridge->vendor == PCI_VENDOR_ID_DEC && + bridge->device == PCI_DEVICE_ID_DEC_21150) { + struct pci_dev *dev2; - if ((dev->bus->self && - dev->bus->self->vendor == PCI_VENDOR_ID_DEC) && - (dev->bus->self->device == PCI_DEVICE_ID_DEC_21150)) { if (PCI_SLOT(dev->devfn) & 2) return -ENODEV; - d->extra = 0; - while ((findev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, findev)) != NULL) { - if ((findev->vendor == dev->vendor) && - (findev->device == dev->device) && - (PCI_SLOT(findev->devfn) & 2)) { - if (findev->irq != dev->irq) { - findev->irq = dev->irq; - } - ret = ide_setup_pci_devices(dev, findev, d); - pci_dev_put(findev); - return ret; + + dev2 = pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn) + 2, + PCI_FUNC(dev->devfn))); + if (dev2 != NULL && + dev2->vendor == dev->vendor && + dev2->device == dev->device) { + int ret; + + if (dev2->irq != dev->irq) { + dev2->irq = dev->irq; + + printk(KERN_WARNING "%s: PCI config space " + "interrupt fixed.\n", d->name); } + + ret = ide_setup_pci_devices(dev, dev2, d); + if (ret < 0) + pci_dev_put(dev2); + return ret; } } return ide_setup_pci_device(dev, d); } -static int __devinit init_setup_pdc20276(struct pci_dev *dev, - ide_pci_device_t *d) +static int __devinit init_setup_pdc20276(struct pci_dev *dev, ide_pci_device_t *d) { - if ((dev->bus->self) && - (dev->bus->self->vendor == PCI_VENDOR_ID_INTEL) && - ((dev->bus->self->device == PCI_DEVICE_ID_INTEL_I960) || - (dev->bus->self->device == PCI_DEVICE_ID_INTEL_I960RM))) { - printk(KERN_INFO "ide: Skipping Promise PDC20276 " - "attached to I2O RAID controller.\n"); + struct pci_dev *bridge = dev->bus->self; + + if (bridge != NULL && + bridge->vendor == PCI_VENDOR_ID_INTEL && + (bridge->device == PCI_DEVICE_ID_INTEL_I960 || + bridge->device == PCI_DEVICE_ID_INTEL_I960RM)) { + + printk(KERN_INFO "%s: attached to I2O RAID controller, " + "skipping.\n", d->name); return -ENODEV; } return ide_setup_pci_device(dev, d); @@ -573,63 +579,63 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = { .init_setup = init_setup_pdcnew, .init_chipset = init_chipset_pdcnew, .init_hwif = init_hwif_pdc202new, - .channels = 2, .autodma = AUTODMA, .bootable = OFF_BOARD, + .pio_mask = ATA_PIO4, .udma_mask = 0x3f, /* udma0-5 */ },{ /* 1 */ .name = "PDC20269", .init_setup = init_setup_pdcnew, .init_chipset = init_chipset_pdcnew, .init_hwif = init_hwif_pdc202new, - .channels = 2, .autodma = AUTODMA, .bootable = OFF_BOARD, + .pio_mask = ATA_PIO4, .udma_mask = 0x7f, /* udma0-6*/ },{ /* 2 */ .name = "PDC20270", .init_setup = init_setup_pdc20270, .init_chipset = init_chipset_pdcnew, .init_hwif = init_hwif_pdc202new, - .channels = 2, .autodma = AUTODMA, .bootable = OFF_BOARD, + .pio_mask = ATA_PIO4, .udma_mask = 0x3f, /* udma0-5 */ },{ /* 3 */ .name = "PDC20271", .init_setup = init_setup_pdcnew, .init_chipset = init_chipset_pdcnew, .init_hwif = init_hwif_pdc202new, - .channels = 2, .autodma = AUTODMA, .bootable = OFF_BOARD, + .pio_mask = ATA_PIO4, .udma_mask = 0x7f, /* udma0-6*/ },{ /* 4 */ .name = "PDC20275", .init_setup = init_setup_pdcnew, .init_chipset = init_chipset_pdcnew, .init_hwif = init_hwif_pdc202new, - .channels = 2, .autodma = AUTODMA, .bootable = OFF_BOARD, + .pio_mask = ATA_PIO4, .udma_mask = 0x7f, /* udma0-6*/ },{ /* 5 */ .name = "PDC20276", .init_setup = init_setup_pdc20276, .init_chipset = init_chipset_pdcnew, .init_hwif = init_hwif_pdc202new, - .channels = 2, .autodma = AUTODMA, .bootable = OFF_BOARD, + .pio_mask = ATA_PIO4, .udma_mask = 0x7f, /* udma0-6*/ },{ /* 6 */ .name = "PDC20277", .init_setup = init_setup_pdcnew, .init_chipset = init_chipset_pdcnew, .init_hwif = init_hwif_pdc202new, - .channels = 2, .autodma = AUTODMA, .bootable = OFF_BOARD, + .pio_mask = ATA_PIO4, .udma_mask = 0x7f, /* udma0-6*/ } }; diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c index 41ac4a94959f..b578307fad51 100644 --- a/drivers/ide/pci/pdc202xx_old.c +++ b/drivers/ide/pci/pdc202xx_old.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/pdc202xx_old.c Version 0.50 Mar 3, 2007 + * linux/drivers/ide/pci/pdc202xx_old.c Version 0.51 Jul 27, 2007 * * Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org> * Copyright (C) 2006-2007 MontaVista Software, Inc. @@ -63,12 +63,11 @@ static const char *pdc_quirk_drives[] = { static void pdc_old_disable_66MHz_clock(ide_hwif_t *); -static int pdc202xx_tune_chipset (ide_drive_t *drive, u8 xferspeed) +static int pdc202xx_tune_chipset(ide_drive_t *drive, const u8 speed) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; u8 drive_pci = 0x60 + (drive->dn << 2); - u8 speed = ide_rate_filter(drive, xferspeed); u8 AP = 0, BP = 0, CP = 0; u8 TA = 0, TB = 0, TC = 0; @@ -143,9 +142,8 @@ static int pdc202xx_tune_chipset (ide_drive_t *drive, u8 xferspeed) return ide_config_drive_speed(drive, speed); } -static void pdc202xx_tune_drive(ide_drive_t *drive, u8 pio) +static void pdc202xx_set_pio_mode(ide_drive_t *drive, const u8 pio) { - pio = ide_get_best_pio_mode(drive, pio, 4, NULL); pdc202xx_tune_chipset(drive, XFER_PIO_0 + pio); } @@ -191,7 +189,7 @@ static int pdc202xx_config_drive_xfer_rate (ide_drive_t *drive) return 0; if (ide_use_fast_pio(drive)) - pdc202xx_tune_drive(drive, 255); + ide_set_max_pio(drive); return -1; } @@ -307,23 +305,16 @@ static void pdc202xx_reset (ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *mate = hwif->mate; - + pdc202xx_reset_host(hwif); pdc202xx_reset_host(mate); - pdc202xx_tune_drive(drive, 255); + + ide_set_max_pio(drive); } static unsigned int __devinit init_chipset_pdc202xx(struct pci_dev *dev, const char *name) { - /* This doesn't appear needed */ - if (dev->resource[PCI_ROM_RESOURCE].start) { - pci_write_config_dword(dev, PCI_ROM_ADDRESS, - dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); - printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", name, - (unsigned long)dev->resource[PCI_ROM_RESOURCE].start); - } - return dev->irq; } @@ -337,7 +328,9 @@ static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif) hwif->rqsize = 256; hwif->autodma = 0; - hwif->tuneproc = &pdc202xx_tune_drive; + + hwif->set_pio_mode = &pdc202xx_set_pio_mode; + hwif->quirkproc = &pdc202xx_quirkproc; if (hwif->pci_dev->device != PCI_DEVICE_ID_PROMISE_20246) @@ -345,15 +338,18 @@ static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif) hwif->speedproc = &pdc202xx_tune_chipset; + hwif->err_stops_fifo = 1; + hwif->drives[0].autotune = hwif->drives[1].autotune = 1; + if (hwif->dma_base == 0) + return; + hwif->ultra_mask = hwif->cds->udma_mask; hwif->mwdma_mask = 0x07; hwif->swdma_mask = 0x07; hwif->atapi_dma = 1; - hwif->err_stops_fifo = 1; - hwif->ide_dma_check = &pdc202xx_config_drive_xfer_rate; hwif->dma_lost_irq = &pdc202xx_dma_lost_irq; hwif->dma_timeout = &pdc202xx_dma_timeout; @@ -449,10 +445,10 @@ static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = { .init_chipset = init_chipset_pdc202xx, .init_hwif = init_hwif_pdc202xx, .init_dma = init_dma_pdc202xx, - .channels = 2, .autodma = AUTODMA, .bootable = OFF_BOARD, .extra = 16, + .pio_mask = ATA_PIO4, .udma_mask = 0x07, /* udma0-2 */ },{ /* 1 */ .name = "PDC20262", @@ -460,10 +456,10 @@ static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = { .init_chipset = init_chipset_pdc202xx, .init_hwif = init_hwif_pdc202xx, .init_dma = init_dma_pdc202xx, - .channels = 2, .autodma = AUTODMA, .bootable = OFF_BOARD, .extra = 48, + .pio_mask = ATA_PIO4, .udma_mask = 0x1f, /* udma0-4 */ },{ /* 2 */ .name = "PDC20263", @@ -471,10 +467,10 @@ static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = { .init_chipset = init_chipset_pdc202xx, .init_hwif = init_hwif_pdc202xx, .init_dma = init_dma_pdc202xx, - .channels = 2, .autodma = AUTODMA, .bootable = OFF_BOARD, .extra = 48, + .pio_mask = ATA_PIO4, .udma_mask = 0x1f, /* udma0-4 */ },{ /* 3 */ .name = "PDC20265", @@ -482,10 +478,10 @@ static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = { .init_chipset = init_chipset_pdc202xx, .init_hwif = init_hwif_pdc202xx, .init_dma = init_dma_pdc202xx, - .channels = 2, .autodma = AUTODMA, .bootable = OFF_BOARD, .extra = 48, + .pio_mask = ATA_PIO4, .udma_mask = 0x3f, /* udma0-5 */ },{ /* 4 */ .name = "PDC20267", @@ -493,10 +489,10 @@ static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = { .init_chipset = init_chipset_pdc202xx, .init_hwif = init_hwif_pdc202xx, .init_dma = init_dma_pdc202xx, - .channels = 2, .autodma = AUTODMA, .bootable = OFF_BOARD, .extra = 48, + .pio_mask = ATA_PIO4, .udma_mask = 0x3f, /* udma0-5 */ } }; diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c index 1372c35be035..fd8214a7ab98 100644 --- a/drivers/ide/pci/piix.c +++ b/drivers/ide/pci/piix.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/piix.c Version 0.50 Jun 10, 2007 + * linux/drivers/ide/pci/piix.c Version 0.52 Jul 14, 2007 * * Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> @@ -17,11 +17,11 @@ * 41 * 43 * - * | PIO 0 | c0 | 80 | 0 | piix_tune_drive(drive, 0); - * | PIO 2 | SW2 | d0 | 90 | 4 | piix_tune_drive(drive, 2); - * | PIO 3 | MW1 | e1 | a1 | 9 | piix_tune_drive(drive, 3); - * | PIO 4 | MW2 | e3 | a3 | b | piix_tune_drive(drive, 4); - * + * | PIO 0 | c0 | 80 | 0 | + * | PIO 2 | SW2 | d0 | 90 | 4 | + * | PIO 3 | MW1 | e1 | a1 | 9 | + * | PIO 4 | MW2 | e3 | a3 | b | + * * sitre = word40 & 0x4000; primary * sitre = word42 & 0x4000; secondary * @@ -109,7 +109,7 @@ static int no_piix_dma; * piix_dma_2_pio - return the PIO mode matching DMA * @xfer_rate: transfer speed * - * Returns the nearest equivalent PIO timing for the PIO or DMA + * Returns the nearest equivalent PIO timing for the DMA * mode requested by the controller. */ @@ -123,20 +123,14 @@ static u8 piix_dma_2_pio (u8 xfer_rate) { case XFER_UDMA_1: case XFER_UDMA_0: case XFER_MW_DMA_2: - case XFER_PIO_4: return 4; case XFER_MW_DMA_1: - case XFER_PIO_3: return 3; case XFER_SW_DMA_2: - case XFER_PIO_2: return 2; case XFER_MW_DMA_0: case XFER_SW_DMA_1: case XFER_SW_DMA_0: - case XFER_PIO_1: - case XFER_PIO_0: - case XFER_PIO_SLOW: default: return 0; } @@ -210,16 +204,16 @@ static void piix_tune_pio (ide_drive_t *drive, u8 pio) } /** - * piix_tune_drive - tune a drive attached to PIIX + * piix_set_pio_mode - set PIO mode * @drive: drive to tune * @pio: desired PIO mode * * Set the drive's PIO mode (might be useful if drive is not registered * in CMOS for any reason). */ -static void piix_tune_drive (ide_drive_t *drive, u8 pio) + +static void piix_set_pio_mode(ide_drive_t *drive, const u8 pio) { - pio = ide_get_best_pio_mode(drive, pio, 4, NULL); piix_tune_pio(drive, pio); (void) ide_config_drive_speed(drive, XFER_PIO_0 + pio); } @@ -227,19 +221,18 @@ static void piix_tune_drive (ide_drive_t *drive, u8 pio) /** * piix_tune_chipset - tune a PIIX interface * @drive: IDE drive to tune - * @xferspeed: speed to configure + * @speed: speed to configure * * Set a PIIX interface channel to the desired speeds. This involves * requires the right timing data into the PIIX configuration space * then setting the drive parameters appropriately */ - -static int piix_tune_chipset (ide_drive_t *drive, u8 xferspeed) + +static int piix_tune_chipset(ide_drive_t *drive, const u8 speed) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; u8 maslave = hwif->channel ? 0x42 : 0x40; - u8 speed = ide_rate_filter(drive, xferspeed); int a_speed = 3 << (drive->dn * 4); int u_flag = 1 << drive->dn; int v_flag = 0x01 << drive->dn; @@ -266,10 +259,6 @@ static int piix_tune_chipset (ide_drive_t *drive, u8 xferspeed) case XFER_MW_DMA_2: case XFER_MW_DMA_1: case XFER_SW_DMA_2: break; - case XFER_PIO_4: - case XFER_PIO_3: - case XFER_PIO_2: - case XFER_PIO_0: break; default: return -1; } @@ -300,6 +289,7 @@ static int piix_tune_chipset (ide_drive_t *drive, u8 xferspeed) } piix_tune_pio(drive, piix_dma_2_pio(speed)); + return ide_config_drive_speed(drive, speed); } @@ -319,7 +309,7 @@ static int piix_config_drive_xfer_rate (ide_drive_t *drive) return 0; if (ide_use_fast_pio(drive)) - piix_tune_drive(drive, 255); + ide_set_max_pio(drive); return -1; } @@ -456,7 +446,8 @@ static void __devinit init_hwif_piix(ide_hwif_t *hwif) } hwif->autodma = 0; - hwif->tuneproc = &piix_tune_drive; + + hwif->set_pio_mode = &piix_set_pio_mode; hwif->speedproc = &piix_tune_chipset; hwif->drives[0].autotune = 1; hwif->drives[1].autotune = 1; @@ -495,10 +486,10 @@ static void __devinit init_hwif_piix(ide_hwif_t *hwif) .name = name_str, \ .init_chipset = init_chipset_piix, \ .init_hwif = init_hwif_piix, \ - .channels = 2, \ .autodma = AUTODMA, \ .enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, \ .bootable = ON_BOARD, \ + .pio_mask = ATA_PIO4, \ .udma_mask = udma, \ } @@ -514,11 +505,11 @@ static ide_pci_device_t piix_pci_info[] __devinitdata = { */ .name = "MPIIX", .init_hwif = init_hwif_piix, - .channels = 2, .autodma = NODMA, .enablebits = {{0x6d,0xc0,0x80}, {0x6d,0xc0,0xc0}}, .bootable = ON_BOARD, - .flags = IDEPCI_FLAG_ISA_PORTS + .host_flags = IDE_HFLAG_ISA_PORTS, + .pio_mask = ATA_PIO4, }, /* 3 */ DECLARE_PIIX_DEV("PIIX3", 0x00), /* no udma */ diff --git a/drivers/ide/pci/rz1000.c b/drivers/ide/pci/rz1000.c index f8c954690142..10e1ae7a4a02 100644 --- a/drivers/ide/pci/rz1000.c +++ b/drivers/ide/pci/rz1000.c @@ -52,7 +52,6 @@ static void __devinit init_hwif_rz1000 (ide_hwif_t *hwif) static ide_pci_device_t rz1000_chipset __devinitdata = { .name = "RZ100x", .init_hwif = init_hwif_rz1000, - .channels = 2, .autodma = NODMA, .bootable = ON_BOARD, }; diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c index 523363c93794..79ecab689489 100644 --- a/drivers/ide/pci/sc1200.c +++ b/drivers/ide/pci/sc1200.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/sc1200.c Version 0.94 Mar 10 2007 + * linux/drivers/ide/pci/sc1200.c Version 0.95 Jun 16 2007 * * Copyright (C) 2000-2002 Mark Lord <mlord@pobox.com> * Copyright (C) 2007 Bartlomiej Zolnierkiewicz @@ -138,7 +138,7 @@ out: return mask; } -static int sc1200_tune_chipset(ide_drive_t *drive, u8 mode) +static int sc1200_tune_chipset(ide_drive_t *drive, const u8 mode) { ide_hwif_t *hwif = HWIF(drive); int unit = drive->select.b.unit; @@ -146,25 +146,11 @@ static int sc1200_tune_chipset(ide_drive_t *drive, u8 mode) unsigned short pci_clock; unsigned int basereg = hwif->channel ? 0x50 : 0x40; - mode = ide_rate_filter(drive, mode); - /* * Tell the drive to switch to the new mode; abort on failure. */ - if (sc1200_set_xfer_mode(drive, mode)) { - printk("SC1200: set xfer mode failure\n"); + if (sc1200_set_xfer_mode(drive, mode)) return 1; /* failure */ - } - - switch (mode) { - case XFER_PIO_4: - case XFER_PIO_3: - case XFER_PIO_2: - case XFER_PIO_1: - case XFER_PIO_0: - sc1200_tunepio(drive, mode - XFER_PIO_0); - return 0; - } pci_clock = sc1200_get_pci_clock(); @@ -274,19 +260,20 @@ static int sc1200_ide_dma_end (ide_drive_t *drive) } /* - * sc1200_tuneproc() handles selection/setting of PIO modes + * sc1200_set_pio_mode() handles setting of PIO modes * for both the chipset and drive. * * All existing BIOSs for this chipset guarantee that all drives * will have valid default PIO timings set up before we get here. */ -static void sc1200_tuneproc (ide_drive_t *drive, byte pio) /* mode=255 means "autotune" */ + +static void sc1200_set_pio_mode(ide_drive_t *drive, const u8 pio) { ide_hwif_t *hwif = HWIF(drive); int mode = -1; /* - * bad abuse of ->tuneproc interface + * bad abuse of ->set_pio_mode interface */ switch (pio) { case 200: mode = XFER_UDMA_0; break; @@ -304,9 +291,6 @@ static void sc1200_tuneproc (ide_drive_t *drive, byte pio) /* mode=255 means "au return; } - pio = ide_get_best_pio_mode(drive, pio, 4, NULL); - printk("SC1200: %s: setting PIO mode%d\n", drive->name, pio); - if (sc1200_set_xfer_mode(drive, XFER_PIO_0 + pio) == 0) sc1200_tunepio(drive, pio); } @@ -390,7 +374,7 @@ static int sc1200_resume (struct pci_dev *dev) // loop over all interfaces that are part of this pci device: // while ((hwif = lookup_pci_dev(hwif, dev)) != NULL) { - unsigned int basereg, r, d, format; + unsigned int basereg, r; sc1200_saved_state_t *ss = (sc1200_saved_state_t *)hwif->config_data; // @@ -402,41 +386,6 @@ static int sc1200_resume (struct pci_dev *dev) pci_write_config_dword(hwif->pci_dev, basereg + (r<<2), ss->regs[r]); } } - // - // Re-program drive PIO modes - // - pci_read_config_dword(hwif->pci_dev, basereg+4, &format); - format = (format >> 31) & 1; - if (format) - format += sc1200_get_pci_clock(); - for (d = 0; d < 2; ++d) { - ide_drive_t *drive = &(hwif->drives[d]); - if (drive->present) { - unsigned int pio, timings; - pci_read_config_dword(hwif->pci_dev, basereg+(drive->select.b.unit << 3), &timings); - for (pio = 0; pio <= 4; ++pio) { - if (sc1200_pio_timings[format][pio] == timings) - break; - } - if (pio > 4) - pio = 255; /* autotune */ - (void)sc1200_tuneproc(drive, pio); - } - } - // - // Re-program drive DMA modes - // - for (d = 0; d < MAX_DRIVES; ++d) { - ide_drive_t *drive = &(hwif->drives[d]); - if (drive->present && !__ide_dma_bad_drive(drive)) { - int enable_dma = drive->using_dma; - hwif->dma_off_quietly(drive); - if (sc1200_config_dma(drive)) - enable_dma = 0; - if (enable_dma) - hwif->dma_host_on(drive); - } - } } return 0; } @@ -457,7 +406,8 @@ static void __devinit init_hwif_sc1200 (ide_hwif_t *hwif) hwif->ide_dma_end = &sc1200_ide_dma_end; if (!noautodma) hwif->autodma = 1; - hwif->tuneproc = &sc1200_tuneproc; + + hwif->set_pio_mode = &sc1200_set_pio_mode; hwif->speedproc = &sc1200_tune_chipset; } hwif->atapi_dma = 1; @@ -471,9 +421,10 @@ static void __devinit init_hwif_sc1200 (ide_hwif_t *hwif) static ide_pci_device_t sc1200_chipset __devinitdata = { .name = "SC1200", .init_hwif = init_hwif_sc1200, - .channels = 2, .autodma = AUTODMA, .bootable = ON_BOARD, + .host_flags = IDE_HFLAG_ABUSE_DMA_MODES, + .pio_mask = ATA_PIO4, }; static int __devinit sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id) diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/pci/scc_pata.c index 7b87488e3daa..66a526e0ece4 100644 --- a/drivers/ide/pci/scc_pata.c +++ b/drivers/ide/pci/scc_pata.c @@ -165,9 +165,9 @@ scc_ide_outbsync(ide_drive_t * drive, u8 addr, unsigned long port) ide_hwif_t *hwif = HWIF(drive); out_be32((void*)port, addr); - __asm__ __volatile__("eieio":::"memory"); + eieio(); in_be32((void*)(hwif->dma_base + 0x01c)); - __asm__ __volatile__("eieio":::"memory"); + eieio(); } static void @@ -190,7 +190,7 @@ scc_ide_outsl(unsigned long port, void *addr, u32 count) } /** - * scc_tuneproc - tune a drive PIO mode + * scc_tune_pio - tune a drive PIO mode * @drive: drive to tune * @mode_wanted: the target operating mode * @@ -198,7 +198,7 @@ scc_ide_outsl(unsigned long port, void *addr, u32 count) * controller. */ -static void scc_tuneproc(ide_drive_t *drive, byte mode_wanted) +static void scc_tune_pio(ide_drive_t *drive, const u8 pio) { ide_hwif_t *hwif = HWIF(drive); struct scc_ports *ports = ide_get_hwifdata(hwif); @@ -207,56 +207,38 @@ static void scc_tuneproc(ide_drive_t *drive, byte mode_wanted) unsigned long piosht_port = ctl_base + 0x000; unsigned long pioct_port = ctl_base + 0x004; unsigned long reg; - unsigned char speed = XFER_PIO_0; int offset; - mode_wanted = ide_get_best_pio_mode(drive, mode_wanted, 4, NULL); - switch (mode_wanted) { - 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; - case 0: - default: - speed = XFER_PIO_0; - break; - } - reg = in_be32((void __iomem *)cckctrl_port); if (reg & CCKCTRL_ATACLKOEN) { offset = 1; /* 133MHz */ } else { offset = 0; /* 100MHz */ } - reg = JCHSTtbl[offset][mode_wanted] << 16 | JCHHTtbl[offset][mode_wanted]; + reg = JCHSTtbl[offset][pio] << 16 | JCHHTtbl[offset][pio]; out_be32((void __iomem *)piosht_port, reg); - reg = JCHCTtbl[offset][mode_wanted]; + reg = JCHCTtbl[offset][pio]; out_be32((void __iomem *)pioct_port, reg); +} - ide_config_drive_speed(drive, speed); +static void scc_set_pio_mode(ide_drive_t *drive, const u8 pio) +{ + scc_tune_pio(drive, pio); + ide_config_drive_speed(drive, XFER_PIO_0 + pio); } /** * scc_tune_chipset - tune a drive DMA mode * @drive: Drive to set up - * @xferspeed: speed we want to achieve + * @speed: speed we want to achieve * * Load the timing settings for this device mode into the * controller. */ -static int scc_tune_chipset(ide_drive_t *drive, byte xferspeed) +static int scc_tune_chipset(ide_drive_t *drive, const u8 speed) { ide_hwif_t *hwif = HWIF(drive); - u8 speed = ide_rate_filter(drive, xferspeed); struct scc_ports *ports = ide_get_hwifdata(hwif); unsigned long ctl_base = ports->ctl; unsigned long cckctrl_port = ctl_base + 0xff0; @@ -280,25 +262,13 @@ static int scc_tune_chipset(ide_drive_t *drive, byte xferspeed) switch (speed) { case XFER_UDMA_6: - idx = 6; - break; case XFER_UDMA_5: - idx = 5; - break; case XFER_UDMA_4: - idx = 4; - break; case XFER_UDMA_3: - idx = 3; - break; case XFER_UDMA_2: - idx = 2; - break; case XFER_UDMA_1: - idx = 1; - break; case XFER_UDMA_0: - idx = 0; + idx = speed - XFER_UDMA_0; break; default: return 1; @@ -329,7 +299,7 @@ static int scc_tune_chipset(ide_drive_t *drive, byte xferspeed) * required. * If the drive isn't suitable for DMA or we hit other problems * then we will drop down to PIO and set up PIO appropriately. - * (return 1) + * (return -1) */ static int scc_config_drive_for_dma(ide_drive_t *drive) @@ -338,7 +308,7 @@ static int scc_config_drive_for_dma(ide_drive_t *drive) return 0; if (ide_use_fast_pio(drive)) - scc_tuneproc(drive, 4); + ide_set_max_pio(drive); return -1; } @@ -401,6 +371,33 @@ static int scc_ide_dma_end(ide_drive_t * drive) ide_hwif_t *hwif = HWIF(drive); unsigned long intsts_port = hwif->dma_base + 0x014; u32 reg; + int dma_stat, data_loss = 0; + static int retry = 0; + + /* errata A308 workaround: Step5 (check data loss) */ + /* We don't check non ide_disk because it is limited to UDMA4 */ + if (!(in_be32((void __iomem *)IDE_ALTSTATUS_REG) & ERR_STAT) && + drive->media == ide_disk && drive->current_speed > XFER_UDMA_4) { + reg = in_be32((void __iomem *)intsts_port); + if (!(reg & INTSTS_ACTEINT)) { + printk(KERN_WARNING "%s: operation failed (transfer data loss)\n", + drive->name); + data_loss = 1; + if (retry++) { + struct request *rq = HWGROUP(drive)->rq; + int unit; + /* ERROR_RESET and drive->crc_count are needed + * to reduce DMA transfer mode in retry process. + */ + if (rq) + rq->errors |= ERROR_RESET; + for (unit = 0; unit < MAX_DRIVES; unit++) { + ide_drive_t *drive = &hwif->drives[unit]; + drive->crc_count++; + } + } + } + } while (1) { reg = in_be32((void __iomem *)intsts_port); @@ -469,27 +466,25 @@ static int scc_ide_dma_end(ide_drive_t * drive) break; } - return __ide_dma_end(drive); + dma_stat = __ide_dma_end(drive); + if (data_loss) + dma_stat |= 2; /* emulate DMA error (to retry command) */ + return dma_stat; } /* returns 1 if dma irq issued, 0 otherwise */ static int scc_dma_test_irq(ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - u8 dma_stat = hwif->INB(hwif->dma_status); + ide_hwif_t *hwif = HWIF(drive); + u32 int_stat = in_be32((void __iomem *)hwif->dma_base + 0x014); - /* return 1 if INTR asserted */ - if ((dma_stat & 4) == 4) + /* SCC errata A252,A308 workaround: Step4 */ + if ((in_be32((void __iomem *)IDE_ALTSTATUS_REG) & ERR_STAT) && + (int_stat & INTSTS_INTRQ)) return 1; - /* Workaround for PTERADD: emulate DMA_INTR when - * - IDE_STATUS[ERR] = 1 - * - INT_STATUS[INTRQ] = 1 - * - DMA_STATUS[IORACTA] = 1 - */ - if (in_be32((void __iomem *)IDE_ALTSTATUS_REG) & ERR_STAT && - in_be32((void __iomem *)(hwif->dma_base + 0x014)) & INTSTS_INTRQ && - dma_stat & 1) + /* SCC errata A308 workaround: Step5 (polling IOIRQS) */ + if (int_stat & INTSTS_IOIRQS) return 1; if (!drive->waiting_for_dma) @@ -498,6 +493,21 @@ static int scc_dma_test_irq(ide_drive_t *drive) return 0; } +static u8 scc_udma_filter(ide_drive_t *drive) +{ + ide_hwif_t *hwif = drive->hwif; + u8 mask = hwif->ultra_mask; + + /* errata A308 workaround: limit non ide_disk drive to UDMA4 */ + if ((drive->media != ide_disk) && (mask & 0xE0)) { + printk(KERN_INFO "%s: limit %s to UDMA4\n", + SCC_PATA_NAME, drive->name); + mask = 0x1F; + } + + return mask; +} + /** * setup_mmio_scc - map CTRL/BMID region * @dev: PCI device we are configuring @@ -511,8 +521,8 @@ static int setup_mmio_scc (struct pci_dev *dev, const char *name) unsigned long dma_base = pci_resource_start(dev, 1); unsigned long ctl_size = pci_resource_len(dev, 0); unsigned long dma_size = pci_resource_len(dev, 1); - void *ctl_addr; - void *dma_addr; + void __iomem *ctl_addr; + void __iomem *dma_addr; int i; for (i = 0; i < MAX_HWIFS; i++) { @@ -699,9 +709,10 @@ static void __devinit init_hwif_scc(ide_hwif_t *hwif) hwif->dma_setup = scc_dma_setup; hwif->ide_dma_end = scc_ide_dma_end; hwif->speedproc = scc_tune_chipset; - hwif->tuneproc = scc_tuneproc; + hwif->set_pio_mode = scc_set_pio_mode; hwif->ide_dma_check = scc_config_drive_for_dma; hwif->ide_dma_test_irq = scc_dma_test_irq; + hwif->udma_filter = scc_udma_filter; hwif->drives[0].autotune = IDE_TUNE_AUTO; hwif->drives[1].autotune = IDE_TUNE_AUTO; @@ -731,9 +742,10 @@ static void __devinit init_hwif_scc(ide_hwif_t *hwif) .init_setup = init_setup_scc, \ .init_iops = init_iops_scc, \ .init_hwif = init_hwif_scc, \ - .channels = 1, \ .autodma = AUTODMA, \ .bootable = ON_BOARD, \ + .host_flags = IDE_HFLAG_SINGLE, \ + .pio_mask = ATA_PIO4, \ } static ide_pci_device_t scc_chipsets[] __devinitdata = { diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c index ed04e0c8dd4c..0351cf210427 100644 --- a/drivers/ide/pci/serverworks.c +++ b/drivers/ide/pci/serverworks.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/serverworks.c Version 0.20 Jun 3 2007 + * linux/drivers/ide/pci/serverworks.c Version 0.22 Jun 27 2007 * * Copyright (C) 1998-2000 Michel Aubry * Copyright (C) 1998-2000 Andrzej Krzysztofowicz @@ -123,23 +123,39 @@ static u8 svwks_csb_check (struct pci_dev *dev) } return 0; } -static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed) + +static void svwks_tune_pio(ide_drive_t *drive, const u8 pio) +{ + static const u8 pio_modes[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 }; + static const u8 drive_pci[] = { 0x41, 0x40, 0x43, 0x42 }; + + struct pci_dev *dev = drive->hwif->pci_dev; + + pci_write_config_byte(dev, drive_pci[drive->dn], pio_modes[pio]); + + if (svwks_csb_check(dev)) { + u16 csb_pio = 0; + + pci_read_config_word(dev, 0x4a, &csb_pio); + + csb_pio &= ~(0x0f << (4 * drive->dn)); + csb_pio |= (pio << (4 * drive->dn)); + + pci_write_config_word(dev, 0x4a, csb_pio); + } +} + +static int svwks_tune_chipset(ide_drive_t *drive, const u8 speed) { static const u8 udma_modes[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; static const u8 dma_modes[] = { 0x77, 0x21, 0x20 }; - static const u8 pio_modes[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 }; - static const u8 drive_pci[] = { 0x41, 0x40, 0x43, 0x42 }; static const u8 drive_pci2[] = { 0x45, 0x44, 0x47, 0x46 }; ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; - u8 speed = ide_rate_filter(drive, xferspeed); - u8 pio = ide_get_best_pio_mode(drive, 255, 4, NULL); u8 unit = (drive->select.b.unit & 0x01); - u8 csb5 = svwks_csb_check(dev); - u8 ultra_enable = 0, ultra_timing = 0; - u8 dma_timing = 0, pio_timing = 0; - u16 csb5_pio = 0; + + u8 ultra_enable = 0, ultra_timing = 0, dma_timing = 0; /* If we are about to put a disk into UDMA mode we screwed up. Our code assumes we never _ever_ do this on an OSB4 */ @@ -149,31 +165,15 @@ static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed) BUG(); pci_read_config_byte(dev, (0x56|hwif->channel), &ultra_timing); - pci_read_config_word(dev, 0x4A, &csb5_pio); pci_read_config_byte(dev, 0x54, &ultra_enable); ultra_timing &= ~(0x0F << (4*unit)); ultra_enable &= ~(0x01 << drive->dn); - csb5_pio &= ~(0x0F << (4*drive->dn)); switch(speed) { - case XFER_PIO_4: - case XFER_PIO_3: - case XFER_PIO_2: - case XFER_PIO_1: - case XFER_PIO_0: - pio_timing |= pio_modes[speed - XFER_PIO_0]; - csb5_pio |= ((speed - XFER_PIO_0) << (4*drive->dn)); - break; - case XFER_MW_DMA_2: case XFER_MW_DMA_1: case XFER_MW_DMA_0: - /* - * TODO: always setup PIO mode so this won't be needed - */ - pio_timing |= pio_modes[pio]; - csb5_pio |= (pio << (4*drive->dn)); dma_timing |= dma_modes[speed - XFER_MW_DMA_0]; break; @@ -183,11 +183,6 @@ static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed) case XFER_UDMA_2: case XFER_UDMA_1: case XFER_UDMA_0: - /* - * TODO: always setup PIO mode so this won't be needed - */ - pio_timing |= pio_modes[pio]; - csb5_pio |= (pio << (4*drive->dn)); dma_timing |= dma_modes[2]; ultra_timing |= ((udma_modes[speed - XFER_UDMA_0]) << (4*unit)); ultra_enable |= (0x01 << drive->dn); @@ -195,10 +190,6 @@ static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed) break; } - pci_write_config_byte(dev, drive_pci[drive->dn], pio_timing); - if (csb5) - pci_write_config_word(dev, 0x4A, csb5_pio); - pci_write_config_byte(dev, drive_pci2[drive->dn], dma_timing); pci_write_config_byte(dev, (0x56|hwif->channel), ultra_timing); pci_write_config_byte(dev, 0x54, ultra_enable); @@ -206,10 +197,10 @@ static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed) return (ide_config_drive_speed(drive, speed)); } -static void svwks_tune_drive (ide_drive_t *drive, u8 pio) +static void svwks_set_pio_mode(ide_drive_t *drive, const u8 pio) { - pio = ide_get_best_pio_mode(drive, pio, 4, NULL); - (void)svwks_tune_chipset(drive, XFER_PIO_0 + pio); + svwks_tune_pio(drive, pio); + (void)ide_config_drive_speed(drive, XFER_PIO_0 + pio); } static int svwks_config_drive_xfer_rate (ide_drive_t *drive) @@ -220,7 +211,7 @@ static int svwks_config_drive_xfer_rate (ide_drive_t *drive) return 0; if (ide_use_fast_pio(drive)) - svwks_tune_drive(drive, 255); + ide_set_max_pio(drive); return -1; } @@ -389,12 +380,10 @@ static u8 __devinit ata66_svwks(ide_hwif_t *hwif) static void __devinit init_hwif_svwks (ide_hwif_t *hwif) { - u8 dma_stat = 0; - if (!hwif->irq) hwif->irq = hwif->channel ? 15 : 14; - hwif->tuneproc = &svwks_tune_drive; + hwif->set_pio_mode = &svwks_set_pio_mode; hwif->speedproc = &svwks_tune_chipset; hwif->udma_filter = &svwks_udma_filter; @@ -407,11 +396,11 @@ static void __devinit init_hwif_svwks (ide_hwif_t *hwif) hwif->autodma = 0; - if (!hwif->dma_base) { - hwif->drives[0].autotune = 1; - hwif->drives[1].autotune = 1; + hwif->drives[0].autotune = 1; + hwif->drives[1].autotune = 1; + + if (!hwif->dma_base) return; - } hwif->ide_dma_check = &svwks_config_drive_xfer_rate; if (hwif->pci_dev->device != PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) { @@ -421,11 +410,7 @@ static void __devinit init_hwif_svwks (ide_hwif_t *hwif) if (!noautodma) hwif->autodma = 1; - dma_stat = inb(hwif->dma_status); - hwif->drives[0].autodma = (dma_stat & 0x20); - hwif->drives[1].autodma = (dma_stat & 0x40); - hwif->drives[0].autotune = (!(dma_stat & 0x20)); - hwif->drives[1].autotune = (!(dma_stat & 0x40)); + hwif->drives[0].autodma = hwif->drives[1].autodma = 1; } static int __devinit init_setup_svwks (struct pci_dev *dev, ide_pci_device_t *d) @@ -441,9 +426,12 @@ static int __devinit init_setup_csb6 (struct pci_dev *dev, ide_pci_device_t *d) d->bootable = ON_BOARD; } - d->channels = ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE || - dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2) && - (!(PCI_FUNC(dev->devfn) & 1))) ? 1 : 2; + if ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE || + dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2) && + (!(PCI_FUNC(dev->devfn) & 1))) + d->host_flags |= IDE_HFLAG_SINGLE; + else + d->host_flags &= ~IDE_HFLAG_SINGLE; return ide_setup_pci_device(dev, d); } @@ -454,41 +442,43 @@ static ide_pci_device_t serverworks_chipsets[] __devinitdata = { .init_setup = init_setup_svwks, .init_chipset = init_chipset_svwks, .init_hwif = init_hwif_svwks, - .channels = 2, .autodma = AUTODMA, .bootable = ON_BOARD, + .pio_mask = ATA_PIO4, },{ /* 1 */ .name = "SvrWks CSB5", .init_setup = init_setup_svwks, .init_chipset = init_chipset_svwks, .init_hwif = init_hwif_svwks, - .channels = 2, .autodma = AUTODMA, .bootable = ON_BOARD, + .pio_mask = ATA_PIO4, },{ /* 2 */ .name = "SvrWks CSB6", .init_setup = init_setup_csb6, .init_chipset = init_chipset_svwks, .init_hwif = init_hwif_svwks, - .channels = 2, .autodma = AUTODMA, .bootable = ON_BOARD, + .pio_mask = ATA_PIO4, },{ /* 3 */ .name = "SvrWks CSB6", .init_setup = init_setup_csb6, .init_chipset = init_chipset_svwks, .init_hwif = init_hwif_svwks, - .channels = 1, /* 2 */ .autodma = AUTODMA, .bootable = ON_BOARD, + .host_flags = IDE_HFLAG_SINGLE, + .pio_mask = ATA_PIO4, },{ /* 4 */ .name = "SvrWks HT1000", .init_setup = init_setup_svwks, .init_chipset = init_chipset_svwks, .init_hwif = init_hwif_svwks, - .channels = 1, /* 2 */ .autodma = AUTODMA, .bootable = ON_BOARD, + .host_flags = IDE_HFLAG_SINGLE, + .pio_mask = ATA_PIO4, } }; diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index d396b2929ed8..c292e1de1d56 100644 --- a/drivers/ide/pci/sgiioc4.c +++ b/drivers/ide/pci/sgiioc4.c @@ -34,6 +34,8 @@ #include <linux/ide.h> +#define DRV_NAME "SGIIOC4" + /* IOC4 Specific Definitions */ #define IOC4_CMD_OFFSET 0x100 #define IOC4_CTRL_OFFSET 0x120 @@ -289,15 +291,26 @@ static void sgiioc4_dma_off_quietly(ide_drive_t *drive) drive->hwif->dma_host_off(drive); } +static int sgiioc4_speedproc(ide_drive_t *drive, const u8 speed) +{ + if (speed != XFER_MW_DMA_2) + return 1; + + return ide_config_drive_speed(drive, speed); +} + static int sgiioc4_ide_dma_check(ide_drive_t *drive) { - /* FIXME: check for available DMA modes */ - if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0) { - printk(KERN_WARNING "%s: couldn't set MWDMA2 mode, " - "using PIO instead\n", drive->name); - return -1; - } else + if (ide_tune_dma(drive)) return 0; + + /* + * ->set_pio_mode is not implemented currently + * so this is just for the completness + */ + ide_set_max_pio(drive); + + return -1; } /* returns 1 if dma irq issued, 0 otherwise */ @@ -353,7 +366,7 @@ sgiioc4_INB(unsigned long port) } /* Creates a dma map for the scatter-gather list entries */ -static void __devinit +static int __devinit ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base) { void __iomem *virt_dma_base; @@ -369,7 +382,7 @@ ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base) "ALREADY in use\n", __FUNCTION__, hwif->name, (void *) dma_base, (void *) dma_base + num_ports - 1); - goto dma_alloc_failure; + return -1; } virt_dma_base = ioremap(dma_base, num_ports); @@ -395,7 +408,7 @@ ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base) if (pad) { ide_set_hwifdata(hwif, pad); - return; + return 0; } pci_free_consistent(hwif->pci_dev, @@ -413,10 +426,7 @@ dma_pci_alloc_failure: dma_remap_failure: release_mem_region(dma_base, num_ports); -dma_alloc_failure: - /* Disable DMA because we couldnot allocate any DMA maps */ - hwif->autodma = 0; - hwif->atapi_dma = 0; + return -1; } /* Initializes the IOC4 DMA Engine */ @@ -581,13 +591,11 @@ static void __devinit ide_init_sgiioc4(ide_hwif_t * hwif) { hwif->mmio = 1; - hwif->autodma = 1; hwif->atapi_dma = 1; - hwif->ultra_mask = 0x0; /* Disable Ultra DMA */ - hwif->mwdma_mask = 0x2; /* Multimode-2 DMA */ - hwif->swdma_mask = 0x2; - hwif->tuneproc = NULL; /* Sets timing for PIO mode */ - hwif->speedproc = NULL; /* Sets timing for DMA &/or PIO modes */ + hwif->mwdma_mask = 0x04; + hwif->pio_mask = 0x00; + hwif->set_pio_mode = NULL; /* Sets timing for PIO mode */ + hwif->speedproc = &sgiioc4_speedproc; hwif->selectproc = NULL;/* Use the default routine to select drive */ hwif->reset_poll = NULL;/* No HBA specific reset_poll needed */ hwif->pre_reset = NULL; /* No HBA specific pre_set needed */ @@ -614,7 +622,7 @@ ide_init_sgiioc4(ide_hwif_t * hwif) } static int __devinit -sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d) +sgiioc4_ide_setup_pci_device(struct pci_dev *dev) { unsigned long cmd_base, dma_base, irqport; unsigned long bar0, cmd_phys_base, ctl; @@ -631,7 +639,8 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d) break; } if (h == MAX_HWIFS) { - printk(KERN_ERR "%s: too many IDE interfaces, no room in table\n", d->name); + printk(KERN_ERR "%s: too many IDE interfaces, no room in table\n", + DRV_NAME); return -ENOMEM; } @@ -640,7 +649,7 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d) virt_base = ioremap(bar0, pci_resource_len(dev, 0)); if (virt_base == NULL) { printk(KERN_ERR "%s: Unable to remap BAR 0 address: 0x%lx\n", - d->name, bar0); + DRV_NAME, bar0); return -ENOMEM; } cmd_base = (unsigned long) virt_base + IOC4_CMD_OFFSET; @@ -671,7 +680,6 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d) hwif->chipset = ide_pci; hwif->pci_dev = dev; hwif->channel = 0; /* Single Channel chip */ - hwif->cds = (struct ide_pci_device_s *) d; hwif->gendev.parent = &dev->dev;/* setup proper ancestral information */ /* The IOC4 uses MMIO rather than Port IO. */ @@ -682,11 +690,14 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d) ide_init_sgiioc4(hwif); - if (dma_base) - ide_dma_sgiioc4(hwif, dma_base); - else + hwif->autodma = 0; + + if (dma_base && ide_dma_sgiioc4(hwif, dma_base) == 0) { + hwif->autodma = 1; + hwif->drives[1].autodma = hwif->drives[0].autodma = 1; + } else printk(KERN_INFO "%s: %s Bus-Master DMA disabled\n", - hwif->name, d->name); + hwif->name, DRV_NAME); if (probe_hwif_init(hwif)) return -EIO; @@ -698,7 +709,7 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d) } static unsigned int __devinit -pci_init_sgiioc4(struct pci_dev *dev, ide_pci_device_t * d) +pci_init_sgiioc4(struct pci_dev *dev) { unsigned int class_rev; int ret; @@ -706,30 +717,20 @@ pci_init_sgiioc4(struct pci_dev *dev, ide_pci_device_t * d) pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); class_rev &= 0xff; printk(KERN_INFO "%s: IDE controller at PCI slot %s, revision %d\n", - d->name, pci_name(dev), class_rev); + DRV_NAME, pci_name(dev), class_rev); if (class_rev < IOC4_SUPPORTED_FIRMWARE_REV) { printk(KERN_ERR "Skipping %s IDE controller in slot %s: " - "firmware is obsolete - please upgrade to revision" - "46 or higher\n", d->name, pci_name(dev)); + "firmware is obsolete - please upgrade to " + "revision46 or higher\n", + DRV_NAME, pci_name(dev)); ret = -EAGAIN; goto out; } - ret = sgiioc4_ide_setup_pci_device(dev, d); + ret = sgiioc4_ide_setup_pci_device(dev); out: return ret; } -static ide_pci_device_t sgiioc4_chipset __devinitdata = { - /* Channel 0 */ - .name = "SGIIOC4", - .init_hwif = ide_init_sgiioc4, - .init_dma = ide_dma_sgiioc4, - .channels = 1, - .autodma = AUTODMA, - /* SGI IOC4 doesn't have enablebits. */ - .bootable = ON_BOARD, -}; - int ioc4_ide_attach_one(struct ioc4_driver_data *idd) { @@ -739,7 +740,7 @@ ioc4_ide_attach_one(struct ioc4_driver_data *idd) if (idd->idd_variant == IOC4_VARIANT_PCI_RT) return 0; - return pci_init_sgiioc4(idd->idd_pdev, &sgiioc4_chipset); + return pci_init_sgiioc4(idd->idd_pdev); } static struct ioc4_submodule ioc4_ide_submodule = { diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c index 1c3e35487893..5d1e5e52a044 100644 --- a/drivers/ide/pci/siimage.c +++ b/drivers/ide/pci/siimage.c @@ -1,9 +1,10 @@ /* - * linux/drivers/ide/pci/siimage.c Version 1.12 Mar 10 2007 + * linux/drivers/ide/pci/siimage.c Version 1.16 Jul 13 2007 * * Copyright (C) 2001-2002 Andre Hedrick <andre@linux-ide.org> * Copyright (C) 2003 Red Hat <alan@redhat.com> * Copyright (C) 2007 MontaVista Software, Inc. + * Copyright (C) 2007 Bartlomiej Zolnierkiewicz * * May be copied or modified under the terms of the GNU General Public License * @@ -31,6 +32,10 @@ * unplugging/replugging the virtual CD interface when the DRAC is reset. * This often causes drivers/ide/siimage to panic but is ok with the rather * smarter code in libata. + * + * TODO: + * - IORDY fixes + * - VDMA support */ #include <linux/types.h> @@ -160,140 +165,90 @@ out: } /** - * siimage_taskfile_timing - turn timing data to a mode - * @hwif: interface to query - * - * Read the timing data for the interface and return the - * mode that is being used. - */ - -static byte siimage_taskfile_timing (ide_hwif_t *hwif) -{ - u16 timing = 0x328a; - unsigned long addr = siimage_selreg(hwif, 2); - - if (hwif->mmio) - timing = hwif->INW(addr); - else - pci_read_config_word(hwif->pci_dev, addr, &timing); - - switch (timing) { - case 0x10c1: return 4; - case 0x10c3: return 3; - case 0x1104: - case 0x1281: return 2; - case 0x2283: return 1; - case 0x328a: - default: return 0; - } -} - -/** - * simmage_tuneproc - tune a drive + * sil_tune_pio - tune a drive * @drive: drive to tune - * @mode_wanted: the target operating mode + * @pio: the desired PIO mode * * Load the timing settings for this device mode into the * controller. If we are in PIO mode 3 or 4 turn on IORDY * monitoring (bit 9). The TF timing is bits 31:16 */ - -static void siimage_tuneproc (ide_drive_t *drive, byte mode_wanted) + +static void sil_tune_pio(ide_drive_t *drive, u8 pio) { + const u16 tf_speed[] = { 0x328a, 0x2283, 0x1281, 0x10c3, 0x10c1 }; + const u16 data_speed[] = { 0x328a, 0x2283, 0x1104, 0x10c3, 0x10c1 }; + ide_hwif_t *hwif = HWIF(drive); + ide_drive_t *pair = &hwif->drives[drive->dn ^ 1]; u32 speedt = 0; u16 speedp = 0; unsigned long addr = siimage_seldev(drive, 0x04); unsigned long tfaddr = siimage_selreg(hwif, 0x02); - - /* cheat for now and use the docs */ - switch (mode_wanted) { - case 4: - speedp = 0x10c1; - speedt = 0x10c1; - break; - case 3: - speedp = 0x10c3; - speedt = 0x10c3; - break; - case 2: - speedp = 0x1104; - speedt = 0x1281; - break; - case 1: - speedp = 0x2283; - speedt = 0x2283; - break; - case 0: - default: - speedp = 0x328a; - speedt = 0x328a; - break; + unsigned long base = (unsigned long)hwif->hwif_data; + u8 tf_pio = pio; + u8 addr_mask = hwif->channel ? (hwif->mmio ? 0xF4 : 0x84) + : (hwif->mmio ? 0xB4 : 0x80); + u8 mode = 0; + u8 unit = drive->select.b.unit; + + /* trim *taskfile* PIO to the slowest of the master/slave */ + if (pair->present) { + u8 pair_pio = ide_get_best_pio_mode(pair, 255, 4); + + if (pair_pio < tf_pio) + tf_pio = pair_pio; } + /* cheat for now and use the docs */ + speedp = data_speed[pio]; + speedt = tf_speed[tf_pio]; + if (hwif->mmio) { hwif->OUTW(speedp, addr); hwif->OUTW(speedt, tfaddr); /* Now set up IORDY */ - if(mode_wanted == 3 || mode_wanted == 4) + if (pio > 2) hwif->OUTW(hwif->INW(tfaddr-2)|0x200, tfaddr-2); else hwif->OUTW(hwif->INW(tfaddr-2)&~0x200, tfaddr-2); + + mode = hwif->INB(base + addr_mask); + mode &= ~(unit ? 0x30 : 0x03); + mode |= (unit ? 0x10 : 0x01); + hwif->OUTB(mode, base + addr_mask); } else { pci_write_config_word(hwif->pci_dev, addr, speedp); pci_write_config_word(hwif->pci_dev, tfaddr, speedt); pci_read_config_word(hwif->pci_dev, tfaddr-2, &speedp); speedp &= ~0x200; /* Set IORDY for mode 3 or 4 */ - if(mode_wanted == 3 || mode_wanted == 4) + if (pio > 2) speedp |= 0x200; pci_write_config_word(hwif->pci_dev, tfaddr-2, speedp); + + pci_read_config_byte(hwif->pci_dev, addr_mask, &mode); + mode &= ~(unit ? 0x30 : 0x03); + mode |= (unit ? 0x10 : 0x01); + pci_write_config_byte(hwif->pci_dev, addr_mask, mode); } } -/** - * config_siimage_chipset_for_pio - set drive timings - * @drive: drive to tune - * @speed we want - * - * Compute the best pio mode we can for a given device. Also honour - * the timings for the driver when dealing with mixed devices. Some - * of this is ugly but its all wrapped up here - * - * The SI680 can also do VDMA - we need to start using that - * - * FIXME: we use the BIOS channel timings to avoid driving the task - * files too fast at the disk. We need to compute the master/slave - * drive PIO mode properly so that we can up the speed on a hotplug - * system. - */ - -static void config_siimage_chipset_for_pio (ide_drive_t *drive, byte set_speed) +static void sil_set_pio_mode(ide_drive_t *drive, const u8 pio) { - u8 channel_timings = siimage_taskfile_timing(HWIF(drive)); - u8 speed = 0, set_pio = ide_get_best_pio_mode(drive, 4, 5, NULL); - - /* 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; - - siimage_tuneproc(drive, set_pio); - speed = XFER_PIO_0 + set_pio; - if (set_speed) - (void) ide_config_drive_speed(drive, speed); + sil_tune_pio(drive, pio); + (void)ide_config_drive_speed(drive, XFER_PIO_0 + pio); } /** * siimage_tune_chipset - set controller timings * @drive: Drive to set up - * @xferspeed: speed we want to achieve + * @speed: speed we want to achieve * - * Tune the SII chipset for the desired mode. If we can't achieve - * the desired mode then tune for a lower one, but ultimately - * make the thing work. + * Tune the SII chipset for the desired mode. */ - -static int siimage_tune_chipset (ide_drive_t *drive, byte xferspeed) + +static int siimage_tune_chipset(ide_drive_t *drive, const u8 speed) { u8 ultra6[] = { 0x0F, 0x0B, 0x07, 0x05, 0x03, 0x02, 0x01 }; u8 ultra5[] = { 0x0C, 0x07, 0x05, 0x04, 0x02, 0x01 }; @@ -302,7 +257,6 @@ static int siimage_tune_chipset (ide_drive_t *drive, byte xferspeed) ide_hwif_t *hwif = HWIF(drive); u16 ultra = 0, multi = 0; u8 mode = 0, unit = drive->select.b.unit; - u8 speed = ide_rate_filter(drive, xferspeed); unsigned long base = (unsigned long)hwif->hwif_data; u8 scsc = 0, addr_mask = ((hwif->channel) ? ((hwif->mmio) ? 0xF4 : 0x84) : @@ -330,20 +284,11 @@ static int siimage_tune_chipset (ide_drive_t *drive, byte xferspeed) 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: @@ -356,7 +301,6 @@ static int siimage_tune_chipset (ide_drive_t *drive, byte xferspeed) 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; @@ -390,7 +334,7 @@ static int siimage_config_drive_for_dma (ide_drive_t *drive) return 0; if (ide_use_fast_pio(drive)) - config_siimage_chipset_for_pio(drive, 1); + ide_set_max_pio(drive); return -1; } @@ -961,7 +905,7 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif) hwif->resetproc = &siimage_reset; hwif->speedproc = &siimage_tune_chipset; - hwif->tuneproc = &siimage_tuneproc; + hwif->set_pio_mode = &sil_set_pio_mode; hwif->reset_poll = &siimage_reset_poll; hwif->pre_reset = &siimage_pre_reset; hwif->udma_filter = &sil_udma_filter; @@ -976,11 +920,11 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif) first = 0; } } - if (!hwif->dma_base) { - hwif->drives[0].autotune = 1; - hwif->drives[1].autotune = 1; + + hwif->drives[0].autotune = hwif->drives[1].autotune = 1; + + if (hwif->dma_base == 0) return; - } hwif->ultra_mask = 0x7f; hwif->mwdma_mask = 0x07; @@ -1016,9 +960,9 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif) .init_iops = init_iops_siimage, \ .init_hwif = init_hwif_siimage, \ .fixup = siimage_fixup, \ - .channels = 2, \ .autodma = AUTODMA, \ .bootable = ON_BOARD, \ + .pio_mask = ATA_PIO4, \ } static ide_pci_device_t siimage_chipsets[] __devinitdata = { diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c index 756a9b6eb462..3e18899de631 100644 --- a/drivers/ide/pci/sis5513.c +++ b/drivers/ide/pci/sis5513.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/sis5513.c Version 0.25 Jun 10, 2007 + * linux/drivers/ide/pci/sis5513.c Version 0.27 Jul 14, 2007 * * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org> * Copyright (C) 2002 Lionel Bouton <Lionel.Bouton@inet6.fr>, Maintainer @@ -519,27 +519,18 @@ static void config_art_rwp_pio (ide_drive_t *drive, u8 pio) } } -static int sis5513_tune_drive(ide_drive_t *drive, u8 pio) +static void sis_set_pio_mode(ide_drive_t *drive, const u8 pio) { - pio = ide_get_best_pio_mode(drive, pio, 4, NULL); config_art_rwp_pio(drive, pio); - return ide_config_drive_speed(drive, XFER_PIO_0 + pio); + (void)ide_config_drive_speed(drive, XFER_PIO_0 + pio); } -static void sis5513_tuneproc(ide_drive_t *drive, u8 pio) -{ - (void)sis5513_tune_drive(drive, pio); -} - -static int sis5513_tune_chipset (ide_drive_t *drive, u8 xferspeed) +static int sis5513_tune_chipset(ide_drive_t *drive, const u8 speed) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; - - u8 drive_pci, reg, speed; u32 regdw; - - speed = ide_rate_filter(drive, xferspeed); + u8 drive_pci, reg; /* See config_art_rwp_pio for drive pci config registers */ drive_pci = 0x40; @@ -582,9 +573,6 @@ static int sis5513_tune_chipset (ide_drive_t *drive, u8 xferspeed) regdw |= (unsigned long)cycle_time_value[ATA_133][speed-XFER_UDMA_0] << 4; regdw |= (unsigned long)cvs_time_value[ATA_133][speed-XFER_UDMA_0] << 8; } else { - /* if ATA133 disable, we should not set speed above UDMA5 */ - if (speed > XFER_UDMA_5) - speed = XFER_UDMA_5; regdw |= (unsigned long)cycle_time_value[ATA_100][speed-XFER_UDMA_0] << 4; regdw |= (unsigned long)cvs_time_value[ATA_100][speed-XFER_UDMA_0] << 8; } @@ -608,12 +596,6 @@ static int sis5513_tune_chipset (ide_drive_t *drive, u8 xferspeed) case XFER_SW_DMA_1: case XFER_SW_DMA_0: break; - case XFER_PIO_4: - case XFER_PIO_3: - case XFER_PIO_2: - case XFER_PIO_1: - case XFER_PIO_0: - return sis5513_tune_drive(drive, speed - XFER_PIO_0); default: BUG(); break; @@ -627,7 +609,7 @@ static int sis5513_config_xfer_rate(ide_drive_t *drive) /* * TODO: always set PIO mode and remove this */ - sis5513_tuneproc(drive, 255); + ide_set_max_pio(drive); drive->init_speed = 0; @@ -635,11 +617,25 @@ static int sis5513_config_xfer_rate(ide_drive_t *drive) return 0; if (ide_use_fast_pio(drive)) - sis5513_tuneproc(drive, 255); + ide_set_max_pio(drive); return -1; } +static u8 sis5513_ata133_udma_filter(ide_drive_t *drive) +{ + struct pci_dev *dev = drive->hwif->pci_dev; + int drive_pci; + u32 reg54 = 0, regdw = 0; + + pci_read_config_dword(dev, 0x54, ®54); + drive_pci = ((reg54 & 0x40000000) ? 0x70 : 0x40) + drive->dn * 4; + pci_read_config_dword(dev, drive_pci, ®dw); + + /* if ATA133 disable, we should not set speed above UDMA5 */ + return (regdw & 0x08) ? ATA_UDMA6 : ATA_UDMA5; +} + /* Chip detection and general config */ static unsigned int __devinit init_chipset_sis5513 (struct pci_dev *dev, const char *name) { @@ -801,6 +797,7 @@ struct sis_laptop { static const struct sis_laptop sis_laptop[] = { /* devid, subvendor, subdev */ { 0x5513, 0x1043, 0x1107 }, /* ASUS A6K */ + { 0x5513, 0x1734, 0x105f }, /* FSC Amilo A1630 */ /* end marker */ { 0, } }; @@ -843,9 +840,12 @@ static void __devinit init_hwif_sis5513 (ide_hwif_t *hwif) if (!hwif->irq) hwif->irq = hwif->channel ? 15 : 14; - hwif->tuneproc = &sis5513_tuneproc; + hwif->set_pio_mode = &sis_set_pio_mode; hwif->speedproc = &sis5513_tune_chipset; + if (chipset_family >= ATA_133) + hwif->udma_filter = sis5513_ata133_udma_filter; + if (!(hwif->dma_base)) { hwif->drives[0].autotune = 1; hwif->drives[1].autotune = 1; @@ -878,10 +878,10 @@ static ide_pci_device_t sis5513_chipset __devinitdata = { .name = "SIS5513", .init_chipset = init_chipset_sis5513, .init_hwif = init_hwif_sis5513, - .channels = 2, .autodma = NOAUTODMA, .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, .bootable = ON_BOARD, + .pio_mask = ATA_PIO4, }; static int __devinit sis5513_init_one(struct pci_dev *dev, const struct pci_device_id *id) diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c index a7323d278c49..f492318ba797 100644 --- a/drivers/ide/pci/sl82c105.c +++ b/drivers/ide/pci/sl82c105.c @@ -52,12 +52,13 @@ * Convert a PIO mode and cycle time to the required on/off times * for the interface. This has protection against runaway timings. */ -static unsigned int get_pio_timings(ide_pio_data_t *p) +static unsigned int get_pio_timings(ide_drive_t *drive, u8 pio) { unsigned int cmd_on, cmd_off; + u8 iordy = 0; - cmd_on = (ide_pio_timings[p->pio_mode].active_time + 29) / 30; - cmd_off = (p->cycle_time - 30 * cmd_on + 29) / 30; + cmd_on = (ide_pio_timings[pio].active_time + 29) / 30; + cmd_off = (ide_pio_cycle_time(drive, pio) - 30 * cmd_on + 29) / 30; if (cmd_on == 0) cmd_on = 1; @@ -65,24 +66,22 @@ static unsigned int get_pio_timings(ide_pio_data_t *p) if (cmd_off == 0) cmd_off = 1; - return (cmd_on - 1) << 8 | (cmd_off - 1) | (p->use_iordy ? 0x40 : 0x00); + if (pio > 2 || ide_dev_has_iordy(drive->id)) + iordy = 0x40; + + return (cmd_on - 1) << 8 | (cmd_off - 1) | iordy; } /* * Configure the chipset for PIO mode. */ -static u8 sl82c105_tune_pio(ide_drive_t *drive, u8 pio) +static void sl82c105_tune_pio(ide_drive_t *drive, const u8 pio) { struct pci_dev *dev = HWIF(drive)->pci_dev; int reg = 0x44 + drive->dn * 4; - ide_pio_data_t p; u16 drv_ctrl; - DBG(("sl82c105_tune_pio(drive:%s, pio:%u)\n", drive->name, pio)); - - pio = ide_get_best_pio_mode(drive, pio, 5, &p); - - drv_ctrl = get_pio_timings(&p); + drv_ctrl = get_pio_timings(drive, pio); /* * Store the PIO timings so that we can restore them @@ -101,15 +100,14 @@ static u8 sl82c105_tune_pio(ide_drive_t *drive, u8 pio) } printk(KERN_DEBUG "%s: selected %s (%dns) (%04X)\n", drive->name, - ide_xfer_verbose(pio + XFER_PIO_0), p.cycle_time, drv_ctrl); - - return pio; + ide_xfer_verbose(pio + XFER_PIO_0), + ide_pio_cycle_time(drive, pio), drv_ctrl); } /* * Configure the drive and chipset for a new transfer speed. */ -static int sl82c105_tune_chipset(ide_drive_t *drive, u8 speed) +static int sl82c105_tune_chipset(ide_drive_t *drive, const u8 speed) { static u16 mwdma_timings[] = {0x0707, 0x0201, 0x0200}; u16 drv_ctrl; @@ -117,8 +115,6 @@ static int sl82c105_tune_chipset(ide_drive_t *drive, u8 speed) DBG(("sl82c105_tune_chipset(drive:%s, speed:%s)\n", drive->name, ide_xfer_verbose(speed))); - speed = ide_rate_filter(drive, speed); - switch (speed) { case XFER_MW_DMA_2: case XFER_MW_DMA_1: @@ -143,14 +139,6 @@ static int sl82c105_tune_chipset(ide_drive_t *drive, u8 speed) pci_write_config_word(dev, reg, drv_ctrl); } break; - case XFER_PIO_5: - case XFER_PIO_4: - case XFER_PIO_3: - case XFER_PIO_2: - case XFER_PIO_1: - case XFER_PIO_0: - (void) sl82c105_tune_pio(drive, speed - XFER_PIO_0); - break; default: return -1; } @@ -323,11 +311,10 @@ static void sl82c105_resetproc(ide_drive_t *drive) * We only deal with PIO mode here - DMA mode 'using_dma' is not * initialised at the point that this function is called. */ -static void sl82c105_tune_drive(ide_drive_t *drive, u8 pio) +static void sl82c105_set_pio_mode(ide_drive_t *drive, const u8 pio) { - DBG(("sl82c105_tune_drive(drive:%s, pio:%u)\n", drive->name, pio)); + sl82c105_tune_pio(drive, pio); - pio = sl82c105_tune_pio(drive, pio); (void) ide_config_drive_speed(drive, XFER_PIO_0 + pio); } @@ -395,7 +382,7 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) DBG(("init_hwif_sl82c105(hwif: ide%d)\n", hwif->index)); - hwif->tuneproc = &sl82c105_tune_drive; + hwif->set_pio_mode = &sl82c105_set_pio_mode; hwif->speedproc = &sl82c105_tune_chipset; hwif->selectproc = &sl82c105_selectproc; hwif->resetproc = &sl82c105_resetproc; @@ -449,10 +436,10 @@ static ide_pci_device_t sl82c105_chipset __devinitdata = { .name = "W82C105", .init_chipset = init_chipset_sl82c105, .init_hwif = init_hwif_sl82c105, - .channels = 2, .autodma = NOAUTODMA, .enablebits = {{0x40,0x01,0x01}, {0x40,0x10,0x10}}, .bootable = ON_BOARD, + .pio_mask = ATA_PIO5, }; static int __devinit sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id) diff --git a/drivers/ide/pci/slc90e66.c b/drivers/ide/pci/slc90e66.c index 575dbbd8b482..ae8e91324577 100644 --- a/drivers/ide/pci/slc90e66.c +++ b/drivers/ide/pci/slc90e66.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/slc90e66.c Version 0.14 February 8, 2007 + * linux/drivers/ide/pci/slc90e66.c Version 0.16 Jul 14, 2007 * * Copyright (C) 2000-2002 Andre Hedrick <andre@linux-ide.org> * Copyright (C) 2006-2007 MontaVista Software, Inc. <source@mvista.com> @@ -29,20 +29,14 @@ static u8 slc90e66_dma_2_pio (u8 xfer_rate) { case XFER_UDMA_1: case XFER_UDMA_0: case XFER_MW_DMA_2: - case XFER_PIO_4: return 4; case XFER_MW_DMA_1: - case XFER_PIO_3: return 3; case XFER_SW_DMA_2: - case XFER_PIO_2: return 2; case XFER_MW_DMA_0: case XFER_SW_DMA_1: case XFER_SW_DMA_0: - case XFER_PIO_1: - case XFER_PIO_0: - case XFER_PIO_SLOW: default: return 0; } @@ -101,19 +95,17 @@ static void slc90e66_tune_pio (ide_drive_t *drive, u8 pio) spin_unlock_irqrestore(&ide_lock, flags); } -static void slc90e66_tune_drive (ide_drive_t *drive, u8 pio) +static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio) { - pio = ide_get_best_pio_mode(drive, pio, 4, NULL); slc90e66_tune_pio(drive, pio); (void) ide_config_drive_speed(drive, XFER_PIO_0 + pio); } -static int slc90e66_tune_chipset (ide_drive_t *drive, u8 xferspeed) +static int slc90e66_tune_chipset(ide_drive_t *drive, const u8 speed) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; u8 maslave = hwif->channel ? 0x42 : 0x40; - u8 speed = ide_rate_filter(drive, xferspeed); int sitre = 0, a_speed = 7 << (drive->dn * 4); int u_speed = 0, u_flag = 1 << drive->dn; u16 reg4042, reg44, reg48, reg4a; @@ -133,10 +125,6 @@ static int slc90e66_tune_chipset (ide_drive_t *drive, u8 xferspeed) case XFER_MW_DMA_2: case XFER_MW_DMA_1: case XFER_SW_DMA_2: break; - case XFER_PIO_4: - case XFER_PIO_3: - case XFER_PIO_2: - case XFER_PIO_0: break; default: return -1; } @@ -157,6 +145,7 @@ static int slc90e66_tune_chipset (ide_drive_t *drive, u8 xferspeed) } slc90e66_tune_pio(drive, slc90e66_dma_2_pio(speed)); + return ide_config_drive_speed(drive, speed); } @@ -168,7 +157,7 @@ static int slc90e66_config_drive_xfer_rate (ide_drive_t *drive) return 0; if (ide_use_fast_pio(drive)) - slc90e66_tune_drive(drive, 255); + ide_set_max_pio(drive); return -1; } @@ -184,7 +173,7 @@ static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif) hwif->irq = hwif->channel ? 15 : 14; hwif->speedproc = &slc90e66_tune_chipset; - hwif->tuneproc = &slc90e66_tune_drive; + hwif->set_pio_mode = &slc90e66_set_pio_mode; pci_read_config_byte(hwif->pci_dev, 0x47, ®47); @@ -214,10 +203,10 @@ static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif) static ide_pci_device_t slc90e66_chipset __devinitdata = { .name = "SLC90E66", .init_hwif = init_hwif_slc90e66, - .channels = 2, .autodma = AUTODMA, .enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, .bootable = ON_BOARD, + .pio_mask = ATA_PIO4, }; static int __devinit slc90e66_init_one(struct pci_dev *dev, const struct pci_device_id *id) diff --git a/drivers/ide/pci/tc86c001.c b/drivers/ide/pci/tc86c001.c index 8de1f8e22494..e23b9cfb6eb4 100644 --- a/drivers/ide/pci/tc86c001.c +++ b/drivers/ide/pci/tc86c001.c @@ -13,14 +13,12 @@ #include <linux/pci.h> #include <linux/ide.h> -static int tc86c001_tune_chipset(ide_drive_t *drive, u8 speed) +static int tc86c001_tune_chipset(ide_drive_t *drive, const u8 speed) { ide_hwif_t *hwif = HWIF(drive); unsigned long scr_port = hwif->config_data + (drive->dn ? 0x02 : 0x00); u16 mode, scr = hwif->INW(scr_port); - speed = ide_rate_filter(drive, speed); - switch (speed) { case XFER_UDMA_4: mode = 0x00c0; break; case XFER_UDMA_3: mode = 0x00b0; break; @@ -45,9 +43,8 @@ static int tc86c001_tune_chipset(ide_drive_t *drive, u8 speed) return ide_config_drive_speed(drive, speed); } -static void tc86c001_tune_drive(ide_drive_t *drive, u8 pio) +static void tc86c001_set_pio_mode(ide_drive_t *drive, const u8 pio) { - pio = ide_get_best_pio_mode(drive, pio, 4, NULL); (void) tc86c001_tune_chipset(drive, XFER_PIO_0 + pio); } @@ -173,7 +170,7 @@ static int tc86c001_config_drive_xfer_rate(ide_drive_t *drive) return 0; if (ide_use_fast_pio(drive)) - tc86c001_tune_drive(drive, 255); + ide_set_max_pio(drive); return -1; } @@ -195,7 +192,7 @@ static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif) /* Store the system control register base for convenience... */ hwif->config_data = sc_base; - hwif->tuneproc = &tc86c001_tune_drive; + hwif->set_pio_mode = &tc86c001_set_pio_mode; hwif->speedproc = &tc86c001_tune_chipset; hwif->busproc = &tc86c001_busproc; @@ -248,9 +245,10 @@ static ide_pci_device_t tc86c001_chipset __devinitdata = { .name = "TC86C001", .init_chipset = init_chipset_tc86c001, .init_hwif = init_hwif_tc86c001, - .channels = 1, .autodma = AUTODMA, - .bootable = OFF_BOARD + .bootable = OFF_BOARD, + .host_flags = IDE_HFLAG_SINGLE, + .pio_mask = ATA_PIO4, }; static int __devinit tc86c001_init_one(struct pci_dev *dev, diff --git a/drivers/ide/pci/triflex.c b/drivers/ide/pci/triflex.c index 35e8c612638f..c3ff066eea5a 100644 --- a/drivers/ide/pci/triflex.c +++ b/drivers/ide/pci/triflex.c @@ -40,7 +40,7 @@ #include <linux/ide.h> #include <linux/init.h> -static int triflex_tune_chipset(ide_drive_t *drive, u8 xferspeed) +static int triflex_tune_chipset(ide_drive_t *drive, const u8 speed) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; @@ -48,7 +48,6 @@ static int triflex_tune_chipset(ide_drive_t *drive, u8 xferspeed) u16 timing = 0; u32 triflex_timings = 0; u8 unit = (drive->select.b.unit & 0x01); - u8 speed = ide_rate_filter(drive, xferspeed); pci_read_config_dword(dev, channel_offset, &triflex_timings); @@ -94,10 +93,9 @@ static int triflex_tune_chipset(ide_drive_t *drive, u8 xferspeed) return (ide_config_drive_speed(drive, speed)); } -static void triflex_tune_drive(ide_drive_t *drive, u8 pio) +static void triflex_set_pio_mode(ide_drive_t *drive, const u8 pio) { - int use_pio = ide_get_best_pio_mode(drive, pio, 4, NULL); - (void) triflex_tune_chipset(drive, (XFER_PIO_0 + use_pio)); + (void)triflex_tune_chipset(drive, XFER_PIO_0 + pio); } static int triflex_config_drive_xfer_rate(ide_drive_t *drive) @@ -105,16 +103,19 @@ static int triflex_config_drive_xfer_rate(ide_drive_t *drive) if (ide_tune_dma(drive)) return 0; - triflex_tune_drive(drive, 255); + ide_set_max_pio(drive); return -1; } static void __devinit init_hwif_triflex(ide_hwif_t *hwif) { - hwif->tuneproc = &triflex_tune_drive; + hwif->set_pio_mode = &triflex_set_pio_mode; hwif->speedproc = &triflex_tune_chipset; + if (hwif->dma_base == 0) + return; + hwif->atapi_dma = 1; hwif->mwdma_mask = 0x07; hwif->swdma_mask = 0x07; @@ -129,10 +130,10 @@ static void __devinit init_hwif_triflex(ide_hwif_t *hwif) static ide_pci_device_t triflex_device __devinitdata = { .name = "TRIFLEX", .init_hwif = init_hwif_triflex, - .channels = 2, .autodma = AUTODMA, .enablebits = {{0x80, 0x01, 0x01}, {0x80, 0x02, 0x02}}, .bootable = ON_BOARD, + .pio_mask = ATA_PIO4, }; static int __devinit triflex_init_one(struct pci_dev *dev, diff --git a/drivers/ide/pci/trm290.c b/drivers/ide/pci/trm290.c index cbb1b11119a5..dc4f4e298e00 100644 --- a/drivers/ide/pci/trm290.c +++ b/drivers/ide/pci/trm290.c @@ -327,7 +327,6 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif) static ide_pci_device_t trm290_chipset __devinitdata = { .name = "TRM290", .init_hwif = init_hwif_trm290, - .channels = 2, .autodma = NOAUTODMA, .bootable = ON_BOARD, }; diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c index 27e92fb9f95e..378feb491ec4 100644 --- a/drivers/ide/pci/via82cxxx.c +++ b/drivers/ide/pci/via82cxxx.c @@ -1,6 +1,6 @@ /* * - * Version 3.45 + * Version 3.48 * * VIA IDE driver for Linux. Supported southbridges: * @@ -74,6 +74,7 @@ static struct via_isa_bridge { u8 udma_mask; u8 flags; } via_isa_bridges[] = { + { "vx800", PCI_DEVICE_ID_VIA_VX800, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST }, { "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST }, { "vt8237s", PCI_DEVICE_ID_VIA_8237S, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST }, { "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST }, @@ -157,7 +158,7 @@ static void via_set_speed(ide_hwif_t *hwif, u8 dn, struct ide_timing *timing) * by upper layers. */ -static int via_set_drive(ide_drive_t *drive, u8 speed) +static int via_set_drive(ide_drive_t *drive, const u8 speed) { ide_drive_t *peer = HWIF(drive)->drives + (~drive->dn & 1); struct via82cxxx_dev *vdev = pci_get_drvdata(drive->hwif->pci_dev); @@ -194,21 +195,16 @@ static int via_set_drive(ide_drive_t *drive, u8 speed) } /** - * via82cxxx_tune_drive - PIO setup - * @drive: drive to set up - * @pio: mode to use (255 for 'best possible') + * via_set_pio_mode - PIO setup + * @drive: drive + * @pio: PIO mode number * * A callback from the upper layers for PIO-only tuning. */ -static void via82cxxx_tune_drive(ide_drive_t *drive, u8 pio) +static void via_set_pio_mode(ide_drive_t *drive, const u8 pio) { - if (pio == 255) { - via_set_drive(drive, ide_find_best_pio_mode(drive)); - return; - } - - via_set_drive(drive, XFER_PIO_0 + min_t(u8, pio, 5)); + via_set_drive(drive, XFER_PIO_0 + pio); } /** @@ -221,16 +217,11 @@ static void via82cxxx_tune_drive(ide_drive_t *drive, u8 pio) static int via82cxxx_ide_dma_check (ide_drive_t *drive) { - u8 speed = ide_max_dma_mode(drive); - - if (speed == 0) - speed = ide_find_best_pio_mode(drive); - - via_set_drive(drive, speed); - - if (drive->autodma && (speed & XFER_MODE) != XFER_PIO) + if (ide_tune_dma(drive)) return 0; + ide_set_max_pio(drive); + return -1; } @@ -418,7 +409,7 @@ static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const * Cable special cases */ -static struct dmi_system_id cable_dmi_table[] = { +static const struct dmi_system_id cable_dmi_table[] = { { .ident = "Acer Ferrari 3400", .matches = { @@ -429,19 +420,26 @@ static struct dmi_system_id cable_dmi_table[] = { { } }; -static int via_cable_override(void) +static int via_cable_override(struct pci_dev *pdev) { /* Systems by DMI */ if (dmi_check_system(cable_dmi_table)) return 1; + + /* Arima W730-K8/Targa Visionary 811/... */ + if (pdev->subsystem_vendor == 0x161F && + pdev->subsystem_device == 0x2032) + return 1; + return 0; } static u8 __devinit via82cxxx_cable_detect(ide_hwif_t *hwif) { - struct via82cxxx_dev *vdev = pci_get_drvdata(hwif->pci_dev); + struct pci_dev *pdev = hwif->pci_dev; + struct via82cxxx_dev *vdev = pci_get_drvdata(pdev); - if (via_cable_override()) + if (via_cable_override(pdev)) return ATA_CBL_PATA40_SHORT; if ((vdev->via_80w >> hwif->channel) & 1) @@ -457,7 +455,7 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif) hwif->autodma = 0; - hwif->tuneproc = &via82cxxx_tune_drive; + hwif->set_pio_mode = &via_set_pio_mode; hwif->speedproc = &via_set_drive; @@ -498,18 +496,22 @@ static ide_pci_device_t via82cxxx_chipsets[] __devinitdata = { .name = "VP_IDE", .init_chipset = init_chipset_via82cxxx, .init_hwif = init_hwif_via82cxxx, - .channels = 2, .autodma = NOAUTODMA, .enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, - .bootable = ON_BOARD + .bootable = ON_BOARD, + .host_flags = IDE_HFLAG_PIO_NO_BLACKLIST + | IDE_HFLAG_PIO_NO_DOWNGRADE, + .pio_mask = ATA_PIO5, },{ /* 1 */ .name = "VP_IDE", .init_chipset = init_chipset_via82cxxx, .init_hwif = init_hwif_via82cxxx, - .channels = 2, .autodma = AUTODMA, .enablebits = {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, .bootable = ON_BOARD, + .host_flags = IDE_HFLAG_PIO_NO_BLACKLIST + | IDE_HFLAG_PIO_NO_DOWNGRADE, + .pio_mask = ATA_PIO5, } }; |