Commit 87260216 authored by Jens Axboe's avatar Jens Axboe

libata: convert to using sg helpers

This converts libata to using the sg helpers for looking up sg
elements, instead of doing it manually.
Signed-off-by: default avatarJens Axboe <jens.axboe@oracle.com>
parent a8474ce2
...@@ -1410,7 +1410,7 @@ static void ata_qc_complete_internal(struct ata_queued_cmd *qc) ...@@ -1410,7 +1410,7 @@ static void ata_qc_complete_internal(struct ata_queued_cmd *qc)
*/ */
unsigned ata_exec_internal_sg(struct ata_device *dev, unsigned ata_exec_internal_sg(struct ata_device *dev,
struct ata_taskfile *tf, const u8 *cdb, struct ata_taskfile *tf, const u8 *cdb,
int dma_dir, struct scatterlist *sg, int dma_dir, struct scatterlist *sgl,
unsigned int n_elem, unsigned long timeout) unsigned int n_elem, unsigned long timeout)
{ {
struct ata_link *link = dev->link; struct ata_link *link = dev->link;
...@@ -1472,11 +1472,12 @@ unsigned ata_exec_internal_sg(struct ata_device *dev, ...@@ -1472,11 +1472,12 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
qc->dma_dir = dma_dir; qc->dma_dir = dma_dir;
if (dma_dir != DMA_NONE) { if (dma_dir != DMA_NONE) {
unsigned int i, buflen = 0; unsigned int i, buflen = 0;
struct scatterlist *sg;
for (i = 0; i < n_elem; i++) for_each_sg(sgl, sg, n_elem, i)
buflen += sg[i].length; buflen += sg->length;
ata_sg_init(qc, sg, n_elem); ata_sg_init(qc, sgl, n_elem);
qc->nbytes = buflen; qc->nbytes = buflen;
} }
...@@ -4292,7 +4293,7 @@ void ata_sg_clean(struct ata_queued_cmd *qc) ...@@ -4292,7 +4293,7 @@ void ata_sg_clean(struct ata_queued_cmd *qc)
if (qc->n_elem) if (qc->n_elem)
dma_unmap_sg(ap->dev, sg, qc->n_elem, dir); dma_unmap_sg(ap->dev, sg, qc->n_elem, dir);
/* restore last sg */ /* restore last sg */
sg[qc->orig_n_elem - 1].length += qc->pad_len; sg_last(sg, qc->orig_n_elem)->length += qc->pad_len;
if (pad_buf) { if (pad_buf) {
struct scatterlist *psg = &qc->pad_sgent; struct scatterlist *psg = &qc->pad_sgent;
void *addr = kmap_atomic(psg->page, KM_IRQ0); void *addr = kmap_atomic(psg->page, KM_IRQ0);
...@@ -4547,6 +4548,7 @@ void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen) ...@@ -4547,6 +4548,7 @@ void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen)
qc->orig_n_elem = 1; qc->orig_n_elem = 1;
qc->buf_virt = buf; qc->buf_virt = buf;
qc->nbytes = buflen; qc->nbytes = buflen;
qc->cursg = qc->__sg;
sg_init_one(&qc->sgent, buf, buflen); sg_init_one(&qc->sgent, buf, buflen);
} }
...@@ -4572,6 +4574,7 @@ void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg, ...@@ -4572,6 +4574,7 @@ void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
qc->__sg = sg; qc->__sg = sg;
qc->n_elem = n_elem; qc->n_elem = n_elem;
qc->orig_n_elem = n_elem; qc->orig_n_elem = n_elem;
qc->cursg = qc->__sg;
} }
/** /**
...@@ -4661,7 +4664,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc) ...@@ -4661,7 +4664,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
{ {
struct ata_port *ap = qc->ap; struct ata_port *ap = qc->ap;
struct scatterlist *sg = qc->__sg; struct scatterlist *sg = qc->__sg;
struct scatterlist *lsg = &sg[qc->n_elem - 1]; struct scatterlist *lsg = sg_last(qc->__sg, qc->n_elem);
int n_elem, pre_n_elem, dir, trim_sg = 0; int n_elem, pre_n_elem, dir, trim_sg = 0;
VPRINTK("ENTER, ata%u\n", ap->print_id); VPRINTK("ENTER, ata%u\n", ap->print_id);
...@@ -4825,7 +4828,6 @@ void ata_data_xfer_noirq(struct ata_device *adev, unsigned char *buf, ...@@ -4825,7 +4828,6 @@ void ata_data_xfer_noirq(struct ata_device *adev, unsigned char *buf,
static void ata_pio_sector(struct ata_queued_cmd *qc) static void ata_pio_sector(struct ata_queued_cmd *qc)
{ {
int do_write = (qc->tf.flags & ATA_TFLAG_WRITE); int do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
struct scatterlist *sg = qc->__sg;
struct ata_port *ap = qc->ap; struct ata_port *ap = qc->ap;
struct page *page; struct page *page;
unsigned int offset; unsigned int offset;
...@@ -4834,8 +4836,8 @@ static void ata_pio_sector(struct ata_queued_cmd *qc) ...@@ -4834,8 +4836,8 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
if (qc->curbytes == qc->nbytes - qc->sect_size) if (qc->curbytes == qc->nbytes - qc->sect_size)
ap->hsm_task_state = HSM_ST_LAST; ap->hsm_task_state = HSM_ST_LAST;
page = sg[qc->cursg].page; page = qc->cursg->page;
offset = sg[qc->cursg].offset + qc->cursg_ofs; offset = qc->cursg->offset + qc->cursg_ofs;
/* get the current page and offset */ /* get the current page and offset */
page = nth_page(page, (offset >> PAGE_SHIFT)); page = nth_page(page, (offset >> PAGE_SHIFT));
...@@ -4863,8 +4865,8 @@ static void ata_pio_sector(struct ata_queued_cmd *qc) ...@@ -4863,8 +4865,8 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
qc->curbytes += qc->sect_size; qc->curbytes += qc->sect_size;
qc->cursg_ofs += qc->sect_size; qc->cursg_ofs += qc->sect_size;
if (qc->cursg_ofs == (&sg[qc->cursg])->length) { if (qc->cursg_ofs == qc->cursg->length) {
qc->cursg++; qc->cursg = sg_next(qc->cursg);
qc->cursg_ofs = 0; qc->cursg_ofs = 0;
} }
} }
...@@ -4959,7 +4961,7 @@ static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes) ...@@ -4959,7 +4961,7 @@ static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes)
ap->hsm_task_state = HSM_ST_LAST; ap->hsm_task_state = HSM_ST_LAST;
next_sg: next_sg:
if (unlikely(qc->cursg >= qc->n_elem)) { if (unlikely(qc->cursg == sg_last(qc->__sg, qc->n_elem))) {
/* /*
* The end of qc->sg is reached and the device expects * The end of qc->sg is reached and the device expects
* more data to transfer. In order not to overrun qc->sg * more data to transfer. In order not to overrun qc->sg
...@@ -4982,7 +4984,7 @@ next_sg: ...@@ -4982,7 +4984,7 @@ next_sg:
return; return;
} }
sg = &qc->__sg[qc->cursg]; sg = qc->cursg;
page = sg->page; page = sg->page;
offset = sg->offset + qc->cursg_ofs; offset = sg->offset + qc->cursg_ofs;
...@@ -5021,7 +5023,7 @@ next_sg: ...@@ -5021,7 +5023,7 @@ next_sg:
qc->cursg_ofs += count; qc->cursg_ofs += count;
if (qc->cursg_ofs == sg->length) { if (qc->cursg_ofs == sg->length) {
qc->cursg++; qc->cursg = sg_next(qc->cursg);
qc->cursg_ofs = 0; qc->cursg_ofs = 0;
} }
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <asm/scatterlist.h> #include <linux/scatterlist.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/ata.h> #include <linux/ata.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
...@@ -416,6 +416,7 @@ struct ata_queued_cmd { ...@@ -416,6 +416,7 @@ struct ata_queued_cmd {
unsigned long flags; /* ATA_QCFLAG_xxx */ unsigned long flags; /* ATA_QCFLAG_xxx */
unsigned int tag; unsigned int tag;
unsigned int n_elem; unsigned int n_elem;
unsigned int n_iter;
unsigned int orig_n_elem; unsigned int orig_n_elem;
int dma_dir; int dma_dir;
...@@ -426,7 +427,7 @@ struct ata_queued_cmd { ...@@ -426,7 +427,7 @@ struct ata_queued_cmd {
unsigned int nbytes; unsigned int nbytes;
unsigned int curbytes; unsigned int curbytes;
unsigned int cursg; struct scatterlist *cursg;
unsigned int cursg_ofs; unsigned int cursg_ofs;
struct scatterlist sgent; struct scatterlist sgent;
...@@ -1043,7 +1044,7 @@ ata_sg_is_last(struct scatterlist *sg, struct ata_queued_cmd *qc) ...@@ -1043,7 +1044,7 @@ ata_sg_is_last(struct scatterlist *sg, struct ata_queued_cmd *qc)
return 1; return 1;
if (qc->pad_len) if (qc->pad_len)
return 0; return 0;
if (((sg - qc->__sg) + 1) == qc->n_elem) if (qc->n_iter == qc->n_elem)
return 1; return 1;
return 0; return 0;
} }
...@@ -1051,6 +1052,7 @@ ata_sg_is_last(struct scatterlist *sg, struct ata_queued_cmd *qc) ...@@ -1051,6 +1052,7 @@ ata_sg_is_last(struct scatterlist *sg, struct ata_queued_cmd *qc)
static inline struct scatterlist * static inline struct scatterlist *
ata_qc_first_sg(struct ata_queued_cmd *qc) ata_qc_first_sg(struct ata_queued_cmd *qc)
{ {
qc->n_iter = 0;
if (qc->n_elem) if (qc->n_elem)
return qc->__sg; return qc->__sg;
if (qc->pad_len) if (qc->pad_len)
...@@ -1063,8 +1065,8 @@ ata_qc_next_sg(struct scatterlist *sg, struct ata_queued_cmd *qc) ...@@ -1063,8 +1065,8 @@ ata_qc_next_sg(struct scatterlist *sg, struct ata_queued_cmd *qc)
{ {
if (sg == &qc->pad_sgent) if (sg == &qc->pad_sgent)
return NULL; return NULL;
if (++sg - qc->__sg < qc->n_elem) if (++qc->n_iter < qc->n_elem)
return sg; return sg_next(sg);
if (qc->pad_len) if (qc->pad_len)
return &qc->pad_sgent; return &qc->pad_sgent;
return NULL; return NULL;
...@@ -1309,9 +1311,11 @@ static inline void ata_qc_reinit(struct ata_queued_cmd *qc) ...@@ -1309,9 +1311,11 @@ static inline void ata_qc_reinit(struct ata_queued_cmd *qc)
qc->dma_dir = DMA_NONE; qc->dma_dir = DMA_NONE;
qc->__sg = NULL; qc->__sg = NULL;
qc->flags = 0; qc->flags = 0;
qc->cursg = qc->cursg_ofs = 0; qc->cursg = NULL;
qc->cursg_ofs = 0;
qc->nbytes = qc->curbytes = 0; qc->nbytes = qc->curbytes = 0;
qc->n_elem = 0; qc->n_elem = 0;
qc->n_iter = 0;
qc->err_mask = 0; qc->err_mask = 0;
qc->pad_len = 0; qc->pad_len = 0;
qc->sect_size = ATA_SECT_SIZE; qc->sect_size = ATA_SECT_SIZE;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment