diff options
author | David S. Miller <davem@davemloft.net> | 2008-09-08 19:59:05 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-09-08 19:59:05 -0400 |
commit | 17dce5dfe38ae2fb359b61e855f5d8a3a8b7892b (patch) | |
tree | 88bb1fcf84f9ebfa4299c9a8dcd9e6330b358446 /drivers/media/video/cx18 | |
parent | 712d6954e3998d0de2840d8130941e8042541246 (diff) | |
parent | 82a28c794f27aac17d7a3ebd7f14d731a11a5532 (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts:
net/mac80211/mlme.c
Diffstat (limited to 'drivers/media/video/cx18')
-rw-r--r-- | drivers/media/video/cx18/cx18-av-firmware.c | 16 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-driver.c | 6 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-dvb.c | 2 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-dvb.h | 2 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-irq.c | 2 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-queue.c | 129 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-queue.h | 2 |
7 files changed, 47 insertions, 112 deletions
diff --git a/drivers/media/video/cx18/cx18-av-firmware.c b/drivers/media/video/cx18/cx18-av-firmware.c index 834b9248242e..e996a4e3123a 100644 --- a/drivers/media/video/cx18/cx18-av-firmware.c +++ b/drivers/media/video/cx18/cx18-av-firmware.c | |||
@@ -32,7 +32,7 @@ int cx18_av_loadfw(struct cx18 *cx) | |||
32 | u32 v; | 32 | u32 v; |
33 | const u8 *ptr; | 33 | const u8 *ptr; |
34 | int i; | 34 | int i; |
35 | int retries = 0; | 35 | int retries1 = 0; |
36 | 36 | ||
37 | if (request_firmware(&fw, FWFILE, &cx->dev->dev) != 0) { | 37 | if (request_firmware(&fw, FWFILE, &cx->dev->dev) != 0) { |
38 | CX18_ERR("unable to open firmware %s\n", FWFILE); | 38 | CX18_ERR("unable to open firmware %s\n", FWFILE); |
@@ -41,7 +41,7 @@ int cx18_av_loadfw(struct cx18 *cx) | |||
41 | 41 | ||
42 | /* The firmware load often has byte errors, so allow for several | 42 | /* The firmware load often has byte errors, so allow for several |
43 | retries, both at byte level and at the firmware load level. */ | 43 | retries, both at byte level and at the firmware load level. */ |
44 | while (retries < 5) { | 44 | while (retries1 < 5) { |
45 | cx18_av_write4(cx, CXADEC_CHIP_CTRL, 0x00010000); | 45 | cx18_av_write4(cx, CXADEC_CHIP_CTRL, 0x00010000); |
46 | cx18_av_write(cx, CXADEC_STD_DET_CTL, 0xf6); | 46 | cx18_av_write(cx, CXADEC_STD_DET_CTL, 0xf6); |
47 | 47 | ||
@@ -57,9 +57,9 @@ int cx18_av_loadfw(struct cx18 *cx) | |||
57 | for (i = 0; i < size; i++) { | 57 | for (i = 0; i < size; i++) { |
58 | u32 dl_control = 0x0F000000 | i | ((u32)ptr[i] << 16); | 58 | u32 dl_control = 0x0F000000 | i | ((u32)ptr[i] << 16); |
59 | u32 value = 0; | 59 | u32 value = 0; |
60 | int retries; | 60 | int retries2; |
61 | 61 | ||
62 | for (retries = 0; retries < 5; retries++) { | 62 | for (retries2 = 0; retries2 < 5; retries2++) { |
63 | cx18_av_write4(cx, CXADEC_DL_CTL, dl_control); | 63 | cx18_av_write4(cx, CXADEC_DL_CTL, dl_control); |
64 | udelay(10); | 64 | udelay(10); |
65 | value = cx18_av_read4(cx, CXADEC_DL_CTL); | 65 | value = cx18_av_read4(cx, CXADEC_DL_CTL); |
@@ -69,18 +69,18 @@ int cx18_av_loadfw(struct cx18 *cx) | |||
69 | the address. We can only write the lower | 69 | the address. We can only write the lower |
70 | address byte of the address. */ | 70 | address byte of the address. */ |
71 | if ((value & 0x3F00) != (dl_control & 0x3F00)) { | 71 | if ((value & 0x3F00) != (dl_control & 0x3F00)) { |
72 | retries = 5; | 72 | retries2 = 5; |
73 | break; | 73 | break; |
74 | } | 74 | } |
75 | } | 75 | } |
76 | if (retries >= 5) | 76 | if (retries2 >= 5) |
77 | break; | 77 | break; |
78 | } | 78 | } |
79 | if (i == size) | 79 | if (i == size) |
80 | break; | 80 | break; |
81 | retries++; | 81 | retries1++; |
82 | } | 82 | } |
83 | if (retries >= 5) { | 83 | if (retries1 >= 5) { |
84 | CX18_ERR("unable to load firmware %s\n", FWFILE); | 84 | CX18_ERR("unable to load firmware %s\n", FWFILE); |
85 | release_firmware(fw); | 85 | release_firmware(fw); |
86 | return -EIO; | 86 | return -EIO; |
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c index 22434aadde31..bd18afebbf86 100644 --- a/drivers/media/video/cx18/cx18-driver.c +++ b/drivers/media/video/cx18/cx18-driver.c | |||
@@ -74,9 +74,9 @@ static int radio[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1, | |||
74 | -1, -1, -1, -1, -1, -1, -1, -1, | 74 | -1, -1, -1, -1, -1, -1, -1, -1, |
75 | -1, -1, -1, -1, -1, -1, -1, -1 }; | 75 | -1, -1, -1, -1, -1, -1, -1, -1 }; |
76 | 76 | ||
77 | static int cardtype_c = 1; | 77 | static unsigned cardtype_c = 1; |
78 | static int tuner_c = 1; | 78 | static unsigned tuner_c = 1; |
79 | static int radio_c = 1; | 79 | static unsigned radio_c = 1; |
80 | static char pal[] = "--"; | 80 | static char pal[] = "--"; |
81 | static char secam[] = "--"; | 81 | static char secam[] = "--"; |
82 | static char ntsc[] = "-"; | 82 | static char ntsc[] = "-"; |
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c index cae38985b131..1e420a804fc9 100644 --- a/drivers/media/video/cx18/cx18-dvb.c +++ b/drivers/media/video/cx18/cx18-dvb.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * cx18 functions for DVB support | 2 | * cx18 functions for DVB support |
3 | * | 3 | * |
4 | * Copyright (c) 2008 Steven Toth <stoth@hauppauge.com> | 4 | * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
diff --git a/drivers/media/video/cx18/cx18-dvb.h b/drivers/media/video/cx18/cx18-dvb.h index d6a6ccda79a9..bf8d8f6f5455 100644 --- a/drivers/media/video/cx18/cx18-dvb.h +++ b/drivers/media/video/cx18/cx18-dvb.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * cx18 functions for DVB support | 2 | * cx18 functions for DVB support |
3 | * | 3 | * |
4 | * Copyright (c) 2008 Steven Toth <stoth@hauppauge.com> | 4 | * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
diff --git a/drivers/media/video/cx18/cx18-irq.c b/drivers/media/video/cx18/cx18-irq.c index 25114a5cbd57..ab218315c84b 100644 --- a/drivers/media/video/cx18/cx18-irq.c +++ b/drivers/media/video/cx18/cx18-irq.c | |||
@@ -61,7 +61,7 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_mailbox *mb) | |||
61 | CX18_WARN("Ack struct = %d for %s\n", | 61 | CX18_WARN("Ack struct = %d for %s\n", |
62 | mb->args[2], s->name); | 62 | mb->args[2], s->name); |
63 | id = read_enc(off); | 63 | id = read_enc(off); |
64 | buf = cx18_queue_find_buf(s, id, read_enc(off + 4)); | 64 | buf = cx18_queue_get_buf_irq(s, id, read_enc(off + 4)); |
65 | CX18_DEBUG_HI_DMA("DMA DONE for %s (buffer %d)\n", s->name, id); | 65 | CX18_DEBUG_HI_DMA("DMA DONE for %s (buffer %d)\n", s->name, id); |
66 | if (buf) { | 66 | if (buf) { |
67 | cx18_buf_sync_for_cpu(s, buf); | 67 | cx18_buf_sync_for_cpu(s, buf); |
diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c index 6990b77c6200..dbe792ac3001 100644 --- a/drivers/media/video/cx18/cx18-queue.c +++ b/drivers/media/video/cx18/cx18-queue.c | |||
@@ -78,12 +78,13 @@ struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q) | |||
78 | return buf; | 78 | return buf; |
79 | } | 79 | } |
80 | 80 | ||
81 | struct cx18_buffer *cx18_queue_find_buf(struct cx18_stream *s, u32 id, | 81 | struct cx18_buffer *cx18_queue_get_buf_irq(struct cx18_stream *s, u32 id, |
82 | u32 bytesused) | 82 | u32 bytesused) |
83 | { | 83 | { |
84 | struct cx18 *cx = s->cx; | 84 | struct cx18 *cx = s->cx; |
85 | struct list_head *p; | 85 | struct list_head *p; |
86 | 86 | ||
87 | spin_lock(&s->qlock); | ||
87 | list_for_each(p, &s->q_free.list) { | 88 | list_for_each(p, &s->q_free.list) { |
88 | struct cx18_buffer *buf = | 89 | struct cx18_buffer *buf = |
89 | list_entry(p, struct cx18_buffer, list); | 90 | list_entry(p, struct cx18_buffer, list); |
@@ -92,114 +93,48 @@ struct cx18_buffer *cx18_queue_find_buf(struct cx18_stream *s, u32 id, | |||
92 | continue; | 93 | continue; |
93 | buf->bytesused = bytesused; | 94 | buf->bytesused = bytesused; |
94 | /* the transport buffers are handled differently, | 95 | /* the transport buffers are handled differently, |
95 | so there is no need to move them to the full queue */ | 96 | they are not moved to the full queue */ |
96 | if (s->type == CX18_ENC_STREAM_TYPE_TS) | 97 | if (s->type != CX18_ENC_STREAM_TYPE_TS) { |
97 | return buf; | 98 | s->q_free.buffers--; |
98 | s->q_free.buffers--; | 99 | s->q_free.length -= s->buf_size; |
99 | s->q_free.length -= s->buf_size; | 100 | s->q_full.buffers++; |
100 | s->q_full.buffers++; | 101 | s->q_full.length += s->buf_size; |
101 | s->q_full.length += s->buf_size; | 102 | s->q_full.bytesused += buf->bytesused; |
102 | s->q_full.bytesused += buf->bytesused; | 103 | list_move_tail(&buf->list, &s->q_full.list); |
103 | list_move_tail(&buf->list, &s->q_full.list); | 104 | } |
105 | spin_unlock(&s->qlock); | ||
104 | return buf; | 106 | return buf; |
105 | } | 107 | } |
108 | spin_unlock(&s->qlock); | ||
106 | CX18_ERR("Cannot find buffer %d for stream %s\n", id, s->name); | 109 | CX18_ERR("Cannot find buffer %d for stream %s\n", id, s->name); |
107 | return NULL; | 110 | return NULL; |
108 | } | 111 | } |
109 | 112 | ||
110 | static void cx18_queue_move_buf(struct cx18_stream *s, struct cx18_queue *from, | 113 | /* Move all buffers of a queue to q_free, while flushing the buffers */ |
111 | struct cx18_queue *to, int clear, int full) | 114 | static void cx18_queue_flush(struct cx18_stream *s, struct cx18_queue *q) |
112 | { | ||
113 | struct cx18_buffer *buf = | ||
114 | list_entry(from->list.next, struct cx18_buffer, list); | ||
115 | |||
116 | list_move_tail(from->list.next, &to->list); | ||
117 | from->buffers--; | ||
118 | from->length -= s->buf_size; | ||
119 | from->bytesused -= buf->bytesused - buf->readpos; | ||
120 | /* special handling for q_free */ | ||
121 | if (clear) | ||
122 | buf->bytesused = buf->readpos = buf->b_flags = 0; | ||
123 | else if (full) { | ||
124 | /* special handling for stolen buffers, assume | ||
125 | all bytes are used. */ | ||
126 | buf->bytesused = s->buf_size; | ||
127 | buf->readpos = buf->b_flags = 0; | ||
128 | } | ||
129 | to->buffers++; | ||
130 | to->length += s->buf_size; | ||
131 | to->bytesused += buf->bytesused - buf->readpos; | ||
132 | } | ||
133 | |||
134 | /* Move 'needed_bytes' worth of buffers from queue 'from' into queue 'to'. | ||
135 | If 'needed_bytes' == 0, then move all buffers from 'from' into 'to'. | ||
136 | If 'steal' != NULL, then buffers may also taken from that queue if | ||
137 | needed. | ||
138 | |||
139 | The buffer is automatically cleared if it goes to the free queue. It is | ||
140 | also cleared if buffers need to be taken from the 'steal' queue and | ||
141 | the 'from' queue is the free queue. | ||
142 | |||
143 | When 'from' is q_free, then needed_bytes is compared to the total | ||
144 | available buffer length, otherwise needed_bytes is compared to the | ||
145 | bytesused value. For the 'steal' queue the total available buffer | ||
146 | length is always used. | ||
147 | |||
148 | -ENOMEM is returned if the buffers could not be obtained, 0 if all | ||
149 | buffers where obtained from the 'from' list and if non-zero then | ||
150 | the number of stolen buffers is returned. */ | ||
151 | static int cx18_queue_move(struct cx18_stream *s, struct cx18_queue *from, | ||
152 | struct cx18_queue *steal, struct cx18_queue *to, | ||
153 | int needed_bytes) | ||
154 | { | 115 | { |
155 | unsigned long flags; | 116 | unsigned long flags; |
156 | int rc = 0; | 117 | struct cx18_buffer *buf; |
157 | int from_free = from == &s->q_free; | ||
158 | int to_free = to == &s->q_free; | ||
159 | int bytes_available; | ||
160 | |||
161 | spin_lock_irqsave(&s->qlock, flags); | ||
162 | if (needed_bytes == 0) { | ||
163 | from_free = 1; | ||
164 | needed_bytes = from->length; | ||
165 | } | ||
166 | |||
167 | bytes_available = from_free ? from->length : from->bytesused; | ||
168 | bytes_available += steal ? steal->length : 0; | ||
169 | 118 | ||
170 | if (bytes_available < needed_bytes) { | 119 | if (q == &s->q_free) |
171 | spin_unlock_irqrestore(&s->qlock, flags); | 120 | return; |
172 | return -ENOMEM; | ||
173 | } | ||
174 | if (from_free) { | ||
175 | u32 old_length = to->length; | ||
176 | 121 | ||
177 | while (to->length - old_length < needed_bytes) { | 122 | spin_lock_irqsave(&s->qlock, flags); |
178 | if (list_empty(&from->list)) | 123 | while (!list_empty(&q->list)) { |
179 | from = steal; | 124 | buf = list_entry(q->list.next, struct cx18_buffer, list); |
180 | if (from == steal) | 125 | list_move_tail(q->list.next, &s->q_free.list); |
181 | rc++; /* keep track of 'stolen' buffers */ | 126 | buf->bytesused = buf->readpos = buf->b_flags = 0; |
182 | cx18_queue_move_buf(s, from, to, 1, 0); | 127 | s->q_free.buffers++; |
183 | } | 128 | s->q_free.length += s->buf_size; |
184 | } else { | ||
185 | u32 old_bytesused = to->bytesused; | ||
186 | |||
187 | while (to->bytesused - old_bytesused < needed_bytes) { | ||
188 | if (list_empty(&from->list)) | ||
189 | from = steal; | ||
190 | if (from == steal) | ||
191 | rc++; /* keep track of 'stolen' buffers */ | ||
192 | cx18_queue_move_buf(s, from, to, to_free, rc); | ||
193 | } | ||
194 | } | 129 | } |
130 | cx18_queue_init(q); | ||
195 | spin_unlock_irqrestore(&s->qlock, flags); | 131 | spin_unlock_irqrestore(&s->qlock, flags); |
196 | return rc; | ||
197 | } | 132 | } |
198 | 133 | ||
199 | void cx18_flush_queues(struct cx18_stream *s) | 134 | void cx18_flush_queues(struct cx18_stream *s) |
200 | { | 135 | { |
201 | cx18_queue_move(s, &s->q_io, NULL, &s->q_free, 0); | 136 | cx18_queue_flush(s, &s->q_io); |
202 | cx18_queue_move(s, &s->q_full, NULL, &s->q_free, 0); | 137 | cx18_queue_flush(s, &s->q_full); |
203 | } | 138 | } |
204 | 139 | ||
205 | int cx18_stream_alloc(struct cx18_stream *s) | 140 | int cx18_stream_alloc(struct cx18_stream *s) |
@@ -214,10 +149,10 @@ int cx18_stream_alloc(struct cx18_stream *s) | |||
214 | s->name, s->buffers, s->buf_size, | 149 | s->name, s->buffers, s->buf_size, |
215 | s->buffers * s->buf_size / 1024); | 150 | s->buffers * s->buf_size / 1024); |
216 | 151 | ||
217 | if (((char *)&cx->scb->cpu_mdl[cx->mdl_offset + s->buffers] - | 152 | if (((char __iomem *)&cx->scb->cpu_mdl[cx->mdl_offset + s->buffers] - |
218 | (char *)cx->scb) > SCB_RESERVED_SIZE) { | 153 | (char __iomem *)cx->scb) > SCB_RESERVED_SIZE) { |
219 | unsigned bufsz = (((char *)cx->scb) + SCB_RESERVED_SIZE - | 154 | unsigned bufsz = (((char __iomem *)cx->scb) + SCB_RESERVED_SIZE - |
220 | ((char *)cx->scb->cpu_mdl)); | 155 | ((char __iomem *)cx->scb->cpu_mdl)); |
221 | 156 | ||
222 | CX18_ERR("Too many buffers, cannot fit in SCB area\n"); | 157 | CX18_ERR("Too many buffers, cannot fit in SCB area\n"); |
223 | CX18_ERR("Max buffers = %zd\n", | 158 | CX18_ERR("Max buffers = %zd\n", |
diff --git a/drivers/media/video/cx18/cx18-queue.h b/drivers/media/video/cx18/cx18-queue.h index 91423b9863a4..7f93bb13c09f 100644 --- a/drivers/media/video/cx18/cx18-queue.h +++ b/drivers/media/video/cx18/cx18-queue.h | |||
@@ -46,7 +46,7 @@ void cx18_queue_init(struct cx18_queue *q); | |||
46 | void cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf, | 46 | void cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf, |
47 | struct cx18_queue *q); | 47 | struct cx18_queue *q); |
48 | struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q); | 48 | struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q); |
49 | struct cx18_buffer *cx18_queue_find_buf(struct cx18_stream *s, u32 id, | 49 | struct cx18_buffer *cx18_queue_get_buf_irq(struct cx18_stream *s, u32 id, |
50 | u32 bytesused); | 50 | u32 bytesused); |
51 | void cx18_flush_queues(struct cx18_stream *s); | 51 | void cx18_flush_queues(struct cx18_stream *s); |
52 | 52 | ||