11a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil/* 21a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil buffer queues. 31a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com> 41a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil Copyright (C) 2004 Chris Kennedy <c@groovy.org> 51a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl> 61a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 71a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil This program is free software; you can redistribute it and/or modify 81a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil it under the terms of the GNU General Public License as published by 91a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil the Free Software Foundation; either version 2 of the License, or 101a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil (at your option) any later version. 111a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 121a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil This program is distributed in the hope that it will be useful, 131a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil but WITHOUT ANY WARRANTY; without even the implied warranty of 141a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 151a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil GNU General Public License for more details. 161a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 171a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil You should have received a copy of the GNU General Public License 181a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil along with this program; if not, write to the Free Software 191a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 201a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil */ 211a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 221a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#include "ivtv-driver.h" 231a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#include "ivtv-queue.h" 241a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 251a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilint ivtv_buf_copy_from_user(struct ivtv_stream *s, struct ivtv_buffer *buf, const char __user *src, int copybytes) 261a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 271a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (s->buf_size - buf->bytesused < copybytes) 281a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil copybytes = s->buf_size - buf->bytesused; 291a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (copy_from_user(buf->buf + buf->bytesused, src, copybytes)) { 301a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return -EFAULT; 311a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 321a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil buf->bytesused += copybytes; 331a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return copybytes; 341a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 351a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 361a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilvoid ivtv_buf_swap(struct ivtv_buffer *buf) 371a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 381a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil int i; 391a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 401a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil for (i = 0; i < buf->bytesused; i += 4) 411a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil swab32s((u32 *)(buf->buf + i)); 421a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 431a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 441a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilvoid ivtv_queue_init(struct ivtv_queue *q) 451a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 461a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil INIT_LIST_HEAD(&q->list); 471a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil q->buffers = 0; 481a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil q->length = 0; 491a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil q->bytesused = 0; 501a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 511a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 521a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilvoid ivtv_enqueue(struct ivtv_stream *s, struct ivtv_buffer *buf, struct ivtv_queue *q) 531a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 547daa4a8897e79911f524ddac065adea05c7e9b16Guennadi Liakhovetski unsigned long flags; 551a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 561a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* clear the buffer if it is going to be enqueued to the free queue */ 571a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (q == &s->q_free) { 581a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil buf->bytesused = 0; 591a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil buf->readpos = 0; 601a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil buf->b_flags = 0; 61f4071b85ea0ca3bd06f63c330562b4cfdffa8473Hans Verkuil buf->dma_xfer_cnt = 0; 621a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 631a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil spin_lock_irqsave(&s->qlock, flags); 641a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil list_add_tail(&buf->list, &q->list); 651a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil q->buffers++; 661a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil q->length += s->buf_size; 671a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil q->bytesused += buf->bytesused - buf->readpos; 681a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil spin_unlock_irqrestore(&s->qlock, flags); 691a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 701a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 711a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstruct ivtv_buffer *ivtv_dequeue(struct ivtv_stream *s, struct ivtv_queue *q) 721a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 731a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv_buffer *buf = NULL; 747daa4a8897e79911f524ddac065adea05c7e9b16Guennadi Liakhovetski unsigned long flags; 751a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 761a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil spin_lock_irqsave(&s->qlock, flags); 771a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (!list_empty(&q->list)) { 781a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil buf = list_entry(q->list.next, struct ivtv_buffer, list); 791a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil list_del_init(q->list.next); 801a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil q->buffers--; 811a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil q->length -= s->buf_size; 821a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil q->bytesused -= buf->bytesused - buf->readpos; 831a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 841a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil spin_unlock_irqrestore(&s->qlock, flags); 851a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return buf; 861a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 871a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 881a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstatic void ivtv_queue_move_buf(struct ivtv_stream *s, struct ivtv_queue *from, 89f4071b85ea0ca3bd06f63c330562b4cfdffa8473Hans Verkuil struct ivtv_queue *to, int clear) 901a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 911a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv_buffer *buf = list_entry(from->list.next, struct ivtv_buffer, list); 921a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 931a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil list_move_tail(from->list.next, &to->list); 941a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil from->buffers--; 951a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil from->length -= s->buf_size; 961a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil from->bytesused -= buf->bytesused - buf->readpos; 971a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* special handling for q_free */ 981a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (clear) 99f4071b85ea0ca3bd06f63c330562b4cfdffa8473Hans Verkuil buf->bytesused = buf->readpos = buf->b_flags = buf->dma_xfer_cnt = 0; 1001a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil to->buffers++; 1011a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil to->length += s->buf_size; 1021a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil to->bytesused += buf->bytesused - buf->readpos; 1031a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 1041a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 1051a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil/* Move 'needed_bytes' worth of buffers from queue 'from' into queue 'to'. 1061a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil If 'needed_bytes' == 0, then move all buffers from 'from' into 'to'. 1071a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil If 'steal' != NULL, then buffers may also taken from that queue if 108f4071b85ea0ca3bd06f63c330562b4cfdffa8473Hans Verkuil needed, but only if 'from' is the free queue. 1091a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 1101a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil The buffer is automatically cleared if it goes to the free queue. It is 1111a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil also cleared if buffers need to be taken from the 'steal' queue and 1121a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil the 'from' queue is the free queue. 1131a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 1141a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil When 'from' is q_free, then needed_bytes is compared to the total 1151a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil available buffer length, otherwise needed_bytes is compared to the 1161a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil bytesused value. For the 'steal' queue the total available buffer 1171a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil length is always used. 1181a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 1191a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil -ENOMEM is returned if the buffers could not be obtained, 0 if all 1201a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil buffers where obtained from the 'from' list and if non-zero then 1211a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil the number of stolen buffers is returned. */ 1221a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilint ivtv_queue_move(struct ivtv_stream *s, struct ivtv_queue *from, struct ivtv_queue *steal, 1231a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv_queue *to, int needed_bytes) 1241a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 1251a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil unsigned long flags; 1261a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil int rc = 0; 1271a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil int from_free = from == &s->q_free; 1281a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil int to_free = to == &s->q_free; 129f4071b85ea0ca3bd06f63c330562b4cfdffa8473Hans Verkuil int bytes_available, bytes_steal; 1301a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 1311a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil spin_lock_irqsave(&s->qlock, flags); 1321a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (needed_bytes == 0) { 1331a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil from_free = 1; 1341a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil needed_bytes = from->length; 1351a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 1361a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 1371a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil bytes_available = from_free ? from->length : from->bytesused; 138f4071b85ea0ca3bd06f63c330562b4cfdffa8473Hans Verkuil bytes_steal = (from_free && steal) ? steal->length : 0; 1391a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 140f4071b85ea0ca3bd06f63c330562b4cfdffa8473Hans Verkuil if (bytes_available + bytes_steal < needed_bytes) { 1411a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil spin_unlock_irqrestore(&s->qlock, flags); 1421a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return -ENOMEM; 1431a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 144f4071b85ea0ca3bd06f63c330562b4cfdffa8473Hans Verkuil while (bytes_available < needed_bytes) { 145f4071b85ea0ca3bd06f63c330562b4cfdffa8473Hans Verkuil struct ivtv_buffer *buf = list_entry(steal->list.prev, struct ivtv_buffer, list); 146f4071b85ea0ca3bd06f63c330562b4cfdffa8473Hans Verkuil u16 dma_xfer_cnt = buf->dma_xfer_cnt; 147f4071b85ea0ca3bd06f63c330562b4cfdffa8473Hans Verkuil 148f4071b85ea0ca3bd06f63c330562b4cfdffa8473Hans Verkuil /* move buffers from the tail of the 'steal' queue to the tail of the 149f4071b85ea0ca3bd06f63c330562b4cfdffa8473Hans Verkuil 'from' queue. Always copy all the buffers with the same dma_xfer_cnt 150f4071b85ea0ca3bd06f63c330562b4cfdffa8473Hans Verkuil value, this ensures that you do not end up with partial frame data 151f4071b85ea0ca3bd06f63c330562b4cfdffa8473Hans Verkuil if one frame is stored in multiple buffers. */ 152f4071b85ea0ca3bd06f63c330562b4cfdffa8473Hans Verkuil while (dma_xfer_cnt == buf->dma_xfer_cnt) { 153f4071b85ea0ca3bd06f63c330562b4cfdffa8473Hans Verkuil list_move_tail(steal->list.prev, &from->list); 154f4071b85ea0ca3bd06f63c330562b4cfdffa8473Hans Verkuil rc++; 155f4071b85ea0ca3bd06f63c330562b4cfdffa8473Hans Verkuil steal->buffers--; 156f4071b85ea0ca3bd06f63c330562b4cfdffa8473Hans Verkuil steal->length -= s->buf_size; 157f4071b85ea0ca3bd06f63c330562b4cfdffa8473Hans Verkuil steal->bytesused -= buf->bytesused - buf->readpos; 158f4071b85ea0ca3bd06f63c330562b4cfdffa8473Hans Verkuil buf->bytesused = buf->readpos = buf->b_flags = buf->dma_xfer_cnt = 0; 159f4071b85ea0ca3bd06f63c330562b4cfdffa8473Hans Verkuil from->buffers++; 160f4071b85ea0ca3bd06f63c330562b4cfdffa8473Hans Verkuil from->length += s->buf_size; 161f4071b85ea0ca3bd06f63c330562b4cfdffa8473Hans Verkuil bytes_available += s->buf_size; 162f4071b85ea0ca3bd06f63c330562b4cfdffa8473Hans Verkuil if (list_empty(&steal->list)) 163f4071b85ea0ca3bd06f63c330562b4cfdffa8473Hans Verkuil break; 164f4071b85ea0ca3bd06f63c330562b4cfdffa8473Hans Verkuil buf = list_entry(steal->list.prev, struct ivtv_buffer, list); 165f4071b85ea0ca3bd06f63c330562b4cfdffa8473Hans Verkuil } 166f4071b85ea0ca3bd06f63c330562b4cfdffa8473Hans Verkuil } 1671a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (from_free) { 1681a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil u32 old_length = to->length; 1691a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 1701a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil while (to->length - old_length < needed_bytes) { 171f4071b85ea0ca3bd06f63c330562b4cfdffa8473Hans Verkuil ivtv_queue_move_buf(s, from, to, 1); 1721a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 1731a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 1741a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil else { 1751a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil u32 old_bytesused = to->bytesused; 1761a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 1771a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil while (to->bytesused - old_bytesused < needed_bytes) { 178f4071b85ea0ca3bd06f63c330562b4cfdffa8473Hans Verkuil ivtv_queue_move_buf(s, from, to, to_free); 1791a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 1801a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 1811a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil spin_unlock_irqrestore(&s->qlock, flags); 1821a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return rc; 1831a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 1841a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 1851a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilvoid ivtv_flush_queues(struct ivtv_stream *s) 1861a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 1871a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_queue_move(s, &s->q_io, NULL, &s->q_free, 0); 1881a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_queue_move(s, &s->q_full, NULL, &s->q_free, 0); 1891a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_queue_move(s, &s->q_dma, NULL, &s->q_free, 0); 1901a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_queue_move(s, &s->q_predma, NULL, &s->q_free, 0); 1911a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 1921a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 1931a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilint ivtv_stream_alloc(struct ivtv_stream *s) 1941a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 1951a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv *itv = s->itv; 196b0510f8dc73dce56f35337487c6374ae84b15446Al Viro int SGsize = sizeof(struct ivtv_sg_host_element) * s->buffers; 1971a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil int i; 1981a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 1991a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (s->buffers == 0) 2001a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return 0; 2011a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 2021a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_INFO("Allocate %s%s stream: %d x %d buffers (%dkB total)\n", 2031a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil s->dma != PCI_DMA_NONE ? "DMA " : "", 2041a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil s->name, s->buffers, s->buf_size, s->buffers * s->buf_size / 1024); 2051a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 2063f98387efa9333c5765d36e144c47c107d6ba64aHans Verkuil s->sg_pending = kzalloc(SGsize, GFP_KERNEL|__GFP_NOWARN); 20737093b1ea600d84fbf7252baf12eedec85ae40f1Hans Verkuil if (s->sg_pending == NULL) { 20837093b1ea600d84fbf7252baf12eedec85ae40f1Hans Verkuil IVTV_ERR("Could not allocate sg_pending for %s stream\n", s->name); 20937093b1ea600d84fbf7252baf12eedec85ae40f1Hans Verkuil return -ENOMEM; 210dc02d50a6d71cba2b2edb78377af5a5965879a49Hans Verkuil } 21137093b1ea600d84fbf7252baf12eedec85ae40f1Hans Verkuil s->sg_pending_size = 0; 212dc02d50a6d71cba2b2edb78377af5a5965879a49Hans Verkuil 2133f98387efa9333c5765d36e144c47c107d6ba64aHans Verkuil s->sg_processing = kzalloc(SGsize, GFP_KERNEL|__GFP_NOWARN); 21437093b1ea600d84fbf7252baf12eedec85ae40f1Hans Verkuil if (s->sg_processing == NULL) { 21537093b1ea600d84fbf7252baf12eedec85ae40f1Hans Verkuil IVTV_ERR("Could not allocate sg_processing for %s stream\n", s->name); 21637093b1ea600d84fbf7252baf12eedec85ae40f1Hans Verkuil kfree(s->sg_pending); 21737093b1ea600d84fbf7252baf12eedec85ae40f1Hans Verkuil s->sg_pending = NULL; 21837093b1ea600d84fbf7252baf12eedec85ae40f1Hans Verkuil return -ENOMEM; 21937093b1ea600d84fbf7252baf12eedec85ae40f1Hans Verkuil } 22037093b1ea600d84fbf7252baf12eedec85ae40f1Hans Verkuil s->sg_processing_size = 0; 22137093b1ea600d84fbf7252baf12eedec85ae40f1Hans Verkuil 2223f98387efa9333c5765d36e144c47c107d6ba64aHans Verkuil s->sg_dma = kzalloc(sizeof(struct ivtv_sg_element), 2233f98387efa9333c5765d36e144c47c107d6ba64aHans Verkuil GFP_KERNEL|__GFP_NOWARN); 22437093b1ea600d84fbf7252baf12eedec85ae40f1Hans Verkuil if (s->sg_dma == NULL) { 22537093b1ea600d84fbf7252baf12eedec85ae40f1Hans Verkuil IVTV_ERR("Could not allocate sg_dma for %s stream\n", s->name); 22637093b1ea600d84fbf7252baf12eedec85ae40f1Hans Verkuil kfree(s->sg_pending); 22737093b1ea600d84fbf7252baf12eedec85ae40f1Hans Verkuil s->sg_pending = NULL; 22837093b1ea600d84fbf7252baf12eedec85ae40f1Hans Verkuil kfree(s->sg_processing); 22937093b1ea600d84fbf7252baf12eedec85ae40f1Hans Verkuil s->sg_processing = NULL; 230dc02d50a6d71cba2b2edb78377af5a5965879a49Hans Verkuil return -ENOMEM; 231dc02d50a6d71cba2b2edb78377af5a5965879a49Hans Verkuil } 232dc02d50a6d71cba2b2edb78377af5a5965879a49Hans Verkuil if (ivtv_might_use_dma(s)) { 233e9e10124e269a39de089c5e0d9936fae2ff889b2Alan Cox s->sg_handle = pci_map_single(itv->pdev, s->sg_dma, 234e9e10124e269a39de089c5e0d9936fae2ff889b2Alan Cox sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE); 2351a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_stream_sync_for_cpu(s); 2361a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 2371a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 2381a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* allocate stream buffers. Initially all buffers are in q_free. */ 2391a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil for (i = 0; i < s->buffers; i++) { 2403f98387efa9333c5765d36e144c47c107d6ba64aHans Verkuil struct ivtv_buffer *buf = kzalloc(sizeof(struct ivtv_buffer), 2413f98387efa9333c5765d36e144c47c107d6ba64aHans Verkuil GFP_KERNEL|__GFP_NOWARN); 2421a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 2431a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (buf == NULL) 2441a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil break; 2453f98387efa9333c5765d36e144c47c107d6ba64aHans Verkuil buf->buf = kmalloc(s->buf_size + 256, GFP_KERNEL|__GFP_NOWARN); 2461a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (buf->buf == NULL) { 2471a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil kfree(buf); 2481a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil break; 2491a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 2501a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil INIT_LIST_HEAD(&buf->list); 251dc02d50a6d71cba2b2edb78377af5a5965879a49Hans Verkuil if (ivtv_might_use_dma(s)) { 2528ac05ae3192ce8a71fc84e4a88772cce0c09173cHans Verkuil buf->dma_handle = pci_map_single(s->itv->pdev, 2531a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil buf->buf, s->buf_size + 256, s->dma); 2541a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_buf_sync_for_cpu(s, buf); 2551a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 2561a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_enqueue(s, buf, &s->q_free); 2571a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 2581a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (i == s->buffers) 2591a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return 0; 2601a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_ERR("Couldn't allocate buffers for %s stream\n", s->name); 2611a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_stream_free(s); 2621a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return -ENOMEM; 2631a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 2641a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 2651a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilvoid ivtv_stream_free(struct ivtv_stream *s) 2661a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 2671a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv_buffer *buf; 2681a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 2691a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* move all buffers to q_free */ 2701a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_flush_queues(s); 2711a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 2721a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* empty q_free */ 2731a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil while ((buf = ivtv_dequeue(s, &s->q_free))) { 274dc02d50a6d71cba2b2edb78377af5a5965879a49Hans Verkuil if (ivtv_might_use_dma(s)) 2758ac05ae3192ce8a71fc84e4a88772cce0c09173cHans Verkuil pci_unmap_single(s->itv->pdev, buf->dma_handle, 2761a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil s->buf_size + 256, s->dma); 2771a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil kfree(buf->buf); 2781a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil kfree(buf); 2791a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 2801a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 2811a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* Free SG Array/Lists */ 28237093b1ea600d84fbf7252baf12eedec85ae40f1Hans Verkuil if (s->sg_dma != NULL) { 28337093b1ea600d84fbf7252baf12eedec85ae40f1Hans Verkuil if (s->sg_handle != IVTV_DMA_UNMAPPED) { 2848ac05ae3192ce8a71fc84e4a88772cce0c09173cHans Verkuil pci_unmap_single(s->itv->pdev, s->sg_handle, 28537093b1ea600d84fbf7252baf12eedec85ae40f1Hans Verkuil sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE); 28637093b1ea600d84fbf7252baf12eedec85ae40f1Hans Verkuil s->sg_handle = IVTV_DMA_UNMAPPED; 2871a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 28837093b1ea600d84fbf7252baf12eedec85ae40f1Hans Verkuil kfree(s->sg_pending); 28937093b1ea600d84fbf7252baf12eedec85ae40f1Hans Verkuil kfree(s->sg_processing); 29037093b1ea600d84fbf7252baf12eedec85ae40f1Hans Verkuil kfree(s->sg_dma); 29137093b1ea600d84fbf7252baf12eedec85ae40f1Hans Verkuil s->sg_pending = NULL; 29237093b1ea600d84fbf7252baf12eedec85ae40f1Hans Verkuil s->sg_processing = NULL; 29337093b1ea600d84fbf7252baf12eedec85ae40f1Hans Verkuil s->sg_dma = NULL; 29437093b1ea600d84fbf7252baf12eedec85ae40f1Hans Verkuil s->sg_pending_size = 0; 29537093b1ea600d84fbf7252baf12eedec85ae40f1Hans Verkuil s->sg_processing_size = 0; 2961a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 2971a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 298