aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/libata-core.c')
-rw-r--r--drivers/ata/libata-core.c145
1 files changed, 9 insertions, 136 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index a109ccbda9ca..3587ac3fe3f3 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -4493,30 +4493,13 @@ void ata_sg_clean(struct ata_queued_cmd *qc)
4493 struct ata_port *ap = qc->ap; 4493 struct ata_port *ap = qc->ap;
4494 struct scatterlist *sg = qc->sg; 4494 struct scatterlist *sg = qc->sg;
4495 int dir = qc->dma_dir; 4495 int dir = qc->dma_dir;
4496 void *pad_buf = NULL;
4497 4496
4498 WARN_ON(sg == NULL); 4497 WARN_ON(sg == NULL);
4499 4498
4500 VPRINTK("unmapping %u sg elements\n", qc->mapped_n_elem); 4499 VPRINTK("unmapping %u sg elements\n", qc->n_elem);
4501 4500
4502 /* if we padded the buffer out to 32-bit bound, and data 4501 if (qc->n_elem)
4503 * xfer direction is from-device, we must copy from the 4502 dma_unmap_sg(ap->dev, sg, qc->n_elem, dir);
4504 * pad buffer back into the supplied buffer
4505 */
4506 if (qc->pad_len && !(qc->tf.flags & ATA_TFLAG_WRITE))
4507 pad_buf = ap->pad + (qc->tag * ATA_DMA_PAD_SZ);
4508
4509 if (qc->mapped_n_elem)
4510 dma_unmap_sg(ap->dev, sg, qc->mapped_n_elem, dir);
4511 /* restore last sg */
4512 if (qc->last_sg)
4513 *qc->last_sg = qc->saved_last_sg;
4514 if (pad_buf) {
4515 struct scatterlist *psg = &qc->extra_sg[1];
4516 void *addr = kmap_atomic(sg_page(psg), KM_IRQ0);
4517 memcpy(addr + psg->offset, pad_buf, qc->pad_len);
4518 kunmap_atomic(addr, KM_IRQ0);
4519 }
4520 4503
4521 qc->flags &= ~ATA_QCFLAG_DMAMAP; 4504 qc->flags &= ~ATA_QCFLAG_DMAMAP;
4522 qc->sg = NULL; 4505 qc->sg = NULL;
@@ -4767,97 +4750,6 @@ void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
4767 qc->cursg = qc->sg; 4750 qc->cursg = qc->sg;
4768} 4751}
4769 4752
4770static unsigned int ata_sg_setup_extra(struct ata_queued_cmd *qc,
4771 unsigned int *n_elem_extra,
4772 unsigned int *nbytes_extra)
4773{
4774 struct ata_port *ap = qc->ap;
4775 unsigned int n_elem = qc->n_elem;
4776 struct scatterlist *lsg, *copy_lsg = NULL, *tsg = NULL, *esg = NULL;
4777
4778 *n_elem_extra = 0;
4779 *nbytes_extra = 0;
4780
4781 /* needs padding? */
4782 qc->pad_len = qc->nbytes & 3;
4783
4784 if (likely(!qc->pad_len))
4785 return n_elem;
4786
4787 /* locate last sg and save it */
4788 lsg = sg_last(qc->sg, n_elem);
4789 qc->last_sg = lsg;
4790 qc->saved_last_sg = *lsg;
4791
4792 sg_init_table(qc->extra_sg, ARRAY_SIZE(qc->extra_sg));
4793
4794 if (qc->pad_len) {
4795 struct scatterlist *psg = &qc->extra_sg[1];
4796 void *pad_buf = ap->pad + (qc->tag * ATA_DMA_PAD_SZ);
4797 unsigned int offset;
4798
4799 WARN_ON(qc->dev->class != ATA_DEV_ATAPI);
4800
4801 memset(pad_buf, 0, ATA_DMA_PAD_SZ);
4802
4803 /* psg->page/offset are used to copy to-be-written
4804 * data in this function or read data in ata_sg_clean.
4805 */
4806 offset = lsg->offset + lsg->length - qc->pad_len;
4807 sg_set_page(psg, nth_page(sg_page(lsg), offset >> PAGE_SHIFT),
4808 qc->pad_len, offset_in_page(offset));
4809
4810 if (qc->tf.flags & ATA_TFLAG_WRITE) {
4811 void *addr = kmap_atomic(sg_page(psg), KM_IRQ0);
4812 memcpy(pad_buf, addr + psg->offset, qc->pad_len);
4813 kunmap_atomic(addr, KM_IRQ0);
4814 }
4815
4816 sg_dma_address(psg) = ap->pad_dma + (qc->tag * ATA_DMA_PAD_SZ);
4817 sg_dma_len(psg) = ATA_DMA_PAD_SZ;
4818
4819 /* Trim the last sg entry and chain the original and
4820 * padding sg lists.
4821 *
4822 * Because chaining consumes one sg entry, one extra
4823 * sg entry is allocated and the last sg entry is
4824 * copied to it if the length isn't zero after padded
4825 * amount is removed.
4826 *
4827 * If the last sg entry is completely replaced by
4828 * padding sg entry, the first sg entry is skipped
4829 * while chaining.
4830 */
4831 lsg->length -= qc->pad_len;
4832 if (lsg->length) {
4833 copy_lsg = &qc->extra_sg[0];
4834 tsg = &qc->extra_sg[0];
4835 } else {
4836 n_elem--;
4837 tsg = &qc->extra_sg[1];
4838 }
4839
4840 esg = &qc->extra_sg[1];
4841
4842 (*n_elem_extra)++;
4843 (*nbytes_extra) += 4 - qc->pad_len;
4844 }
4845
4846 if (copy_lsg)
4847 sg_set_page(copy_lsg, sg_page(lsg), lsg->length, lsg->offset);
4848
4849 sg_chain(lsg, 1, tsg);
4850 sg_mark_end(esg);
4851
4852 /* sglist can't start with chaining sg entry, fast forward */
4853 if (qc->sg == lsg) {
4854 qc->sg = tsg;
4855 qc->cursg = tsg;
4856 }
4857
4858 return n_elem;
4859}
4860
4861/** 4753/**
4862 * ata_sg_setup - DMA-map the scatter-gather table associated with a command. 4754 * ata_sg_setup - DMA-map the scatter-gather table associated with a command.
4863 * @qc: Command with scatter-gather table to be mapped. 4755 * @qc: Command with scatter-gather table to be mapped.
@@ -4874,26 +4766,17 @@ static unsigned int ata_sg_setup_extra(struct ata_queued_cmd *qc,
4874static int ata_sg_setup(struct ata_queued_cmd *qc) 4766static int ata_sg_setup(struct ata_queued_cmd *qc)
4875{ 4767{
4876 struct ata_port *ap = qc->ap; 4768 struct ata_port *ap = qc->ap;
4877 unsigned int n_elem, n_elem_extra, nbytes_extra; 4769 unsigned int n_elem;
4878 4770
4879 VPRINTK("ENTER, ata%u\n", ap->print_id); 4771 VPRINTK("ENTER, ata%u\n", ap->print_id);
4880 4772
4881 n_elem = ata_sg_setup_extra(qc, &n_elem_extra, &nbytes_extra); 4773 n_elem = dma_map_sg(ap->dev, qc->sg, qc->n_elem, qc->dma_dir);
4774 if (n_elem < 1)
4775 return -1;
4882 4776
4883 if (n_elem) { 4777 DPRINTK("%d sg elements mapped\n", n_elem);
4884 n_elem = dma_map_sg(ap->dev, qc->sg, n_elem, qc->dma_dir);
4885 if (n_elem < 1) {
4886 /* restore last sg */
4887 if (qc->last_sg)
4888 *qc->last_sg = qc->saved_last_sg;
4889 return -1;
4890 }
4891 DPRINTK("%d sg elements mapped\n", n_elem);
4892 }
4893 4778
4894 qc->n_elem = qc->mapped_n_elem = n_elem; 4779 qc->n_elem = n_elem;
4895 qc->n_elem += n_elem_extra;
4896 qc->nbytes += nbytes_extra;
4897 qc->flags |= ATA_QCFLAG_DMAMAP; 4780 qc->flags |= ATA_QCFLAG_DMAMAP;
4898 4781
4899 return 0; 4782 return 0;
@@ -5962,9 +5845,6 @@ void ata_qc_issue(struct ata_queued_cmd *qc)
5962 */ 5845 */
5963 BUG_ON(ata_is_data(prot) && (!qc->sg || !qc->n_elem || !qc->nbytes)); 5846 BUG_ON(ata_is_data(prot) && (!qc->sg || !qc->n_elem || !qc->nbytes));
5964 5847
5965 /* ata_sg_setup() may update nbytes */
5966 qc->raw_nbytes = qc->nbytes;
5967
5968 if (ata_is_dma(prot) || (ata_is_pio(prot) && 5848 if (ata_is_dma(prot) || (ata_is_pio(prot) &&
5969 (ap->flags & ATA_FLAG_PIO_DMA))) 5849 (ap->flags & ATA_FLAG_PIO_DMA)))
5970 if (ata_sg_setup(qc)) 5850 if (ata_sg_setup(qc))
@@ -6573,19 +6453,12 @@ void ata_host_resume(struct ata_host *host)
6573int ata_port_start(struct ata_port *ap) 6453int ata_port_start(struct ata_port *ap)
6574{ 6454{
6575 struct device *dev = ap->dev; 6455 struct device *dev = ap->dev;
6576 int rc;
6577 6456
6578 ap->prd = dmam_alloc_coherent(dev, ATA_PRD_TBL_SZ, &ap->prd_dma, 6457 ap->prd = dmam_alloc_coherent(dev, ATA_PRD_TBL_SZ, &ap->prd_dma,
6579 GFP_KERNEL); 6458 GFP_KERNEL);
6580 if (!ap->prd) 6459 if (!ap->prd)
6581 return -ENOMEM; 6460 return -ENOMEM;
6582 6461
6583 rc = ata_pad_alloc(ap, dev);
6584 if (rc)
6585 return rc;
6586
6587 DPRINTK("prd alloc, virt %p, dma %llx\n", ap->prd,
6588 (unsigned long long)ap->prd_dma);
6589 return 0; 6462 return 0;
6590} 6463}
6591 6464