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> ...@@ -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. What: Video4Linux API 1 ioctls and video_decoder.h from Video devices.
When: July 2006 When: July 2006
Why: V4L1 AP1 was replaced by V4L2 API. during migration from 2.4 to 2.6 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> ...@@ -1398,36 +1398,29 @@ M: Gadi Oxman <gadio@netvision.net.il>
L: linux-kernel@vger.kernel.org L: linux-kernel@vger.kernel.org
S: Maintained S: Maintained
IEEE 1394 ETHERNET (eth1394)
L: linux1394-devel@lists.sourceforge.net
W: http://www.linux1394.org/
S: Orphan
IEEE 1394 SUBSYSTEM IEEE 1394 SUBSYSTEM
P: Ben Collins P: Ben Collins
M: bcollins@debian.org M: bcollins@debian.org
P: Jody McIntyre P: Stefan Richter
M: scjody@modernduck.com M: stefanr@s5r6.in-berlin.de
L: linux1394-devel@lists.sourceforge.net L: linux1394-devel@lists.sourceforge.net
W: http://www.linux1394.org/ 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 S: Maintained
IEEE 1394 OHCI DRIVER IEEE 1394 IPV4 DRIVER (eth1394)
P: Ben Collins P: Stefan Richter
M: bcollins@debian.org M: stefanr@s5r6.in-berlin.de
P: Jody McIntyre
M: scjody@modernduck.com
L: linux1394-devel@lists.sourceforge.net L: linux1394-devel@lists.sourceforge.net
W: http://www.linux1394.org/ S: Odd Fixes
S: Maintained
IEEE 1394 PCILYNX DRIVER IEEE 1394 PCILYNX DRIVER
P: Jody McIntyre P: Jody McIntyre
M: scjody@modernduck.com M: scjody@modernduck.com
P: Stefan Richter
M: stefanr@s5r6.in-berlin.de
L: linux1394-devel@lists.sourceforge.net L: linux1394-devel@lists.sourceforge.net
W: http://www.linux1394.org/ S: Odd Fixes
S: Maintained
IEEE 1394 RAW I/O DRIVER IEEE 1394 RAW I/O DRIVER
P: Ben Collins P: Ben Collins
...@@ -1435,16 +1428,6 @@ M: bcollins@debian.org ...@@ -1435,16 +1428,6 @@ M: bcollins@debian.org
P: Dan Dennedy P: Dan Dennedy
M: dan@dennedy.org M: dan@dennedy.org
L: linux1394-devel@lists.sourceforge.net 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 S: Maintained
IMS TWINTURBO FRAMEBUFFER DRIVER IMS TWINTURBO FRAMEBUFFER DRIVER
......
...@@ -120,12 +120,19 @@ config IEEE1394_VIDEO1394 ...@@ -120,12 +120,19 @@ config IEEE1394_VIDEO1394
this option only if you have an IEEE 1394 video device connected to this option only if you have an IEEE 1394 video device connected to
an OHCI-1394 card. an OHCI-1394 card.
comment "SBP-2 support (for storage devices) requires SCSI"
depends on IEEE1394 && SCSI=n
config IEEE1394_SBP2 config IEEE1394_SBP2
tristate "SBP-2 support (Harddisks etc.)" tristate "SBP-2 support (Harddisks etc.)"
depends on IEEE1394 && SCSI && (PCI || BROKEN) depends on IEEE1394 && SCSI && (PCI || BROKEN)
help help
This option enables you to use SBP-2 devices connected to your IEEE This option enables you to use SBP-2 devices connected to an IEEE
1394 bus. SBP-2 devices include harddrives and DVD devices. 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 config IEEE1394_SBP2_PHYS_DMA
bool "Enable replacement for physical DMA in SBP2" bool "Enable replacement for physical DMA in SBP2"
......
...@@ -17,11 +17,13 @@ ...@@ -17,11 +17,13 @@
* *
*/ */
#include <linux/string.h> #include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/param.h> #include <linux/param.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/string.h>
#include "csr1212.h" #include "csr1212.h"
#include "ieee1394_types.h" #include "ieee1394_types.h"
...@@ -149,31 +151,18 @@ static void host_reset(struct hpsb_host *host) ...@@ -149,31 +151,18 @@ static void host_reset(struct hpsb_host *host)
/* /*
* HI == seconds (bits 0:2) * HI == seconds (bits 0:2)
* LO == fraction units of 1/8000 of a second, as per 1394 (bits 19:31) * LO == fractions of a second in units of 125usec (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).
* *
* NOTE: The spec says 1/8000, but also says we can compute based on 1/8192 * Convert SPLIT_TIMEOUT to jiffies.
* like CSR specifies. Should make our math less complex. * 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) static inline void calculate_expire(struct csr_control *csr)
{ {
unsigned long units; unsigned long usecs =
(csr->split_timeout_hi & 0x07) * USEC_PER_SEC +
/* Take the seconds, and convert to units */ (csr->split_timeout_lo >> 19) * 125L;
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;
/* Just to keep from rounding low */ csr->expire = usecs_to_jiffies(usecs > 100000L ? usecs : 100000L);
csr->expire++;
HPSB_VERBOSE("CSR: setting expire to %lu, HZ=%u", csr->expire, HZ); HPSB_VERBOSE("CSR: setting expire to %lu, HZ=%u", csr->expire, HZ);
} }
......
#ifndef _IEEE1394_CSR_H #ifndef _IEEE1394_CSR_H
#define _IEEE1394_CSR_H #define _IEEE1394_CSR_H
#ifdef CONFIG_PREEMPT #include <linux/spinlock_types.h>
#include <linux/sched.h>
#endif
#include "csr1212.h" #include "csr1212.h"
#include "ieee1394_types.h"
#define CSR_REGISTER_BASE 0xfffff0000000ULL #define CSR_REGISTER_BASE 0xfffff0000000ULL
...@@ -39,7 +37,7 @@ ...@@ -39,7 +37,7 @@
/* IEEE 1394 bus specific Configuration ROM Key IDs */ /* IEEE 1394 bus specific Configuration ROM Key IDs */
#define IEEE1394_KV_ID_POWER_REQUIREMENTS (0x30) #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_BUS_INFO_SIZE (5 * sizeof(quadlet_t))
#define CSR_IRMC_SHIFT 31 #define CSR_IRMC_SHIFT 31
...@@ -64,7 +62,7 @@ struct csr_control { ...@@ -64,7 +62,7 @@ struct csr_control {
quadlet_t state; quadlet_t state;
quadlet_t node_ids; quadlet_t node_ids;
quadlet_t split_timeout_hi, split_timeout_lo; quadlet_t split_timeout_hi, split_timeout_lo;
unsigned long expire; // Calculated from split_timeout unsigned long expire; /* Calculated from split_timeout */
quadlet_t cycle_time; quadlet_t cycle_time;
quadlet_t bus_time; quadlet_t bus_time;
quadlet_t bus_manager_id; quadlet_t bus_manager_id;
...@@ -93,4 +91,9 @@ extern struct csr1212_bus_ops csr_bus_ops; ...@@ -93,4 +91,9 @@ extern struct csr1212_bus_ops csr_bus_ops;
int init_csr(void); int init_csr(void);
void cleanup_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 */ #endif /* _IEEE1394_CSR_H */
...@@ -7,10 +7,13 @@ ...@@ -7,10 +7,13 @@
* directory of the kernel sources for details. * directory of the kernel sources for details.
*/ */
#include <linux/mm.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/vmalloc.h> #include <linux/pci.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/mm.h> #include <linux/vmalloc.h>
#include <asm/scatterlist.h>
#include "dma.h" #include "dma.h"
/* dma_prog_region */ /* dma_prog_region */
......
...@@ -10,69 +10,91 @@ ...@@ -10,69 +10,91 @@
#ifndef IEEE1394_DMA_H #ifndef IEEE1394_DMA_H
#define IEEE1394_DMA_H #define IEEE1394_DMA_H
#include <linux/pci.h> #include <asm/types.h>
#include <asm/scatterlist.h>
struct pci_dev;
/* struct dma_prog_region struct scatterlist;
struct vm_area_struct;
a small, physically-contiguous DMA buffer with random-access,
synchronous usage characteristics /**
*/ * 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 { struct dma_prog_region {
unsigned char *kvirt; /* kernel virtual address */ unsigned char *kvirt;
struct pci_dev *dev; /* PCI device */ struct pci_dev *dev;
unsigned int n_pages; /* # of kernel pages */ unsigned int n_pages;
dma_addr_t bus_addr; /* base bus address */ dma_addr_t bus_addr;
}; };
/* clear out all fields but do not allocate any memory */ /* clear out all fields but do not allocate any memory */
void dma_prog_region_init(struct dma_prog_region *prog); 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); 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; return prog->bus_addr + offset;
} }
/* struct dma_region /**
* struct dma_region - large non-contiguous DMA buffer
a large, non-physically-contiguous DMA buffer with streaming, * @virt: kernel virtual address
asynchronous usage characteristics * @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 { struct dma_region {
unsigned char *kvirt; /* kernel virtual address */ unsigned char *kvirt;
struct pci_dev *dev; /* PCI device */ struct pci_dev *dev;
unsigned int n_pages; /* # of kernel pages */ unsigned int n_pages;
unsigned int n_dma_pages; /* # of IOMMU pages */ unsigned int n_dma_pages;
struct scatterlist *sglist; /* IOMMU mapping */ struct scatterlist *sglist;
int direction; /* PCI_DMA_TODEVICE, etc */ int direction;
}; };
/* clear out all fields but do not allocate anything */ /* clear out all fields but do not allocate anything */
void dma_region_init(struct dma_region *dma); void dma_region_init(struct dma_region *dma);
/* allocate the buffer and map it to the IOMMU */ /* 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 */ /* unmap and free the buffer */
void dma_region_free(struct dma_region *dma); void dma_region_free(struct dma_region *dma);
/* sync the CPU's view of the buffer */ /* 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 */ /* 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 */ /* 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) */ /* 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 /* return the DMA bus address of the byte with the given offset
relative to the beginning of the dma_region */ * relative to the beginning of the dma_region */
dma_addr_t dma_region_offset_to_bus(struct dma_region *dma, unsigned long offset); dma_addr_t dma_region_offset_to_bus(struct dma_region *dma,
unsigned long offset);
#endif /* IEEE1394_DMA_H */ #endif /* IEEE1394_DMA_H */
...@@ -460,7 +460,7 @@ struct video_card { ...@@ -460,7 +460,7 @@ struct video_card {
int dma_running; 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 to serialize various operations on the video_card. Even though only one
open() is allowed, we still need to prevent multiple threads of execution open() is allowed, we still need to prevent multiple threads of execution
from entering calls like read, write, ioctl, etc. from entering calls like read, write, ioctl, etc.
...@@ -468,9 +468,9 @@ struct video_card { ...@@ -468,9 +468,9 @@ struct video_card {
I honestly can't think of a good reason to use dv1394 from several threads 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 =). 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... */ /* people waiting for buffer space, please form a line here... */
wait_queue_head_t waitq; wait_queue_head_t waitq;
......
...@@ -95,6 +95,7 @@ ...@@ -95,6 +95,7 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/poll.h> #include <linux/poll.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/mutex.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include <asm/atomic.h> #include <asm/atomic.h>
...@@ -110,15 +111,15 @@ ...@@ -110,15 +111,15 @@
#include <linux/compat.h> #include <linux/compat.h>
#include <linux/cdev.h> #include <linux/cdev.h>
#include "dv1394.h"
#include "dv1394-private.h"
#include "highlevel.h"
#include "hosts.h"
#include "ieee1394.h" #include "ieee1394.h"
#include "ieee1394_core.h"
#include "ieee1394_hotplug.h"
#include "ieee1394_types.h" #include "ieee1394_types.h"
#include "nodemgr.h" #include "nodemgr.h"
#include "hosts.h"
#include "ieee1394_core.h"
#include "highlevel.h"
#include "dv1394.h"
#include "dv1394-private.h"
#include "ohci1394.h" #include "ohci1394.h"
/* DEBUG LEVELS: /* DEBUG LEVELS:
...@@ -136,13 +137,13 @@ ...@@ -136,13 +137,13 @@
#if DV1394_DEBUG_LEVEL >= 2 #if DV1394_DEBUG_LEVEL >= 2
#define irq_printk( args... ) printk( args ) #define irq_printk( args... ) printk( args )
#else #else
#define irq_printk( args... ) #define irq_printk( args... ) do {} while (0)
#endif #endif
#if DV1394_DEBUG_LEVEL >= 1 #if DV1394_DEBUG_LEVEL >= 1
#define debug_printk( args... ) printk( args) #define debug_printk( args... ) printk( args)
#else #else
#define debug_printk( args... ) #define debug_printk( args... ) do {} while (0)
#endif #endif
/* issue a dummy PCI read to force the preceding write /* issue a dummy PCI read to force the preceding write
...@@ -247,7 +248,7 @@ static void frame_delete(struct frame *f) ...@@ -247,7 +248,7 @@ static void frame_delete(struct frame *f)
Frame_prepare() must be called OUTSIDE the video->spinlock. Frame_prepare() must be called OUTSIDE the video->spinlock.
However, frame_prepare() must still be serialized, so 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) 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) ...@@ -1271,7 +1272,7 @@ static int dv1394_mmap(struct file *file, struct vm_area_struct *vma)
int retval = -EINVAL; int retval = -EINVAL;
/* serialize mmap */ /* serialize mmap */
down(&video->sem); mutex_lock(&video->mtx);
if ( ! video_card_initialized(video) ) { if ( ! video_card_initialized(video) ) {
retval = do_dv1394_init_default(video); retval = do_dv1394_init_default(video);
...@@ -1281,7 +1282,7 @@ static int dv1394_mmap(struct file *file, struct vm_area_struct *vma) ...@@ -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); retval = dma_region_mmap(&video->dv_buf, file, vma);
out: out:
up(&video->sem); mutex_unlock(&video->mtx);
return retval; return retval;
} }
...@@ -1337,17 +1338,17 @@ static ssize_t dv1394_write(struct file *file, const char __user *buffer, size_t ...@@ -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 */ /* serialize this to prevent multi-threaded mayhem */
if (file->f_flags & O_NONBLOCK) { if (file->f_flags & O_NONBLOCK) {
if (down_trylock(&video->sem)) if (!mutex_trylock(&video->mtx))
return -EAGAIN; return -EAGAIN;
} else { } else {
if (down_interruptible(&video->sem)) if (mutex_lock_interruptible(&video->mtx))
return -ERESTARTSYS; return -ERESTARTSYS;
} }
if ( !video_card_initialized(video) ) { if ( !video_card_initialized(video) ) {
ret = do_dv1394_init_default(video); ret = do_dv1394_init_default(video);
if (ret) { if (ret) {
up(&video->sem); mutex_unlock(&video->mtx);
return ret; return ret;
} }
} }
...@@ -1418,7 +1419,7 @@ static ssize_t dv1394_write(struct file *file, const char __user *buffer, size_t ...@@ -1418,7 +1419,7 @@ static ssize_t dv1394_write(struct file *file, const char __user *buffer, size_t
remove_wait_queue(&video->waitq, &wait); remove_wait_queue(&video->waitq, &wait);
set_current_state(TASK_RUNNING); set_current_state(TASK_RUNNING);
up(&video->sem); mutex_unlock(&video->mtx);
return ret; return ret;
} }
...@@ -1434,17 +1435,17 @@ static ssize_t dv1394_read(struct file *file, char __user *buffer, size_t count ...@@ -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 */ /* serialize this to prevent multi-threaded mayhem */
if (file->f_flags & O_NONBLOCK) { if (file->f_flags & O_NONBLOCK) {
if (down_trylock(&video->sem)) if (!mutex_trylock(&video->mtx))
return -EAGAIN; return -EAGAIN;
} else { } else {
if (down_interruptible(&video->sem)) if (mutex_lock_interruptible(&video->mtx))
return -ERESTARTSYS; return -ERESTARTSYS;
} }
if ( !video_card_initialized(video) ) { if ( !video_card_initialized(video) ) {
ret = do_dv1394_init_default(video); ret = do_dv1394_init_default(video);
if (ret) { if (ret) {
up(&video->sem); mutex_unlock(&video->mtx);
return ret; return ret;
} }
video->continuity_counter = -1; video->continuity_counter = -1;
...@@ -1526,7 +1527,7 @@ static ssize_t dv1394_read(struct file *file, char __user *buffer, size_t count ...@@ -1526,7 +1527,7 @@ static ssize_t dv1394_read(struct file *file, char __user *buffer, size_t count
remove_wait_queue(&video->waitq, &wait); remove_wait_queue(&video->waitq, &wait);
set_current_state(TASK_RUNNING); set_current_state(TASK_RUNNING);
up(&video->sem); mutex_unlock(&video->mtx);
return ret; return ret;
} }
...@@ -1547,12 +1548,12 @@ static long dv1394_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ...@@ -1547,12 +1548,12 @@ static long dv1394_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
/* serialize this to prevent multi-threaded mayhem */ /* serialize this to prevent multi-threaded mayhem */
if (file->f_flags & O_NONBLOCK) { if (file->f_flags & O_NONBLOCK) {
if (down_trylock(&video->sem)) { if (!mutex_trylock(&video->mtx)) {
unlock_kernel(); unlock_kernel();
return -EAGAIN; return -EAGAIN;
} }
} else { } else {
if (down_interruptible(&video->sem)) { if (mutex_lock_interruptible(&video->mtx)) {
unlock_kernel(); unlock_kernel();
return -ERESTARTSYS; return -ERESTARTSYS;
} }
...@@ -1778,7 +1779,7 @@ static long dv1394_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ...@@ -1778,7 +1779,7 @@ static long dv1394_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
} }
out: out:
up(&video->sem); mutex_unlock(&video->mtx);
unlock_kernel(); unlock_kernel();
return ret; return ret;
} }
...@@ -2253,7 +2254,7 @@ static int dv1394_init(struct ti_ohci *ohci, enum pal_or_ntsc format, enum modes ...@@ -2253,7 +2254,7 @@ static int dv1394_init(struct ti_ohci *ohci, enum pal_or_ntsc format, enum modes
clear_bit(0, &video->open); clear_bit(0, &video->open);
spin_lock_init(&video->spinlock); spin_lock_init(&video->spinlock);
video->dma_running = 0; video->dma_running = 0;
init_MUTEX(&video->sem); mutex_init(&video->mtx);
init_waitqueue_head(&video->waitq); init_waitqueue_head(&video->waitq);
video->fasync = NULL; video->fasync = NULL;
......
...@@ -64,19 +64,19 @@ ...@@ -64,19 +64,19 @@
#include <linux/ethtool.h> #include <linux/ethtool.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/delay.h> #include <asm/delay.h>
#include <asm/semaphore.h>
#include <net/arp.h> #include <net/arp.h>
#include "config_roms.h"
#include "csr1212.h" #include "csr1212.h"
#include "ieee1394_types.h" #include "eth1394.h"
#include "highlevel.h"
#include "ieee1394.h"
#include "ieee1394_core.h" #include "ieee1394_core.h"
#include "ieee1394_hotplug.h"
#include "ieee1394_transactions.h" #include "ieee1394_transactions.h"
#include "ieee1394.h" #include "ieee1394_types.h"
#include "highlevel.h"
#include "iso.h" #include "iso.h"
#include "nodemgr.h" #include "nodemgr.h"
#include "eth1394.h"
#include "config_roms.h"
#define ETH1394_PRINT_G(level, fmt, args...) \ #define ETH1394_PRINT_G(level, fmt, args...) \
printk(level "%s: " fmt, driver_name, ## 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) ...@@ -90,6 +90,16 @@ static int alloc_hostnum_cb(struct hpsb_host *host, void *__data)
return 0; 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. * hpsb_alloc_host - allocate a new host controller.
* @drv: the driver that will manage the 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) ...@@ -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 * Return Value: a pointer to the &hpsb_host if successful, %NULL if
* no memory was available. * 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 hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
struct device *dev) struct device *dev)
{ {
...@@ -143,9 +143,6 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra, ...@@ -143,9 +143,6 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
for (i = 2; i < 16; i++) for (i = 2; i < 16; i++)
h->csr.gen_timestamp[i] = jiffies - 60 * HZ; 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); atomic_set(&h->generation, 0);
INIT_WORK(&h->delayed_reset, delayed_reset_bus, h); INIT_WORK(&h->delayed_reset, delayed_reset_bus, h);
......
...@@ -2,17 +2,19 @@ ...@@ -2,17 +2,19 @@
#define _IEEE1394_HOSTS_H #define _IEEE1394_HOSTS_H
#include <linux/device.h> #include <linux/device.h>
#include <linux/wait.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/timer.h>
#include <linux/skbuff.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 "ieee1394_types.h"
#include "csr.h" #include "csr.h"
struct hpsb_packet; struct hpsb_packet;
struct hpsb_iso; struct hpsb_iso;
...@@ -33,7 +35,6 @@ struct hpsb_host { ...@@ -33,7 +35,6 @@ struct hpsb_host {
int node_count; /* number of identified nodes on this bus */ int node_count; /* number of identified nodes on this bus */
int selfid_count; /* total number of SelfIDs received */ int selfid_count; /* total number of SelfIDs received */
int nodes_active; /* number of nodes with active link layer */ 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 node_id; /* node ID of this host */
nodeid_t irm_id; /* ID of this bus' isochronous resource manager */ nodeid_t irm_id; /* ID of this bus' isochronous resource manager */
...@@ -53,31 +54,29 @@ struct hpsb_host { ...@@ -53,31 +54,29 @@ struct hpsb_host {
int reset_retries; int reset_retries;
quadlet_t *topology_map; quadlet_t *topology_map;
u8 *speed_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 hpsb_host_driver *driver;
struct pci_dev *pdev; struct pci_dev *pdev;
int id;
struct device device; struct device device;
struct class_device class_dev; struct class_device class_dev;
int update_config_rom; int update_config_rom;
struct work_struct delayed_reset; struct work_struct delayed_reset;
unsigned int config_roms; unsigned int config_roms;
struct list_head addr_space; struct list_head addr_space;
u64 low_addr_space; /* upper bound of physical DMA area */ u64 low_addr_space; /* upper bound of physical DMA area */
u64 middle_addr_space; /* upper bound of posted write 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 { enum devctl_cmd {
/* Host is requested to reset its bus and cancel all outstanding async /* Host is requested to reset its bus and cancel all outstanding async
...@@ -112,7 +111,7 @@ enum devctl_cmd { ...@@ -112,7 +111,7 @@ enum devctl_cmd {
enum isoctl_cmd { enum isoctl_cmd {
/* rawiso API - see iso.h for the meanings of these commands /* rawiso API - see iso.h for the meanings of these commands
(they correspond exactly to the hpsb_iso_* API functions) * (they correspond exactly to the hpsb_iso_* API functions)
* INIT = allocate resources * INIT = allocate resources
* START = begin transmission/reception * START = begin transmission/reception
* STOP = halt transmission/reception * STOP = halt transmission/reception
...@@ -160,7 +159,8 @@ struct hpsb_host_driver { ...@@ -160,7 +159,8 @@ struct hpsb_host_driver {
/* The hardware driver may optionally support a function that is used /* The hardware driver may optionally support a function that is used
* to set the hardware ConfigROM if the hardware supports handling * to set the hardware ConfigROM if the hardware supports handling
* reads to the ConfigROM on its own. */ * 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 /* This function shall implement packet transmission based on
* packet->type. It shall CRC both parts of the packet (unless * packet->type. It shall CRC both parts of the packet (unless
...@@ -170,20 +170,21 @@ struct hpsb_host_driver { ...@@ -170,20 +170,21 @@ struct hpsb_host_driver {
* called. Return 0 on success, negative errno on failure. * called. Return 0 on success, negative errno on failure.
* NOTE: The function must be callable in interrupt context. * NOTE: The function must be callable in interrupt context.
*/ */
int (*transmit_packet) (struct hpsb_host *host, int (*transmit_packet)(struct hpsb_host *host,
struct hpsb_packet *packet); struct hpsb_packet *packet);
/* This function requests miscellanous services from the driver, see /* This function requests miscellanous services from the driver, see
* above for command codes and expected actions. Return -1 for unknown * above for command codes and expected actions. Return -1 for unknown
* command, though that should never happen. * 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 /* ISO transmission/reception functions. Return 0 on success, -1
* (or -EXXX errno code) on failure. If the low-level driver does not * (or -EXXX errno code) on failure. If the low-level driver does not
* support the new ISO API, set isoctl to NULL. * 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 /* This function is mainly to redirect local CSR reads/locks to the iso
* management registers (bus manager id, bandwidth available, channels * management registers (bus manager id, bandwidth available, channels
...@@ -196,19 +197,11 @@ struct hpsb_host_driver { ...@@ -196,19 +197,11 @@ struct hpsb_host_driver {
quadlet_t data, quadlet_t compare); quadlet_t data, quadlet_t compare);
}; };
struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra, struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
struct device *dev); struct device *dev);
int hpsb_add_host(struct hpsb_host *host); int hpsb_add_host(struct hpsb_host *host);
void hpsb_remove_host(struct hpsb_host *h); 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 /* 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 * current version, otherwise it will fail with return value -1. If this
* host does not support config-rom-update, it will return -EINVAL. * 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 #ifndef __IEEE1394_IOCTL_H
#define __IEEE1394_IOCTL_H #define __IEEE1394_IOCTL_H
...@@ -99,5 +101,4 @@ ...@@ -99,5 +101,4 @@
#define RAW1394_IOC_ISO_RECV_FLUSH \ #define RAW1394_IOC_ISO_RECV_FLUSH \
_IO ('#', 0x29) _IO ('#', 0x29)
#endif /* __IEEE1394_IOCTL_H */ #endif /* __IEEE1394_IOCTL_H */
...@@ -48,20 +48,19 @@ ...@@ -48,20 +48,19 @@
#define ACKX_ABORTED (-3) #define ACKX_ABORTED (-3)
#define ACKX_TIMEOUT (-4) #define ACKX_TIMEOUT (-4)
#define IEEE1394_SPEED_100 0x00 #define IEEE1394_SPEED_100 0x00
#define IEEE1394_SPEED_200 0x01 #define IEEE1394_SPEED_200 0x01
#define IEEE1394_SPEED_400 0x02 #define IEEE1394_SPEED_400 0x02
#define IEEE1394_SPEED_800 0x03 #define IEEE1394_SPEED_800 0x03
#define IEEE1394_SPEED_1600 0x04 #define IEEE1394_SPEED_1600 0x04
#define IEEE1394_SPEED_3200 0x05 #define IEEE1394_SPEED_3200 0x05
/* The current highest tested speed supported by the subsystem */ /* 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 */ /* Maps speed values above to a string representation */
extern const char *hpsb_speedto_str[]; extern const char *hpsb_speedto_str[];
/* 1394a cable PHY packets */ /* 1394a cable PHY packets */
#define SELFID_PWRCL_NO_POWER 0x0 #define SELFID_PWRCL_NO_POWER 0x0
#define SELFID_PWRCL_PROVIDE_15W 0x1 #define SELFID_PWRCL_PROVIDE_15W 0x1
...@@ -77,6 +76,8 @@ extern const char *hpsb_speedto_str[]; ...@@ -77,6 +76,8 @@ extern const char *hpsb_speedto_str[];
#define SELFID_PORT_NCONN 0x1 #define SELFID_PORT_NCONN 0x1
#define SELFID_PORT_NONE 0x0 #define SELFID_PORT_NONE 0x0
#define SELFID_SPEED_UNKNOWN 0x3 /* 1394b PHY */
#define PHYPACKET_LINKON 0x40000000 #define PHYPACKET_LINKON 0x40000000
#define PHYPACKET_PHYCONFIG_R 0x00800000 #define PHYPACKET_PHYCONFIG_R 0x00800000
#define PHYPACKET_PHYCONFIG_T 0x00400000 #define PHYPACKET_PHYCONFIG_T 0x00400000
...@@ -215,5 +216,4 @@ struct ext_selfid { ...@@ -215,5 +216,4 @@ struct ext_selfid {
#error What? PDP endian? #error What? PDP endian?
#endif /* __BIG_ENDIAN_BITFIELD */ #endif /* __BIG_ENDIAN_BITFIELD */
#endif /* _IEEE1394_IEEE1394_H */ #endif /* _IEEE1394_IEEE1394_H */
...@@ -35,7 +35,6 @@ ...@@ -35,7 +35,6 @@
#include <linux/kthread.h> #include <linux/kthread.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include <asm/semaphore.h>
#include "ieee1394_types.h" #include "ieee1394_types.h"
#include "ieee1394.h" #include "ieee1394.h"
...@@ -86,7 +85,7 @@ static void dump_packet(const char *text, quadlet_t *data, int size, int speed) ...@@ -86,7 +85,7 @@ static void dump_packet(const char *text, quadlet_t *data, int size, int speed)
printk("\n"); printk("\n");
} }
#else #else
#define dump_packet(a,b,c,d) #define dump_packet(a,b,c,d) do {} while (0)
#endif #endif
static void abort_requests(struct hpsb_host *host); static void abort_requests(struct hpsb_host *host);
...@@ -355,10 +354,12 @@ static void build_speed_map(struct hpsb_host *host, int nodecount) ...@@ -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 */ /* assume maximum speed for 1394b PHYs, nodemgr will correct it */
for (n = 0; n < nodecount; n++) for (n = 0; n < nodecount; n++)
if (speedcap[n] == 3) if (speedcap[n] == SELFID_SPEED_UNKNOWN)
speedcap[n] = IEEE1394_SPEED_MAX; speedcap[n] = IEEE1394_SPEED_MAX;
#endif
} }
...@@ -1169,7 +1170,7 @@ static void __exit ieee1394_cleanup(void) ...@@ -1169,7 +1170,7 @@ static void __exit ieee1394_cleanup(void)
unregister_chrdev_region(IEEE1394_CORE_DEV, 256); unregister_chrdev_region(IEEE1394_CORE_DEV, 256);
} }
module_init(ieee1394_init); fs_initcall(ieee1394_init); /* same as ohci1394 */
module_exit(ieee1394_cleanup); module_exit(ieee1394_cleanup);
/* Exported symbols */ /* Exported symbols */
......
#ifndef _IEEE1394_CORE_H #ifndef _IEEE1394_CORE_H
#define _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/atomic.h>
#include <asm/semaphore.h>
#include "hosts.h"
#include "hosts.h"
#include "ieee1394_types.h"
struct hpsb_packet { struct hpsb_packet {
/* This struct is basically read-only for hosts with the exception of /* This struct is basically read-only for hosts with the exception of
...@@ -58,7 +61,6 @@ struct hpsb_packet { ...@@ -58,7 +61,6 @@ struct hpsb_packet {
size_t header_size; size_t header_size;
size_t data_size; size_t data_size;
struct hpsb_host *host; struct hpsb_host *host;
unsigned int generation; unsigned int generation;
...@@ -92,7 +94,6 @@ void abort_timedouts(unsigned long __opaque); ...@@ -92,7 +94,6 @@ void abort_timedouts(unsigned long __opaque);
struct hpsb_packet *hpsb_alloc_packet(size_t data_size); struct hpsb_packet *hpsb_alloc_packet(size_t data_size);
void hpsb_free_packet(struct hpsb_packet *packet); void hpsb_free_packet(struct hpsb_packet *packet);
/* /*
* Generation counter for the complete 1394 subsystem. Generation gets * Generation counter for the complete 1394 subsystem. Generation gets
* incremented on every change in the subsystem (e.g. bus reset). * 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, ...@@ -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_MINOR_BLOCK_EXPERIMENTAL 15
#define IEEE1394_CORE_DEV MKDEV(IEEE1394_MAJOR, 0) #define IEEE1394_CORE_DEV MKDEV(IEEE1394_MAJOR, 0)
#define IEEE1394_RAW1394_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16) #define IEEE1394_RAW1394_DEV MKDEV(IEEE1394_MAJOR, \
#define IEEE1394_VIDEO1394_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_VIDEO1394 * 16) IEEE1394_MINOR_BLOCK_RAW1394 * 16)
#define IEEE1394_DV1394_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16) #define IEEE1394_VIDEO1394_DEV MKDEV(IEEE1394_MAJOR, \
#define IEEE1394_EXPERIMENTAL_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_EXPERIMENTAL * 16) 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 */ /* return the index (within a minor number block) of a file */
static inline unsigned char ieee1394_file_to_instance(struct file *file) static inline unsigned char ieee1394_file_to_instance(struct file *file)
...@@ -223,4 +228,3 @@ extern struct class hpsb_host_class; ...@@ -223,4 +228,3 @@ extern struct class hpsb_host_class;
extern struct class *hpsb_protocol_class; extern struct class *hpsb_protocol_class;
#endif /* _IEEE1394_CORE_H */ #endif /* _IEEE1394_CORE_H */
#ifndef _IEEE1394_HOTPLUG_H #ifndef _IEEE1394_HOTPLUG_H
#define _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 */ /* Unit spec id and sw version entry for some protocols */
#define AVC_UNIT_SPEC_ID_ENTRY 0x0000A02D #define AVC_UNIT_SPEC_ID_ENTRY 0x0000A02D
#define AVC_SW_VERSION_ENTRY 0x00010001 #define AVC_SW_VERSION_ENTRY 0x00010001
#define CAMERA_UNIT_SPEC_ID_ENTRY 0x0000A02D #define CAMERA_UNIT_SPEC_ID_ENTRY 0x0000A02D
#define CAMERA_SW_VERSION_ENTRY 0x00000100 #define CAMERA_SW_VERSION_ENTRY 0x00000100
/* Check to make sure this all isn't already defined */ /* /include/linux/mod_devicetable.h defines:
#ifndef IEEE1394_MATCH_VENDOR_ID * IEEE1394_MATCH_VENDOR_ID
* IEEE1394_MATCH_MODEL_ID
#define IEEE1394_MATCH_VENDOR_ID 0x0001 * IEEE1394_MATCH_SPECIFIER_ID
#define IEEE1394_MATCH_MODEL_ID 0x0002 * IEEE1394_MATCH_VERSION
#define IEEE1394_MATCH_SPECIFIER_ID 0x0004 * struct ieee1394_device_id
#define IEEE1394_MATCH_VERSION 0x0008 */
#include <linux/mod_devicetable.h>
struct ieee1394_device_id {
u32 match_flags;
u32 vendor_id;
u32 model_id;
u32 specifier_id;
u32 version;
void *driver_data;
};
#endif
#endif /* _IEEE1394_HOTPLUG_H */ #endif /* _IEEE1394_HOTPLUG_H */
...@@ -9,19 +9,17 @@ ...@@ -9,19 +9,17 @@
* directory of the kernel sources for details. * directory of the kernel sources for details.
*/ */
#include <linux/sched.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/smp_lock.h> #include <linux/spinlock.h>
#include <linux/interrupt.h> #include <linux/wait.h>
#include <asm/bug.h>
#include <asm/errno.h> #include <asm/errno.h>
#include "ieee1394.h" #include "ieee1394.h"
#include "ieee1394_types.h" #include "ieee1394_types.h"
#include "hosts.h" #include "hosts.h"
#include "ieee1394_core.h" #include "ieee1394_core.h"
#include "highlevel.h"
#include "nodemgr.h"
#include "ieee1394_transactions.h" #include "ieee1394_transactions.h"
#define PREP_ASYNC_HEAD_ADDRESS(tc) \ #define PREP_ASYNC_HEAD_ADDRESS(tc) \
...@@ -31,6 +29,13 @@ ...@@ -31,6 +29,13 @@
packet->header[1] = (packet->host->node_id << 16) | (addr >> 32); \ packet->header[1] = (packet->host->node_id << 16) | (addr >> 32); \
packet->header[2] = addr & 0xffffffff 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) static void fill_async_readquad(struct hpsb_packet *packet, u64 addr)
{ {
PREP_ASYNC_HEAD_ADDRESS(TCODE_READQ); PREP_ASYNC_HEAD_ADDRESS(TCODE_READQ);
...@@ -114,9 +119,41 @@ static void fill_async_stream_packet(struct hpsb_packet *packet, int length, ...@@ -114,9 +119,41 @@ static void fill_async_stream_packet(struct hpsb_packet *packet, int length,
packet->tcode = TCODE_ISO_DATA; 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 * 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 * Every asynchronous transaction on the 1394 bus needs a transaction
* label to match the response to the request. This label has to be * 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, ...@@ -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 * Return value: Zero on success, otherwise non-zero. A non-zero return
* generally means there are no available tlabels. If this is called out * 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 * 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) int hpsb_get_tlabel(struct hpsb_packet *packet)
{ {
unsigned long flags; if (irqs_disabled() || in_atomic())
struct hpsb_tlabel_pool *tp; return hpsb_get_tlabel_atomic(packet);
int n = NODEID_TO_NODE(packet->node_id);
/* NB: The macro wait_event_interruptible() is called with a condition
if (unlikely(n == ALL_NODES)) * argument with side effect. This is only possible because the side
return 0; * effect does not occur until the condition became true, and
tp = &packet->host->tpool[n]; * wait_event_interruptible() won't evaluate the condition again after
* that. */
if (irqs_disabled() || in_atomic()) { return wait_event_interruptible(tlabel_wq,
if (down_trylock(&tp->count)) !hpsb_get_tlabel_atomic(packet));
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;
} }
/** /**
* hpsb_free_tlabel - free an allocated transaction label * 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 * Frees the transaction label allocated with hpsb_get_tlabel(). The
* tlabel has to be freed after the transaction is complete (i.e. response * 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) ...@@ -176,21 +196,20 @@ int hpsb_get_tlabel(struct hpsb_packet *packet)
*/ */
void hpsb_free_tlabel(struct hpsb_packet *packet) void hpsb_free_tlabel(struct hpsb_packet *packet)
{ {
unsigned long flags; unsigned long flags, *tp;
struct hpsb_tlabel_pool *tp; int tlabel, n = NODEID_TO_NODE(packet->node_id);
int n = NODEID_TO_NODE(packet->node_id);
if (unlikely(n == ALL_NODES)) if (unlikely(n == ALL_NODES))
return; 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); wake_up_interruptible(&tlabel_wq);
BUG_ON(!test_and_clear_bit(packet->tlabel, tp->pool));
spin_unlock_irqrestore(&tp->lock, flags);
up(&tp->count);
} }
int hpsb_packet_success(struct hpsb_packet *packet) int hpsb_packet_success(struct hpsb_packet *packet)
...@@ -214,7 +233,7 @@ int hpsb_packet_success(struct hpsb_packet *packet) ...@@ -214,7 +233,7 @@ int hpsb_packet_success(struct hpsb_packet *packet)
packet->node_id); packet->node_id);
return -EAGAIN; return -EAGAIN;
} }
HPSB_PANIC("reached unreachable code 1 in %s", __FUNCTION__); BUG();
case ACK_BUSY_X: case ACK_BUSY_X:
case ACK_BUSY_A: case ACK_BUSY_A:
...@@ -261,8 +280,7 @@ int hpsb_packet_success(struct hpsb_packet *packet) ...@@ -261,8 +280,7 @@ int hpsb_packet_success(struct hpsb_packet *packet)
packet->ack_code, packet->node_id, packet->tcode); packet->ack_code, packet->node_id, packet->tcode);
return -EAGAIN; return -EAGAIN;
} }
BUG();
HPSB_PANIC("reached unreachable code 2 in %s", __FUNCTION__);
} }
struct hpsb_packet *hpsb_make_readpacket(struct hpsb_host *host, nodeid_t node, struct hpsb_packet *hpsb_make_readpacket(struct hpsb_host *host, nodeid_t node,
......
#ifndef _IEEE1394_TRANSACTIONS_H #ifndef _IEEE1394_TRANSACTIONS_H
#define _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); int hpsb_get_tlabel(struct hpsb_packet *packet);
void hpsb_free_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, struct hpsb_packet *hpsb_make_readpacket(struct hpsb_host *host, nodeid_t node,
u64 addr, size_t length); u64 addr, size_t length);
struct hpsb_packet *hpsb_make_lockpacket(struct hpsb_host *host, nodeid_t node, 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); quadlet_t arg);
struct hpsb_packet *hpsb_make_lock64packet(struct hpsb_host *host, nodeid_t node, struct hpsb_packet *hpsb_make_lock64packet(struct hpsb_host *host,
u64 addr, int extcode, octlet_t *data, nodeid_t node, u64 addr, int extcode,
octlet_t arg); octlet_t *data, octlet_t arg);
struct hpsb_packet *hpsb_make_phypacket(struct hpsb_host *host, struct hpsb_packet *hpsb_make_phypacket(struct hpsb_host *host, quadlet_t data);
quadlet_t data) ; struct hpsb_packet *hpsb_make_isopacket(struct hpsb_host *host, int length,
struct hpsb_packet *hpsb_make_isopacket(struct hpsb_host *host, int channel, int tag, int sync);
int length, int channel, struct hpsb_packet *hpsb_make_writepacket(struct hpsb_host *host,
int tag, int sync); nodeid_t node, u64 addr,
struct hpsb_packet *hpsb_make_writepacket (struct hpsb_host *host, nodeid_t node, quadlet_t *buffer, size_t length);
u64 addr, quadlet_t *buffer, size_t length);
struct hpsb_packet *hpsb_make_streampacket(struct hpsb_host *host, u8 *buffer, 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 * 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, ...@@ -40,9 +40,8 @@ struct hpsb_packet *hpsb_make_streampacket(struct hpsb_host *host, u8 *buffer,
*/ */
int hpsb_packet_success(struct hpsb_packet *packet); 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 * and act accordingly. Read and write automatically use quadlet commands if
* length == 4 and and block commands otherwise (however, they do not yet * 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 * 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, ...@@ -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, int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation,
u64 addr, quadlet_t *buffer, size_t length); u64 addr, quadlet_t *buffer, size_t length);
#ifdef HPSB_DEBUG_TLABELS
extern spinlock_t hpsb_tlabel_lock;
#endif
#endif /* _IEEE1394_TRANSACTIONS_H */ #endif /* _IEEE1394_TRANSACTIONS_H */
#ifndef _IEEE1394_TYPES_H #ifndef _IEEE1394_TYPES_H
#define _IEEE1394_TYPES_H #define _IEEE1394_TYPES_H
#include <linux/kernel.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/string.h>
#include <linux/types.h>
#include <asm/semaphore.h>
#include <asm/byteorder.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 u32 quadlet_t;
typedef u64 octlet_t; typedef u64 octlet_t;
typedef u16 nodeid_t; typedef u16 nodeid_t;
...@@ -54,7 +28,8 @@ typedef u16 arm_length_t; ...@@ -54,7 +28,8 @@ typedef u16 arm_length_t;
#define NODE_BUS_ARGS(__host, __nodeid) \ #define NODE_BUS_ARGS(__host, __nodeid) \
__host->id, NODEID_TO_NODE(__nodeid), NODEID_TO_BUS(__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_DEBUG(fmt, args...) HPSB_PRINT(KERN_DEBUG, fmt , ## args)
#define HPSB_INFO(fmt, args...) HPSB_PRINT(KERN_INFO, fmt , ## args) #define HPSB_INFO(fmt, args...) HPSB_PRINT(KERN_INFO, fmt , ## args)
...@@ -64,28 +39,21 @@ typedef u16 arm_length_t; ...@@ -64,28 +39,21 @@ typedef u16 arm_length_t;
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG #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 #else
#define HPSB_VERBOSE(fmt, args...) #define HPSB_VERBOSE(fmt, args...) do {} while (0)
#endif #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 #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; u32 *src = (u32 *)__src;
count /= 4; count /= 4;
while (count--)
while (count--) {
*dest++ = swab32p(src++); *dest++ = swab32p(src++);
}
return tmp; return tmp;
} }
......
...@@ -9,8 +9,11 @@ ...@@ -9,8 +9,11 @@
* directory of the kernel sources for details. * directory of the kernel sources for details.
*/ */
#include <linux/slab.h> #include <linux/pci.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/slab.h>
#include "hosts.h"
#include "iso.h" #include "iso.h"
void hpsb_iso_stop(struct hpsb_iso *iso) void hpsb_iso_stop(struct hpsb_iso *iso)
......
...@@ -12,33 +12,40 @@ ...@@ -12,33 +12,40 @@
#ifndef IEEE1394_ISO_H #ifndef IEEE1394_ISO_H
#define 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" #include "dma.h"
/* high-level ISO interface */ struct hpsb_host;
/* This API sends and receives isochronous packets on a large, /* high-level ISO interface */
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, * This API sends and receives isochronous packets on a large,
low-level drivers may impose certain restrictions on alignment or * virtually-contiguous kernel memory buffer. The buffer may be mapped
size of packets. (e.g. in OHCI no packet may cross a page boundary, * into a user-space process for zero-copy transmission and reception.
and packets should be quadlet-aligned) *
*/ * 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 /* 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 { struct hpsb_iso_packet_info {
/* offset of data payload relative to the first byte of the buffer */ /* offset of data payload relative to the first byte of the buffer */
__u32 offset; __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; __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; __u16 cycle;
/* (recv only) channel on which the packet was received */ /* (recv only) channel on which the packet was received */
...@@ -48,12 +55,10 @@ struct hpsb_iso_packet_info { ...@@ -48,12 +55,10 @@ struct hpsb_iso_packet_info {
__u8 tag; __u8 tag;
__u8 sy; __u8 sy;
/* /* length in bytes of the packet including header/trailer.
* length in bytes of the packet including header/trailer. * MUST be at structure end, since the first part of this structure is
* MUST be at structure end, since the first part of this structure is also * also defined in raw1394.h (i.e. struct raw1394_iso_packet_info), is
* defined in raw1394.h (i.e. struct raw1394_iso_packet_info), is copied to * copied to userspace and is accessed there through libraw1394. */
* userspace and is accessed there through libraw1394.
*/
__u16 total_len; __u16 total_len;
}; };
...@@ -75,8 +80,8 @@ struct hpsb_iso { ...@@ -75,8 +80,8 @@ struct hpsb_iso {
void *hostdata; void *hostdata;
/* a function to be called (from interrupt context) after /* a function to be called (from interrupt context) after
outgoing packets have been sent, or incoming packets have * outgoing packets have been sent, or incoming packets have
arrived */ * arrived */
void (*callback)(struct hpsb_iso*); void (*callback)(struct hpsb_iso*);
/* wait for buffer space */ /* wait for buffer space */
...@@ -88,7 +93,7 @@ struct hpsb_iso { ...@@ -88,7 +93,7 @@ struct hpsb_iso {
/* greatest # of packets between interrupts - controls /* greatest # of packets between interrupts - controls
the maximum latency of the buffer */ * the maximum latency of the buffer */
int irq_interval; int irq_interval;
/* the buffer for packet data payloads */ /* the buffer for packet data payloads */
...@@ -112,8 +117,8 @@ struct hpsb_iso { ...@@ -112,8 +117,8 @@ struct hpsb_iso {
int pkt_dma; int pkt_dma;
/* how many packets, starting at first_packet: /* how many packets, starting at first_packet:
(transmit) are ready to be filled with data * (transmit) are ready to be filled with data
(receive) contain received data */ * (receive) contain received data */
int n_ready_packets; int n_ready_packets;
/* how many times the buffer has overflowed or underflowed */ /* how many times the buffer has overflowed or underflowed */
...@@ -134,7 +139,7 @@ struct hpsb_iso { ...@@ -134,7 +139,7 @@ struct hpsb_iso {
int start_cycle; int start_cycle;
/* cycle at which next packet will be transmitted, /* cycle at which next packet will be transmitted,
-1 if not known */ * -1 if not known */
int xmit_cycle; int xmit_cycle;
/* ringbuffer of packet descriptors in regular kernel memory /* 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); ...@@ -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); int hpsb_iso_recv_set_channel_mask(struct hpsb_iso *iso, u64 mask);
/* start/stop DMA */ /* start/stop DMA */
int hpsb_iso_xmit_start(struct hpsb_iso *iso, int start_on_cycle, int prebuffer); int hpsb_iso_xmit_start(struct hpsb_iso *iso, int start_on_cycle,
int hpsb_iso_recv_start(struct hpsb_iso *iso, int start_on_cycle, int tag_mask, int sync); 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); void hpsb_iso_stop(struct hpsb_iso *iso);
/* deallocate buffer and DMA context */ /* deallocate buffer and DMA context */
void hpsb_iso_shutdown(struct hpsb_iso *iso); void hpsb_iso_shutdown(struct hpsb_iso *iso);
/* queue a packet for transmission. 'offset' is relative to the beginning of the /* queue a packet for transmission.
DMA buffer, where the packet's data payload should already have been placed */ * 'offset' is relative to the beginning of the DMA buffer, where the packet's
int hpsb_iso_xmit_queue_packet(struct hpsb_iso *iso, u32 offset, u16 len, u8 tag, u8 sy); * 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 */ /* wait until all queued packets have been transmitted to the bus */
int hpsb_iso_xmit_sync(struct hpsb_iso *iso); int hpsb_iso_xmit_sync(struct hpsb_iso *iso);
/* N packets have been read out of the buffer, re-use the buffer space */ /* N packets have been read out of the buffer, re-use the buffer space */
int hpsb_iso_recv_release_packets(struct hpsb_iso *recv, unsigned int n_packets); int hpsb_iso_recv_release_packets(struct hpsb_iso *recv,
unsigned int n_packets);
/* check for arrival of new packets immediately (even if irq_interval /* 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); int hpsb_iso_recv_flush(struct hpsb_iso *iso);
/* returns # of packets ready to send or receive */ /* returns # of packets ready to send or receive */
...@@ -197,14 +207,15 @@ int hpsb_iso_n_ready(struct hpsb_iso *iso); ...@@ -197,14 +207,15 @@ int hpsb_iso_n_ready(struct hpsb_iso *iso);
/* the following are callbacks available to low-level drivers */ /* the following are callbacks available to low-level drivers */
/* call after a packet has been transmitted to the bus (interrupt context is OK) /* call after a packet has been transmitted to the bus (interrupt context is OK)
'cycle' is the _exact_ cycle the packet was sent on * '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 * '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); void hpsb_iso_packet_sent(struct hpsb_iso *iso, int cycle, int error);
/* call after a packet has been received (interrupt context OK) */ /* call after a packet has been received (interrupt context OK) */
void hpsb_iso_packet_received(struct hpsb_iso *iso, u32 offset, u16 len, 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. */ /* call to wake waiting processes after buffer space has opened up. */
void hpsb_iso_wake(struct hpsb_iso *iso); void hpsb_iso_wake(struct hpsb_iso *iso);
......
This diff is collapsed.
...@@ -21,9 +21,15 @@ ...@@ -21,9 +21,15 @@
#define _IEEE1394_NODEMGR_H #define _IEEE1394_NODEMGR_H
#include <linux/device.h> #include <linux/device.h>
#include "csr1212.h" #include <asm/types.h>
#include "ieee1394_core.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 */ /* '1' '3' '9' '4' in ASCII */
#define IEEE1394_BUSID_MAGIC __constant_cpu_to_be32(0x31333934) #define IEEE1394_BUSID_MAGIC __constant_cpu_to_be32(0x31333934)
...@@ -44,7 +50,6 @@ struct bus_options { ...@@ -44,7 +50,6 @@ struct bus_options {
u16 max_rec; /* Maximum packet size node can receive */ u16 max_rec; /* Maximum packet size node can receive */
}; };
#define UNIT_DIRECTORY_VENDOR_ID 0x01 #define UNIT_DIRECTORY_VENDOR_ID 0x01
#define UNIT_DIRECTORY_MODEL_ID 0x02 #define UNIT_DIRECTORY_MODEL_ID 0x02
#define UNIT_DIRECTORY_SPECIFIER_ID 0x04 #define UNIT_DIRECTORY_SPECIFIER_ID 0x04
...@@ -79,7 +84,6 @@ struct unit_directory { ...@@ -79,7 +84,6 @@ struct unit_directory {
int length; /* Number of quadlets */ int length; /* Number of quadlets */
struct device device; struct device device;
struct class_device class_dev; struct class_device class_dev;
struct csr1212_keyval *ud_kv; struct csr1212_keyval *ud_kv;
...@@ -103,10 +107,8 @@ struct node_entry { ...@@ -103,10 +107,8 @@ struct node_entry {
const char *vendor_oui; const char *vendor_oui;
u32 capabilities; u32 capabilities;
struct hpsb_tlabel_pool *tpool;
struct device device; struct device device;
struct class_device class_dev; struct class_device class_dev;
/* Means this node is not attached anymore */ /* Means this node is not attached anymore */
...@@ -153,8 +155,8 @@ static inline int hpsb_node_entry_valid(struct node_entry *ne) ...@@ -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 * 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 * 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 * return false if the node owning the GUID is not accessible (and not modify
* hpsb_packet) and return true otherwise. * the hpsb_packet) and return true otherwise.
* *
* Note that packet sending may still fail in hpsb_send_packet if a bus reset * 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 * 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, ...@@ -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 hpsb_node_lock(struct node_entry *ne, u64 addr,
int extcode, quadlet_t *data, quadlet_t arg); int extcode, quadlet_t *data, quadlet_t arg);
/* Iterate the hosts, calling a given function with supplied data for each /* Iterate the hosts, calling a given function with supplied data for each
* host. */ * host. */
int nodemgr_for_each_host(void *__data, int (*cb)(struct hpsb_host *, void *)); int nodemgr_for_each_host(void *__data, int (*cb)(struct hpsb_host *, void *));
int init_ieee1394_nodemgr(void); int init_ieee1394_nodemgr(void);
void cleanup_ieee1394_nodemgr(void); void cleanup_ieee1394_nodemgr(void);
/* The template for a host device */ /* The template for a host device */
extern struct device nodemgr_dev_template_host; extern struct device nodemgr_dev_template_host;
......
...@@ -136,7 +136,7 @@ ...@@ -136,7 +136,7 @@
#define DBGMSG(fmt, args...) \ #define DBGMSG(fmt, args...) \
printk(KERN_INFO "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args) printk(KERN_INFO "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
#else #else
#define DBGMSG(fmt, args...) #define DBGMSG(fmt, args...) do {} while (0)
#endif #endif
#ifdef CONFIG_IEEE1394_OHCI_DMA_DEBUG #ifdef CONFIG_IEEE1394_OHCI_DMA_DEBUG
...@@ -148,8 +148,8 @@ printk(KERN_INFO "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host-> ...@@ -148,8 +148,8 @@ printk(KERN_INFO "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->
--global_outstanding_dmas, ## args) --global_outstanding_dmas, ## args)
static int global_outstanding_dmas = 0; static int global_outstanding_dmas = 0;
#else #else
#define OHCI_DMA_ALLOC(fmt, args...) #define OHCI_DMA_ALLOC(fmt, args...) do {} while (0)
#define OHCI_DMA_FREE(fmt, args...) #define OHCI_DMA_FREE(fmt, args...) do {} while (0)
#endif #endif
/* print general (card independent) information */ /* print general (card independent) information */
...@@ -181,36 +181,35 @@ static int alloc_dma_trm_ctx(struct ti_ohci *ohci, struct dma_trm_ctx *d, ...@@ -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); static void ohci1394_pci_remove(struct pci_dev *pdev);
#ifndef __LITTLE_ENDIAN #ifndef __LITTLE_ENDIAN
static unsigned hdr_sizes[] = const static size_t hdr_sizes[] = {
{
3, /* TCODE_WRITEQ */ 3, /* TCODE_WRITEQ */
4, /* TCODE_WRITEB */ 4, /* TCODE_WRITEB */
3, /* TCODE_WRITE_RESPONSE */ 3, /* TCODE_WRITE_RESPONSE */
0, /* ??? */ 0, /* reserved */
3, /* TCODE_READQ */ 3, /* TCODE_READQ */
4, /* TCODE_READB */ 4, /* TCODE_READB */
3, /* TCODE_READQ_RESPONSE */ 3, /* TCODE_READQ_RESPONSE */
4, /* TCODE_READB_RESPONSE */ 4, /* TCODE_READB_RESPONSE */
1, /* TCODE_CYCLE_START (???) */ 1, /* TCODE_CYCLE_START */
4, /* TCODE_LOCK_REQUEST */ 4, /* TCODE_LOCK_REQUEST */
2, /* TCODE_ISO_DATA */ 2, /* TCODE_ISO_DATA */
4, /* TCODE_LOCK_RESPONSE */ 4, /* TCODE_LOCK_RESPONSE */
/* rest is reserved or link-internal */
}; };
/* Swap headers */ static inline void header_le32_to_cpu(quadlet_t *data, unsigned char tcode)
static inline void packet_swab(quadlet_t *data, int 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; return;
size = hdr_sizes[tcode];
while (size--) while (size--)
data[size] = swab32(data[size]); data[size] = le32_to_cpu(data[size]);
} }
#else #else
/* Don't waste cycles on same sex byte swaps */ #define header_le32_to_cpu(w,x) do {} while (0)
#define packet_swab(w,x)
#endif /* !LITTLE_ENDIAN */ #endif /* !LITTLE_ENDIAN */
/*********************************** /***********************************
...@@ -701,7 +700,7 @@ static void insert_packet(struct ti_ohci *ohci, ...@@ -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[2] = packet->header[2];
d->prg_cpu[idx]->data[3] = packet->header[3]; 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 */ if (packet->data_size) { /* block transmit */
...@@ -777,7 +776,7 @@ static void insert_packet(struct ti_ohci *ohci, ...@@ -777,7 +776,7 @@ static void insert_packet(struct ti_ohci *ohci,
d->prg_cpu[idx]->data[0] = packet->speed_code<<16 | d->prg_cpu[idx]->data[0] = packet->speed_code<<16 |
(packet->header[0] & 0xFFFF); (packet->header[0] & 0xFFFF);
d->prg_cpu[idx]->data[1] = packet->header[0] & 0xFFFF0000; 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 = d->prg_cpu[idx]->begin.control =
cpu_to_le32(DMA_CTL_OUTPUT_MORE | 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, ...@@ -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 * Determine the length of a packet in the buffer
* Optimization suggested by Pascal Drolet <pascal.drolet@informission.ca> * 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, static inline int packet_length(struct dma_rcv_ctx *d, int idx,
int offset, unsigned char tcode, int noswap) quadlet_t *buf_ptr, int offset,
unsigned char tcode, int noswap)
{ {
int length = -1; int length = -1;
...@@ -2730,7 +2730,7 @@ static void dma_rcv_tasklet (unsigned long data) ...@@ -2730,7 +2730,7 @@ static void dma_rcv_tasklet (unsigned long data)
* bus reset. We always ignore it. */ * bus reset. We always ignore it. */
if (tcode != OHCI1394_TCODE_PHY) { if (tcode != OHCI1394_TCODE_PHY) {
if (!ohci->no_swap_incoming) if (!ohci->no_swap_incoming)
packet_swab(d->spb, tcode); header_le32_to_cpu(d->spb, tcode);
DBGMSG("Packet received from node" DBGMSG("Packet received from node"
" %d ack=0x%02X spd=%d tcode=0x%X" " %d ack=0x%02X spd=%d tcode=0x%X"
" length=%d ctx=%d tlabel=%d", " length=%d ctx=%d tlabel=%d",
...@@ -2738,7 +2738,7 @@ static void dma_rcv_tasklet (unsigned long data) ...@@ -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)>>16)&0x1f,
(cond_le32_to_cpu(d->spb[length/4-1], ohci->no_swap_incoming)>>21)&0x3, (cond_le32_to_cpu(d->spb[length/4-1], ohci->no_swap_incoming)>>21)&0x3,
tcode, length, d->ctx, 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) ack = (((cond_le32_to_cpu(d->spb[length/4-1], ohci->no_swap_incoming)>>16)&0x1f)
== 0x11) ? 1 : 0; == 0x11) ? 1 : 0;
...@@ -3529,9 +3529,10 @@ static void ohci1394_pci_remove(struct pci_dev *pdev) ...@@ -3529,9 +3529,10 @@ static void ohci1394_pci_remove(struct pci_dev *pdev)
put_device(dev); put_device(dev);
} }
#ifdef CONFIG_PM
static int ohci1394_pci_resume (struct pci_dev *pdev) static int ohci1394_pci_resume (struct pci_dev *pdev)
{ {
/* PowerMac resume code comes first */
#ifdef CONFIG_PPC_PMAC #ifdef CONFIG_PPC_PMAC
if (machine_is(powermac)) { if (machine_is(powermac)) {
struct device_node *of_node; struct device_node *of_node;
...@@ -3543,17 +3544,23 @@ static int ohci1394_pci_resume (struct pci_dev *pdev) ...@@ -3543,17 +3544,23 @@ static int ohci1394_pci_resume (struct pci_dev *pdev)
} }
#endif /* CONFIG_PPC_PMAC */ #endif /* CONFIG_PPC_PMAC */
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev); pci_restore_state(pdev);
pci_enable_device(pdev); return pci_enable_device(pdev);
return 0;
} }
static int ohci1394_pci_suspend (struct pci_dev *pdev, pm_message_t state) 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 #ifdef CONFIG_PPC_PMAC
if (machine_is(powermac)) { if (machine_is(powermac)) {
struct device_node *of_node; struct device_node *of_node;
...@@ -3563,11 +3570,11 @@ static int ohci1394_pci_suspend (struct pci_dev *pdev, pm_message_t state) ...@@ -3563,11 +3570,11 @@ static int ohci1394_pci_suspend (struct pci_dev *pdev, pm_message_t state)
if (of_node) if (of_node)
pmac_call_feature(PMAC_FTR_1394_ENABLE, of_node, 0, 0); pmac_call_feature(PMAC_FTR_1394_ENABLE, of_node, 0, 0);
} }
#endif #endif /* CONFIG_PPC_PMAC */
out:
return 0; return err;
} }
#endif /* CONFIG_PM */
#define PCI_CLASS_FIREWIRE_OHCI ((PCI_CLASS_SERIAL_FIREWIRE << 8) | 0x10) #define PCI_CLASS_FIREWIRE_OHCI ((PCI_CLASS_SERIAL_FIREWIRE << 8) | 0x10)
...@@ -3590,8 +3597,10 @@ static struct pci_driver ohci1394_pci_driver = { ...@@ -3590,8 +3597,10 @@ static struct pci_driver ohci1394_pci_driver = {
.id_table = ohci1394_pci_tbl, .id_table = ohci1394_pci_tbl,
.probe = ohci1394_pci_probe, .probe = ohci1394_pci_probe,
.remove = ohci1394_pci_remove, .remove = ohci1394_pci_remove,
#ifdef CONFIG_PM
.resume = ohci1394_pci_resume, .resume = ohci1394_pci_resume,
.suspend = ohci1394_pci_suspend, .suspend = ohci1394_pci_suspend,
#endif
}; };
/*********************************** /***********************************
...@@ -3718,5 +3727,7 @@ static int __init ohci1394_init(void) ...@@ -3718,5 +3727,7 @@ static int __init ohci1394_init(void)
return pci_register_driver(&ohci1394_pci_driver); 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); module_exit(ohci1394_cleanup);
...@@ -29,9 +29,8 @@ struct file_info { ...@@ -29,9 +29,8 @@ struct file_info {
struct list_head req_pending; struct list_head req_pending;
struct list_head req_complete; struct list_head req_complete;
struct semaphore complete_sem;
spinlock_t reqlists_lock; spinlock_t reqlists_lock;
wait_queue_head_t poll_wait_complete; wait_queue_head_t wait_complete;
struct list_head addr_list; struct list_head addr_list;
......
This diff is collapsed.
This diff is collapsed.
...@@ -46,8 +46,8 @@ ...@@ -46,8 +46,8 @@
#define ORB_SET_DIRECTION(value) ((value & 0x1) << 27) #define ORB_SET_DIRECTION(value) ((value & 0x1) << 27)
struct sbp2_command_orb { struct sbp2_command_orb {
volatile u32 next_ORB_hi; u32 next_ORB_hi;
volatile u32 next_ORB_lo; u32 next_ORB_lo;
u32 data_descriptor_hi; u32 data_descriptor_hi;
u32 data_descriptor_lo; u32 data_descriptor_lo;
u32 misc; u32 misc;
...@@ -180,12 +180,14 @@ struct sbp2_unrestricted_page_table { ...@@ -180,12 +180,14 @@ struct sbp2_unrestricted_page_table {
#define SBP2_SCSI_STATUS_SELECTION_TIMEOUT 0xff #define SBP2_SCSI_STATUS_SELECTION_TIMEOUT 0xff
#define STATUS_GET_ORB_OFFSET_HI(value) (value & 0xffff) #define STATUS_GET_SRC(value) (((value) >> 30) & 0x3)
#define STATUS_GET_SBP_STATUS(value) ((value >> 16) & 0xff) #define STATUS_GET_RESP(value) (((value) >> 28) & 0x3)
#define STATUS_GET_LENGTH(value) ((value >> 24) & 0x7) #define STATUS_GET_LEN(value) (((value) >> 24) & 0x7)
#define STATUS_GET_DEAD_BIT(value) ((value >> 27) & 0x1) #define STATUS_GET_SBP_STATUS(value) (((value) >> 16) & 0xff)
#define STATUS_GET_RESP(value) ((value >> 28) & 0x3) #define STATUS_GET_ORB_OFFSET_HI(value) ((value) & 0x0000ffff)
#define STATUS_GET_SRC(value) ((value >> 30) & 0x3) #define STATUS_TEST_DEAD(value) ((value) & 0x08000000)
/* test 'resp' | 'dead' | 'sbp2_status' */
#define STATUS_TEST_RDS(value) ((value) & 0x38ff0000)
struct sbp2_status_block { struct sbp2_status_block {
u32 ORB_offset_hi_misc; u32 ORB_offset_hi_misc;
...@@ -318,9 +320,9 @@ struct scsi_id_instance_data { ...@@ -318,9 +320,9 @@ struct scsi_id_instance_data {
u64 status_fifo_addr; 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 * Pool of command orbs, so we can have more than overlapped command per id
...@@ -344,6 +346,16 @@ struct scsi_id_instance_data { ...@@ -344,6 +346,16 @@ struct scsi_id_instance_data {
/* Device specific workarounds/brokeness */ /* Device specific workarounds/brokeness */
unsigned workarounds; 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) */ /* Sbp2 host data structure (one per IEEE1394 host) */
...@@ -390,11 +402,6 @@ static int sbp2_logout_device(struct scsi_id_instance_data *scsi_id); ...@@ -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, static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int destid,
quadlet_t *data, u64 addr, size_t length, u16 flags); 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_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, static unsigned int sbp2_status_to_sense_data(unchar *sbp2_status,
unchar *sense_data); unchar *sense_data);
static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id, static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id,
......
...@@ -49,16 +49,16 @@ ...@@ -49,16 +49,16 @@
#include <linux/compat.h> #include <linux/compat.h>
#include <linux/cdev.h> #include <linux/cdev.h>
#include "ieee1394.h" #include "dma.h"
#include "ieee1394_types.h" #include "highlevel.h"
#include "hosts.h" #include "hosts.h"
#include "ieee1394.h"
#include "ieee1394_core.h" #include "ieee1394_core.h"
#include "highlevel.h" #include "ieee1394_hotplug.h"
#include "video1394.h" #include "ieee1394_types.h"
#include "nodemgr.h" #include "nodemgr.h"
#include "dma.h"
#include "ohci1394.h" #include "ohci1394.h"
#include "video1394.h"
#define ISO_CHANNELS 64 #define ISO_CHANNELS 64
...@@ -129,7 +129,7 @@ struct file_ctx { ...@@ -129,7 +129,7 @@ struct file_ctx {
#define DBGMSG(card, fmt, args...) \ #define DBGMSG(card, fmt, args...) \
printk(KERN_INFO "video1394_%d: " fmt "\n" , card , ## args) printk(KERN_INFO "video1394_%d: " fmt "\n" , card , ## args)
#else #else
#define DBGMSG(card, fmt, args...) #define DBGMSG(card, fmt, args...) do {} while (0)
#endif #endif
/* print general (card independent) information */ /* print general (card independent) information */
...@@ -1181,7 +1181,8 @@ static int video1394_mmap(struct file *file, struct vm_area_struct *vma) ...@@ -1181,7 +1181,8 @@ static int video1394_mmap(struct file *file, struct vm_area_struct *vma)
lock_kernel(); lock_kernel();
if (ctx->current_ctx == NULL) { 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 } else
res = dma_region_mmap(&ctx->current_ctx->dma, file, vma); res = dma_region_mmap(&ctx->current_ctx->dma, file, vma);
unlock_kernel(); unlock_kernel();
...@@ -1189,6 +1190,40 @@ static int video1394_mmap(struct file *file, struct vm_area_struct *vma) ...@@ -1189,6 +1190,40 @@ static int video1394_mmap(struct file *file, struct vm_area_struct *vma)
return res; 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) static int video1394_open(struct inode *inode, struct file *file)
{ {
int i = ieee1394_file_to_instance(file); int i = ieee1394_file_to_instance(file);
...@@ -1257,6 +1292,7 @@ static struct file_operations video1394_fops= ...@@ -1257,6 +1292,7 @@ static struct file_operations video1394_fops=
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
.compat_ioctl = video1394_compat_ioctl, .compat_ioctl = video1394_compat_ioctl,
#endif #endif
.poll = video1394_poll,
.mmap = video1394_mmap, .mmap = video1394_mmap,
.open = video1394_open, .open = video1394_open,
.release = video1394_release .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