sgiioc4_clearirq(ide_drive_t * drive)
{
u32 intr_reg;
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
unsigned long other_ir = io_ports->irq_addr + (IOC4_INTR_REG << 2);
static void sgiioc4_dma_start(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
unsigned long ioc4_dma_addr = hwif->dma_base + IOC4_DMA_CTRL * 4;
unsigned int reg = readl((void __iomem *)ioc4_dma_addr);
unsigned int temp_reg = reg | IOC4_S_DMA_START;
static int sgiioc4_dma_end(ide_drive_t *drive)
{
u32 ioc4_dma, bc_dev, bc_mem, num, valid = 0, cnt = 0;
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
unsigned long dma_base = hwif->dma_base;
int dma_stat = 0;
unsigned long *ending_dma = ide_get_hwifdata(hwif);
}
}
- drive->waiting_for_dma = 0;
- ide_destroy_dmatable(drive);
-
return dma_stat;
}
/* returns 1 if dma irq issued, 0 otherwise */
static int sgiioc4_dma_test_irq(ide_drive_t *drive)
{
- return sgiioc4_checkirq(HWIF(drive));
+ return sgiioc4_checkirq(drive->hwif);
}
static void sgiioc4_dma_host_set(ide_drive_t *drive, int on)
sgiioc4_clearirq(drive);
}
-static void
-sgiioc4_resetproc(ide_drive_t * drive)
+static void sgiioc4_resetproc(ide_drive_t *drive)
{
+ struct ide_cmd *cmd = &drive->hwif->cmd;
+
sgiioc4_dma_end(drive);
+ ide_dma_unmap_sg(drive, cmd);
sgiioc4_clearirq(drive);
}
sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive)
{
u32 ioc4_dma;
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
unsigned long dma_base = hwif->dma_base;
unsigned long ioc4_dma_addr = dma_base + IOC4_DMA_CTRL * 4;
u32 dma_addr, ending_dma_addr;
writel(ending_dma_addr, (void __iomem *)(dma_base + IOC4_DMA_END_ADDR * 4));
writel(dma_direction, (void __iomem *)ioc4_dma_addr);
- drive->waiting_for_dma = 1;
}
/* IOC4 Scatter Gather list Format */
/* | Upper 32 bits - Zero |EOL| 15 unused | 16 Bit Length| */
/* --------------------------------------------------------------------- */
/* Creates the scatter gather list, DMA Table */
-static unsigned int
-sgiioc4_build_dma_table(ide_drive_t * drive, struct request *rq, int ddir)
+static int sgiioc4_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
unsigned int *table = hwif->dmatable_cpu;
- unsigned int count = 0, i = 1;
- struct scatterlist *sg;
-
- hwif->sg_nents = i = ide_build_sglist(drive, rq);
-
- if (!i)
- return 0; /* sglist of length Zero */
+ unsigned int count = 0, i = cmd->sg_nents;
+ struct scatterlist *sg = hwif->sg_table;
- sg = hwif->sg_table;
while (i && sg_dma_len(sg)) {
dma_addr_t cur_addr;
int cur_len;
printk(KERN_WARNING
"%s: DMA table too small\n",
drive->name);
- goto use_pio_instead;
+ return 0;
} else {
u32 bcount =
0x10000 - (cur_addr & 0xffff);
return count;
}
-use_pio_instead:
- ide_destroy_dmatable(drive);
-
return 0; /* revert to PIO for this request */
}
-static int sgiioc4_dma_setup(ide_drive_t *drive)
+static int sgiioc4_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
{
- struct request *rq = drive->hwif->rq;
- unsigned int count = 0;
int ddir;
+ u8 write = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
- if (rq_data_dir(rq))
- ddir = PCI_DMA_TODEVICE;
- else
- ddir = PCI_DMA_FROMDEVICE;
-
- if (!(count = sgiioc4_build_dma_table(drive, rq, ddir))) {
+ if (sgiioc4_build_dmatable(drive, cmd) == 0)
/* try PIO instead of DMA */
- ide_map_sg(drive, rq);
return 1;
- }
- if (rq_data_dir(rq))
+ if (write)
/* Writes TO the IOC4 FROM Main Memory */
ddir = IOC4_DMA_READ;
else
.exec_command = ide_exec_command,
.read_status = sgiioc4_read_status,
.read_altstatus = ide_read_altstatus,
- .read_sff_dma_status = ide_read_sff_dma_status,
-
- .set_irq = ide_set_irq,
+ .write_devctl = ide_write_devctl,
+ .dev_select = ide_dev_select,
.tf_load = ide_tf_load,
.tf_read = ide_tf_read,
.dma_end = sgiioc4_dma_end,
.dma_test_irq = sgiioc4_dma_test_irq,
.dma_lost_irq = sgiioc4_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
};
static const struct ide_port_info sgiioc4_port_info __devinitconst = {
.port_ops = &sgiioc4_port_ops,
.dma_ops = &sgiioc4_dma_ops,
.host_flags = IDE_HFLAG_MMIO,
+ .irq_flags = IRQF_SHARED,
.mwdma_mask = ATA_MWDMA2_ONLY,
};