X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fide%2Fpci%2Faec62xx.c;h=c743e68c33aadca3894017ed2ba1c82cde5cff52;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=f474e1dbe6d9ec71d9e166052f60921ce2836ca1;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c index f474e1dbe..c743e68c3 100644 --- a/drivers/ide/pci/aec62xx.c +++ b/drivers/ide/pci/aec62xx.c @@ -16,167 +16,55 @@ #include -#include "aec62xx.h" - -#if defined(DISPLAY_AEC62XX_TIMINGS) && defined(CONFIG_PROC_FS) -#include -#include +struct chipset_bus_clock_list_entry { + u8 xfer_speed; + u8 chipset_settings; + u8 ultra_settings; +}; -static u8 aec62xx_proc = 0; +static struct chipset_bus_clock_list_entry aec6xxx_33_base [] = { + { XFER_UDMA_6, 0x31, 0x07 }, + { XFER_UDMA_5, 0x31, 0x06 }, + { XFER_UDMA_4, 0x31, 0x05 }, + { XFER_UDMA_3, 0x31, 0x04 }, + { XFER_UDMA_2, 0x31, 0x03 }, + { XFER_UDMA_1, 0x31, 0x02 }, + { XFER_UDMA_0, 0x31, 0x01 }, + + { XFER_MW_DMA_2, 0x31, 0x00 }, + { XFER_MW_DMA_1, 0x31, 0x00 }, + { XFER_MW_DMA_0, 0x0a, 0x00 }, + { XFER_PIO_4, 0x31, 0x00 }, + { XFER_PIO_3, 0x33, 0x00 }, + { XFER_PIO_2, 0x08, 0x00 }, + { XFER_PIO_1, 0x0a, 0x00 }, + { XFER_PIO_0, 0x00, 0x00 }, + { 0, 0x00, 0x00 } +}; -#define AEC_MAX_DEVS 5 +static struct chipset_bus_clock_list_entry aec6xxx_34_base [] = { + { XFER_UDMA_6, 0x41, 0x06 }, + { XFER_UDMA_5, 0x41, 0x05 }, + { XFER_UDMA_4, 0x41, 0x04 }, + { XFER_UDMA_3, 0x41, 0x03 }, + { XFER_UDMA_2, 0x41, 0x02 }, + { XFER_UDMA_1, 0x41, 0x01 }, + { XFER_UDMA_0, 0x41, 0x01 }, + + { XFER_MW_DMA_2, 0x41, 0x00 }, + { XFER_MW_DMA_1, 0x42, 0x00 }, + { XFER_MW_DMA_0, 0x7a, 0x00 }, + { XFER_PIO_4, 0x41, 0x00 }, + { XFER_PIO_3, 0x43, 0x00 }, + { XFER_PIO_2, 0x78, 0x00 }, + { XFER_PIO_1, 0x7a, 0x00 }, + { XFER_PIO_0, 0x70, 0x00 }, + { 0, 0x00, 0x00 } +}; -static struct pci_dev *aec_devs[AEC_MAX_DEVS]; -static int n_aec_devs; +#define BUSCLOCK(D) \ + ((struct chipset_bus_clock_list_entry *) pci_get_drvdata((D))) -#undef DEBUG_AEC_REGS - -static int aec62xx_get_info (char *buffer, char **addr, off_t offset, int count) -{ - char *p = buffer; - char *chipset_nums[] = {"error", "error", "error", "error", - "error", "error", "850UF", "860", - "860R", "865", "865R", "error" }; - int len; - int i; - - for (i = 0; i < n_aec_devs; i++) { - struct pci_dev *dev = aec_devs[i]; - unsigned long iobase = pci_resource_start(dev, 4); - u8 c0 = 0, c1 = 0, art = 0; -#ifdef DEBUG_AEC_REGS - u8 uart = 0; -#endif /* DEBUG_AEC_REGS */ - - c0 = inb(iobase + 0x02); - c1 = inb(iobase + 0x0a); - - p += sprintf(p, "\nController: %d\n", i); - p += sprintf(p, "Chipset: AEC%s\n", chipset_nums[dev->device]); - - p += sprintf(p, "--------------- Primary Channel " - "---------------- Secondary Channel " - "-------------\n"); - (void) pci_read_config_byte(dev, 0x4a, &art); - p += sprintf(p, " %sabled ", - (art&0x02)?" en":"dis"); - p += sprintf(p, " %sabled\n", - (art&0x04)?" en":"dis"); - p += sprintf(p, "--------------- drive0 --------- drive1 " - "-------- drive0 ---------- drive1 ------\n"); - p += sprintf(p, "DMA enabled: %s %s ", - (c0&0x20)?"yes":"no ",(c0&0x40)?"yes":"no "); - p += sprintf(p, " %s %s\n", - (c1&0x20)?"yes":"no ",(c1&0x40)?"yes":"no "); - - if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) { - (void) pci_read_config_byte(dev, 0x54, &art); - p += sprintf(p, "DMA Mode: %s(%s)", - (c0&0x20)?((art&0x03)?"UDMA":" DMA"):" PIO", - (art&0x02)?"2":(art&0x01)?"1":"0"); - p += sprintf(p, " %s(%s)", - (c0&0x40)?((art&0x0c)?"UDMA":" DMA"):" PIO", - (art&0x08)?"2":(art&0x04)?"1":"0"); - p += sprintf(p, " %s(%s)", - (c1&0x20)?((art&0x30)?"UDMA":" DMA"):" PIO", - (art&0x20)?"2":(art&0x10)?"1":"0"); - p += sprintf(p, " %s(%s)\n", - (c1&0x40)?((art&0xc0)?"UDMA":" DMA"):" PIO", - (art&0x80)?"2":(art&0x40)?"1":"0"); -#ifdef DEBUG_AEC_REGS - (void) pci_read_config_byte(dev, 0x40, &art); - p += sprintf(p, "Active: 0x%02x", art); - (void) pci_read_config_byte(dev, 0x42, &art); - p += sprintf(p, " 0x%02x", art); - (void) pci_read_config_byte(dev, 0x44, &art); - p += sprintf(p, " 0x%02x", art); - (void) pci_read_config_byte(dev, 0x46, &art); - p += sprintf(p, " 0x%02x\n", art); - (void) pci_read_config_byte(dev, 0x41, &art); - p += sprintf(p, "Recovery: 0x%02x", art); - (void) pci_read_config_byte(dev, 0x43, &art); - p += sprintf(p, " 0x%02x", art); - (void) pci_read_config_byte(dev, 0x45, &art); - p += sprintf(p, " 0x%02x", art); - (void) pci_read_config_byte(dev, 0x47, &art); - p += sprintf(p, " 0x%02x\n", art); -#endif /* DEBUG_AEC_REGS */ - } else { - /* - * case PCI_DEVICE_ID_ARTOP_ATP860: - * case PCI_DEVICE_ID_ARTOP_ATP860R: - * case PCI_DEVICE_ID_ARTOP_ATP865: - * case PCI_DEVICE_ID_ARTOP_ATP865R: - */ - (void) pci_read_config_byte(dev, 0x44, &art); - p += sprintf(p, "DMA Mode: %s(%s)", - (c0&0x20)?((art&0x07)?"UDMA":" DMA"):" PIO", - ((art&0x07)==0x07)?"6": - ((art&0x06)==0x06)?"5": - ((art&0x05)==0x05)?"4": - ((art&0x04)==0x04)?"3": - ((art&0x03)==0x03)?"2": - ((art&0x02)==0x02)?"1": - ((art&0x01)==0x01)?"0":"?"); - p += sprintf(p, " %s(%s)", - (c0&0x40)?((art&0x70)?"UDMA":" DMA"):" PIO", - ((art&0x70)==0x70)?"6": - ((art&0x60)==0x60)?"5": - ((art&0x50)==0x50)?"4": - ((art&0x40)==0x40)?"3": - ((art&0x30)==0x30)?"2": - ((art&0x20)==0x20)?"1": - ((art&0x10)==0x10)?"0":"?"); - (void) pci_read_config_byte(dev, 0x45, &art); - p += sprintf(p, " %s(%s)", - (c1&0x20)?((art&0x07)?"UDMA":" DMA"):" PIO", - ((art&0x07)==0x07)?"6": - ((art&0x06)==0x06)?"5": - ((art&0x05)==0x05)?"4": - ((art&0x04)==0x04)?"3": - ((art&0x03)==0x03)?"2": - ((art&0x02)==0x02)?"1": - ((art&0x01)==0x01)?"0":"?"); - p += sprintf(p, " %s(%s)\n", - (c1&0x40)?((art&0x70)?"UDMA":" DMA"):" PIO", - ((art&0x70)==0x70)?"6": - ((art&0x60)==0x60)?"5": - ((art&0x50)==0x50)?"4": - ((art&0x40)==0x40)?"3": - ((art&0x30)==0x30)?"2": - ((art&0x20)==0x20)?"1": - ((art&0x10)==0x10)?"0":"?"); -#ifdef DEBUG_AEC_REGS - (void) pci_read_config_byte(dev, 0x40, &art); - p += sprintf(p, "Active: 0x%02x", HIGH_4(art)); - (void) pci_read_config_byte(dev, 0x41, &art); - p += sprintf(p, " 0x%02x", HIGH_4(art)); - (void) pci_read_config_byte(dev, 0x42, &art); - p += sprintf(p, " 0x%02x", HIGH_4(art)); - (void) pci_read_config_byte(dev, 0x43, &art); - p += sprintf(p, " 0x%02x\n", HIGH_4(art)); - (void) pci_read_config_byte(dev, 0x40, &art); - p += sprintf(p, "Recovery: 0x%02x", LOW_4(art)); - (void) pci_read_config_byte(dev, 0x41, &art); - p += sprintf(p, " 0x%02x", LOW_4(art)); - (void) pci_read_config_byte(dev, 0x42, &art); - p += sprintf(p, " 0x%02x", LOW_4(art)); - (void) pci_read_config_byte(dev, 0x43, &art); - p += sprintf(p, " 0x%02x\n", LOW_4(art)); - (void) pci_read_config_byte(dev, 0x49, &uart); - p += sprintf(p, "reg49h = 0x%02x ", uart); - (void) pci_read_config_byte(dev, 0x4a, &uart); - p += sprintf(p, "reg4ah = 0x%02x\n", uart); -#endif /* DEBUG_AEC_REGS */ - } - } - /* p - buffer must be less than 4k! */ - len = (p - buffer) - offset; - *addr = buffer + offset; - - return len > count ? count : len; -} -#endif /* defined(DISPLAY_AEC62xx_TIMINGS) && defined(CONFIG_PROC_FS) */ /* * TO DO: active tuning and correction of cards without a bios. @@ -207,13 +95,9 @@ static u8 aec62xx_ratemask (ide_drive_t *drive) switch(hwif->pci_dev->device) { case PCI_DEVICE_ID_ARTOP_ATP865: case PCI_DEVICE_ID_ARTOP_ATP865R: -#if 0 - mode = (hwif->INB(hwif->dma_master) & 0x10) ? 4 : 3; -#else mode = (hwif->INB(((hwif->channel) ? hwif->mate->dma_status : hwif->dma_status)) & 0x10) ? 4 : 3; -#endif break; case PCI_DEVICE_ID_ARTOP_ATP860: case PCI_DEVICE_ID_ARTOP_ATP860R: @@ -240,10 +124,10 @@ static int aec6210_tune_chipset (ide_drive_t *drive, u8 xferspeed) unsigned long flags; local_irq_save(flags); + /* 0x40|(2*drive->dn): Active, 0x41|(2*drive->dn): Recovery */ pci_read_config_word(dev, 0x40|(2*drive->dn), &d_conf); tmp0 = pci_bus_clock_list(speed, BUSCLOCK(dev)); - SPLIT_BYTE(tmp0,tmp1,tmp2); - MAKE_WORD(d_conf,tmp1,tmp2); + d_conf = ((tmp0 & 0xf0) << 4) | (tmp0 & 0xf); pci_write_config_word(dev, 0x40|(2*drive->dn), d_conf); tmp1 = 0x00; @@ -268,6 +152,7 @@ static int aec6260_tune_chipset (ide_drive_t *drive, u8 xferspeed) unsigned long flags; local_irq_save(flags); + /* high 4-bits: Active, low 4-bits: Recovery */ pci_read_config_byte(dev, 0x40|drive->dn, &drive_conf); drive_conf = pci_bus_clock_list(speed, BUSCLOCK(dev)); pci_write_config_byte(dev, 0x40|drive->dn, drive_conf); @@ -329,36 +214,16 @@ static int aec62xx_config_drive_xfer_rate (ide_drive_t *drive) struct hd_driveid *id = drive->id; if ((id->capability & 1) && drive->autodma) { - /* Consult the list of known "bad" drives */ - if (__ide_dma_bad_drive(drive)) - goto fast_ata_pio; - if (id->field_valid & 4) { - if (id->dma_ultra & hwif->ultra_mask) { - /* Force if Capable UltraDMA */ - int dma = config_chipset_for_dma(drive); - if ((id->field_valid & 2) && !dma) - goto try_dma_modes; - } - } else if (id->field_valid & 2) { -try_dma_modes: - if ((id->dma_mword & hwif->mwdma_mask) || - (id->dma_1word & hwif->swdma_mask)) { - /* Force if Capable regular DMA modes */ - if (!config_chipset_for_dma(drive)) - goto no_dma_set; - } - } else if (__ide_dma_good_drive(drive) && - (id->eide_dma_time < 150)) { - /* Consult the list of known "good" drives */ - if (!config_chipset_for_dma(drive)) - goto no_dma_set; - } else { - goto fast_ata_pio; + + if (ide_use_dma(drive)) { + if (config_chipset_for_dma(drive)) + return hwif->ide_dma_on(drive); } - return hwif->ide_dma_on(drive); + + goto fast_ata_pio; + } else if ((id->capability & 8) || (id->field_valid & 2)) { fast_ata_pio: -no_dma_set: aec62xx_tune_drive(drive, 5); return hwif->ide_dma_off_quietly(drive); } @@ -377,39 +242,13 @@ static int aec62xx_irq_timeout (ide_drive_t *drive) case PCI_DEVICE_ID_ARTOP_ATP865: case PCI_DEVICE_ID_ARTOP_ATP865R: printk(" AEC62XX time out "); -#if 0 - { - int i = 0; - u8 reg49h = 0; - pci_read_config_byte(HWIF(drive)->pci_dev, 0x49, ®49h); - for (i=0;i<256;i++) - pci_write_config_byte(HWIF(drive)->pci_dev, 0x49, reg49h|0x10); - pci_write_config_byte(HWIF(drive)->pci_dev, 0x49, reg49h & ~0x10); - } - return 0; -#endif default: break; } -#if 0 - { - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - u8 tmp1 = 0, tmp2 = 0, mode6 = 0; - - pci_read_config_byte(dev, 0x44, &tmp1); - pci_read_config_byte(dev, 0x45, &tmp2); - printk(" AEC6280 r44=%x r45=%x ",tmp1,tmp2); - mode6 = HWIF(drive)->INB(((hwif->channel) ? - hwif->mate->dma_status : - hwif->dma_status)); - printk(" AEC6280 133=%x ", (mode6 & 0x10)); - } -#endif return 0; } -static unsigned int __init init_chipset_aec62xx (struct pci_dev *dev, const char *name) +static unsigned int __devinit init_chipset_aec62xx(struct pci_dev *dev, const char *name) { int bus_speed = system_bus_clock(); @@ -418,24 +257,30 @@ static unsigned int __init init_chipset_aec62xx (struct pci_dev *dev, const char printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", name, dev->resource[PCI_ROM_RESOURCE].start); } -#if defined(DISPLAY_AEC62XX_TIMINGS) && defined(CONFIG_PROC_FS) - aec_devs[n_aec_devs++] = dev; - - if (!aec62xx_proc) { - aec62xx_proc = 1; - ide_pci_create_host_proc("aec62xx", aec62xx_get_info); - } -#endif /* DISPLAY_AEC62XX_TIMINGS && CONFIG_PROC_FS */ - if (bus_speed <= 33) pci_set_drvdata(dev, (void *) aec6xxx_33_base); else pci_set_drvdata(dev, (void *) aec6xxx_34_base); + /* These are necessary to get AEC6280 Macintosh cards to work */ + if ((dev->device == PCI_DEVICE_ID_ARTOP_ATP865) || + (dev->device == PCI_DEVICE_ID_ARTOP_ATP865R)) { + u8 reg49h = 0, reg4ah = 0; + /* Clear reset and test bits. */ + pci_read_config_byte(dev, 0x49, ®49h); + pci_write_config_byte(dev, 0x49, reg49h & ~0x30); + /* Enable chip interrupt output. */ + pci_read_config_byte(dev, 0x4a, ®4ah); + pci_write_config_byte(dev, 0x4a, reg4ah & ~0x01); + /* Enable burst mode. */ + pci_read_config_byte(dev, 0x4a, ®4ah); + pci_write_config_byte(dev, 0x4a, reg4ah | 0x80); + } + return dev->irq; } -static void __init init_hwif_aec62xx (ide_hwif_t *hwif) +static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif) { hwif->autodma = 0; hwif->tuneproc = &aec62xx_tune_drive; @@ -468,7 +313,7 @@ static void __init init_hwif_aec62xx (ide_hwif_t *hwif) hwif->drives[1].autodma = hwif->autodma; } -static void __init init_dma_aec62xx (ide_hwif_t *hwif, unsigned long dmabase) +static void __devinit init_dma_aec62xx(ide_hwif_t *hwif, unsigned long dmabase) { struct pci_dev *dev = hwif->pci_dev; @@ -490,12 +335,12 @@ static void __init init_dma_aec62xx (ide_hwif_t *hwif, unsigned long dmabase) ide_setup_dma(hwif, dmabase, 8); } -static void __init init_setup_aec62xx (struct pci_dev *dev, ide_pci_device_t *d) +static int __devinit init_setup_aec62xx(struct pci_dev *dev, ide_pci_device_t *d) { - ide_setup_pci_device(dev, d); + return ide_setup_pci_device(dev, d); } -static void __init init_setup_aec6x80 (struct pci_dev *dev, ide_pci_device_t *d) +static int __devinit init_setup_aec6x80(struct pci_dev *dev, ide_pci_device_t *d) { unsigned long bar4reg = pci_resource_start(dev, 4); @@ -509,9 +354,61 @@ static void __init init_setup_aec6x80 (struct pci_dev *dev, ide_pci_device_t *d) strcpy(d->name, "AEC6280R"); } - ide_setup_pci_device(dev, d); + return ide_setup_pci_device(dev, d); } +static ide_pci_device_t aec62xx_chipsets[] __devinitdata = { + { /* 0 */ + .name = "AEC6210", + .init_setup = init_setup_aec62xx, + .init_chipset = init_chipset_aec62xx, + .init_hwif = init_hwif_aec62xx, + .init_dma = init_dma_aec62xx, + .channels = 2, + .autodma = AUTODMA, + .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, + .bootable = OFF_BOARD, + },{ /* 1 */ + .name = "AEC6260", + .init_setup = init_setup_aec62xx, + .init_chipset = init_chipset_aec62xx, + .init_hwif = init_hwif_aec62xx, + .init_dma = init_dma_aec62xx, + .channels = 2, + .autodma = NOAUTODMA, + .bootable = OFF_BOARD, + },{ /* 2 */ + .name = "AEC6260R", + .init_setup = init_setup_aec62xx, + .init_chipset = init_chipset_aec62xx, + .init_hwif = init_hwif_aec62xx, + .init_dma = init_dma_aec62xx, + .channels = 2, + .autodma = AUTODMA, + .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, + .bootable = NEVER_BOARD, + },{ /* 3 */ + .name = "AEC6X80", + .init_setup = init_setup_aec6x80, + .init_chipset = init_chipset_aec62xx, + .init_hwif = init_hwif_aec62xx, + .init_dma = init_dma_aec62xx, + .channels = 2, + .autodma = AUTODMA, + .bootable = OFF_BOARD, + },{ /* 4 */ + .name = "AEC6X80R", + .init_setup = init_setup_aec6x80, + .init_chipset = init_chipset_aec62xx, + .init_hwif = init_hwif_aec62xx, + .init_dma = init_dma_aec62xx, + .channels = 2, + .autodma = AUTODMA, + .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, + .bootable = OFF_BOARD, + } +}; + /** * aec62xx_init_one - called when a AEC is found * @dev: the aec62xx device @@ -525,10 +422,7 @@ static int __devinit aec62xx_init_one(struct pci_dev *dev, const struct pci_devi { ide_pci_device_t *d = &aec62xx_chipsets[id->driver_data]; - if (dev->device != d->device) - BUG(); - d->init_setup(dev, d); - return 0; + return d->init_setup(dev, d); } static struct pci_device_id aec62xx_pci_tbl[] = { @@ -542,7 +436,7 @@ static struct pci_device_id aec62xx_pci_tbl[] = { MODULE_DEVICE_TABLE(pci, aec62xx_pci_tbl); static struct pci_driver driver = { - .name = "AEC62xx IDE", + .name = "AEC62xx_IDE", .id_table = aec62xx_pci_tbl, .probe = aec62xx_init_one, };