aboutsummaryrefslogtreecommitdiff
path: root/drivers/ieee1394
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ieee1394')
-rw-r--r--drivers/ieee1394/csr.c31
-rw-r--r--drivers/ieee1394/csr.h109
-rw-r--r--drivers/ieee1394/dma.c7
-rw-r--r--drivers/ieee1394/dma.h90
-rw-r--r--drivers/ieee1394/dv1394-private.h6
-rw-r--r--drivers/ieee1394/dv1394.c43
-rw-r--r--drivers/ieee1394/eth1394.c11
-rw-r--r--drivers/ieee1394/highlevel.h201
-rw-r--r--drivers/ieee1394/hosts.c20
-rw-r--r--drivers/ieee1394/hosts.h32
-rw-r--r--drivers/ieee1394/ieee1394-ioctl.h9
-rw-r--r--drivers/ieee1394/ieee1394.h316
-rw-r--r--drivers/ieee1394/ieee1394_core.c4
-rw-r--r--drivers/ieee1394/ieee1394_core.h27
-rw-r--r--drivers/ieee1394/ieee1394_hotplug.h30
-rw-r--r--drivers/ieee1394/ieee1394_transactions.c6
-rw-r--r--drivers/ieee1394/ieee1394_transactions.h37
-rw-r--r--drivers/ieee1394/ieee1394_types.h45
-rw-r--r--drivers/ieee1394/iso.c5
-rw-r--r--drivers/ieee1394/iso.h87
-rw-r--r--drivers/ieee1394/nodemgr.c173
-rw-r--r--drivers/ieee1394/nodemgr.h26
-rw-r--r--drivers/ieee1394/ohci1394.c5
-rw-r--r--drivers/ieee1394/raw1394-private.h3
-rw-r--r--drivers/ieee1394/raw1394.c102
-rw-r--r--drivers/ieee1394/sbp2.c4
-rw-r--r--drivers/ieee1394/video1394.c12
27 files changed, 715 insertions, 726 deletions
diff --git a/drivers/ieee1394/csr.c b/drivers/ieee1394/csr.c
index 149573db91c..ab0c80f61b9 100644
--- a/drivers/ieee1394/csr.c
+++ b/drivers/ieee1394/csr.c
@@ -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);
}
diff --git a/drivers/ieee1394/csr.h b/drivers/ieee1394/csr.h
index ea9aa4f53ab..f11546550d8 100644
--- a/drivers/ieee1394/csr.h
+++ b/drivers/ieee1394/csr.h
@@ -1,75 +1,73 @@
-
#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 */
diff --git a/drivers/ieee1394/dma.c b/drivers/ieee1394/dma.c
index ca5167de707..c68f328e1a2 100644
--- a/drivers/ieee1394/dma.c
+++ b/drivers/ieee1394/dma.c
@@ -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 */
diff --git a/drivers/ieee1394/dma.h b/drivers/ieee1394/dma.h
index 061550a6fb9..a1682aba71c 100644
--- a/drivers/ieee1394/dma.h
+++ b/drivers/ieee1394/dma.h
@@ -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 */
diff --git a/drivers/ieee1394/dv1394-private.h b/drivers/ieee1394/dv1394-private.h
index 80b5ac7fe38..7d1d2845b42 100644
--- a/drivers/ieee1394/dv1394-private.h
+++ b/drivers/ieee1394/dv1394-private.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;
diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c
index 87532dd4337..6e71d68b109 100644
--- a/drivers/ieee1394/dv1394.c
+++ b/drivers/ieee1394/dv1394.c
@@ -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:
@@ -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;
diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c
index 2d5b57be98c..09826be86aa 100644
--- a/drivers/ieee1394/eth1394.c
+++ b/drivers/ieee1394/eth1394.c
@@ -67,16 +67,17 @@
#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)
diff --git a/drivers/ieee1394/highlevel.h b/drivers/ieee1394/highlevel.h
index e119fb87e5b..50f2dd2c7e2 100644
--- a/drivers/ieee1394/highlevel.h
+++ b/drivers/ieee1394/highlevel.h
@@ -1,60 +1,61 @@
-
#ifndef IEEE1394_HIGHLEVEL_H
#define IEEE1394_HIGHLEVEL_H
+#include <linux/list.h>
+#include <linux/spinlock_types.h>
+#include <linux/types.h>
-struct hpsb_address_serve {
- struct list_head host_list; /* per host list */
+struct module;
- struct list_head hl_list; /* hpsb_highlevel list */
+#include "ieee1394_types.h"
- struct hpsb_address_ops *op;
+struct hpsb_host;
+/* internal to ieee1394 core */
+struct hpsb_address_serve {
+ struct list_head host_list; /* per host list */
+ struct list_head hl_list; /* hpsb_highlevel list */
+ struct hpsb_address_ops *op;
struct hpsb_host *host;
-
- /* first address handled and first address behind, quadlet aligned */
- u64 start, end;
+ u64 start; /* first address handled, quadlet aligned */
+ u64 end; /* first address behind, quadlet aligned */
};
-
-/*
- * The above structs are internal to highlevel driver handling. Only the
- * following structures are of interest to actual highlevel drivers.
- */
+/* Only the following structures are of interest to actual highlevel drivers. */
struct hpsb_highlevel {
struct module *owner;
const char *name;
- /* Any of the following pointers can legally be NULL, except for
- * iso_receive which can only be NULL when you don't request
- * channels. */
+ /* Any of the following pointers can legally be NULL, except for
+ * iso_receive which can only be NULL when you don't request
+ * channels. */
- /* New host initialized. Will also be called during
- * hpsb_register_highlevel for all hosts already installed. */
- void (*add_host) (struct hpsb_host *host);
+ /* New host initialized. Will also be called during
+ * hpsb_register_highlevel for all hosts already installed. */
+ void (*add_host)(struct hpsb_host *host);
- /* Host about to be removed. Will also be called during
- * hpsb_unregister_highlevel once for each host. */
- void (*remove_host) (struct hpsb_host *host);
+ /* Host about to be removed. Will also be called during
+ * hpsb_unregister_highlevel once for each host. */
+ void (*remove_host)(struct hpsb_host *host);
- /* Host experienced bus reset with possible configuration changes.
+ /* Host experienced bus reset with possible configuration changes.
* Note that this one may occur during interrupt/bottom half handling.
* You can not expect to be able to do stock hpsb_reads. */
- void (*host_reset) (struct hpsb_host *host);
+ void (*host_reset)(struct hpsb_host *host);
- /* An isochronous packet was received. Channel contains the channel
- * number for your convenience, it is also contained in the included
- * packet header (first quadlet, CRCs are missing). You may get called
- * for channel/host combinations you did not request. */
- void (*iso_receive) (struct hpsb_host *host, int channel,
- quadlet_t *data, size_t length);
+ /* An isochronous packet was received. Channel contains the channel
+ * number for your convenience, it is also contained in the included
+ * packet header (first quadlet, CRCs are missing). You may get called
+ * for channel/host combinations you did not request. */
+ void (*iso_receive)(struct hpsb_host *host, int channel,
+ quadlet_t *data, size_t length);
- /* A write request was received on either the FCP_COMMAND (direction =
- * 0) or the FCP_RESPONSE (direction = 1) register. The cts arg
- * contains the cts field (first byte of data). */
- void (*fcp_request) (struct hpsb_host *host, int nodeid, int direction,
- int cts, u8 *data, size_t length);
+ /* A write request was received on either the FCP_COMMAND (direction =
+ * 0) or the FCP_RESPONSE (direction = 1) register. The cts arg
+ * contains the cts field (first byte of data). */
+ void (*fcp_request)(struct hpsb_host *host, int nodeid, int direction,
+ int cts, u8 *data, size_t length);
/* These are initialized by the subsystem when the
* hpsb_higlevel is registered. */
@@ -67,61 +68,62 @@ struct hpsb_highlevel {
};
struct hpsb_address_ops {
- /*
- * Null function pointers will make the respective operation complete
- * with RCODE_TYPE_ERROR. Makes for easy to implement read-only
- * registers (just leave everything but read NULL).
- *
- * All functions shall return appropriate IEEE 1394 rcodes.
- */
-
- /* These functions have to implement block reads for themselves. */
- /* These functions either return a response code
- or a negative number. In the first case a response will be generated; in the
- later case, no response will be sent and the driver, that handled the request
- will send the response itself
- */
- int (*read) (struct hpsb_host *host, int nodeid, quadlet_t *buffer,
- u64 addr, size_t length, u16 flags);
- int (*write) (struct hpsb_host *host, int nodeid, int destid,
- quadlet_t *data, u64 addr, size_t length, u16 flags);
-
- /* Lock transactions: write results of ext_tcode operation into
- * *store. */
- int (*lock) (struct hpsb_host *host, int nodeid, quadlet_t *store,
- u64 addr, quadlet_t data, quadlet_t arg, int ext_tcode, u16 flags);
- int (*lock64) (struct hpsb_host *host, int nodeid, octlet_t *store,
- u64 addr, octlet_t data, octlet_t arg, int ext_tcode, u16 flags);
+ /*
+ * Null function pointers will make the respective operation complete
+ * with RCODE_TYPE_ERROR. Makes for easy to implement read-only
+ * registers (just leave everything but read NULL).
+ *
+ * All functions shall return appropriate IEEE 1394 rcodes.
+ */
+
+ /* These functions have to implement block reads for themselves.
+ *
+ * These functions either return a response code or a negative number.
+ * In the first case a response will be generated. In the latter case,
+ * no response will be sent and the driver which handled the request
+ * will send the response itself. */
+ int (*read)(struct hpsb_host *host, int nodeid, quadlet_t *buffer,
+ u64 addr, size_t length, u16 flags);
+ int (*write)(struct hpsb_host *host, int nodeid, int destid,
+ quadlet_t *data, u64 addr, size_t length, u16 flags);
+
+ /* Lock transactions: write results of ext_tcode operation into
+ * *store. */
+ int (*lock)(struct hpsb_host *host, int nodeid, quadlet_t *store,
+ u64 addr, quadlet_t data, quadlet_t arg, int ext_tcode,
+ u16 flags);
+ int (*lock64)(struct hpsb_host *host, int nodeid, octlet_t *store,
+ u64 addr, octlet_t data, octlet_t arg, int ext_tcode,
+ u16 flags);
};
-
void highlevel_add_host(struct hpsb_host *host);
void highlevel_remove_host(struct hpsb_host *host);
void highlevel_host_reset(struct hpsb_host *host);
-
-/* these functions are called to handle transactions. They are called, when
- a packet arrives. The flags argument contains the second word of the first header
- quadlet of the incoming packet (containing transaction label, retry code,
- transaction code and priority). These functions either return a response code
- or a negative number. In the first case a response will be generated; in the
- later case, no response will be sent and the driver, that handled the request
- will send the response itself.
-*/
-int highlevel_read(struct hpsb_host *host, int nodeid, void *data,
- u64 addr, unsigned int length, u16 flags);
-int highlevel_write(struct hpsb_host *host, int nodeid, int destid,
- void *data, u64 addr, unsigned int length, u16 flags);
+/*
+ * These functions are called to handle transactions. They are called when a
+ * packet arrives. The flags argument contains the second word of the first
+ * header quadlet of the incoming packet (containing transaction label, retry
+ * code, transaction code and priority). These functions either return a
+ * response code or a negative number. In the first case a response will be
+ * generated. In the latter case, no response will be sent and the driver which
+ * handled the request will send the response itself.
+ */
+int highlevel_read(struct hpsb_host *host, int nodeid, void *data, u64 addr,
+ unsigned int length, u16 flags);
+int highlevel_write(struct hpsb_host *host, int nodeid, int destid, void *data,
+ u64 addr, unsigned int length, u16 flags);
int highlevel_lock(struct hpsb_host *host, int nodeid, quadlet_t *store,
- u64 addr, quadlet_t data, quadlet_t arg, int ext_tcode, u16 flags);
+ u64 addr, quadlet_t data, quadlet_t arg, int ext_tcode,
+ u16 flags);
int highlevel_lock64(struct hpsb_host *host, int nodeid, octlet_t *store,
- u64 addr, octlet_t data, octlet_t arg, int ext_tcode, u16 flags);
+ u64 addr, octlet_t data, octlet_t arg, int ext_tcode,
+ u16 flags);
-void highlevel_iso_receive(struct hpsb_host *host, void *data,
- size_t length);
+void highlevel_iso_receive(struct hpsb_host *host, void *data, size_t length);
void highlevel_fcp_request(struct hpsb_host *host, int nodeid, int direction,
- void *data, size_t length);
-
+ void *data, size_t length);
/*
* Register highlevel driver. The name pointer has to stay valid at all times
@@ -132,13 +134,15 @@ void hpsb_unregister_highlevel(struct hpsb_highlevel *hl);
/*
* Register handlers for host address spaces. Start and end are 48 bit pointers
- * and have to be quadlet aligned (end points to the first address behind the
- * handled addresses. This function can be called multiple times for a single
- * hpsb_highlevel to implement sparse register sets. The requested region must
- * not overlap any previously allocated region, otherwise registering will fail.
+ * and have to be quadlet aligned. Argument "end" points to the first address
+ * behind the handled addresses. This function can be called multiple times for
+ * a single hpsb_highlevel to implement sparse register sets. The requested
+ * region must not overlap any previously allocated region, otherwise
+ * registering will fail.
*
- * It returns true for successful allocation. There is no unregister function,
- * all address spaces are deallocated together with the hpsb_highlevel.
+ * It returns true for successful allocation. Address spaces can be
+ * unregistered with hpsb_unregister_addrspace. All remaining address spaces
+ * are automatically deallocated together with the hpsb_highlevel.
*/
u64 hpsb_allocate_and_register_addrspace(struct hpsb_highlevel *hl,
struct hpsb_host *host,
@@ -146,20 +150,18 @@ u64 hpsb_allocate_and_register_addrspace(struct hpsb_highlevel *hl,
u64 size, u64 alignment,
u64 start, u64 end);
int hpsb_register_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host,
- struct hpsb_address_ops *ops, u64 start, u64 end);
-
+ struct hpsb_address_ops *ops, u64 start, u64 end);
int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host,
- u64 start);
+ u64 start);
/*
* Enable or disable receving a certain isochronous channel through the
* iso_receive op.
*/
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,
- unsigned int channel);
-
+ unsigned int channel);
/* Retrieve a hostinfo pointer bound to this driver/host */
void *hpsb_get_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host);
@@ -172,19 +174,24 @@ void *hpsb_create_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host,
void hpsb_destroy_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host);
/* Set an alternate lookup key for the hostinfo bound to this driver/host */
-void hpsb_set_hostinfo_key(struct hpsb_highlevel *hl, struct hpsb_host *host, unsigned long key);
+void hpsb_set_hostinfo_key(struct hpsb_highlevel *hl, struct hpsb_host *host,
+ unsigned long key);
-/* Retrieve the alternate lookup key for the hostinfo bound to this driver/host */
-unsigned long hpsb_get_hostinfo_key(struct hpsb_highlevel *hl, struct hpsb_host *host);
+/* Retrieve the alternate lookup key for the hostinfo bound to this
+ * driver/host */
+unsigned long hpsb_get_hostinfo_key(struct hpsb_highlevel *hl,
+ struct hpsb_host *host);
/* Retrieve a hostinfo pointer bound to this driver using its alternate key */
void *hpsb_get_hostinfo_bykey(struct hpsb_highlevel *hl, unsigned long key);
/* Set the hostinfo pointer to something useful. Usually follows a call to
* hpsb_create_hostinfo, where the size is 0. */
-int hpsb_set_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host, void *data);
+int hpsb_set_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host,
+ void *data);
/* Retrieve hpsb_host using a highlevel handle and a key */
-struct hpsb_host *hpsb_get_host_bykey(struct hpsb_highlevel *hl, unsigned long key);
+struct hpsb_host *hpsb_get_host_bykey(struct hpsb_highlevel *hl,
+ unsigned long key);
#endif /* IEEE1394_HIGHLEVEL_H */
diff --git a/drivers/ieee1394/hosts.c b/drivers/ieee1394/hosts.c
index 4feead4a35c..59e6f49545b 100644
--- a/drivers/ieee1394/hosts.c
+++ b/drivers/ieee1394/hosts.c
@@ -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)
{
diff --git a/drivers/ieee1394/hosts.h b/drivers/ieee1394/hosts.h
index 9ad4b246307..69a7c9ff5ed 100644
--- a/drivers/ieee1394/hosts.h
+++ b/drivers/ieee1394/hosts.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;
@@ -112,7 +114,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 +162,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 +173,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 +200,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.
diff --git a/drivers/ieee1394/ieee1394-ioctl.h b/drivers/ieee1394/ieee1394-ioctl.h
index 15670398634..8f207508ed1 100644
--- a/drivers/ieee1394/ieee1394-ioctl.h
+++ b/drivers/ieee1394/ieee1394-ioctl.h
@@ -1,5 +1,7 @@
-/* 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 */
diff --git a/drivers/ieee1394/ieee1394.h b/drivers/ieee1394/ieee1394.h
index 936d776de00..40492074c01 100644
--- a/drivers/ieee1394/ieee1394.h
+++ b/drivers/ieee1394/ieee1394.h
@@ -5,77 +5,78 @@
#ifndef _IEEE1394_IEEE1394_H
#define _IEEE1394_IEEE1394_H
-#define TCODE_WRITEQ 0x0
-#define TCODE_WRITEB 0x1
-#define TCODE_WRITE_RESPONSE 0x2
-#define TCODE_READQ 0x4
-#define TCODE_READB 0x5
-#define TCODE_READQ_RESPONSE 0x6
-#define TCODE_READB_RESPONSE 0x7
-#define TCODE_CYCLE_START 0x8
-#define TCODE_LOCK_REQUEST 0x9
-#define TCODE_ISO_DATA 0xa
-#define TCODE_STREAM_DATA 0xa
-#define TCODE_LOCK_RESPONSE 0xb
-
-#define RCODE_COMPLETE 0x0
-#define RCODE_CONFLICT_ERROR 0x4
-#define RCODE_DATA_ERROR 0x5
-#define RCODE_TYPE_ERROR 0x6
-#define RCODE_ADDRESS_ERROR 0x7
-
-#define EXTCODE_MASK_SWAP 0x1
-#define EXTCODE_COMPARE_SWAP 0x2
-#define EXTCODE_FETCH_ADD 0x3
-#define EXTCODE_LITTLE_ADD 0x4
-#define EXTCODE_BOUNDED_ADD 0x5
-#define EXTCODE_WRAP_ADD 0x6
-
-#define ACK_COMPLETE 0x1
-#define ACK_PENDING 0x2
-#define ACK_BUSY_X 0x4
-#define ACK_BUSY_A 0x5
-#define ACK_BUSY_B 0x6
-#define ACK_TARDY 0xb
-#define ACK_CONFLICT_ERROR 0xc
-#define ACK_DATA_ERROR 0xd
-#define ACK_TYPE_ERROR 0xe
-#define ACK_ADDRESS_ERROR 0xf
+#define TCODE_WRITEQ 0x0
+#define TCODE_WRITEB 0x1
+#define TCODE_WRITE_RESPONSE 0x2
+#define TCODE_READQ 0x4
+#define TCODE_READB 0x5
+#define TCODE_READQ_RESPONSE 0x6
+#define TCODE_READB_RESPONSE 0x7
+#define TCODE_CYCLE_START 0x8
+#define TCODE_LOCK_REQUEST 0x9
+#define TCODE_ISO_DATA 0xa
+#define TCODE_STREAM_DATA 0xa
+#define TCODE_LOCK_RESPONSE 0xb
+
+#define RCODE_COMPLETE 0x0
+#define RCODE_CONFLICT_ERROR 0x4
+#define RCODE_DATA_ERROR 0x5
+#define RCODE_TYPE_ERROR 0x6
+#define RCODE_ADDRESS_ERROR 0x7
+
+#define EXTCODE_MASK_SWAP 0x1
+#define EXTCODE_COMPARE_SWAP 0x2
+#define EXTCODE_FETCH_ADD 0x3
+#define EXTCODE_LITTLE_ADD 0x4
+#define EXTCODE_BOUNDED_ADD 0x5
+#define EXTCODE_WRAP_ADD 0x6
+
+#define ACK_COMPLETE 0x1
+#define ACK_PENDING 0x2
+#define ACK_BUSY_X 0x4
+#define ACK_BUSY_A 0x5
+#define ACK_BUSY_B 0x6
+#define ACK_TARDY 0xb
+#define ACK_CONFLICT_ERROR 0xc
+#define ACK_DATA_ERROR 0xd
+#define ACK_TYPE_ERROR 0xe
+#define ACK_ADDRESS_ERROR 0xf
/* Non-standard "ACK codes" for internal use */
-#define ACKX_NONE (-1)
-#define ACKX_SEND_ERROR (-2)
-#define ACKX_ABORTED (-3)
-#define ACKX_TIMEOUT (-4)
-
-
-#define IEEE1394_SPEED_100 0x00
-#define IEEE1394_SPEED_200 0x01
-#define IEEE1394_SPEED_400 0x02
-#define IEEE1394_SPEED_800 0x03
-#define IEEE1394_SPEED_1600 0x04
-#define IEEE1394_SPEED_3200 0x05
+#define ACKX_NONE (-1)
+#define ACKX_SEND_ERROR (-2)
+#define ACKX_ABORTED (-3)
+#define ACKX_TIMEOUT (-4)
+
+#define IEEE1394_SPEED_100 0x00
+#define IEEE1394_SPEED_200 0x01
+#define IEEE1394_SPEED_400 0x02
+#define IEEE1394_SPEED_800 0x03
+#define IEEE1394_SPEED_1600 0x04
+#define IEEE1394_SPEED_3200 0x05
+
/* The current highest tested speed supported by the subsystem */
-#define IEEE1394_SPEED_MAX IEEE1394_SPEED_800
+#define IEEE1394_SPEED_MAX IEEE1394_SPEED_800
/* Maps speed values above to a string representation */
extern const char *hpsb_speedto_str[];
-
/* 1394a cable PHY packets */
-#define SELFID_PWRCL_NO_POWER 0x0
-#define SELFID_PWRCL_PROVIDE_15W 0x1
-#define SELFID_PWRCL_PROVIDE_30W 0x2
-#define SELFID_PWRCL_PROVIDE_45W 0x3
-#define SELFID_PWRCL_USE_1W 0x4
-#define SELFID_PWRCL_USE_3W 0x5
-#define SELFID_PWRCL_USE_6W 0x6
-#define SELFID_PWRCL_USE_10W 0x7
-
-#define SELFID_PORT_CHILD 0x3
-#define SELFID_PORT_PARENT 0x2
-#define SELFID_PORT_NCONN 0x1
-#define SELFID_PORT_NONE 0x0
+#define SELFID_PWRCL_NO_POWER 0x0
+#define SELFID_PWRCL_PROVIDE_15W 0x1
+#define SELFID_PWRCL_PROVIDE_30W 0x2
+#define SELFID_PWRCL_PROVIDE_45W 0x3
+#define SELFID_PWRCL_USE_1W 0x4
+#define SELFID_PWRCL_USE_3W 0x5
+#define SELFID_PWRCL_USE_6W 0x6
+#define SELFID_PWRCL_USE_10W 0x7
+
+#define SELFID_PORT_CHILD 0x3
+#define SELFID_PORT_PARENT 0x2
+#define SELFID_PORT_NCONN 0x1
+#define SELFID_PORT_NONE 0x0
+
+#define SELFID_SPEED_UNKNOWN 0x3 /* 1394b PHY */
#define PHYPACKET_LINKON 0x40000000
#define PHYPACKET_PHYCONFIG_R 0x00800000
@@ -91,76 +92,76 @@ extern const char *hpsb_speedto_str[];
#define EXTPHYPACKET_TYPEMASK 0xC0FC0000
-#define PHYPACKET_PORT_SHIFT 24
-#define PHYPACKET_GAPCOUNT_SHIFT 16
+#define PHYPACKET_PORT_SHIFT 24
+#define PHYPACKET_GAPCOUNT_SHIFT 16
/* 1394a PHY register map bitmasks */
-#define PHY_00_PHYSICAL_ID 0xFC
-#define PHY_00_R 0x02 /* Root */
-#define PHY_00_PS 0x01 /* Power Status*/
-#define PHY_01_RHB 0x80 /* Root Hold-Off */
-#define PHY_01_IBR 0x80 /* Initiate Bus Reset */
-#define PHY_01_GAP_COUNT 0x3F
-#define PHY_02_EXTENDED 0xE0 /* 0x7 for 1394a-compliant PHY */
-#define PHY_02_TOTAL_PORTS 0x1F
-#define PHY_03_MAX_SPEED 0xE0
-#define PHY_03_DELAY 0x0F
-#define PHY_04_LCTRL 0x80 /* Link Active Report Control */
-#define PHY_04_CONTENDER 0x40
-#define PHY_04_JITTER 0x38
-#define PHY_04_PWR_CLASS 0x07 /* Power Class */
-#define PHY_05_WATCHDOG 0x80
-#define PHY_05_ISBR 0x40 /* Initiate Short Bus Reset */
-#define PHY_05_LOOP 0x20 /* Loop Detect */
-#define PHY_05_PWR_FAIL 0x10 /* Cable Power Failure Detect */
-#define PHY_05_TIMEOUT 0x08 /* Arbitration State Machine Timeout */
-#define PHY_05_PORT_EVENT 0x04 /* Port Event Detect */
-#define PHY_05_ENAB_ACCEL 0x02 /* Enable Arbitration Acceleration */
-#define PHY_05_ENAB_MULTI 0x01 /* Ena. Multispeed Packet Concatenation */
+#define PHY_00_PHYSICAL_ID 0xFC
+#define PHY_00_R 0x02 /* Root */
+#define PHY_00_PS 0x01 /* Power Status*/
+#define PHY_01_RHB 0x80 /* Root Hold-Off */
+#define PHY_01_IBR 0x80 /* Initiate Bus Reset */
+#define PHY_01_GAP_COUNT 0x3F
+#define PHY_02_EXTENDED 0xE0 /* 0x7 for 1394a-compliant PHY */
+#define PHY_02_TOTAL_PORTS 0x1F
+#define PHY_03_MAX_SPEED 0xE0
+#define PHY_03_DELAY 0x0F
+#define PHY_04_LCTRL 0x80 /* Link Active Report Control */
+#define PHY_04_CONTENDER 0x40
+#define PHY_04_JITTER 0x38
+#define PHY_04_PWR_CLASS 0x07 /* Power Class */
+#define PHY_05_WATCHDOG 0x80
+#define PHY_05_ISBR 0x40 /* Initiate Short Bus Reset */
+#define PHY_05_LOOP 0x20 /* Loop Detect */
+#define PHY_05_PWR_FAIL 0x10 /* Cable Power Failure Detect */
+#define PHY_05_TIMEOUT 0x08 /* Arbitration State Machine Timeout */
+#define PHY_05_PORT_EVENT 0x04 /* Port Event Detect */
+#define PHY_05_ENAB_ACCEL 0x02 /* Enable Arbitration Acceleration */
+#define PHY_05_ENAB_MULTI 0x01 /* Ena. Multispeed Packet Concatenation */
#include <asm/byteorder.h>
#ifdef __BIG_ENDIAN_BITFIELD
struct selfid {
- u32 packet_identifier:2; /* always binary 10 */
- u32 phy_id:6;
- /* byte */
- u32 extended:1; /* if true is struct ext_selfid */
- u32 link_active:1;
- u32 gap_count:6;
- /* byte */
- u32 speed:2;
- u32 phy_delay:2;
- u32 contender:1;
- u32 power_class:3;
- /* byte */
- u32 port0:2;
- u32 port1:2;
- u32 port2:2;
- u32 initiated_reset:1;
- u32 more_packets:1;
+ u32 packet_identifier:2; /* always binary 10 */
+ u32 phy_id:6;
+ /* byte */
+ u32 extended:1; /* if true is struct ext_selfid */
+ u32 link_active:1;
+ u32 gap_count:6;
+ /* byte */
+ u32 speed:2;
+ u32 phy_delay:2;
+ u32 contender:1;
+ u32 power_class:3;
+ /* byte */
+ u32 port0:2;
+ u32 port1:2;
+ u32 port2:2;
+ u32 initiated_reset:1;
+ u32 more_packets:1;
} __attribute__((packed));
struct ext_selfid {
- u32 packet_identifier:2; /* always binary 10 */
- u32 phy_id:6;
- /* byte */
- u32 extended:1; /* if false is struct selfid */
- u32 seq_nr:3;
- u32 reserved:2;
- u32 porta:2;
- /* byte */
- u32 portb:2;
- u32 portc:2;
- u32 portd:2;
- u32 porte:2;
- /* byte */
- u32 portf:2;
- u32 portg:2;
- u32 porth:2;
- u32 reserved2:1;
- u32 more_packets:1;
+ u32 packet_identifier:2; /* always binary 10 */
+ u32 phy_id:6;
+ /* byte */
+ u32 extended:1; /* if false is struct selfid */
+ u32 seq_nr:3;
+ u32 reserved:2;
+ u32 porta:2;
+ /* byte */
+ u32 portb:2;
+ u32 portc:2;
+ u32 portd:2;
+ u32 porte:2;
+ /* byte */
+ u32 portf:2;
+ u32 portg:2;
+ u32 porth:2;
+ u32 reserved2:1;
+ u32 more_packets:1;
} __attribute__((packed));
#elif defined __LITTLE_ENDIAN_BITFIELD /* __BIG_ENDIAN_BITFIELD */
@@ -171,49 +172,48 @@ struct ext_selfid {
*/
struct selfid {
- u32 phy_id:6;
- u32 packet_identifier:2; /* always binary 10 */
- /* byte */
- u32 gap_count:6;
- u32 link_active:1;
- u32 extended:1; /* if true is struct ext_selfid */
- /* byte */
- u32 power_class:3;
- u32 contender:1;
- u32 phy_delay:2;
- u32 speed:2;
- /* byte */
- u32 more_packets:1;
- u32 initiated_reset:1;
- u32 port2:2;
- u32 port1:2;
- u32 port0:2;
+ u32 phy_id:6;
+ u32 packet_identifier:2; /* always binary 10 */
+ /* byte */
+ u32 gap_count:6;
+ u32 link_active:1;
+ u32 extended:1; /* if true is struct ext_selfid */
+ /* byte */
+ u32 power_class:3;
+ u32 contender:1;
+ u32 phy_delay:2;
+ u32 speed:2;
+ /* byte */
+ u32 more_packets:1;
+ u32 initiated_reset:1;
+ u32 port2:2;
+ u32 port1:2;
+ u32 port0:2;
} __attribute__((packed));
struct ext_selfid {
- u32 phy_id:6;
- u32 packet_identifier:2; /* always binary 10 */
- /* byte */
- u32 porta:2;
- u32 reserved:2;
- u32 seq_nr:3;
- u32 extended:1; /* if false is struct selfid */
- /* byte */
- u32 porte:2;
- u32 portd:2;
- u32 portc:2;
- u32 portb:2;
- /* byte */
- u32 more_packets:1;
- u32 reserved2:1;
- u32 porth:2;
- u32 portg:2;
- u32 portf:2;
+ u32 phy_id:6;
+ u32 packet_identifier:2; /* always binary 10 */
+ /* byte */
+ u32 porta:2;
+ u32 reserved:2;
+ u32 seq_nr:3;
+ u32 extended:1; /* if false is struct selfid */
+ /* byte */
+ u32 porte:2;
+ u32 portd:2;
+ u32 portc:2;
+ u32 portb:2;
+ /* byte */
+ u32 more_packets:1;
+ u32 reserved2:1;
+ u32 porth:2;
+ u32 portg:2;
+ u32 portf:2;
} __attribute__((packed));
#else
#error What? PDP endian?
#endif /* __BIG_ENDIAN_BITFIELD */
-
#endif /* _IEEE1394_IEEE1394_H */
diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c
index f43739c5cab..559c477092f 100644
--- a/drivers/ieee1394/ieee1394_core.c
+++ b/drivers/ieee1394/ieee1394_core.c
@@ -355,10 +355,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
}
diff --git a/drivers/ieee1394/ieee1394_core.h b/drivers/ieee1394/ieee1394_core.h
index 0ecbf335c64..1ce172b2856 100644
--- a/drivers/ieee1394/ieee1394_core.h
+++ b/drivers/ieee1394/ieee1394_core.h
@@ -1,12 +1,16 @@
-
#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 +62,6 @@ struct hpsb_packet {
size_t header_size;
size_t data_size;
-
struct hpsb_host *host;
unsigned int generation;
@@ -80,7 +83,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 +95,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 +206,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 +229,3 @@ extern struct class hpsb_host_class;
extern struct class *hpsb_protocol_class;
#endif /* _IEEE1394_CORE_H */
-
diff --git a/drivers/ieee1394/ieee1394_hotplug.h b/drivers/ieee1394/ieee1394_hotplug.h
index 5be70d31b00..dd5500ed832 100644
--- a/drivers/ieee1394/ieee1394_hotplug.h
+++ b/drivers/ieee1394/ieee1394_hotplug.h
@@ -1,33 +1,19 @@
#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 */
diff --git a/drivers/ieee1394/ieee1394_transactions.c b/drivers/ieee1394/ieee1394_transactions.c
index a114b91d606..751960037e2 100644
--- a/drivers/ieee1394/ieee1394_transactions.c
+++ b/drivers/ieee1394/ieee1394_transactions.c
@@ -14,6 +14,7 @@
#include <linux/smp_lock.h>
#include <linux/interrupt.h>
+#include <asm/bug.h>
#include <asm/errno.h>
#include "ieee1394.h"
@@ -214,7 +215,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 +262,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,
diff --git a/drivers/ieee1394/ieee1394_transactions.h b/drivers/ieee1394/ieee1394_transactions.h
index 45ba784fe6d..290d37060b0 100644
--- a/drivers/ieee1394/ieee1394_transactions.h
+++ b/drivers/ieee1394/ieee1394_transactions.h
@@ -1,32 +1,32 @@
#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
diff --git a/drivers/ieee1394/ieee1394_types.h b/drivers/ieee1394/ieee1394_types.h
index 3165609ec1e..16fd2d0b5ed 100644
--- a/drivers/ieee1394/ieee1394_types.h
+++ b/drivers/ieee1394/ieee1394_types.h
@@ -1,17 +1,14 @@
-
#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 <linux/types.h>
-#include <asm/semaphore.h>
#include <asm/byteorder.h>
-
+#include <asm/semaphore.h>
/* Transaction Label handling */
struct hpsb_tlabel_pool {
@@ -31,7 +28,6 @@ do { \
sema_init(&(_tp)->count, 63); \
} while (0)
-
typedef u32 quadlet_t;
typedef u64 octlet_t;
typedef u16 nodeid_t;
@@ -54,46 +50,39 @@ 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)
#else
#define HPSB_VERBOSE(fmt, args...)
#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 */
diff --git a/drivers/ieee1394/iso.c b/drivers/ieee1394/iso.c
index f26680ebef7..08bd15d2a7b 100644
--- a/drivers/ieee1394/iso.c
+++ b/drivers/ieee1394/iso.c
@@ -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)
diff --git a/drivers/ieee1394/iso.h b/drivers/ieee1394/iso.h
index 3efc60b33a8..1210a97e868 100644
--- a/drivers/ieee1394/iso.h
+++ b/drivers/ieee1394/iso.h
@@ -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);
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
index d541b508a15..f8f6079cc48 100644
--- a/drivers/ieee1394/nodemgr.c
+++ b/drivers/ieee1394/nodemgr.c
@@ -12,26 +12,23 @@
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
-#include <linux/interrupt.h>
-#include <linux/kmod.h>
-#include <linux/completion.h>
#include <linux/delay.h>
-#include <linux/pci.h>
+#include <linux/kthread.h>
#include <linux/moduleparam.h>
#include <asm/atomic.h>
-#include "ieee1394_types.h"
+#include "csr.h"
+#include "highlevel.h"
+#include "hosts.h"
#include "ieee1394.h"
#include "ieee1394_core.h"
-#include "hosts.h"
+#include "ieee1394_hotplug.h"
+#include "ieee1394_types.h"
#include "ieee1394_transactions.h"
-#include "highlevel.h"
-#include "csr.h"
#include "nodemgr.h"
static int ignore_drivers;
-module_param(ignore_drivers, int, 0444);
+module_param(ignore_drivers, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(ignore_drivers, "Disable automatic probing for drivers.");
struct nodemgr_csr_info {
@@ -71,7 +68,7 @@ static int nodemgr_check_speed(struct nodemgr_csr_info *ci, u64 addr,
u8 i, *speed, old_speed, good_speed;
int ret;
- speed = ci->host->speed + NODEID_TO_NODE(ci->nodeid);
+ speed = &(ci->host->speed[NODEID_TO_NODE(ci->nodeid)]);
old_speed = *speed;
good_speed = IEEE1394_SPEED_MAX + 1;
@@ -161,16 +158,12 @@ static struct csr1212_bus_ops nodemgr_csr_ops = {
* but now we are much simpler because of the LDM.
*/
-static DECLARE_MUTEX(nodemgr_serialize);
+static DEFINE_MUTEX(nodemgr_serialize);
struct host_info {
struct hpsb_host *host;
struct list_head list;
- struct completion exited;
- struct semaphore reset_sem;
- int pid;
- char daemon_name[15];
- int kill_me;
+ struct task_struct *thread;
};
static int nodemgr_bus_match(struct device * dev, struct device_driver * drv);
@@ -408,26 +401,11 @@ static ssize_t fw_get_destroy_node(struct bus_type *bus, char *buf)
}
static BUS_ATTR(destroy_node, S_IWUSR | S_IRUGO, fw_get_destroy_node, fw_set_destroy_node);
-static int nodemgr_rescan_bus_thread(void *__unused)
-{
- /* No userlevel access needed */
- daemonize("kfwrescan");
-
- bus_rescan_devices(&ieee1394_bus_type);
-
- return 0;
-}
static ssize_t fw_set_rescan(struct bus_type *bus, const char *buf, size_t count)
{
- int state = simple_strtoul(buf, NULL, 10);
-
- /* Don't wait for this, or care about errors. Root could do
- * something stupid and spawn this a lot of times, but that's
- * root's fault. */
- if (state == 1)
- kernel_thread(nodemgr_rescan_bus_thread, NULL, CLONE_KERNEL);
-
+ if (simple_strtoul(buf, NULL, 10) == 1)
+ bus_rescan_devices(&ieee1394_bus_type);
return count;
}
static ssize_t fw_get_rescan(struct bus_type *bus, char *buf)
@@ -1251,6 +1229,7 @@ static void nodemgr_node_scan_one(struct host_info *hi,
octlet_t guid;
struct csr1212_csr *csr;
struct nodemgr_csr_info *ci;
+ u8 *speed;
ci = kmalloc(sizeof(*ci), GFP_KERNEL);
if (!ci)
@@ -1259,8 +1238,12 @@ static void nodemgr_node_scan_one(struct host_info *hi,
ci->host = host;
ci->nodeid = nodeid;
ci->generation = generation;
- ci->speed_unverified =
- host->speed[NODEID_TO_NODE(nodeid)] > IEEE1394_SPEED_100;
+
+ /* Prepare for speed probe which occurs when reading the ROM */
+ speed = &(host->speed[NODEID_TO_NODE(nodeid)]);
+ if (*speed > host->csr.lnk_spd)
+ *speed = host->csr.lnk_spd;
+ ci->speed_unverified = *speed > IEEE1394_SPEED_100;
/* We need to detect when the ConfigROM's generation has changed,
* so we only update the node's info when it needs to be. */
@@ -1300,8 +1283,6 @@ static void nodemgr_node_scan_one(struct host_info *hi,
nodemgr_create_node(guid, csr, hi, nodeid, generation);
else
nodemgr_update_node(ne, csr, hi, nodeid, generation);
-
- return;
}
@@ -1492,9 +1473,8 @@ static void nodemgr_node_probe(struct host_info *hi, int generation)
/* If we had a bus reset while we were scanning the bus, it is
* possible that we did not probe all nodes. In that case, we
* skip the clean up for now, since we could remove nodes that
- * were still on the bus. The bus reset increased hi->reset_sem,
- * so there's a bus scan pending which will do the clean up
- * eventually.
+ * were still on the bus. Another bus scan is pending which will
+ * do the clean up eventually.
*
* Now let's tell the bus to rescan our devices. This may seem
* like overhead, but the driver-model core will only scan a
@@ -1622,41 +1602,37 @@ static int nodemgr_host_thread(void *__hi)
{
struct host_info *hi = (struct host_info *)__hi;
struct hpsb_host *host = hi->host;
- int reset_cycles = 0;
-
- /* No userlevel access needed */
- daemonize(hi->daemon_name);
+ unsigned int g, generation = get_hpsb_generation(host) - 1;
+ int i, reset_cycles = 0;
/* Setup our device-model entries */
nodemgr_create_host_dev_files(host);
- /* Sit and wait for a signal to probe the nodes on the bus. This
- * happens when we get a bus reset. */
- while (1) {
- unsigned int generation = 0;
- int i;
+ for (;;) {
+ /* Sleep until next bus reset */
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (get_hpsb_generation(host) == generation)
+ schedule();
+ __set_current_state(TASK_RUNNING);
- if (down_interruptible(&hi->reset_sem) ||
- down_interruptible(&nodemgr_serialize)) {
+ /* Thread may have been woken up to freeze or to exit */
+ if (try_to_freeze())
+ continue;
+ if (kthread_should_stop())
+ goto exit;
+
+ if (mutex_lock_interruptible(&nodemgr_serialize)) {
if (try_to_freeze())
continue;
- printk("NodeMgr: received unexpected signal?!\n" );
- break;
- }
-
- if (hi->kill_me) {
- up(&nodemgr_serialize);
- break;
+ goto exit;
}
/* Pause for 1/4 second in 1/16 second intervals,
* to make sure things settle down. */
+ g = get_hpsb_generation(host);
for (i = 0; i < 4 ; i++) {
- set_current_state(TASK_INTERRUPTIBLE);
- if (msleep_interruptible(63)) {
- up(&nodemgr_serialize);
- goto caught_signal;
- }
+ if (msleep_interruptible(63) || kthread_should_stop())
+ goto unlock_exit;
/* Now get the generation in which the node ID's we collect
* are valid. During the bus scan we will use this generation
@@ -1667,20 +1643,14 @@ static int nodemgr_host_thread(void *__hi)
/* If we get a reset before we are done waiting, then
* start the the waiting over again */
- while (!down_trylock(&hi->reset_sem))
- i = 0;
-
- /* Check the kill_me again */
- if (hi->kill_me) {
- up(&nodemgr_serialize);
- goto caught_signal;
- }
+ if (generation != g)
+ g = generation, i = 0;
}
if (!nodemgr_check_irm_capability(host, reset_cycles) ||
!nodemgr_do_irm_duties(host, reset_cycles)) {
reset_cycles++;
- up(&nodemgr_serialize);
+ mutex_unlock(&nodemgr_serialize);
continue;
}
reset_cycles = 0;
@@ -1698,13 +1668,13 @@ static int nodemgr_host_thread(void *__hi)
/* Update some of our sysfs symlinks */
nodemgr_update_host_dev_links(host);
- up(&nodemgr_serialize);
+ mutex_unlock(&nodemgr_serialize);
}
-
-caught_signal:
+unlock_exit:
+ mutex_unlock(&nodemgr_serialize);
+exit:
HPSB_VERBOSE("NodeMgr: Exiting thread");
-
- complete_and_exit(&hi->exited, 0);
+ return 0;
}
int nodemgr_for_each_host(void *__data, int (*cb)(struct hpsb_host *, void *))
@@ -1764,41 +1734,27 @@ static void nodemgr_add_host(struct hpsb_host *host)
struct host_info *hi;
hi = hpsb_create_hostinfo(&nodemgr_highlevel, host, sizeof(*hi));
-
if (!hi) {
- HPSB_ERR ("NodeMgr: out of memory in add host");
+ HPSB_ERR("NodeMgr: out of memory in add host");
return;
}
-
hi->host = host;
- init_completion(&hi->exited);
- sema_init(&hi->reset_sem, 0);
-
- sprintf(hi->daemon_name, "knodemgrd_%d", host->id);
-
- hi->pid = kernel_thread(nodemgr_host_thread, hi, CLONE_KERNEL);
-
- if (hi->pid < 0) {
- HPSB_ERR ("NodeMgr: failed to start %s thread for %s",
- hi->daemon_name, host->driver->name);
+ hi->thread = kthread_run(nodemgr_host_thread, hi, "knodemgrd_%d",
+ host->id);
+ if (IS_ERR(hi->thread)) {
+ HPSB_ERR("NodeMgr: cannot start thread for host %d", host->id);
hpsb_destroy_hostinfo(&nodemgr_highlevel, host);
- return;
}
-
- return;
}
static void nodemgr_host_reset(struct hpsb_host *host)
{
struct host_info *hi = hpsb_get_hostinfo(&nodemgr_highlevel, host);
- if (hi != NULL) {
- HPSB_VERBOSE("NodeMgr: Processing host reset for %s", hi->daemon_name);
- up(&hi->reset_sem);
- } else
- HPSB_ERR ("NodeMgr: could not process reset of unused host");
-
- return;
+ if (hi) {
+ HPSB_VERBOSE("NodeMgr: Processing reset for host %d", host->id);
+ wake_up_process(hi->thread);
+ }
}
static void nodemgr_remove_host(struct hpsb_host *host)
@@ -1806,18 +1762,9 @@ static void nodemgr_remove_host(struct hpsb_host *host)
struct host_info *hi = hpsb_get_hostinfo(&nodemgr_highlevel, host);
if (hi) {
- if (hi->pid >= 0) {
- hi->kill_me = 1;
- mb();
- up(&hi->reset_sem);
- wait_for_completion(&hi->exited);
- nodemgr_remove_host_dev(&host->device);
- }
- } else
- HPSB_ERR("NodeMgr: host %s does not exist, cannot remove",
- host->driver->name);
-
- return;
+ kthread_stop(hi->thread);
+ nodemgr_remove_host_dev(&host->device);
+ }
}
static struct hpsb_highlevel nodemgr_highlevel = {
diff --git a/drivers/ieee1394/nodemgr.h b/drivers/ieee1394/nodemgr.h
index 0b26616e16c..f649c9d321b 100644
--- a/drivers/ieee1394/nodemgr.h
+++ b/drivers/ieee1394/nodemgr.h
@@ -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 {
@@ -106,7 +110,6 @@ struct node_entry {
struct hpsb_tlabel_pool *tpool;
struct device device;
-
struct class_device class_dev;
/* Means this node is not attached anymore */
@@ -153,8 +156,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 +173,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;
diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c
index 448df277337..baa090d08d2 100644
--- a/drivers/ieee1394/ohci1394.c
+++ b/drivers/ieee1394/ohci1394.c
@@ -2598,8 +2598,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;
diff --git a/drivers/ieee1394/raw1394-private.h b/drivers/ieee1394/raw1394-private.h
index c93587be9ca..c7731d1bcd8 100644
--- a/drivers/ieee1394/raw1394-private.h
+++ b/drivers/ieee1394/raw1394-private.h
@@ -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;
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
index 571ea68c0cf..840b705fd5d 100644
--- a/drivers/ieee1394/raw1394.c
+++ b/drivers/ieee1394/raw1394.c
@@ -44,14 +44,15 @@
#include <linux/compat.h>
#include "csr1212.h"
+#include "highlevel.h"
+#include "hosts.h"
#include "ieee1394.h"
-#include "ieee1394_types.h"
#include "ieee1394_core.h"
-#include "nodemgr.h"
-#include "hosts.h"
-#include "highlevel.h"
-#include "iso.h"
+#include "ieee1394_hotplug.h"
#include "ieee1394_transactions.h"
+#include "ieee1394_types.h"
+#include "iso.h"
+#include "nodemgr.h"
#include "raw1394.h"
#include "raw1394-private.h"
@@ -132,10 +133,9 @@ static void free_pending_request(struct pending_request *req)
static void __queue_complete_req(struct pending_request *req)
{
struct file_info *fi = req->file_info;
- list_move_tail(&req->list, &fi->req_complete);
- up(&fi->complete_sem);
- wake_up_interruptible(&fi->poll_wait_complete);
+ list_move_tail(&req->list, &fi->req_complete);
+ wake_up(&fi->wait_complete);
}
static void queue_complete_req(struct pending_request *req)
@@ -463,13 +463,36 @@ raw1394_compat_read(const char __user *buf, struct raw1394_request *r)
#endif
+/* get next completed request (caller must hold fi->reqlists_lock) */
+static inline struct pending_request *__next_complete_req(struct file_info *fi)
+{
+ struct list_head *lh;
+ struct pending_request *req = NULL;
+
+ if (!list_empty(&fi->req_complete)) {
+ lh = fi->req_complete.next;
+ list_del(lh);
+ req = list_entry(lh, struct pending_request, list);
+ }
+ return req;
+}
+
+/* atomically get next completed request */
+static struct pending_request *next_complete_req(struct file_info *fi)
+{
+ unsigned long flags;
+ struct pending_request *req;
+
+ spin_lock_irqsave(&fi->reqlists_lock, flags);
+ req = __next_complete_req(fi);
+ spin_unlock_irqrestore(&fi->reqlists_lock, flags);
+ return req;
+}
static ssize_t raw1394_read(struct file *file, char __user * buffer,
size_t count, loff_t * offset_is_ignored)
{
- unsigned long flags;
struct file_info *fi = (struct file_info *)file->private_data;
- struct list_head *lh;
struct pending_request *req;
ssize_t ret;
@@ -487,22 +510,21 @@ static ssize_t raw1394_read(struct file *file, char __user * buffer,
}
if (file->f_flags & O_NONBLOCK) {
- if (down_trylock(&fi->complete_sem)) {
+ if (!(req = next_complete_req(fi)))
return -EAGAIN;
- }
} else {
- if (down_interruptible(&fi->complete_sem)) {
+ /*
+ * NB: We call the macro wait_event_interruptible() 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.
+ */
+ if (wait_event_interruptible(fi->wait_complete,
+ (req = next_complete_req(fi))))
return -ERESTARTSYS;
- }
}
- spin_lock_irqsave(&fi->reqlists_lock, flags);
- lh = fi->req_complete.next;
- list_del(lh);
- spin_unlock_irqrestore(&fi->reqlists_lock, flags);
-
- req = list_entry(lh, struct pending_request, list);
-
if (req->req.length) {
if (copy_to_user(int2ptr(req->req.recvb), req->data,
req->req.length)) {
@@ -2744,7 +2766,7 @@ static unsigned int raw1394_poll(struct file *file, poll_table * pt)
unsigned int mask = POLLOUT | POLLWRNORM;
unsigned long flags;
- poll_wait(file, &fi->poll_wait_complete, pt);
+ poll_wait(file, &fi->wait_complete, pt);
spin_lock_irqsave(&fi->reqlists_lock, flags);
if (!list_empty(&fi->req_complete)) {
@@ -2769,9 +2791,8 @@ static int raw1394_open(struct inode *inode, struct file *file)
fi->state = opened;
INIT_LIST_HEAD(&fi->req_pending);
INIT_LIST_HEAD(&fi->req_complete);
- sema_init(&fi->complete_sem, 0);
spin_lock_init(&fi->reqlists_lock);
- init_waitqueue_head(&fi->poll_wait_complete);
+ init_waitqueue_head(&fi->wait_complete);
INIT_LIST_HEAD(&fi->addr_list);
file->private_data = fi;
@@ -2784,7 +2805,7 @@ static int raw1394_release(struct inode *inode, struct file *file)
struct file_info *fi = file->private_data;
struct list_head *lh;
struct pending_request *req;
- int done = 0, i, fail = 0;
+ int i, fail;
int retval = 0;
struct list_head *entry;
struct arm_addr *addr = NULL;
@@ -2864,25 +2885,28 @@ static int raw1394_release(struct inode *inode, struct file *file)
"error(s) occurred \n");
}
- while (!done) {
+ for (;;) {
+ /* This locked section guarantees that neither
+ * complete nor pending requests exist once i!=0 */
spin_lock_irqsave(&fi->reqlists_lock, flags);
-
- while (!list_empty(&fi->req_complete)) {
- lh = fi->req_complete.next;
- list_del(lh);
-
- req = list_entry(lh, struct pending_request, list);
-
+ while ((req = __next_complete_req(fi)))
free_pending_request(req);
- }
-
- if (list_empty(&fi->req_pending))
- done = 1;
+ i = list_empty(&fi->req_pending);
spin_unlock_irqrestore(&fi->reqlists_lock, flags);
- if (!done)
- down_interruptible(&fi->complete_sem);
+ if (i)
+ break;
+ /*
+ * Sleep until more requests can be freed.
+ *
+ * NB: We call the macro wait_event() 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() won't evaluate the condition again after that.
+ */
+ wait_event(fi->wait_complete, (req = next_complete_req(fi)));
+ free_pending_request(req);
}
/* Remove any sub-trees left by user space programs */
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index b08755e2e68..baa063c9e6e 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -356,7 +356,7 @@ static const struct {
/*
* Converts a buffer from be32 to cpu byte ordering. Length is in bytes.
*/
-static __inline__ void sbp2util_be32_to_cpu_buffer(void *buffer, int length)
+static inline void sbp2util_be32_to_cpu_buffer(void *buffer, int length)
{
u32 *temp = buffer;
@@ -369,7 +369,7 @@ static __inline__ void sbp2util_be32_to_cpu_buffer(void *buffer, int length)
/*
* Converts a buffer from cpu to be32 byte ordering. Length is in bytes.
*/
-static __inline__ void sbp2util_cpu_to_be32_buffer(void *buffer, int length)
+static inline void sbp2util_cpu_to_be32_buffer(void *buffer, int length)
{
u32 *temp = buffer;
diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c
index c6e3f02bc6d..6b5353d81ae 100644
--- a/drivers/ieee1394/video1394.c
+++ b/drivers/ieee1394/video1394.c
@@ -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