Commit 8e14bc0b authored by Ben Collins's avatar Ben Collins Committed by Jens Axboe

[PATCH] IEEE-1394 Updates

- Converts Video1394 to PCI dma.
- Converts ioctl's to standard interface.
- Various minor fixes
- Merges from 2.5.x tree
parent fe2701f1
...@@ -18,6 +18,8 @@ obj-$(CONFIG_IEEE1394_CMP) += cmp.o ...@@ -18,6 +18,8 @@ obj-$(CONFIG_IEEE1394_CMP) += cmp.o
clean-files := oui.c clean-files := oui.c
ieee1394.o: $(ieee1394-objs)
$(LD) $(LDFLAGS) -r -o $@ $(ieee1394-objs)
ifeq ($(obj),) ifeq ($(obj),)
obj = . obj = .
......
...@@ -598,6 +598,8 @@ static struct buffer *buffer_alloc(int size) ...@@ -598,6 +598,8 @@ static struct buffer *buffer_alloc(int size)
struct buffer *b; struct buffer *b;
b = kmalloc(sizeof *b + size, SLAB_KERNEL); b = kmalloc(sizeof *b + size, SLAB_KERNEL);
if (b == NULL)
return NULL;
b->head = 0; b->head = 0;
b->tail = 0; b->tail = 0;
b->length = 0; b->length = 0;
......
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
#ifndef __AMDTP_H #ifndef __AMDTP_H
#define __AMDTP_H #define __AMDTP_H
#include <asm/ioctl.h>
#include <asm/types.h> #include <asm/types.h>
#include "ieee1394-ioctl.h"
/* The userspace interface for the Audio & Music Data Transmission /* The userspace interface for the Audio & Music Data Transmission
* Protocol driver is really simple. First, open /dev/amdtp, use the * Protocol driver is really simple. First, open /dev/amdtp, use the
...@@ -57,13 +57,6 @@ ...@@ -57,13 +57,6 @@
* *
*/ */
/* We use '#' for our ioctl magic number because it's cool. */
#define AMDTP_IOC_CHANNEL _IOW('#', 0, sizeof (struct amdtp_ioctl))
#define AMDTP_IOC_PLUG _IOW('#', 1, sizeof (struct amdtp_ioctl))
#define AMDTP_IOC_PING _IOW('#', 2, sizeof (struct amdtp_ioctl))
#define AMDTP_IOC_ZAP _IO('#', 3)
enum { enum {
AMDTP_FORMAT_RAW, AMDTP_FORMAT_RAW,
AMDTP_FORMAT_IEC958_PCM, AMDTP_FORMAT_IEC958_PCM,
......
...@@ -25,9 +25,8 @@ void dma_prog_region_init(struct dma_prog_region *prog) ...@@ -25,9 +25,8 @@ void dma_prog_region_init(struct dma_prog_region *prog)
int dma_prog_region_alloc(struct dma_prog_region *prog, unsigned long n_bytes, struct pci_dev *dev) int dma_prog_region_alloc(struct dma_prog_region *prog, unsigned long n_bytes, struct pci_dev *dev)
{ {
/* round up to page size */ /* round up to page size */
if(n_bytes % PAGE_SIZE) n_bytes = round_up_to_page(n_bytes);
n_bytes += PAGE_SIZE - (n_bytes & PAGE_SIZE);
prog->n_pages = n_bytes / PAGE_SIZE; prog->n_pages = n_bytes / PAGE_SIZE;
prog->kvirt = pci_alloc_consistent(dev, prog->n_pages * PAGE_SIZE, &prog->bus_addr); prog->kvirt = pci_alloc_consistent(dev, prog->n_pages * PAGE_SIZE, &prog->bus_addr);
...@@ -47,7 +46,7 @@ void dma_prog_region_free(struct dma_prog_region *prog) ...@@ -47,7 +46,7 @@ void dma_prog_region_free(struct dma_prog_region *prog)
if(prog->kvirt) { if(prog->kvirt) {
pci_free_consistent(prog->dev, prog->n_pages * PAGE_SIZE, prog->kvirt, prog->bus_addr); pci_free_consistent(prog->dev, prog->n_pages * PAGE_SIZE, prog->kvirt, prog->bus_addr);
} }
prog->kvirt = NULL; prog->kvirt = NULL;
prog->dev = NULL; prog->dev = NULL;
prog->n_pages = 0; prog->n_pages = 0;
...@@ -70,11 +69,10 @@ int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes, struct pci_d ...@@ -70,11 +69,10 @@ int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes, struct pci_d
unsigned int i, n_pages; unsigned int i, n_pages;
/* round up to page size */ /* round up to page size */
if(n_bytes % PAGE_SIZE) n_bytes = round_up_to_page(n_bytes);
n_bytes += PAGE_SIZE - (n_bytes & PAGE_SIZE);
n_pages = n_bytes / PAGE_SIZE; n_pages = n_bytes / PAGE_SIZE;
dma->kvirt = vmalloc_32(n_pages * PAGE_SIZE); dma->kvirt = vmalloc_32(n_pages * PAGE_SIZE);
if(!dma->kvirt) { if(!dma->kvirt) {
printk(KERN_ERR "dma_region_alloc: vmalloc_32() failed\n"); printk(KERN_ERR "dma_region_alloc: vmalloc_32() failed\n");
...@@ -82,7 +80,7 @@ int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes, struct pci_d ...@@ -82,7 +80,7 @@ int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes, struct pci_d
} }
dma->n_pages = n_pages; dma->n_pages = n_pages;
/* Clear the ram out, no junk to the user */ /* Clear the ram out, no junk to the user */
memset(dma->kvirt, 0, n_pages * PAGE_SIZE); memset(dma->kvirt, 0, n_pages * PAGE_SIZE);
...@@ -114,7 +112,7 @@ int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes, struct pci_d ...@@ -114,7 +112,7 @@ int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes, struct pci_d
dma->dev = dev; dma->dev = dev;
dma->direction = direction; dma->direction = direction;
return 0; return 0;
err: err:
...@@ -148,7 +146,7 @@ static inline int dma_region_find(struct dma_region *dma, unsigned long offset, ...@@ -148,7 +146,7 @@ static inline int dma_region_find(struct dma_region *dma, unsigned long offset,
{ {
int i; int i;
unsigned long off = offset; unsigned long off = offset;
for(i = 0; i < dma->n_dma_pages; i++) { for(i = 0; i < dma->n_dma_pages; i++) {
if(off < sg_dma_len(&dma->sglist[i])) { if(off < sg_dma_len(&dma->sglist[i])) {
*rem = off; *rem = off;
...@@ -157,14 +155,14 @@ static inline int dma_region_find(struct dma_region *dma, unsigned long offset, ...@@ -157,14 +155,14 @@ static inline int dma_region_find(struct dma_region *dma, unsigned long offset,
off -= sg_dma_len(&dma->sglist[i]); off -= sg_dma_len(&dma->sglist[i]);
} }
panic("dma_region_find: offset %lu beyond end of DMA mapping\n", offset); panic("dma_region_find: offset %lu beyond end of DMA mapping\n", offset);
} }
dma_addr_t dma_region_offset_to_bus(struct dma_region *dma, unsigned long offset) dma_addr_t dma_region_offset_to_bus(struct dma_region *dma, unsigned long offset)
{ {
unsigned long rem; unsigned long rem;
struct scatterlist *sg = &dma->sglist[dma_region_find(dma, offset, &rem)]; struct scatterlist *sg = &dma->sglist[dma_region_find(dma, offset, &rem)];
return sg_dma_address(sg) + rem; return sg_dma_address(sg) + rem;
} }
...@@ -176,10 +174,10 @@ void dma_region_sync(struct dma_region *dma, unsigned long offset, unsigned long ...@@ -176,10 +174,10 @@ void dma_region_sync(struct dma_region *dma, unsigned long offset, unsigned long
if(!len) if(!len)
len = 1; len = 1;
first = dma_region_find(dma, offset, &rem); first = dma_region_find(dma, offset, &rem);
last = dma_region_find(dma, offset + len - 1, &rem); last = dma_region_find(dma, offset + len - 1, &rem);
pci_dma_sync_sg(dma->dev, &dma->sglist[first], last - first + 1, dma->direction); pci_dma_sync_sg(dma->dev, &dma->sglist[first], last - first + 1, dma->direction);
} }
...@@ -210,13 +208,13 @@ dma_region_pagefault(struct vm_area_struct *area, unsigned long address, int wri ...@@ -210,13 +208,13 @@ dma_region_pagefault(struct vm_area_struct *area, unsigned long address, int wri
} }
static struct vm_operations_struct dma_region_vm_ops = { static struct vm_operations_struct dma_region_vm_ops = {
nopage: dma_region_pagefault, .nopage = dma_region_pagefault,
}; };
int dma_region_mmap(struct dma_region *dma, struct file *file, struct vm_area_struct *vma) int dma_region_mmap(struct dma_region *dma, struct file *file, struct vm_area_struct *vma)
{ {
unsigned long size; unsigned long size;
if(!dma->kvirt) if(!dma->kvirt)
return -EINVAL; return -EINVAL;
...@@ -233,6 +231,6 @@ int dma_region_mmap(struct dma_region *dma, struct file *file, struct vm_area_st ...@@ -233,6 +231,6 @@ int dma_region_mmap(struct dma_region *dma, struct file *file, struct vm_area_st
vma->vm_private_data = dma; vma->vm_private_data = dma;
vma->vm_file = file; vma->vm_file = file;
vma->vm_flags |= VM_RESERVED; vma->vm_flags |= VM_RESERVED;
return 0; return 0;
} }
...@@ -73,4 +73,12 @@ int dma_region_mmap(struct dma_region *dma, struct file *file, struct vm_area_s ...@@ -73,4 +73,12 @@ int dma_region_mmap(struct dma_region *dma, struct file *file, struct vm_area_s
relative to the beginning of the dma_region */ relative to the beginning of the dma_region */
dma_addr_t dma_region_offset_to_bus(struct dma_region *dma, unsigned long offset); dma_addr_t dma_region_offset_to_bus(struct dma_region *dma, unsigned long offset);
/* round up a number of bytes to be a multiple of the PAGE_SIZE */
static inline unsigned long round_up_to_page(unsigned long len)
{
if(len % PAGE_SIZE)
len += PAGE_SIZE - (len % PAGE_SIZE);
return len;
}
#endif /* IEEE1394_DMA_H */ #endif /* IEEE1394_DMA_H */
...@@ -918,6 +918,7 @@ static int do_dv1394_init(struct video_card *video, struct dv1394_init *init) ...@@ -918,6 +918,7 @@ static int do_dv1394_init(struct video_card *video, struct dv1394_init *init)
u64 chan_mask; u64 chan_mask;
int retval = -EINVAL; int retval = -EINVAL;
debug_printk( "dv1394: initialising %d\n", video->id );
if(init->api_version != DV1394_API_VERSION) if(init->api_version != DV1394_API_VERSION)
goto err; goto err;
...@@ -1186,6 +1187,7 @@ static void stop_dma(struct video_card *video) ...@@ -1186,6 +1187,7 @@ static void stop_dma(struct video_card *video)
if( (reg_read(video->ohci, video->ohci_IsoXmitContextControlClear) & (1 << 10)) || if( (reg_read(video->ohci, video->ohci_IsoXmitContextControlClear) & (1 << 10)) ||
(reg_read(video->ohci, video->ohci_IsoRcvContextControlClear) & (1 << 10)) ) { (reg_read(video->ohci, video->ohci_IsoRcvContextControlClear) & (1 << 10)) ) {
/* still active */ /* still active */
debug_printk("dv1394: stop_dma: DMA not stopped yet\n" );
mb(); mb();
} else { } else {
debug_printk("dv1394: stop_dma: DMA stopped safely after %d ms\n", i/10); debug_printk("dv1394: stop_dma: DMA stopped safely after %d ms\n", i/10);
...@@ -1199,7 +1201,9 @@ static void stop_dma(struct video_card *video) ...@@ -1199,7 +1201,9 @@ static void stop_dma(struct video_card *video)
printk(KERN_ERR "dv1394: stop_dma: DMA still going after %d ms!\n", i/10); printk(KERN_ERR "dv1394: stop_dma: DMA still going after %d ms!\n", i/10);
} }
} }
else
debug_printk("dv1394: stop_dma: already stopped.\n");
spin_unlock_irqrestore(&video->spinlock, flags); spin_unlock_irqrestore(&video->spinlock, flags);
} }
...@@ -1226,7 +1230,8 @@ static int do_dv1394_shutdown(struct video_card *video, int free_dv_buf) ...@@ -1226,7 +1230,8 @@ static int do_dv1394_shutdown(struct video_card *video, int free_dv_buf)
/* disable interrupts for IT context */ /* disable interrupts for IT context */
reg_write(video->ohci, OHCI1394_IsoXmitIntMaskClear, (1 << video->ohci_it_ctx)); reg_write(video->ohci, OHCI1394_IsoXmitIntMaskClear, (1 << video->ohci_it_ctx));
clear_bit(video->ohci_it_ctx, &video->ohci->it_ctx_usage); /* remove tasklet */
ohci1394_unregister_iso_tasklet(video->ohci, &video->it_tasklet);
debug_printk("dv1394: IT context %d released\n", video->ohci_it_ctx); debug_printk("dv1394: IT context %d released\n", video->ohci_it_ctx);
video->ohci_it_ctx = -1; video->ohci_it_ctx = -1;
} }
...@@ -1240,23 +1245,14 @@ static int do_dv1394_shutdown(struct video_card *video, int free_dv_buf) ...@@ -1240,23 +1245,14 @@ static int do_dv1394_shutdown(struct video_card *video, int free_dv_buf)
/* disable interrupts for IR context */ /* disable interrupts for IR context */
reg_write(video->ohci, OHCI1394_IsoRecvIntMaskClear, (1 << video->ohci_ir_ctx)); reg_write(video->ohci, OHCI1394_IsoRecvIntMaskClear, (1 << video->ohci_ir_ctx));
clear_bit(video->ohci_ir_ctx, &video->ohci->ir_ctx_usage); /* remove tasklet */
ohci1394_unregister_iso_tasklet(video->ohci, &video->ir_tasklet);
debug_printk("dv1394: IR context %d released\n", video->ohci_ir_ctx); debug_printk("dv1394: IR context %d released\n", video->ohci_ir_ctx);
video->ohci_ir_ctx = -1; video->ohci_ir_ctx = -1;
} }
spin_unlock_irqrestore(&video->spinlock, flags); spin_unlock_irqrestore(&video->spinlock, flags);
/* remove tasklets */
if(video->ohci_it_ctx != -1) {
ohci1394_unregister_iso_tasklet(video->ohci, &video->it_tasklet);
video->ohci_it_ctx = -1;
}
if(video->ohci_ir_ctx != -1) {
ohci1394_unregister_iso_tasklet(video->ohci, &video->ir_tasklet);
video->ohci_ir_ctx = -1;
}
/* release the ISO channel */ /* release the ISO channel */
if(video->channel != -1) { if(video->channel != -1) {
u64 chan_mask; u64 chan_mask;
...@@ -1612,7 +1608,7 @@ static int dv1394_ioctl(struct inode *inode, struct file *file, ...@@ -1612,7 +1608,7 @@ static int dv1394_ioctl(struct inode *inode, struct file *file,
switch(cmd) switch(cmd)
{ {
case DV1394_SUBMIT_FRAMES: { case DV1394_IOC_SUBMIT_FRAMES: {
unsigned int n_submit; unsigned int n_submit;
if( !video_card_initialized(video) ) { if( !video_card_initialized(video) ) {
...@@ -1666,7 +1662,7 @@ static int dv1394_ioctl(struct inode *inode, struct file *file, ...@@ -1666,7 +1662,7 @@ static int dv1394_ioctl(struct inode *inode, struct file *file,
break; break;
} }
case DV1394_WAIT_FRAMES: { case DV1394_IOC_WAIT_FRAMES: {
unsigned int n_wait; unsigned int n_wait;
if( !video_card_initialized(video) ) { if( !video_card_initialized(video) ) {
...@@ -1715,7 +1711,7 @@ static int dv1394_ioctl(struct inode *inode, struct file *file, ...@@ -1715,7 +1711,7 @@ static int dv1394_ioctl(struct inode *inode, struct file *file,
break; break;
} }
case DV1394_RECEIVE_FRAMES: { case DV1394_IOC_RECEIVE_FRAMES: {
unsigned int n_recv; unsigned int n_recv;
if( !video_card_initialized(video) ) { if( !video_card_initialized(video) ) {
...@@ -1748,7 +1744,7 @@ static int dv1394_ioctl(struct inode *inode, struct file *file, ...@@ -1748,7 +1744,7 @@ static int dv1394_ioctl(struct inode *inode, struct file *file,
break; break;
} }
case DV1394_START_RECEIVE: { case DV1394_IOC_START_RECEIVE: {
if( !video_card_initialized(video) ) { if( !video_card_initialized(video) ) {
ret = do_dv1394_init_default(video); ret = do_dv1394_init_default(video);
if(ret) if(ret)
...@@ -1765,7 +1761,7 @@ static int dv1394_ioctl(struct inode *inode, struct file *file, ...@@ -1765,7 +1761,7 @@ static int dv1394_ioctl(struct inode *inode, struct file *file,
break; break;
} }
case DV1394_INIT: { case DV1394_IOC_INIT: {
struct dv1394_init init; struct dv1394_init init;
if(arg == (unsigned long) NULL) { if(arg == (unsigned long) NULL) {
ret = do_dv1394_init_default(video); ret = do_dv1394_init_default(video);
...@@ -1779,12 +1775,12 @@ static int dv1394_ioctl(struct inode *inode, struct file *file, ...@@ -1779,12 +1775,12 @@ static int dv1394_ioctl(struct inode *inode, struct file *file,
break; break;
} }
case DV1394_SHUTDOWN: case DV1394_IOC_SHUTDOWN:
ret = do_dv1394_shutdown(video, 0); ret = do_dv1394_shutdown(video, 0);
break; break;
case DV1394_GET_STATUS: { case DV1394_IOC_GET_STATUS: {
struct dv1394_status status; struct dv1394_status status;
if( !video_card_initialized(video) ) { if( !video_card_initialized(video) ) {
...@@ -2346,6 +2342,7 @@ static void ir_tasklet_func(unsigned long data) ...@@ -2346,6 +2342,7 @@ static void ir_tasklet_func(unsigned long data)
dbc = (int) (p->cip_h1 >> 24); dbc = (int) (p->cip_h1 >> 24);
if ( video->continuity_counter != -1 && dbc > ((video->continuity_counter + 1) % 256) ) if ( video->continuity_counter != -1 && dbc > ((video->continuity_counter + 1) % 256) )
{ {
printk(KERN_WARNING "dv1394: discontinuity detected, dropping all frames\n" );
video->dropped_frames += video->n_clear_frames + 1; video->dropped_frames += video->n_clear_frames + 1;
video->first_frame = 0; video->first_frame = 0;
video->n_clear_frames = 0; video->n_clear_frames = 0;
...@@ -2364,9 +2361,8 @@ static void ir_tasklet_func(unsigned long data) ...@@ -2364,9 +2361,8 @@ static void ir_tasklet_func(unsigned long data)
video->n_clear_frames++; video->n_clear_frames++;
if (video->n_clear_frames > video->n_frames) { if (video->n_clear_frames > video->n_frames) {
video->dropped_frames++; video->dropped_frames++;
video->n_clear_frames--; printk(KERN_WARNING "dv1394: dropped a frame during reception\n" );
if (video->n_clear_frames < 0) video->n_clear_frames = video->n_frames-1;
video->n_clear_frames = 0;
video->first_clear_frame = (video->first_clear_frame + 1) % video->n_frames; video->first_clear_frame = (video->first_clear_frame + 1) % video->n_frames;
} }
if (video->first_clear_frame == -1) if (video->first_clear_frame == -1)
...@@ -2375,7 +2371,6 @@ static void ir_tasklet_func(unsigned long data) ...@@ -2375,7 +2371,6 @@ static void ir_tasklet_func(unsigned long data)
/* get the next frame */ /* get the next frame */
video->active_frame = (video->active_frame + 1) % video->n_frames; video->active_frame = (video->active_frame + 1) % video->n_frames;
f = video->frames[video->active_frame]; f = video->frames[video->active_frame];
irq_printk(" frame received, active_frame = %d, n_clear_frames = %d, first_clear_frame = %d\n", irq_printk(" frame received, active_frame = %d, n_clear_frames = %d, first_clear_frame = %d\n",
video->active_frame, video->n_clear_frames, video->first_clear_frame); video->active_frame, video->n_clear_frames, video->first_clear_frame);
} }
......
...@@ -200,48 +200,7 @@ ...@@ -200,48 +200,7 @@
/* ioctl() commands */ /* ioctl() commands */
#include "ieee1394-ioctl.h"
enum {
/* I don't like using 0 as a valid ioctl() */
DV1394_INVALID = 0,
/* get the driver ready to transmit video.
pass a struct dv1394_init* as the parameter (see below),
or NULL to get default parameters */
DV1394_INIT,
/* stop transmitting video and free the ringbuffer */
DV1394_SHUTDOWN,
/* submit N new frames to be transmitted, where
the index of the first new frame is first_clear_buffer,
and the index of the last new frame is
(first_clear_buffer + N) % n_frames */
DV1394_SUBMIT_FRAMES,
/* block until N buffers are clear (pass N as the parameter)
Because we re-transmit the last frame on underrun, there
will at most be n_frames - 1 clear frames at any time */
DV1394_WAIT_FRAMES,
/* capture new frames that have been received, where
the index of the first new frame is first_clear_buffer,
and the index of the last new frame is
(first_clear_buffer + N) % n_frames */
DV1394_RECEIVE_FRAMES,
DV1394_START_RECEIVE,
/* pass a struct dv1394_status* as the parameter (see below) */
DV1394_GET_STATUS,
};
enum pal_or_ntsc { enum pal_or_ntsc {
......
...@@ -77,7 +77,7 @@ ...@@ -77,7 +77,7 @@
printk(KERN_ERR fmt, ## args) printk(KERN_ERR fmt, ## args)
static char version[] __devinitdata = static char version[] __devinitdata =
"$Rev: 641 $ Ben Collins <bcollins@debian.org>"; "$Rev: 770 $ Ben Collins <bcollins@debian.org>";
/* Our ieee1394 highlevel driver */ /* Our ieee1394 highlevel driver */
#define ETHER1394_DRIVER_NAME "ether1394" #define ETHER1394_DRIVER_NAME "ether1394"
...@@ -368,6 +368,7 @@ static void ether1394_add_host (struct hpsb_host *host) ...@@ -368,6 +368,7 @@ static void ether1394_add_host (struct hpsb_host *host)
if (register_netdev (dev)) { if (register_netdev (dev)) {
ETH1394_PRINT (KERN_ERR, dev->name, "Error registering network driver\n"); ETH1394_PRINT (KERN_ERR, dev->name, "Error registering network driver\n");
kfree (dev); kfree (dev);
kfree (hi);
return; return;
} }
......
...@@ -164,17 +164,19 @@ int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, u64 start) ...@@ -164,17 +164,19 @@ int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, u64 start)
return retval; return retval;
} }
void hpsb_listen_channel(struct hpsb_highlevel *hl, struct hpsb_host *host, int hpsb_listen_channel(struct hpsb_highlevel *hl, struct hpsb_host *host,
unsigned int channel) unsigned int channel)
{ {
if (channel > 63) { if (channel > 63) {
HPSB_ERR("%s called with invalid channel", __FUNCTION__); HPSB_ERR("%s called with invalid channel", __FUNCTION__);
return; return -EINVAL;
} }
if (host->iso_listen_count[channel]++ == 0) { if (host->iso_listen_count[channel]++ == 0) {
host->driver->devctl(host, ISO_LISTEN_CHANNEL, channel); return host->driver->devctl(host, ISO_LISTEN_CHANNEL, channel);
} }
return 0;
} }
void hpsb_unlisten_channel(struct hpsb_highlevel *hl, struct hpsb_host *host, void hpsb_unlisten_channel(struct hpsb_highlevel *hl, struct hpsb_host *host,
......
...@@ -150,8 +150,8 @@ int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, u64 start); ...@@ -150,8 +150,8 @@ int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, u64 start);
* Enable or disable receving a certain isochronous channel through the * Enable or disable receving a certain isochronous channel through the
* iso_receive op. * iso_receive op.
*/ */
void hpsb_listen_channel(struct hpsb_highlevel *hl, struct hpsb_host *host, int hpsb_listen_channel(struct hpsb_highlevel *hl, struct hpsb_host *host,
unsigned int channel); unsigned int channel);
void hpsb_unlisten_channel(struct hpsb_highlevel *hl, struct hpsb_host *host, void hpsb_unlisten_channel(struct hpsb_highlevel *hl, struct hpsb_host *host,
unsigned int channel); unsigned int channel);
......
...@@ -38,9 +38,15 @@ static int dummy_devctl(struct hpsb_host *h, enum devctl_cmd c, int arg) ...@@ -38,9 +38,15 @@ static int dummy_devctl(struct hpsb_host *h, enum devctl_cmd c, int arg)
return -1; return -1;
} }
static int dummy_isoctl(struct hpsb_iso *iso, enum isoctl_cmd command, unsigned long arg)
{
return -1;
}
static struct hpsb_host_driver dummy_driver = { static struct hpsb_host_driver dummy_driver = {
.transmit_packet = dummy_transmit_packet, .transmit_packet = dummy_transmit_packet,
.devctl = dummy_devctl .devctl = dummy_devctl,
.isoctl = dummy_isoctl
}; };
/** /**
...@@ -63,9 +69,11 @@ int hpsb_ref_host(struct hpsb_host *host) ...@@ -63,9 +69,11 @@ int hpsb_ref_host(struct hpsb_host *host)
spin_lock_irqsave(&hosts_lock, flags); spin_lock_irqsave(&hosts_lock, flags);
list_for_each(lh, &hosts) { list_for_each(lh, &hosts) {
if (host == list_entry(lh, struct hpsb_host, host_list)) { if (host == list_entry(lh, struct hpsb_host, host_list)) {
host->driver->devctl(host, MODIFY_USAGE, 1); if (host->driver->devctl(host, MODIFY_USAGE, 1)) {
host->refcount++; host->driver->devctl(host, MODIFY_USAGE, 1);
retval = 1; host->refcount++;
retval = 1;
}
break; break;
} }
} }
......
...@@ -108,19 +108,22 @@ enum devctl_cmd { ...@@ -108,19 +108,22 @@ enum devctl_cmd {
enum isoctl_cmd { enum isoctl_cmd {
/* rawiso API - see iso.h for the meanings of these commands /* rawiso API - see iso.h for the meanings of these commands
* INIT = allocate resources * INIT = allocate resources
* START = begin transmission/reception (arg: cycle to start on) * START = begin transmission/reception
* STOP = halt transmission/reception * STOP = halt transmission/reception
* QUEUE/RELEASE = produce/consume packets (arg: # of packets) * QUEUE/RELEASE = produce/consume packets
* SHUTDOWN = deallocate resources * SHUTDOWN = deallocate resources
*/ */
XMIT_INIT, XMIT_INIT,
XMIT_START, XMIT_START,
XMIT_STOP, XMIT_STOP,
XMIT_QUEUE, XMIT_QUEUE,
XMIT_SHUTDOWN, XMIT_SHUTDOWN,
RECV_INIT, RECV_INIT,
RECV_LISTEN_CHANNEL, /* multi-channel only */
RECV_UNLISTEN_CHANNEL, /* multi-channel only */
RECV_SET_CHANNEL_MASK, /* multi-channel only; arg is a *u64 */
RECV_START, RECV_START,
RECV_STOP, RECV_STOP,
RECV_RELEASE, RECV_RELEASE,
...@@ -170,11 +173,12 @@ struct hpsb_host_driver { ...@@ -170,11 +173,12 @@ struct hpsb_host_driver {
*/ */
int (*devctl) (struct hpsb_host *host, enum devctl_cmd command, int arg); int (*devctl) (struct hpsb_host *host, enum devctl_cmd command, int arg);
/* ISO transmission/reception functions. Return 0 on success, -1 on failure. /* ISO transmission/reception functions. Return 0 on success, -1
* If the low-level driver does not support the new ISO API, set isoctl to NULL. * (or -EXXX errno code) on failure. If the low-level driver does not
* support the new ISO API, set isoctl to NULL.
*/ */
int (*isoctl) (struct hpsb_iso *iso, enum isoctl_cmd command, int arg); int (*isoctl) (struct hpsb_iso *iso, enum isoctl_cmd command, unsigned long arg);
/* This function is mainly to redirect local CSR reads/locks to the iso /* This function is mainly to redirect local CSR reads/locks to the iso
* management registers (bus manager id, bandwidth available, channels * management registers (bus manager id, bandwidth available, channels
* available) to the hardware registers in OHCI. reg is 0,1,2,3 for bus * available) to the hardware registers in OHCI. reg is 0,1,2,3 for bus
......
/* Base file for all ieee1394 ioctl's. Linux-1394 has allocated base '#'
* with a range of 0x00-0x3f. */
#ifndef __IEEE1394_IOCTL_H
#define __IEEE1394_IOCTL_H
#include <asm/ioctl.h>
#include <asm/types.h>
/* AMDTP Gets 6 */
#define AMDTP_IOC_CHANNEL _IOW('#', 0x00, struct amdtp_ioctl)
#define AMDTP_IOC_PLUG _IOW('#', 0x01, struct amdtp_ioctl)
#define AMDTP_IOC_PING _IOW('#', 0x02, struct amdtp_ioctl)
#define AMDTP_IOC_ZAP _IO ('#', 0x03)
/* DV1394 Gets 10 */
/* Get the driver ready to transmit video. pass a struct dv1394_init* as
* the parameter (see below), or NULL to get default parameters */
#define DV1394_IOC_INIT _IOW('#', 0x06, struct dv1394_init)
/* Stop transmitting video and free the ringbuffer */
#define DV1394_IOC_SHUTDOWN _IO ('#', 0x07)
/* Submit N new frames to be transmitted, where the index of the first new
* frame is first_clear_buffer, and the index of the last new frame is
* (first_clear_buffer + N) % n_frames */
#define DV1394_IOC_SUBMIT_FRAMES _IO ('#', 0x08)
/* Block until N buffers are clear (pass N as the parameter) Because we
* re-transmit the last frame on underrun, there will at most be n_frames
* - 1 clear frames at any time */
#define DV1394_IOC_WAIT_FRAMES _IO ('#', 0x09)
/* Capture new frames that have been received, where the index of the
* first new frame is first_clear_buffer, and the index of the last new
* frame is (first_clear_buffer + N) % n_frames */
#define DV1394_IOC_RECEIVE_FRAMES _IO ('#', 0x0a)
/* Tell card to start receiving DMA */
#define DV1394_IOC_START_RECEIVE _IO ('#', 0x0b)
/* Pass a struct dv1394_status* as the parameter */
#define DV1394_IOC_GET_STATUS _IOR('#', 0x0c, struct dv1394_status)
/* Video1394 Gets 10 */
#define VIDEO1394_IOC_LISTEN_CHANNEL \
_IOWR('#', 0x10, struct video1394_mmap)
#define VIDEO1394_IOC_UNLISTEN_CHANNEL \
_IOW ('#', 0x11, int)
#define VIDEO1394_IOC_LISTEN_QUEUE_BUFFER \
_IOW ('#', 0x12, struct video1394_wait)
#define VIDEO1394_IOC_LISTEN_WAIT_BUFFER \
_IOWR('#', 0x13, struct video1394_wait)
#define VIDEO1394_IOC_TALK_CHANNEL \
_IOWR('#', 0x14, struct video1394_mmap)
#define VIDEO1394_IOC_UNTALK_CHANNEL \
_IOW ('#', 0x15, int)
#define VIDEO1394_IOC_TALK_QUEUE_BUFFER \
_IOW ('#', 0x16, sizeof (struct video1394_wait) + \
sizeof (struct video1394_queue_variable))
#define VIDEO1394_IOC_TALK_WAIT_BUFFER \
_IOW ('#', 0x17, struct video1394_wait)
#define VIDEO1394_IOC_LISTEN_POLL_BUFFER \
_IOWR('#', 0x18, struct video1394_wait)
/* Raw1394's ISO interface */
#define RAW1394_IOC_ISO_XMIT_INIT \
_IOW ('#', 0x1a, struct raw1394_iso_status)
#define RAW1394_IOC_ISO_RECV_INIT \
_IOWR('#', 0x1b, struct raw1394_iso_status)
#define RAW1394_IOC_ISO_RECV_START \
_IOC (_IOC_WRITE, '#', 0x1c, sizeof(int) * 3)
#define RAW1394_IOC_ISO_XMIT_START \
_IOC (_IOC_WRITE, '#', 0x1d, sizeof(int) * 2)
#define RAW1394_IOC_ISO_XMIT_RECV_STOP \
_IO ('#', 0x1e)
#define RAW1394_IOC_ISO_GET_STATUS \
_IOR ('#', 0x1f, struct raw1394_iso_status)
#define RAW1394_IOC_ISO_SHUTDOWN \
_IO ('#', 0x20)
#define RAW1394_IOC_ISO_QUEUE_ACTIVITY \
_IO ('#', 0x21)
#define RAW1394_IOC_ISO_RECV_LISTEN_CHANNEL \
_IOW ('#', 0x22, unsigned char)
#define RAW1394_IOC_ISO_RECV_UNLISTEN_CHANNEL \
_IOW ('#', 0x23, unsigned char)
#define RAW1394_IOC_ISO_RECV_SET_CHANNEL_MASK \
_IOW ('#', 0x24, u64)
#define RAW1394_IOC_ISO_RECV_PACKETS \
_IOW ('#', 0x25, struct raw1394_iso_packets)
#define RAW1394_IOC_ISO_RECV_RELEASE_PACKETS \
_IOW ('#', 0x26, unsigned int)
#define RAW1394_IOC_ISO_XMIT_PACKETS \
_IOW ('#', 0x27, struct raw1394_iso_packets)
#define RAW1394_IOC_ISO_XMIT_SYNC \
_IO ('#', 0x28)
#endif /* __IEEE1394_IOCTL_H */
...@@ -1000,7 +1000,7 @@ int ieee1394_register_chardev(int blocknum, ...@@ -1000,7 +1000,7 @@ int ieee1394_register_chardev(int blocknum,
struct file_operations *file_ops) struct file_operations *file_ops)
{ {
int retval; int retval;
if( (blocknum < 0) || (blocknum > 15) ) if( (blocknum < 0) || (blocknum > 15) )
return -EINVAL; return -EINVAL;
...@@ -1016,7 +1016,7 @@ int ieee1394_register_chardev(int blocknum, ...@@ -1016,7 +1016,7 @@ int ieee1394_register_chardev(int blocknum,
/* block already taken */ /* block already taken */
retval = -EBUSY; retval = -EBUSY;
} }
write_unlock(&ieee1394_chardevs_lock); write_unlock(&ieee1394_chardevs_lock);
return retval; return retval;
...@@ -1027,14 +1027,14 @@ void ieee1394_unregister_chardev(int blocknum) ...@@ -1027,14 +1027,14 @@ void ieee1394_unregister_chardev(int blocknum)
{ {
if( (blocknum < 0) || (blocknum > 15) ) if( (blocknum < 0) || (blocknum > 15) )
return; return;
write_lock(&ieee1394_chardevs_lock); write_lock(&ieee1394_chardevs_lock);
if(ieee1394_chardevs[blocknum].file_ops) { if(ieee1394_chardevs[blocknum].file_ops) {
ieee1394_chardevs[blocknum].file_ops = NULL; ieee1394_chardevs[blocknum].file_ops = NULL;
ieee1394_chardevs[blocknum].module = NULL; ieee1394_chardevs[blocknum].module = NULL;
} }
write_unlock(&ieee1394_chardevs_lock); write_unlock(&ieee1394_chardevs_lock);
} }
...@@ -1055,7 +1055,7 @@ static int ieee1394_get_chardev(int blocknum, ...@@ -1055,7 +1055,7 @@ static int ieee1394_get_chardev(int blocknum,
{ {
int ret = 0; int ret = 0;
if( (blocknum < 0) || (blocknum > 15) ) if ((blocknum < 0) || (blocknum > 15))
return ret; return ret;
read_lock(&ieee1394_chardevs_lock); read_lock(&ieee1394_chardevs_lock);
...@@ -1063,15 +1063,15 @@ static int ieee1394_get_chardev(int blocknum, ...@@ -1063,15 +1063,15 @@ static int ieee1394_get_chardev(int blocknum,
*module = ieee1394_chardevs[blocknum].module; *module = ieee1394_chardevs[blocknum].module;
*file_ops = ieee1394_chardevs[blocknum].file_ops; *file_ops = ieee1394_chardevs[blocknum].file_ops;
if(*file_ops == NULL) if (*file_ops == NULL)
goto out; goto out;
if(!try_module_get(*module)) if (!try_module_get(*module))
goto out; goto out;
/* success! */ /* success! */
ret = 1; ret = 1;
out: out:
read_unlock(&ieee1394_chardevs_lock); read_unlock(&ieee1394_chardevs_lock);
return ret; return ret;
...@@ -1101,11 +1101,11 @@ static int ieee1394_dispatch_open(struct inode *inode, struct file *file) ...@@ -1101,11 +1101,11 @@ static int ieee1394_dispatch_open(struct inode *inode, struct file *file)
reference count of whatever module file->f_op->owner points reference count of whatever module file->f_op->owner points
to, immediately after this function returns. to, immediately after this function returns.
*/ */
/* shift away lower four bits of the minor /* shift away lower four bits of the minor
to get the index of the ieee1394_driver to get the index of the ieee1394_driver
we want */ we want */
blocknum = (minor(inode->i_rdev) >> 4) & 0xF; blocknum = (minor(inode->i_rdev) >> 4) & 0xF;
/* look up the driver */ /* look up the driver */
...@@ -1126,14 +1126,14 @@ static int ieee1394_dispatch_open(struct inode *inode, struct file *file) ...@@ -1126,14 +1126,14 @@ static int ieee1394_dispatch_open(struct inode *inode, struct file *file)
if(retval == 0) { if(retval == 0) {
/* If the open() succeeded, then ieee1394 will be left /* If the open() succeeded, then ieee1394 will be left
with an extra module reference, so we discard it here. * with an extra module reference, so we discard it here.
*
The task-specific driver still has the extra * The task-specific driver still has the extra reference
reference given to it by ieee1394_get_chardev(). * given to it by ieee1394_get_chardev(). This extra
This extra reference prevents the module from * reference prevents the module from unloading while the
unloading while the file is open, and will be * file is open, and will be dropped by the VFS when the
dropped by the VFS when the file is released. * file is released. */
*/
module_put(THIS_MODULE); module_put(THIS_MODULE);
} else { } else {
/* point the file's f_ops back to ieee1394. The VFS will then /* point the file's f_ops back to ieee1394. The VFS will then
...@@ -1142,11 +1142,10 @@ static int ieee1394_dispatch_open(struct inode *inode, struct file *file) ...@@ -1142,11 +1142,10 @@ static int ieee1394_dispatch_open(struct inode *inode, struct file *file)
file->f_op = &ieee1394_chardev_ops; file->f_op = &ieee1394_chardev_ops;
/* if the open() failed, then we need to drop the /* If the open() failed, then we need to drop the extra
extra reference we gave to the task-specific * reference we gave to the task-specific driver. */
driver */
module_put(module); module_put(module);
} }
return retval; return retval;
...@@ -1199,10 +1198,10 @@ static void __exit ieee1394_cleanup(void) ...@@ -1199,10 +1198,10 @@ static void __exit ieee1394_cleanup(void)
kmem_cache_destroy(hpsb_packet_cache); kmem_cache_destroy(hpsb_packet_cache);
unregister_chrdev(IEEE1394_MAJOR, "ieee1394"); unregister_chrdev(IEEE1394_MAJOR, "ieee1394");
/* it's ok to pass a NULL devfs_handle to devfs_unregister */ /* it's ok to pass a NULL devfs_handle to devfs_unregister */
devfs_unregister(ieee1394_devfs_handle); devfs_unregister(ieee1394_devfs_handle);
remove_proc_entry("ieee1394", proc_bus); remove_proc_entry("ieee1394", proc_bus);
} }
...@@ -1298,10 +1297,16 @@ EXPORT_SYMBOL(hpsb_iso_xmit_init); ...@@ -1298,10 +1297,16 @@ EXPORT_SYMBOL(hpsb_iso_xmit_init);
EXPORT_SYMBOL(hpsb_iso_recv_init); EXPORT_SYMBOL(hpsb_iso_recv_init);
EXPORT_SYMBOL(hpsb_iso_xmit_start); EXPORT_SYMBOL(hpsb_iso_xmit_start);
EXPORT_SYMBOL(hpsb_iso_recv_start); EXPORT_SYMBOL(hpsb_iso_recv_start);
EXPORT_SYMBOL(hpsb_iso_recv_listen_channel);
EXPORT_SYMBOL(hpsb_iso_recv_unlisten_channel);
EXPORT_SYMBOL(hpsb_iso_recv_set_channel_mask);
EXPORT_SYMBOL(hpsb_iso_stop); EXPORT_SYMBOL(hpsb_iso_stop);
EXPORT_SYMBOL(hpsb_iso_shutdown); EXPORT_SYMBOL(hpsb_iso_shutdown);
EXPORT_SYMBOL(hpsb_iso_xmit_queue_packets); EXPORT_SYMBOL(hpsb_iso_xmit_queue_packet);
EXPORT_SYMBOL(hpsb_iso_xmit_sync);
EXPORT_SYMBOL(hpsb_iso_recv_release_packets); EXPORT_SYMBOL(hpsb_iso_recv_release_packets);
EXPORT_SYMBOL(hpsb_iso_n_ready); EXPORT_SYMBOL(hpsb_iso_n_ready);
EXPORT_SYMBOL(hpsb_iso_packet_data); EXPORT_SYMBOL(hpsb_iso_packet_sent);
EXPORT_SYMBOL(hpsb_iso_packet_info); EXPORT_SYMBOL(hpsb_iso_packet_received);
EXPORT_SYMBOL(hpsb_iso_wake);
This diff is collapsed.
...@@ -17,25 +17,37 @@ ...@@ -17,25 +17,37 @@
/* high-level ISO interface */ /* high-level ISO interface */
/* per-packet data embedded in the ringbuffer */ /* This API sends and receives isochronous packets on a large,
virtually-contiguous kernel memory buffer. The buffer may be mapped
into a user-space process for zero-copy transmission and reception.
There are no explicit boundaries between packets in the buffer. A
packet may be transmitted or received at any location. However,
low-level drivers may impose certain restrictions on alignment or
size of packets. (e.g. in OHCI no packet may cross a page boundary,
and packets should be quadlet-aligned)
*/
/* Packet descriptor - the API maintains a ring buffer of these packet
descriptors in kernel memory (hpsb_iso.infos[]). */
struct hpsb_iso_packet_info { struct hpsb_iso_packet_info {
unsigned short len; /* offset of data payload relative to the first byte of the buffer */
unsigned short cycle; __u32 offset;
unsigned char channel; /* recv only */
unsigned char tag;
unsigned char sy;
};
/* /* length of the data payload, in bytes (not including the isochronous header) */
* each packet in the ringbuffer consists of three things: __u16 len;
* 1. the packet's data payload (no isochronous header)
* 2. a struct hpsb_iso_packet_info /* (recv only) the cycle number (mod 8000) on which the packet was received */
* 3. some empty space before the next packet __u16 cycle;
*
* packets are separated by hpsb_iso.buf_stride bytes /* (recv only) channel on which the packet was received */
* an even number of packets fit on one page __u8 channel;
* no packet can be larger than one page
*/ /* 2-bit 'tag' and 4-bit 'sy' fields of the isochronous header */
__u8 tag;
__u8 sy;
};
enum hpsb_iso_type { HPSB_ISO_RECV = 0, HPSB_ISO_XMIT = 1 }; enum hpsb_iso_type { HPSB_ISO_RECV = 0, HPSB_ISO_XMIT = 1 };
...@@ -45,48 +57,49 @@ struct hpsb_iso { ...@@ -45,48 +57,49 @@ struct hpsb_iso {
/* pointer to low-level driver and its private data */ /* pointer to low-level driver and its private data */
struct hpsb_host *host; struct hpsb_host *host;
void *hostdata; void *hostdata;
/* function to be called (from interrupt context) when the iso status changes */ /* a function to be called (from interrupt context) after
outgoing packets have been sent, or incoming packets have
arrived */
void (*callback)(struct hpsb_iso*); void (*callback)(struct hpsb_iso*);
/* wait for buffer space */
wait_queue_head_t waitq;
int speed; /* SPEED_100, 200, or 400 */ int speed; /* SPEED_100, 200, or 400 */
int channel; int channel; /* -1 if multichannel */
/* greatest # of packets between interrupts - controls /* greatest # of packets between interrupts - controls
the maximum latency of the buffer */ the maximum latency of the buffer */
int irq_interval; int irq_interval;
/* the packet ringbuffer */ /* the buffer for packet data payloads */
struct dma_region buf; struct dma_region data_buf;
/* size of data_buf, in bytes (always a multiple of PAGE_SIZE) */
unsigned int buf_size;
/* ringbuffer of packet descriptors in regular kernel memory */
struct hpsb_iso_packet_info *infos;
/* # of packets in the ringbuffer */ /* # of packets in the ringbuffer */
unsigned int buf_packets; unsigned int buf_packets;
/* offset between successive packets, in bytes - /* protects packet cursors */
you can assume that this is a power of 2, spinlock_t lock;
and less than or equal to the page size */
int buf_stride;
/* largest possible packet size, in bytes */
unsigned int max_packet_size;
/* offset relative to (buf.kvirt + N*buf_stride) at which
the data payload begins for packet N */
int packet_data_offset;
/* offset relative to (buf.kvirt + N*buf_stride) at which the
struct hpsb_iso_packet_info is stored for packet N */
int packet_info_offset;
/* the index of the next packet that will be produced /* the index of the next packet that will be produced
or consumed by the user */ or consumed by the user */
int first_packet; int first_packet;
/* number of packets owned by the low-level driver and /* the index of the next packet that will be transmitted
queued for transmission or reception. or received by the 1394 hardware */
this is related to the number of packets available int pkt_dma;
to the user process: n_ready = buf_packets - n_dma_packets */
atomic_t n_dma_packets; /* how many packets, starting at first_packet:
(transmit) are ready to be filled with data
(receive) contain received data */
int n_ready_packets;
/* how many times the buffer has overflowed or underflowed */ /* how many times the buffer has overflowed or underflowed */
atomic_t overflows; atomic_t overflows;
...@@ -99,8 +112,12 @@ struct hpsb_iso { ...@@ -99,8 +112,12 @@ struct hpsb_iso {
/* # of packets left to prebuffer (xmit only) */ /* # of packets left to prebuffer (xmit only) */
int prebuffer; int prebuffer;
/* starting cycle (xmit only) */ /* starting cycle for DMA (xmit only) */
int start_cycle; int start_cycle;
/* cycle at which next packet will be transmitted,
-1 if not known */
int xmit_cycle;
}; };
/* functions available to high-level drivers (e.g. raw1394) */ /* functions available to high-level drivers (e.g. raw1394) */
...@@ -108,30 +125,40 @@ struct hpsb_iso { ...@@ -108,30 +125,40 @@ struct hpsb_iso {
/* allocate the buffer and DMA context */ /* allocate the buffer and DMA context */
struct hpsb_iso* hpsb_iso_xmit_init(struct hpsb_host *host, struct hpsb_iso* hpsb_iso_xmit_init(struct hpsb_host *host,
unsigned int data_buf_size,
unsigned int buf_packets, unsigned int buf_packets,
unsigned int max_packet_size,
int channel, int channel,
int speed, int speed,
int irq_interval, int irq_interval,
void (*callback)(struct hpsb_iso*)); void (*callback)(struct hpsb_iso*));
/* note: if channel = -1, multi-channel receive is enabled */
struct hpsb_iso* hpsb_iso_recv_init(struct hpsb_host *host, struct hpsb_iso* hpsb_iso_recv_init(struct hpsb_host *host,
unsigned int data_buf_size,
unsigned int buf_packets, unsigned int buf_packets,
unsigned int max_packet_size,
int channel, int channel,
int irq_interval, int irq_interval,
void (*callback)(struct hpsb_iso*)); void (*callback)(struct hpsb_iso*));
/* multi-channel only */
int hpsb_iso_recv_listen_channel(struct hpsb_iso *iso, unsigned char channel);
int hpsb_iso_recv_unlisten_channel(struct hpsb_iso *iso, unsigned char channel);
int hpsb_iso_recv_set_channel_mask(struct hpsb_iso *iso, u64 mask);
/* start/stop DMA */ /* start/stop DMA */
int hpsb_iso_xmit_start(struct hpsb_iso *iso, int start_on_cycle, int prebuffer); int hpsb_iso_xmit_start(struct hpsb_iso *iso, int start_on_cycle, int prebuffer);
int hpsb_iso_recv_start(struct hpsb_iso *iso, int start_on_cycle); int hpsb_iso_recv_start(struct hpsb_iso *iso, int start_on_cycle, int tag_mask, int sync);
void hpsb_iso_stop(struct hpsb_iso *iso); void hpsb_iso_stop(struct hpsb_iso *iso);
/* deallocate buffer and DMA context */ /* deallocate buffer and DMA context */
void hpsb_iso_shutdown(struct hpsb_iso *iso); void hpsb_iso_shutdown(struct hpsb_iso *iso);
/* N packets have been written to the buffer; queue them for transmission */ /* queue a packet for transmission. 'offset' is relative to the beginning of the
int hpsb_iso_xmit_queue_packets(struct hpsb_iso *xmit, unsigned int n_packets); DMA buffer, where the packet's data payload should already have been placed */
int hpsb_iso_xmit_queue_packet(struct hpsb_iso *iso, u32 offset, u16 len, u8 tag, u8 sy);
/* wait until all queued packets have been transmitted to the bus */
int hpsb_iso_xmit_sync(struct hpsb_iso *iso);
/* N packets have been read out of the buffer, re-use the buffer space */ /* N packets have been read out of the buffer, re-use the buffer space */
int hpsb_iso_recv_release_packets(struct hpsb_iso *recv, unsigned int n_packets); int hpsb_iso_recv_release_packets(struct hpsb_iso *recv, unsigned int n_packets);
...@@ -139,10 +166,19 @@ int hpsb_iso_recv_release_packets(struct hpsb_iso *recv, unsigned int n_packets ...@@ -139,10 +166,19 @@ int hpsb_iso_recv_release_packets(struct hpsb_iso *recv, unsigned int n_packets
/* returns # of packets ready to send or receive */ /* returns # of packets ready to send or receive */
int hpsb_iso_n_ready(struct hpsb_iso *iso); int hpsb_iso_n_ready(struct hpsb_iso *iso);
/* returns a pointer to the payload of packet 'pkt' */ /* the following are callbacks available to low-level drivers */
unsigned char* hpsb_iso_packet_data(struct hpsb_iso *iso, unsigned int pkt);
/* call after a packet has been transmitted to the bus (interrupt context is OK)
'cycle' is the _exact_ cycle the packet was sent on
'error' should be non-zero if some sort of error occurred when sending the packet
*/
void hpsb_iso_packet_sent(struct hpsb_iso *iso, int cycle, int error);
/* call after a packet has been received (interrupt context OK) */
void hpsb_iso_packet_received(struct hpsb_iso *iso, u32 offset, u16 len,
u16 cycle, u8 channel, u8 tag, u8 sy);
/* returns a pointer to the info struct of packet 'pkt' */ /* call to wake waiting processes after buffer space has opened up. */
struct hpsb_iso_packet_info* hpsb_iso_packet_info(struct hpsb_iso *iso, unsigned int pkt); void hpsb_iso_wake(struct hpsb_iso *iso);
#endif /* IEEE1394_ISO_H */ #endif /* IEEE1394_ISO_H */
...@@ -1089,8 +1089,7 @@ static int read_businfo_block(struct hpsb_host *host, nodeid_t nodeid, unsigned ...@@ -1089,8 +1089,7 @@ static int read_businfo_block(struct hpsb_host *host, nodeid_t nodeid, unsigned
static void nodemgr_remove_node(struct node_entry *ne) static void nodemgr_remove_node(struct node_entry *ne)
{ {
HPSB_DEBUG("%s removed: Node[" NODE_BUS_FMT "] GUID[%016Lx] [%s]", HPSB_DEBUG("Device removed: Node[" NODE_BUS_FMT "] GUID[%016Lx] [%s]",
(ne->host->node_id == ne->nodeid) ? "Host" : "Device",
NODE_BUS_ARGS(ne->nodeid), (unsigned long long)ne->guid, NODE_BUS_ARGS(ne->nodeid), (unsigned long long)ne->guid,
ne->vendor_name ?: "Unknown"); ne->vendor_name ?: "Unknown");
......
This diff is collapsed.
...@@ -109,6 +109,7 @@ struct dma_rcv_ctx { ...@@ -109,6 +109,7 @@ struct dma_rcv_ctx {
int ctrlClear; int ctrlClear;
int ctrlSet; int ctrlSet;
int cmdPtr; int cmdPtr;
int ctxtMatch;
}; };
/* DMA transmit context */ /* DMA transmit context */
...@@ -145,7 +146,8 @@ struct ohci1394_iso_tasklet { ...@@ -145,7 +146,8 @@ struct ohci1394_iso_tasklet {
struct tasklet_struct tasklet; struct tasklet_struct tasklet;
struct list_head link; struct list_head link;
int context; int context;
enum { OHCI_ISO_TRANSMIT, OHCI_ISO_RECEIVE } type; enum { OHCI_ISO_TRANSMIT, OHCI_ISO_RECEIVE,
OHCI_ISO_MULTICHANNEL_RECEIVE } type;
}; };
struct ti_ohci { struct ti_ohci {
...@@ -170,7 +172,7 @@ struct ti_ohci { ...@@ -170,7 +172,7 @@ struct ti_ohci {
/* dma buffer for self-id packets */ /* dma buffer for self-id packets */
quadlet_t *selfid_buf_cpu; quadlet_t *selfid_buf_cpu;
dma_addr_t selfid_buf_bus; dma_addr_t selfid_buf_bus;
/* buffer for csr config rom */ /* buffer for csr config rom */
quadlet_t *csr_config_rom_cpu; quadlet_t *csr_config_rom_cpu;
dma_addr_t csr_config_rom_bus; dma_addr_t csr_config_rom_bus;
...@@ -187,18 +189,28 @@ struct ti_ohci { ...@@ -187,18 +189,28 @@ struct ti_ohci {
struct dma_trm_ctx at_req_context; struct dma_trm_ctx at_req_context;
/* iso receive */ /* iso receive */
struct dma_rcv_ctx ir_context;
struct ohci1394_iso_tasklet ir_tasklet;
spinlock_t IR_channel_lock;
int nb_iso_rcv_ctx; int nb_iso_rcv_ctx;
unsigned long ir_ctx_usage; /* use test_and_set_bit() for atomicity */ unsigned long ir_ctx_usage; /* use test_and_set_bit() for atomicity */
unsigned long ir_multichannel_used; /* ditto */
spinlock_t IR_channel_lock;
/* iso receive (legacy API) */
u64 ir_legacy_channels; /* note: this differs from ISO_channel_usage;
it only accounts for channels listened to
by the legacy API, so that we can know when
it is safe to free the legacy API context */
struct dma_rcv_ctx ir_legacy_context;
struct ohci1394_iso_tasklet ir_legacy_tasklet;
/* iso transmit */ /* iso transmit */
struct dma_trm_ctx it_context;
struct ohci1394_iso_tasklet it_tasklet;
int nb_iso_xmit_ctx; int nb_iso_xmit_ctx;
unsigned long it_ctx_usage; /* use test_and_set_bit() for atomicity */ unsigned long it_ctx_usage; /* use test_and_set_bit() for atomicity */
/* iso transmit (legacy API) */
struct dma_trm_ctx it_legacy_context;
struct ohci1394_iso_tasklet it_legacy_tasklet;
u64 ISO_channel_usage; u64 ISO_channel_usage;
/* IEEE-1394 part follows */ /* IEEE-1394 part follows */
...@@ -213,10 +225,10 @@ struct ti_ohci { ...@@ -213,10 +225,10 @@ struct ti_ohci {
/* Tasklets for iso receive and transmit, used by video1394, /* Tasklets for iso receive and transmit, used by video1394,
* amdtp and dv1394 */ * amdtp and dv1394 */
struct list_head iso_tasklet_list; struct list_head iso_tasklet_list;
spinlock_t iso_tasklet_list_lock; spinlock_t iso_tasklet_list_lock;
/* Swap the selfid buffer? */ /* Swap the selfid buffer? */
unsigned int selfid_swap:1; unsigned int selfid_swap:1;
/* Some Apple chipset seem to swap incoming headers for us */ /* Some Apple chipset seem to swap incoming headers for us */
...@@ -385,7 +397,7 @@ static inline u32 reg_read(const struct ti_ohci *ohci, int offset) ...@@ -385,7 +397,7 @@ static inline u32 reg_read(const struct ti_ohci *ohci, int offset)
/* OHCI evt_* error types, table 3-2 of the OHCI 1.1 spec. */ /* OHCI evt_* error types, table 3-2 of the OHCI 1.1 spec. */
#define EVT_NO_STATUS 0x0 /* No event status */ #define EVT_NO_STATUS 0x0 /* No event status */
#define EVT_RESERVED 0x1 /* Reserved, not used !!! */ #define EVT_RESERVED_A 0x1 /* Reserved, not used !!! */
#define EVT_LONG_PACKET 0x2 /* The revc data was longer than the buf */ #define EVT_LONG_PACKET 0x2 /* The revc data was longer than the buf */
#define EVT_MISSING_ACK 0x3 /* A subaction gap was detected before an ack #define EVT_MISSING_ACK 0x3 /* A subaction gap was detected before an ack
arrived, or recv'd ack had a parity error */ arrived, or recv'd ack had a parity error */
...@@ -404,6 +416,17 @@ static inline u32 reg_read(const struct ti_ohci *ohci, int offset) ...@@ -404,6 +416,17 @@ static inline u32 reg_read(const struct ti_ohci *ohci, int offset)
16-bit host memory write */ 16-bit host memory write */
#define EVT_BUS_RESET 0x9 /* Identifies a PHY packet in the recv buffer as #define EVT_BUS_RESET 0x9 /* Identifies a PHY packet in the recv buffer as
being a synthesized bus reset packet */ being a synthesized bus reset packet */
#define EVT_TIMEOUT 0xa /* Indicates that the asynchronous transmit response
packet expired and was not transmitted, or that an
IT DMA context experienced a skip processing overflow */
#define EVT_TCODE_ERR 0xb /* A bad tCode is associated with this packet.
The packet was flushed */
#define EVT_RESERVED_B 0xc /* Reserved, not used !!! */
#define EVT_RESERVED_C 0xd /* Reserved, not used !!! */
#define EVT_UNKNOWN 0xe /* An error condition has occurred that cannot be
represented by any other event codes defined herein. */
#define EVT_FLUSHED 0xf /* Send by the link side of output FIFO when asynchronous
packets are being flushed due to a bus reset. */
#define OHCI1394_TCODE_PHY 0xE #define OHCI1394_TCODE_PHY 0xE
...@@ -416,8 +439,8 @@ int ohci1394_register_iso_tasklet(struct ti_ohci *ohci, ...@@ -416,8 +439,8 @@ int ohci1394_register_iso_tasklet(struct ti_ohci *ohci,
void ohci1394_unregister_iso_tasklet(struct ti_ohci *ohci, void ohci1394_unregister_iso_tasklet(struct ti_ohci *ohci,
struct ohci1394_iso_tasklet *tasklet); struct ohci1394_iso_tasklet *tasklet);
void ohci1394_stop_context (struct ti_ohci *ohci, int reg, char *msg); /* returns zero if successful, one if DMA context is locked up */
int ohci1394_stop_context (struct ti_ohci *ohci, int reg, char *msg);
struct ti_ohci *ohci1394_get_struct(int card_num); struct ti_ohci *ohci1394_get_struct(int card_num);
#endif #endif
This diff is collapsed.
...@@ -95,6 +95,7 @@ struct ti_lynx { ...@@ -95,6 +95,7 @@ struct ti_lynx {
struct lynx_send_data { struct lynx_send_data {
pcl_t pcl_start, pcl; pcl_t pcl_start, pcl;
struct list_head queue; struct list_head queue;
struct list_head pcl_queue; /* this queue contains at most one packet */
spinlock_t queue_lock; spinlock_t queue_lock;
dma_addr_t header_dma, data_dma; dma_addr_t header_dma, data_dma;
int channel; int channel;
...@@ -514,13 +515,13 @@ static inline void run_pcl(const struct ti_lynx *lynx, pcl_t pclid, int dmachan) ...@@ -514,13 +515,13 @@ static inline void run_pcl(const struct ti_lynx *lynx, pcl_t pclid, int dmachan)
static quadlet_t lynx_csr_rom[] = { static quadlet_t lynx_csr_rom[] = {
/* bus info block offset (hex) */ /* bus info block offset (hex) */
_(0x04040000), /* info/CRC length, CRC 400 */ _(0x04046aaf), /* info/CRC length, CRC 400 */
_(0x31333934), /* 1394 magic number 404 */ _(0x31333934), /* 1394 magic number 404 */
_(0xf064a000), /* misc. settings 408 */ _(0xf064a000), /* misc. settings 408 */
_(0x08002850), /* vendor ID, chip ID high 40c */ _(0x08002850), /* vendor ID, chip ID high 40c */
_(0x0000ffff), /* chip ID low 410 */ _(0x0000ffff), /* chip ID low 410 */
/* root directory */ /* root directory */
_(0x00090000), /* directory length, CRC 414 */ _(0x00095778), /* directory length, CRC 414 */
_(0x03080028), /* vendor ID (Texas Instr.) 418 */ _(0x03080028), /* vendor ID (Texas Instr.) 418 */
_(0x81000008), /* offset to textual ID 41c */ _(0x81000008), /* offset to textual ID 41c */
_(0x0c000200), /* node capabilities 420 */ _(0x0c000200), /* node capabilities 420 */
...@@ -530,8 +531,8 @@ static quadlet_t lynx_csr_rom[] = { ...@@ -530,8 +531,8 @@ static quadlet_t lynx_csr_rom[] = {
_(0x81000014), /* offset to textual ID 430 */ _(0x81000014), /* offset to textual ID 430 */
_(0x09000000), /* node hardware version 434 */ _(0x09000000), /* node hardware version 434 */
_(0x81000018), /* offset to textual ID 438 */ _(0x81000018), /* offset to textual ID 438 */
/* module vendor ID textual */ /* module vendor ID textual */
_(0x00070000), /* CRC length, CRC 43c */ _(0x00070812), /* CRC length, CRC 43c */
_(0x00000000), /* 440 */ _(0x00000000), /* 440 */
_(0x00000000), /* 444 */ _(0x00000000), /* 444 */
_(0x54455841), /* "Texas Instruments" 448 */ _(0x54455841), /* "Texas Instruments" 448 */
...@@ -540,25 +541,25 @@ static quadlet_t lynx_csr_rom[] = { ...@@ -540,25 +541,25 @@ static quadlet_t lynx_csr_rom[] = {
_(0x4d454e54), /* 454 */ _(0x4d454e54), /* 454 */
_(0x53000000), /* 458 */ _(0x53000000), /* 458 */
/* node unique ID leaf */ /* node unique ID leaf */
_(0x00020000), /* CRC length, CRC 45c */ _(0x00022ead), /* CRC length, CRC 45c */
_(0x08002850), /* vendor ID, chip ID high 460 */ _(0x08002850), /* vendor ID, chip ID high 460 */
_(0x0000ffff), /* chip ID low 464 */ _(0x0000ffff), /* chip ID low 464 */
/* module dependent info */ /* module dependent info */
_(0x00050000), /* CRC length, CRC 468 */ _(0x0005d837), /* CRC length, CRC 468 */
_(0x81000012), /* offset to module textual ID 46c */ _(0x81000012), /* offset to module textual ID 46c */
_(0x81000017), /* textual descriptor 470 */ _(0x81000017), /* textual descriptor 470 */
_(0x39010000), /* SRAM size 474 */ _(0x39010000), /* SRAM size 474 */
_(0x3a010000), /* AUXRAM size 478 */ _(0x3a010000), /* AUXRAM size 478 */
_(0x3b000000), /* AUX device 47c */ _(0x3b000000), /* AUX device 47c */
/* module textual ID */ /* module textual ID */
_(0x00050000), /* CRC length, CRC 480 */ _(0x000594df), /* CRC length, CRC 480 */
_(0x00000000), /* 484 */ _(0x00000000), /* 484 */
_(0x00000000), /* 488 */ _(0x00000000), /* 488 */
_(0x54534231), /* "TSB12LV21" 48c */ _(0x54534231), /* "TSB12LV21" 48c */
_(0x324c5632), /* 490 */ _(0x324c5632), /* 490 */
_(0x31000000), /* 494 */ _(0x31000000), /* 494 */
/* part number */ /* part number */
_(0x00060000), /* CRC length, CRC 498 */ _(0x00068405), /* CRC length, CRC 498 */
_(0x00000000), /* 49c */ _(0x00000000), /* 49c */
_(0x00000000), /* 4a0 */ _(0x00000000), /* 4a0 */
_(0x39383036), /* "9806000-0001" 4a4 */ _(0x39383036), /* "9806000-0001" 4a4 */
...@@ -566,14 +567,14 @@ static quadlet_t lynx_csr_rom[] = { ...@@ -566,14 +567,14 @@ static quadlet_t lynx_csr_rom[] = {
_(0x30303031), /* 4ac */ _(0x30303031), /* 4ac */
_(0x20000001), /* 4b0 */ _(0x20000001), /* 4b0 */
/* module hardware version textual */ /* module hardware version textual */
_(0x00050000), /* CRC length, CRC 4b4 */ _(0x00056501), /* CRC length, CRC 4b4 */
_(0x00000000), /* 4b8 */ _(0x00000000), /* 4b8 */
_(0x00000000), /* 4bc */ _(0x00000000), /* 4bc */
_(0x5453424b), /* "TSBKPCITST" 4c0 */ _(0x5453424b), /* "TSBKPCITST" 4c0 */
_(0x50434954), /* 4c4 */ _(0x50434954), /* 4c4 */
_(0x53540000), /* 4c8 */ _(0x53540000), /* 4c8 */
/* node hardware version textual */ /* node hardware version textual */
_(0x00050000), /* CRC length, CRC 4d0 */ _(0x0005d805), /* CRC length, CRC 4d0 */
_(0x00000000), /* 4d4 */ _(0x00000000), /* 4d4 */
_(0x00000000), /* 4d8 */ _(0x00000000), /* 4d8 */
_(0x54534232), /* "TSB21LV03" 4dc */ _(0x54534232), /* "TSB21LV03" 4dc */
......
#ifndef IEEE1394_RAW1394_PRIVATE_H
#define IEEE1394_RAW1394_PRIVATE_H
/* header for definitions that are private to the raw1394 driver
and not visible to user-space */
#define RAW1394_DEVICE_MAJOR 171
#define RAW1394_DEVICE_NAME "raw1394"
struct iso_block_store {
atomic_t refcount;
size_t data_size;
quadlet_t data[0];
};
enum raw1394_iso_state { RAW1394_ISO_INACTIVE = 0,
RAW1394_ISO_RECV = 1,
RAW1394_ISO_XMIT = 2 };
struct file_info {
struct list_head list;
enum { opened, initialized, connected } state;
unsigned int protocol_version;
struct hpsb_host *host;
struct list_head req_pending;
struct list_head req_complete;
struct semaphore complete_sem;
spinlock_t reqlists_lock;
wait_queue_head_t poll_wait_complete;
struct list_head addr_list;
u8 *fcp_buffer;
/* old ISO API */
u64 listen_channels;
quadlet_t *iso_buffer;
size_t iso_buffer_length;
u8 notification; /* (busreset-notification) RAW1394_NOTIFY_OFF/ON */
/* new rawiso API */
enum raw1394_iso_state iso_state;
struct hpsb_iso *iso_handle;
};
struct arm_addr {
struct list_head addr_list; /* file_info list */
u64 start, end;
u64 arm_tag;
u8 access_rights;
u8 notification_options;
u8 client_transactions;
u64 recvb;
u16 rec_length;
u8 *addr_space_buffer; /* accessed by read/write/lock */
};
struct pending_request {
struct list_head list;
struct file_info *file_info;
struct hpsb_packet *packet;
struct iso_block_store *ibs;
quadlet_t *data;
int free_data;
struct raw1394_request req;
};
struct host_info {
struct list_head list;
struct hpsb_host *host;
struct list_head file_info_list;
};
#endif /* IEEE1394_RAW1394_PRIVATE_H */
This diff is collapsed.
#ifndef IEEE1394_RAW1394_H #ifndef IEEE1394_RAW1394_H
#define IEEE1394_RAW1394_H #define IEEE1394_RAW1394_H
#define RAW1394_DEVICE_MAJOR 171 /* header for the raw1394 API that is exported to user-space */
#define RAW1394_DEVICE_NAME "raw1394"
#define RAW1394_KERNELAPI_VERSION 4 #define RAW1394_KERNELAPI_VERSION 4
...@@ -94,21 +93,21 @@ struct raw1394_khost_list { ...@@ -94,21 +93,21 @@ struct raw1394_khost_list {
}; };
typedef struct arm_request { typedef struct arm_request {
nodeid_t destination_nodeid; __u16 destination_nodeid;
nodeid_t source_nodeid; __u16 source_nodeid;
nodeaddr_t destination_offset; __u64 destination_offset;
u8 tlabel; __u8 tlabel;
u8 tcode; __u8 tcode;
u_int8_t extended_transaction_code; __u8 extended_transaction_code;
u_int32_t generation; __u32 generation;
arm_length_t buffer_length; __u16 buffer_length;
byte_t *buffer; __u8 *buffer;
} *arm_request_t; } *arm_request_t;
typedef struct arm_response { typedef struct arm_response {
int response_code; __s32 response_code;
arm_length_t buffer_length; __u16 buffer_length;
byte_t *buffer; __u8 *buffer;
} *arm_response_t; } *arm_response_t;
typedef struct arm_request_response { typedef struct arm_request_response {
...@@ -117,133 +116,59 @@ typedef struct arm_request_response { ...@@ -117,133 +116,59 @@ typedef struct arm_request_response {
} *arm_request_response_t; } *arm_request_response_t;
/* rawiso API */ /* rawiso API */
#include "ieee1394-ioctl.h"
/* ioctls */
#define RAW1394_ISO_XMIT_INIT 1 /* arg: raw1394_iso_status* */
#define RAW1394_ISO_RECV_INIT 2 /* arg: raw1394_iso_status* */
#define RAW1394_ISO_RECV_START 3 /* arg: int, starting cycle */
#define RAW1394_ISO_XMIT_START 8 /* arg: int[2], { starting cycle, prebuffer } */
#define RAW1394_ISO_STOP 4
#define RAW1394_ISO_GET_STATUS 5 /* arg: raw1394_iso_status* */
#define RAW1394_ISO_PRODUCE_CONSUME 6 /* arg: int, # of packets */
#define RAW1394_ISO_SHUTDOWN 7
/* per-packet metadata embedded in the ringbuffer */ /* per-packet metadata embedded in the ringbuffer */
/* must be identical to hpsb_iso_packet_info in iso.h! */ /* must be identical to hpsb_iso_packet_info in iso.h! */
struct raw1394_iso_packet_info { struct raw1394_iso_packet_info {
unsigned short len; __u32 offset;
unsigned short cycle; __u16 len;
unsigned char channel; /* recv only */ __u16 cycle; /* recv only */
unsigned char tag; __u8 channel; /* recv only */
unsigned char sy; __u8 tag;
__u8 sy;
};
/* argument for RAW1394_ISO_RECV/XMIT_PACKETS ioctls */
struct raw1394_iso_packets {
__u32 n_packets;
struct raw1394_iso_packet_info *infos;
}; };
struct raw1394_iso_config { struct raw1394_iso_config {
unsigned int buf_packets; /* size of packet data buffer, in bytes (will be rounded up to PAGE_SIZE) */
unsigned int max_packet_size; __u32 data_buf_size;
int channel;
int speed; /* xmit only */ /* # of packets to buffer */
int irq_interval; __u32 buf_packets;
/* iso channel (set to -1 for multi-channel recv) */
__s32 channel;
/* xmit only - iso transmission speed */
__u8 speed;
/* max. latency of buffer, in packets (-1 if you don't care) */
__s32 irq_interval;
}; };
/* argument to RAW1394_ISO_XMIT/RECV_INIT and RAW1394_ISO_GET_STATUS */ /* argument to RAW1394_ISO_XMIT/RECV_INIT and RAW1394_ISO_GET_STATUS */
struct raw1394_iso_status { struct raw1394_iso_status {
/* current settings */ /* current settings */
struct raw1394_iso_config config; struct raw1394_iso_config config;
/* byte offset between successive packets in the buffer */
int buf_stride;
/* byte offset of data payload within each packet */
int packet_data_offset;
/* byte offset of struct iso_packet_info within each packet */
int packet_info_offset;
/* index of next packet to fill with data (ISO transmission)
or next packet containing data recieved (ISO reception) */
unsigned int first_packet;
/* number of packets waiting to be filled with data (ISO transmission) /* number of packets waiting to be filled with data (ISO transmission)
or containing data received (ISO reception) */ or containing data received (ISO reception) */
unsigned int n_packets; __u32 n_packets;
/* approximate number of packets dropped due to overflow or /* approximate number of packets dropped due to overflow or
underflow of the packet buffer (a value of zero guarantees underflow of the packet buffer (a value of zero guarantees
that no packets have been dropped) */ that no packets have been dropped) */
unsigned int overflows; __u32 overflows;
};
#ifdef __KERNEL__ /* cycle number at which next packet will be transmitted;
-1 if not known */
struct iso_block_store { __s16 xmit_cycle;
atomic_t refcount;
size_t data_size;
quadlet_t data[0];
}; };
enum raw1394_iso_state { RAW1394_ISO_INACTIVE = 0,
RAW1394_ISO_RECV = 1,
RAW1394_ISO_XMIT = 2 };
struct file_info {
struct list_head list;
enum { opened, initialized, connected } state;
unsigned int protocol_version;
struct hpsb_host *host;
struct list_head req_pending;
struct list_head req_complete;
struct semaphore complete_sem;
spinlock_t reqlists_lock;
wait_queue_head_t poll_wait_complete;
struct list_head addr_list;
u8 *fcp_buffer;
/* old ISO API */
u64 listen_channels;
quadlet_t *iso_buffer;
size_t iso_buffer_length;
u8 notification; /* (busreset-notification) RAW1394_NOTIFY_OFF/ON */
/* new rawiso API */
enum raw1394_iso_state iso_state;
struct hpsb_iso *iso_handle;
};
struct arm_addr {
struct list_head addr_list; /* file_info list */
u64 start, end;
u64 arm_tag;
u8 access_rights;
u8 notification_options;
u8 client_transactions;
u64 recvb;
u16 rec_length;
u8 *addr_space_buffer; /* accessed by read/write/lock */
};
struct pending_request {
struct list_head list;
struct file_info *file_info;
struct hpsb_packet *packet;
struct iso_block_store *ibs;
quadlet_t *data;
int free_data;
struct raw1394_request req;
};
struct host_info {
struct list_head list;
struct hpsb_host *host;
struct list_head file_info_list;
};
#endif /* __KERNEL__ */
#endif /* IEEE1394_RAW1394_H */ #endif /* IEEE1394_RAW1394_H */
This diff is collapsed.
This diff is collapsed.
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
#ifndef _VIDEO_1394_H #ifndef _VIDEO_1394_H
#define _VIDEO_1394_H #define _VIDEO_1394_H
#include "ieee1394-ioctl.h"
#define VIDEO1394_DRIVER_NAME "video1394" #define VIDEO1394_DRIVER_NAME "video1394"
#define VIDEO1394_MAX_SIZE 0x4000000 #define VIDEO1394_MAX_SIZE 0x4000000
...@@ -31,18 +33,6 @@ enum { ...@@ -31,18 +33,6 @@ enum {
VIDEO1394_BUFFER_READY VIDEO1394_BUFFER_READY
}; };
enum {
VIDEO1394_LISTEN_CHANNEL = 0,
VIDEO1394_UNLISTEN_CHANNEL,
VIDEO1394_LISTEN_QUEUE_BUFFER,
VIDEO1394_LISTEN_WAIT_BUFFER, // wait until buffer is ready
VIDEO1394_TALK_CHANNEL,
VIDEO1394_UNTALK_CHANNEL,
VIDEO1394_TALK_QUEUE_BUFFER,
VIDEO1394_TALK_WAIT_BUFFER,
VIDEO1394_LISTEN_POLL_BUFFER // return immediately with -EINTR if not ready
};
#define VIDEO1394_SYNC_FRAMES 0x00000001 #define VIDEO1394_SYNC_FRAMES 0x00000001
#define VIDEO1394_INCLUDE_ISO_HEADERS 0x00000002 #define VIDEO1394_INCLUDE_ISO_HEADERS 0x00000002
#define VIDEO1394_VARIABLE_PACKET_SIZE 0x00000004 #define VIDEO1394_VARIABLE_PACKET_SIZE 0x00000004
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment