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>
15 #include <linux/slab.h>
21 * hpsb_iso_stop - stop DMA
23 void hpsb_iso_stop(struct hpsb_iso
*iso
)
25 if (!(iso
->flags
& HPSB_ISO_DRIVER_STARTED
))
28 iso
->host
->driver
->isoctl(iso
, iso
->type
== HPSB_ISO_XMIT
?
29 XMIT_STOP
: RECV_STOP
, 0);
30 iso
->flags
&= ~HPSB_ISO_DRIVER_STARTED
;
34 * hpsb_iso_shutdown - deallocate buffer and DMA context
36 void hpsb_iso_shutdown(struct hpsb_iso
*iso
)
38 if (iso
->flags
& HPSB_ISO_DRIVER_INIT
) {
40 iso
->host
->driver
->isoctl(iso
, iso
->type
== HPSB_ISO_XMIT
?
41 XMIT_SHUTDOWN
: RECV_SHUTDOWN
, 0);
42 iso
->flags
&= ~HPSB_ISO_DRIVER_INIT
;
45 dma_region_free(&iso
->data_buf
);
49 static struct hpsb_iso
*hpsb_iso_common_init(struct hpsb_host
*host
,
50 enum hpsb_iso_type type
,
51 unsigned int data_buf_size
,
52 unsigned int buf_packets
,
53 int channel
, int dma_mode
,
55 void (*callback
) (struct hpsb_iso
61 /* make sure driver supports the ISO API */
62 if (!host
->driver
->isoctl
) {
64 "ieee1394: host driver '%s' does not support the rawiso API\n",
69 /* sanitize parameters */
74 if ((dma_mode
< HPSB_ISO_DMA_DEFAULT
)
75 || (dma_mode
> HPSB_ISO_DMA_PACKET_PER_BUFFER
))
76 dma_mode
= HPSB_ISO_DMA_DEFAULT
;
78 if ((irq_interval
< 0) || (irq_interval
> buf_packets
/ 4))
79 irq_interval
= buf_packets
/ 4;
80 if (irq_interval
== 0) /* really interrupt for each packet */
83 if (channel
< -1 || channel
>= 64)
86 /* channel = -1 is OK for multi-channel recv but not for xmit */
87 if (type
== HPSB_ISO_XMIT
&& channel
< 0)
90 /* allocate and write the struct hpsb_iso */
93 kmalloc(sizeof(*iso
) +
94 buf_packets
* sizeof(struct hpsb_iso_packet_info
),
99 iso
->infos
= (struct hpsb_iso_packet_info
*)(iso
+ 1);
103 iso
->hostdata
= NULL
;
104 iso
->callback
= callback
;
105 init_waitqueue_head(&iso
->waitq
);
106 iso
->channel
= channel
;
107 iso
->irq_interval
= irq_interval
;
108 iso
->dma_mode
= dma_mode
;
109 dma_region_init(&iso
->data_buf
);
110 iso
->buf_size
= PAGE_ALIGN(data_buf_size
);
111 iso
->buf_packets
= buf_packets
;
113 iso
->first_packet
= 0;
114 spin_lock_init(&iso
->lock
);
116 if (iso
->type
== HPSB_ISO_XMIT
) {
117 iso
->n_ready_packets
= iso
->buf_packets
;
118 dma_direction
= PCI_DMA_TODEVICE
;
120 iso
->n_ready_packets
= 0;
121 dma_direction
= PCI_DMA_FROMDEVICE
;
124 atomic_set(&iso
->overflows
, 0);
125 iso
->bytes_discarded
= 0;
129 /* allocate the packet buffer */
131 (&iso
->data_buf
, iso
->buf_size
, host
->pdev
, dma_direction
))
137 hpsb_iso_shutdown(iso
);
142 * hpsb_iso_n_ready - returns number of packets ready to send or receive
144 int hpsb_iso_n_ready(struct hpsb_iso
*iso
)
149 spin_lock_irqsave(&iso
->lock
, flags
);
150 val
= iso
->n_ready_packets
;
151 spin_unlock_irqrestore(&iso
->lock
, flags
);
157 * hpsb_iso_xmit_init - allocate the buffer and DMA context
159 struct hpsb_iso
*hpsb_iso_xmit_init(struct hpsb_host
*host
,
160 unsigned int data_buf_size
,
161 unsigned int buf_packets
,
165 void (*callback
) (struct hpsb_iso
*))
167 struct hpsb_iso
*iso
= hpsb_iso_common_init(host
, HPSB_ISO_XMIT
,
168 data_buf_size
, buf_packets
,
170 HPSB_ISO_DMA_DEFAULT
,
171 irq_interval
, callback
);
177 /* tell the driver to start working */
178 if (host
->driver
->isoctl(iso
, XMIT_INIT
, 0))
181 iso
->flags
|= HPSB_ISO_DRIVER_INIT
;
185 hpsb_iso_shutdown(iso
);
190 * hpsb_iso_recv_init - allocate the buffer and DMA context
192 * Note, if channel = -1, multi-channel receive is enabled.
194 struct hpsb_iso
*hpsb_iso_recv_init(struct hpsb_host
*host
,
195 unsigned int data_buf_size
,
196 unsigned int buf_packets
,
200 void (*callback
) (struct hpsb_iso
*))
202 struct hpsb_iso
*iso
= hpsb_iso_common_init(host
, HPSB_ISO_RECV
,
203 data_buf_size
, buf_packets
,
205 irq_interval
, callback
);
209 /* tell the driver to start working */
210 if (host
->driver
->isoctl(iso
, RECV_INIT
, 0))
213 iso
->flags
|= HPSB_ISO_DRIVER_INIT
;
217 hpsb_iso_shutdown(iso
);
222 * hpsb_iso_recv_listen_channel
226 int hpsb_iso_recv_listen_channel(struct hpsb_iso
*iso
, unsigned char channel
)
228 if (iso
->type
!= HPSB_ISO_RECV
|| iso
->channel
!= -1 || channel
>= 64)
230 return iso
->host
->driver
->isoctl(iso
, RECV_LISTEN_CHANNEL
, channel
);
234 * hpsb_iso_recv_unlisten_channel
238 int hpsb_iso_recv_unlisten_channel(struct hpsb_iso
*iso
, unsigned char channel
)
240 if (iso
->type
!= HPSB_ISO_RECV
|| iso
->channel
!= -1 || channel
>= 64)
242 return iso
->host
->driver
->isoctl(iso
, RECV_UNLISTEN_CHANNEL
, channel
);
246 * hpsb_iso_recv_set_channel_mask
250 int hpsb_iso_recv_set_channel_mask(struct hpsb_iso
*iso
, u64 mask
)
252 if (iso
->type
!= HPSB_ISO_RECV
|| iso
->channel
!= -1)
254 return iso
->host
->driver
->isoctl(iso
, RECV_SET_CHANNEL_MASK
,
255 (unsigned long)&mask
);
259 * hpsb_iso_recv_flush - check for arrival of new packets
261 * check for arrival of new packets immediately (even if irq_interval
262 * has not yet been reached)
264 int hpsb_iso_recv_flush(struct hpsb_iso
*iso
)
266 if (iso
->type
!= HPSB_ISO_RECV
)
268 return iso
->host
->driver
->isoctl(iso
, RECV_FLUSH
, 0);
271 static int do_iso_xmit_start(struct hpsb_iso
*iso
, int cycle
)
273 int retval
= iso
->host
->driver
->isoctl(iso
, XMIT_START
, cycle
);
277 iso
->flags
|= HPSB_ISO_DRIVER_STARTED
;
282 * hpsb_iso_xmit_start - start DMA
284 int hpsb_iso_xmit_start(struct hpsb_iso
*iso
, int cycle
, int prebuffer
)
286 if (iso
->type
!= HPSB_ISO_XMIT
)
289 if (iso
->flags
& HPSB_ISO_DRIVER_STARTED
)
294 else if (cycle
>= 8000)
297 iso
->xmit_cycle
= cycle
;
300 prebuffer
= iso
->buf_packets
- 1;
301 else if (prebuffer
== 0)
304 if (prebuffer
>= iso
->buf_packets
)
305 prebuffer
= iso
->buf_packets
- 1;
307 iso
->prebuffer
= prebuffer
;
309 /* remember the starting cycle; DMA will commence from xmit_queue_packets()
310 once enough packets have been buffered */
311 iso
->start_cycle
= cycle
;
317 * hpsb_iso_recv_start - start DMA
319 int hpsb_iso_recv_start(struct hpsb_iso
*iso
, int cycle
, int tag_mask
, int sync
)
324 if (iso
->type
!= HPSB_ISO_RECV
)
327 if (iso
->flags
& HPSB_ISO_DRIVER_STARTED
)
332 else if (cycle
>= 8000)
335 isoctl_args
[0] = cycle
;
340 isoctl_args
[1] = tag_mask
;
342 isoctl_args
[2] = sync
;
345 iso
->host
->driver
->isoctl(iso
, RECV_START
,
346 (unsigned long)&isoctl_args
[0]);
350 iso
->flags
|= HPSB_ISO_DRIVER_STARTED
;
354 /* check to make sure the user has not supplied bogus values of offset/len
355 * that would cause the kernel to access memory outside the buffer */
356 static int hpsb_iso_check_offset_len(struct hpsb_iso
*iso
,
357 unsigned int offset
, unsigned short len
,
358 unsigned int *out_offset
,
359 unsigned short *out_len
)
361 if (offset
>= iso
->buf_size
)
364 /* make sure the packet does not go beyond the end of the buffer */
365 if (offset
+ len
> iso
->buf_size
)
368 /* check for wrap-around */
369 if (offset
+ len
< offset
)
372 /* now we can trust 'offset' and 'length' */
373 *out_offset
= offset
;
380 * hpsb_iso_xmit_queue_packet - queue a packet for transmission.
382 * @offset is relative to the beginning of the DMA buffer, where the packet's
383 * data payload should already have been placed.
385 int hpsb_iso_xmit_queue_packet(struct hpsb_iso
*iso
, u32 offset
, u16 len
,
388 struct hpsb_iso_packet_info
*info
;
392 if (iso
->type
!= HPSB_ISO_XMIT
)
395 /* is there space in the buffer? */
396 if (iso
->n_ready_packets
<= 0) {
400 info
= &iso
->infos
[iso
->first_packet
];
402 /* check for bogus offset/length */
403 if (hpsb_iso_check_offset_len
404 (iso
, offset
, len
, &info
->offset
, &info
->len
))
410 spin_lock_irqsave(&iso
->lock
, flags
);
412 rv
= iso
->host
->driver
->isoctl(iso
, XMIT_QUEUE
, (unsigned long)info
);
416 /* increment cursors */
417 iso
->first_packet
= (iso
->first_packet
+ 1) % iso
->buf_packets
;
418 iso
->xmit_cycle
= (iso
->xmit_cycle
+ 1) % 8000;
419 iso
->n_ready_packets
--;
421 if (iso
->prebuffer
!= 0) {
423 if (iso
->prebuffer
<= 0) {
425 rv
= do_iso_xmit_start(iso
, iso
->start_cycle
);
430 spin_unlock_irqrestore(&iso
->lock
, flags
);
435 * hpsb_iso_xmit_sync - wait until all queued packets have been transmitted
437 int hpsb_iso_xmit_sync(struct hpsb_iso
*iso
)
439 if (iso
->type
!= HPSB_ISO_XMIT
)
442 return wait_event_interruptible(iso
->waitq
,
443 hpsb_iso_n_ready(iso
) ==
448 * hpsb_iso_packet_sent
450 * Available to low-level drivers.
452 * Call after a packet has been transmitted to the bus (interrupt context is
453 * OK). @cycle is the _exact_ cycle the packet was sent on. @error should be
454 * non-zero if some sort of error occurred when sending the packet.
456 void hpsb_iso_packet_sent(struct hpsb_iso
*iso
, int cycle
, int error
)
459 spin_lock_irqsave(&iso
->lock
, flags
);
461 /* predict the cycle of the next packet to be queued */
463 /* jump ahead by the number of packets that are already buffered */
464 cycle
+= iso
->buf_packets
- iso
->n_ready_packets
;
467 iso
->xmit_cycle
= cycle
;
468 iso
->n_ready_packets
++;
469 iso
->pkt_dma
= (iso
->pkt_dma
+ 1) % iso
->buf_packets
;
471 if (iso
->n_ready_packets
== iso
->buf_packets
|| error
!= 0) {
472 /* the buffer has run empty! */
473 atomic_inc(&iso
->overflows
);
476 spin_unlock_irqrestore(&iso
->lock
, flags
);
480 * hpsb_iso_packet_received
482 * Available to low-level drivers.
484 * Call after a packet has been received (interrupt context is OK).
486 void hpsb_iso_packet_received(struct hpsb_iso
*iso
, u32 offset
, u16 len
,
487 u16 total_len
, u16 cycle
, u8 channel
, u8 tag
,
491 spin_lock_irqsave(&iso
->lock
, flags
);
493 if (iso
->n_ready_packets
== iso
->buf_packets
) {
495 atomic_inc(&iso
->overflows
);
496 /* Record size of this discarded packet */
497 iso
->bytes_discarded
+= total_len
;
499 struct hpsb_iso_packet_info
*info
= &iso
->infos
[iso
->pkt_dma
];
500 info
->offset
= offset
;
502 info
->total_len
= total_len
;
504 info
->channel
= channel
;
508 iso
->pkt_dma
= (iso
->pkt_dma
+ 1) % iso
->buf_packets
;
509 iso
->n_ready_packets
++;
512 spin_unlock_irqrestore(&iso
->lock
, flags
);
516 * hpsb_iso_recv_release_packets - release packets, reuse buffer
518 * @n_packets have been read out of the buffer, re-use the buffer space
520 int hpsb_iso_recv_release_packets(struct hpsb_iso
*iso
, unsigned int n_packets
)
526 if (iso
->type
!= HPSB_ISO_RECV
)
529 spin_lock_irqsave(&iso
->lock
, flags
);
530 for (i
= 0; i
< n_packets
; i
++) {
531 rv
= iso
->host
->driver
->isoctl(iso
, RECV_RELEASE
,
532 (unsigned long)&iso
->infos
[iso
->
537 iso
->first_packet
= (iso
->first_packet
+ 1) % iso
->buf_packets
;
538 iso
->n_ready_packets
--;
540 /* release memory from packets discarded when queue was full */
541 if (iso
->n_ready_packets
== 0) { /* Release only after all prior packets handled */
542 if (iso
->bytes_discarded
!= 0) {
543 struct hpsb_iso_packet_info inf
;
544 inf
.total_len
= iso
->bytes_discarded
;
545 iso
->host
->driver
->isoctl(iso
, RECV_RELEASE
,
546 (unsigned long)&inf
);
547 iso
->bytes_discarded
= 0;
551 spin_unlock_irqrestore(&iso
->lock
, flags
);
558 * Available to low-level drivers.
560 * Call to wake waiting processes after buffer space has opened up.
562 void hpsb_iso_wake(struct hpsb_iso
*iso
)
564 wake_up_interruptible(&iso
->waitq
);