X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fide%2Fpci%2Fcmd64x.c;h=08674711d0895c6fae3476cba5d02a2d1f351541;hb=eeb85d0b0e312ab9a6c3476f18308409913ab369;hp=cd4eb9def1515719d2d3c998a67438a8aefa9bbf;hpb=d0d42df2a440003d96c8bf29991c2afb691ef720;p=linux-2.6 diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c index cd4eb9def1..08674711d0 100644 --- a/drivers/ide/pci/cmd64x.c +++ b/drivers/ide/pci/cmd64x.c @@ -1,6 +1,4 @@ /* - * linux/drivers/ide/pci/cmd64x.c Version 1.53 Dec 24, 2007 - * * cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines. * Due to massive hardware bugs, UltraDMA is only supported * on the 646U2 and not on the 646U. @@ -15,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -71,8 +68,8 @@ static u8 quantize_timing(int timing, int quant) */ static void program_cycle_times (ide_drive_t *drive, int cycle_time, int active_time) { - struct pci_dev *dev = HWIF(drive)->pci_dev; - int clock_time = 1000 / system_bus_clock(); + struct pci_dev *dev = to_pci_dev(drive->hwif->dev); + int clock_time = 1000 / (ide_pci_clk ? ide_pci_clk : system_bus_clock()); u8 cycle_count, active_count, recovery_count, drwtim; static const u8 recovery_values[] = {15, 15, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0}; @@ -118,7 +115,7 @@ static void program_cycle_times (ide_drive_t *drive, int cycle_time, int active_ 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; + struct pci_dev *dev = to_pci_dev(hwif->dev); unsigned int cycle_time; u8 setup_count, arttim = 0; @@ -131,7 +128,7 @@ static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio) ide_pio_timings[pio].active_time); setup_count = quantize_timing(ide_pio_timings[pio].setup_time, - 1000 / system_bus_clock()); + 1000 / (ide_pci_clk ? ide_pci_clk : system_bus_clock())); /* * The primary channel has individual address setup timing registers @@ -183,7 +180,7 @@ static void cmd64x_set_pio_mode(ide_drive_t *drive, const u8 pio) static void cmd64x_set_dma_mode(ide_drive_t *drive, const u8 speed) { ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; + struct pci_dev *dev = to_pci_dev(hwif->dev); u8 unit = drive->dn & 0x01; u8 regU = 0, pciU = hwif->channel ? UDIDETCR1 : UDIDETCR0; @@ -226,7 +223,7 @@ static void cmd64x_set_dma_mode(ide_drive_t *drive, const u8 speed) (void) pci_write_config_byte(dev, pciU, regU); } -static int cmd648_ide_dma_end (ide_drive_t *drive) +static int cmd648_dma_end(ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); unsigned long base = hwif->dma_base - (hwif->channel * 8); @@ -242,10 +239,10 @@ static int cmd648_ide_dma_end (ide_drive_t *drive) return err; } -static int cmd64x_ide_dma_end (ide_drive_t *drive) +static int cmd64x_dma_end(ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; + struct pci_dev *dev = to_pci_dev(hwif->dev); int irq_reg = hwif->channel ? ARTTIM23 : CFR; u8 irq_mask = hwif->channel ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0; @@ -259,7 +256,7 @@ static int cmd64x_ide_dma_end (ide_drive_t *drive) return err; } -static int cmd648_ide_dma_test_irq (ide_drive_t *drive) +static int cmd648_dma_test_irq(ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); unsigned long base = hwif->dma_base - (hwif->channel * 8); @@ -282,10 +279,10 @@ static int cmd648_ide_dma_test_irq (ide_drive_t *drive) return 0; } -static int cmd64x_ide_dma_test_irq (ide_drive_t *drive) +static int cmd64x_dma_test_irq(ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; + struct pci_dev *dev = to_pci_dev(hwif->dev); int irq_reg = hwif->channel ? ARTTIM23 : CFR; u8 irq_mask = hwif->channel ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0; @@ -313,7 +310,7 @@ static int cmd64x_ide_dma_test_irq (ide_drive_t *drive) * event order for DMA transfers. */ -static int cmd646_1_ide_dma_end (ide_drive_t *drive) +static int cmd646_1_dma_end(ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); u8 dma_stat = 0, dma_cmd = 0; @@ -373,9 +370,9 @@ static unsigned int __devinit init_chipset_cmd64x(struct pci_dev *dev, const cha return 0; } -static u8 __devinit ata66_cmd64x(ide_hwif_t *hwif) +static u8 __devinit cmd64x_cable_detect(ide_hwif_t *hwif) { - struct pci_dev *dev = hwif->pci_dev; + struct pci_dev *dev = to_pci_dev(hwif->dev); u8 bmidecsr = 0, mask = hwif->channel ? 0x02 : 0x01; switch (dev->device) { @@ -388,90 +385,85 @@ static u8 __devinit ata66_cmd64x(ide_hwif_t *hwif) } } -static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif) -{ - struct pci_dev *dev = hwif->pci_dev; - - hwif->set_pio_mode = &cmd64x_set_pio_mode; - hwif->set_dma_mode = &cmd64x_set_dma_mode; - - if (!hwif->dma_base) - return; +static const struct ide_port_ops cmd64x_port_ops = { + .set_pio_mode = cmd64x_set_pio_mode, + .set_dma_mode = cmd64x_set_dma_mode, + .cable_detect = cmd64x_cable_detect, +}; - /* - * UltraDMA only supported on PCI646U and PCI646U2, which - * correspond to revisions 0x03, 0x05 and 0x07 respectively. - * Actually, although the CMD tech support people won't - * tell me the details, the 0x03 revision cannot support - * UDMA correctly without hardware modifications, and even - * then it only works with Quantum disks due to some - * hold time assumptions in the 646U part which are fixed - * in the 646U2. - * - * So we only do UltraDMA on revision 0x05 and 0x07 chipsets. - */ - if (dev->device == PCI_DEVICE_ID_CMD_646 && dev->revision < 5) - hwif->ultra_mask = 0x00; +static const struct ide_dma_ops cmd64x_dma_ops = { + .dma_host_set = ide_dma_host_set, + .dma_setup = ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, + .dma_start = ide_dma_start, + .dma_end = cmd64x_dma_end, + .dma_test_irq = cmd64x_dma_test_irq, + .dma_lost_irq = ide_dma_lost_irq, + .dma_timeout = ide_dma_timeout, +}; - if (hwif->cbl != ATA_CBL_PATA40_SHORT) - hwif->cbl = ata66_cmd64x(hwif); +static const struct ide_dma_ops cmd646_rev1_dma_ops = { + .dma_host_set = ide_dma_host_set, + .dma_setup = ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, + .dma_start = ide_dma_start, + .dma_end = cmd646_1_dma_end, + .dma_test_irq = ide_dma_test_irq, + .dma_lost_irq = ide_dma_lost_irq, + .dma_timeout = ide_dma_timeout, +}; - switch (dev->device) { - case PCI_DEVICE_ID_CMD_648: - case PCI_DEVICE_ID_CMD_649: - alt_irq_bits: - hwif->ide_dma_end = &cmd648_ide_dma_end; - hwif->ide_dma_test_irq = &cmd648_ide_dma_test_irq; - break; - case PCI_DEVICE_ID_CMD_646: - if (dev->revision == 0x01) { - hwif->ide_dma_end = &cmd646_1_ide_dma_end; - break; - } else if (dev->revision >= 0x03) - goto alt_irq_bits; - /* fall thru */ - default: - hwif->ide_dma_end = &cmd64x_ide_dma_end; - hwif->ide_dma_test_irq = &cmd64x_ide_dma_test_irq; - break; - } -} +static const struct ide_dma_ops cmd648_dma_ops = { + .dma_host_set = ide_dma_host_set, + .dma_setup = ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, + .dma_start = ide_dma_start, + .dma_end = cmd648_dma_end, + .dma_test_irq = cmd648_dma_test_irq, + .dma_lost_irq = ide_dma_lost_irq, + .dma_timeout = ide_dma_timeout, +}; static const struct ide_port_info cmd64x_chipsets[] __devinitdata = { { /* 0 */ .name = "CMD643", .init_chipset = init_chipset_cmd64x, - .init_hwif = init_hwif_cmd64x, .enablebits = {{0x00,0x00,0x00}, {0x51,0x08,0x08}}, - .host_flags = IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_BOOTABLE, + .port_ops = &cmd64x_port_ops, + .dma_ops = &cmd64x_dma_ops, + .host_flags = IDE_HFLAG_CLEAR_SIMPLEX | + IDE_HFLAG_ABUSE_PREFETCH, .pio_mask = ATA_PIO5, .mwdma_mask = ATA_MWDMA2, .udma_mask = 0x00, /* no udma */ },{ /* 1 */ .name = "CMD646", .init_chipset = init_chipset_cmd64x, - .init_hwif = init_hwif_cmd64x, .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, .chipset = ide_cmd646, - .host_flags = IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_BOOTABLE, + .port_ops = &cmd64x_port_ops, + .dma_ops = &cmd648_dma_ops, + .host_flags = IDE_HFLAG_ABUSE_PREFETCH, .pio_mask = ATA_PIO5, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA2, },{ /* 2 */ .name = "CMD648", .init_chipset = init_chipset_cmd64x, - .init_hwif = init_hwif_cmd64x, .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, - .host_flags = IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_BOOTABLE, + .port_ops = &cmd64x_port_ops, + .dma_ops = &cmd648_dma_ops, + .host_flags = IDE_HFLAG_ABUSE_PREFETCH, .pio_mask = ATA_PIO5, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA4, },{ /* 3 */ .name = "CMD649", .init_chipset = init_chipset_cmd64x, - .init_hwif = init_hwif_cmd64x, .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, - .host_flags = IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_BOOTABLE, + .port_ops = &cmd64x_port_ops, + .dma_ops = &cmd648_dma_ops, + .host_flags = IDE_HFLAG_ABUSE_PREFETCH, .pio_mask = ATA_PIO5, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA5, @@ -485,12 +477,35 @@ static int __devinit cmd64x_init_one(struct pci_dev *dev, const struct pci_devic d = cmd64x_chipsets[idx]; - /* - * The original PCI0646 didn't have the primary channel enable bit, - * it appeared starting with PCI0646U (i.e. revision ID 3). - */ - if (idx == 1 && dev->revision < 3) - d.enablebits[0].reg = 0; + if (idx == 1) { + /* + * UltraDMA only supported on PCI646U and PCI646U2, which + * correspond to revisions 0x03, 0x05 and 0x07 respectively. + * Actually, although the CMD tech support people won't + * tell me the details, the 0x03 revision cannot support + * UDMA correctly without hardware modifications, and even + * then it only works with Quantum disks due to some + * hold time assumptions in the 646U part which are fixed + * in the 646U2. + * + * So we only do UltraDMA on revision 0x05 and 0x07 chipsets. + */ + if (dev->revision < 5) { + d.udma_mask = 0x00; + /* + * The original PCI0646 didn't have the primary + * channel enable bit, it appeared starting with + * PCI0646U (i.e. revision ID 3). + */ + if (dev->revision < 3) { + d.enablebits[0].reg = 0; + if (dev->revision == 1) + d.dma_ops = &cmd646_rev1_dma_ops; + else + d.dma_ops = &cmd64x_dma_ops; + } + } + } return ide_setup_pci_device(dev, &d); }