diff options
Diffstat (limited to 'drivers/ide/pci/alim15x3.c')
-rw-r--r-- | drivers/ide/pci/alim15x3.c | 332 |
1 files changed, 53 insertions, 279 deletions
diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c index b3b6f514ce2d..b36a22b8c213 100644 --- a/drivers/ide/pci/alim15x3.c +++ b/drivers/ide/pci/alim15x3.c @@ -38,8 +38,6 @@ #include <asm/io.h> -#define DISPLAY_ALI_TIMINGS - /* * ALi devices are not plug in. Otherwise these static values would * need to go. They ought to go away anyway @@ -49,236 +47,6 @@ static u8 m5229_revision; static u8 chip_is_1543c_e; static struct pci_dev *isa_dev; -#if defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_IDE_PROC_FS) -#include <linux/stat.h> -#include <linux/proc_fs.h> - -static u8 ali_proc = 0; - -static struct pci_dev *bmide_dev; - -static char *fifo[4] = { - "FIFO Off", - "FIFO On ", - "DMA mode", - "PIO mode" }; - -static char *udmaT[8] = { - "1.5T", - " 2T", - "2.5T", - " 3T", - "3.5T", - " 4T", - " 6T", - " 8T" -}; - -static char *channel_status[8] = { - "OK ", - "busy ", - "DRQ ", - "DRQ busy ", - "error ", - "error busy ", - "error DRQ ", - "error DRQ busy" -}; - -/** - * ali_get_info - generate proc file for ALi IDE - * @buffer: buffer to fill - * @addr: address of user start in buffer - * @offset: offset into 'file' - * @count: buffer count - * - * Walks the Ali devices and outputs summary data on the tuning and - * anything else that will help with debugging - */ - -static int ali_get_info (char *buffer, char **addr, off_t offset, int count) -{ - unsigned long bibma; - u8 reg53h, reg5xh, reg5yh, reg5xh1, reg5yh1, c0, c1, rev, tmp; - char *q, *p = buffer; - - /* fetch rev. */ - pci_read_config_byte(bmide_dev, 0x08, &rev); - if (rev >= 0xc1) /* M1543C or newer */ - udmaT[7] = " ???"; - else - fifo[3] = " ??? "; - - /* first fetch bibma: */ - - bibma = pci_resource_start(bmide_dev, 4); - - /* - * at that point bibma+0x2 et bibma+0xa are byte - * registers to investigate: - */ - c0 = inb(bibma + 0x02); - c1 = inb(bibma + 0x0a); - - p += sprintf(p, - "\n Ali M15x3 Chipset.\n"); - p += sprintf(p, - " ------------------\n"); - pci_read_config_byte(bmide_dev, 0x78, ®53h); - p += sprintf(p, "PCI Clock: %d.\n", reg53h); - - pci_read_config_byte(bmide_dev, 0x53, ®53h); - p += sprintf(p, - "CD_ROM FIFO:%s, CD_ROM DMA:%s\n", - (reg53h & 0x02) ? "Yes" : "No ", - (reg53h & 0x01) ? "Yes" : "No " ); - pci_read_config_byte(bmide_dev, 0x74, ®53h); - p += sprintf(p, - "FIFO Status: contains %d Words, runs%s%s\n\n", - (reg53h & 0x3f), - (reg53h & 0x40) ? " OVERWR" : "", - (reg53h & 0x80) ? " OVERRD." : "." ); - - p += sprintf(p, - "-------------------primary channel" - "-------------------secondary channel" - "---------\n\n"); - - pci_read_config_byte(bmide_dev, 0x09, ®53h); - p += sprintf(p, - "channel status: %s" - " %s\n", - (reg53h & 0x20) ? "On " : "Off", - (reg53h & 0x10) ? "On " : "Off" ); - - p += sprintf(p, - "both channels togth: %s" - " %s\n", - (c0&0x80) ? "No " : "Yes", - (c1&0x80) ? "No " : "Yes" ); - - pci_read_config_byte(bmide_dev, 0x76, ®53h); - p += sprintf(p, - "Channel state: %s %s\n", - channel_status[reg53h & 0x07], - channel_status[(reg53h & 0x70) >> 4] ); - - pci_read_config_byte(bmide_dev, 0x58, ®5xh); - pci_read_config_byte(bmide_dev, 0x5c, ®5yh); - p += sprintf(p, - "Add. Setup Timing: %dT" - " %dT\n", - (reg5xh & 0x07) ? (reg5xh & 0x07) : 8, - (reg5yh & 0x07) ? (reg5yh & 0x07) : 8 ); - - pci_read_config_byte(bmide_dev, 0x59, ®5xh); - pci_read_config_byte(bmide_dev, 0x5d, ®5yh); - p += sprintf(p, - "Command Act. Count: %dT" - " %dT\n" - "Command Rec. Count: %dT" - " %dT\n\n", - (reg5xh & 0x70) ? ((reg5xh & 0x70) >> 4) : 8, - (reg5yh & 0x70) ? ((reg5yh & 0x70) >> 4) : 8, - (reg5xh & 0x0f) ? (reg5xh & 0x0f) : 16, - (reg5yh & 0x0f) ? (reg5yh & 0x0f) : 16 ); - - p += sprintf(p, - "----------------drive0-----------drive1" - "------------drive0-----------drive1------\n\n"); - p += sprintf(p, - "DMA enabled: %s %s" - " %s %s\n", - (c0&0x20) ? "Yes" : "No ", - (c0&0x40) ? "Yes" : "No ", - (c1&0x20) ? "Yes" : "No ", - (c1&0x40) ? "Yes" : "No " ); - - pci_read_config_byte(bmide_dev, 0x54, ®5xh); - pci_read_config_byte(bmide_dev, 0x55, ®5yh); - q = "FIFO threshold: %2d Words %2d Words" - " %2d Words %2d Words\n"; - if (rev < 0xc1) { - if ((rev == 0x20) && - (pci_read_config_byte(bmide_dev, 0x4f, &tmp), (tmp &= 0x20))) { - p += sprintf(p, q, 8, 8, 8, 8); - } else { - p += sprintf(p, q, - (reg5xh & 0x03) + 12, - ((reg5xh & 0x30)>>4) + 12, - (reg5yh & 0x03) + 12, - ((reg5yh & 0x30)>>4) + 12 ); - } - } else { - int t1 = (tmp = (reg5xh & 0x03)) ? (tmp << 3) : 4; - int t2 = (tmp = ((reg5xh & 0x30)>>4)) ? (tmp << 3) : 4; - int t3 = (tmp = (reg5yh & 0x03)) ? (tmp << 3) : 4; - int t4 = (tmp = ((reg5yh & 0x30)>>4)) ? (tmp << 3) : 4; - p += sprintf(p, q, t1, t2, t3, t4); - } - -#if 0 - p += sprintf(p, - "FIFO threshold: %2d Words %2d Words" - " %2d Words %2d Words\n", - (reg5xh & 0x03) + 12, - ((reg5xh & 0x30)>>4) + 12, - (reg5yh & 0x03) + 12, - ((reg5yh & 0x30)>>4) + 12 ); -#endif - - p += sprintf(p, - "FIFO mode: %s %s %s %s\n", - fifo[((reg5xh & 0x0c) >> 2)], - fifo[((reg5xh & 0xc0) >> 6)], - fifo[((reg5yh & 0x0c) >> 2)], - fifo[((reg5yh & 0xc0) >> 6)] ); - - pci_read_config_byte(bmide_dev, 0x5a, ®5xh); - pci_read_config_byte(bmide_dev, 0x5b, ®5xh1); - pci_read_config_byte(bmide_dev, 0x5e, ®5yh); - pci_read_config_byte(bmide_dev, 0x5f, ®5yh1); - - p += sprintf(p,/* - "------------------drive0-----------drive1" - "------------drive0-----------drive1------\n")*/ - "Dt RW act. Cnt %2dT %2dT" - " %2dT %2dT\n" - "Dt RW rec. Cnt %2dT %2dT" - " %2dT %2dT\n\n", - (reg5xh & 0x70) ? ((reg5xh & 0x70) >> 4) : 8, - (reg5xh1 & 0x70) ? ((reg5xh1 & 0x70) >> 4) : 8, - (reg5yh & 0x70) ? ((reg5yh & 0x70) >> 4) : 8, - (reg5yh1 & 0x70) ? ((reg5yh1 & 0x70) >> 4) : 8, - (reg5xh & 0x0f) ? (reg5xh & 0x0f) : 16, - (reg5xh1 & 0x0f) ? (reg5xh1 & 0x0f) : 16, - (reg5yh & 0x0f) ? (reg5yh & 0x0f) : 16, - (reg5yh1 & 0x0f) ? (reg5yh1 & 0x0f) : 16 ); - - p += sprintf(p, - "-----------------------------------UDMA Timings" - "--------------------------------\n\n"); - - pci_read_config_byte(bmide_dev, 0x56, ®5xh); - pci_read_config_byte(bmide_dev, 0x57, ®5yh); - p += sprintf(p, - "UDMA: %s %s" - " %s %s\n" - "UDMA timings: %s %s" - " %s %s\n\n", - (reg5xh & 0x08) ? "OK" : "No", - (reg5xh & 0x80) ? "OK" : "No", - (reg5yh & 0x08) ? "OK" : "No", - (reg5yh & 0x80) ? "OK" : "No", - udmaT[(reg5xh & 0x07)], - udmaT[(reg5xh & 0x70) >> 4], - udmaT[reg5yh & 0x07], - udmaT[(reg5yh & 0x70) >> 4] ); - - return p-buffer; /* => must be less than 4k! */ -} -#endif /* defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_IDE_PROC_FS) */ - /** * ali_set_pio_mode - set host controller for PIO mode * @drive: drive @@ -294,7 +62,7 @@ static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio) int s_time, a_time, c_time; u8 s_clc, a_clc, r_clc; unsigned long flags; - int bus_speed = system_bus_clock(); + int bus_speed = ide_pci_clk ? ide_pci_clk : system_bus_clock(); int port = hwif->channel ? 0x5c : 0x58; int portFIFO = hwif->channel ? 0x55 : 0x54; u8 cd_dma_fifo = 0; @@ -465,14 +233,6 @@ static unsigned int __devinit init_chipset_ali15x3 (struct pci_dev *dev, const c isa_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL); -#if defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_IDE_PROC_FS) - if (!ali_proc) { - ali_proc = 1; - bmide_dev = dev; - ide_pci_create_host_proc("ali", ali_get_info); - } -#endif /* defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_IDE_PROC_FS) */ - local_irq_save(flags); if (m5229_revision < 0xC2) { @@ -610,7 +370,7 @@ static int ali_cable_override(struct pci_dev *pdev) } /** - * ata66_ali15x3 - check for UDMA 66 support + * ali_cable_detect - cable detection * @hwif: IDE interface * * This checks if the controller and the cable are capable @@ -620,7 +380,7 @@ static int ali_cable_override(struct pci_dev *pdev) * FIXME: frobs bits that are not defined on newer ALi devicea */ -static u8 __devinit ata66_ali15x3(ide_hwif_t *hwif) +static u8 __devinit ali_cable_detect(ide_hwif_t *hwif) { struct pci_dev *dev = to_pci_dev(hwif->dev); unsigned long flags; @@ -652,27 +412,7 @@ static u8 __devinit ata66_ali15x3(ide_hwif_t *hwif) return cbl; } -/** - * init_hwif_common_ali15x3 - Set up ALI IDE hardware - * @hwif: IDE interface - * - * Initialize the IDE structure side of the ALi 15x3 driver. - */ - -static void __devinit init_hwif_common_ali15x3 (ide_hwif_t *hwif) -{ - hwif->set_pio_mode = &ali_set_pio_mode; - hwif->set_dma_mode = &ali_set_dma_mode; - hwif->udma_filter = &ali_udma_filter; - - hwif->cable_detect = ata66_ali15x3; - - if (hwif->dma_base == 0) - return; - - hwif->dma_setup = &ali15x3_dma_setup; -} - +#ifndef CONFIG_SPARC64 /** * init_hwif_ali15x3 - Initialize the ALI IDE x86 stuff * @hwif: interface to configure @@ -722,35 +462,66 @@ static void __devinit init_hwif_ali15x3 (ide_hwif_t *hwif) if(irq >= 0) hwif->irq = irq; } - - init_hwif_common_ali15x3(hwif); } +#endif /** * init_dma_ali15x3 - set up DMA on ALi15x3 * @hwif: IDE interface - * @dmabase: DMA interface base PCI address + * @d: IDE port info * - * Set up the DMA functionality on the ALi 15x3. For the ALi - * controllers this is generic so we can let the generic code do - * the actual work. + * Set up the DMA functionality on the ALi 15x3. */ -static void __devinit init_dma_ali15x3 (ide_hwif_t *hwif, unsigned long dmabase) +static int __devinit init_dma_ali15x3(ide_hwif_t *hwif, + const struct ide_port_info *d) { - if (m5229_revision < 0x20) - return; + struct pci_dev *dev = to_pci_dev(hwif->dev); + unsigned long base = ide_pci_dma_base(hwif, d); + + if (base == 0 || ide_pci_set_master(dev, d->name) < 0) + return -1; + if (!hwif->channel) - outb(inb(dmabase + 2) & 0x60, dmabase + 2); - ide_setup_dma(hwif, dmabase); + outb(inb(base + 2) & 0x60, base + 2); + + printk(KERN_INFO " %s: BM-DMA at 0x%04lx-0x%04lx\n", + hwif->name, base, base + 7); + + if (ide_allocate_dma_engine(hwif)) + return -1; + + ide_setup_dma(hwif, base); + + return 0; } +static const struct ide_port_ops ali_port_ops = { + .set_pio_mode = ali_set_pio_mode, + .set_dma_mode = ali_set_dma_mode, + .udma_filter = ali_udma_filter, + .cable_detect = ali_cable_detect, +}; + +static const struct ide_dma_ops ali_dma_ops = { + .dma_host_set = ide_dma_host_set, + .dma_setup = ali15x3_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, + .dma_start = ide_dma_start, + .dma_end = __ide_dma_end, + .dma_test_irq = ide_dma_test_irq, + .dma_lost_irq = ide_dma_lost_irq, + .dma_timeout = ide_dma_timeout, +}; + static const struct ide_port_info ali15x3_chipset __devinitdata = { .name = "ALI15X3", .init_chipset = init_chipset_ali15x3, +#ifndef CONFIG_SPARC64 .init_hwif = init_hwif_ali15x3, +#endif .init_dma = init_dma_ali15x3, - .host_flags = IDE_HFLAG_BOOTABLE, + .port_ops = &ali_port_ops, .pio_mask = ATA_PIO5, .swdma_mask = ATA_SWDMA2, .mwdma_mask = ATA_MWDMA2, @@ -793,14 +564,17 @@ static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_dev d.udma_mask = ATA_UDMA5; else d.udma_mask = ATA_UDMA6; + + d.dma_ops = &ali_dma_ops; + } else { + d.host_flags |= IDE_HFLAG_NO_DMA; + + d.mwdma_mask = d.swdma_mask = 0; } if (idx == 0) d.host_flags |= IDE_HFLAG_CLEAR_SIMPLEX; -#if defined(CONFIG_SPARC64) - d.init_hwif = init_hwif_common_ali15x3; -#endif /* CONFIG_SPARC64 */ return ide_setup_pci_device(dev, &d); } |