patch-2.4.20 linux-2.4.20/drivers/ieee1394/video1394.c
Next file: linux-2.4.20/drivers/isdn/Config.in
Previous file: linux-2.4.20/drivers/ieee1394/sbp2.h
Back to the patch index
Back to the overall index
- Lines: 367
- Date:
Thu Nov 28 15:53:13 2002
- Orig file:
linux-2.4.19/drivers/ieee1394/video1394.c
- Orig date:
Fri Aug 2 17:39:44 2002
diff -urN linux-2.4.19/drivers/ieee1394/video1394.c linux-2.4.20/drivers/ieee1394/video1394.c
@@ -56,8 +56,6 @@
#include "ohci1394.h"
#define ISO_CHANNELS 64
-#define ISO_RECEIVE 0
-#define ISO_TRANSMIT 1
#ifndef virt_to_page
#define virt_to_page(x) MAP_NR(x)
@@ -84,9 +82,10 @@
struct dma_iso_ctx {
struct ti_ohci *ohci;
- int type; /* ISO_TRANSMIT or ISO_RECEIVE */
- int ctx;
+ int type; /* OHCI_ISO_TRANSMIT or OHCI_ISO_RECEIVE */
+ struct ohci1394_iso_tasklet iso_tasklet;
int channel;
+ int ctx;
int last_buffer;
int * next_buffer; /* For ISO Transmit of video packets
to write the correct SYT field
@@ -153,8 +152,8 @@
#define PRINT(level, card, fmt, args...) \
printk(level "video1394_%d: " fmt "\n" , card , ## args)
-static void irq_handler(int card, quadlet_t isoRecvIntEvent,
- quadlet_t isoXmitIntEvent, void *data);
+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;
@@ -234,12 +233,12 @@
static int free_dma_iso_ctx(struct dma_iso_ctx *d)
{
int i;
- unsigned long *usage;
DBGMSG(d->ohci->id, "Freeing dma_iso_ctx %d", d->ctx);
ohci1394_stop_context(d->ohci, d->ctrlClear, NULL);
- ohci1394_unhook_irq(d->ohci, irq_handler, d);
+ 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);
@@ -265,11 +264,6 @@
if (d->next_buffer)
kfree(d->next_buffer);
- usage = (d->type == ISO_RECEIVE) ? &d->ohci->ir_ctx_usage :
- &d->ohci->it_ctx_usage;
-
- /* clear the ISO context usage bit */
- clear_bit(d->ctx, usage);
list_del(&d->link);
kfree(d);
@@ -281,55 +275,28 @@
alloc_dma_iso_ctx(struct ti_ohci *ohci, int type, int num_desc,
int buf_size, int channel, unsigned int packet_size)
{
- struct dma_iso_ctx *d=NULL;
+ struct dma_iso_ctx *d;
int i;
- unsigned long *usage = (type == ISO_RECEIVE) ? &ohci->ir_ctx_usage :
- &ohci->it_ctx_usage;
-
- /* try to claim the ISO context usage bit */
- for (i = 0; i < ohci->nb_iso_rcv_ctx; i++) {
- if (!test_and_set_bit(i, usage)) {
- PRINT(KERN_ERR, ohci->id, "Free iso ctx %d found", i);
- break;
- }
- }
-
- if (i == ohci->nb_iso_rcv_ctx) {
- PRINT(KERN_ERR, ohci->id, "No DMA contexts available");
- return NULL;
- }
-
- d = (struct dma_iso_ctx *)kmalloc(sizeof(struct dma_iso_ctx),
- GFP_KERNEL);
- if (d==NULL) {
+ d = kmalloc(sizeof(struct dma_iso_ctx), GFP_KERNEL);
+ if (d == NULL) {
PRINT(KERN_ERR, ohci->id, "Failed to allocate dma_iso_ctx");
return NULL;
}
- memset(d, 0, sizeof(struct dma_iso_ctx));
+ memset(d, 0, sizeof *d);
- d->ohci = (void *)ohci;
+ d->ohci = ohci;
d->type = type;
- d->ctx = i;
d->channel = channel;
d->num_desc = num_desc;
d->frame_size = buf_size;
- if (buf_size%PAGE_SIZE)
- d->buf_size = buf_size + PAGE_SIZE - (buf_size%PAGE_SIZE);
- else
- d->buf_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);
- if (ohci1394_hook_irq(ohci, irq_handler, d) != 0) {
- PRINT(KERN_ERR, ohci->id, "ohci1394_hook_irq() failed");
- free_dma_iso_ctx(d);
- return NULL;
- }
-
d->buf = rvmalloc(d->num_desc * d->buf_size);
if (d->buf == NULL) {
@@ -339,7 +306,24 @@
}
memset(d->buf, 0, d->num_desc * d->buf_size);
- if (type == ISO_RECEIVE) {
+ if (type == OHCI_ISO_RECEIVE)
+ ohci1394_init_iso_tasklet(&d->iso_tasklet, type,
+ wakeup_dma_ir_ctx,
+ (unsigned long) d);
+ else
+ ohci1394_init_iso_tasklet(&d->iso_tasklet, type,
+ wakeup_dma_it_ctx,
+ (unsigned long) d);
+
+ if (ohci1394_register_iso_tasklet(ohci, &d->iso_tasklet) < 0) {
+ PRINT(KERN_ERR, ohci->id, "no free iso %s contexts",
+ type == OHCI_ISO_RECEIVE ? "receive" : "transmit");
+ free_dma_iso_ctx(d);
+ return NULL;
+ }
+ d->ctx = d->iso_tasklet.context;
+
+ if (type == OHCI_ISO_RECEIVE) {
d->ctrlSet = OHCI1394_IsoRcvContextControlSet+32*d->ctx;
d->ctrlClear = OHCI1394_IsoRcvContextControlClear+32*d->ctx;
d->cmdPtr = OHCI1394_IsoRcvCommandPtr+32*d->ctx;
@@ -359,7 +343,7 @@
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),
@@ -371,8 +355,9 @@
return NULL;
}
}
+
}
- else { /* 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;
@@ -458,7 +443,7 @@
PRINT(KERN_INFO, ohci->id, "Iso %s DMA: %d buffers "
"of size %d allocated for a frame size %d, each with %d prgs",
- (type==ISO_RECEIVE) ? "receive" : "transmit",
+ (type == OHCI_ISO_RECEIVE) ? "receive" : "transmit",
d->num_desc, d->buf_size, d->frame_size, d->nb_cmd);
return d;
@@ -563,18 +548,14 @@
return NULL;
}
-int wakeup_dma_ir_ctx(struct ti_ohci *ohci, struct dma_iso_ctx *d)
+void wakeup_dma_ir_ctx(unsigned long l)
{
+ struct dma_iso_ctx *d = (struct dma_iso_ctx *) l;
int i;
- if (d==NULL) {
- PRINT(KERN_ERR, ohci->id, "Iso receive event received but "
- "context not allocated");
- return -EFAULT;
- }
-
spin_lock(&d->lock);
- for (i=0;i<d->num_desc;i++) {
+
+ for (i = 0; i < d->num_desc; i++) {
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;
@@ -585,9 +566,11 @@
#endif
}
}
+
spin_unlock(&d->lock);
- if (waitqueue_active(&d->waitq)) wake_up_interruptible(&d->waitq);
- return 0;
+
+ if (waitqueue_active(&d->waitq))
+ wake_up_interruptible(&d->waitq);
}
static inline void put_timestamp(struct ti_ohci *ohci, struct dma_iso_ctx * d,
@@ -642,29 +625,28 @@
#endif
}
-int wakeup_dma_it_ctx(struct ti_ohci *ohci, struct dma_iso_ctx *d)
+void wakeup_dma_it_ctx(unsigned long l)
{
+ struct dma_iso_ctx *d = (struct dma_iso_ctx *) l;
+ struct ti_ohci *ohci = d->ohci;
int i;
- if (d==NULL) {
- PRINT(KERN_ERR, ohci->id, "Iso transmit event received but "
- "context not allocated");
- return -EFAULT;
- }
-
spin_lock(&d->lock);
- for (i=0;i<d->num_desc;i++) {
- if (d->it_prg[i][d->last_used_cmd[i]].end.status&
- cpu_to_le32(0xFFFF0000)) {
+
+ for (i = 0; i < d->num_desc; i++) {
+ if (d->it_prg[i][d->last_used_cmd[i]].end.status &
+ cpu_to_le32(0xFFFF0000)) {
int next = d->next_buffer[i];
put_timestamp(ohci, d, next);
d->it_prg[i][d->last_used_cmd[i]].end.status = 0;
d->buffer_status[i] = VIDEO1394_BUFFER_READY;
}
}
+
spin_unlock(&d->lock);
- if (waitqueue_active(&d->waitq)) wake_up_interruptible(&d->waitq);
- return 0;
+
+ if (waitqueue_active(&d->waitq))
+ wake_up_interruptible(&d->waitq);
}
static void initialize_dma_it_prg(struct dma_iso_ctx *d, int n, int sync_tag)
@@ -871,13 +853,13 @@
}
ohci->ISO_channel_usage |= mask;
- if (v.buf_size<=0) {
+ if (v.buf_size == 0 || v.buf_size > VIDEO1394_MAX_SIZE) {
PRINT(KERN_ERR, ohci->id,
"Invalid %d length buffer requested",v.buf_size);
return -EFAULT;
}
- if (v.nb_buffers<=0) {
+ if (v.nb_buffers == 0 || v.nb_buffers > VIDEO1394_MAX_SIZE) {
PRINT(KERN_ERR, ohci->id,
"Invalid %d buffers requested",v.nb_buffers);
return -EFAULT;
@@ -891,7 +873,7 @@
}
if (cmd == VIDEO1394_LISTEN_CHANNEL) {
- d = alloc_dma_iso_ctx(ohci, ISO_RECEIVE,
+ d = alloc_dma_iso_ctx(ohci, OHCI_ISO_RECEIVE,
v.nb_buffers, v.buf_size,
v.channel, 0);
@@ -912,7 +894,7 @@
d->ctx, v.channel);
}
else {
- d = alloc_dma_iso_ctx(ohci, ISO_TRANSMIT,
+ d = alloc_dma_iso_ctx(ohci, OHCI_ISO_TRANSMIT,
v.nb_buffers, v.buf_size,
v.channel, v.packet_size);
@@ -966,9 +948,9 @@
ohci->ISO_channel_usage &= ~mask;
if (cmd == VIDEO1394_UNLISTEN_CHANNEL)
- d = find_ctx(&ctx->context_list, ISO_RECEIVE, channel);
+ d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, channel);
else
- d = find_ctx(&ctx->context_list, ISO_TRANSMIT, channel);
+ d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, channel);
if (d == NULL) return -EFAULT;
PRINT(KERN_INFO, ohci->id, "Iso context %d "
@@ -985,7 +967,7 @@
if(copy_from_user(&v, (void *)arg, sizeof(v)))
return -EFAULT;
- d = find_ctx(&ctx->context_list, ISO_RECEIVE, v.channel);
+ d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel);
if ((v.buffer<0) || (v.buffer>d->num_desc)) {
PRINT(KERN_ERR, ohci->id,
@@ -1047,7 +1029,7 @@
if(copy_from_user(&v, (void *)arg, sizeof(v)))
return -EFAULT;
- d = find_ctx(&ctx->context_list, ISO_RECEIVE, v.channel);
+ d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel);
if ((v.buffer<0) || (v.buffer>d->num_desc)) {
PRINT(KERN_ERR, ohci->id,
@@ -1128,7 +1110,7 @@
if(copy_from_user(&v, (void *)arg, sizeof(v)))
return -EFAULT;
- d = find_ctx(&ctx->context_list, ISO_TRANSMIT, v.channel);
+ d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
if ((v.buffer<0) || (v.buffer>d->num_desc)) {
PRINT(KERN_ERR, ohci->id,
@@ -1217,7 +1199,7 @@
if(copy_from_user(&v, (void *)arg, sizeof(v)))
return -EFAULT;
- d = find_ctx(&ctx->context_list, ISO_TRANSMIT, v.channel);
+ d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
if ((v.buffer<0) || (v.buffer>d->num_desc)) {
PRINT(KERN_ERR, ohci->id,
@@ -1340,7 +1322,7 @@
ohci->ISO_channel_usage &= ~mask;
PRINT(KERN_INFO, ohci->id, "On release: Iso %s context "
"%d stop listening on channel %d",
- d->type == ISO_RECEIVE ? "receive" : "transmit",
+ d->type == OHCI_ISO_RECEIVE ? "receive" : "transmit",
d->ctx, d->channel);
free_dma_iso_ctx(d);
}
@@ -1352,20 +1334,6 @@
return 0;
}
-static void irq_handler(int card, quadlet_t isoRecvIntEvent,
- quadlet_t isoXmitIntEvent, void *data)
-{
- struct dma_iso_ctx *d = (struct dma_iso_ctx *) data;
-
- DBGMSG(card, "Iso event Recv: %08x Xmit: %08x",
- isoRecvIntEvent, isoXmitIntEvent);
-
- if (d->type == ISO_RECEIVE && isoRecvIntEvent & (1 << d->ctx))
- wakeup_dma_ir_ctx(d->ohci, d);
- if (d->type == ISO_TRANSMIT && isoXmitIntEvent & (1 << d->ctx))
- wakeup_dma_it_ctx(d->ohci, d);
-}
-
static struct file_operations video1394_fops=
{
.owner = THIS_MODULE,
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)