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