You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
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 ...
This commit is contained in:
@@ -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
|
||||||
|
|||||||
+10
-27
@@ -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
|
|||||||
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
|
|||||||
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"
|
||||||
|
|||||||
+10
-21
@@ -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)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* 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.
|
* Convert SPLIT_TIMEOUT to jiffies.
|
||||||
*
|
* The default and minimum as per 1394a-2000 clause 8.3.2.2.6 is 100ms.
|
||||||
* 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
|
|
||||||
* like CSR specifies. Should make our math less complex.
|
|
||||||
*/
|
*/
|
||||||
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 +
|
||||||
|
(csr->split_timeout_lo >> 19) * 125L;
|
||||||
|
|
||||||
/* Take the seconds, and convert to units */
|
csr->expire = usecs_to_jiffies(usecs > 100000L ? usecs : 100000L);
|
||||||
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++;
|
|
||||||
|
|
||||||
HPSB_VERBOSE("CSR: setting expire to %lu, HZ=%u", csr->expire, HZ);
|
HPSB_VERBOSE("CSR: setting expire to %lu, HZ=%u", csr->expire, HZ);
|
||||||
}
|
}
|
||||||
|
|||||||
+55
-52
@@ -1,75 +1,73 @@
|
|||||||
|
|
||||||
#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
|
||||||
|
|
||||||
/* register offsets relative to CSR_REGISTER_BASE */
|
/* register offsets relative to CSR_REGISTER_BASE */
|
||||||
#define CSR_STATE_CLEAR 0x0
|
#define CSR_STATE_CLEAR 0x0
|
||||||
#define CSR_STATE_SET 0x4
|
#define CSR_STATE_SET 0x4
|
||||||
#define CSR_NODE_IDS 0x8
|
#define CSR_NODE_IDS 0x8
|
||||||
#define CSR_RESET_START 0xc
|
#define CSR_RESET_START 0xc
|
||||||
#define CSR_SPLIT_TIMEOUT_HI 0x18
|
#define CSR_SPLIT_TIMEOUT_HI 0x18
|
||||||
#define CSR_SPLIT_TIMEOUT_LO 0x1c
|
#define CSR_SPLIT_TIMEOUT_LO 0x1c
|
||||||
#define CSR_CYCLE_TIME 0x200
|
#define CSR_CYCLE_TIME 0x200
|
||||||
#define CSR_BUS_TIME 0x204
|
#define CSR_BUS_TIME 0x204
|
||||||
#define CSR_BUSY_TIMEOUT 0x210
|
#define CSR_BUSY_TIMEOUT 0x210
|
||||||
#define CSR_BUS_MANAGER_ID 0x21c
|
#define CSR_BUS_MANAGER_ID 0x21c
|
||||||
#define CSR_BANDWIDTH_AVAILABLE 0x220
|
#define CSR_BANDWIDTH_AVAILABLE 0x220
|
||||||
#define CSR_CHANNELS_AVAILABLE 0x224
|
#define CSR_CHANNELS_AVAILABLE 0x224
|
||||||
#define CSR_CHANNELS_AVAILABLE_HI 0x224
|
#define CSR_CHANNELS_AVAILABLE_HI 0x224
|
||||||
#define CSR_CHANNELS_AVAILABLE_LO 0x228
|
#define CSR_CHANNELS_AVAILABLE_LO 0x228
|
||||||
#define CSR_BROADCAST_CHANNEL 0x234
|
#define CSR_BROADCAST_CHANNEL 0x234
|
||||||
#define CSR_CONFIG_ROM 0x400
|
#define CSR_CONFIG_ROM 0x400
|
||||||
#define CSR_CONFIG_ROM_END 0x800
|
#define CSR_CONFIG_ROM_END 0x800
|
||||||
#define CSR_FCP_COMMAND 0xB00
|
#define CSR_FCP_COMMAND 0xB00
|
||||||
#define CSR_FCP_RESPONSE 0xD00
|
#define CSR_FCP_RESPONSE 0xD00
|
||||||
#define CSR_FCP_END 0xF00
|
#define CSR_FCP_END 0xF00
|
||||||
#define CSR_TOPOLOGY_MAP 0x1000
|
#define CSR_TOPOLOGY_MAP 0x1000
|
||||||
#define CSR_TOPOLOGY_MAP_END 0x1400
|
#define CSR_TOPOLOGY_MAP_END 0x1400
|
||||||
#define CSR_SPEED_MAP 0x2000
|
#define CSR_SPEED_MAP 0x2000
|
||||||
#define CSR_SPEED_MAP_END 0x3000
|
#define CSR_SPEED_MAP_END 0x3000
|
||||||
|
|
||||||
/* 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
|
||||||
#define CSR_CMC_SHIFT 30
|
#define CSR_CMC_SHIFT 30
|
||||||
#define CSR_ISC_SHIFT 29
|
#define CSR_ISC_SHIFT 29
|
||||||
#define CSR_BMC_SHIFT 28
|
#define CSR_BMC_SHIFT 28
|
||||||
#define CSR_PMC_SHIFT 27
|
#define CSR_PMC_SHIFT 27
|
||||||
#define CSR_CYC_CLK_ACC_SHIFT 16
|
#define CSR_CYC_CLK_ACC_SHIFT 16
|
||||||
#define CSR_MAX_REC_SHIFT 12
|
#define CSR_MAX_REC_SHIFT 12
|
||||||
#define CSR_MAX_ROM_SHIFT 8
|
#define CSR_MAX_ROM_SHIFT 8
|
||||||
#define CSR_GENERATION_SHIFT 4
|
#define CSR_GENERATION_SHIFT 4
|
||||||
|
|
||||||
#define CSR_SET_BUS_INFO_GENERATION(csr, gen) \
|
#define CSR_SET_BUS_INFO_GENERATION(csr, gen) \
|
||||||
((csr)->bus_info_data[2] = \
|
((csr)->bus_info_data[2] = \
|
||||||
cpu_to_be32((be32_to_cpu((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))
|
(gen) << CSR_GENERATION_SHIFT))
|
||||||
|
|
||||||
struct csr_control {
|
struct csr_control {
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
|
|
||||||
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;
|
||||||
quadlet_t bandwidth_available;
|
quadlet_t bandwidth_available;
|
||||||
quadlet_t channels_available_hi, channels_available_lo;
|
quadlet_t channels_available_hi, channels_available_lo;
|
||||||
quadlet_t broadcast_channel;
|
quadlet_t broadcast_channel;
|
||||||
|
|
||||||
/* Bus Info */
|
/* Bus Info */
|
||||||
@@ -84,8 +82,8 @@ struct csr_control {
|
|||||||
|
|
||||||
struct csr1212_csr *rom;
|
struct csr1212_csr *rom;
|
||||||
|
|
||||||
quadlet_t topology_map[256];
|
quadlet_t topology_map[256];
|
||||||
quadlet_t speed_map[1024];
|
quadlet_t speed_map[1024];
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct csr1212_bus_ops csr_bus_ops;
|
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 @@
|
|||||||
* directory of the kernel sources for details.
|
* directory of the kernel sources for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/vmalloc.h>
|
|
||||||
#include <linux/slab.h>
|
|
||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/pci.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/vmalloc.h>
|
||||||
|
#include <asm/scatterlist.h>
|
||||||
|
|
||||||
#include "dma.h"
|
#include "dma.h"
|
||||||
|
|
||||||
/* dma_prog_region */
|
/* dma_prog_region */
|
||||||
|
|||||||
+54
-32
@@ -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 dma_prog_region
|
struct pci_dev;
|
||||||
|
struct scatterlist;
|
||||||
a small, physically-contiguous DMA buffer with random-access,
|
struct vm_area_struct;
|
||||||
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 {
|
|||||||
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 {
|
|||||||
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;
|
||||||
|
|||||||
+25
-24
@@ -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 @@
|
|||||||
#include <linux/compat.h>
|
#include <linux/compat.h>
|
||||||
#include <linux/cdev.h>
|
#include <linux/cdev.h>
|
||||||
|
|
||||||
#include "ieee1394.h"
|
|
||||||
#include "ieee1394_types.h"
|
|
||||||
#include "nodemgr.h"
|
|
||||||
#include "hosts.h"
|
|
||||||
#include "ieee1394_core.h"
|
|
||||||
#include "highlevel.h"
|
|
||||||
#include "dv1394.h"
|
#include "dv1394.h"
|
||||||
#include "dv1394-private.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 "ohci1394.h"
|
#include "ohci1394.h"
|
||||||
|
|
||||||
/* DEBUG LEVELS:
|
/* DEBUG LEVELS:
|
||||||
@@ -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)
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
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
|
|||||||
|
|
||||||
/* 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
|
|||||||
|
|
||||||
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
|
|||||||
|
|
||||||
/* 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
|
|||||||
|
|
||||||
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)
|
|||||||
|
|
||||||
/* 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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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
|
|||||||
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 @@
|
|||||||
#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 "ieee1394_core.h"
|
|
||||||
#include "ieee1394_transactions.h"
|
|
||||||
#include "ieee1394.h"
|
|
||||||
#include "highlevel.h"
|
#include "highlevel.h"
|
||||||
|
#include "ieee1394.h"
|
||||||
|
#include "ieee1394_core.h"
|
||||||
|
#include "ieee1394_hotplug.h"
|
||||||
|
#include "ieee1394_transactions.h"
|
||||||
|
#include "ieee1394_types.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)
|
||||||
|
|||||||
+104
-97
@@ -1,60 +1,61 @@
|
|||||||
|
|
||||||
#ifndef IEEE1394_HIGHLEVEL_H
|
#ifndef IEEE1394_HIGHLEVEL_H
|
||||||
#define IEEE1394_HIGHLEVEL_H
|
#define IEEE1394_HIGHLEVEL_H
|
||||||
|
|
||||||
|
#include <linux/list.h>
|
||||||
|
#include <linux/spinlock_types.h>
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
struct module;
|
||||||
|
|
||||||
|
#include "ieee1394_types.h"
|
||||||
|
|
||||||
|
struct hpsb_host;
|
||||||
|
|
||||||
|
/* internal to ieee1394 core */
|
||||||
struct hpsb_address_serve {
|
struct hpsb_address_serve {
|
||||||
struct list_head host_list; /* per host list */
|
struct list_head host_list; /* per host list */
|
||||||
|
struct list_head hl_list; /* hpsb_highlevel list */
|
||||||
struct list_head hl_list; /* hpsb_highlevel list */
|
struct hpsb_address_ops *op;
|
||||||
|
|
||||||
struct hpsb_address_ops *op;
|
|
||||||
|
|
||||||
struct hpsb_host *host;
|
struct hpsb_host *host;
|
||||||
|
u64 start; /* first address handled, quadlet aligned */
|
||||||
/* first address handled and first address behind, quadlet aligned */
|
u64 end; /* first address behind, quadlet aligned */
|
||||||
u64 start, end;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Only the following structures are of interest to actual highlevel drivers. */
|
||||||
/*
|
|
||||||
* The above structs are internal to highlevel driver handling. Only the
|
|
||||||
* following structures are of interest to actual highlevel drivers.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct hpsb_highlevel {
|
struct hpsb_highlevel {
|
||||||
struct module *owner;
|
struct module *owner;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
/* Any of the following pointers can legally be NULL, except for
|
/* Any of the following pointers can legally be NULL, except for
|
||||||
* iso_receive which can only be NULL when you don't request
|
* iso_receive which can only be NULL when you don't request
|
||||||
* channels. */
|
* channels. */
|
||||||
|
|
||||||
/* New host initialized. Will also be called during
|
/* New host initialized. Will also be called during
|
||||||
* hpsb_register_highlevel for all hosts already installed. */
|
* hpsb_register_highlevel for all hosts already installed. */
|
||||||
void (*add_host) (struct hpsb_host *host);
|
void (*add_host)(struct hpsb_host *host);
|
||||||
|
|
||||||
/* Host about to be removed. Will also be called during
|
/* Host about to be removed. Will also be called during
|
||||||
* hpsb_unregister_highlevel once for each host. */
|
* hpsb_unregister_highlevel once for each host. */
|
||||||
void (*remove_host) (struct hpsb_host *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.
|
* Note that this one may occur during interrupt/bottom half handling.
|
||||||
* You can not expect to be able to do stock hpsb_reads. */
|
* 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
|
/* An isochronous packet was received. Channel contains the channel
|
||||||
* number for your convenience, it is also contained in the included
|
* number for your convenience, it is also contained in the included
|
||||||
* packet header (first quadlet, CRCs are missing). You may get called
|
* packet header (first quadlet, CRCs are missing). You may get called
|
||||||
* for channel/host combinations you did not request. */
|
* for channel/host combinations you did not request. */
|
||||||
void (*iso_receive) (struct hpsb_host *host, int channel,
|
void (*iso_receive)(struct hpsb_host *host, int channel,
|
||||||
quadlet_t *data, size_t length);
|
quadlet_t *data, size_t length);
|
||||||
|
|
||||||
/* A write request was received on either the FCP_COMMAND (direction =
|
/* A write request was received on either the FCP_COMMAND (direction =
|
||||||
* 0) or the FCP_RESPONSE (direction = 1) register. The cts arg
|
* 0) or the FCP_RESPONSE (direction = 1) register. The cts arg
|
||||||
* contains the cts field (first byte of data). */
|
* contains the cts field (first byte of data). */
|
||||||
void (*fcp_request) (struct hpsb_host *host, int nodeid, int direction,
|
void (*fcp_request)(struct hpsb_host *host, int nodeid, int direction,
|
||||||
int cts, u8 *data, size_t length);
|
int cts, u8 *data, size_t length);
|
||||||
|
|
||||||
/* These are initialized by the subsystem when the
|
/* These are initialized by the subsystem when the
|
||||||
* hpsb_higlevel is registered. */
|
* hpsb_higlevel is registered. */
|
||||||
@@ -67,61 +68,62 @@ struct hpsb_highlevel {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct hpsb_address_ops {
|
struct hpsb_address_ops {
|
||||||
/*
|
/*
|
||||||
* Null function pointers will make the respective operation complete
|
* Null function pointers will make the respective operation complete
|
||||||
* with RCODE_TYPE_ERROR. Makes for easy to implement read-only
|
* with RCODE_TYPE_ERROR. Makes for easy to implement read-only
|
||||||
* registers (just leave everything but read NULL).
|
* registers (just leave everything but read NULL).
|
||||||
*
|
*
|
||||||
* All functions shall return appropriate IEEE 1394 rcodes.
|
* All functions shall return appropriate IEEE 1394 rcodes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* These functions have to implement block reads for themselves. */
|
/* 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
|
* These functions either return a response code or a negative number.
|
||||||
later case, no response will be sent and the driver, that handled the request
|
* In the first case a response will be generated. In the latter case,
|
||||||
will send the response itself
|
* 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,
|
int (*read)(struct hpsb_host *host, int nodeid, quadlet_t *buffer,
|
||||||
u64 addr, size_t length, u16 flags);
|
u64 addr, size_t length, u16 flags);
|
||||||
int (*write) (struct hpsb_host *host, int nodeid, int destid,
|
int (*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);
|
||||||
|
|
||||||
/* Lock transactions: write results of ext_tcode operation into
|
/* Lock transactions: write results of ext_tcode operation into
|
||||||
* *store. */
|
* *store. */
|
||||||
int (*lock) (struct hpsb_host *host, int nodeid, quadlet_t *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);
|
u64 addr, quadlet_t data, quadlet_t arg, int ext_tcode,
|
||||||
int (*lock64) (struct hpsb_host *host, int nodeid, octlet_t *store,
|
u16 flags);
|
||||||
u64 addr, octlet_t data, octlet_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_add_host(struct hpsb_host *host);
|
||||||
void highlevel_remove_host(struct hpsb_host *host);
|
void highlevel_remove_host(struct hpsb_host *host);
|
||||||
void highlevel_host_reset(struct hpsb_host *host);
|
void highlevel_host_reset(struct hpsb_host *host);
|
||||||
|
|
||||||
|
/*
|
||||||
/* these functions are called to handle transactions. They are called, when
|
* These functions are called to handle transactions. They are called when a
|
||||||
a packet arrives. The flags argument contains the second word of the first header
|
* packet arrives. The flags argument contains the second word of the first
|
||||||
quadlet of the incoming packet (containing transaction label, retry code,
|
* header quadlet of the incoming packet (containing transaction label, retry
|
||||||
transaction code and priority). These functions either return a response code
|
* code, transaction code and priority). These functions either return a
|
||||||
or a negative number. In the first case a response will be generated; in the
|
* response code or a negative number. In the first case a response will be
|
||||||
later case, no response will be sent and the driver, that handled the request
|
* generated. In the latter case, no response will be sent and the driver which
|
||||||
will send the response itself.
|
* handled the request will send the response itself.
|
||||||
*/
|
*/
|
||||||
int highlevel_read(struct hpsb_host *host, int nodeid, void *data,
|
int highlevel_read(struct hpsb_host *host, int nodeid, void *data, u64 addr,
|
||||||
u64 addr, unsigned int length, u16 flags);
|
unsigned int length, u16 flags);
|
||||||
int highlevel_write(struct hpsb_host *host, int nodeid, int destid,
|
int highlevel_write(struct hpsb_host *host, int nodeid, int destid, void *data,
|
||||||
void *data, u64 addr, unsigned int length, u16 flags);
|
u64 addr, unsigned int length, u16 flags);
|
||||||
int highlevel_lock(struct hpsb_host *host, int nodeid, quadlet_t *store,
|
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,
|
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,
|
void highlevel_iso_receive(struct hpsb_host *host, void *data, size_t length);
|
||||||
size_t length);
|
|
||||||
void highlevel_fcp_request(struct hpsb_host *host, int nodeid, int direction,
|
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
|
* 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
|
* 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
|
* and have to be quadlet aligned. Argument "end" points to the first address
|
||||||
* handled addresses. This function can be called multiple times for a single
|
* behind the handled addresses. This function can be called multiple times for
|
||||||
* hpsb_highlevel to implement sparse register sets. The requested region must
|
* a single hpsb_highlevel to implement sparse register sets. The requested
|
||||||
* not overlap any previously allocated region, otherwise registering will fail.
|
* region must not overlap any previously allocated region, otherwise
|
||||||
|
* registering will fail.
|
||||||
*
|
*
|
||||||
* It returns true for successful allocation. There is no unregister function,
|
* It returns true for successful allocation. Address spaces can be
|
||||||
* all address spaces are deallocated together with the hpsb_highlevel.
|
* 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,
|
u64 hpsb_allocate_and_register_addrspace(struct hpsb_highlevel *hl,
|
||||||
struct hpsb_host *host,
|
struct hpsb_host *host,
|
||||||
@@ -146,20 +150,18 @@ u64 hpsb_allocate_and_register_addrspace(struct hpsb_highlevel *hl,
|
|||||||
u64 size, u64 alignment,
|
u64 size, u64 alignment,
|
||||||
u64 start, u64 end);
|
u64 start, u64 end);
|
||||||
int hpsb_register_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host,
|
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,
|
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
|
* Enable or disable receving a certain isochronous channel through the
|
||||||
* iso_receive op.
|
* iso_receive op.
|
||||||
*/
|
*/
|
||||||
int hpsb_listen_channel(struct hpsb_highlevel *hl, struct hpsb_host *host,
|
int hpsb_listen_channel(struct hpsb_highlevel *hl, struct hpsb_host *host,
|
||||||
unsigned int channel);
|
unsigned int channel);
|
||||||
void hpsb_unlisten_channel(struct hpsb_highlevel *hl, struct hpsb_host *host,
|
void hpsb_unlisten_channel(struct hpsb_highlevel *hl, struct hpsb_host *host,
|
||||||
unsigned int channel);
|
unsigned int channel);
|
||||||
|
|
||||||
|
|
||||||
/* Retrieve a hostinfo pointer bound to this driver/host */
|
/* Retrieve a hostinfo pointer bound to this driver/host */
|
||||||
void *hpsb_get_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *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);
|
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 */
|
/* 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 */
|
/* Retrieve the alternate lookup key for the hostinfo bound to this
|
||||||
unsigned long hpsb_get_hostinfo_key(struct hpsb_highlevel *hl, struct hpsb_host *host);
|
* 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 */
|
/* Retrieve a hostinfo pointer bound to this driver using its alternate key */
|
||||||
void *hpsb_get_hostinfo_bykey(struct hpsb_highlevel *hl, unsigned long 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
|
/* Set the hostinfo pointer to something useful. Usually follows a call to
|
||||||
* hpsb_create_hostinfo, where the size is 0. */
|
* 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 */
|
/* 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 */
|
#endif /* IEEE1394_HIGHLEVEL_H */
|
||||||
|
|||||||
+10
-13
@@ -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)
|
|||||||
* 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,
|
|||||||
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);
|
||||||
|
|||||||
+24
-31
@@ -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 {
|
|||||||
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,32 +54,30 @@ 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];
|
|
||||||
|
|
||||||
struct hpsb_host_driver *driver;
|
|
||||||
|
|
||||||
struct pci_dev *pdev;
|
|
||||||
|
|
||||||
int id;
|
int id;
|
||||||
|
struct hpsb_host_driver *driver;
|
||||||
|
struct pci_dev *pdev;
|
||||||
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
|
||||||
* requests. If arg == 1, it shall also attempt to become root on the
|
* requests. If arg == 1, it shall also attempt to become root on the
|
||||||
@@ -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 {
|
|||||||
/* 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 {
|
|||||||
* 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 {
|
|||||||
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.
|
||||||
|
|||||||
@@ -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
|
#ifndef __IEEE1394_IOCTL_H
|
||||||
#define __IEEE1394_IOCTL_H
|
#define __IEEE1394_IOCTL_H
|
||||||
@@ -96,8 +98,7 @@
|
|||||||
_IOW ('#', 0x27, struct raw1394_iso_packets)
|
_IOW ('#', 0x27, struct raw1394_iso_packets)
|
||||||
#define RAW1394_IOC_ISO_XMIT_SYNC \
|
#define RAW1394_IOC_ISO_XMIT_SYNC \
|
||||||
_IO ('#', 0x28)
|
_IO ('#', 0x28)
|
||||||
#define RAW1394_IOC_ISO_RECV_FLUSH \
|
#define RAW1394_IOC_ISO_RECV_FLUSH \
|
||||||
_IO ('#', 0x29)
|
_IO ('#', 0x29)
|
||||||
|
|
||||||
|
|
||||||
#endif /* __IEEE1394_IOCTL_H */
|
#endif /* __IEEE1394_IOCTL_H */
|
||||||
|
|||||||
+152
-152
@@ -5,77 +5,78 @@
|
|||||||
#ifndef _IEEE1394_IEEE1394_H
|
#ifndef _IEEE1394_IEEE1394_H
|
||||||
#define _IEEE1394_IEEE1394_H
|
#define _IEEE1394_IEEE1394_H
|
||||||
|
|
||||||
#define TCODE_WRITEQ 0x0
|
#define TCODE_WRITEQ 0x0
|
||||||
#define TCODE_WRITEB 0x1
|
#define TCODE_WRITEB 0x1
|
||||||
#define TCODE_WRITE_RESPONSE 0x2
|
#define TCODE_WRITE_RESPONSE 0x2
|
||||||
#define TCODE_READQ 0x4
|
#define TCODE_READQ 0x4
|
||||||
#define TCODE_READB 0x5
|
#define TCODE_READB 0x5
|
||||||
#define TCODE_READQ_RESPONSE 0x6
|
#define TCODE_READQ_RESPONSE 0x6
|
||||||
#define TCODE_READB_RESPONSE 0x7
|
#define TCODE_READB_RESPONSE 0x7
|
||||||
#define TCODE_CYCLE_START 0x8
|
#define TCODE_CYCLE_START 0x8
|
||||||
#define TCODE_LOCK_REQUEST 0x9
|
#define TCODE_LOCK_REQUEST 0x9
|
||||||
#define TCODE_ISO_DATA 0xa
|
#define TCODE_ISO_DATA 0xa
|
||||||
#define TCODE_STREAM_DATA 0xa
|
#define TCODE_STREAM_DATA 0xa
|
||||||
#define TCODE_LOCK_RESPONSE 0xb
|
#define TCODE_LOCK_RESPONSE 0xb
|
||||||
|
|
||||||
#define RCODE_COMPLETE 0x0
|
#define RCODE_COMPLETE 0x0
|
||||||
#define RCODE_CONFLICT_ERROR 0x4
|
#define RCODE_CONFLICT_ERROR 0x4
|
||||||
#define RCODE_DATA_ERROR 0x5
|
#define RCODE_DATA_ERROR 0x5
|
||||||
#define RCODE_TYPE_ERROR 0x6
|
#define RCODE_TYPE_ERROR 0x6
|
||||||
#define RCODE_ADDRESS_ERROR 0x7
|
#define RCODE_ADDRESS_ERROR 0x7
|
||||||
|
|
||||||
#define EXTCODE_MASK_SWAP 0x1
|
#define EXTCODE_MASK_SWAP 0x1
|
||||||
#define EXTCODE_COMPARE_SWAP 0x2
|
#define EXTCODE_COMPARE_SWAP 0x2
|
||||||
#define EXTCODE_FETCH_ADD 0x3
|
#define EXTCODE_FETCH_ADD 0x3
|
||||||
#define EXTCODE_LITTLE_ADD 0x4
|
#define EXTCODE_LITTLE_ADD 0x4
|
||||||
#define EXTCODE_BOUNDED_ADD 0x5
|
#define EXTCODE_BOUNDED_ADD 0x5
|
||||||
#define EXTCODE_WRAP_ADD 0x6
|
#define EXTCODE_WRAP_ADD 0x6
|
||||||
|
|
||||||
#define ACK_COMPLETE 0x1
|
#define ACK_COMPLETE 0x1
|
||||||
#define ACK_PENDING 0x2
|
#define ACK_PENDING 0x2
|
||||||
#define ACK_BUSY_X 0x4
|
#define ACK_BUSY_X 0x4
|
||||||
#define ACK_BUSY_A 0x5
|
#define ACK_BUSY_A 0x5
|
||||||
#define ACK_BUSY_B 0x6
|
#define ACK_BUSY_B 0x6
|
||||||
#define ACK_TARDY 0xb
|
#define ACK_TARDY 0xb
|
||||||
#define ACK_CONFLICT_ERROR 0xc
|
#define ACK_CONFLICT_ERROR 0xc
|
||||||
#define ACK_DATA_ERROR 0xd
|
#define ACK_DATA_ERROR 0xd
|
||||||
#define ACK_TYPE_ERROR 0xe
|
#define ACK_TYPE_ERROR 0xe
|
||||||
#define ACK_ADDRESS_ERROR 0xf
|
#define ACK_ADDRESS_ERROR 0xf
|
||||||
|
|
||||||
/* Non-standard "ACK codes" for internal use */
|
/* Non-standard "ACK codes" for internal use */
|
||||||
#define ACKX_NONE (-1)
|
#define ACKX_NONE (-1)
|
||||||
#define ACKX_SEND_ERROR (-2)
|
#define ACKX_SEND_ERROR (-2)
|
||||||
#define ACKX_ABORTED (-3)
|
#define ACKX_ABORTED (-3)
|
||||||
#define ACKX_TIMEOUT (-4)
|
#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 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 */
|
/* 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
|
||||||
#define SELFID_PWRCL_PROVIDE_30W 0x2
|
#define SELFID_PWRCL_PROVIDE_30W 0x2
|
||||||
#define SELFID_PWRCL_PROVIDE_45W 0x3
|
#define SELFID_PWRCL_PROVIDE_45W 0x3
|
||||||
#define SELFID_PWRCL_USE_1W 0x4
|
#define SELFID_PWRCL_USE_1W 0x4
|
||||||
#define SELFID_PWRCL_USE_3W 0x5
|
#define SELFID_PWRCL_USE_3W 0x5
|
||||||
#define SELFID_PWRCL_USE_6W 0x6
|
#define SELFID_PWRCL_USE_6W 0x6
|
||||||
#define SELFID_PWRCL_USE_10W 0x7
|
#define SELFID_PWRCL_USE_10W 0x7
|
||||||
|
|
||||||
#define SELFID_PORT_CHILD 0x3
|
#define SELFID_PORT_CHILD 0x3
|
||||||
#define SELFID_PORT_PARENT 0x2
|
#define SELFID_PORT_PARENT 0x2
|
||||||
#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
|
||||||
@@ -91,76 +92,76 @@ extern const char *hpsb_speedto_str[];
|
|||||||
|
|
||||||
#define EXTPHYPACKET_TYPEMASK 0xC0FC0000
|
#define EXTPHYPACKET_TYPEMASK 0xC0FC0000
|
||||||
|
|
||||||
#define PHYPACKET_PORT_SHIFT 24
|
#define PHYPACKET_PORT_SHIFT 24
|
||||||
#define PHYPACKET_GAPCOUNT_SHIFT 16
|
#define PHYPACKET_GAPCOUNT_SHIFT 16
|
||||||
|
|
||||||
/* 1394a PHY register map bitmasks */
|
/* 1394a PHY register map bitmasks */
|
||||||
#define PHY_00_PHYSICAL_ID 0xFC
|
#define PHY_00_PHYSICAL_ID 0xFC
|
||||||
#define PHY_00_R 0x02 /* Root */
|
#define PHY_00_R 0x02 /* Root */
|
||||||
#define PHY_00_PS 0x01 /* Power Status*/
|
#define PHY_00_PS 0x01 /* Power Status*/
|
||||||
#define PHY_01_RHB 0x80 /* Root Hold-Off */
|
#define PHY_01_RHB 0x80 /* Root Hold-Off */
|
||||||
#define PHY_01_IBR 0x80 /* Initiate Bus Reset */
|
#define PHY_01_IBR 0x80 /* Initiate Bus Reset */
|
||||||
#define PHY_01_GAP_COUNT 0x3F
|
#define PHY_01_GAP_COUNT 0x3F
|
||||||
#define PHY_02_EXTENDED 0xE0 /* 0x7 for 1394a-compliant PHY */
|
#define PHY_02_EXTENDED 0xE0 /* 0x7 for 1394a-compliant PHY */
|
||||||
#define PHY_02_TOTAL_PORTS 0x1F
|
#define PHY_02_TOTAL_PORTS 0x1F
|
||||||
#define PHY_03_MAX_SPEED 0xE0
|
#define PHY_03_MAX_SPEED 0xE0
|
||||||
#define PHY_03_DELAY 0x0F
|
#define PHY_03_DELAY 0x0F
|
||||||
#define PHY_04_LCTRL 0x80 /* Link Active Report Control */
|
#define PHY_04_LCTRL 0x80 /* Link Active Report Control */
|
||||||
#define PHY_04_CONTENDER 0x40
|
#define PHY_04_CONTENDER 0x40
|
||||||
#define PHY_04_JITTER 0x38
|
#define PHY_04_JITTER 0x38
|
||||||
#define PHY_04_PWR_CLASS 0x07 /* Power Class */
|
#define PHY_04_PWR_CLASS 0x07 /* Power Class */
|
||||||
#define PHY_05_WATCHDOG 0x80
|
#define PHY_05_WATCHDOG 0x80
|
||||||
#define PHY_05_ISBR 0x40 /* Initiate Short Bus Reset */
|
#define PHY_05_ISBR 0x40 /* Initiate Short Bus Reset */
|
||||||
#define PHY_05_LOOP 0x20 /* Loop Detect */
|
#define PHY_05_LOOP 0x20 /* Loop Detect */
|
||||||
#define PHY_05_PWR_FAIL 0x10 /* Cable Power Failure Detect */
|
#define PHY_05_PWR_FAIL 0x10 /* Cable Power Failure Detect */
|
||||||
#define PHY_05_TIMEOUT 0x08 /* Arbitration State Machine Timeout */
|
#define PHY_05_TIMEOUT 0x08 /* Arbitration State Machine Timeout */
|
||||||
#define PHY_05_PORT_EVENT 0x04 /* Port Event Detect */
|
#define PHY_05_PORT_EVENT 0x04 /* Port Event Detect */
|
||||||
#define PHY_05_ENAB_ACCEL 0x02 /* Enable Arbitration Acceleration */
|
#define PHY_05_ENAB_ACCEL 0x02 /* Enable Arbitration Acceleration */
|
||||||
#define PHY_05_ENAB_MULTI 0x01 /* Ena. Multispeed Packet Concatenation */
|
#define PHY_05_ENAB_MULTI 0x01 /* Ena. Multispeed Packet Concatenation */
|
||||||
|
|
||||||
#include <asm/byteorder.h>
|
#include <asm/byteorder.h>
|
||||||
|
|
||||||
#ifdef __BIG_ENDIAN_BITFIELD
|
#ifdef __BIG_ENDIAN_BITFIELD
|
||||||
|
|
||||||
struct selfid {
|
struct selfid {
|
||||||
u32 packet_identifier:2; /* always binary 10 */
|
u32 packet_identifier:2; /* always binary 10 */
|
||||||
u32 phy_id:6;
|
u32 phy_id:6;
|
||||||
/* byte */
|
/* byte */
|
||||||
u32 extended:1; /* if true is struct ext_selfid */
|
u32 extended:1; /* if true is struct ext_selfid */
|
||||||
u32 link_active:1;
|
u32 link_active:1;
|
||||||
u32 gap_count:6;
|
u32 gap_count:6;
|
||||||
/* byte */
|
/* byte */
|
||||||
u32 speed:2;
|
u32 speed:2;
|
||||||
u32 phy_delay:2;
|
u32 phy_delay:2;
|
||||||
u32 contender:1;
|
u32 contender:1;
|
||||||
u32 power_class:3;
|
u32 power_class:3;
|
||||||
/* byte */
|
/* byte */
|
||||||
u32 port0:2;
|
u32 port0:2;
|
||||||
u32 port1:2;
|
u32 port1:2;
|
||||||
u32 port2:2;
|
u32 port2:2;
|
||||||
u32 initiated_reset:1;
|
u32 initiated_reset:1;
|
||||||
u32 more_packets:1;
|
u32 more_packets:1;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct ext_selfid {
|
struct ext_selfid {
|
||||||
u32 packet_identifier:2; /* always binary 10 */
|
u32 packet_identifier:2; /* always binary 10 */
|
||||||
u32 phy_id:6;
|
u32 phy_id:6;
|
||||||
/* byte */
|
/* byte */
|
||||||
u32 extended:1; /* if false is struct selfid */
|
u32 extended:1; /* if false is struct selfid */
|
||||||
u32 seq_nr:3;
|
u32 seq_nr:3;
|
||||||
u32 reserved:2;
|
u32 reserved:2;
|
||||||
u32 porta:2;
|
u32 porta:2;
|
||||||
/* byte */
|
/* byte */
|
||||||
u32 portb:2;
|
u32 portb:2;
|
||||||
u32 portc:2;
|
u32 portc:2;
|
||||||
u32 portd:2;
|
u32 portd:2;
|
||||||
u32 porte:2;
|
u32 porte:2;
|
||||||
/* byte */
|
/* byte */
|
||||||
u32 portf:2;
|
u32 portf:2;
|
||||||
u32 portg:2;
|
u32 portg:2;
|
||||||
u32 porth:2;
|
u32 porth:2;
|
||||||
u32 reserved2:1;
|
u32 reserved2:1;
|
||||||
u32 more_packets:1;
|
u32 more_packets:1;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
#elif defined __LITTLE_ENDIAN_BITFIELD /* __BIG_ENDIAN_BITFIELD */
|
#elif defined __LITTLE_ENDIAN_BITFIELD /* __BIG_ENDIAN_BITFIELD */
|
||||||
@@ -171,49 +172,48 @@ struct ext_selfid {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
struct selfid {
|
struct selfid {
|
||||||
u32 phy_id:6;
|
u32 phy_id:6;
|
||||||
u32 packet_identifier:2; /* always binary 10 */
|
u32 packet_identifier:2; /* always binary 10 */
|
||||||
/* byte */
|
/* byte */
|
||||||
u32 gap_count:6;
|
u32 gap_count:6;
|
||||||
u32 link_active:1;
|
u32 link_active:1;
|
||||||
u32 extended:1; /* if true is struct ext_selfid */
|
u32 extended:1; /* if true is struct ext_selfid */
|
||||||
/* byte */
|
/* byte */
|
||||||
u32 power_class:3;
|
u32 power_class:3;
|
||||||
u32 contender:1;
|
u32 contender:1;
|
||||||
u32 phy_delay:2;
|
u32 phy_delay:2;
|
||||||
u32 speed:2;
|
u32 speed:2;
|
||||||
/* byte */
|
/* byte */
|
||||||
u32 more_packets:1;
|
u32 more_packets:1;
|
||||||
u32 initiated_reset:1;
|
u32 initiated_reset:1;
|
||||||
u32 port2:2;
|
u32 port2:2;
|
||||||
u32 port1:2;
|
u32 port1:2;
|
||||||
u32 port0:2;
|
u32 port0:2;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct ext_selfid {
|
struct ext_selfid {
|
||||||
u32 phy_id:6;
|
u32 phy_id:6;
|
||||||
u32 packet_identifier:2; /* always binary 10 */
|
u32 packet_identifier:2; /* always binary 10 */
|
||||||
/* byte */
|
/* byte */
|
||||||
u32 porta:2;
|
u32 porta:2;
|
||||||
u32 reserved:2;
|
u32 reserved:2;
|
||||||
u32 seq_nr:3;
|
u32 seq_nr:3;
|
||||||
u32 extended:1; /* if false is struct selfid */
|
u32 extended:1; /* if false is struct selfid */
|
||||||
/* byte */
|
/* byte */
|
||||||
u32 porte:2;
|
u32 porte:2;
|
||||||
u32 portd:2;
|
u32 portd:2;
|
||||||
u32 portc:2;
|
u32 portc:2;
|
||||||
u32 portb:2;
|
u32 portb:2;
|
||||||
/* byte */
|
/* byte */
|
||||||
u32 more_packets:1;
|
u32 more_packets:1;
|
||||||
u32 reserved2:1;
|
u32 reserved2:1;
|
||||||
u32 porth:2;
|
u32 porth:2;
|
||||||
u32 portg:2;
|
u32 portg:2;
|
||||||
u32 portf:2;
|
u32 portf:2;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#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 @@
|
|||||||
#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)
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#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)
|
|||||||
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 */
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
|
|
||||||
#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 {
|
|||||||
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;
|
||||||
|
|
||||||
@@ -80,7 +82,7 @@ struct hpsb_packet {
|
|||||||
|
|
||||||
/* Set a task for when a packet completes */
|
/* Set a task for when a packet completes */
|
||||||
void hpsb_set_packet_complete_task(struct hpsb_packet *packet,
|
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)
|
static inline struct hpsb_packet *driver_packet(struct list_head *l)
|
||||||
{
|
{
|
||||||
@@ -92,7 +94,6 @@ void abort_timedouts(unsigned long __opaque);
|
|||||||
struct hpsb_packet *hpsb_alloc_packet(size_t data_size);
|
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,
|
|||||||
#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;
|
|||||||
extern struct class *hpsb_protocol_class;
|
extern struct class *hpsb_protocol_class;
|
||||||
|
|
||||||
#endif /* _IEEE1394_CORE_H */
|
#endif /* _IEEE1394_CORE_H */
|
||||||
|
|
||||||
|
|||||||
@@ -1,33 +1,19 @@
|
|||||||
#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 @@
|
|||||||
* 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 @@
|
|||||||
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,
|
|||||||
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,
|
|||||||
* 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);
|
|
||||||
|
|
||||||
if (unlikely(n == ALL_NODES))
|
/* NB: The macro wait_event_interruptible() is called with a condition
|
||||||
return 0;
|
* argument with side effect. This is only possible because the side
|
||||||
tp = &packet->host->tpool[n];
|
* effect does not occur until the condition became true, and
|
||||||
|
* wait_event_interruptible() won't evaluate the condition again after
|
||||||
if (irqs_disabled() || in_atomic()) {
|
* that. */
|
||||||
if (down_trylock(&tp->count))
|
return wait_event_interruptible(tlabel_wq,
|
||||||
return 1;
|
!hpsb_get_tlabel_atomic(packet));
|
||||||
} 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)
|
|||||||
*/
|
*/
|
||||||
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)
|
|||||||
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)
|
|||||||
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,
|
||||||
|
|||||||
@@ -1,32 +1,32 @@
|
|||||||
#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,
|
|||||||
*/
|
*/
|
||||||
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,
|
|||||||
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 */
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user