Commit 0cd43f83 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'upstream-linus' of...

Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6

* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6: (48 commits)
  ieee1394: raw1394: arm functions slept in atomic context
  ieee1394: sbp2: enable auto spin-up for all SBP-2 devices
  MAINTAINERS: updates to IEEE 1394 subsystem maintainership
  ieee1394: ohci1394: check for errors in suspend or resume
  set power state of firewire host during suspend
  ieee1394: ohci1394: more obvious endianess handling
  ieee1394: ohci1394: fix endianess bug in debug message
  ieee1394: sbp2: don't prefer MODE SENSE 10
  ieee1394: nodemgr: grab class.subsys.rwsem in nodemgr_resume_ne
  ieee1394: nodemgr: fix rwsem recursion
  ieee1394: sbp2: more help in Kconfig
  ieee1394: sbp2: prevent rare deadlock in shutdown
  ieee1394: sbp2: update includes
  ieee1394: sbp2: better handling of transport errors
  ieee1394: sbp2: recheck node generation in sbp2_update
  ieee1394: sbp2: safer agent reset in error handlers
  ieee1394: sbp2: handle "sbp2util_node_write_no_wait failed"
  CONFIG_PM=n slim: drivers/ieee1394/ohci1394.c
  ieee1394: safer definition of empty macros
  video1394: add poll file operation support
  ...
parents db1a19b3 3253b669
......@@ -46,15 +46,6 @@ Who: Jody McIntyre <scjody@modernduck.com>
---------------------------
What: sbp2: module parameter "force_inquiry_hack"
When: July 2006
Why: Superceded by parameter "workarounds". Both parameters are meant to be
used ad-hoc and for single devices only, i.e. not in modprobe.conf,
therefore the impact of this feature replacement should be low.
Who: Stefan Richter <stefanr@s5r6.in-berlin.de>
---------------------------
What: Video4Linux API 1 ioctls and video_decoder.h from Video devices.
When: July 2006
Why: V4L1 AP1 was replaced by V4L2 API. during migration from 2.4 to 2.6
......
......@@ -1398,36 +1398,29 @@ M: Gadi Oxman <gadio@netvision.net.il>
L: linux-kernel@vger.kernel.org
S: Maintained
IEEE 1394 ETHERNET (eth1394)
L: linux1394-devel@lists.sourceforge.net
W: http://www.linux1394.org/
S: Orphan
IEEE 1394 SUBSYSTEM
P: Ben Collins
M: bcollins@debian.org
P: Jody McIntyre
M: scjody@modernduck.com
P: Stefan Richter
M: stefanr@s5r6.in-berlin.de
L: linux1394-devel@lists.sourceforge.net
W: http://www.linux1394.org/
T: git kernel.org:/pub/scm/linux/kernel/git/scjody/ieee1394.git
T: git kernel.org:/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git
S: Maintained
IEEE 1394 OHCI DRIVER
P: Ben Collins
M: bcollins@debian.org
P: Jody McIntyre
M: scjody@modernduck.com
IEEE 1394 IPV4 DRIVER (eth1394)
P: Stefan Richter
M: stefanr@s5r6.in-berlin.de
L: linux1394-devel@lists.sourceforge.net
W: http://www.linux1394.org/
S: Maintained
S: Odd Fixes
IEEE 1394 PCILYNX DRIVER
P: Jody McIntyre
M: scjody@modernduck.com
P: Stefan Richter
M: stefanr@s5r6.in-berlin.de
L: linux1394-devel@lists.sourceforge.net
W: http://www.linux1394.org/
S: Maintained
S: Odd Fixes
IEEE 1394 RAW I/O DRIVER
P: Ben Collins
......@@ -1435,16 +1428,6 @@ M: bcollins@debian.org
P: Dan Dennedy
M: dan@dennedy.org
L: linux1394-devel@lists.sourceforge.net
W: http://www.linux1394.org/
S: Maintained
IEEE 1394 SBP2
P: Ben Collins
M: bcollins@debian.org
P: Stefan Richter
M: stefanr@s5r6.in-berlin.de
L: linux1394-devel@lists.sourceforge.net
W: http://www.linux1394.org/
S: Maintained
IMS TWINTURBO FRAMEBUFFER DRIVER
......
......@@ -120,12 +120,19 @@ config IEEE1394_VIDEO1394
this option only if you have an IEEE 1394 video device connected to
an OHCI-1394 card.
comment "SBP-2 support (for storage devices) requires SCSI"
depends on IEEE1394 && SCSI=n
config IEEE1394_SBP2
tristate "SBP-2 support (Harddisks etc.)"
depends on IEEE1394 && SCSI && (PCI || BROKEN)
help
This option enables you to use SBP-2 devices connected to your IEEE
1394 bus. SBP-2 devices include harddrives and DVD devices.
This option enables you to use SBP-2 devices connected to an IEEE
1394 bus. SBP-2 devices include storage devices like harddisks and
DVD drives, also some other FireWire devices like scanners.
You should also enable support for disks, CD-ROMs, etc. in the SCSI
configuration section.
config IEEE1394_SBP2_PHYS_DMA
bool "Enable replacement for physical DMA in SBP2"
......
......@@ -17,11 +17,13 @@
*
*/
#include <linux/string.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/param.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include "csr1212.h"
#include "ieee1394_types.h"
......@@ -149,31 +151,18 @@ static void host_reset(struct hpsb_host *host)
/*
* HI == seconds (bits 0:2)
* LO == fraction units of 1/8000 of a second, as per 1394 (bits 19:31)
*
* Convert to units and then to HZ, for comparison to jiffies.
*
* By default this will end up being 800 units, or 100ms (125usec per
* unit).
* LO == fractions of a second in units of 125usec (bits 19:31)
*
* NOTE: The spec says 1/8000, but also says we can compute based on 1/8192
* like CSR specifies. Should make our math less complex.
* Convert SPLIT_TIMEOUT to jiffies.
* The default and minimum as per 1394a-2000 clause 8.3.2.2.6 is 100ms.
*/
static inline void calculate_expire(struct csr_control *csr)
{
unsigned long units;
/* Take the seconds, and convert to units */
units = (unsigned long)(csr->split_timeout_hi & 0x07) << 13;
/* Add in the fractional units */
units += (unsigned long)(csr->split_timeout_lo >> 19);
/* Convert to jiffies */
csr->expire = (unsigned long)(units * HZ) >> 13UL;
unsigned long usecs =
(csr->split_timeout_hi & 0x07) * USEC_PER_SEC +
(csr->split_timeout_lo >> 19) * 125L;
/* Just to keep from rounding low */
csr->expire++;
csr->expire = usecs_to_jiffies(usecs > 100000L ? usecs : 100000L);
HPSB_VERBOSE("CSR: setting expire to %lu, HZ=%u", csr->expire, HZ);
}
......
#ifndef _IEEE1394_CSR_H
#define _IEEE1394_CSR_H
#ifdef CONFIG_PREEMPT
#include <linux/sched.h>
#endif
#include <linux/spinlock_types.h>
#include "csr1212.h"
#include "ieee1394_types.h"
#define CSR_REGISTER_BASE 0xfffff0000000ULL
#define CSR_REGISTER_BASE 0xfffff0000000ULL
/* register offsets relative to CSR_REGISTER_BASE */
#define CSR_STATE_CLEAR 0x0
#define CSR_STATE_SET 0x4
#define CSR_NODE_IDS 0x8
#define CSR_RESET_START 0xc
#define CSR_SPLIT_TIMEOUT_HI 0x18
#define CSR_SPLIT_TIMEOUT_LO 0x1c
#define CSR_CYCLE_TIME 0x200
#define CSR_BUS_TIME 0x204
#define CSR_BUSY_TIMEOUT 0x210
#define CSR_BUS_MANAGER_ID 0x21c
#define CSR_BANDWIDTH_AVAILABLE 0x220
#define CSR_CHANNELS_AVAILABLE 0x224
#define CSR_CHANNELS_AVAILABLE_HI 0x224
#define CSR_CHANNELS_AVAILABLE_LO 0x228
#define CSR_BROADCAST_CHANNEL 0x234
#define CSR_CONFIG_ROM 0x400
#define CSR_CONFIG_ROM_END 0x800
#define CSR_FCP_COMMAND 0xB00
#define CSR_FCP_RESPONSE 0xD00
#define CSR_FCP_END 0xF00
#define CSR_TOPOLOGY_MAP 0x1000
#define CSR_TOPOLOGY_MAP_END 0x1400
#define CSR_SPEED_MAP 0x2000
#define CSR_SPEED_MAP_END 0x3000
#define CSR_STATE_CLEAR 0x0
#define CSR_STATE_SET 0x4
#define CSR_NODE_IDS 0x8
#define CSR_RESET_START 0xc
#define CSR_SPLIT_TIMEOUT_HI 0x18
#define CSR_SPLIT_TIMEOUT_LO 0x1c
#define CSR_CYCLE_TIME 0x200
#define CSR_BUS_TIME 0x204
#define CSR_BUSY_TIMEOUT 0x210
#define CSR_BUS_MANAGER_ID 0x21c
#define CSR_BANDWIDTH_AVAILABLE 0x220
#define CSR_CHANNELS_AVAILABLE 0x224
#define CSR_CHANNELS_AVAILABLE_HI 0x224
#define CSR_CHANNELS_AVAILABLE_LO 0x228
#define CSR_BROADCAST_CHANNEL 0x234
#define CSR_CONFIG_ROM 0x400
#define CSR_CONFIG_ROM_END 0x800
#define CSR_FCP_COMMAND 0xB00
#define CSR_FCP_RESPONSE 0xD00
#define CSR_FCP_END 0xF00
#define CSR_TOPOLOGY_MAP 0x1000
#define CSR_TOPOLOGY_MAP_END 0x1400
#define CSR_SPEED_MAP 0x2000
#define CSR_SPEED_MAP_END 0x3000
/* IEEE 1394 bus specific Configuration ROM Key IDs */
#define IEEE1394_KV_ID_POWER_REQUIREMENTS (0x30)
/* IEEE 1394 Bus Inforamation Block specifics */
/* IEEE 1394 Bus Information Block specifics */
#define CSR_BUS_INFO_SIZE (5 * sizeof(quadlet_t))
#define CSR_IRMC_SHIFT 31
#define CSR_CMC_SHIFT 30
#define CSR_ISC_SHIFT 29
#define CSR_BMC_SHIFT 28
#define CSR_PMC_SHIFT 27
#define CSR_CYC_CLK_ACC_SHIFT 16
#define CSR_MAX_REC_SHIFT 12
#define CSR_MAX_ROM_SHIFT 8
#define CSR_GENERATION_SHIFT 4
#define CSR_IRMC_SHIFT 31
#define CSR_CMC_SHIFT 30
#define CSR_ISC_SHIFT 29
#define CSR_BMC_SHIFT 28
#define CSR_PMC_SHIFT 27
#define CSR_CYC_CLK_ACC_SHIFT 16
#define CSR_MAX_REC_SHIFT 12
#define CSR_MAX_ROM_SHIFT 8
#define CSR_GENERATION_SHIFT 4
#define CSR_SET_BUS_INFO_GENERATION(csr, gen) \
((csr)->bus_info_data[2] = \
cpu_to_be32((be32_to_cpu((csr)->bus_info_data[2]) & \
~(0xf << CSR_GENERATION_SHIFT)) | \
~(0xf << CSR_GENERATION_SHIFT)) | \
(gen) << CSR_GENERATION_SHIFT))
struct csr_control {
spinlock_t lock;
quadlet_t state;
quadlet_t node_ids;
quadlet_t split_timeout_hi, split_timeout_lo;
unsigned long expire; // Calculated from split_timeout
quadlet_t cycle_time;
quadlet_t bus_time;
quadlet_t bus_manager_id;
quadlet_t bandwidth_available;
quadlet_t channels_available_hi, channels_available_lo;
spinlock_t lock;
quadlet_t state;
quadlet_t node_ids;
quadlet_t split_timeout_hi, split_timeout_lo;
unsigned long expire; /* Calculated from split_timeout */
quadlet_t cycle_time;
quadlet_t bus_time;
quadlet_t bus_manager_id;
quadlet_t bandwidth_available;
quadlet_t channels_available_hi, channels_available_lo;
quadlet_t broadcast_channel;
/* Bus Info */
......@@ -84,8 +82,8 @@ struct csr_control {
struct csr1212_csr *rom;
quadlet_t topology_map[256];
quadlet_t speed_map[1024];
quadlet_t topology_map[256];
quadlet_t speed_map[1024];
};
extern struct csr1212_bus_ops csr_bus_ops;
......@@ -93,4 +91,9 @@ extern struct csr1212_bus_ops csr_bus_ops;
int init_csr(void);
void cleanup_csr(void);
/* hpsb_update_config_rom() is deprecated */
struct hpsb_host;
int hpsb_update_config_rom(struct hpsb_host *host, const quadlet_t *new_rom,
size_t size, unsigned char rom_version);
#endif /* _IEEE1394_CSR_H */
......@@ -7,10 +7,13 @@
* directory of the kernel sources for details.
*/
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/vmalloc.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/vmalloc.h>
#include <asm/scatterlist.h>
#include "dma.h"
/* dma_prog_region */
......
......@@ -10,69 +10,91 @@
#ifndef IEEE1394_DMA_H
#define IEEE1394_DMA_H
#include <linux/pci.h>
#include <asm/scatterlist.h>
/* struct dma_prog_region
a small, physically-contiguous DMA buffer with random-access,
synchronous usage characteristics
*/
#include <asm/types.h>
struct pci_dev;
struct scatterlist;
struct vm_area_struct;
/**
* struct dma_prog_region - small contiguous DMA buffer
* @kvirt: kernel virtual address
* @dev: PCI device
* @n_pages: number of kernel pages
* @bus_addr: base bus address
*
* a small, physically contiguous DMA buffer with random-access, synchronous
* usage characteristics
*/
struct dma_prog_region {
unsigned char *kvirt; /* kernel virtual address */
struct pci_dev *dev; /* PCI device */
unsigned int n_pages; /* # of kernel pages */
dma_addr_t bus_addr; /* base bus address */
unsigned char *kvirt;
struct pci_dev *dev;
unsigned int n_pages;
dma_addr_t bus_addr;
};
/* clear out all fields but do not allocate any memory */
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);
void dma_prog_region_free(struct dma_prog_region *prog);
static inline dma_addr_t dma_prog_region_offset_to_bus(struct dma_prog_region *prog, unsigned long offset)
static inline dma_addr_t dma_prog_region_offset_to_bus(
struct dma_prog_region *prog, unsigned long offset)
{
return prog->bus_addr + offset;
}
/* struct dma_region
a large, non-physically-contiguous DMA buffer with streaming,
asynchronous usage characteristics
*/
/**
* struct dma_region - large non-contiguous DMA buffer
* @virt: kernel virtual address
* @dev: PCI device
* @n_pages: number of kernel pages
* @n_dma_pages: number of IOMMU pages
* @sglist: IOMMU mapping
* @direction: PCI_DMA_TODEVICE, etc.
*
* a large, non-physically-contiguous DMA buffer with streaming, asynchronous
* usage characteristics
*/
struct dma_region {
unsigned char *kvirt; /* kernel virtual address */
struct pci_dev *dev; /* PCI device */
unsigned int n_pages; /* # of kernel pages */
unsigned int n_dma_pages; /* # of IOMMU pages */
struct scatterlist *sglist; /* IOMMU mapping */
int direction; /* PCI_DMA_TODEVICE, etc */
unsigned char *kvirt;
struct pci_dev *dev;
unsigned int n_pages;
unsigned int n_dma_pages;
struct scatterlist *sglist;
int direction;
};
/* clear out all fields but do not allocate anything */
void dma_region_init(struct dma_region *dma);
/* allocate the buffer and map it to the IOMMU */
int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes, struct pci_dev *dev, int direction);
int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes,
struct pci_dev *dev, int direction);
/* unmap and free the buffer */
void dma_region_free(struct dma_region *dma);
/* sync the CPU's view of the buffer */
void dma_region_sync_for_cpu(struct dma_region *dma, unsigned long offset, unsigned long len);
void dma_region_sync_for_cpu(struct dma_region *dma, unsigned long offset,
unsigned long len);
/* sync the IO bus' view of the buffer */
void dma_region_sync_for_device(struct dma_region *dma, unsigned long offset, unsigned long len);
void dma_region_sync_for_device(struct dma_region *dma, unsigned long offset,
unsigned long len);
/* map the buffer into a user space process */
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);
/* macro to index into a DMA region (or dma_prog_region) */
#define dma_region_i(_dma, _type, _index) ( ((_type*) ((_dma)->kvirt)) + (_index) )
#define dma_region_i(_dma, _type, _index) \
( ((_type*) ((_dma)->kvirt)) + (_index) )
/* return the DMA bus address of the byte with the given offset
relative to the beginning of the dma_region */
dma_addr_t dma_region_offset_to_bus(struct dma_region *dma, unsigned long offset);
* relative to the beginning of the dma_region */
dma_addr_t dma_region_offset_to_bus(struct dma_region *dma,
unsigned long offset);
#endif /* IEEE1394_DMA_H */
......@@ -460,7 +460,7 @@ struct video_card {
int dma_running;
/*
3) the sleeping semaphore 'sem' - this is used from process context only,
3) the sleeping mutex 'mtx' - this is used from process context only,
to serialize various operations on the video_card. Even though only one
open() is allowed, we still need to prevent multiple threads of execution
from entering calls like read, write, ioctl, etc.
......@@ -468,9 +468,9 @@ struct video_card {
I honestly can't think of a good reason to use dv1394 from several threads
at once, but we need to serialize anyway to prevent oopses =).
NOTE: if you need both spinlock and sem, take sem first to avoid deadlock!
NOTE: if you need both spinlock and mtx, take mtx first to avoid deadlock!
*/
struct semaphore sem;
struct mutex mtx;
/* people waiting for buffer space, please form a line here... */
wait_queue_head_t waitq;
......
......@@ -95,6 +95,7 @@
#include <linux/fs.h>
#include <linux/poll.h>
#include <linux/smp_lock.h>
#include <linux/mutex.h>
#include <linux/bitops.h>
#include <asm/byteorder.h>
#include <asm/atomic.h>
......@@ -110,15 +111,15 @@
#include <linux/compat.h>
#include <linux/cdev.h>
#include "dv1394.h"
#include "dv1394-private.h"
#include "highlevel.h"
#include "hosts.h"
#include "ieee1394.h"
#include "ieee1394_core.h"
#include "ieee1394_hotplug.h"
#include "ieee1394_types.h"
#include "nodemgr.h"
#include "hosts.h"
#include "ieee1394_core.h"
#include "highlevel.h"
#include "dv1394.h"
#include "dv1394-private.h"
#include "ohci1394.h"
/* DEBUG LEVELS:
......@@ -136,13 +137,13 @@
#if DV1394_DEBUG_LEVEL >= 2
#define irq_printk( args... ) printk( args )
#else
#define irq_printk( args... )
#define irq_printk( args... ) do {} while (0)
#endif
#if DV1394_DEBUG_LEVEL >= 1
#define debug_printk( args... ) printk( args)
#else
#define debug_printk( args... )
#define debug_printk( args... ) do {} while (0)
#endif
/* issue a dummy PCI read to force the preceding write
......@@ -247,7 +248,7 @@ static void frame_delete(struct frame *f)
Frame_prepare() must be called OUTSIDE the video->spinlock.
However, frame_prepare() must still be serialized, so
it should be called WITH the video->sem taken.
it should be called WITH the video->mtx taken.
*/
static void frame_prepare(struct video_card *video, unsigned int this_frame)
......@@ -1271,7 +1272,7 @@ static int dv1394_mmap(struct file *file, struct vm_area_struct *vma)
int retval = -EINVAL;
/* serialize mmap */
down(&video->sem);
mutex_lock(&video->mtx);
if ( ! video_card_initialized(video) ) {
retval = do_dv1394_init_default(video);
......@@ -1281,7 +1282,7 @@ static int dv1394_mmap(struct file *file, struct vm_area_struct *vma)
retval = dma_region_mmap(&video->dv_buf, file, vma);
out:
up(&video->sem);
mutex_unlock(&video->mtx);
return retval;
}
......@@ -1337,17 +1338,17 @@ static ssize_t dv1394_write(struct file *file, const char __user *buffer, size_t
/* serialize this to prevent multi-threaded mayhem */
if (file->f_flags & O_NONBLOCK) {
if (down_trylock(&video->sem))
if (!mutex_trylock(&video->mtx))
return -EAGAIN;
} else {
if (down_interruptible(&video->sem))
if (mutex_lock_interruptible(&video->mtx))
return -ERESTARTSYS;
}
if ( !video_card_initialized(video) ) {
ret = do_dv1394_init_default(video);
if (ret) {
up(&video->sem);
mutex_unlock(&video->mtx);
return ret;
}
}
......@@ -1418,7 +1419,7 @@ static ssize_t dv1394_write(struct file *file, const char __user *buffer, size_t
remove_wait_queue(&video->waitq, &wait);
set_current_state(TASK_RUNNING);
up(&video->sem);
mutex_unlock(&video->mtx);
return ret;
}
......@@ -1434,17 +1435,17 @@ static ssize_t dv1394_read(struct file *file, char __user *buffer, size_t count
/* serialize this to prevent multi-threaded mayhem */
if (file->f_flags & O_NONBLOCK) {
if (down_trylock(&video->sem))
if (!mutex_trylock(&video->mtx))
return -EAGAIN;
} else {
if (down_interruptible(&video->sem))
if (mutex_lock_interruptible(&video->mtx))
return -ERESTARTSYS;
}
if ( !video_card_initialized(video) ) {
ret = do_dv1394_init_default(video);
if (ret) {
up(&video->sem);
mutex_unlock(&video->mtx);
return ret;
}
video->continuity_counter = -1;
......@@ -1526,7 +1527,7 @@ static ssize_t dv1394_read(struct file *file, char __user *buffer, size_t count
remove_wait_queue(&video->waitq, &wait);
set_current_state(TASK_RUNNING);
up(&video->sem);
mutex_unlock(&video->mtx);
return ret;
}
......@@ -1547,12 +1548,12 @@ static long dv1394_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
/* serialize this to prevent multi-threaded mayhem */
if (file->f_flags & O_NONBLOCK) {
if (down_trylock(&video->sem)) {
if (!mutex_trylock(&video->mtx)) {
unlock_kernel();
return -EAGAIN;
}
} else {
if (down_interruptible(&video->sem)) {
if (mutex_lock_interruptible(&video->mtx)) {
unlock_kernel();
return -ERESTARTSYS;
}
......@@ -1778,7 +1779,7 @@ static long dv1394_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
}
out:
up(&video->sem);
mutex_unlock(&video->mtx);
unlock_kernel();
return ret;
}
......@@ -2253,7 +2254,7 @@ static int dv1394_init(struct ti_ohci *ohci, enum pal_or_ntsc format, enum modes
clear_bit(0, &video->open);
spin_lock_init(&video->spinlock);
video->dma_running = 0;
init_MUTEX(&video->sem);
mutex_init(&video->mtx);
init_waitqueue_head(&video->waitq);
video->fasync = NULL;
......
......@@ -64,19 +64,19 @@
#include <linux/ethtool.h>
#include <asm/uaccess.h>
#include <asm/delay.h>
#include <asm/semaphore.h>
#include <net/arp.h>
#include "config_roms.h"
#include "csr1212.h"
#include "ieee1394_types.h"
#include "eth1394.h"
#include "highlevel.h"
#include "ieee1394.h"
#include "ieee1394_core.h"
#include "ieee1394_hotplug.h"
#include "ieee1394_transactions.h"
#include "ieee1394.h"
#include "highlevel.h"
#include "ieee1394_types.h"
#include "iso.h"
#include "nodemgr.h"
#include "eth1394.h"
#include "config_roms.h"
#define ETH1394_PRINT_G(level, fmt, args...) \
printk(level "%s: " fmt, driver_name, ## args)
......
This diff is collapsed.
......@@ -90,6 +90,16 @@ static int alloc_hostnum_cb(struct hpsb_host *host, void *__data)
return 0;
}
/*
* The pending_packet_queue is special in that it's processed
* from hardirq context too (such as hpsb_bus_reset()). Hence
* split the lock class from the usual networking skb-head
* lock class by using a separate key for it:
*/
static struct lock_class_key pending_packet_queue_key;
static DEFINE_MUTEX(host_num_alloc);
/**
* hpsb_alloc_host - allocate a new host controller.
* @drv: the driver that will manage the host controller
......@@ -105,16 +115,6 @@ static int alloc_hostnum_cb(struct hpsb_host *host, void *__data)
* Return Value: a pointer to the &hpsb_host if successful, %NULL if
* no memory was available.
*/
static DEFINE_MUTEX(host_num_alloc);
/*
* The pending_packet_queue is special in that it's processed
* from hardirq context too (such as hpsb_bus_reset()). Hence
* split the lock class from the usual networking skb-head
* lock class by using a separate key for it:
*/
static struct lock_class_key pending_packet_queue_key;
struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
struct device *dev)
{
......@@ -143,9 +143,6 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
for (i = 2; i < 16; i++)
h->csr.gen_timestamp[i] = jiffies - 60 * HZ;
for (i = 0; i < ARRAY_SIZE(h->tpool); i++)
HPSB_TPOOL_INIT(&h->tpool[i]);
atomic_set(&h->generation, 0);
INIT_WORK(&h->delayed_reset, delayed_reset_bus, h);
......
......@@ -2,17 +2,19 @@
#define _IEEE1394_HOSTS_H
#include <linux/device.h>
#include <linux/wait.h>
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/skbuff.h>
#include <linux/timer.h>
#include <linux/types.h>
#include <linux/workqueue.h>
#include <asm/atomic.h>
#include <asm/semaphore.h>
struct pci_dev;
struct module;
#include "ieee1394_types.h"
#include "csr.h"
struct hpsb_packet;
struct hpsb_iso;
......@@ -33,7 +35,6 @@ struct hpsb_host {
int node_count; /* number of identified nodes on this bus */
int selfid_count; /* total number of SelfIDs received */
int nodes_active; /* number of nodes with active link layer */
u8 speed[ALL_NODES]; /* speed between each node and local node */
nodeid_t node_id; /* node ID of this host */
nodeid_t irm_id; /* ID of this bus' isochronous resource manager */
......@@ -53,31 +54,29 @@ struct hpsb_host {
int reset_retries;
quadlet_t *topology_map;
u8 *speed_map;
struct csr_control csr;
/* Per node tlabel pool allocation */
struct hpsb_tlabel_pool tpool[ALL_NODES];
int id;
struct hpsb_host_driver *driver;
struct pci_dev *pdev;
int id;
struct device device;
struct class_device class_dev;
int update_config_rom;
struct work_struct delayed_reset;
unsigned int config_roms;
struct list_head addr_space;
u64 low_addr_space; /* upper bound of physical DMA area */
u64 middle_addr_space; /* upper bound of posted write area */
};
u8 speed[ALL_NODES]; /* speed between each node and local node */
/* per node tlabel allocation */
u8 next_tl[ALL_NODES];
struct { DECLARE_BITMAP(map, 64); } tl_pool[ALL_NODES];
struct csr_control csr;
};
enum devctl_cmd {
/* Host is requested to reset its bus and cancel all outstanding async
......@@ -112,7 +111,7 @@ enum devctl_cmd {
enum isoctl_cmd {
/* rawiso API - see iso.h for the meanings of these commands
(they correspond exactly to the hpsb_iso_* API functions)
* (they correspond exactly to the hpsb_iso_* API functions)
* INIT = allocate resources
* START = begin transmission/reception
* STOP = halt transmission/reception
......@@ -160,7 +159,8 @@ struct hpsb_host_driver {
/* The hardware driver may optionally support a function that is used
* to set the hardware ConfigROM if the hardware supports handling
* reads to the ConfigROM on its own. */
void (*set_hw_config_rom) (struct hpsb_host *host, quadlet_t *config_rom);
void (*set_hw_config_rom)(struct hpsb_host *host,
quadlet_t *config_rom);
/* This function shall implement packet transmission based on
* packet->type. It shall CRC both parts of the packet (unless
......@@ -170,20 +170,21 @@ struct hpsb_host_driver {
* called. Return 0 on success, negative errno on failure.
* NOTE: The function must be callable in interrupt context.
*/
int (*transmit_packet) (struct hpsb_host *host,
struct hpsb_packet *packet);
int (*transmit_packet)(struct hpsb_host *host,
struct hpsb_packet *packet);
/* This function requests miscellanous services from the driver, see
* above for command codes and expected actions. Return -1 for unknown
* command, though that should never happen.
*/
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
* (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, unsigned long 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
* management registers (bus manager id, bandwidth available, channels
......@@ -196,19 +197,11 @@ struct hpsb_host_driver {
quadlet_t data, quadlet_t compare);
};
struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
struct device *dev);
int hpsb_add_host(struct hpsb_host *host);
void hpsb_remove_host(struct hpsb_host *h);
/* The following 2 functions are deprecated and will be removed when the
* raw1394/libraw1394 update is complete. */
int hpsb_update_config_rom(struct hpsb_host *host,
const quadlet_t *new_rom, size_t size, unsigned char rom_version);
int hpsb_get_config_rom(struct hpsb_host *host, quadlet_t *buffer,
size_t buffersize, size_t *rom_size, unsigned char *rom_version);
/* Updates the configuration rom image of a host. rom_version must be the
* current version, otherwise it will fail with return value -1. If this
* host does not support config-rom-update, it will return -EINVAL.
......
/* Base file for all ieee1394 ioctl's. Linux-1394 has allocated base '#'
* with a range of 0x00-0x3f. */
/*
* 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
......@@ -96,8 +98,7 @@
_IOW ('#', 0x27, struct raw1394_iso_packets)
#define RAW1394_IOC_ISO_XMIT_SYNC \
_IO ('#', 0x28)
#define RAW1394_IOC_ISO_RECV_FLUSH \
#define RAW1394_IOC_ISO_RECV_FLUSH \
_IO ('#', 0x29)
#endif /* __IEEE1394_IOCTL_H */
This diff is collapsed.
......@@ -35,7 +35,6 @@
#include <linux/kthread.h>
#include <asm/byteorder.h>
#include <asm/semaphore.h>
#include "ieee1394_types.h"
#include "ieee1394.h"
......@@ -86,7 +85,7 @@ static void dump_packet(const char *text, quadlet_t *data, int size, int speed)
printk("\n");
}
#else
#define dump_packet(a,b,c,d)
#define dump_packet(a,b,c,d) do {} while (0)
#endif
static void abort_requests(struct hpsb_host *host);
......@@ -355,10 +354,12 @@ static void build_speed_map(struct hpsb_host *host, int nodecount)
}
}
#if SELFID_SPEED_UNKNOWN != IEEE1394_SPEED_MAX
/* assume maximum speed for 1394b PHYs, nodemgr will correct it */
for (n = 0; n < nodecount; n++)
if (speedcap[n] == 3)
if (speedcap[n] == SELFID_SPEED_UNKNOWN)
speedcap[n] = IEEE1394_SPEED_MAX;
#endif
}
......@@ -1169,7 +1170,7 @@ static void __exit ieee1394_cleanup(void)
unregister_chrdev_region(IEEE1394_CORE_DEV, 256);
}
module_init(ieee1394_init);
fs_initcall(ieee1394_init); /* same as ohci1394 */
module_exit(ieee1394_cleanup);
/* Exported symbols */
......
#ifndef _IEEE1394_CORE_H
#define _IEEE1394_CORE_H
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/list.h>
#include <linux/skbuff.h>
#include <linux/types.h>
#include <asm/atomic.h>
#include <asm/semaphore.h>
#include "hosts.h"
#include "hosts.h"
#include "ieee1394_types.h"
struct hpsb_packet {
/* This struct is basically read-only for hosts with the exception of
......@@ -58,7 +61,6 @@ struct hpsb_packet {
size_t header_size;
size_t data_size;
struct hpsb_host *host;
unsigned int generation;
......@@ -80,7 +82,7 @@ struct hpsb_packet {
/* Set a task for when a packet completes */
void hpsb_set_packet_complete_task(struct hpsb_packet *packet,
void (*routine)(void *), void *data);
void (*routine)(void *), void *data);
static inline struct hpsb_packet *driver_packet(struct list_head *l)
{
......@@ -92,7 +94,6 @@ void abort_timedouts(unsigned long __opaque);
struct hpsb_packet *hpsb_alloc_packet(size_t data_size);
void hpsb_free_packet(struct hpsb_packet *packet);
/*
* Generation counter for the complete 1394 subsystem. Generation gets
* incremented on every change in the subsystem (e.g. bus reset).
......@@ -204,10 +205,14 @@ void hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size,
#define IEEE1394_MINOR_BLOCK_EXPERIMENTAL 15
#define IEEE1394_CORE_DEV MKDEV(IEEE1394_MAJOR, 0)
#define IEEE1394_RAW1394_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16)
#define IEEE1394_VIDEO1394_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_VIDEO1394 * 16)
#define IEEE1394_DV1394_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16)
#define IEEE1394_EXPERIMENTAL_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_EXPERIMENTAL * 16)
#define IEEE1394_RAW1394_DEV MKDEV(IEEE1394_MAJOR, \
IEEE1394_MINOR_BLOCK_RAW1394 * 16)
#define IEEE1394_VIDEO1394_DEV MKDEV(IEEE1394_MAJOR, \
IEEE1394_MINOR_BLOCK_VIDEO1394 * 16)
#define IEEE1394_DV1394_DEV MKDEV(IEEE1394_MAJOR, \
IEEE1394_MINOR_BLOCK_DV1394 * 16)
#define IEEE1394_EXPERIMENTAL_DEV MKDEV(IEEE1394_MAJOR, \
IEEE1394_MINOR_BLOCK_EXPERIMENTAL * 16)
/* return the index (within a minor number block) of a file */
static inline unsigned char ieee1394_file_to_instance(struct file *file)
......@@ -223,4 +228,3 @@ extern struct class hpsb_host_class;
extern struct class *hpsb_protocol_class;
#endif /* _IEEE1394_CORE_H */
#ifndef _IEEE1394_HOTPLUG_H
#define _IEEE1394_HOTPLUG_H
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/mod_devicetable.h>
/* Unit spec id and sw version entry for some protocols */
#define AVC_UNIT_SPEC_ID_ENTRY 0x0000A02D
#define AVC_SW_VERSION_ENTRY 0x00010001
#define CAMERA_UNIT_SPEC_ID_ENTRY 0x0000A02D
#define CAMERA_SW_VERSION_ENTRY 0x00000100
/* Check to make sure this all isn't already defined */
#ifndef IEEE1394_MATCH_VENDOR_ID
#define IEEE1394_MATCH_VENDOR_ID 0x0001
#define IEEE1394_MATCH_MODEL_ID 0x0002
#define IEEE1394_MATCH_SPECIFIER_ID 0x0004
#define IEEE1394_MATCH_VERSION 0x0008
struct ieee1394_device_id {
u32 match_flags;
u32 vendor_id;
u32 model_id;
u32 specifier_id;
u32 version;
void *driver_data;
};
#endif
/* /include/linux/mod_devicetable.h defines:
* IEEE1394_MATCH_VENDOR_ID
* IEEE1394_MATCH_MODEL_ID
* IEEE1394_MATCH_SPECIFIER_ID
* IEEE1394_MATCH_VERSION
* struct ieee1394_device_id
*/
#include <linux/mod_devicetable.h>
#endif /* _IEEE1394_HOTPLUG_H */
......@@ -9,19 +9,17 @@
* directory of the kernel sources for details.
*/
#include <linux/sched.h>
#include <linux/bitops.h>
#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/wait.h>
#include <asm/bug.h>
#include <asm/errno.h>
#include "ieee1394.h"
#include "ieee1394_types.h"
#include "hosts.h"
#include "ieee1394_core.h"
#include "highlevel.h"
#include "nodemgr.h"
#include "ieee1394_transactions.h"
#define PREP_ASYNC_HEAD_ADDRESS(tc) \
......@@ -31,6 +29,13 @@
packet->header[1] = (packet->host->node_id << 16) | (addr >> 32); \
packet->header[2] = addr & 0xffffffff
#ifndef HPSB_DEBUG_TLABELS
static
#endif
spinlock_t hpsb_tlabel_lock = SPIN_LOCK_UNLOCKED;
static DECLARE_WAIT_QUEUE_HEAD(tlabel_wq);
static void fill_async_readquad(struct hpsb_packet *packet, u64 addr)
{
PREP_ASYNC_HEAD_ADDRESS(TCODE_READQ);
......@@ -114,9 +119,41 @@ static void fill_async_stream_packet(struct hpsb_packet *packet, int length,
packet->tcode = TCODE_ISO_DATA;
}
/* same as hpsb_get_tlabel, except that it returns immediately */
static int hpsb_get_tlabel_atomic(struct hpsb_packet *packet)
{
unsigned long flags, *tp;
u8 *next;
int tlabel, n = NODEID_TO_NODE(packet->node_id);
/* Broadcast transactions are complete once the request has been sent.
* Use the same transaction label for all broadcast transactions. */
if (unlikely(n == ALL_NODES)) {
packet->tlabel = 0;
return 0;
}
tp = packet->host->tl_pool[n].map;
next = &packet->host->next_tl[n];
spin_lock_irqsave(&hpsb_tlabel_lock, flags);
tlabel = find_next_zero_bit(tp, 64, *next);
if (tlabel > 63)
tlabel = find_first_zero_bit(tp, 64);
if (tlabel > 63) {
spin_unlock_irqrestore(&hpsb_tlabel_lock, flags);
return -EAGAIN;
}
__set_bit(tlabel, tp);
*next = (tlabel + 1) & 63;
spin_unlock_irqrestore(&hpsb_tlabel_lock, flags);
packet->tlabel = tlabel;
return 0;
}
/**
* hpsb_get_tlabel - allocate a transaction label
* @packet: the packet who's tlabel/tpool we set
* @packet: the packet whose tlabel and tl_pool we set
*
* Every asynchronous transaction on the 1394 bus needs a transaction
* label to match the response to the request. This label has to be
......@@ -130,42 +167,25 @@ static void fill_async_stream_packet(struct hpsb_packet *packet, int length,
* Return value: Zero on success, otherwise non-zero. A non-zero return
* generally means there are no available tlabels. If this is called out
* of interrupt or atomic context, then it will sleep until can return a
* tlabel.
* tlabel or a signal is received.
*/
int hpsb_get_tlabel(struct hpsb_packet *packet)
{
unsigned long flags;
struct hpsb_tlabel_pool *tp;
int n = NODEID_TO_NODE(packet->node_id);
if (unlikely(n == ALL_NODES))
return 0;
tp = &packet->host->tpool[n];
if (irqs_disabled() || in_atomic()) {
if (down_trylock(&tp->count))
return 1;
} else {
down(&tp->count);
}
spin_lock_irqsave(&tp->lock, flags);
packet->tlabel = find_next_zero_bit(tp->pool, 64, tp->next);
if (packet->tlabel > 63)
packet->tlabel = find_first_zero_bit(tp->pool, 64);
tp->next = (packet->tlabel + 1) % 64;
/* Should _never_ happen */
BUG_ON(test_and_set_bit(packet->tlabel, tp->pool));
tp->allocations++;
spin_unlock_irqrestore(&tp->lock, flags);
return 0;
if (irqs_disabled() || in_atomic())
return hpsb_get_tlabel_atomic(packet);
/* NB: The macro wait_event_interruptible() is called with a condition
* argument with side effect. This is only possible because the side
* effect does not occur until the condition became true, and
* wait_event_interruptible() won't evaluate the condition again after
* that. */
return wait_event_interruptible(tlabel_wq,
!hpsb_get_tlabel_atomic(packet));
}
/**
* hpsb_free_tlabel - free an allocated transaction label
* @packet: packet whos tlabel/tpool needs to be cleared
* @packet: packet whose tlabel and tl_pool needs to be cleared
*
* Frees the transaction label allocated with hpsb_get_tlabel(). The
* tlabel has to be freed after the transaction is complete (i.e. response
......@@ -176,21 +196,20 @@ int hpsb_get_tlabel(struct hpsb_packet *packet)
*/
void hpsb_free_tlabel(struct hpsb_packet *packet)
{
unsigned long flags;
struct hpsb_tlabel_pool *tp;
int n = NODEID_TO_NODE(packet->node_id);
unsigned long flags, *tp;
int tlabel, n = NODEID_TO_NODE(packet->node_id);
if (unlikely(n == ALL_NODES))
return;
tp = &packet->host->tpool[n];
tp = packet->host->tl_pool[n].map;
tlabel = packet->tlabel;
BUG_ON(tlabel > 63 || tlabel < 0);
BUG_ON(packet->tlabel > 63 || packet->tlabel < 0);
spin_lock_irqsave(&hpsb_tlabel_lock, flags);
BUG_ON(!__test_and_clear_bit(tlabel, tp));
spin_unlock_irqrestore(&hpsb_tlabel_lock, flags);
spin_lock_irqsave(&tp->lock, flags);
BUG_ON(!test_and_clear_bit(packet->tlabel, tp->pool));
spin_unlock_irqrestore(&tp->lock, flags);
up(&tp->count);
wake_up_interruptible(&tlabel_wq);
}
int hpsb_packet_success(struct hpsb_packet *packet)
......@@ -214,7 +233,7 @@ int hpsb_packet_success(struct hpsb_packet *packet)
packet->node_id);
return -EAGAIN;
}
HPSB_PANIC("reached unreachable code 1 in %s", __FUNCTION__);
BUG();
case ACK_BUSY_X:
case ACK_BUSY_A:
......@@ -261,8 +280,7 @@ int hpsb_packet_success(struct hpsb_packet *packet)
packet->ack_code, packet->node_id, packet->tcode);
return -EAGAIN;
}
HPSB_PANIC("reached unreachable code 2 in %s", __FUNCTION__);
BUG();
}
struct hpsb_packet *hpsb_make_readpacket(struct hpsb_host *host, nodeid_t node,
......
#ifndef _IEEE1394_TRANSACTIONS_H
#define _IEEE1394_TRANSACTIONS_H
#include "ieee1394_core.h"
#include <linux/types.h>
#include "ieee1394_types.h"
struct hpsb_packet;
struct hpsb_host;
/*
* Get and free transaction labels.
*/
int hpsb_get_tlabel(struct hpsb_packet *packet);
void hpsb_free_tlabel(struct hpsb_packet *packet);
struct hpsb_packet *hpsb_make_readpacket(struct hpsb_host *host, nodeid_t node,
u64 addr, size_t length);
struct hpsb_packet *hpsb_make_lockpacket(struct hpsb_host *host, nodeid_t node,
u64 addr, int extcode, quadlet_t *data,
u64 addr, int extcode, quadlet_t *data,
quadlet_t arg);
struct hpsb_packet *hpsb_make_lock64packet(struct hpsb_host *host, nodeid_t node,
u64 addr, int extcode, octlet_t *data,
octlet_t arg);
struct hpsb_packet *hpsb_make_phypacket(struct hpsb_host *host,
quadlet_t data) ;
struct hpsb_packet *hpsb_make_isopacket(struct hpsb_host *host,
int length, int channel,
int tag, int sync);
struct hpsb_packet *hpsb_make_writepacket (struct hpsb_host *host, nodeid_t node,
u64 addr, quadlet_t *buffer, size_t length);
struct hpsb_packet *hpsb_make_lock64packet(struct hpsb_host *host,
nodeid_t node, u64 addr, int extcode,
octlet_t *data, octlet_t arg);
struct hpsb_packet *hpsb_make_phypacket(struct hpsb_host *host, quadlet_t data);
struct hpsb_packet *hpsb_make_isopacket(struct hpsb_host *host, int length,
int channel, int tag, int sync);
struct hpsb_packet *hpsb_make_writepacket(struct hpsb_host *host,
nodeid_t node, u64 addr,
quadlet_t *buffer, size_t length);
struct hpsb_packet *hpsb_make_streampacket(struct hpsb_host *host, u8 *buffer,
int length, int channel, int tag, int sync);
int length, int channel, int tag,
int sync);
/*
* hpsb_packet_success - Make sense of the ack and reply codes and
......@@ -40,9 +40,8 @@ struct hpsb_packet *hpsb_make_streampacket(struct hpsb_host *host, u8 *buffer,
*/
int hpsb_packet_success(struct hpsb_packet *packet);
/*
* The generic read, write and lock functions. All recognize the local node ID
* The generic read and write functions. All recognize the local node ID
* and act accordingly. Read and write automatically use quadlet commands if
* length == 4 and and block commands otherwise (however, they do not yet
* support lengths that are not a multiple of 4). You must explicitly specifiy
......@@ -54,4 +53,8 @@ int hpsb_read(struct hpsb_host *host, nodeid_t node, unsigned int generation,
int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation,
u64 addr, quadlet_t *buffer, size_t length);
#ifdef HPSB_DEBUG_TLABELS
extern spinlock_t hpsb_tlabel_lock;
#endif
#endif /* _IEEE1394_TRANSACTIONS_H */
#ifndef _IEEE1394_TYPES_H
#define _IEEE1394_TYPES_H
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/list.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <asm/semaphore.h>
#include <linux/types.h>
#include <asm/byteorder.h>
/* Transaction Label handling */
struct hpsb_tlabel_pool {
DECLARE_BITMAP(pool, 64);
spinlock_t lock;
u8 next;
u32 allocations;
struct semaphore count;
};
#define HPSB_TPOOL_INIT(_tp) \
do { \
bitmap_zero((_tp)->pool, 64); \
spin_lock_init(&(_tp)->lock); \
(_tp)->next = 0; \
(_tp)->allocations = 0; \
sema_init(&(_tp)->count, 63); \
} while (0)
typedef u32 quadlet_t;
typedef u64 octlet_t;
typedef u16 nodeid_t;
......@@ -54,46 +28,40 @@ typedef u16 arm_length_t;
#define NODE_BUS_ARGS(__host, __nodeid) \
__host->id, NODEID_TO_NODE(__nodeid), NODEID_TO_BUS(__nodeid)
#define HPSB_PRINT(level, fmt, args...) printk(level "ieee1394: " fmt "\n" , ## args)
#define HPSB_PRINT(level, fmt, args...) \
printk(level "ieee1394: " fmt "\n" , ## args)
#define HPSB_DEBUG(fmt, args...) HPSB_PRINT(KERN_DEBUG, fmt , ## args)
#define HPSB_INFO(fmt, args...) HPSB_PRINT(KERN_INFO, fmt , ## args)
#define HPSB_NOTICE(fmt, args...) HPSB_PRINT(KERN_NOTICE, fmt , ## args)
#define HPSB_WARN(fmt, args...) HPSB_PRINT(KERN_WARNING, fmt , ## args)
#define HPSB_ERR(fmt, args...) HPSB_PRINT(KERN_ERR, fmt , ## args)
#define HPSB_DEBUG(fmt, args...) HPSB_PRINT(KERN_DEBUG, fmt , ## args)
#define HPSB_INFO(fmt, args...) HPSB_PRINT(KERN_INFO, fmt , ## args)
#define HPSB_NOTICE(fmt, args...) HPSB_PRINT(KERN_NOTICE, fmt , ## args)
#define HPSB_WARN(fmt, args...) HPSB_PRINT(KERN_WARNING, fmt , ## args)
#define HPSB_ERR(fmt, args...) HPSB_PRINT(KERN_ERR, fmt , ## args)
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
#define HPSB_VERBOSE(fmt, args...) HPSB_PRINT(KERN_DEBUG, fmt , ## args)
#define HPSB_VERBOSE(fmt, args...) HPSB_PRINT(KERN_DEBUG, fmt , ## args)
#define HPSB_DEBUG_TLABELS
#else
#define HPSB_VERBOSE(fmt, args...)
#define HPSB_VERBOSE(fmt, args...) do {} while (0)
#endif
#define HPSB_PANIC(fmt, args...) panic("ieee1394: " fmt "\n" , ## args)
#define HPSB_TRACE() HPSB_PRINT(KERN_INFO, "TRACE - %s, %s(), line %d", __FILE__, __FUNCTION__, __LINE__)
#ifdef __BIG_ENDIAN
static __inline__ void *memcpy_le32(u32 *dest, const u32 *__src, size_t count)
static inline void *memcpy_le32(u32 *dest, const u32 *__src, size_t count)
{
void *tmp = dest;
void *tmp = dest;
u32 *src = (u32 *)__src;
count /= 4;
while (count--) {
*dest++ = swab32p(src++);
}
return tmp;
count /= 4;
while (count--)
*dest++ = swab32p(src++);
return tmp;
}
#else
static __inline__ void *memcpy_le32(u32 *dest, const u32 *src, size_t count)
{
return memcpy(dest, src, count);
return memcpy(dest, src, count);
}
#endif /* __BIG_ENDIAN */
......
......@@ -9,8 +9,11 @@
* directory of the kernel sources for details.
*/
#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include "hosts.h"
#include "iso.h"
void hpsb_iso_stop(struct hpsb_iso *iso)
......
......@@ -12,33 +12,40 @@
#ifndef IEEE1394_ISO_H
#define IEEE1394_ISO_H
#include "hosts.h"
#include <linux/spinlock_types.h>
#include <asm/atomic.h>
#include <asm/types.h>
#include "dma.h"
/* high-level ISO interface */
struct hpsb_host;
/* 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.
/* high-level ISO interface */
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)
*/
/*
* 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[]). */
* descriptors in kernel memory (hpsb_iso.infos[]). */
struct hpsb_iso_packet_info {
/* offset of data payload relative to the first byte of the buffer */
__u32 offset;
/* length of the data payload, in bytes (not including the isochronous header) */
/* length of the data payload, in bytes (not including the isochronous
* header) */
__u16 len;
/* (recv only) the cycle number (mod 8000) on which the packet was received */
/* (recv only) the cycle number (mod 8000) on which the packet was
* received */
__u16 cycle;
/* (recv only) channel on which the packet was received */
......@@ -48,12 +55,10 @@ struct hpsb_iso_packet_info {
__u8 tag;
__u8 sy;
/*
* length in bytes of the packet including header/trailer.
* MUST be at structure end, since the first part of this structure is also
* defined in raw1394.h (i.e. struct raw1394_iso_packet_info), is copied to
* userspace and is accessed there through libraw1394.
*/
/* length in bytes of the packet including header/trailer.
* MUST be at structure end, since the first part of this structure is
* also defined in raw1394.h (i.e. struct raw1394_iso_packet_info), is
* copied to userspace and is accessed there through libraw1394. */
__u16 total_len;
};
......@@ -75,8 +80,8 @@ struct hpsb_iso {
void *hostdata;
/* a function to be called (from interrupt context) after
outgoing packets have been sent, or incoming packets have
arrived */
* outgoing packets have been sent, or incoming packets have
* arrived */
void (*callback)(struct hpsb_iso*);
/* wait for buffer space */
......@@ -88,7 +93,7 @@ struct hpsb_iso {
/* greatest # of packets between interrupts - controls
the maximum latency of the buffer */
* the maximum latency of the buffer */
int irq_interval;
/* the buffer for packet data payloads */
......@@ -112,8 +117,8 @@ struct hpsb_iso {
int pkt_dma;
/* how many packets, starting at first_packet:
(transmit) are ready to be filled with data
(receive) contain received data */
* (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 */
......@@ -134,7 +139,7 @@ struct hpsb_iso {
int start_cycle;
/* cycle at which next packet will be transmitted,
-1 if not known */
* -1 if not known */
int xmit_cycle;
/* ringbuffer of packet descriptors in regular kernel memory
......@@ -170,25 +175,30 @@ 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 */
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 tag_mask, int sync);
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 tag_mask, int sync);
void hpsb_iso_stop(struct hpsb_iso *iso);
/* deallocate buffer and DMA context */
void hpsb_iso_shutdown(struct hpsb_iso *iso);
/* queue a packet for transmission. 'offset' is relative to the beginning of the
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);
/* queue a packet for transmission.
* 'offset' is relative to the beginning of the 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 */
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);
/* check for arrival of new packets immediately (even if irq_interval
has not yet been reached) */
* has not yet been reached) */
int hpsb_iso_recv_flush(struct hpsb_iso *iso);
/* returns # of packets ready to send or receive */
......@@ -197,14 +207,15 @@ int hpsb_iso_n_ready(struct hpsb_iso *iso);
/* the following are callbacks available to low-level drivers */
/* 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
*/
* '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 total_len, u16 cycle, u8 channel, u8 tag, u8 sy);
u16 total_len, u16 cycle, u8 channel, u8 tag,
u8 sy);
/* call to wake waiting processes after buffer space has opened up. */
void hpsb_iso_wake(struct hpsb_iso *iso);
......
This diff is collapsed.
......@@ -21,9 +21,15 @@
#define _IEEE1394_NODEMGR_H
#include <linux/device.h>
#include "csr1212.h"
#include <asm/types.h>
#include "ieee1394_core.h"
#include "ieee1394_hotplug.h"
#include "ieee1394_types.h"
struct csr1212_csr;
struct csr1212_keyval;
struct hpsb_host;
struct ieee1394_device_id;
/* '1' '3' '9' '4' in ASCII */
#define IEEE1394_BUSID_MAGIC __constant_cpu_to_be32(0x31333934)
......@@ -44,7 +50,6 @@ struct bus_options {
u16 max_rec; /* Maximum packet size node can receive */
};
#define UNIT_DIRECTORY_VENDOR_ID 0x01
#define UNIT_DIRECTORY_MODEL_ID 0x02
#define UNIT_DIRECTORY_SPECIFIER_ID 0x04
......@@ -59,8 +64,8 @@ struct bus_options {
* unit directory for each of these protocols.
*/
struct unit_directory {
struct node_entry *ne; /* The node which this directory belongs to */
octlet_t address; /* Address of the unit directory on the node */
struct node_entry *ne; /* The node which this directory belongs to */
octlet_t address; /* Address of the unit directory on the node */
u8 flags; /* Indicates which entries were read */
quadlet_t vendor_id;
......@@ -79,11 +84,10 @@ struct unit_directory {
int length; /* Number of quadlets */
struct device device;
struct class_device class_dev;
struct csr1212_keyval *ud_kv;
u32 lun; /* logical unit number immediate value */
u32 lun; /* logical unit number immediate value */
};
struct node_entry {
......@@ -103,10 +107,8 @@ struct node_entry {
const char *vendor_oui;
u32 capabilities;
struct hpsb_tlabel_pool *tpool;
struct device device;
struct class_device class_dev;
/* Means this node is not attached anymore */
......@@ -153,8 +155,8 @@ static inline int hpsb_node_entry_valid(struct node_entry *ne)
/*
* This will fill in the given, pre-initialised hpsb_packet with the current
* information from the node entry (host, node ID, generation number). It will
* return false if the node owning the GUID is not accessible (and not modify the
* hpsb_packet) and return true otherwise.
* return false if the node owning the GUID is not accessible (and not modify
* the hpsb_packet) and return true otherwise.
*
* Note that packet sending may still fail in hpsb_send_packet if a bus reset
* happens while you are trying to set up the packet (due to obsolete generation
......@@ -170,16 +172,13 @@ int hpsb_node_write(struct node_entry *ne, u64 addr,
int hpsb_node_lock(struct node_entry *ne, u64 addr,
int extcode, quadlet_t *data, quadlet_t arg);
/* Iterate the hosts, calling a given function with supplied data for each
* host. */
int nodemgr_for_each_host(void *__data, int (*cb)(struct hpsb_host *, void *));
int init_ieee1394_nodemgr(void);
void cleanup_ieee1394_nodemgr(void);
/* The template for a host device */
extern struct device nodemgr_dev_template_host;
......
......@@ -136,7 +136,7 @@
#define DBGMSG(fmt, args...) \
printk(KERN_INFO "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
#else
#define DBGMSG(fmt, args...)
#define DBGMSG(fmt, args...) do {} while (0)
#endif
#ifdef CONFIG_IEEE1394_OHCI_DMA_DEBUG
......@@ -148,8 +148,8 @@ printk(KERN_INFO "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->
--global_outstanding_dmas, ## args)
static int global_outstanding_dmas = 0;
#else
#define OHCI_DMA_ALLOC(fmt, args...)
#define OHCI_DMA_FREE(fmt, args...)
#define OHCI_DMA_ALLOC(fmt, args...) do {} while (0)
#define OHCI_DMA_FREE(fmt, args...) do {} while (0)
#endif
/* print general (card independent) information */
......@@ -181,36 +181,35 @@ static int alloc_dma_trm_ctx(struct ti_ohci *ohci, struct dma_trm_ctx *d,
static void ohci1394_pci_remove(struct pci_dev *pdev);
#ifndef __LITTLE_ENDIAN
static unsigned hdr_sizes[] =
{
const static size_t hdr_sizes[] = {
3, /* TCODE_WRITEQ */
4, /* TCODE_WRITEB */
3, /* TCODE_WRITE_RESPONSE */
0, /* ??? */
0, /* reserved */
3, /* TCODE_READQ */
4, /* TCODE_READB */
3, /* TCODE_READQ_RESPONSE */
4, /* TCODE_READB_RESPONSE */
1, /* TCODE_CYCLE_START (???) */
1, /* TCODE_CYCLE_START */
4, /* TCODE_LOCK_REQUEST */
2, /* TCODE_ISO_DATA */
4, /* TCODE_LOCK_RESPONSE */
/* rest is reserved or link-internal */
};
/* Swap headers */
static inline void packet_swab(quadlet_t *data, int tcode)
static inline void header_le32_to_cpu(quadlet_t *data, unsigned char tcode)
{
size_t size = hdr_sizes[tcode];
size_t size;
if (tcode > TCODE_LOCK_RESPONSE || hdr_sizes[tcode] == 0)
if (unlikely(tcode >= ARRAY_SIZE(hdr_sizes)))
return;
size = hdr_sizes[tcode];
while (size--)
data[size] = swab32(data[size]);
data[size] = le32_to_cpu(data[size]);
}
#else
/* Don't waste cycles on same sex byte swaps */
#define packet_swab(w,x)
#define header_le32_to_cpu(w,x) do {} while (0)
#endif /* !LITTLE_ENDIAN */
/***********************************
......@@ -701,7 +700,7 @@ static void insert_packet(struct ti_ohci *ohci,
d->prg_cpu[idx]->data[2] = packet->header[2];
d->prg_cpu[idx]->data[3] = packet->header[3];
}
packet_swab(d->prg_cpu[idx]->data, packet->tcode);
header_le32_to_cpu(d->prg_cpu[idx]->data, packet->tcode);
}
if (packet->data_size) { /* block transmit */
......@@ -777,7 +776,7 @@ static void insert_packet(struct ti_ohci *ohci,
d->prg_cpu[idx]->data[0] = packet->speed_code<<16 |
(packet->header[0] & 0xFFFF);
d->prg_cpu[idx]->data[1] = packet->header[0] & 0xFFFF0000;
packet_swab(d->prg_cpu[idx]->data, packet->tcode);
header_le32_to_cpu(d->prg_cpu[idx]->data, packet->tcode);
d->prg_cpu[idx]->begin.control =
cpu_to_le32(DMA_CTL_OUTPUT_MORE |
......@@ -2598,8 +2597,9 @@ static const int TCODE_SIZE[16] = {20, 0, 16, -1, 16, 20, 20, 0,
* Determine the length of a packet in the buffer
* Optimization suggested by Pascal Drolet <pascal.drolet@informission.ca>
*/
static __inline__ int packet_length(struct dma_rcv_ctx *d, int idx, quadlet_t *buf_ptr,
int offset, unsigned char tcode, int noswap)
static inline int packet_length(struct dma_rcv_ctx *d, int idx,
quadlet_t *buf_ptr, int offset,
unsigned char tcode, int noswap)
{
int length = -1;
......@@ -2730,7 +2730,7 @@ static void dma_rcv_tasklet (unsigned long data)
* bus reset. We always ignore it. */
if (tcode != OHCI1394_TCODE_PHY) {
if (!ohci->no_swap_incoming)
packet_swab(d->spb, tcode);
header_le32_to_cpu(d->spb, tcode);
DBGMSG("Packet received from node"
" %d ack=0x%02X spd=%d tcode=0x%X"
" length=%d ctx=%d tlabel=%d",
......@@ -2738,7 +2738,7 @@ static void dma_rcv_tasklet (unsigned long data)
(cond_le32_to_cpu(d->spb[length/4-1], ohci->no_swap_incoming)>>16)&0x1f,
(cond_le32_to_cpu(d->spb[length/4-1], ohci->no_swap_incoming)>>21)&0x3,
tcode, length, d->ctx,
(cond_le32_to_cpu(d->spb[0], ohci->no_swap_incoming)>>10)&0x3f);
(d->spb[0]>>10)&0x3f);
ack = (((cond_le32_to_cpu(d->spb[length/4-1], ohci->no_swap_incoming)>>16)&0x1f)
== 0x11) ? 1 : 0;
......@@ -3529,9 +3529,10 @@ static void ohci1394_pci_remove(struct pci_dev *pdev)
put_device(dev);
}
#ifdef CONFIG_PM
static int ohci1394_pci_resume (struct pci_dev *pdev)
{
/* PowerMac resume code comes first */
#ifdef CONFIG_PPC_PMAC
if (machine_is(powermac)) {
struct device_node *of_node;
......@@ -3543,17 +3544,23 @@ static int ohci1394_pci_resume (struct pci_dev *pdev)
}
#endif /* CONFIG_PPC_PMAC */
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
pci_enable_device(pdev);
return 0;
return pci_enable_device(pdev);
}
static int ohci1394_pci_suspend (struct pci_dev *pdev, pm_message_t state)
{
pci_save_state(pdev);
int err;
err = pci_save_state(pdev);
if (err)
goto out;
err = pci_set_power_state(pdev, pci_choose_state(pdev, state));
if (err)
goto out;
/* PowerMac suspend code comes last */
#ifdef CONFIG_PPC_PMAC
if (machine_is(powermac)) {
struct device_node *of_node;
......@@ -3563,11 +3570,11 @@ static int ohci1394_pci_suspend (struct pci_dev *pdev, pm_message_t state)
if (of_node)
pmac_call_feature(PMAC_FTR_1394_ENABLE, of_node, 0, 0);
}
#endif
return 0;
#endif /* CONFIG_PPC_PMAC */
out:
return err;
}
#endif /* CONFIG_PM */
#define PCI_CLASS_FIREWIRE_OHCI ((PCI_CLASS_SERIAL_FIREWIRE << 8) | 0x10)
......@@ -3590,8 +3597,10 @@ static struct pci_driver ohci1394_pci_driver = {
.id_table = ohci1394_pci_tbl,
.probe = ohci1394_pci_probe,
.remove = ohci1394_pci_remove,
#ifdef CONFIG_PM
.resume = ohci1394_pci_resume,
.suspend = ohci1394_pci_suspend,
#endif
};
/***********************************
......@@ -3718,5 +3727,7 @@ static int __init ohci1394_init(void)
return pci_register_driver(&ohci1394_pci_driver);
}
module_init(ohci1394_init);
/* Register before most other device drivers.
* Useful for remote debugging via physical DMA, e.g. using firescope. */
fs_initcall(ohci1394_init);
module_exit(ohci1394_cleanup);
......@@ -29,9 +29,8 @@ struct file_info {
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;
wait_queue_head_t wait_complete;
struct list_head addr_list;
......
This diff is collapsed.
This diff is collapsed.
......@@ -46,8 +46,8 @@
#define ORB_SET_DIRECTION(value) ((value & 0x1) << 27)
struct sbp2_command_orb {
volatile u32 next_ORB_hi;
volatile u32 next_ORB_lo;
u32 next_ORB_hi;
u32 next_ORB_lo;
u32 data_descriptor_hi;
u32 data_descriptor_lo;
u32 misc;
......@@ -180,12 +180,14 @@ struct sbp2_unrestricted_page_table {
#define SBP2_SCSI_STATUS_SELECTION_TIMEOUT 0xff
#define STATUS_GET_ORB_OFFSET_HI(value) (value & 0xffff)
#define STATUS_GET_SBP_STATUS(value) ((value >> 16) & 0xff)
#define STATUS_GET_LENGTH(value) ((value >> 24) & 0x7)
#define STATUS_GET_DEAD_BIT(value) ((value >> 27) & 0x1)
#define STATUS_GET_RESP(value) ((value >> 28) & 0x3)
#define STATUS_GET_SRC(value) ((value >> 30) & 0x3)
#define STATUS_GET_SRC(value) (((value) >> 30) & 0x3)
#define STATUS_GET_RESP(value) (((value) >> 28) & 0x3)
#define STATUS_GET_LEN(value) (((value) >> 24) & 0x7)
#define STATUS_GET_SBP_STATUS(value) (((value) >> 16) & 0xff)
#define STATUS_GET_ORB_OFFSET_HI(value) ((value) & 0x0000ffff)
#define STATUS_TEST_DEAD(value) ((value) & 0x08000000)
/* test 'resp' | 'dead' | 'sbp2_status' */
#define STATUS_TEST_RDS(value) ((value) & 0x38ff0000)
struct sbp2_status_block {
u32 ORB_offset_hi_misc;
......@@ -318,9 +320,9 @@ struct scsi_id_instance_data {
u64 status_fifo_addr;
/*
* Variable used for logins, reconnects, logouts, query logins
* Waitqueue flag for logins, reconnects, logouts, query logins
*/
atomic_t sbp2_login_complete;
int access_complete:1;
/*
* Pool of command orbs, so we can have more than overlapped command per id
......@@ -344,6 +346,16 @@ struct scsi_id_instance_data {
/* Device specific workarounds/brokeness */
unsigned workarounds;
atomic_t state;
struct work_struct protocol_work;
};
/* For use in scsi_id_instance_data.state */
enum sbp2lu_state_types {
SBP2LU_STATE_RUNNING, /* all normal */
SBP2LU_STATE_IN_RESET, /* between bus reset and reconnect */
SBP2LU_STATE_IN_SHUTDOWN /* when sbp2_remove was called */
};
/* Sbp2 host data structure (one per IEEE1394 host) */
......@@ -390,11 +402,6 @@ static int sbp2_logout_device(struct scsi_id_instance_data *scsi_id);
static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int destid,
quadlet_t *data, u64 addr, size_t length, u16 flags);
static int sbp2_agent_reset(struct scsi_id_instance_data *scsi_id, int wait);
static int sbp2_link_orb_command(struct scsi_id_instance_data *scsi_id,
struct sbp2_command_info *command);
static int sbp2_send_command(struct scsi_id_instance_data *scsi_id,
struct scsi_cmnd *SCpnt,
void (*done)(struct scsi_cmnd *));
static unsigned int sbp2_status_to_sense_data(unchar *sbp2_status,
unchar *sense_data);
static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id,
......
......@@ -49,16 +49,16 @@
#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
......@@ -129,7 +129,7 @@ struct file_ctx {
#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 */
......@@ -1181,7 +1181,8 @@ static int video1394_mmap(struct file *file, struct vm_area_struct *vma)
lock_kernel();
if (ctx->current_ctx == NULL) {
PRINT(KERN_ERR, ctx->ohci->host->id, "Current iso context not set");
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();
......@@ -1189,6 +1190,40 @@ static int video1394_mmap(struct file *file, struct vm_area_struct *vma)
return res;
}
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;
lock_kernel();
ctx = file->private_data;
d = ctx->current_ctx;
if (d == NULL) {
PRINT(KERN_ERR, ctx->ohci->host->id,
"Current iso context not set");
mask = POLLERR;
goto done;
}
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);
done:
unlock_kernel();
return mask;
}
static int video1394_open(struct inode *inode, struct file *file)
{
int i = ieee1394_file_to_instance(file);
......@@ -1257,6 +1292,7 @@ static struct file_operations video1394_fops=
#ifdef CONFIG_COMPAT
.compat_ioctl = video1394_compat_ioctl,
#endif
.poll = video1394_poll,
.mmap = video1394_mmap,
.open = video1394_open,
.release = video1394_release
......
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