aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2007-12-05 02:43:12 -0500
committerJeff Garzik <jeff@garzik.org>2008-01-23 05:24:15 -0500
commit0bcc65ad78ae517de16b2ca07a2891f49d44d156 (patch)
tree87eecc4aec56500f3e29a1e82b631093f950ac85 /drivers/ata
parentff2aeb1eb64c8a4770a6304f9addbae9f9828646 (diff)
libata: make qc->nbytes include extra buffers
qc->nbytes didn't use to include extra buffers setup by libata core layer and my be odd. This patch makes qc->nbytes include any extra buffers setup by libata core layer and guaranteed to be aligned on 4 byte boundary. This value is to be used to program the host controller. As this represents the actual length of buffer available to the controller and the controller must be able to deal with short transfers for ATAPI commands which can transfer variable length, this shouldn't break any controllers while making problems like rounding-down and controllers choking up on odd transfer bytes much less likely. The unmodified value is stored in new field qc->raw_nbytes. 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.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index e998028302da..ee72994500a3 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -4763,13 +4763,15 @@ void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
4763} 4763}
4764 4764
4765static unsigned int ata_sg_setup_extra(struct ata_queued_cmd *qc, 4765static unsigned int ata_sg_setup_extra(struct ata_queued_cmd *qc,
4766 unsigned int *n_elem_extra) 4766 unsigned int *n_elem_extra,
4767 unsigned int *nbytes_extra)
4767{ 4768{
4768 struct ata_port *ap = qc->ap; 4769 struct ata_port *ap = qc->ap;
4769 unsigned int n_elem = qc->n_elem; 4770 unsigned int n_elem = qc->n_elem;
4770 struct scatterlist *lsg, *copy_lsg = NULL, *tsg = NULL, *esg = NULL; 4771 struct scatterlist *lsg, *copy_lsg = NULL, *tsg = NULL, *esg = NULL;
4771 4772
4772 *n_elem_extra = 0; 4773 *n_elem_extra = 0;
4774 *nbytes_extra = 0;
4773 4775
4774 /* needs padding? */ 4776 /* needs padding? */
4775 qc->pad_len = qc->nbytes & 3; 4777 qc->pad_len = qc->nbytes & 3;
@@ -4833,6 +4835,7 @@ static unsigned int ata_sg_setup_extra(struct ata_queued_cmd *qc,
4833 esg = &qc->extra_sg[1]; 4835 esg = &qc->extra_sg[1];
4834 4836
4835 (*n_elem_extra)++; 4837 (*n_elem_extra)++;
4838 (*nbytes_extra) += 4 - qc->pad_len;
4836 } 4839 }
4837 4840
4838 if (copy_lsg) 4841 if (copy_lsg)
@@ -4866,11 +4869,11 @@ static unsigned int ata_sg_setup_extra(struct ata_queued_cmd *qc,
4866static int ata_sg_setup(struct ata_queued_cmd *qc) 4869static int ata_sg_setup(struct ata_queued_cmd *qc)
4867{ 4870{
4868 struct ata_port *ap = qc->ap; 4871 struct ata_port *ap = qc->ap;
4869 unsigned int n_elem, n_elem_extra; 4872 unsigned int n_elem, n_elem_extra, nbytes_extra;
4870 4873
4871 VPRINTK("ENTER, ata%u\n", ap->print_id); 4874 VPRINTK("ENTER, ata%u\n", ap->print_id);
4872 4875
4873 n_elem = ata_sg_setup_extra(qc, &n_elem_extra); 4876 n_elem = ata_sg_setup_extra(qc, &n_elem_extra, &nbytes_extra);
4874 4877
4875 if (n_elem) { 4878 if (n_elem) {
4876 n_elem = dma_map_sg(ap->dev, qc->sg, n_elem, qc->dma_dir); 4879 n_elem = dma_map_sg(ap->dev, qc->sg, n_elem, qc->dma_dir);
@@ -4885,7 +4888,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
4885 4888
4886 qc->n_elem = qc->mapped_n_elem = n_elem; 4889 qc->n_elem = qc->mapped_n_elem = n_elem;
4887 qc->n_elem += n_elem_extra; 4890 qc->n_elem += n_elem_extra;
4888 4891 qc->nbytes += nbytes_extra;
4889 qc->flags |= ATA_QCFLAG_DMAMAP; 4892 qc->flags |= ATA_QCFLAG_DMAMAP;
4890 4893
4891 return 0; 4894 return 0;
@@ -5949,6 +5952,9 @@ void ata_qc_issue(struct ata_queued_cmd *qc)
5949 */ 5952 */
5950 BUG_ON(ata_is_data(prot) && (!qc->sg || !qc->n_elem || !qc->nbytes)); 5953 BUG_ON(ata_is_data(prot) && (!qc->sg || !qc->n_elem || !qc->nbytes));
5951 5954
5955 /* ata_sg_setup() may update nbytes */
5956 qc->raw_nbytes = qc->nbytes;
5957
5952 if (ata_is_dma(prot) || (ata_is_pio(prot) && 5958 if (ata_is_dma(prot) || (ata_is_pio(prot) &&
5953 (ap->flags & ATA_FLAG_PIO_DMA))) 5959 (ap->flags & ATA_FLAG_PIO_DMA)))
5954 if (ata_sg_setup(qc)) 5960 if (ata_sg_setup(qc))