4 * kernel ISO transmission/reception
6 * Copyright (C) 2002 Maas Digital LLC
8 * This code is licensed under the GPL. See the file COPYING in the root
9 * directory of the kernel sources for details.
12 #include <linux/pci.h>
13 #include <linux/sched.h>
14 #include <linux/slab.h>
20 * hpsb_iso_stop - stop DMA
22 void hpsb_iso_stop(struct hpsb_iso
*iso
)
24 if (!(iso
->flags
& HPSB_ISO_DRIVER_STARTED
))
27 iso
->host
->driver
->isoctl(iso
, iso
->type
== HPSB_ISO_XMIT
?
28 XMIT_STOP
: RECV_STOP
, 0);
29 iso
->flags
&= ~HPSB_ISO_DRIVER_STARTED
;
33 * hpsb_iso_shutdown - deallocate buffer and DMA context
35 void hpsb_iso_shutdown(struct hpsb_iso
*iso
)
37 if (iso
->flags
& HPSB_ISO_DRIVER_INIT
) {
39 iso
->host
->driver
->isoctl(iso
, iso
->type
== HPSB_ISO_XMIT
?
40 XMIT_SHUTDOWN
: RECV_SHUTDOWN
, 0);
41 iso
->flags
&= ~HPSB_ISO_DRIVER_INIT
;
44 dma_region_free(&iso
->data_buf
);
48 static struct hpsb_iso
*hpsb_iso_common_init(struct hpsb_host
*host
,
49 enum hpsb_iso_type type
,
50 unsigned int data_buf_size
,
51 unsigned int buf_packets
,
52 int channel
, int dma_mode
,
54 void (*callback
) (struct hpsb_iso
60 /* make sure driver supports the ISO API */
61 if (!host
->driver
->isoctl
) {
63 "ieee1394: host driver '%s' does not support the rawiso API\n",
68 /* sanitize parameters */
73 if ((dma_mode
< HPSB_ISO_DMA_DEFAULT
)
74 || (dma_mode
> HPSB_ISO_DMA_PACKET_PER_BUFFER
))
75 dma_mode
= HPSB_ISO_DMA_DEFAULT
;
77 if ((irq_interval
< 0) || (irq_interval
> buf_packets
/ 4))
78 irq_interval
= buf_packets
/ 4;
79 if (irq_interval
== 0) /* really interrupt for each packet */
82 if (channel
< -1 || channel
>= 64)
85 /* channel = -1 is OK for multi-channel recv but not for xmit */
86 if (type
== HPSB_ISO_XMIT
&& channel
< 0)
89 /* allocate and write the struct hpsb_iso */
92 kmalloc(sizeof(*iso
) +
93 buf_packets
* sizeof(struct hpsb_iso_packet_info
),
98 iso
->infos
= (struct hpsb_iso_packet_info
*)(iso
+ 1);
102 iso
->hostdata
= NULL
;
103 iso
->callback
= callback
;
104 init_waitqueue_head(&iso
->waitq
);
105 iso
->channel
= channel
;
106 iso
->irq_interval
= irq_interval
;
107 iso
->dma_mode
= dma_mode
;
108 dma_region_init(&iso
->data_buf
);
109 iso
->buf_size
= PAGE_ALIGN(data_buf_size
);
110 iso
->buf_packets
= buf_packets
;
112 iso
->first_packet
= 0;
113 spin_lock_init(&iso
->lock
);
115 if (iso
->type
== HPSB_ISO_XMIT
) {
116 iso
->n_ready_packets
= iso
->buf_packets
;
117 dma_direction
= PCI_DMA_TODEVICE
;
119 iso
->n_ready_packets
= 0;
120 dma_direction
= PCI_DMA_FROMDEVICE
;
123 atomic_set(&iso
->overflows
, 0);
124 iso
->bytes_discarded
= 0;
128 /* allocate the packet buffer */
130 (&iso
->data_buf
, iso
->buf_size
, host
->pdev
, dma_direction
))
136 hpsb_iso_shutdown(iso
);
141 * hpsb_iso_n_ready - returns number of packets ready to send or receive
143 int hpsb_iso_n_ready(struct hpsb_iso
*iso
)
148 spin_lock_irqsave(&iso
->lock
, flags
);
149 val
= iso
->n_ready_packets
;
150 spin_unlock_irqrestore(&iso
->lock
, flags
);
156 * hpsb_iso_xmit_init - allocate the buffer and DMA context
158 struct hpsb_iso
*hpsb_iso_xmit_init(struct hpsb_host
*host
,
159 unsigned int data_buf_size
,
160 unsigned int buf_packets
,
164 void (*callback
) (struct hpsb_iso
*))
166 struct hpsb_iso
*iso
= hpsb_iso_common_init(host
, HPSB_ISO_XMIT
,
167 data_buf_size
, buf_packets
,
169 HPSB_ISO_DMA_DEFAULT
,
170 irq_interval
, callback
);
176 /* tell the driver to start working */
177 if (host
->driver
->isoctl(iso
, XMIT_INIT
, 0))
180 iso
->flags
|= HPSB_ISO_DRIVER_INIT
;
184 hpsb_iso_shutdown(iso
);
189 * hpsb_iso_recv_init - allocate the buffer and DMA context
191 * Note, if channel = -1, multi-channel receive is enabled.
193 struct hpsb_iso
*hpsb_iso_recv_init(struct hpsb_host
*host
,
194 unsigned int data_buf_size
,
195 unsigned int buf_packets
,
199 void (*callback
) (struct hpsb_iso
*))
201 struct hpsb_iso
*iso
= hpsb_iso_common_init(host
, HPSB_ISO_RECV
,
202 data_buf_size
, buf_packets
,
204 irq_interval
, callback
);
208 /* tell the driver to start working */
209 if (host
->driver
->isoctl(iso
, RECV_INIT
, 0))
212 iso
->flags
|= HPSB_ISO_DRIVER_INIT
;
216 hpsb_iso_shutdown(iso
);
221 * hpsb_iso_recv_listen_channel
225 int hpsb_iso_recv_listen_channel(struct hpsb_iso
*iso
, unsigned char channel
)
227 if (iso
->type
!= HPSB_ISO_RECV
|| iso
->channel
!= -1 || channel
>= 64)
229 return iso
->host
->driver
->isoctl(iso
, RECV_LISTEN_CHANNEL
, channel
);
233 * hpsb_iso_recv_unlisten_channel
237 int hpsb_iso_recv_unlisten_channel(struct hpsb_iso
*iso
, unsigned char channel
)
239 if (iso
->type
!= HPSB_ISO_RECV
|| iso
->channel
!= -1 || channel
>= 64)
241 return iso
->host
->driver
->isoctl(iso
, RECV_UNLISTEN_CHANNEL
, channel
);
245 * hpsb_iso_recv_set_channel_mask
249 int hpsb_iso_recv_set_channel_mask(struct hpsb_iso
*iso
, u64 mask
)
251 if (iso
->type
!= HPSB_ISO_RECV
|| iso
->channel
!= -1)
253 return iso
->host
->driver
->isoctl(iso
, RECV_SET_CHANNEL_MASK
,
254 (unsigned long)&mask
);
258 * hpsb_iso_recv_flush - check for arrival of new packets
260 * check for arrival of new packets immediately (even if irq_interval
261 * has not yet been reached)
263 int hpsb_iso_recv_flush(struct hpsb_iso
*iso
)
265 if (iso
->type
!= HPSB_ISO_RECV
)
267 return iso
->host
->driver
->isoctl(iso
, RECV_FLUSH
, 0);
270 static int do_iso_xmit_start(struct hpsb_iso
*iso
, int cycle
)
272 int retval
= iso
->host
->driver
->isoctl(iso
, XMIT_START
, cycle
);
276 iso
->flags
|= HPSB_ISO_DRIVER_STARTED
;
281 * hpsb_iso_xmit_start - start DMA
283 int hpsb_iso_xmit_start(struct hpsb_iso
*iso
, int cycle
, int prebuffer
)
285 if (iso
->type
!= HPSB_ISO_XMIT
)
288 if (iso
->flags
& HPSB_ISO_DRIVER_STARTED
)
293 else if (cycle
>= 8000)
296 iso
->xmit_cycle
= cycle
;
299 prebuffer
= iso
->buf_packets
- 1;
300 else if (prebuffer
== 0)
303 if (prebuffer
>= iso
->buf_packets
)
304 prebuffer
= iso
->buf_packets
- 1;
306 iso
->prebuffer
= prebuffer
;
308 /* remember the starting cycle; DMA will commence from xmit_queue_packets()
309 once enough packets have been buffered */
310 iso
->start_cycle
= cycle
;
316 * hpsb_iso_recv_start - start DMA
318 int hpsb_iso_recv_start(struct hpsb_iso
*iso
, int cycle
, int tag_mask
, int sync
)
323 if (iso
->type
!= HPSB_ISO_RECV
)
326 if (iso
->flags
& HPSB_ISO_DRIVER_STARTED
)
331 else if (cycle
>= 8000)
334 isoctl_args
[0] = cycle
;
339 isoctl_args
[1] = tag_mask
;
341 isoctl_args
[2] = sync
;
344 iso
->host
->driver
->isoctl(iso
, RECV_START
,
345 (unsigned long)&isoctl_args
[0]);
349 iso
->flags
|= HPSB_ISO_DRIVER_STARTED
;
353 /* check to make sure the user has not supplied bogus values of offset/len
354 * that would cause the kernel to access memory outside the buffer */
355 static int hpsb_iso_check_offset_len(struct hpsb_iso
*iso
,
356 unsigned int offset
, unsigned short len
,
357 unsigned int *out_offset
,
358 unsigned short *out_len
)
360 if (offset
>= iso
->buf_size
)
363 /* make sure the packet does not go beyond the end of the buffer */
364 if (offset
+ len
> iso
->buf_size
)
367 /* check for wrap-around */
368 if (offset
+ len
< offset
)
371 /* now we can trust 'offset' and 'length' */
372 *out_offset
= offset
;
379 * hpsb_iso_xmit_queue_packet - queue a packet for transmission.
381 * @offset is relative to the beginning of the DMA buffer, where the packet's
382 * data payload should already have been placed.
384 int hpsb_iso_xmit_queue_packet(struct hpsb_iso
*iso
, u32 offset
, u16 len
,
387 struct hpsb_iso_packet_info
*info
;
391 if (iso
->type
!= HPSB_ISO_XMIT
)
394 /* is there space in the buffer? */
395 if (iso
->n_ready_packets
<= 0) {
399 info
= &iso
->infos
[iso
->first_packet
];
401 /* check for bogus offset/length */
402 if (hpsb_iso_check_offset_len
403 (iso
, offset
, len
, &info
->offset
, &info
->len
))
409 spin_lock_irqsave(&iso
->lock
, flags
);
411 rv
= iso
->host
->driver
->isoctl(iso
, XMIT_QUEUE
, (unsigned long)info
);
415 /* increment cursors */
416 iso
->first_packet
= (iso
->first_packet
+ 1) % iso
->buf_packets
;
417 iso
->xmit_cycle
= (iso
->xmit_cycle
+ 1) % 8000;
418 iso
->n_ready_packets
--;
420 if (iso
->prebuffer
!= 0) {
422 if (iso
->prebuffer
<= 0) {
424 rv
= do_iso_xmit_start(iso
, iso
->start_cycle
);
429 spin_unlock_irqrestore(&iso
->lock
, flags
);
434 * hpsb_iso_xmit_sync - wait until all queued packets have been transmitted
436 int hpsb_iso_xmit_sync(struct hpsb_iso
*iso
)
438 if (iso
->type
!= HPSB_ISO_XMIT
)
441 return wait_event_interruptible(iso
->waitq
,
442 hpsb_iso_n_ready(iso
) ==
447 * hpsb_iso_packet_sent
449 * Available to low-level drivers.
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.
455 void hpsb_iso_packet_sent(struct hpsb_iso
*iso
, int cycle
, int error
)
458 spin_lock_irqsave(&iso
->lock
, flags
);
460 /* predict the cycle of the next packet to be queued */
462 /* jump ahead by the number of packets that are already buffered */
463 cycle
+= iso
->buf_packets
- iso
->n_ready_packets
;
466 iso
->xmit_cycle
= cycle
;
467 iso
->n_ready_packets
++;
468 iso
->pkt_dma
= (iso
->pkt_dma
+ 1) % iso
->buf_packets
;
470 if (iso
->n_ready_packets
== iso
->buf_packets
|| error
!= 0) {
471 /* the buffer has run empty! */
472 atomic_inc(&iso
->overflows
);
475 spin_unlock_irqrestore(&iso
->lock
, flags
);
479 * hpsb_iso_packet_received
481 * Available to low-level drivers.
483 * Call after a packet has been received (interrupt context is OK).
485 void hpsb_iso_packet_received(struct hpsb_iso
*iso
, u32 offset
, u16 len
,
486 u16 total_len
, u16 cycle
, u8 channel
, u8 tag
,
490 spin_lock_irqsave(&iso
->lock
, flags
);
492 if (iso
->n_ready_packets
== iso
->buf_packets
) {
494 atomic_inc(&iso
->overflows
);
495 /* Record size of this discarded packet */
496 iso
->bytes_discarded
+= total_len
;
498 struct hpsb_iso_packet_info
*info
= &iso
->infos
[iso
->pkt_dma
];
499 info
->offset
= offset
;
501 info
->total_len
= total_len
;
503 info
->channel
= channel
;
507 iso
->pkt_dma
= (iso
->pkt_dma
+ 1) % iso
->buf_packets
;
508 iso
->n_ready_packets
++;
511 spin_unlock_irqrestore(&iso
->lock
, flags
);
515 * hpsb_iso_recv_release_packets - release packets, reuse buffer
517 * @n_packets have been read out of the buffer, re-use the buffer space
519 int hpsb_iso_recv_release_packets(struct hpsb_iso
*iso
, unsigned int n_packets
)
525 if (iso
->type
!= HPSB_ISO_RECV
)
528 spin_lock_irqsave(&iso
->lock
, flags
);
529 for (i
= 0; i
< n_packets
; i
++) {
530 rv
= iso
->host
->driver
->isoctl(iso
, RECV_RELEASE
,
531 (unsigned long)&iso
->infos
[iso
->
536 iso
->first_packet
= (iso
->first_packet
+ 1) % iso
->buf_packets
;
537 iso
->n_ready_packets
--;
539 /* release memory from packets discarded when queue was full */
540 if (iso
->n_ready_packets
== 0) { /* Release only after all prior packets handled */
541 if (iso
->bytes_discarded
!= 0) {
542 struct hpsb_iso_packet_info inf
;
543 inf
.total_len
= iso
->bytes_discarded
;
544 iso
->host
->driver
->isoctl(iso
, RECV_RELEASE
,
545 (unsigned long)&inf
);
546 iso
->bytes_discarded
= 0;
550 spin_unlock_irqrestore(&iso
->lock
, flags
);
557 * Available to low-level drivers.
559 * Call to wake waiting processes after buffer space has opened up.
561 void hpsb_iso_wake(struct hpsb_iso
*iso
)
563 wake_up_interruptible(&iso
->waitq
);