diff options
author | Tejun Heo <htejun@gmail.com> | 2007-12-05 02:43:10 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2008-01-23 05:24:14 -0500 |
commit | f92a26365a72333f418abe82700c6030d4a1a807 (patch) | |
tree | 73bb3ae684abfabf2d0aecac33af1a3f2112afc4 /drivers/ata | |
parent | 001102d7859be0e7f7b9f2d62b841f2c0f9c2640 (diff) |
libata: change ATA_QCFLAG_DMAMAP semantics
ATA_QCFLAG_DMAMAP was a bit peculiar in that it got set during qc
initialization and cleared if DMA mapping wasn't necessary. Make it
more straight forward by making the following changes.
* Don't set it during initialization. Set it after DMA is actually
mapped.
* Add BUG_ON() to guarantee that there is data to transfer if DMAMAP
is set. This always holds for the current code. The BUG_ON() is
for docummentation and sanity check.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/libata-core.c | 15 |
1 files changed, 7 insertions, 8 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 76360f0ca20d..865428a64de3 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -4475,7 +4475,6 @@ void ata_sg_clean(struct ata_queued_cmd *qc) | |||
4475 | int dir = qc->dma_dir; | 4475 | int dir = qc->dma_dir; |
4476 | void *pad_buf = NULL; | 4476 | void *pad_buf = NULL; |
4477 | 4477 | ||
4478 | WARN_ON(!(qc->flags & ATA_QCFLAG_DMAMAP)); | ||
4479 | WARN_ON(sg == NULL); | 4478 | WARN_ON(sg == NULL); |
4480 | 4479 | ||
4481 | VPRINTK("unmapping %u sg elements\n", qc->n_elem); | 4480 | VPRINTK("unmapping %u sg elements\n", qc->n_elem); |
@@ -4762,11 +4761,9 @@ void ata_noop_qc_prep(struct ata_queued_cmd *qc) { } | |||
4762 | * LOCKING: | 4761 | * LOCKING: |
4763 | * spin_lock_irqsave(host lock) | 4762 | * spin_lock_irqsave(host lock) |
4764 | */ | 4763 | */ |
4765 | |||
4766 | void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg, | 4764 | void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg, |
4767 | unsigned int n_elem) | 4765 | unsigned int n_elem) |
4768 | { | 4766 | { |
4769 | qc->flags |= ATA_QCFLAG_DMAMAP; | ||
4770 | qc->__sg = sg; | 4767 | qc->__sg = sg; |
4771 | qc->n_elem = n_elem; | 4768 | qc->n_elem = n_elem; |
4772 | qc->orig_n_elem = n_elem; | 4769 | qc->orig_n_elem = n_elem; |
@@ -4795,7 +4792,6 @@ static int ata_sg_setup(struct ata_queued_cmd *qc) | |||
4795 | int n_elem, pre_n_elem, dir, trim_sg = 0; | 4792 | int n_elem, pre_n_elem, dir, trim_sg = 0; |
4796 | 4793 | ||
4797 | VPRINTK("ENTER, ata%u\n", ap->print_id); | 4794 | VPRINTK("ENTER, ata%u\n", ap->print_id); |
4798 | WARN_ON(!(qc->flags & ATA_QCFLAG_DMAMAP)); | ||
4799 | 4795 | ||
4800 | /* we must lengthen transfers to end on a 32-bit boundary */ | 4796 | /* we must lengthen transfers to end on a 32-bit boundary */ |
4801 | qc->pad_len = lsg->length & 3; | 4797 | qc->pad_len = lsg->length & 3; |
@@ -4855,6 +4851,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc) | |||
4855 | 4851 | ||
4856 | skip_map: | 4852 | skip_map: |
4857 | qc->n_elem = n_elem; | 4853 | qc->n_elem = n_elem; |
4854 | qc->flags |= ATA_QCFLAG_DMAMAP; | ||
4858 | 4855 | ||
4859 | return 0; | 4856 | return 0; |
4860 | } | 4857 | } |
@@ -5912,12 +5909,15 @@ void ata_qc_issue(struct ata_queued_cmd *qc) | |||
5912 | qc->flags |= ATA_QCFLAG_ACTIVE; | 5909 | qc->flags |= ATA_QCFLAG_ACTIVE; |
5913 | ap->qc_active |= 1 << qc->tag; | 5910 | ap->qc_active |= 1 << qc->tag; |
5914 | 5911 | ||
5912 | /* We guarantee to LLDs that they will have at least one | ||
5913 | * non-zero sg if the command is a data command. | ||
5914 | */ | ||
5915 | BUG_ON(ata_is_data(prot) && (!qc->__sg || !qc->n_elem || !qc->nbytes)); | ||
5916 | |||
5915 | if (ata_is_dma(prot) || (ata_is_pio(prot) && | 5917 | if (ata_is_dma(prot) || (ata_is_pio(prot) && |
5916 | (ap->flags & ATA_FLAG_PIO_DMA))) { | 5918 | (ap->flags & ATA_FLAG_PIO_DMA))) |
5917 | if (ata_sg_setup(qc)) | 5919 | if (ata_sg_setup(qc)) |
5918 | goto sg_err; | 5920 | goto sg_err; |
5919 | } else | ||
5920 | qc->flags &= ATA_QCFLAG_DMAMAP; | ||
5921 | 5921 | ||
5922 | /* if device is sleeping, schedule softreset and abort the link */ | 5922 | /* if device is sleeping, schedule softreset and abort the link */ |
5923 | if (unlikely(qc->dev->flags & ATA_DFLAG_SLEEPING)) { | 5923 | if (unlikely(qc->dev->flags & ATA_DFLAG_SLEEPING)) { |
@@ -5935,7 +5935,6 @@ void ata_qc_issue(struct ata_queued_cmd *qc) | |||
5935 | return; | 5935 | return; |
5936 | 5936 | ||
5937 | sg_err: | 5937 | sg_err: |
5938 | qc->flags &= ~ATA_QCFLAG_DMAMAP; | ||
5939 | qc->err_mask |= AC_ERR_SYSTEM; | 5938 | qc->err_mask |= AC_ERR_SYSTEM; |
5940 | err: | 5939 | err: |
5941 | ata_qc_complete(qc); | 5940 | ata_qc_complete(qc); |