|
@@ -1410,7 +1410,7 @@ static void ata_qc_complete_internal(struct ata_queued_cmd *qc)
|
|
|
*/
|
|
|
unsigned ata_exec_internal_sg(struct ata_device *dev,
|
|
|
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)
|
|
|
{
|
|
|
struct ata_link *link = dev->link;
|
|
@@ -1472,11 +1472,12 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
|
|
|
qc->dma_dir = dma_dir;
|
|
|
if (dma_dir != DMA_NONE) {
|
|
|
unsigned int i, buflen = 0;
|
|
|
+ struct scatterlist *sg;
|
|
|
|
|
|
- for (i = 0; i < n_elem; i++)
|
|
|
- buflen += sg[i].length;
|
|
|
+ for_each_sg(sgl, sg, n_elem, i)
|
|
|
+ buflen += sg->length;
|
|
|
|
|
|
- ata_sg_init(qc, sg, n_elem);
|
|
|
+ ata_sg_init(qc, sgl, n_elem);
|
|
|
qc->nbytes = buflen;
|
|
|
}
|
|
|
|
|
@@ -4292,7 +4293,7 @@ void ata_sg_clean(struct ata_queued_cmd *qc)
|
|
|
if (qc->n_elem)
|
|
|
dma_unmap_sg(ap->dev, sg, qc->n_elem, dir);
|
|
|
/* 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) {
|
|
|
struct scatterlist *psg = &qc->pad_sgent;
|
|
|
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)
|
|
|
qc->orig_n_elem = 1;
|
|
|
qc->buf_virt = buf;
|
|
|
qc->nbytes = buflen;
|
|
|
+ qc->cursg = qc->__sg;
|
|
|
|
|
|
sg_init_one(&qc->sgent, buf, buflen);
|
|
|
}
|
|
@@ -4572,6 +4574,7 @@ void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
|
|
|
qc->__sg = sg;
|
|
|
qc->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)
|
|
|
{
|
|
|
struct ata_port *ap = qc->ap;
|
|
|
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;
|
|
|
|
|
|
VPRINTK("ENTER, ata%u\n", ap->print_id);
|
|
@@ -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)
|
|
|
{
|
|
|
int do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
|
|
|
- struct scatterlist *sg = qc->__sg;
|
|
|
struct ata_port *ap = qc->ap;
|
|
|
struct page *page;
|
|
|
unsigned int offset;
|
|
@@ -4834,8 +4836,8 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
|
|
|
if (qc->curbytes == qc->nbytes - qc->sect_size)
|
|
|
ap->hsm_task_state = HSM_ST_LAST;
|
|
|
|
|
|
- page = sg[qc->cursg].page;
|
|
|
- offset = sg[qc->cursg].offset + qc->cursg_ofs;
|
|
|
+ page = qc->cursg->page;
|
|
|
+ offset = qc->cursg->offset + qc->cursg_ofs;
|
|
|
|
|
|
/* get the current page and offset */
|
|
|
page = nth_page(page, (offset >> PAGE_SHIFT));
|
|
@@ -4863,8 +4865,8 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
|
|
|
qc->curbytes += qc->sect_size;
|
|
|
qc->cursg_ofs += qc->sect_size;
|
|
|
|
|
|
- if (qc->cursg_ofs == (&sg[qc->cursg])->length) {
|
|
|
- qc->cursg++;
|
|
|
+ if (qc->cursg_ofs == qc->cursg->length) {
|
|
|
+ qc->cursg = sg_next(qc->cursg);
|
|
|
qc->cursg_ofs = 0;
|
|
|
}
|
|
|
}
|
|
@@ -4959,7 +4961,7 @@ static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes)
|
|
|
ap->hsm_task_state = HSM_ST_LAST;
|
|
|
|
|
|
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
|
|
|
* more data to transfer. In order not to overrun qc->sg
|
|
@@ -4982,7 +4984,7 @@ next_sg:
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- sg = &qc->__sg[qc->cursg];
|
|
|
+ sg = qc->cursg;
|
|
|
|
|
|
page = sg->page;
|
|
|
offset = sg->offset + qc->cursg_ofs;
|
|
@@ -5021,7 +5023,7 @@ next_sg:
|
|
|
qc->cursg_ofs += count;
|
|
|
|
|
|
if (qc->cursg_ofs == sg->length) {
|
|
|
- qc->cursg++;
|
|
|
+ qc->cursg = sg_next(qc->cursg);
|
|
|
qc->cursg_ofs = 0;
|
|
|
}
|
|
|
|