patch-2.4.21 linux-2.4.21/drivers/ieee1394/video1394.c
Next file: linux-2.4.21/drivers/ieee1394/video1394.h
Previous file: linux-2.4.21/drivers/ieee1394/sbp2.h
Back to the patch index
Back to the overall index
- Lines: 851
- Date:
2003-06-13 07:51:34.000000000 -0700
- Orig file:
linux-2.4.20/drivers/ieee1394/video1394.c
- Orig date:
2002-11-28 15:53:13.000000000 -0800
diff -urN linux-2.4.20/drivers/ieee1394/video1394.c linux-2.4.21/drivers/ieee1394/video1394.c
@@ -35,11 +35,9 @@
#include <linux/poll.h>
#include <linux/smp_lock.h>
#include <linux/proc_fs.h>
-#include <linux/tqueue.h>
#include <linux/delay.h>
#include <linux/devfs_fs_kernel.h>
-
-#include <asm/bitops.h>
+#include <linux/bitops.h>
#include <linux/types.h>
#include <linux/wrapper.h>
#include <linux/vmalloc.h>
@@ -48,10 +46,12 @@
#include "ieee1394.h"
#include "ieee1394_types.h"
+#include "ieee1394_hotplug.h"
#include "hosts.h"
#include "ieee1394_core.h"
#include "highlevel.h"
#include "video1394.h"
+#include "dma.h"
#include "ohci1394.h"
@@ -65,14 +65,6 @@
#define vmalloc_32(x) vmalloc(x)
#endif
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,3))
-#define remap_page_range_1394(vma, start, addr, size, prot) \
- remap_page_range(start, addr, size, prot)
-#else
-#define remap_page_range_1394(vma, start, addr, size, prot) \
- remap_page_range(vma, start, addr, size, prot)
-#endif
-
struct it_dma_prg {
struct dma_cmd begin;
quadlet_t data[4];
@@ -96,9 +88,14 @@
unsigned int packet_size;
unsigned int left_size;
unsigned int nb_cmd;
- unsigned char *buf;
+
+ struct dma_region dma;
+
+ struct dma_prog_region *prg_reg;
+
struct dma_cmd **ir_prg;
struct it_dma_prg **it_prg;
+
unsigned int *buffer_status;
struct timeval *buffer_time; /* time when the buffer was received */
unsigned int *last_used_cmd; /* For ISO Transmit with
@@ -117,8 +114,6 @@
struct video_card {
struct ti_ohci *ohci;
- struct list_head list;
- int id;
devfs_handle_t devfs;
};
@@ -155,80 +150,9 @@
void wakeup_dma_ir_ctx(unsigned long l);
void wakeup_dma_it_ctx(unsigned long l);
-static LIST_HEAD(video1394_cards);
-static spinlock_t video1394_cards_lock = SPIN_LOCK_UNLOCKED;
-
static devfs_handle_t devfs_handle;
-static struct hpsb_highlevel *hl_handle = NULL;
-/* Code taken from bttv.c */
-
-/*******************************/
-/* Memory management functions */
-/*******************************/
-
-static inline unsigned long kvirt_to_bus(unsigned long adr)
-{
- unsigned long kva, ret;
-
- kva = (unsigned long) page_address(vmalloc_to_page((void *)adr));
- kva |= adr & (PAGE_SIZE-1); /* restore the offset */
- ret = virt_to_bus((void *)kva);
- return ret;
-}
-
-/* Here we want the physical address of the memory.
- * This is used when initializing the contents of the area.
- */
-static inline unsigned long kvirt_to_pa(unsigned long adr)
-{
- unsigned long kva, ret;
-
- kva = (unsigned long) page_address(vmalloc_to_page((void *)adr));
- kva |= adr & (PAGE_SIZE-1); /* restore the offset */
- ret = __pa(kva);
- return ret;
-}
-
-static void * rvmalloc(unsigned long size)
-{
- void * mem;
- unsigned long adr;
-
- size=PAGE_ALIGN(size);
- mem=vmalloc_32(size);
- if (mem)
- {
- memset(mem, 0, size); /* Clear the ram out,
- no junk to the user */
- adr=(unsigned long) mem;
- while (size > 0)
- {
- mem_map_reserve(vmalloc_to_page((void *)adr));
- adr+=PAGE_SIZE;
- size-=PAGE_SIZE;
- }
- }
- return mem;
-}
-
-static void rvfree(void * mem, unsigned long size)
-{
- unsigned long adr;
-
- if (mem)
- {
- adr=(unsigned long) mem;
- while ((long) size > 0)
- {
- mem_map_unreserve(vmalloc_to_page((void *)adr));
- adr+=PAGE_SIZE;
- size-=PAGE_SIZE;
- }
- vfree(mem);
- }
-}
-/* End of code taken from bttv.c */
+static struct hpsb_highlevel video1394_highlevel;
static int free_dma_iso_ctx(struct dma_iso_ctx *d)
{
@@ -240,20 +164,19 @@
if (d->iso_tasklet.link.next != NULL)
ohci1394_unregister_iso_tasklet(d->ohci, &d->iso_tasklet);
- if (d->buf)
- rvfree((void *)d->buf, d->num_desc * d->buf_size);
+ dma_region_free(&d->dma);
- if (d->ir_prg) {
- for (i=0;i<d->num_desc;i++)
- if (d->ir_prg[i]) kfree(d->ir_prg[i]);
- kfree(d->ir_prg);
+ if (d->prg_reg) {
+ for (i = 0; i < d->num_desc; i++)
+ dma_prog_region_free(&d->prg_reg[i]);
+ kfree(d->prg_reg);
}
- if (d->it_prg) {
- for (i=0;i<d->num_desc;i++)
- if (d->it_prg[i]) kfree(d->it_prg[i]);
+ if (d->ir_prg)
+ kfree(d->ir_prg);
+
+ if (d->it_prg)
kfree(d->it_prg);
- }
if (d->buffer_status)
kfree(d->buffer_status);
@@ -293,18 +216,17 @@
d->frame_size = buf_size;
d->buf_size = PAGE_ALIGN(buf_size);
d->last_buffer = -1;
- d->buf = NULL;
- d->ir_prg = NULL;
init_waitqueue_head(&d->waitq);
- d->buf = rvmalloc(d->num_desc * d->buf_size);
+ /* Init the regions for easy cleanup */
+ dma_region_init(&d->dma);
- if (d->buf == NULL) {
+ if (dma_region_alloc(&d->dma, d->num_desc * d->buf_size, ohci->dev,
+ PCI_DMA_BIDIRECTIONAL)) {
PRINT(KERN_ERR, ohci->id, "Failed to allocate dma buffer");
free_dma_iso_ctx(d);
return NULL;
}
- memset(d->buf, 0, d->num_desc * d->buf_size);
if (type == OHCI_ISO_RECEIVE)
ohci1394_init_iso_tasklet(&d->iso_tasklet, type,
@@ -323,6 +245,17 @@
}
d->ctx = d->iso_tasklet.context;
+ d->prg_reg = kmalloc(d->num_desc * sizeof(struct dma_prog_region),
+ GFP_KERNEL);
+ if (d->prg_reg == NULL) {
+ PRINT(KERN_ERR, ohci->id, "Failed to allocate ir prg regs");
+ free_dma_iso_ctx(d);
+ return NULL;
+ }
+ /* Makes for easier cleanup */
+ for (i = 0; i < d->num_desc; i++)
+ dma_prog_region_init(&d->prg_reg[i]);
+
if (type == OHCI_ISO_RECEIVE) {
d->ctrlSet = OHCI1394_IsoRcvContextControlSet+32*d->ctx;
d->ctrlClear = OHCI1394_IsoRcvContextControlClear+32*d->ctx;
@@ -333,31 +266,27 @@
GFP_KERNEL);
if (d->ir_prg == NULL) {
- PRINT(KERN_ERR, ohci->id,
- "Failed to allocate dma ir prg");
+ PRINT(KERN_ERR, ohci->id, "Failed to allocate dma ir prg");
free_dma_iso_ctx(d);
return NULL;
}
memset(d->ir_prg, 0, d->num_desc * sizeof(struct dma_cmd *));
-
+
d->nb_cmd = d->buf_size / PAGE_SIZE + 1;
d->left_size = (d->frame_size % PAGE_SIZE) ?
d->frame_size % PAGE_SIZE : PAGE_SIZE;
- for (i=0;i<d->num_desc;i++) {
- d->ir_prg[i] = kmalloc(d->nb_cmd *
- sizeof(struct dma_cmd),
- GFP_KERNEL);
- if (d->ir_prg[i] == NULL) {
- PRINT(KERN_ERR, ohci->id,
- "Failed to allocate dma ir prg");
+ for (i = 0;i < d->num_desc; i++) {
+ if (dma_prog_region_alloc(&d->prg_reg[i], d->nb_cmd *
+ sizeof(struct dma_cmd), ohci->dev)) {
+ PRINT(KERN_ERR, ohci->id, "Failed to allocate dma ir prg");
free_dma_iso_ctx(d);
return NULL;
}
+ d->ir_prg[i] = (struct dma_cmd *)d->prg_reg[i].kvirt;
}
- }
- else { /* OHCI_ISO_TRANSMIT */
+ } else { /* OHCI_ISO_TRANSMIT */
d->ctrlSet = OHCI1394_IsoXmitContextControlSet+16*d->ctx;
d->ctrlClear = OHCI1394_IsoXmitContextControlClear+16*d->ctx;
d->cmdPtr = OHCI1394_IsoXmitCommandPtr+16*d->ctx;
@@ -388,20 +317,17 @@
if (d->frame_size % d->packet_size) {
d->nb_cmd++;
d->left_size = d->frame_size % d->packet_size;
- }
- else
+ } else
d->left_size = d->packet_size;
- for (i=0;i<d->num_desc;i++) {
- d->it_prg[i] = kmalloc(d->nb_cmd *
- sizeof(struct it_dma_prg),
- GFP_KERNEL);
- if (d->it_prg[i] == NULL) {
- PRINT(KERN_ERR, ohci->id,
- "Failed to allocate dma it prg");
+ for (i = 0; i < d->num_desc; i++) {
+ if (dma_prog_region_alloc(&d->prg_reg[i], d->nb_cmd *
+ sizeof(struct it_dma_prg), ohci->dev)) {
+ PRINT(KERN_ERR, ohci->id, "Failed to allocate dma it prg");
free_dma_iso_ctx(d);
return NULL;
}
+ d->it_prg[i] = (struct it_dma_prg *)d->prg_reg[i].kvirt;
}
}
@@ -454,7 +380,7 @@
int i;
d->ir_prg[n][0].status = cpu_to_le32(4);
d->ir_prg[n][1].status = cpu_to_le32(PAGE_SIZE-4);
- for (i=2;i<d->nb_cmd-1;i++)
+ for (i = 2; i < d->nb_cmd - 1; i++)
d->ir_prg[n][i].status = cpu_to_le32(PAGE_SIZE);
d->ir_prg[n][i].status = cpu_to_le32(d->left_size);
}
@@ -462,7 +388,8 @@
static void initialize_dma_ir_prg(struct dma_iso_ctx *d, int n, int flags)
{
struct dma_cmd *ir_prg = d->ir_prg[n];
- unsigned long buf = (unsigned long)d->buf+n*d->buf_size;
+ struct dma_prog_region *ir_reg = &d->prg_reg[n];
+ unsigned long buf = (unsigned long)d->dma.kvirt + n * d->buf_size;
int i;
/* the first descriptor will read only 4 bytes */
@@ -473,31 +400,37 @@
if (flags & VIDEO1394_SYNC_FRAMES)
ir_prg[0].control |= cpu_to_le32(DMA_CTL_WAIT);
- ir_prg[0].address = cpu_to_le32(kvirt_to_bus(buf));
- ir_prg[0].branchAddress = cpu_to_le32((virt_to_bus(&(ir_prg[1].control))
- & 0xfffffff0) | 0x1);
+ ir_prg[0].address = cpu_to_le32(dma_region_offset_to_bus(&d->dma, buf -
+ (unsigned long)d->dma.kvirt));
+ ir_prg[0].branchAddress = cpu_to_le32((dma_prog_region_offset_to_bus(ir_reg,
+ 1 * sizeof(struct dma_cmd)) & 0xfffffff0) | 0x1);
/* the second descriptor will read PAGE_SIZE-4 bytes */
ir_prg[1].control = cpu_to_le32(DMA_CTL_INPUT_MORE | DMA_CTL_UPDATE |
DMA_CTL_BRANCH | (PAGE_SIZE-4));
- ir_prg[1].address = cpu_to_le32(kvirt_to_bus(buf+4));
- ir_prg[1].branchAddress = cpu_to_le32((virt_to_bus(&(ir_prg[2].control))
- & 0xfffffff0) | 0x1);
+ ir_prg[1].address = cpu_to_le32(dma_region_offset_to_bus(&d->dma, (buf + 4) -
+ (unsigned long)d->dma.kvirt));
+ ir_prg[1].branchAddress = cpu_to_le32((dma_prog_region_offset_to_bus(ir_reg,
+ 2 * sizeof(struct dma_cmd)) & 0xfffffff0) | 0x1);
for (i=2;i<d->nb_cmd-1;i++) {
ir_prg[i].control = cpu_to_le32(DMA_CTL_INPUT_MORE | DMA_CTL_UPDATE |
DMA_CTL_BRANCH | PAGE_SIZE);
- ir_prg[i].address = cpu_to_le32(kvirt_to_bus(buf+(i-1)*PAGE_SIZE));
-
- ir_prg[i].branchAddress =
- cpu_to_le32((virt_to_bus(&(ir_prg[i+1].control))
- & 0xfffffff0) | 0x1);
+ ir_prg[i].address = cpu_to_le32(dma_region_offset_to_bus(&d->dma,
+ (buf+(i-1)*PAGE_SIZE) -
+ (unsigned long)d->dma.kvirt));
+
+ ir_prg[i].branchAddress =
+ cpu_to_le32((dma_prog_region_offset_to_bus(ir_reg,
+ (i + 1) * sizeof(struct dma_cmd)) & 0xfffffff0) | 0x1);
}
/* the last descriptor will generate an interrupt */
ir_prg[i].control = cpu_to_le32(DMA_CTL_INPUT_MORE | DMA_CTL_UPDATE |
DMA_CTL_IRQ | DMA_CTL_BRANCH | d->left_size);
- ir_prg[i].address = cpu_to_le32(kvirt_to_bus(buf+(i-1)*PAGE_SIZE));
+ ir_prg[i].address = cpu_to_le32(dma_region_offset_to_bus(&d->dma,
+ (buf+(i-1)*PAGE_SIZE) -
+ (unsigned long)d->dma.kvirt));
}
static void initialize_dma_ir_ctx(struct dma_iso_ctx *d, int tag, int flags)
@@ -559,11 +492,7 @@
if (d->ir_prg[i][d->nb_cmd-1].status & cpu_to_le32(0xFFFF0000)) {
reset_ir_status(d, i);
d->buffer_status[i] = VIDEO1394_BUFFER_READY;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18)
- get_fast_time(&d->buffer_time[i]);
-#else
do_gettimeofday(&d->buffer_time[i]);
-#endif
}
}
@@ -576,7 +505,7 @@
static inline void put_timestamp(struct ti_ohci *ohci, struct dma_iso_ctx * d,
int n)
{
- unsigned char* buf = d->buf + n * d->buf_size;
+ unsigned char* buf = d->dma.kvirt + n * d->buf_size;
u32 cycleTimer;
u32 timeStamp;
@@ -605,7 +534,7 @@
if (n == -1) {
return;
}
- buf = d->buf + n * d->buf_size;
+ buf = d->dma.kvirt + n * d->buf_size;
timeStamp += (d->last_used_cmd[n] << 12) & 0xffff;
@@ -652,7 +581,8 @@
static void initialize_dma_it_prg(struct dma_iso_ctx *d, int n, int sync_tag)
{
struct it_dma_prg *it_prg = d->it_prg[n];
- unsigned long buf = (unsigned long)d->buf+n*d->buf_size;
+ struct dma_prog_region *it_reg = &d->prg_reg[n];
+ unsigned long buf = (unsigned long)d->dma.kvirt + n * d->buf_size;
int i;
d->last_used_cmd[n] = d->nb_cmd - 1;
for (i=0;i<d->nb_cmd;i++) {
@@ -676,18 +606,18 @@
it_prg[i].end.control = cpu_to_le32(DMA_CTL_OUTPUT_LAST |
DMA_CTL_BRANCH);
it_prg[i].end.address =
- cpu_to_le32(kvirt_to_bus(buf+i*d->packet_size));
+ cpu_to_le32(dma_region_offset_to_bus(&d->dma, (buf+i*d->packet_size) -
+ (unsigned long)d->dma.kvirt));
if (i<d->nb_cmd-1) {
it_prg[i].end.control |= cpu_to_le32(d->packet_size);
it_prg[i].begin.branchAddress =
- cpu_to_le32((virt_to_bus(&(it_prg[i+1].begin.control))
- & 0xfffffff0) | 0x3);
+ cpu_to_le32((dma_prog_region_offset_to_bus(it_reg, (i + 1) *
+ sizeof(struct it_dma_prg)) & 0xfffffff0) | 0x3);
it_prg[i].end.branchAddress =
- cpu_to_le32((virt_to_bus(&(it_prg[i+1].begin.control))
- & 0xfffffff0) | 0x3);
- }
- else {
+ cpu_to_le32((dma_prog_region_offset_to_bus(it_reg, (i + 1) *
+ sizeof(struct it_dma_prg)) & 0xfffffff0) | 0x3);
+ } else {
/* the last prg generates an interrupt */
it_prg[i].end.control |= cpu_to_le32(DMA_CTL_UPDATE |
DMA_CTL_IRQ | d->left_size);
@@ -696,15 +626,6 @@
it_prg[i].end.branchAddress = 0;
}
it_prg[i].end.status = 0;
-
-#if 0
- printk("%d:%d: %08x-%08x ctrl %08x brch %08x d0 %08x d1 %08x\n",n,i,
- virt_to_bus(&(it_prg[i].begin.control)),
- virt_to_bus(&(it_prg[i].end.control)),
- it_prg[i].end.control,
- it_prg[i].end.branchAddress,
- it_prg[i].data[0], it_prg[i].data[1]);
-#endif
}
}
@@ -713,6 +634,7 @@
struct ti_ohci *ohci)
{
struct it_dma_prg *it_prg = d->it_prg[n];
+ struct dma_prog_region *it_reg = &d->prg_reg[n];
int i;
#if 0
@@ -734,12 +656,12 @@
if (i < d->nb_cmd-1 && packet_sizes[i+1] != 0) {
it_prg[i].end.control |= cpu_to_le32(size);
- it_prg[i].begin.branchAddress =
- cpu_to_le32((virt_to_bus(&(it_prg[i+1].begin.control))
- & 0xfffffff0) | 0x3);
- it_prg[i].end.branchAddress =
- cpu_to_le32((virt_to_bus(&(it_prg[i+1].begin.control))
- & 0xfffffff0) | 0x3);
+ it_prg[i].begin.branchAddress =
+ cpu_to_le32((dma_prog_region_offset_to_bus(it_reg, (i + 1) *
+ sizeof(struct it_dma_prg)) & 0xfffffff0) | 0x3);
+ it_prg[i].end.branchAddress =
+ cpu_to_le32((dma_prog_region_offset_to_bus(it_reg, (i + 1) *
+ sizeof(struct it_dma_prg)) & 0xfffffff0) | 0x3);
} else {
/* the last prg generates an interrupt */
it_prg[i].end.control |= cpu_to_le32(DMA_CTL_UPDATE |
@@ -771,37 +693,6 @@
reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, 1<<d->ctx);
}
-static int do_iso_mmap(struct ti_ohci *ohci, struct dma_iso_ctx *d,
- struct vm_area_struct *vma)
-{
- unsigned long start = vma->vm_start;
- unsigned long size = vma->vm_end - vma->vm_start;
- unsigned long page, pos;
-
- if (size > d->num_desc * d->buf_size) {
- PRINT(KERN_ERR, ohci->id,
- "iso context %d buf size is different from mmap size",
- d->ctx);
- return -EINVAL;
- }
- if (!d->buf) {
- PRINT(KERN_ERR, ohci->id,
- "iso context %d is not allocated", d->ctx);
- return -EINVAL;
- }
-
- pos = (unsigned long) d->buf;
- while (size > 0) {
- page = kvirt_to_pa(pos);
- if (remap_page_range_1394(vma, start, page, PAGE_SIZE, PAGE_SHARED))
- return -EAGAIN;
- start += PAGE_SIZE;
- pos += PAGE_SIZE;
- size -= PAGE_SIZE;
- }
- return 0;
-}
-
static int video1394_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
@@ -814,6 +705,8 @@
{
case VIDEO1394_LISTEN_CHANNEL:
case VIDEO1394_TALK_CHANNEL:
+ case VIDEO1394_IOC_LISTEN_CHANNEL:
+ case VIDEO1394_IOC_TALK_CHANNEL:
{
struct video1394_mmap v;
u64 mask;
@@ -872,7 +765,7 @@
return -EFAULT;
}
- if (cmd == VIDEO1394_LISTEN_CHANNEL) {
+ if (cmd == VIDEO1394_IOC_LISTEN_CHANNEL || cmd == VIDEO1394_LISTEN_CHANNEL) {
d = alloc_dma_iso_ctx(ohci, OHCI_ISO_RECEIVE,
v.nb_buffers, v.buf_size,
v.channel, 0);
@@ -922,8 +815,10 @@
return 0;
}
- case VIDEO1394_UNLISTEN_CHANNEL:
+ case VIDEO1394_UNLISTEN_CHANNEL:
case VIDEO1394_UNTALK_CHANNEL:
+ case VIDEO1394_IOC_UNLISTEN_CHANNEL:
+ case VIDEO1394_IOC_UNTALK_CHANNEL:
{
int channel;
u64 mask;
@@ -947,7 +842,7 @@
/* Mark this channel as unused */
ohci->ISO_channel_usage &= ~mask;
- if (cmd == VIDEO1394_UNLISTEN_CHANNEL)
+ if (cmd == VIDEO1394_IOC_UNLISTEN_CHANNEL || cmd == VIDEO1394_UNLISTEN_CHANNEL)
d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, channel);
else
d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, channel);
@@ -960,6 +855,7 @@
return 0;
}
case VIDEO1394_LISTEN_QUEUE_BUFFER:
+ case VIDEO1394_IOC_LISTEN_QUEUE_BUFFER:
{
struct video1394_wait v;
struct dma_iso_ctx *d;
@@ -986,10 +882,10 @@
d->buffer_status[v.buffer]=VIDEO1394_BUFFER_QUEUED;
- if (d->last_buffer>=0)
- d->ir_prg[d->last_buffer][d->nb_cmd-1].branchAddress =
- cpu_to_le32((virt_to_bus(&(d->ir_prg[v.buffer][0].control))
- & 0xfffffff0) | 0x1);
+ if (d->last_buffer>=0)
+ d->ir_prg[d->last_buffer][d->nb_cmd-1].branchAddress =
+ cpu_to_le32((dma_prog_region_offset_to_bus(&d->prg_reg[v.buffer], 0)
+ & 0xfffffff0) | 0x1);
d->last_buffer = v.buffer;
@@ -1002,9 +898,9 @@
DBGMSG(ohci->id, "Starting iso DMA ctx=%d",d->ctx);
/* Tell the controller where the first program is */
- reg_write(ohci, d->cmdPtr,
- virt_to_bus(&(d->ir_prg[v.buffer][0]))|0x1);
-
+ reg_write(ohci, d->cmdPtr,
+ dma_prog_region_offset_to_bus(&d->prg_reg[v.buffer], 0) | 0x1);
+
/* Run IR context */
reg_write(ohci, d->ctrlSet, 0x8000);
}
@@ -1021,6 +917,8 @@
}
case VIDEO1394_LISTEN_WAIT_BUFFER:
case VIDEO1394_LISTEN_POLL_BUFFER:
+ case VIDEO1394_IOC_LISTEN_WAIT_BUFFER:
+ case VIDEO1394_IOC_LISTEN_POLL_BUFFER:
{
struct video1394_wait v;
struct dma_iso_ctx *d;
@@ -1047,7 +945,8 @@
d->buffer_status[v.buffer]=VIDEO1394_BUFFER_FREE;
break;
case VIDEO1394_BUFFER_QUEUED:
- if (cmd == VIDEO1394_LISTEN_POLL_BUFFER) {
+ if (cmd == VIDEO1394_IOC_LISTEN_POLL_BUFFER ||
+ cmd == VIDEO1394_LISTEN_POLL_BUFFER) {
/* for polling, return error code EINTR */
spin_unlock_irqrestore(&d->lock, flags);
return -EINTR;
@@ -1102,6 +1001,7 @@
return 0;
}
case VIDEO1394_TALK_QUEUE_BUFFER:
+ case VIDEO1394_IOC_TALK_QUEUE_BUFFER:
{
struct video1394_wait v;
struct video1394_queue_variable qv;
@@ -1144,18 +1044,16 @@
d->buffer_status[v.buffer]=VIDEO1394_BUFFER_QUEUED;
- if (d->last_buffer>=0) {
+ if (d->last_buffer >= 0) {
d->it_prg[d->last_buffer]
- [ d->last_used_cmd[d->last_buffer]
- ].end.branchAddress =
- cpu_to_le32((virt_to_bus(&(d->it_prg[v.buffer][0].begin.control))
- & 0xfffffff0) | 0x3);
+ [ d->last_used_cmd[d->last_buffer] ].end.branchAddress =
+ cpu_to_le32((dma_prog_region_offset_to_bus(&d->prg_reg[v.buffer],
+ 0) & 0xfffffff0) | 0x3);
d->it_prg[d->last_buffer]
- [d->last_used_cmd[d->last_buffer]
- ].begin.branchAddress =
- cpu_to_le32((virt_to_bus(&(d->it_prg[v.buffer][0].begin.control))
- & 0xfffffff0) | 0x3);
+ [ d->last_used_cmd[d->last_buffer] ].begin.branchAddress =
+ cpu_to_le32((dma_prog_region_offset_to_bus(&d->prg_reg[v.buffer],
+ 0) & 0xfffffff0) | 0x3);
d->next_buffer[d->last_buffer] = v.buffer;
}
d->last_buffer = v.buffer;
@@ -1172,9 +1070,9 @@
put_timestamp(ohci, d, d->last_buffer);
/* Tell the controller where the first program is */
- reg_write(ohci, d->cmdPtr,
- virt_to_bus(&(d->it_prg[v.buffer][0]))|0x3);
-
+ reg_write(ohci, d->cmdPtr,
+ dma_prog_region_offset_to_bus(&d->prg_reg[v.buffer], 0) | 0x3);
+
/* Run IT context */
reg_write(ohci, d->ctrlSet, 0x8000);
}
@@ -1192,6 +1090,7 @@
}
case VIDEO1394_TALK_WAIT_BUFFER:
+ case VIDEO1394_IOC_TALK_WAIT_BUFFER:
{
struct video1394_wait v;
struct dma_iso_ctx *d;
@@ -1260,7 +1159,7 @@
if (ctx->current_ctx == NULL) {
PRINT(KERN_ERR, ohci->id, "Current iso context not set");
} else
- res = do_iso_mmap(ohci, ctx->current_ctx, vma);
+ res = dma_region_mmap(&ctx->current_ctx->dma, file, vma);
unlock_kernel();
return res;
}
@@ -1268,21 +1167,10 @@
static int video1394_open(struct inode *inode, struct file *file)
{
int i = ieee1394_file_to_instance(file);
- unsigned long flags;
- struct video_card *video = NULL;
- struct list_head *lh;
+ struct video_card *video;
struct file_ctx *ctx;
- spin_lock_irqsave(&video1394_cards_lock, flags);
- list_for_each(lh, &video1394_cards) {
- struct video_card *p = list_entry(lh, struct video_card, list);
- if (p->id == i) {
- video = p;
- break;
- }
- }
- spin_unlock_irqrestore(&video1394_cards_lock, flags);
-
+ video = hpsb_get_hostinfo_bykey(&video1394_highlevel, i);
if (video == NULL)
return -EIO;
@@ -1343,91 +1231,74 @@
.release = video1394_release
};
-static int video1394_init(struct ti_ohci *ohci)
+/*** HOTPLUG STUFF **********************************************************/
+/*
+ * Export information about protocols/devices supported by this driver.
+ */
+static struct ieee1394_device_id video1394_id_table[] = {
+ {
+ .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
+ .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
+ .version = CAMERA_SW_VERSION_ENTRY & 0xffffff
+ },
+ { }
+};
+
+MODULE_DEVICE_TABLE(ieee1394, video1394_id_table);
+
+static struct hpsb_protocol_driver video1394_driver = {
+ .name = "1394 Digital Camera Driver",
+ .id_table = video1394_id_table,
+};
+
+
+static void video1394_add_host (struct hpsb_host *host)
{
+ struct ti_ohci *ohci;
struct video_card *video;
- unsigned long flags;
char name[16];
int minor;
- video = kmalloc(sizeof(struct video_card), GFP_KERNEL);
+ /* We only work with the OHCI-1394 driver */
+ if (strcmp(host->driver->name, OHCI1394_DRIVER_NAME))
+ return;
+
+ ohci = (struct ti_ohci *)host->hostdata;
+
+ video = hpsb_create_hostinfo(&video1394_highlevel, host, sizeof(*video));
if (video == NULL) {
PRINT(KERN_ERR, ohci->id, "Cannot allocate video_card");
- return -1;
+ return;
}
- memset(video, 0, sizeof(struct video_card));
-
- spin_lock_irqsave(&video1394_cards_lock, flags);
- INIT_LIST_HEAD(&video->list);
- list_add_tail(&video->list, &video1394_cards);
- spin_unlock_irqrestore(&video1394_cards_lock, flags);
-
- video->id = ohci->id;
+ hpsb_set_hostinfo_key(&video1394_highlevel, host, ohci->id);
video->ohci = ohci;
- sprintf(name, "%d", video->id);
- minor = IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + video->id;
+ sprintf(name, "%d", ohci->id);
+ minor = IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->id;
video->devfs = devfs_register(devfs_handle, name,
DEVFS_FL_AUTO_OWNER,
IEEE1394_MAJOR, minor,
S_IFCHR | S_IRUSR | S_IWUSR,
&video1394_fops, NULL);
- return 0;
+ return;
}
-/* Must be called under spinlock */
-static void remove_card(struct video_card *video)
-{
- devfs_unregister(video->devfs);
- list_del(&video->list);
-
- kfree(video);
-}
static void video1394_remove_host (struct hpsb_host *host)
{
- struct ti_ohci *ohci;
- unsigned long flags;
- struct list_head *lh, *next;
- struct video_card *p;
+ struct video_card *video = hpsb_get_hostinfo(&video1394_highlevel, host);
- /* We only work with the OHCI-1394 driver */
- if (strcmp(host->driver->name, OHCI1394_DRIVER_NAME))
- return;
-
- ohci = (struct ti_ohci *)host->hostdata;
-
- spin_lock_irqsave(&video1394_cards_lock, flags);
- list_for_each_safe(lh, next, &video1394_cards) {
- p = list_entry(lh, struct video_card, list);
- if (p->ohci == ohci) {
- remove_card(p);
- break;
- }
- }
- spin_unlock_irqrestore(&video1394_cards_lock, flags);
+ if (video)
+ devfs_unregister(video->devfs);
return;
}
-static void video1394_add_host (struct hpsb_host *host)
-{
- struct ti_ohci *ohci;
- /* We only work with the OHCI-1394 driver */
- if (strcmp(host->driver->name, OHCI1394_DRIVER_NAME))
- return;
-
- ohci = (struct ti_ohci *)host->hostdata;
-
- video1394_init(ohci);
-
- return;
-}
-
-static struct hpsb_highlevel_ops hl_ops = {
+static struct hpsb_highlevel video1394_highlevel = {
+ .name = VIDEO1394_DRIVER_NAME,
.add_host = video1394_add_host,
.remove_host = video1394_remove_host,
};
@@ -1439,7 +1310,9 @@
static void __exit video1394_exit_module (void)
{
- hpsb_unregister_highlevel (hl_handle);
+ hpsb_unregister_protocol(&video1394_driver);
+
+ hpsb_unregister_highlevel(&video1394_highlevel);
devfs_unregister(devfs_handle);
ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_VIDEO1394);
@@ -1455,20 +1328,11 @@
return -EIO;
}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
- devfs_handle = devfs_mk_dir(NULL, VIDEO1394_DRIVER_NAME,
- strlen(VIDEO1394_DRIVER_NAME), NULL);
-#else
devfs_handle = devfs_mk_dir(NULL, VIDEO1394_DRIVER_NAME, NULL);
-#endif
- hl_handle = hpsb_register_highlevel (VIDEO1394_DRIVER_NAME, &hl_ops);
- if (hl_handle == NULL) {
- PRINT_G(KERN_ERR, "No more memory for driver\n");
- devfs_unregister(devfs_handle);
- ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_VIDEO1394);
- return -ENOMEM;
- }
+ hpsb_register_highlevel(&video1394_highlevel);
+
+ hpsb_register_protocol(&video1394_driver);
PRINT_G(KERN_INFO, "Installed " VIDEO1394_DRIVER_NAME " module");
return 0;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)