X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Fata%2Fsata_fsl.c;h=fddd346b1d5728c289d1a9a44ae5ab8c2de37412;hb=1cfd19aeb8c8b6291a9d11143b4d8f3dac508ed4;hp=c47f2d4bf86039498cba79f15f48c38446b03c26;hpb=25ce945a8e775d1f494447969e6a8fffcebcc352;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index c47f2d4..fddd346 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c @@ -35,7 +35,6 @@ enum { SATA_FSL_HOST_FLAGS = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | ATA_FLAG_NCQ), - SATA_FSL_HOST_LFLAGS = ATA_LFLAG_SKIP_D2H_BSY, SATA_FSL_MAX_CMDS = SATA_FSL_QUEUE_DEPTH, SATA_FSL_CMD_HDR_SIZE = 16, /* 4 DWORDS */ @@ -245,17 +244,6 @@ struct sata_fsl_port_priv { dma_addr_t cmdslot_paddr; struct command_desc *cmdentry; dma_addr_t cmdentry_paddr; - - /* - * SATA FSL controller has a Status FIS which should contain the - * received D2H FIS & taskfile registers. This SFIS is present in - * the command descriptor, and to have a ready reference to it, - * we are caching it here, quite similar to what is done in H/W on - * AHCI compliant devices by copying taskfile fields to a 32-bit - * register. - */ - - struct ata_taskfile tf; }; /* @@ -269,7 +257,7 @@ struct sata_fsl_host_priv { }; static inline unsigned int sata_fsl_tag(unsigned int tag, - void __iomem * hcr_base) + void __iomem *hcr_base) { /* We let libATA core do actual (queue) tag allocation */ @@ -308,7 +296,7 @@ static void sata_fsl_setup_cmd_hdr_entry(struct sata_fsl_port_priv *pp, pp->cmdslot[tag].prde_fis_len = cpu_to_le32((num_prde << 16) | (fis_len << 2)); pp->cmdslot[tag].ttl = cpu_to_le32(data_xfer_len & ~0x03); - pp->cmdslot[tag].desc_info = cpu_to_le32((desc_info | (tag & 0x1F))); + pp->cmdslot[tag].desc_info = cpu_to_le32(desc_info | (tag & 0x1F)); VPRINTK("cda=0x%x, prde_fis_len=0x%x, ttl=0x%x, di=0x%x\n", pp->cmdslot[tag].cda, @@ -318,7 +306,7 @@ static void sata_fsl_setup_cmd_hdr_entry(struct sata_fsl_port_priv *pp, } static unsigned int sata_fsl_fill_sg(struct ata_queued_cmd *qc, void *cmd_desc, - u32 * ttl, dma_addr_t cmd_desc_paddr) + u32 *ttl, dma_addr_t cmd_desc_paddr) { struct scatterlist *sg; unsigned int num_prde = 0; @@ -333,13 +321,14 @@ static unsigned int sata_fsl_fill_sg(struct ata_queued_cmd *qc, void *cmd_desc, struct prde *prd_ptr_to_indirect_ext = NULL; unsigned indirect_ext_segment_sz = 0; dma_addr_t indirect_ext_segment_paddr; + unsigned int si; - VPRINTK("SATA FSL : cd = 0x%x, prd = 0x%x\n", cmd_desc, prd); + VPRINTK("SATA FSL : cd = 0x%p, prd = 0x%p\n", cmd_desc, prd); indirect_ext_segment_paddr = cmd_desc_paddr + SATA_FSL_CMD_DESC_OFFSET_TO_PRDT + SATA_FSL_MAX_PRD_DIRECT * 16; - ata_for_each_sg(sg, qc) { + for_each_sg(qc->sg, sg, qc->n_elem, si) { dma_addr_t sg_addr = sg_dma_address(sg); u32 sg_len = sg_dma_len(sg); @@ -354,8 +343,8 @@ static unsigned int sata_fsl_fill_sg(struct ata_queued_cmd *qc, void *cmd_desc, ata_port_printk(qc->ap, KERN_ERR, "s/g len unaligned : 0x%x\n", sg_len); - if ((num_prde == (SATA_FSL_MAX_PRD_DIRECT - 1)) && - (qc->n_iter + 1 != qc->n_elem)) { + if (num_prde == (SATA_FSL_MAX_PRD_DIRECT - 1) && + sg_next(sg) != NULL) { VPRINTK("setting indirect prde\n"); prd_ptr_to_indirect_ext = prd; prd->dba = cpu_to_le32(indirect_ext_segment_paddr); @@ -406,7 +395,7 @@ static void sata_fsl_qc_prep(struct ata_queued_cmd *qc) cd = (struct command_desc *)pp->cmdentry + tag; cd_paddr = pp->cmdentry_paddr + tag * SATA_FSL_CMD_DESC_SIZE; - ata_tf_to_fis(&qc->tf, 0, 1, (u8 *) & cd->cfis); + ata_tf_to_fis(&qc->tf, 0, 1, (u8 *) &cd->cfis); VPRINTK("Dumping cfis : 0x%x, 0x%x, 0x%x\n", cd->cfis[0], cd->cfis[1], cd->cfis[2]); @@ -417,7 +406,7 @@ static void sata_fsl_qc_prep(struct ata_queued_cmd *qc) } /* setup "ACMD - atapi command" in cmd. desc. if this is ATAPI cmd */ - if (is_atapi_taskfile(&qc->tf)) { + if (ata_is_atapi(qc->tf.protocol)) { desc_info |= ATAPI_CMD; memset((void *)&cd->acmd, 0, 32); memcpy((void *)&cd->acmd, qc->cdb, qc->dev->cdb_len); @@ -458,11 +447,26 @@ static unsigned int sata_fsl_qc_issue(struct ata_queued_cmd *qc) VPRINTK("CE=0x%x, DE=0x%x, CC=0x%x, CmdStat = 0x%x\n", ioread32(CE + hcr_base), ioread32(DE + hcr_base), - ioread32(CC + hcr_base), ioread32(COMMANDSTAT + csr_base)); + ioread32(CC + hcr_base), + ioread32(COMMANDSTAT + host_priv->csr_base)); return 0; } +static bool sata_fsl_qc_fill_rtf(struct ata_queued_cmd *qc) +{ + struct sata_fsl_port_priv *pp = qc->ap->private_data; + struct sata_fsl_host_priv *host_priv = qc->ap->host->private_data; + void __iomem *hcr_base = host_priv->hcr_base; + unsigned int tag = sata_fsl_tag(qc->tag, hcr_base); + struct command_desc *cd; + + cd = pp->cmdentry + tag; + + ata_tf_from_fis(cd->sfis, &qc->result_tf); + return true; +} + static int sata_fsl_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val) { @@ -521,7 +525,8 @@ static void sata_fsl_freeze(struct ata_port *ap) ioread32(CQ + hcr_base), ioread32(CA + hcr_base), ioread32(CE + hcr_base), ioread32(DE + hcr_base)); - VPRINTK("CmdStat = 0x%x\n", ioread32(csr_base + COMMANDSTAT)); + VPRINTK("CmdStat = 0x%x\n", + ioread32(host_priv->csr_base + COMMANDSTAT)); /* disable interrupts on the controller/port */ temp = ioread32(hcr_base + HCONTROL); @@ -553,38 +558,6 @@ static void sata_fsl_thaw(struct ata_port *ap) ioread32(hcr_base + HCONTROL), ioread32(hcr_base + HSTATUS)); } -/* - * NOTE : 1st D2H FIS from device does not update sfis in command descriptor. - */ -static inline void sata_fsl_cache_taskfile_from_d2h_fis(struct ata_queued_cmd - *qc, - struct ata_port *ap) -{ - struct sata_fsl_port_priv *pp = ap->private_data; - struct sata_fsl_host_priv *host_priv = ap->host->private_data; - void __iomem *hcr_base = host_priv->hcr_base; - unsigned int tag = sata_fsl_tag(qc->tag, hcr_base); - struct command_desc *cd; - - cd = pp->cmdentry + tag; - - ata_tf_from_fis(cd->sfis, &pp->tf); -} - -static u8 sata_fsl_check_status(struct ata_port *ap) -{ - struct sata_fsl_port_priv *pp = ap->private_data; - - return pp->tf.command; -} - -static void sata_fsl_tf_read(struct ata_port *ap, struct ata_taskfile *tf) -{ - struct sata_fsl_port_priv *pp = ap->private_data; - - *tf = pp->tf; -} - static int sata_fsl_port_start(struct ata_port *ap) { struct device *dev = ap->host->dev; @@ -600,21 +573,9 @@ static int sata_fsl_port_start(struct ata_port *ap) if (!pp) return -ENOMEM; - /* - * allocate per command dma alignment pad buffer, which is used - * internally by libATA to ensure that all transfers ending on - * unaligned boundaries are padded, to align on Dword boundaries - */ - retval = ata_pad_alloc(ap, dev); - if (retval) { - kfree(pp); - return retval; - } - mem = dma_alloc_coherent(dev, SATA_FSL_PORT_PRIV_DMA_SZ, &mem_dma, GFP_KERNEL); if (!mem) { - ata_pad_free(ap, dev); kfree(pp); return -ENOMEM; } @@ -652,6 +613,7 @@ static int sata_fsl_port_start(struct ata_port *ap) VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL)); VPRINTK("CHBA = 0x%x\n", ioread32(hcr_base + CHBA)); +#ifdef CONFIG_MPC8315_DS /* * Workaround for 8315DS board 3gbps link-up issue, * currently limit SATA port to GEN1 speed @@ -664,6 +626,7 @@ static int sata_fsl_port_start(struct ata_port *ap) sata_fsl_scr_read(ap, SCR_CONTROL, &temp); dev_printk(KERN_WARNING, dev, "scr_control, speed limited to %x\n", temp); +#endif return 0; } @@ -691,7 +654,6 @@ static void sata_fsl_port_stop(struct ata_port *ap) dma_free_coherent(dev, SATA_FSL_PORT_PRIV_DMA_SZ, pp->cmdslot, pp->cmdslot_paddr); - ata_pad_free(ap, dev); kfree(pp); } @@ -716,6 +678,15 @@ static unsigned int sata_fsl_dev_classify(struct ata_port *ap) return ata_dev_classify(&tf); } +static int sata_fsl_prereset(struct ata_linke *link, unsigned long deadline) +{ + /* FIXME: Never skip softreset, sata_fsl_softreset() is + * combination of soft and hard resets. sata_fsl_softreset() + * needs to be splitted into soft and hard resets. + */ + return 0; +} + static int sata_fsl_softreset(struct ata_link *link, unsigned int *class, unsigned long deadline) { @@ -728,10 +699,6 @@ static int sata_fsl_softreset(struct ata_link *link, unsigned int *class, u8 *cfis; u32 Serror; int i = 0; - struct ata_queued_cmd qc; - u8 *buf; - dma_addr_t dma_address; - struct scatterlist *sg; unsigned long start_jiffies; DPRINTK("in xx_softreset\n"); @@ -831,13 +798,10 @@ try_offline_again: * reached here, we can send a command to the target device */ - if (link->sactive) - goto skip_srst_do_ncq_error_handling; - DPRINTK("Sending SRST/device reset\n"); ata_tf_init(link->device, &tf); - cfis = (u8 *) & pp->cmdentry->cfis; + cfis = (u8 *) &pp->cmdentry->cfis; /* device reset/SRST is a control register update FIS, uses tag0 */ sata_fsl_setup_cmd_hdr_entry(pp, 0, @@ -901,69 +865,6 @@ try_offline_again: * command bit of the CCreg */ iowrite32(0x01, CC + hcr_base); /* We know it will be cmd#0 always */ - goto check_device_signature; - -skip_srst_do_ncq_error_handling: - - VPRINTK("Sending read log ext(10h) command\n"); - - memset(&qc, 0, sizeof(struct ata_queued_cmd)); - ata_tf_init(link->device, &tf); - - tf.command = ATA_CMD_READ_LOG_EXT; - tf.lbal = ATA_LOG_SATA_NCQ; - tf.nsect = 1; - tf.hob_nsect = 0; - tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_LBA48 | ATA_TFLAG_DEVICE; - tf.protocol = ATA_PROT_PIO; - - qc.tag = ATA_TAG_INTERNAL; - qc.scsicmd = NULL; - qc.ap = ap; - qc.dev = link->device; - - qc.tf = tf; - qc.flags |= ATA_QCFLAG_RESULT_TF; - qc.dma_dir = DMA_FROM_DEVICE; - - buf = ap->sector_buf; - ata_sg_init_one(&qc, buf, 1 * ATA_SECT_SIZE); - - /* - * Need to DMA-map the memory buffer associated with the command - */ - - sg = qc.__sg; - dma_address = dma_map_single(ap->dev, qc.buf_virt, - sg->length, DMA_FROM_DEVICE); - - sg_dma_address(sg) = dma_address; - sg_dma_len(sg) = sg->length; - - VPRINTK("EH, addr = 0x%x, len = 0x%x\n", dma_address, sg->length); - - sata_fsl_qc_prep(&qc); - sata_fsl_qc_issue(&qc); - - temp = ata_wait_register(CQ + hcr_base, 0x1, 0x1, 1, 5000); - if (temp & 0x1) { - VPRINTK("READ_LOG_EXT_10H issue failed\n"); - - VPRINTK("READ_LOG@5000,CQ=0x%x,CA=0x%x,CC=0x%x\n", - ioread32(CQ + hcr_base), - ioread32(CA + hcr_base), ioread32(CC + hcr_base)); - - sata_fsl_scr_read(ap, SCR_ERROR, &Serror); - - VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS)); - VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL)); - VPRINTK("Serror = 0x%x\n", Serror); - goto err; - } - - iowrite32(0x01, CC + hcr_base); /* We know it will be cmd#0 always */ - - check_device_signature: DPRINTK("SATA FSL : Now checking device signature\n"); @@ -991,28 +892,6 @@ err: return -EIO; } -static int sata_fsl_hardreset(struct ata_port *ap, unsigned int *class, - unsigned long deadline) -{ - int retval; - - retval = sata_std_hardreset(ap, class, deadline); - - DPRINTK("SATA FSL : in xx_hardreset, retval = 0x%d\n", retval); - - return retval; -} - -static void sata_fsl_error_handler(struct ata_port *ap) -{ - - DPRINTK("in xx_error_handler\n"); - - /* perform recovery */ - ata_do_eh(ap, ata_std_prereset, sata_fsl_softreset, sata_fsl_hardreset, - ata_std_postreset); -} - static void sata_fsl_post_internal_cmd(struct ata_queued_cmd *qc) { if (qc->flags & ATA_QCFLAG_FAILED) @@ -1024,11 +903,6 @@ static void sata_fsl_post_internal_cmd(struct ata_queued_cmd *qc) } } -static void sata_fsl_irq_clear(struct ata_port *ap) -{ - /* unused */ -} - static void sata_fsl_error_intr(struct ata_port *ap) { struct ata_link *link = &ap->link; @@ -1086,7 +960,7 @@ static void sata_fsl_error_intr(struct ata_port *ap) /* handle fatal errors */ if (hstatus & FATAL_ERROR_DECODE) { err_mask |= AC_ERR_ATA_BUS; - action |= ATA_EH_SOFTRESET; + action |= ATA_EH_RESET; /* how will fatal error interrupts be completed ?? */ freeze = 1; } @@ -1103,10 +977,9 @@ static void sata_fsl_error_intr(struct ata_port *ap) /* record error info */ qc = ata_qc_from_tag(ap, link->active_tag); - if (qc) { - sata_fsl_cache_taskfile_from_d2h_fis(qc, qc->ap); + if (qc) qc->err_mask |= err_mask; - } else + else ehi->err_mask |= err_mask; ehi->action |= action; @@ -1119,14 +992,6 @@ static void sata_fsl_error_intr(struct ata_port *ap) ata_port_abort(ap); } -static void sata_fsl_qc_complete(struct ata_queued_cmd *qc) -{ - if (qc->flags & ATA_QCFLAG_RESULT_TF) { - DPRINTK("xx_qc_complete called\n"); - sata_fsl_cache_taskfile_from_d2h_fis(qc, qc->ap); - } -} - static void sata_fsl_host_intr(struct ata_port *ap) { struct ata_link *link = &ap->link; @@ -1167,10 +1032,8 @@ static void sata_fsl_host_intr(struct ata_port *ap) for (i = 0; i < SATA_FSL_QUEUE_DEPTH; i++) { if (qc_active & (1 << i)) { qc = ata_qc_from_tag(ap, i); - if (qc) { - sata_fsl_qc_complete(qc); + if (qc) ata_qc_complete(qc); - } DPRINTK ("completing ncq cmd,tag=%d,CC=0x%x,CA=0x%x\n", i, ioread32(hcr_base + CC), @@ -1186,10 +1049,8 @@ static void sata_fsl_host_intr(struct ata_port *ap) DPRINTK("completing non-ncq cmd, tag=%d,CC=0x%x\n", link->active_tag, ioread32(hcr_base + CC)); - if (qc) { - sata_fsl_qc_complete(qc); + if (qc) ata_qc_complete(qc); - } } else { /* Spurious Interrupt!! */ DPRINTK("spurious interrupt!!, CC = 0x%x\n", @@ -1287,45 +1148,26 @@ static int sata_fsl_init_controller(struct ata_host *host) * scsi mid-layer and libata interface structures */ static struct scsi_host_template sata_fsl_sht = { - .module = THIS_MODULE, - .name = "sata_fsl", - .ioctl = ata_scsi_ioctl, - .queuecommand = ata_scsi_queuecmd, - .change_queue_depth = ata_scsi_change_queue_depth, + ATA_NCQ_SHT("sata_fsl"), .can_queue = SATA_FSL_QUEUE_DEPTH, - .this_id = ATA_SHT_THIS_ID, .sg_tablesize = SATA_FSL_MAX_PRD_USABLE, - .cmd_per_lun = ATA_SHT_CMD_PER_LUN, - .emulated = ATA_SHT_EMULATED, - .use_clustering = ATA_SHT_USE_CLUSTERING, - .proc_name = "sata_fsl", .dma_boundary = ATA_DMA_BOUNDARY, - .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, - .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .suspend = ata_scsi_device_suspend, - .resume = ata_scsi_device_resume, -#endif }; static const struct ata_port_operations sata_fsl_ops = { - .check_status = sata_fsl_check_status, - .check_altstatus = sata_fsl_check_status, - .dev_select = ata_noop_dev_select, - - .tf_read = sata_fsl_tf_read, + .inherits = &sata_port_ops, .qc_prep = sata_fsl_qc_prep, .qc_issue = sata_fsl_qc_issue, - .irq_clear = sata_fsl_irq_clear, + .qc_fill_rtf = sata_fsl_qc_fill_rtf, .scr_read = sata_fsl_scr_read, .scr_write = sata_fsl_scr_write, .freeze = sata_fsl_freeze, .thaw = sata_fsl_thaw, - .error_handler = sata_fsl_error_handler, + .prereset = sata_fsl_prereset, + .softreset = sata_fsl_softreset, .post_internal_cmd = sata_fsl_post_internal_cmd, .port_start = sata_fsl_port_start, @@ -1335,7 +1177,6 @@ static const struct ata_port_operations sata_fsl_ops = { static const struct ata_port_info sata_fsl_port_info[] = { { .flags = SATA_FSL_HOST_FLAGS, - .link_flags = SATA_FSL_HOST_LFLAGS, .pio_mask = 0x1f, /* pio 0-4 */ .udma_mask = 0x7f, /* udma 0-6 */ .port_ops = &sata_fsl_ops, @@ -1350,7 +1191,6 @@ static int sata_fsl_probe(struct of_device *ofdev, void __iomem *ssr_base = NULL; void __iomem *csr_base = NULL; struct sata_fsl_host_priv *host_priv = NULL; - struct resource *r; int irq; struct ata_host *host; @@ -1360,8 +1200,6 @@ static int sata_fsl_probe(struct of_device *ofdev, dev_printk(KERN_INFO, &ofdev->dev, "Sata FSL Platform/CSB Driver init\n"); - r = kmalloc(sizeof(struct resource), GFP_KERNEL); - hcr_base = of_iomap(ofdev->node, 0); if (!hcr_base) goto error_exit_with_cleanup; @@ -1394,11 +1232,6 @@ static int sata_fsl_probe(struct of_device *ofdev, /* host->iomap is not used currently */ host->private_data = host_priv; - /* setup port(s) */ - - host->ports[0]->ioaddr.cmd_addr = host_priv->hcr_base; - host->ports[0]->ioaddr.scr_addr = host_priv->ssr_base; - /* initialize host controller */ sata_fsl_init_controller(host); @@ -1442,10 +1275,7 @@ static int sata_fsl_remove(struct of_device *ofdev) static struct of_device_id fsl_sata_match[] = { { - .compatible = "fsl,mpc8315-sata", - }, - { - .compatible = "fsl,mpc8379-sata", + .compatible = "fsl,pq-sata", }, {}, };