diff options
-rw-r--r-- | drivers/ata/libata-core.c | 148 | ||||
-rw-r--r-- | include/linux/libata.h | 7 |
2 files changed, 16 insertions, 139 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) | |||
4765 | void ata_noop_qc_prep(struct ata_queued_cmd *qc) { } | 4750 | void 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 | |||
4780 | void 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) | |||
4808 | void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg, | 4766 | void 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 | |||
4831 | static 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 | |||
4880 | skip_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); | |||
7612 | EXPORT_SYMBOL_GPL(ata_host_activate); | 7495 | EXPORT_SYMBOL_GPL(ata_host_activate); |
7613 | EXPORT_SYMBOL_GPL(ata_host_detach); | 7496 | EXPORT_SYMBOL_GPL(ata_host_detach); |
7614 | EXPORT_SYMBOL_GPL(ata_sg_init); | 7497 | EXPORT_SYMBOL_GPL(ata_sg_init); |
7615 | EXPORT_SYMBOL_GPL(ata_sg_init_one); | ||
7616 | EXPORT_SYMBOL_GPL(ata_hsm_move); | 7498 | EXPORT_SYMBOL_GPL(ata_hsm_move); |
7617 | EXPORT_SYMBOL_GPL(ata_qc_complete); | 7499 | EXPORT_SYMBOL_GPL(ata_qc_complete); |
7618 | EXPORT_SYMBOL_GPL(ata_qc_complete_multiple); | 7500 | EXPORT_SYMBOL_GPL(ata_qc_complete_multiple); |
diff --git a/include/linux/libata.h b/include/linux/libata.h index 7fa96cb4f6db..acd90ad78417 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
@@ -219,9 +219,7 @@ enum { | |||
219 | 219 | ||
220 | /* struct ata_queued_cmd flags */ | 220 | /* struct ata_queued_cmd flags */ |
221 | ATA_QCFLAG_ACTIVE = (1 << 0), /* cmd not yet ack'd to scsi lyer */ | 221 | ATA_QCFLAG_ACTIVE = (1 << 0), /* cmd not yet ack'd to scsi lyer */ |
222 | ATA_QCFLAG_SG = (1 << 1), /* have s/g table? */ | 222 | ATA_QCFLAG_DMAMAP = (1 << 1), /* SG table is DMA mapped */ |
223 | ATA_QCFLAG_SINGLE = (1 << 2), /* no s/g, just a single buffer */ | ||
224 | ATA_QCFLAG_DMAMAP = ATA_QCFLAG_SG | ATA_QCFLAG_SINGLE, | ||
225 | ATA_QCFLAG_IO = (1 << 3), /* standard IO command */ | 223 | ATA_QCFLAG_IO = (1 << 3), /* standard IO command */ |
226 | ATA_QCFLAG_RESULT_TF = (1 << 4), /* result TF requested */ | 224 | ATA_QCFLAG_RESULT_TF = (1 << 4), /* result TF requested */ |
227 | ATA_QCFLAG_CLEAR_EXCL = (1 << 5), /* clear excl_link on completion */ | 225 | ATA_QCFLAG_CLEAR_EXCL = (1 << 5), /* clear excl_link on completion */ |
@@ -475,7 +473,6 @@ struct ata_queued_cmd { | |||
475 | 473 | ||
476 | struct scatterlist sgent; | 474 | struct scatterlist sgent; |
477 | struct scatterlist pad_sgent; | 475 | struct scatterlist pad_sgent; |
478 | void *buf_virt; | ||
479 | 476 | ||
480 | /* DO NOT iterate over __sg manually, use ata_for_each_sg() */ | 477 | /* DO NOT iterate over __sg manually, use ata_for_each_sg() */ |
481 | struct scatterlist *__sg; | 478 | struct scatterlist *__sg; |
@@ -891,8 +888,6 @@ extern void ata_dumb_qc_prep(struct ata_queued_cmd *qc); | |||
891 | extern void ata_qc_prep(struct ata_queued_cmd *qc); | 888 | extern void ata_qc_prep(struct ata_queued_cmd *qc); |
892 | extern void ata_noop_qc_prep(struct ata_queued_cmd *qc); | 889 | extern void ata_noop_qc_prep(struct ata_queued_cmd *qc); |
893 | extern unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc); | 890 | extern unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc); |
894 | extern void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, | ||
895 | unsigned int buflen); | ||
896 | extern void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg, | 891 | extern void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg, |
897 | unsigned int n_elem); | 892 | unsigned int n_elem); |
898 | extern unsigned int ata_dev_classify(const struct ata_taskfile *tf); | 893 | extern unsigned int ata_dev_classify(const struct ata_taskfile *tf); |