@@ -113,6 +113,8 @@ struct sci_port {
struct scatterlist sg_tx;
unsigned int sg_len_tx;
struct scatterlist sg_rx[MAX_BUF_RX];
+ void *rx_chunk;
+ u8 *rx_buf[MAX_BUF_RX];
unsigned int total_buf_len_rx;
unsigned int nr_buf_rx;
struct work_struct work_tx;
@@ -1307,8 +1309,7 @@ static void sci_dma_tx_complete(void *arg)
}
/* Locking: called with port lock held */
-static int sci_dma_rx_push(struct sci_port *s, struct scatterlist *sg,
- unsigned int count)
+static int sci_dma_rx_push(struct sci_port *s, u8 *buf, unsigned int count)
{
struct uart_port *port = &s->port;
struct tty_port *tport = &port->state->port;
@@ -1323,7 +1324,7 @@ static int sci_dma_rx_push(struct sci_port *s, struct scatterlist *sg,
return room;
for (i = 0; i < room; i++)
- tty_insert_flip_char(tport, ((u8 *)sg_virt(sg))[i], TTY_NORMAL);
+ tty_insert_flip_char(tport, buf[i], TTY_NORMAL);
port->icount.rx += room;
@@ -1357,7 +1358,7 @@ static void sci_dma_rx_complete(void *arg)
active = sci_dma_rx_find_active(s);
if (active >= 0)
- count = sci_dma_rx_push(s, &s->sg_rx[active],
+ count = sci_dma_rx_push(s, s->rx_buf[active],
sg_dma_len(&s->sg_rx[active]));
mod_timer(&s->rx_timer, jiffies + s->rx_timeout);
@@ -1385,8 +1386,7 @@ static void sci_rx_dma_release(struct sci_port *s, bool enable_pio)
s->cookie_rx[i] = -EINVAL;
if (sg_dma_address(&s->sg_rx[0])) {
dma_free_coherent(chan->device->dev, s->total_buf_len_rx,
- sg_virt(&s->sg_rx[0]),
- sg_dma_address(&s->sg_rx[0]));
+ s->rx_chunk, sg_dma_address(&s->sg_rx[0]));
sg_dma_address(&s->sg_rx[0]) = 0;
}
dma_release_channel(chan);
@@ -1491,7 +1491,7 @@ static void work_fn_rx(struct work_struct *work)
dev_dbg(port->dev, "Read %zu bytes with cookie %d\n", read,
s->active_rx);
- count = sci_dma_rx_push(s, &s->sg_rx[new], read);
+ count = sci_dma_rx_push(s, s->rx_buf[new], read);
if (count)
tty_flip_buffer_push(&port->state->port);
@@ -1823,12 +1823,13 @@ static void sci_request_dma(struct uart_port *port)
return;
}
+ s->rx_chunk = buf;
for (i = 0; i < s->nr_buf_rx; i++) {
struct scatterlist *sg = &s->sg_rx[i];
sg_init_table(sg, 1);
- sg_set_page(sg, virt_to_page(buf), buflen[i],
- offset_in_page(buf));
+ s->rx_buf[i] = buf;
+ sg->length = buflen[i];
sg_dma_address(sg) = dma;
buf += buflen[i];