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.c148
1 files changed, 15 insertions, 133 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 39cedd949ed4..76360f0ca20d 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -4478,9 +4478,6 @@ void ata_sg_clean(struct ata_queued_cmd *qc)
4478 WARN_ON(!(qc->flags & ATA_QCFLAG_DMAMAP)); 4478 WARN_ON(!(qc->flags & ATA_QCFLAG_DMAMAP));
4479 WARN_ON(sg == NULL); 4479 WARN_ON(sg == NULL);
4480 4480
4481 if (qc->flags & ATA_QCFLAG_SINGLE)
4482 WARN_ON(qc->n_elem > 1);
4483
4484 VPRINTK("unmapping %u sg elements\n", qc->n_elem); 4481 VPRINTK("unmapping %u sg elements\n", qc->n_elem);
4485 4482
4486 /* if we padded the buffer out to 32-bit bound, and data 4483 /* if we padded the buffer out to 32-bit bound, and data
@@ -4490,27 +4487,15 @@ void ata_sg_clean(struct ata_queued_cmd *qc)
4490 if (qc->pad_len && !(qc->tf.flags & ATA_TFLAG_WRITE)) 4487 if (qc->pad_len && !(qc->tf.flags & ATA_TFLAG_WRITE))
4491 pad_buf = ap->pad + (qc->tag * ATA_DMA_PAD_SZ); 4488 pad_buf = ap->pad + (qc->tag * ATA_DMA_PAD_SZ);
4492 4489
4493 if (qc->flags & ATA_QCFLAG_SG) { 4490 if (qc->n_elem)
4494 if (qc->n_elem) 4491 dma_unmap_sg(ap->dev, sg, qc->n_elem, dir);
4495 dma_unmap_sg(ap->dev, sg, qc->n_elem, dir); 4492 /* restore last sg */
4496 /* restore last sg */ 4493 sg_last(sg, qc->orig_n_elem)->length += qc->pad_len;
4497 sg_last(sg, qc->orig_n_elem)->length += qc->pad_len; 4494 if (pad_buf) {
4498 if (pad_buf) { 4495 struct scatterlist *psg = &qc->pad_sgent;
4499 struct scatterlist *psg = &qc->pad_sgent; 4496 void *addr = kmap_atomic(sg_page(psg), KM_IRQ0);
4500 void *addr = kmap_atomic(sg_page(psg), KM_IRQ0); 4497 memcpy(addr + psg->offset, pad_buf, qc->pad_len);
4501 memcpy(addr + psg->offset, pad_buf, qc->pad_len); 4498 kunmap_atomic(addr, KM_IRQ0);
4502 kunmap_atomic(addr, KM_IRQ0);
4503 }
4504 } else {
4505 if (qc->n_elem)
4506 dma_unmap_single(ap->dev,
4507 sg_dma_address(&sg[0]), sg_dma_len(&sg[0]),
4508 dir);
4509 /* restore sg */
4510 sg->length += qc->pad_len;
4511 if (pad_buf)
4512 memcpy(qc->buf_virt + sg->length - qc->pad_len,
4513 pad_buf, qc->pad_len);
4514 } 4499 }
4515 4500
4516 qc->flags &= ~ATA_QCFLAG_DMAMAP; 4501 qc->flags &= ~ATA_QCFLAG_DMAMAP;
@@ -4765,33 +4750,6 @@ void ata_dumb_qc_prep(struct ata_queued_cmd *qc)
4765void ata_noop_qc_prep(struct ata_queued_cmd *qc) { } 4750void ata_noop_qc_prep(struct ata_queued_cmd *qc) { }
4766 4751
4767/** 4752/**
4768 * ata_sg_init_one - Associate command with memory buffer
4769 * @qc: Command to be associated
4770 * @buf: Memory buffer
4771 * @buflen: Length of memory buffer, in bytes.
4772 *
4773 * Initialize the data-related elements of queued_cmd @qc
4774 * to point to a single memory buffer, @buf of byte length @buflen.
4775 *
4776 * LOCKING:
4777 * spin_lock_irqsave(host lock)
4778 */
4779
4780void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen)
4781{
4782 qc->flags |= ATA_QCFLAG_SINGLE;
4783
4784 qc->__sg = &qc->sgent;
4785 qc->n_elem = 1;
4786 qc->orig_n_elem = 1;
4787 qc->buf_virt = buf;
4788 qc->nbytes = buflen;
4789 qc->cursg = qc->__sg;
4790
4791 sg_init_one(&qc->sgent, buf, buflen);
4792}
4793
4794/**
4795 * ata_sg_init - Associate command with scatter-gather table. 4753 * ata_sg_init - Associate command with scatter-gather table.
4796 * @qc: Command to be associated 4754 * @qc: Command to be associated
4797 * @sg: Scatter-gather table. 4755 * @sg: Scatter-gather table.
@@ -4808,7 +4766,7 @@ void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen)
4808void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg, 4766void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
4809 unsigned int n_elem) 4767 unsigned int n_elem)
4810{ 4768{
4811 qc->flags |= ATA_QCFLAG_SG; 4769 qc->flags |= ATA_QCFLAG_DMAMAP;
4812 qc->__sg = sg; 4770 qc->__sg = sg;
4813 qc->n_elem = n_elem; 4771 qc->n_elem = n_elem;
4814 qc->orig_n_elem = n_elem; 4772 qc->orig_n_elem = n_elem;
@@ -4816,75 +4774,6 @@ void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
4816} 4774}
4817 4775
4818/** 4776/**
4819 * ata_sg_setup_one - DMA-map the memory buffer associated with a command.
4820 * @qc: Command with memory buffer to be mapped.
4821 *
4822 * DMA-map the memory buffer associated with queued_cmd @qc.
4823 *
4824 * LOCKING:
4825 * spin_lock_irqsave(host lock)
4826 *
4827 * RETURNS:
4828 * Zero on success, negative on error.
4829 */
4830
4831static int ata_sg_setup_one(struct ata_queued_cmd *qc)
4832{
4833 struct ata_port *ap = qc->ap;
4834 int dir = qc->dma_dir;
4835 struct scatterlist *sg = qc->__sg;
4836 dma_addr_t dma_address;
4837 int trim_sg = 0;
4838
4839 /* we must lengthen transfers to end on a 32-bit boundary */
4840 qc->pad_len = sg->length & 3;
4841 if (qc->pad_len) {
4842 void *pad_buf = ap->pad + (qc->tag * ATA_DMA_PAD_SZ);
4843 struct scatterlist *psg = &qc->pad_sgent;
4844
4845 WARN_ON(qc->dev->class != ATA_DEV_ATAPI);
4846
4847 memset(pad_buf, 0, ATA_DMA_PAD_SZ);
4848
4849 if (qc->tf.flags & ATA_TFLAG_WRITE)
4850 memcpy(pad_buf, qc->buf_virt + sg->length - qc->pad_len,
4851 qc->pad_len);
4852
4853 sg_dma_address(psg) = ap->pad_dma + (qc->tag * ATA_DMA_PAD_SZ);
4854 sg_dma_len(psg) = ATA_DMA_PAD_SZ;
4855 /* trim sg */
4856 sg->length -= qc->pad_len;
4857 if (sg->length == 0)
4858 trim_sg = 1;
4859
4860 DPRINTK("padding done, sg->length=%u pad_len=%u\n",
4861 sg->length, qc->pad_len);
4862 }
4863
4864 if (trim_sg) {
4865 qc->n_elem--;
4866 goto skip_map;
4867 }
4868
4869 dma_address = dma_map_single(ap->dev, qc->buf_virt,
4870 sg->length, dir);
4871 if (dma_mapping_error(dma_address)) {
4872 /* restore sg */
4873 sg->length += qc->pad_len;
4874 return -1;
4875 }
4876
4877 sg_dma_address(sg) = dma_address;
4878 sg_dma_len(sg) = sg->length;
4879
4880skip_map:
4881 DPRINTK("mapped buffer of %d bytes for %s\n", sg_dma_len(sg),
4882 qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read");
4883
4884 return 0;
4885}
4886
4887/**
4888 * ata_sg_setup - DMA-map the scatter-gather table associated with a command. 4777 * ata_sg_setup - DMA-map the scatter-gather table associated with a command.
4889 * @qc: Command with scatter-gather table to be mapped. 4778 * @qc: Command with scatter-gather table to be mapped.
4890 * 4779 *
@@ -4906,7 +4795,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
4906 int n_elem, pre_n_elem, dir, trim_sg = 0; 4795 int n_elem, pre_n_elem, dir, trim_sg = 0;
4907 4796
4908 VPRINTK("ENTER, ata%u\n", ap->print_id); 4797 VPRINTK("ENTER, ata%u\n", ap->print_id);
4909 WARN_ON(!(qc->flags & ATA_QCFLAG_SG)); 4798 WARN_ON(!(qc->flags & ATA_QCFLAG_DMAMAP));
4910 4799
4911 /* we must lengthen transfers to end on a 32-bit boundary */ 4800 /* we must lengthen transfers to end on a 32-bit boundary */
4912 qc->pad_len = lsg->length & 3; 4801 qc->pad_len = lsg->length & 3;
@@ -6025,16 +5914,10 @@ void ata_qc_issue(struct ata_queued_cmd *qc)
6025 5914
6026 if (ata_is_dma(prot) || (ata_is_pio(prot) && 5915 if (ata_is_dma(prot) || (ata_is_pio(prot) &&
6027 (ap->flags & ATA_FLAG_PIO_DMA))) { 5916 (ap->flags & ATA_FLAG_PIO_DMA))) {
6028 if (qc->flags & ATA_QCFLAG_SG) { 5917 if (ata_sg_setup(qc))
6029 if (ata_sg_setup(qc)) 5918 goto sg_err;
6030 goto sg_err; 5919 } else
6031 } else if (qc->flags & ATA_QCFLAG_SINGLE) { 5920 qc->flags &= ATA_QCFLAG_DMAMAP;
6032 if (ata_sg_setup_one(qc))
6033 goto sg_err;
6034 }
6035 } else {
6036 qc->flags &= ~ATA_QCFLAG_DMAMAP;
6037 }
6038 5921
6039 /* if device is sleeping, schedule softreset and abort the link */ 5922 /* if device is sleeping, schedule softreset and abort the link */
6040 if (unlikely(qc->dev->flags & ATA_DFLAG_SLEEPING)) { 5923 if (unlikely(qc->dev->flags & ATA_DFLAG_SLEEPING)) {
@@ -7612,7 +7495,6 @@ EXPORT_SYMBOL_GPL(ata_host_register);
7612EXPORT_SYMBOL_GPL(ata_host_activate); 7495EXPORT_SYMBOL_GPL(ata_host_activate);
7613EXPORT_SYMBOL_GPL(ata_host_detach); 7496EXPORT_SYMBOL_GPL(ata_host_detach);
7614EXPORT_SYMBOL_GPL(ata_sg_init); 7497EXPORT_SYMBOL_GPL(ata_sg_init);
7615EXPORT_SYMBOL_GPL(ata_sg_init_one);
7616EXPORT_SYMBOL_GPL(ata_hsm_move); 7498EXPORT_SYMBOL_GPL(ata_hsm_move);
7617EXPORT_SYMBOL_GPL(ata_qc_complete); 7499EXPORT_SYMBOL_GPL(ata_qc_complete);
7618EXPORT_SYMBOL_GPL(ata_qc_complete_multiple); 7500EXPORT_SYMBOL_GPL(ata_qc_complete_multiple);