2 * Isochronous IO functionality
4 * Copyright (C) 2006 Kristian Hoegsberg <krh@bitplanet.net>
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
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 #include <linux/kernel.h>
22 #include <linux/module.h>
23 #include <linux/dma-mapping.h>
24 #include <linux/vmalloc.h>
27 #include "fw-transaction.h"
28 #include "fw-topology.h"
29 #include "fw-device.h"
32 fw_iso_buffer_init(struct fw_iso_buffer
*buffer
, struct fw_card
*card
,
33 int page_count
, enum dma_data_direction direction
)
35 int i
, j
, retval
= -ENOMEM
;
38 buffer
->page_count
= page_count
;
39 buffer
->direction
= direction
;
41 buffer
->pages
= kmalloc(page_count
* sizeof(buffer
->pages
[0]),
43 if (buffer
->pages
== NULL
)
46 for (i
= 0; i
< buffer
->page_count
; i
++) {
47 buffer
->pages
[i
] = alloc_page(GFP_KERNEL
| GFP_DMA32
| __GFP_ZERO
);
48 if (buffer
->pages
[i
] == NULL
)
51 address
= dma_map_page(card
->device
, buffer
->pages
[i
],
52 0, PAGE_SIZE
, direction
);
53 if (dma_mapping_error(address
)) {
54 __free_page(buffer
->pages
[i
]);
57 set_page_private(buffer
->pages
[i
], address
);
63 for (j
= 0; j
< i
; j
++) {
64 address
= page_private(buffer
->pages
[j
]);
65 dma_unmap_page(card
->device
, address
,
66 PAGE_SIZE
, DMA_TO_DEVICE
);
67 __free_page(buffer
->pages
[j
]);
75 int fw_iso_buffer_map(struct fw_iso_buffer
*buffer
, struct vm_area_struct
*vma
)
80 uaddr
= vma
->vm_start
;
81 for (i
= 0; i
< buffer
->page_count
; i
++) {
82 retval
= vm_insert_page(vma
, uaddr
, buffer
->pages
[i
]);
91 void fw_iso_buffer_destroy(struct fw_iso_buffer
*buffer
,
97 for (i
= 0; i
< buffer
->page_count
; i
++) {
98 address
= page_private(buffer
->pages
[i
]);
99 dma_unmap_page(card
->device
, address
,
100 PAGE_SIZE
, DMA_TO_DEVICE
);
101 __free_page(buffer
->pages
[i
]);
104 kfree(buffer
->pages
);
105 buffer
->pages
= NULL
;
108 struct fw_iso_context
*
109 fw_iso_context_create(struct fw_card
*card
, int type
,
110 int channel
, int speed
, size_t header_size
,
111 fw_iso_callback_t callback
, void *callback_data
)
113 struct fw_iso_context
*ctx
;
115 ctx
= card
->driver
->allocate_iso_context(card
, type
, header_size
);
121 ctx
->channel
= channel
;
123 ctx
->header_size
= header_size
;
124 ctx
->callback
= callback
;
125 ctx
->callback_data
= callback_data
;
129 EXPORT_SYMBOL(fw_iso_context_create
);
131 void fw_iso_context_destroy(struct fw_iso_context
*ctx
)
133 struct fw_card
*card
= ctx
->card
;
135 card
->driver
->free_iso_context(ctx
);
137 EXPORT_SYMBOL(fw_iso_context_destroy
);
140 fw_iso_context_start(struct fw_iso_context
*ctx
, int cycle
, int sync
, int tags
)
142 return ctx
->card
->driver
->start_iso(ctx
, cycle
, sync
, tags
);
144 EXPORT_SYMBOL(fw_iso_context_start
);
147 fw_iso_context_queue(struct fw_iso_context
*ctx
,
148 struct fw_iso_packet
*packet
,
149 struct fw_iso_buffer
*buffer
,
150 unsigned long payload
)
152 struct fw_card
*card
= ctx
->card
;
154 return card
->driver
->queue_iso(ctx
, packet
, buffer
, payload
);
156 EXPORT_SYMBOL(fw_iso_context_queue
);
159 fw_iso_context_stop(struct fw_iso_context
*ctx
)
161 return ctx
->card
->driver
->stop_iso(ctx
);
163 EXPORT_SYMBOL(fw_iso_context_stop
);