X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fata%2Fpata_scc.c;h=55055b27524cfa9efd2771a96d1d44fe7dcc624b;hb=55dba3120fbcbea6800f9a18503d25f73212a347;hp=36cdbd2b0bd50c963df8253925f856328be0579e;hpb=efa7e8673c78cc6de2d6c367eb6f50449c57ed90;p=pandora-kernel.git diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c index 36cdbd2b0bd5..55055b27524c 100644 --- a/drivers/ata/pata_scc.c +++ b/drivers/ata/pata_scc.c @@ -43,7 +43,7 @@ #include #define DRV_NAME "pata_scc" -#define DRV_VERSION "0.2" +#define DRV_VERSION "0.3" #define PCI_DEVICE_ID_TOSHIBA_SCC_ATA 0x01b4 @@ -570,17 +570,8 @@ static unsigned int scc_bus_softreset(struct ata_port *ap, unsigned int devmask, udelay(20); out_be32(ioaddr->ctl_addr, ap->ctl); - /* spec mandates ">= 2ms" before checking status. - * We wait 150ms, because that was the magic delay used for - * ATAPI devices in Hale Landis's ATADRVR, for the period of time - * between when the ATA command register is written, and then - * status is checked. Because waiting for "a while" before - * checking status is fine, post SRST, we perform this magic - * delay here as well. - * - * Old drivers/ide uses the 2mS rule and then waits for ready - */ - msleep(150); + /* wait a while before checking status */ + ata_wait_after_reset(ap, deadline); /* Before we perform post reset processing we want to see if * the bus shows 0xFF because the odd clown forgets the D7 @@ -603,16 +594,17 @@ static unsigned int scc_bus_softreset(struct ata_port *ap, unsigned int devmask, * Note: Original code is ata_std_softreset(). */ -static int scc_std_softreset (struct ata_port *ap, unsigned int *classes, - unsigned long deadline) +static int scc_std_softreset(struct ata_link *link, unsigned int *classes, + unsigned long deadline) { + struct ata_port *ap = link->ap; unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS; unsigned int devmask = 0, err_mask; u8 err; DPRINTK("ENTER\n"); - if (ata_port_offline(ap)) { + if (ata_link_offline(link)) { classes[0] = ATA_DEV_NONE; goto out; } @@ -636,9 +628,11 @@ static int scc_std_softreset (struct ata_port *ap, unsigned int *classes, } /* determine by signature whether we have ATA or ATAPI devices */ - classes[0] = ata_dev_try_classify(ap, 0, &err); + classes[0] = ata_dev_try_classify(&ap->link.device[0], + devmask & (1 << 0), &err); if (slave_possible && err != 0x81) - classes[1] = ata_dev_try_classify(ap, 1, &err); + classes[1] = ata_dev_try_classify(&ap->link.device[1], + devmask & (1 << 1), &err); out: DPRINTK("EXIT, classes[0]=%u [1]=%u\n", classes[0], classes[1]); @@ -701,7 +695,7 @@ static void scc_bmdma_stop (struct ata_queued_cmd *qc) printk(KERN_WARNING "%s: Internal Bus Error\n", DRV_NAME); out_be32(bmid_base + SCC_DMA_INTST, INTSTS_BMSINT); /* TBD: SW reset */ - scc_std_softreset(ap, &classes, deadline); + scc_std_softreset(&ap->link, &classes, deadline); continue; } @@ -740,7 +734,7 @@ static u8 scc_bmdma_status (struct ata_port *ap) void __iomem *mmio = ap->ioaddr.bmdma_addr; u8 host_stat = in_be32(mmio + SCC_DMA_STATUS); u32 int_status = in_be32(mmio + SCC_DMA_INTST); - struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag); + struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->link.active_tag); static int retry = 0; /* return if IOS_SS is cleared */ @@ -774,45 +768,47 @@ static u8 scc_bmdma_status (struct ata_port *ap) /** * scc_data_xfer - Transfer data by PIO - * @adev: device for this I/O + * @dev: device for this I/O * @buf: data buffer * @buflen: buffer length - * @write_data: read/write + * @rw: read/write * * Note: Original code is ata_data_xfer(). */ -static void scc_data_xfer (struct ata_device *adev, unsigned char *buf, - unsigned int buflen, int write_data) +static unsigned int scc_data_xfer (struct ata_device *dev, unsigned char *buf, + unsigned int buflen, int rw) { - struct ata_port *ap = adev->ap; + struct ata_port *ap = dev->link->ap; unsigned int words = buflen >> 1; unsigned int i; u16 *buf16 = (u16 *) buf; void __iomem *mmio = ap->ioaddr.data_addr; /* Transfer multiple of 2 bytes */ - if (write_data) { - for (i = 0; i < words; i++) - out_be32(mmio, cpu_to_le16(buf16[i])); - } else { + if (rw == READ) for (i = 0; i < words; i++) buf16[i] = le16_to_cpu(in_be32(mmio)); - } + else + for (i = 0; i < words; i++) + out_be32(mmio, cpu_to_le16(buf16[i])); /* Transfer trailing 1 byte, if any. */ if (unlikely(buflen & 0x01)) { u16 align_buf[1] = { 0 }; unsigned char *trailing_buf = buf + buflen - 1; - if (write_data) { - memcpy(align_buf, trailing_buf, 1); - out_be32(mmio, cpu_to_le16(align_buf[0])); - } else { + if (rw == READ) { align_buf[0] = le16_to_cpu(in_be32(mmio)); memcpy(trailing_buf, align_buf, 1); + } else { + memcpy(align_buf, trailing_buf, 1); + out_be32(mmio, cpu_to_le16(align_buf[0])); } + words++; } + + return words << 1; } /** @@ -838,38 +834,6 @@ static u8 scc_irq_on (struct ata_port *ap) return tmp; } -/** - * scc_irq_ack - Acknowledge a device interrupt. - * @ap: Port on which interrupts are enabled. - * - * Note: Original code is ata_irq_ack(). - */ - -static u8 scc_irq_ack (struct ata_port *ap, unsigned int chk_drq) -{ - unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY; - u8 host_stat, post_stat, status; - - status = ata_busy_wait(ap, bits, 1000); - if (status & bits) - if (ata_msg_err(ap)) - printk(KERN_ERR "abnormal status 0x%X\n", status); - - /* get controller status; clear intr, err bits */ - host_stat = in_be32(ap->ioaddr.bmdma_addr + SCC_DMA_STATUS); - out_be32(ap->ioaddr.bmdma_addr + SCC_DMA_STATUS, - host_stat | ATA_DMA_INTR | ATA_DMA_ERR); - - post_stat = in_be32(ap->ioaddr.bmdma_addr + SCC_DMA_STATUS); - - if (ata_msg_intr(ap)) - printk(KERN_INFO "%s: irq ack: host_stat 0x%X, new host_stat 0x%X, drv_stat 0x%X\n", - __FUNCTION__, - host_stat, post_stat, status); - - return status; -} - /** * scc_bmdma_freeze - Freeze BMDMA controller port * @ap: port to freeze @@ -901,10 +865,10 @@ static void scc_bmdma_freeze (struct ata_port *ap) * @deadline: deadline jiffies for the operation */ -static int scc_pata_prereset(struct ata_port *ap, unsigned long deadline) +static int scc_pata_prereset(struct ata_link *link, unsigned long deadline) { - ap->cbl = ATA_CBL_PATA80; - return ata_std_prereset(ap, deadline); + link->ap->cbl = ATA_CBL_PATA80; + return ata_std_prereset(link, deadline); } /** @@ -915,8 +879,10 @@ static int scc_pata_prereset(struct ata_port *ap, unsigned long deadline) * Note: Original code is ata_std_postreset(). */ -static void scc_std_postreset (struct ata_port *ap, unsigned int *classes) +static void scc_std_postreset(struct ata_link *link, unsigned int *classes) { + struct ata_port *ap = link->ap; + DPRINTK("ENTER\n"); /* is double-select really necessary? */ @@ -1020,7 +986,6 @@ static struct scsi_host_template scc_sht = { }; static const struct ata_port_operations scc_pata_ops = { - .port_disable = ata_port_disable, .set_piomode = scc_set_piomode, .set_dmamode = scc_set_dmamode, .mode_filter = scc_mode_filter, @@ -1047,7 +1012,6 @@ static const struct ata_port_operations scc_pata_ops = { .irq_clear = scc_bmdma_irq_clear, .irq_on = scc_irq_on, - .irq_ack = scc_irq_ack, .port_start = scc_port_start, .port_stop = scc_port_stop, @@ -1193,6 +1157,9 @@ static int scc_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) return rc; host->iomap = pcim_iomap_table(pdev); + ata_port_pbar_desc(host->ports[0], SCC_CTRL_BAR, -1, "ctrl"); + ata_port_pbar_desc(host->ports[0], SCC_BMID_BAR, -1, "bmid"); + rc = scc_host_init(host); if (rc) return rc;