X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Fide%2Fscc_pata.c;h=1104bb301eb98eb4f2d22b78a05ba33d1d99761c;hb=9bd7496f5dd488e109e91d9d5743915fb4dfbfde;hp=90574ab76345f4e3b566193f8c5d68e7e84b2a38;hpb=898ec223fea2a2df88035e58dbf50f493577e225;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/ide/scc_pata.c b/drivers/ide/scc_pata.c index 90574ab..1104bb3 100644 --- a/drivers/ide/scc_pata.c +++ b/drivers/ide/scc_pata.c @@ -143,22 +143,13 @@ static u8 scc_read_altstatus(ide_hwif_t *hwif) return (u8)in_be32((void *)hwif->io_ports.ctl_addr); } -static u8 scc_read_sff_dma_status(ide_hwif_t *hwif) +static u8 scc_dma_sff_read_status(ide_hwif_t *hwif) { return (u8)in_be32((void *)(hwif->dma_base + 4)); } -static void scc_set_irq(ide_hwif_t *hwif, int on) +static void scc_write_devctl(ide_hwif_t *hwif, u8 ctl) { - u8 ctl = ATA_DEVCTL_OBS; - - if (on == 4) { /* hack for SRST */ - ctl |= 4; - on &= ~4; - } - - ctl |= on ? 0 : 2; - out_be32((void *)hwif->io_ports.ctl_addr, ctl); eieio(); in_be32((void *)(hwif->dma_base + 0x01c)); @@ -259,7 +250,7 @@ static void scc_set_dma_mode(ide_drive_t *drive, const u8 speed) unsigned long scrcst_port = ctl_base + 0x014; unsigned long udenvt_port = ctl_base + 0x018; unsigned long tdvhsel_port = ctl_base + 0x020; - int is_slave = (&hwif->drives[1] == drive); + int is_slave = drive->dn & 1; int offset, idx; unsigned long reg; unsigned long jcactsel; @@ -292,7 +283,7 @@ static void scc_dma_host_set(ide_drive_t *drive, int on) { ide_hwif_t *hwif = drive->hwif; u8 unit = drive->dn & 1; - u8 dma_stat = scc_ide_inb(hwif->dma_base + 4); + u8 dma_stat = scc_dma_sff_read_status(hwif); if (on) dma_stat |= (1 << (5 + unit)); @@ -303,8 +294,9 @@ static void scc_dma_host_set(ide_drive_t *drive, int on) } /** - * scc_ide_dma_setup - begin a DMA phase + * scc_dma_setup - begin a DMA phase * @drive: target device + * @cmd: command * * Build an IDE DMA PRD (IDE speak for scatter gather table) * and then set up the DMA transfer registers. @@ -313,36 +305,28 @@ static void scc_dma_host_set(ide_drive_t *drive, int on) * is returned. */ -static int scc_dma_setup(ide_drive_t *drive) +static int scc_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) { ide_hwif_t *hwif = drive->hwif; - struct request *rq = hwif->rq; - unsigned int reading; + u32 rw = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 0 : ATA_DMA_WR; u8 dma_stat; - if (rq_data_dir(rq)) - reading = 0; - else - reading = 1 << 3; - /* fall back to pio! */ - if (!ide_build_dmatable(drive, rq)) { - ide_map_sg(drive, rq); + if (ide_build_dmatable(drive, cmd) == 0) return 1; - } /* PRD table */ out_be32((void __iomem *)(hwif->dma_base + 8), hwif->dmatable_dma); /* specify r/w */ - out_be32((void __iomem *)hwif->dma_base, reading); + out_be32((void __iomem *)hwif->dma_base, rw); /* read DMA status for INTR & ERROR flags */ - dma_stat = in_be32((void __iomem *)(hwif->dma_base + 4)); + dma_stat = scc_dma_sff_read_status(hwif); /* clear INTR & ERROR flags */ out_be32((void __iomem *)(hwif->dma_base + 4), dma_stat | 6); - drive->waiting_for_dma = 1; + return 0; } @@ -353,7 +337,6 @@ static void scc_dma_start(ide_drive_t *drive) /* start DMA */ scc_ide_outb(dma_cmd | 1, hwif->dma_base); - wmb(); } static int __scc_dma_end(ide_drive_t *drive) @@ -361,19 +344,15 @@ static int __scc_dma_end(ide_drive_t *drive) ide_hwif_t *hwif = drive->hwif; u8 dma_stat, dma_cmd; - drive->waiting_for_dma = 0; /* get DMA command mode */ dma_cmd = scc_ide_inb(hwif->dma_base); /* stop DMA */ scc_ide_outb(dma_cmd & ~1, hwif->dma_base); /* get DMA status */ - dma_stat = scc_ide_inb(hwif->dma_base + 4); + dma_stat = scc_dma_sff_read_status(hwif); /* clear the INTR & ERROR bits */ scc_ide_outb(dma_stat | 6, hwif->dma_base + 4); - /* purge DMA mappings */ - ide_destroy_dmatable(drive); /* verify good DMA status */ - wmb(); return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0; } @@ -406,16 +385,17 @@ static int scc_dma_end(ide_drive_t *drive) data_loss = 1; if (retry++) { struct request *rq = hwif->rq; - int unit; + ide_drive_t *drive; + int i; + /* ERROR_RESET and drive->crc_count are needed * to reduce DMA transfer mode in retry process. */ if (rq) rq->errors |= ERROR_RESET; - for (unit = 0; unit < MAX_DRIVES; unit++) { - ide_drive_t *drive = &hwif->drives[unit]; + + ide_port_for_each_dev(i, drive, hwif) drive->crc_count++; - } } } } @@ -579,7 +559,7 @@ static int scc_ide_setup_pci_device(struct pci_dev *dev, { struct scc_ports *ports = pci_get_drvdata(dev); struct ide_host *host; - hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; + struct ide_hw hw, *hws[] = { &hw }; int i, rc; memset(&hw, 0, sizeof(hw)); @@ -587,9 +567,8 @@ static int scc_ide_setup_pci_device(struct pci_dev *dev, hw.io_ports_array[i] = ports->dma + 0x20 + i * 4; hw.irq = dev->irq; hw.dev = &dev->dev; - hw.chipset = ide_pci; - rc = ide_host_add(d, hws, &host); + rc = ide_host_add(d, hws, 1, &host); if (rc) return rc; @@ -665,91 +644,43 @@ static int __devinit init_setup_scc(struct pci_dev *dev, return rc; } -static void scc_tf_load(ide_drive_t *drive, ide_task_t *task) +static void scc_tf_load(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid) { struct ide_io_ports *io_ports = &drive->hwif->io_ports; - struct ide_taskfile *tf = &task->tf; - u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF; - - if (task->tf_flags & IDE_TFLAG_FLAGGED) - HIHI = 0xFF; - - if (task->tf_flags & IDE_TFLAG_OUT_DATA) - out_be32((void *)io_ports->data_addr, - (tf->hob_data << 8) | tf->data); - - if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE) - scc_ide_outb(tf->hob_feature, io_ports->feature_addr); - if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) - scc_ide_outb(tf->hob_nsect, io_ports->nsect_addr); - if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) - scc_ide_outb(tf->hob_lbal, io_ports->lbal_addr); - if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) - scc_ide_outb(tf->hob_lbam, io_ports->lbam_addr); - if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) - scc_ide_outb(tf->hob_lbah, io_ports->lbah_addr); - - if (task->tf_flags & IDE_TFLAG_OUT_FEATURE) + + if (valid & IDE_VALID_FEATURE) scc_ide_outb(tf->feature, io_ports->feature_addr); - if (task->tf_flags & IDE_TFLAG_OUT_NSECT) + if (valid & IDE_VALID_NSECT) scc_ide_outb(tf->nsect, io_ports->nsect_addr); - if (task->tf_flags & IDE_TFLAG_OUT_LBAL) + if (valid & IDE_VALID_LBAL) scc_ide_outb(tf->lbal, io_ports->lbal_addr); - if (task->tf_flags & IDE_TFLAG_OUT_LBAM) + if (valid & IDE_VALID_LBAM) scc_ide_outb(tf->lbam, io_ports->lbam_addr); - if (task->tf_flags & IDE_TFLAG_OUT_LBAH) + if (valid & IDE_VALID_LBAH) scc_ide_outb(tf->lbah, io_ports->lbah_addr); - - if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) - scc_ide_outb((tf->device & HIHI) | drive->select, - io_ports->device_addr); + if (valid & IDE_VALID_DEVICE) + scc_ide_outb(tf->device, io_ports->device_addr); } -static void scc_tf_read(ide_drive_t *drive, ide_task_t *task) +static void scc_tf_read(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid) { struct ide_io_ports *io_ports = &drive->hwif->io_ports; - struct ide_taskfile *tf = &task->tf; - - if (task->tf_flags & IDE_TFLAG_IN_DATA) { - u16 data = (u16)in_be32((void *)io_ports->data_addr); - - tf->data = data & 0xff; - tf->hob_data = (data >> 8) & 0xff; - } - /* be sure we're looking at the low order bits */ - scc_ide_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr); - - if (task->tf_flags & IDE_TFLAG_IN_FEATURE) - tf->feature = scc_ide_inb(io_ports->feature_addr); - if (task->tf_flags & IDE_TFLAG_IN_NSECT) + if (valid & IDE_VALID_ERROR) + tf->error = scc_ide_inb(io_ports->feature_addr); + if (valid & IDE_VALID_NSECT) tf->nsect = scc_ide_inb(io_ports->nsect_addr); - if (task->tf_flags & IDE_TFLAG_IN_LBAL) + if (valid & IDE_VALID_LBAL) tf->lbal = scc_ide_inb(io_ports->lbal_addr); - if (task->tf_flags & IDE_TFLAG_IN_LBAM) + if (valid & IDE_VALID_LBAM) tf->lbam = scc_ide_inb(io_ports->lbam_addr); - if (task->tf_flags & IDE_TFLAG_IN_LBAH) + if (valid & IDE_VALID_LBAH) tf->lbah = scc_ide_inb(io_ports->lbah_addr); - if (task->tf_flags & IDE_TFLAG_IN_DEVICE) + if (valid & IDE_VALID_DEVICE) tf->device = scc_ide_inb(io_ports->device_addr); - - if (task->tf_flags & IDE_TFLAG_LBA48) { - scc_ide_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr); - - if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) - tf->hob_feature = scc_ide_inb(io_ports->feature_addr); - if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT) - tf->hob_nsect = scc_ide_inb(io_ports->nsect_addr); - if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL) - tf->hob_lbal = scc_ide_inb(io_ports->lbal_addr); - if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM) - tf->hob_lbam = scc_ide_inb(io_ports->lbam_addr); - if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH) - tf->hob_lbah = scc_ide_inb(io_ports->lbah_addr); - } } -static void scc_input_data(ide_drive_t *drive, struct request *rq, +static void scc_input_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf, unsigned int len) { unsigned long data_addr = drive->hwif->io_ports.data_addr; @@ -765,7 +696,7 @@ static void scc_input_data(ide_drive_t *drive, struct request *rq, scc_ide_insw(data_addr, buf, len / 2); } -static void scc_output_data(ide_drive_t *drive, struct request *rq, +static void scc_output_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf, unsigned int len) { unsigned long data_addr = drive->hwif->io_ports.data_addr; @@ -852,10 +783,9 @@ static const struct ide_tp_ops scc_tp_ops = { .exec_command = scc_exec_command, .read_status = scc_read_status, .read_altstatus = scc_read_altstatus, - .read_sff_dma_status = scc_read_sff_dma_status, - - .set_irq = scc_set_irq, + .write_devctl = scc_write_devctl, + .dev_select = ide_dev_select, .tf_load = scc_tf_load, .tf_read = scc_tf_read, @@ -873,29 +803,26 @@ static const struct ide_port_ops scc_port_ops = { static const struct ide_dma_ops scc_dma_ops = { .dma_host_set = scc_dma_host_set, .dma_setup = scc_dma_setup, - .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = scc_dma_start, .dma_end = scc_dma_end, .dma_test_irq = scc_dma_test_irq, .dma_lost_irq = ide_dma_lost_irq, - .dma_timeout = ide_dma_timeout, + .dma_timer_expiry = ide_dma_sff_timer_expiry, + .dma_sff_read_status = scc_dma_sff_read_status, }; -#define DECLARE_SCC_DEV(name_str) \ - { \ - .name = name_str, \ - .init_iops = init_iops_scc, \ - .init_dma = scc_init_dma, \ - .init_hwif = init_hwif_scc, \ - .tp_ops = &scc_tp_ops, \ - .port_ops = &scc_port_ops, \ - .dma_ops = &scc_dma_ops, \ - .host_flags = IDE_HFLAG_SINGLE, \ - .pio_mask = ATA_PIO4, \ - } - -static const struct ide_port_info scc_chipsets[] __devinitdata = { - /* 0 */ DECLARE_SCC_DEV("sccIDE"), +static const struct ide_port_info scc_chipset __devinitdata = { + .name = "sccIDE", + .init_iops = init_iops_scc, + .init_dma = scc_init_dma, + .init_hwif = init_hwif_scc, + .tp_ops = &scc_tp_ops, + .port_ops = &scc_port_ops, + .dma_ops = &scc_dma_ops, + .host_flags = IDE_HFLAG_SINGLE, + .irq_flags = IRQF_SHARED, + .pio_mask = ATA_PIO4, + .chipset = ide_pci, }; /** @@ -909,7 +836,7 @@ static const struct ide_port_info scc_chipsets[] __devinitdata = { static int __devinit scc_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - return init_setup_scc(dev, &scc_chipsets[id->driver_data]); + return init_setup_scc(dev, &scc_chipset); } /**