* ENOTTY for unsupported ioctl request
*
*/
-#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/poll.h>
#include <linux/smp_lock.h>
#include <linux/delay.h>
-#include <linux/devfs_fs_kernel.h>
#include <linux/bitops.h>
#include <linux/types.h>
#include <linux/vmalloc.h>
#include <linux/compat.h>
#include <linux/cdev.h>
-#include "ieee1394.h"
-#include "ieee1394_types.h"
+#include "dma.h"
+#include "highlevel.h"
#include "hosts.h"
+#include "ieee1394.h"
#include "ieee1394_core.h"
-#include "highlevel.h"
-#include "video1394.h"
+#include "ieee1394_hotplug.h"
+#include "ieee1394_types.h"
#include "nodemgr.h"
-#include "dma.h"
-
#include "ohci1394.h"
+#include "video1394.h"
#define ISO_CHANNELS 64
#define DBGMSG(card, fmt, args...) \
printk(KERN_INFO "video1394_%d: " fmt "\n" , card , ## args)
#else
-#define DBGMSG(card, fmt, args...)
+#define DBGMSG(card, fmt, args...) do {} while (0)
#endif
/* print general (card independent) information */
spin_lock_init(&d->lock);
- PRINT(KERN_INFO, ohci->host->id, "Iso %s DMA: %d buffers "
+ DBGMSG(ohci->host->id, "Iso %s DMA: %d buffers "
"of size %d allocated for a frame size %d, each with %d prgs",
(type == OHCI_ISO_RECEIVE) ? "receive" : "transmit",
d->num_desc - 1, d->buf_size, d->frame_size, d->nb_cmd);
reset_ir_status(d, i);
d->buffer_status[d->buffer_prg_assignment[i]] = VIDEO1394_BUFFER_READY;
do_gettimeofday(&d->buffer_time[d->buffer_prg_assignment[i]]);
+ dma_region_sync_for_cpu(&d->dma,
+ d->buffer_prg_assignment[i] * d->buf_size,
+ d->buf_size);
}
}
return ret;
}
-static int __video1394_ioctl(struct file *file,
- unsigned int cmd, unsigned long arg)
+static long video1394_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg)
{
struct file_ctx *ctx = (struct file_ctx *)file->private_data;
struct ti_ohci *ohci = ctx->ohci;
} else {
mask = (u64)0x1<<v.channel;
}
- PRINT(KERN_INFO, ohci->host->id, "mask: %08X%08X usage: %08X%08X\n",
+ DBGMSG(ohci->host->id, "mask: %08X%08X usage: %08X%08X\n",
(u32)(mask>>32),(u32)(mask&0xffffffff),
(u32)(ohci->ISO_channel_usage>>32),
(u32)(ohci->ISO_channel_usage&0xffffffff));
v.buf_size = d->buf_size;
list_add_tail(&d->link, &ctx->context_list);
- PRINT(KERN_INFO, ohci->host->id,
+ DBGMSG(ohci->host->id,
"iso context %d listen on channel %d",
d->ctx, v.channel);
}
list_add_tail(&d->link, &ctx->context_list);
- PRINT(KERN_INFO, ohci->host->id,
+ DBGMSG(ohci->host->id,
"Iso context %d talk on channel %d", d->ctx,
v.channel);
}
d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, channel);
if (d == NULL) return -ESRCH;
- PRINT(KERN_INFO, ohci->host->id, "Iso context %d "
+ DBGMSG(ohci->host->id, "Iso context %d "
"stop talking on channel %d", d->ctx, channel);
free_dma_iso_ctx(d);
struct dma_iso_ctx *d;
int next_prg;
- if (copy_from_user(&v, argp, sizeof(v)))
+ if (unlikely(copy_from_user(&v, argp, sizeof(v))))
return -EFAULT;
d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel);
- if (d == NULL) return -EFAULT;
+ if (unlikely(d == NULL))
+ return -EFAULT;
- if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) {
+ if (unlikely((v.buffer<0) || (v.buffer>=d->num_desc - 1))) {
PRINT(KERN_ERR, ohci->host->id,
"Buffer %d out of range",v.buffer);
return -EINVAL;
spin_lock_irqsave(&d->lock,flags);
- if (d->buffer_status[v.buffer]==VIDEO1394_BUFFER_QUEUED) {
+ if (unlikely(d->buffer_status[v.buffer]==VIDEO1394_BUFFER_QUEUED)) {
PRINT(KERN_ERR, ohci->host->id,
"Buffer %d is already used",v.buffer);
spin_unlock_irqrestore(&d->lock,flags);
else {
/* Wake up dma context if necessary */
if (!(reg_read(ohci, d->ctrlSet) & 0x400)) {
- PRINT(KERN_INFO, ohci->host->id,
+ DBGMSG(ohci->host->id,
"Waking up iso dma ctx=%d", d->ctx);
reg_write(ohci, d->ctrlSet, 0x1000);
}
struct dma_iso_ctx *d;
int i = 0;
- if (copy_from_user(&v, argp, sizeof(v)))
+ if (unlikely(copy_from_user(&v, argp, sizeof(v))))
return -EFAULT;
d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel);
- if (d == NULL) return -EFAULT;
+ if (unlikely(d == NULL))
+ return -EFAULT;
- if ((v.buffer<0) || (v.buffer>d->num_desc - 1)) {
+ if (unlikely((v.buffer<0) || (v.buffer>d->num_desc - 1))) {
PRINT(KERN_ERR, ohci->host->id,
"Buffer %d out of range",v.buffer);
return -EINVAL;
spin_unlock_irqrestore(&d->lock, flags);
v.buffer=i;
- if (copy_to_user(argp, &v, sizeof(v)))
+ if (unlikely(copy_to_user(argp, &v, sizeof(v))))
return -EFAULT;
return 0;
DBGMSG(ohci->host->id, "Starting iso transmit DMA ctx=%d",
d->ctx);
put_timestamp(ohci, d, d->last_buffer);
+ dma_region_sync_for_device(&d->dma,
+ v.buffer * d->buf_size, d->buf_size);
/* Tell the controller where the first program is */
reg_write(ohci, d->cmdPtr,
else {
/* Wake up dma context if necessary */
if (!(reg_read(ohci, d->ctrlSet) & 0x400)) {
- PRINT(KERN_INFO, ohci->host->id,
+ DBGMSG(ohci->host->id,
"Waking up iso transmit dma ctx=%d",
d->ctx);
put_timestamp(ohci, d, d->last_buffer);
+ dma_region_sync_for_device(&d->dma,
+ v.buffer * d->buf_size, d->buf_size);
+
reg_write(ohci, d->ctrlSet, 0x1000);
}
}
}
}
-static long video1394_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- int err;
- lock_kernel();
- err = __video1394_ioctl(file, cmd, arg);
- unlock_kernel();
- return err;
-}
-
/*
* This maps the vmalloced and reserved buffer to user space.
*
static int video1394_mmap(struct file *file, struct vm_area_struct *vma)
{
struct file_ctx *ctx = (struct file_ctx *)file->private_data;
- int res = -EINVAL;
- lock_kernel();
if (ctx->current_ctx == NULL) {
- PRINT(KERN_ERR, ctx->ohci->host->id, "Current iso context not set");
- } else
- res = dma_region_mmap(&ctx->current_ctx->dma, file, vma);
- unlock_kernel();
+ PRINT(KERN_ERR, ctx->ohci->host->id,
+ "Current iso context not set");
+ return -EINVAL;
+ }
- return res;
+ return dma_region_mmap(&ctx->current_ctx->dma, file, vma);
+}
+
+static unsigned int video1394_poll(struct file *file, poll_table *pt)
+{
+ struct file_ctx *ctx;
+ unsigned int mask = 0;
+ unsigned long flags;
+ struct dma_iso_ctx *d;
+ int i;
+
+ ctx = file->private_data;
+ d = ctx->current_ctx;
+ if (d == NULL) {
+ PRINT(KERN_ERR, ctx->ohci->host->id,
+ "Current iso context not set");
+ return POLLERR;
+ }
+
+ poll_wait(file, &d->waitq, pt);
+
+ spin_lock_irqsave(&d->lock, flags);
+ for (i = 0; i < d->num_desc; i++) {
+ if (d->buffer_status[i] == VIDEO1394_BUFFER_READY) {
+ mask |= POLLIN | POLLRDNORM;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&d->lock, flags);
+
+ return mask;
}
static int video1394_open(struct inode *inode, struct file *file)
struct list_head *lh, *next;
u64 mask;
- lock_kernel();
list_for_each_safe(lh, next, &ctx->context_list) {
struct dma_iso_ctx *d;
d = list_entry(lh, struct dma_iso_ctx, link);
"is not being used", d->channel);
else
ohci->ISO_channel_usage &= ~mask;
- PRINT(KERN_INFO, ohci->host->id, "On release: Iso %s context "
+ DBGMSG(ohci->host->id, "On release: Iso %s context "
"%d stop listening on channel %d",
d->type == OHCI_ISO_RECEIVE ? "receive" : "transmit",
d->ctx, d->channel);
kfree(ctx);
file->private_data = NULL;
- unlock_kernel();
return 0;
}
#ifdef CONFIG_COMPAT
.compat_ioctl = video1394_compat_ioctl,
#endif
+ .poll = video1394_poll,
.mmap = video1394_mmap,
.open = video1394_open,
.release = video1394_release
MODULE_DEVICE_TABLE(ieee1394, video1394_id_table);
static struct hpsb_protocol_driver video1394_driver = {
- .name = "1394 Digital Camera Driver",
+ .name = VIDEO1394_DRIVER_NAME,
.id_table = video1394_id_table,
- .driver = {
- .name = VIDEO1394_DRIVER_NAME,
- .bus = &ieee1394_bus_type,
- },
};
class_device_create(hpsb_protocol_class, NULL, MKDEV(
IEEE1394_MAJOR, minor),
NULL, "%s-%d", VIDEO1394_DRIVER_NAME, ohci->host->id);
- devfs_mk_cdev(MKDEV(IEEE1394_MAJOR, minor),
- S_IFCHR | S_IRUSR | S_IWUSR,
- "%s/%d", VIDEO1394_DRIVER_NAME, ohci->host->id);
}
{
struct ti_ohci *ohci = hpsb_get_hostinfo(&video1394_highlevel, host);
- if (ohci) {
+ if (ohci)
class_device_destroy(hpsb_protocol_class, MKDEV(IEEE1394_MAJOR,
IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id));
- devfs_remove("%s/%d", VIDEO1394_DRIVER_NAME, ohci->host->id);
- }
-
return;
}
static void __exit video1394_exit_module (void)
{
hpsb_unregister_protocol(&video1394_driver);
-
hpsb_unregister_highlevel(&video1394_highlevel);
-
- devfs_remove(VIDEO1394_DRIVER_NAME);
cdev_del(&video1394_cdev);
-
PRINT_G(KERN_INFO, "Removed " VIDEO1394_DRIVER_NAME " module");
}
return ret;
}
- devfs_mk_dir(VIDEO1394_DRIVER_NAME);
-
hpsb_register_highlevel(&video1394_highlevel);
ret = hpsb_register_protocol(&video1394_driver);
if (ret) {
PRINT_G(KERN_ERR, "video1394: failed to register protocol");
hpsb_unregister_highlevel(&video1394_highlevel);
- devfs_remove(VIDEO1394_DRIVER_NAME);
cdev_del(&video1394_cdev);
return ret;
}