diff options
author | David S. Miller <davem@davemloft.net> | 2010-03-02 23:57:59 -0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-03-02 23:57:59 -0800 |
commit | 950f564b707ca1b1c5bb94cd1e7d2a0702bfcadc (patch) | |
tree | 290cc32af2f8cfd232c57d491733592aed4dbf88 /drivers | |
parent | b1681c56f5b6bf551bed2617a395855055836571 (diff) | |
parent | 8495fb1b8d016657133c01a2f258c5f192d2a1b7 (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/ide-2.6
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ide/cmd640.c | 2 | ||||
-rw-r--r-- | drivers/ide/icside.c | 64 | ||||
-rw-r--r-- | drivers/ide/ide-cs.c | 23 | ||||
-rw-r--r-- | drivers/ide/pdc202xx_old.c | 4 | ||||
-rw-r--r-- | drivers/ide/scc_pata.c | 12 |
5 files changed, 79 insertions, 26 deletions
diff --git a/drivers/ide/cmd640.c b/drivers/ide/cmd640.c index c7d46a3d347..d2b8b272bc2 100644 --- a/drivers/ide/cmd640.c +++ b/drivers/ide/cmd640.c @@ -606,7 +606,7 @@ static void cmd640_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive) } #endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */ -static void cmd640_init_dev(ide_drive_t *drive) +static void __init cmd640_init_dev(ide_drive_t *drive) { unsigned int i = drive->hwif->channel * 2 + (drive->dn & 1); diff --git a/drivers/ide/icside.c b/drivers/ide/icside.c index 26b6c0a1f77..4a697a238e2 100644 --- a/drivers/ide/icside.c +++ b/drivers/ide/icside.c @@ -65,6 +65,8 @@ static struct cardinfo icside_cardinfo_v6_2 = { }; struct icside_state { + unsigned int channel; + unsigned int enabled; void __iomem *irq_port; void __iomem *ioc_base; unsigned int sel; @@ -114,11 +116,18 @@ static void icside_irqenable_arcin_v6 (struct expansion_card *ec, int irqnr) struct icside_state *state = ec->irq_data; void __iomem *base = state->irq_port; - writeb(0, base + ICS_ARCIN_V6_INTROFFSET_1); - readb(base + ICS_ARCIN_V6_INTROFFSET_2); + state->enabled = 1; - writeb(0, base + ICS_ARCIN_V6_INTROFFSET_2); - readb(base + ICS_ARCIN_V6_INTROFFSET_1); + switch (state->channel) { + case 0: + writeb(0, base + ICS_ARCIN_V6_INTROFFSET_1); + readb(base + ICS_ARCIN_V6_INTROFFSET_2); + break; + case 1: + writeb(0, base + ICS_ARCIN_V6_INTROFFSET_2); + readb(base + ICS_ARCIN_V6_INTROFFSET_1); + break; + } } /* Prototype: icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr) @@ -128,6 +137,8 @@ static void icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr) { struct icside_state *state = ec->irq_data; + state->enabled = 0; + readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1); readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2); } @@ -149,6 +160,44 @@ static const expansioncard_ops_t icside_ops_arcin_v6 = { .irqpending = icside_irqpending_arcin_v6, }; +/* + * Handle routing of interrupts. This is called before + * we write the command to the drive. + */ +static void icside_maskproc(ide_drive_t *drive, int mask) +{ + ide_hwif_t *hwif = drive->hwif; + struct expansion_card *ec = ECARD_DEV(hwif->dev); + struct icside_state *state = ecard_get_drvdata(ec); + unsigned long flags; + + local_irq_save(flags); + + state->channel = hwif->channel; + + if (state->enabled && !mask) { + switch (hwif->channel) { + case 0: + writeb(0, state->irq_port + ICS_ARCIN_V6_INTROFFSET_1); + readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2); + break; + case 1: + writeb(0, state->irq_port + ICS_ARCIN_V6_INTROFFSET_2); + readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1); + break; + } + } else { + readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2); + readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1); + } + + local_irq_restore(flags); +} + +static const struct ide_port_ops icside_v6_no_dma_port_ops = { + .maskproc = icside_maskproc, +}; + #ifdef CONFIG_BLK_DEV_IDEDMA_ICS /* * SG-DMA support. @@ -229,6 +278,7 @@ static void icside_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive) static const struct ide_port_ops icside_v6_port_ops = { .set_dma_mode = icside_set_dma_mode, + .maskproc = icside_maskproc, }; static void icside_dma_host_set(ide_drive_t *drive, int on) @@ -273,6 +323,11 @@ static int icside_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) BUG_ON(dma_channel_active(ec->dma)); /* + * Ensure that we have the right interrupt routed. + */ + icside_maskproc(drive, 0); + + /* * Route the DMA signals to the correct interface. */ writeb(state->sel | hwif->channel, state->ioc_base); @@ -400,6 +455,7 @@ err_free: static const struct ide_port_info icside_v6_port_info __initdata = { .init_dma = icside_dma_off_init, + .port_ops = &icside_v6_no_dma_port_ops, .dma_ops = &icside_v6_dma_ops, .host_flags = IDE_HFLAG_SERIALIZE | IDE_HFLAG_MMIO, .mwdma_mask = ATA_MWDMA2, diff --git a/drivers/ide/ide-cs.c b/drivers/ide/ide-cs.c index dd6396384c2..ab87e4f7cec 100644 --- a/drivers/ide/ide-cs.c +++ b/drivers/ide/ide-cs.c @@ -121,19 +121,11 @@ static int ide_probe(struct pcmcia_device *link) static void ide_detach(struct pcmcia_device *link) { ide_info_t *info = link->priv; - ide_hwif_t *hwif = info->host->ports[0]; - unsigned long data_addr, ctl_addr; dev_dbg(&link->dev, "ide_detach(0x%p)\n", link); - data_addr = hwif->io_ports.data_addr; - ctl_addr = hwif->io_ports.ctl_addr; - ide_release(link); - release_region(ctl_addr, 1); - release_region(data_addr, 8); - kfree(info); } /* ide_detach */ @@ -354,12 +346,19 @@ static void ide_release(struct pcmcia_device *link) dev_dbg(&link->dev, "ide_release(0x%p)\n", link); - if (info->ndev) - /* FIXME: if this fails we need to queue the cleanup somehow - -- need to investigate the required PCMCIA magic */ + if (info->ndev) { + ide_hwif_t *hwif = host->ports[0]; + unsigned long data_addr, ctl_addr; + + data_addr = hwif->io_ports.data_addr; + ctl_addr = hwif->io_ports.ctl_addr; + ide_host_remove(host); + info->ndev = 0; - info->ndev = 0; + release_region(ctl_addr, 1); + release_region(data_addr, 8); + } pcmcia_disable_device(link); } /* ide_release */ diff --git a/drivers/ide/pdc202xx_old.c b/drivers/ide/pdc202xx_old.c index 07cd37516ba..c5f3841af36 100644 --- a/drivers/ide/pdc202xx_old.c +++ b/drivers/ide/pdc202xx_old.c @@ -93,13 +93,13 @@ static int pdc202xx_test_irq(ide_hwif_t *hwif) * bit 7: error, bit 6: interrupting, * bit 5: FIFO full, bit 4: FIFO empty */ - return ((sc1d & 0x50) == 0x40) ? 1 : 0; + return ((sc1d & 0x50) == 0x50) ? 1 : 0; } else { /* * bit 3: error, bit 2: interrupting, * bit 1: FIFO full, bit 0: FIFO empty */ - return ((sc1d & 0x05) == 0x04) ? 1 : 0; + return ((sc1d & 0x05) == 0x05) ? 1 : 0; } } diff --git a/drivers/ide/scc_pata.c b/drivers/ide/scc_pata.c index e9d4b441d1c..b7f5b0c4310 100644 --- a/drivers/ide/scc_pata.c +++ b/drivers/ide/scc_pata.c @@ -872,20 +872,18 @@ static struct pci_driver scc_pci_driver = { .remove = __devexit_p(scc_remove), }; -static int scc_ide_init(void) +static int __init scc_ide_init(void) { return ide_pci_register_driver(&scc_pci_driver); } -module_init(scc_ide_init); -/* -- No exit code? -static void scc_ide_exit(void) +static void __exit scc_ide_exit(void) { - ide_pci_unregister_driver(&scc_pci_driver); + pci_unregister_driver(&scc_pci_driver); } -module_exit(scc_ide_exit); - */ +module_init(scc_ide_init); +module_exit(scc_ide_exit); MODULE_DESCRIPTION("PCI driver module for Toshiba SCC IDE"); MODULE_LICENSE("GPL"); |