diff options
Diffstat (limited to 'drivers/ieee1394/iso.c')
-rw-r--r-- | drivers/ieee1394/iso.c | 84 |
1 files changed, 82 insertions, 2 deletions
diff --git a/drivers/ieee1394/iso.c b/drivers/ieee1394/iso.c index c6227e51136d..f223f347d180 100644 --- a/drivers/ieee1394/iso.c +++ b/drivers/ieee1394/iso.c | |||
@@ -15,6 +15,9 @@ | |||
15 | #include "hosts.h" | 15 | #include "hosts.h" |
16 | #include "iso.h" | 16 | #include "iso.h" |
17 | 17 | ||
18 | /** | ||
19 | * hpsb_iso_stop - stop DMA | ||
20 | */ | ||
18 | void hpsb_iso_stop(struct hpsb_iso *iso) | 21 | void hpsb_iso_stop(struct hpsb_iso *iso) |
19 | { | 22 | { |
20 | if (!(iso->flags & HPSB_ISO_DRIVER_STARTED)) | 23 | if (!(iso->flags & HPSB_ISO_DRIVER_STARTED)) |
@@ -25,6 +28,9 @@ void hpsb_iso_stop(struct hpsb_iso *iso) | |||
25 | iso->flags &= ~HPSB_ISO_DRIVER_STARTED; | 28 | iso->flags &= ~HPSB_ISO_DRIVER_STARTED; |
26 | } | 29 | } |
27 | 30 | ||
31 | /** | ||
32 | * hpsb_iso_shutdown - deallocate buffer and DMA context | ||
33 | */ | ||
28 | void hpsb_iso_shutdown(struct hpsb_iso *iso) | 34 | void hpsb_iso_shutdown(struct hpsb_iso *iso) |
29 | { | 35 | { |
30 | if (iso->flags & HPSB_ISO_DRIVER_INIT) { | 36 | if (iso->flags & HPSB_ISO_DRIVER_INIT) { |
@@ -130,6 +136,9 @@ static struct hpsb_iso *hpsb_iso_common_init(struct hpsb_host *host, | |||
130 | return NULL; | 136 | return NULL; |
131 | } | 137 | } |
132 | 138 | ||
139 | /** | ||
140 | * hpsb_iso_n_ready - returns number of packets ready to send or receive | ||
141 | */ | ||
133 | int hpsb_iso_n_ready(struct hpsb_iso *iso) | 142 | int hpsb_iso_n_ready(struct hpsb_iso *iso) |
134 | { | 143 | { |
135 | unsigned long flags; | 144 | unsigned long flags; |
@@ -142,6 +151,9 @@ int hpsb_iso_n_ready(struct hpsb_iso *iso) | |||
142 | return val; | 151 | return val; |
143 | } | 152 | } |
144 | 153 | ||
154 | /** | ||
155 | * hpsb_iso_xmit_init - allocate the buffer and DMA context | ||
156 | */ | ||
145 | struct hpsb_iso *hpsb_iso_xmit_init(struct hpsb_host *host, | 157 | struct hpsb_iso *hpsb_iso_xmit_init(struct hpsb_host *host, |
146 | unsigned int data_buf_size, | 158 | unsigned int data_buf_size, |
147 | unsigned int buf_packets, | 159 | unsigned int buf_packets, |
@@ -172,6 +184,11 @@ struct hpsb_iso *hpsb_iso_xmit_init(struct hpsb_host *host, | |||
172 | return NULL; | 184 | return NULL; |
173 | } | 185 | } |
174 | 186 | ||
187 | /** | ||
188 | * hpsb_iso_recv_init - allocate the buffer and DMA context | ||
189 | * | ||
190 | * Note, if channel = -1, multi-channel receive is enabled. | ||
191 | */ | ||
175 | struct hpsb_iso *hpsb_iso_recv_init(struct hpsb_host *host, | 192 | struct hpsb_iso *hpsb_iso_recv_init(struct hpsb_host *host, |
176 | unsigned int data_buf_size, | 193 | unsigned int data_buf_size, |
177 | unsigned int buf_packets, | 194 | unsigned int buf_packets, |
@@ -199,6 +216,11 @@ struct hpsb_iso *hpsb_iso_recv_init(struct hpsb_host *host, | |||
199 | return NULL; | 216 | return NULL; |
200 | } | 217 | } |
201 | 218 | ||
219 | /** | ||
220 | * hpsb_iso_recv_listen_channel | ||
221 | * | ||
222 | * multi-channel only | ||
223 | */ | ||
202 | int hpsb_iso_recv_listen_channel(struct hpsb_iso *iso, unsigned char channel) | 224 | int hpsb_iso_recv_listen_channel(struct hpsb_iso *iso, unsigned char channel) |
203 | { | 225 | { |
204 | if (iso->type != HPSB_ISO_RECV || iso->channel != -1 || channel >= 64) | 226 | if (iso->type != HPSB_ISO_RECV || iso->channel != -1 || channel >= 64) |
@@ -206,6 +228,11 @@ int hpsb_iso_recv_listen_channel(struct hpsb_iso *iso, unsigned char channel) | |||
206 | return iso->host->driver->isoctl(iso, RECV_LISTEN_CHANNEL, channel); | 228 | return iso->host->driver->isoctl(iso, RECV_LISTEN_CHANNEL, channel); |
207 | } | 229 | } |
208 | 230 | ||
231 | /** | ||
232 | * hpsb_iso_recv_unlisten_channel | ||
233 | * | ||
234 | * multi-channel only | ||
235 | */ | ||
209 | int hpsb_iso_recv_unlisten_channel(struct hpsb_iso *iso, unsigned char channel) | 236 | int hpsb_iso_recv_unlisten_channel(struct hpsb_iso *iso, unsigned char channel) |
210 | { | 237 | { |
211 | if (iso->type != HPSB_ISO_RECV || iso->channel != -1 || channel >= 64) | 238 | if (iso->type != HPSB_ISO_RECV || iso->channel != -1 || channel >= 64) |
@@ -213,6 +240,11 @@ int hpsb_iso_recv_unlisten_channel(struct hpsb_iso *iso, unsigned char channel) | |||
213 | return iso->host->driver->isoctl(iso, RECV_UNLISTEN_CHANNEL, channel); | 240 | return iso->host->driver->isoctl(iso, RECV_UNLISTEN_CHANNEL, channel); |
214 | } | 241 | } |
215 | 242 | ||
243 | /** | ||
244 | * hpsb_iso_recv_set_channel_mask | ||
245 | * | ||
246 | * multi-channel only | ||
247 | */ | ||
216 | int hpsb_iso_recv_set_channel_mask(struct hpsb_iso *iso, u64 mask) | 248 | int hpsb_iso_recv_set_channel_mask(struct hpsb_iso *iso, u64 mask) |
217 | { | 249 | { |
218 | if (iso->type != HPSB_ISO_RECV || iso->channel != -1) | 250 | if (iso->type != HPSB_ISO_RECV || iso->channel != -1) |
@@ -221,6 +253,12 @@ int hpsb_iso_recv_set_channel_mask(struct hpsb_iso *iso, u64 mask) | |||
221 | (unsigned long)&mask); | 253 | (unsigned long)&mask); |
222 | } | 254 | } |
223 | 255 | ||
256 | /** | ||
257 | * hpsb_iso_recv_flush - check for arrival of new packets | ||
258 | * | ||
259 | * check for arrival of new packets immediately (even if irq_interval | ||
260 | * has not yet been reached) | ||
261 | */ | ||
224 | int hpsb_iso_recv_flush(struct hpsb_iso *iso) | 262 | int hpsb_iso_recv_flush(struct hpsb_iso *iso) |
225 | { | 263 | { |
226 | if (iso->type != HPSB_ISO_RECV) | 264 | if (iso->type != HPSB_ISO_RECV) |
@@ -238,6 +276,9 @@ static int do_iso_xmit_start(struct hpsb_iso *iso, int cycle) | |||
238 | return retval; | 276 | return retval; |
239 | } | 277 | } |
240 | 278 | ||
279 | /** | ||
280 | * hpsb_iso_xmit_start - start DMA | ||
281 | */ | ||
241 | int hpsb_iso_xmit_start(struct hpsb_iso *iso, int cycle, int prebuffer) | 282 | int hpsb_iso_xmit_start(struct hpsb_iso *iso, int cycle, int prebuffer) |
242 | { | 283 | { |
243 | if (iso->type != HPSB_ISO_XMIT) | 284 | if (iso->type != HPSB_ISO_XMIT) |
@@ -270,6 +311,9 @@ int hpsb_iso_xmit_start(struct hpsb_iso *iso, int cycle, int prebuffer) | |||
270 | return 0; | 311 | return 0; |
271 | } | 312 | } |
272 | 313 | ||
314 | /** | ||
315 | * hpsb_iso_recv_start - start DMA | ||
316 | */ | ||
273 | int hpsb_iso_recv_start(struct hpsb_iso *iso, int cycle, int tag_mask, int sync) | 317 | int hpsb_iso_recv_start(struct hpsb_iso *iso, int cycle, int tag_mask, int sync) |
274 | { | 318 | { |
275 | int retval = 0; | 319 | int retval = 0; |
@@ -306,8 +350,7 @@ int hpsb_iso_recv_start(struct hpsb_iso *iso, int cycle, int tag_mask, int sync) | |||
306 | } | 350 | } |
307 | 351 | ||
308 | /* check to make sure the user has not supplied bogus values of offset/len | 352 | /* check to make sure the user has not supplied bogus values of offset/len |
309 | that would cause the kernel to access memory outside the buffer */ | 353 | * that would cause the kernel to access memory outside the buffer */ |
310 | |||
311 | static int hpsb_iso_check_offset_len(struct hpsb_iso *iso, | 354 | static int hpsb_iso_check_offset_len(struct hpsb_iso *iso, |
312 | unsigned int offset, unsigned short len, | 355 | unsigned int offset, unsigned short len, |
313 | unsigned int *out_offset, | 356 | unsigned int *out_offset, |
@@ -331,6 +374,12 @@ static int hpsb_iso_check_offset_len(struct hpsb_iso *iso, | |||
331 | return 0; | 374 | return 0; |
332 | } | 375 | } |
333 | 376 | ||
377 | /** | ||
378 | * hpsb_iso_xmit_queue_packet - queue a packet for transmission. | ||
379 | * | ||
380 | * @offset is relative to the beginning of the DMA buffer, where the packet's | ||
381 | * data payload should already have been placed. | ||
382 | */ | ||
334 | int hpsb_iso_xmit_queue_packet(struct hpsb_iso *iso, u32 offset, u16 len, | 383 | int hpsb_iso_xmit_queue_packet(struct hpsb_iso *iso, u32 offset, u16 len, |
335 | u8 tag, u8 sy) | 384 | u8 tag, u8 sy) |
336 | { | 385 | { |
@@ -380,6 +429,9 @@ int hpsb_iso_xmit_queue_packet(struct hpsb_iso *iso, u32 offset, u16 len, | |||
380 | return rv; | 429 | return rv; |
381 | } | 430 | } |
382 | 431 | ||
432 | /** | ||
433 | * hpsb_iso_xmit_sync - wait until all queued packets have been transmitted | ||
434 | */ | ||
383 | int hpsb_iso_xmit_sync(struct hpsb_iso *iso) | 435 | int hpsb_iso_xmit_sync(struct hpsb_iso *iso) |
384 | { | 436 | { |
385 | if (iso->type != HPSB_ISO_XMIT) | 437 | if (iso->type != HPSB_ISO_XMIT) |
@@ -390,6 +442,15 @@ int hpsb_iso_xmit_sync(struct hpsb_iso *iso) | |||
390 | iso->buf_packets); | 442 | iso->buf_packets); |
391 | } | 443 | } |
392 | 444 | ||
445 | /** | ||
446 | * hpsb_iso_packet_sent | ||
447 | * | ||
448 | * Available to low-level drivers. | ||
449 | * | ||
450 | * Call after a packet has been transmitted to the bus (interrupt context is | ||
451 | * OK). @cycle is the _exact_ cycle the packet was sent on. @error should be | ||
452 | * non-zero if some sort of error occurred when sending the packet. | ||
453 | */ | ||
393 | void hpsb_iso_packet_sent(struct hpsb_iso *iso, int cycle, int error) | 454 | void hpsb_iso_packet_sent(struct hpsb_iso *iso, int cycle, int error) |
394 | { | 455 | { |
395 | unsigned long flags; | 456 | unsigned long flags; |
@@ -413,6 +474,13 @@ void hpsb_iso_packet_sent(struct hpsb_iso *iso, int cycle, int error) | |||
413 | spin_unlock_irqrestore(&iso->lock, flags); | 474 | spin_unlock_irqrestore(&iso->lock, flags); |
414 | } | 475 | } |
415 | 476 | ||
477 | /** | ||
478 | * hpsb_iso_packet_received | ||
479 | * | ||
480 | * Available to low-level drivers. | ||
481 | * | ||
482 | * Call after a packet has been received (interrupt context is OK). | ||
483 | */ | ||
416 | void hpsb_iso_packet_received(struct hpsb_iso *iso, u32 offset, u16 len, | 484 | void hpsb_iso_packet_received(struct hpsb_iso *iso, u32 offset, u16 len, |
417 | u16 total_len, u16 cycle, u8 channel, u8 tag, | 485 | u16 total_len, u16 cycle, u8 channel, u8 tag, |
418 | u8 sy) | 486 | u8 sy) |
@@ -442,6 +510,11 @@ void hpsb_iso_packet_received(struct hpsb_iso *iso, u32 offset, u16 len, | |||
442 | spin_unlock_irqrestore(&iso->lock, flags); | 510 | spin_unlock_irqrestore(&iso->lock, flags); |
443 | } | 511 | } |
444 | 512 | ||
513 | /** | ||
514 | * hpsb_iso_recv_release_packets - release packets, reuse buffer | ||
515 | * | ||
516 | * @n_packets have been read out of the buffer, re-use the buffer space | ||
517 | */ | ||
445 | int hpsb_iso_recv_release_packets(struct hpsb_iso *iso, unsigned int n_packets) | 518 | int hpsb_iso_recv_release_packets(struct hpsb_iso *iso, unsigned int n_packets) |
446 | { | 519 | { |
447 | unsigned long flags; | 520 | unsigned long flags; |
@@ -477,6 +550,13 @@ int hpsb_iso_recv_release_packets(struct hpsb_iso *iso, unsigned int n_packets) | |||
477 | return rv; | 550 | return rv; |
478 | } | 551 | } |
479 | 552 | ||
553 | /** | ||
554 | * hpsb_iso_wake | ||
555 | * | ||
556 | * Available to low-level drivers. | ||
557 | * | ||
558 | * Call to wake waiting processes after buffer space has opened up. | ||
559 | */ | ||
480 | void hpsb_iso_wake(struct hpsb_iso *iso) | 560 | void hpsb_iso_wake(struct hpsb_iso *iso) |
481 | { | 561 | { |
482 | wake_up_interruptible(&iso->waitq); | 562 | wake_up_interruptible(&iso->waitq); |