Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/ide-2.6

This commit is contained in:
David S. Miller
2010-03-02 23:57:59 -08:00
6 changed files with 82 additions and 64 deletions

View File

@@ -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);

View File

@@ -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)
@@ -272,6 +322,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.
*/
@@ -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,

View File

@@ -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 */
ide_host_remove(host);
if (info->ndev) {
ide_hwif_t *hwif = host->ports[0];
unsigned long data_addr, ctl_addr;
info->ndev = 0;
data_addr = hwif->io_ports.data_addr;
ctl_addr = hwif->io_ports.ctl_addr;
ide_host_remove(host);
info->ndev = 0;
release_region(ctl_addr, 1);
release_region(data_addr, 8);
}
pcmcia_disable_device(link);
} /* ide_release */

View File

@@ -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;
}
}

View File

@@ -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");