Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
356a8fd1
Commit
356a8fd1
authored
Mar 03, 2003
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://ldm.bkbits.net/linux-2.5-core
into home.transmeta.com:/home/torvalds/v2.5/linux
parents
3221c18e
2f1e7356
Changes
18
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
957 additions
and
374 deletions
+957
-374
Documentation/ioctl-number.txt
Documentation/ioctl-number.txt
+1
-0
drivers/ieee1394/amdtp.c
drivers/ieee1394/amdtp.c
+27
-2
drivers/ieee1394/dma.c
drivers/ieee1394/dma.c
+1
-0
drivers/ieee1394/dv1394.c
drivers/ieee1394/dv1394.c
+132
-5
drivers/ieee1394/eth1394.c
drivers/ieee1394/eth1394.c
+241
-25
drivers/ieee1394/eth1394.h
drivers/ieee1394/eth1394.h
+13
-0
drivers/ieee1394/hosts.c
drivers/ieee1394/hosts.c
+0
-3
drivers/ieee1394/ieee1394-ioctl.h
drivers/ieee1394/ieee1394-ioctl.h
+3
-3
drivers/ieee1394/ieee1394_core.c
drivers/ieee1394/ieee1394_core.c
+6
-8
drivers/ieee1394/ieee1394_transactions.c
drivers/ieee1394/ieee1394_transactions.c
+66
-1
drivers/ieee1394/ieee1394_transactions.h
drivers/ieee1394/ieee1394_transactions.h
+3
-0
drivers/ieee1394/ieee1394_types.h
drivers/ieee1394/ieee1394_types.h
+6
-3
drivers/ieee1394/nodemgr.c
drivers/ieee1394/nodemgr.c
+56
-1
drivers/ieee1394/ohci1394.c
drivers/ieee1394/ohci1394.c
+62
-47
drivers/ieee1394/raw1394.c
drivers/ieee1394/raw1394.c
+4
-5
drivers/ieee1394/sbp2.c
drivers/ieee1394/sbp2.c
+177
-235
drivers/ieee1394/sbp2.h
drivers/ieee1394/sbp2.h
+0
-30
drivers/ieee1394/video1394.c
drivers/ieee1394/video1394.c
+159
-6
No files found.
Documentation/ioctl-number.txt
View file @
356a8fd1
...
...
@@ -72,6 +72,7 @@ Code Seq# Include File Comments
linux/blkpg.h
0x20 all drivers/cdrom/cm206.h
0x22 all scsi/sg.h
'#' 00-3F IEEE 1394 Subsystem Block for the entire subsystem
'1' 00-1F <linux/timepps.h> PPS kit from Ulrich Windl
<ftp://ftp.de.kernel.org/pub/linux/daemons/ntp/PPS/>
'6' 00-10 <asm-i386/processor.h> Intel IA32 microcode update driver
...
...
drivers/ieee1394/amdtp.c
View file @
356a8fd1
...
...
@@ -74,6 +74,8 @@
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/poll.h>
#include <linux/ioctl32.h>
#include <linux/compat.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
...
...
@@ -1262,8 +1264,11 @@ MODULE_LICENSE("GPL");
static
int
__init
amdtp_init_module
(
void
)
{
if
(
ieee1394_register_chardev
(
IEEE1394_MINOR_BLOCK_AMDTP
,
THIS_MODULE
,
&
amdtp_fops
))
{
int
ret
;
ret
=
ieee1394_register_chardev
(
IEEE1394_MINOR_BLOCK_AMDTP
,
THIS_MODULE
,
&
amdtp_fops
);
if
(
ret
)
{
HPSB_ERR
(
"amdtp: unable to get minor device block"
);
return
-
EIO
;
}
...
...
@@ -1276,6 +1281,15 @@ static int __init amdtp_init_module (void)
return
-
EIO
;
}
#ifdef CONFIG_COMPAT
ret
=
register_ioctl32_conversion
(
AMDTP_IOC_CHANNEL
,
NULL
);
ret
|=
register_ioctl32_conversion
(
AMDTP_IOC_PLUG
,
NULL
);
ret
|=
register_ioctl32_conversion
(
AMDTP_IOC_PING
,
NULL
);
ret
|=
register_ioctl32_conversion
(
AMDTP_IOC_ZAP
,
NULL
);
if
(
ret
)
HPSB_ERR
(
"amdtp: Error registering ioctl32 translations"
);
#endif
HPSB_INFO
(
"Loaded AMDTP driver"
);
return
0
;
...
...
@@ -1283,6 +1297,17 @@ static int __init amdtp_init_module (void)
static
void
__exit
amdtp_exit_module
(
void
)
{
#ifdef CONFIG_COMPAT
int
ret
;
ret
=
unregister_ioctl32_conversion
(
AMDTP_IOC_CHANNEL
);
ret
|=
unregister_ioctl32_conversion
(
AMDTP_IOC_PLUG
);
ret
|=
unregister_ioctl32_conversion
(
AMDTP_IOC_PING
);
ret
|=
unregister_ioctl32_conversion
(
AMDTP_IOC_ZAP
);
if
(
ret
)
HPSB_ERR
(
"amdtp: Error unregistering ioctl32 translations"
);
#endif
hpsb_unregister_highlevel
(
amdtp_highlevel
);
ieee1394_unregister_chardev
(
IEEE1394_MINOR_BLOCK_AMDTP
);
...
...
drivers/ieee1394/dma.c
View file @
356a8fd1
...
...
@@ -10,6 +10,7 @@
#include <linux/module.h>
#include <linux/vmalloc.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include "dma.h"
/* dma_prog_region */
...
...
drivers/ieee1394/dv1394.c
View file @
356a8fd1
...
...
@@ -111,6 +111,8 @@
#include <linux/wrapper.h>
#include <linux/vmalloc.h>
#include <linux/string.h>
#include <linux/ioctl32.h>
#include <linux/compat.h>
#include "ieee1394.h"
#include "ieee1394_types.h"
...
...
@@ -2907,6 +2909,98 @@ static struct hpsb_highlevel_ops hl_ops = {
.
host_reset
=
dv1394_host_reset
,
};
#ifdef CONFIG_COMPAT
#define DV1394_IOC32_INIT _IOW('#', 0x06, struct dv1394_init32)
#define DV1394_IOC32_GET_STATUS _IOR('#', 0x0c, struct dv1394_status32)
struct
dv1394_init32
{
u32
api_version
;
u32
channel
;
u32
n_frames
;
u32
format
;
u32
cip_n
;
u32
cip_d
;
u32
syt_offset
;
};
struct
dv1394_status32
{
struct
dv1394_init32
init
;
s32
active_frame
;
u32
first_clear_frame
;
u32
n_clear_frames
;
u32
dropped_frames
;
};
static
int
handle_dv1394_init
(
unsigned
int
fd
,
unsigned
int
cmd
,
unsigned
long
arg
,
struct
file
*
file
)
{
struct
dv1394_init32
dv32
;
struct
dv1394_init
dv
;
mm_segment_t
old_fs
;
int
ret
;
if
(
file
->
f_op
->
ioctl
!=
dv1394_ioctl
)
return
-
EFAULT
;
if
(
copy_from_user
(
&
dv32
,
(
void
*
)
arg
,
sizeof
(
dv32
)))
return
-
EFAULT
;
dv
.
api_version
=
dv32
.
api_version
;
dv
.
channel
=
dv32
.
channel
;
dv
.
n_frames
=
dv32
.
n_frames
;
dv
.
format
=
dv32
.
format
;
dv
.
cip_n
=
(
unsigned
long
)
dv32
.
cip_n
;
dv
.
cip_d
=
(
unsigned
long
)
dv32
.
cip_d
;
dv
.
syt_offset
=
dv32
.
syt_offset
;
old_fs
=
get_fs
();
set_fs
(
KERNEL_DS
);
ret
=
dv1394_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
DV1394_IOC_INIT
,
(
unsigned
long
)
&
dv
);
set_fs
(
old_fs
);
return
ret
;
}
static
int
handle_dv1394_get_status
(
unsigned
int
fd
,
unsigned
int
cmd
,
unsigned
long
arg
,
struct
file
*
file
)
{
struct
dv1394_status32
dv32
;
struct
dv1394_status
dv
;
mm_segment_t
old_fs
;
int
ret
;
if
(
file
->
f_op
->
ioctl
!=
dv1394_ioctl
)
return
-
EFAULT
;
old_fs
=
get_fs
();
set_fs
(
KERNEL_DS
);
ret
=
dv1394_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
DV1394_IOC_GET_STATUS
,
(
unsigned
long
)
&
dv
);
set_fs
(
old_fs
);
if
(
!
ret
)
{
dv32
.
init
.
api_version
=
dv
.
init
.
api_version
;
dv32
.
init
.
channel
=
dv
.
init
.
channel
;
dv32
.
init
.
n_frames
=
dv
.
init
.
n_frames
;
dv32
.
init
.
format
=
dv
.
init
.
format
;
dv32
.
init
.
cip_n
=
(
u32
)
dv
.
init
.
cip_n
;
dv32
.
init
.
cip_d
=
(
u32
)
dv
.
init
.
cip_d
;
dv32
.
init
.
syt_offset
=
dv
.
init
.
syt_offset
;
dv32
.
active_frame
=
dv
.
active_frame
;
dv32
.
first_clear_frame
=
dv
.
first_clear_frame
;
dv32
.
n_clear_frames
=
dv
.
n_clear_frames
;
dv32
.
dropped_frames
=
dv
.
dropped_frames
;
if
(
copy_to_user
((
struct
dv1394_status32
*
)
arg
,
&
dv32
,
sizeof
(
dv32
)))
ret
=
-
EFAULT
;
}
return
ret
;
}
#endif
/* CONFIG_COMPAT */
/*** KERNEL MODULE HANDLERS ************************************************/
...
...
@@ -2917,6 +3011,20 @@ MODULE_LICENSE("GPL");
static
void
__exit
dv1394_exit_module
(
void
)
{
#ifdef CONFIG_COMPAT
int
ret
;
ret
=
unregister_ioctl32_conversion
(
DV1394_IOC_SHUTDOWN
);
ret
|=
unregister_ioctl32_conversion
(
DV1394_IOC_SUBMIT_FRAMES
);
ret
|=
unregister_ioctl32_conversion
(
DV1394_IOC_WAIT_FRAMES
);
ret
|=
unregister_ioctl32_conversion
(
DV1394_IOC_RECEIVE_FRAMES
);
ret
|=
unregister_ioctl32_conversion
(
DV1394_IOC_START_RECEIVE
);
ret
|=
unregister_ioctl32_conversion
(
DV1394_IOC32_INIT
);
ret
|=
unregister_ioctl32_conversion
(
DV1394_IOC32_GET_STATUS
);
if
(
ret
)
printk
(
KERN_ERR
"dv1394: Error unregistering ioctl32 translations
\n
"
);
#endif
hpsb_unregister_highlevel
(
hl_handle
);
ieee1394_unregister_chardev
(
IEEE1394_MINOR_BLOCK_DV1394
);
#ifdef CONFIG_DEVFS_FS
...
...
@@ -2929,14 +3037,18 @@ static void __exit dv1394_exit_module(void)
static
int
__init
dv1394_init_module
(
void
)
{
if
(
ieee1394_register_chardev
(
IEEE1394_MINOR_BLOCK_DV1394
,
THIS_MODULE
,
&
dv1394_fops
))
{
int
ret
;
ret
=
ieee1394_register_chardev
(
IEEE1394_MINOR_BLOCK_DV1394
,
THIS_MODULE
,
&
dv1394_fops
);
if
(
ret
)
{
printk
(
KERN_ERR
"dv1394: unable to register character device
\n
"
);
return
-
EIO
;
}
#ifdef CONFIG_DEVFS_FS
if
(
dv1394_devfs_add_dir
(
"dv"
,
NULL
,
NULL
)
<
0
)
{
ret
=
dv1394_devfs_add_dir
(
"dv"
,
NULL
,
NULL
);
if
(
ret
<
0
)
{
printk
(
KERN_ERR
"dv1394: unable to create /dev/ieee1394/dv
\n
"
);
ieee1394_unregister_chardev
(
IEEE1394_MINOR_BLOCK_DV1394
);
return
-
ENOMEM
;
...
...
@@ -2944,7 +3056,8 @@ static int __init dv1394_init_module(void)
#endif
#ifdef CONFIG_PROC_FS
if
(
dv1394_procfs_add_dir
(
"dv"
,
NULL
,
NULL
)
<
0
)
{
ret
=
dv1394_procfs_add_dir
(
"dv"
,
NULL
,
NULL
);
if
(
ret
<
0
)
{
printk
(
KERN_ERR
"dv1394: unable to create /proc/bus/ieee1394/dv
\n
"
);
ieee1394_unregister_chardev
(
IEEE1394_MINOR_BLOCK_DV1394
);
#ifdef CONFIG_DEVFS_FS
...
...
@@ -2967,9 +3080,23 @@ static int __init dv1394_init_module(void)
return
-
ENOMEM
;
}
#ifdef CONFIG_COMPAT
/* First compatible ones */
ret
=
register_ioctl32_conversion
(
DV1394_IOC_SHUTDOWN
,
NULL
);
ret
|=
register_ioctl32_conversion
(
DV1394_IOC_SUBMIT_FRAMES
,
NULL
);
ret
|=
register_ioctl32_conversion
(
DV1394_IOC_WAIT_FRAMES
,
NULL
);
ret
|=
register_ioctl32_conversion
(
DV1394_IOC_RECEIVE_FRAMES
,
NULL
);
ret
|=
register_ioctl32_conversion
(
DV1394_IOC_START_RECEIVE
,
NULL
);
/* These need to be handled by translation */
ret
|=
register_ioctl32_conversion
(
DV1394_IOC32_INIT
,
handle_dv1394_init
);
ret
|=
register_ioctl32_conversion
(
DV1394_IOC32_GET_STATUS
,
handle_dv1394_get_status
);
if
(
ret
)
printk
(
KERN_ERR
"dv1394: Error registering ioctl32 translations
\n
"
);
#endif
return
0
;
}
module_init
(
dv1394_init_module
);
module_exit
(
dv1394_exit_module
);
drivers/ieee1394/eth1394.c
View file @
356a8fd1
...
...
@@ -65,6 +65,7 @@
#include "ieee1394_transactions.h"
#include "ieee1394.h"
#include "highlevel.h"
#include "iso.h"
#include "eth1394.h"
#define ETH1394_PRINT_G(level, fmt, args...) \
...
...
@@ -77,7 +78,7 @@
printk(KERN_ERR fmt, ## args)
static
char
version
[]
__devinitdata
=
"$Rev:
770
$ Ben Collins <bcollins@debian.org>"
;
"$Rev:
801
$ Ben Collins <bcollins@debian.org>"
;
/* Our ieee1394 highlevel driver */
#define ETHER1394_DRIVER_NAME "ether1394"
...
...
@@ -101,6 +102,9 @@ MODULE_AUTHOR("Ben Collins (bcollins@debian.org)");
MODULE_DESCRIPTION
(
"IEEE 1394 IPv4 Driver (IPv4-over-1394 as per RFC 2734)"
);
MODULE_LICENSE
(
"GPL"
);
static
void
ether1394_iso
(
struct
hpsb_iso
*
iso
);
/* Find our host_info struct for a given host pointer. Must be called
* under spinlock. */
static
inline
struct
host_info
*
find_host_info
(
struct
hpsb_host
*
host
)
...
...
@@ -178,15 +182,26 @@ static void ether1394_tx_timeout (struct net_device *dev)
* XXX: This is where we need to create a list of skb's for fragmented
* packets. */
static
inline
void
ether1394_encapsulate
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
,
int
proto
)
int
proto
,
struct
packet_task
*
ptask
)
{
union
eth1394_hdr
*
hdr
=
(
union
eth1394_hdr
*
)
skb_push
(
skb
,
hdr_type_len
[
ETH1394_HDR_LF_UF
]);
hdr
->
words
.
word1
=
0
;
hdr
->
common
.
lf
=
ETH1394_HDR_LF_UF
;
hdr
->
words
.
word1
=
htons
(
hdr
->
words
.
word1
);
hdr
->
uf
.
ether_type
=
proto
;
/* Set the transmission type for the packet. Right now only ARP
* packets are sent via GASP. IP broadcast and IP multicast are not
* yet supported properly, they too should use GASP. */
switch
(
proto
)
{
case
__constant_htons
(
ETH_P_ARP
):
ptask
->
tx_type
=
ETH1394_GASP
;
break
;
default:
ptask
->
tx_type
=
ETH1394_WRREQ
;
}
return
;
}
...
...
@@ -199,7 +214,7 @@ static inline void ether1394_arp_to_1394arp (struct sk_buff *skb, struct net_dev
{
struct
eth1394_priv
*
priv
=
(
struct
eth1394_priv
*
)(
dev
->
priv
);
u16
phy_id
=
priv
->
host
->
node_id
&
NODE_MASK
;
u16
phy_id
=
NODEID_TO_NODE
(
priv
->
host
->
node_id
)
;
unsigned
char
*
arp_ptr
=
(
unsigned
char
*
)
skb
->
data
;
struct
eth1394_arp
*
arp1394
=
(
struct
eth1394_arp
*
)
skb
->
data
;
...
...
@@ -279,7 +294,8 @@ static void ether1394_reset_priv (struct net_device *dev, int set_mtu)
{
unsigned
long
flags
;
struct
eth1394_priv
*
priv
=
(
struct
eth1394_priv
*
)
dev
->
priv
;
int
phy_id
=
priv
->
host
->
node_id
&
NODE_MASK
;
int
phy_id
=
NODEID_TO_NODE
(
priv
->
host
->
node_id
);
struct
hpsb_host
*
host
=
priv
->
host
;
spin_lock_irqsave
(
&
priv
->
lock
,
flags
);
...
...
@@ -289,20 +305,23 @@ static void ether1394_reset_priv (struct net_device *dev, int set_mtu)
memset
(
priv
->
fifo_hi
,
0
,
sizeof
(
priv
->
fifo_hi
));
memset
(
priv
->
fifo_lo
,
0
,
sizeof
(
priv
->
fifo_lo
));
priv
->
bc_state
=
ETHER1394_BC_CHECK
;
/* Register our limits now */
ether1394_register_limits
(
phy_id
,
(
be32_to_cpu
(
priv
->
host
->
csr
.
rom
[
2
])
>>
12
)
&
0xf
,
priv
->
host
->
speed_map
[(
phy_id
<<
6
)
+
phy_id
],
(
u64
)(((
u64
)
be32_to_cpu
(
priv
->
host
->
csr
.
rom
[
3
])
<<
32
)
|
be32_to_cpu
(
priv
->
host
->
csr
.
rom
[
4
])),
ether1394_register_limits
(
phy_id
,
(
be32_to_cpu
(
host
->
csr
.
rom
[
2
])
>>
12
)
&
0xf
,
host
->
speed_map
[(
phy_id
<<
6
)
+
phy_id
],
(
u64
)(((
u64
)
be32_to_cpu
(
host
->
csr
.
rom
[
3
])
<<
32
)
|
be32_to_cpu
(
host
->
csr
.
rom
[
4
])),
ETHER1394_REGION_ADDR
>>
32
,
ETHER1394_REGION_ADDR
&
0xffffffff
,
priv
);
/* We'll use our max_rec as the default mtu */
if
(
set_mtu
)
dev
->
mtu
=
(
1
<<
(
priv
->
max_rec
[
phy_id
]
+
1
))
-
sizeof
(
union
eth1394_hdr
);
dev
->
mtu
=
(
1
<<
(
priv
->
max_rec
[
phy_id
]
+
1
))
-
/* mtu = max_rec - */
(
sizeof
(
union
eth1394_hdr
)
+
8
);
/* (hdr + GASP) */
/* Set our hardware address while we're at it */
*
(
nodeid_t
*
)
dev
->
dev_addr
=
htons
(
priv
->
host
->
node_id
);
*
(
nodeid_t
*
)
dev
->
dev_addr
=
htons
(
host
->
node_id
);
spin_unlock_irqrestore
(
&
priv
->
lock
,
flags
);
}
...
...
@@ -383,6 +402,15 @@ static void ether1394_add_host (struct hpsb_host *host)
list_add_tail
(
&
hi
->
list
,
&
host_info_list
);
spin_unlock_irq
(
&
host_info_lock
);
/* Ignore validity in hopes that it will be set in the future. It'll
* check it on transmit. */
priv
->
broadcast_channel
=
host
->
csr
.
broadcast_channel
&
0x3f
;
priv
->
iso
=
hpsb_iso_recv_init
(
host
,
8
*
4096
,
8
,
priv
->
broadcast_channel
,
1
,
ether1394_iso
);
if
(
priv
->
iso
==
NULL
)
{
priv
->
bc_state
=
ETHER1394_BC_CLOSED
;
}
return
;
out:
...
...
@@ -396,11 +424,14 @@ static void ether1394_add_host (struct hpsb_host *host)
/* Remove a card from our list */
static
void
ether1394_remove_host
(
struct
hpsb_host
*
host
)
{
struct
eth1394_priv
*
priv
;
struct
host_info
*
hi
;
spin_lock_irq
(
&
host_info_lock
);
hi
=
find_host_info
(
host
);
if
(
hi
!=
NULL
)
{
priv
=
(
struct
eth1394_priv
*
)
hi
->
dev
->
priv
;
priv
->
bc_state
=
ETHER1394_BC_CLOSED
;
unregister_netdev
(
hi
->
dev
);
kfree
(
hi
->
dev
);
list_del
(
&
hi
->
list
);
...
...
@@ -480,7 +511,7 @@ static inline unsigned short ether1394_parse_encap (struct sk_buff *skb, struct
* about the sending machine. */
if
(
hdr
->
uf
.
ether_type
==
__constant_htons
(
ETH_P_ARP
))
{
unsigned
long
flags
;
u16
phy_id
=
srcid
&
NODE_MASK
;
u16
phy_id
=
NODEID_TO_NODE
(
srcid
)
;
struct
eth1394_priv
*
priv
=
(
struct
eth1394_priv
*
)
dev
->
priv
;
struct
eth1394_arp
arp1394
;
...
...
@@ -591,6 +622,104 @@ static int ether1394_write (struct hpsb_host *host, int srcid, int destid,
return
RCODE_COMPLETE
;
}
static
void
ether1394_iso
(
struct
hpsb_iso
*
iso
)
{
struct
sk_buff
*
skb
;
quadlet_t
*
data
;
char
*
buf
;
int
flags
;
struct
net_device
*
dev
=
ether1394_find_dev
(
iso
->
host
);
struct
eth1394_priv
*
priv
;
unsigned
int
len
;
u32
specifier_id
;
u16
source_id
;
int
i
;
int
nready
;
if
(
dev
==
NULL
)
{
ETH1394_PRINT_G
(
KERN_ERR
,
"Could not find net device for host %s
\n
"
,
iso
->
host
->
driver
->
name
);
return
;
}
nready
=
hpsb_iso_n_ready
(
iso
);
for
(
i
=
0
;
i
<
nready
;
i
++
)
{
struct
hpsb_iso_packet_info
*
info
=
&
iso
->
infos
[
iso
->
first_packet
+
i
];
data
=
(
quadlet_t
*
)
(
iso
->
data_buf
.
kvirt
+
info
->
offset
);
/* skip over GASP header */
buf
=
(
char
*
)
data
+
8
;
len
=
info
->
len
-
8
;
specifier_id
=
(((
be32_to_cpu
(
data
[
0
])
&
0xffff
)
<<
8
)
|
((
be32_to_cpu
(
data
[
1
])
&
0xff000000
)
>>
24
));
source_id
=
be32_to_cpu
(
data
[
0
])
>>
16
;
priv
=
(
struct
eth1394_priv
*
)
dev
->
priv
;
if
(
info
->
channel
!=
priv
->
broadcast_channel
||
specifier_id
!=
ETHER1394_GASP_SPECIFIER_ID
)
{
/* This packet is not for us */
continue
;
}
/* A packet has been received by the ieee1394 bus. Build an skbuff
* around it so we can pass it to the high level network layer. */
skb
=
dev_alloc_skb
(
len
+
dev
->
hard_header_len
+
15
);
if
(
!
skb
)
{
HPSB_PRINT
(
KERN_ERR
,
"ether1394 rx: low on mem
\n
"
);
priv
->
stats
.
rx_dropped
++
;
break
;
}
skb_reserve
(
skb
,
(
dev
->
hard_header_len
+
15
)
&
~
15
);
memcpy
(
skb_put
(
skb
,
len
),
buf
,
len
);
/* Write metadata, and then pass to the receive level */
skb
->
dev
=
dev
;
skb
->
ip_summed
=
CHECKSUM_UNNECESSARY
;
/* don't check it */
/* Parse the encapsulation header. This actually does the job of
* converting to an ethernet frame header, aswell as arp
* conversion if needed. ARP conversion is easier in this
* direction, since we are using ethernet as our backend. */
skb
->
protocol
=
ether1394_parse_encap
(
skb
,
dev
,
source_id
,
LOCAL_BUS
|
ALL_NODES
);
spin_lock_irqsave
(
&
priv
->
lock
,
flags
);
if
(
!
skb
->
protocol
)
{
priv
->
stats
.
rx_errors
++
;
priv
->
stats
.
rx_dropped
++
;
dev_kfree_skb_any
(
skb
);
goto
bad_proto
;
}
netif_stop_queue
(
dev
);
if
(
netif_rx
(
skb
)
==
NET_RX_DROP
)
{
priv
->
stats
.
rx_errors
++
;
priv
->
stats
.
rx_dropped
++
;
goto
bad_proto
;
}
/* Statistics */
priv
->
stats
.
rx_packets
++
;
priv
->
stats
.
rx_bytes
+=
skb
->
len
;
bad_proto:
spin_unlock_irqrestore
(
&
priv
->
lock
,
flags
);
}
hpsb_iso_recv_release_packets
(
iso
,
i
);
netif_start_queue
(
dev
);
dev
->
last_rx
=
jiffies
;
return
;
}
/* This function is our scheduled write */
static
void
hpsb_write_sched
(
void
*
__ptask
)
{
...
...
@@ -598,13 +727,26 @@ static void hpsb_write_sched (void *__ptask)
struct
sk_buff
*
skb
=
ptask
->
skb
;
struct
net_device
*
dev
=
ptask
->
skb
->
dev
;
struct
eth1394_priv
*
priv
=
(
struct
eth1394_priv
*
)
dev
->
priv
;
unsigned
long
flags
;
unsigned
long
flags
;
int
status
;
if
(
ptask
->
tx_type
==
ETH1394_GASP
)
{
status
=
hpsb_send_gasp
(
priv
->
host
,
priv
->
broadcast_channel
,
get_hpsb_generation
(
priv
->
host
),
(
quadlet_t
*
)
skb
->
data
,
skb
->
len
,
ETHER1394_GASP_SPECIFIER_ID
,
ETHER1394_GASP_VERSION
);
}
else
{
status
=
hpsb_write
(
priv
->
host
,
ptask
->
dest_node
,
get_hpsb_generation
(
priv
->
host
),
ptask
->
addr
,
(
quadlet_t
*
)
skb
->
data
,
skb
->
len
);
}
/* Statistics */
spin_lock_irqsave
(
&
priv
->
lock
,
flags
);
if
(
!
hpsb_write
(
priv
->
host
,
ptask
->
dest_node
,
get_hpsb_generation
(
priv
->
host
),
ptask
->
addr
,
(
quadlet_t
*
)
skb
->
data
,
skb
->
len
))
{
if
(
!
status
)
{
priv
->
stats
.
tx_bytes
+=
skb
->
len
;
priv
->
stats
.
tx_packets
++
;
}
else
{
...
...
@@ -636,6 +778,67 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev)
struct
packet_task
*
ptask
=
NULL
;
int
ret
=
0
;
spin_lock_irqsave
(
&
priv
->
lock
,
flags
);
if
(
priv
->
bc_state
==
ETHER1394_BC_CLOSED
)
{
ETH1394_PRINT
(
KERN_ERR
,
dev
->
name
,
"Cannot send packet, no broadcast channel available."
);
ret
=
-
EAGAIN
;
goto
fail
;
}
/* First time sending? Need a broadcast channel for ARP and for
* listening on */
if
(
priv
->
bc_state
==
ETHER1394_BC_CHECK
)
{
quadlet_t
bc
;
/* Get the local copy of the broadcast channel and check its
* validity (the IRM should validate it for us) */
bc
=
priv
->
host
->
csr
.
broadcast_channel
;
if
((
bc
&
0xc0000000
)
!=
0xc0000000
)
{
/* broadcast channel not validated yet */
ETH1394_PRINT
(
KERN_WARNING
,
dev
->
name
,
"Error BROADCAST_CHANNEL register valid "
"bit not set, can't send IP traffic
\n
"
);
hpsb_iso_shutdown
(
priv
->
iso
);
priv
->
bc_state
=
ETHER1394_BC_CLOSED
;
ret
=
-
EAGAIN
;
spin_unlock_irqrestore
(
&
priv
->
lock
,
flags
);
goto
fail
;
}
if
(
priv
->
broadcast_channel
!=
(
bc
&
0x3f
))
{
/* This really shouldn't be possible, but just in case
* the IEEE 1394 spec changes regarding broadcast
* channels in the future. */
hpsb_iso_shutdown
(
priv
->
iso
);
priv
->
broadcast_channel
=
bc
&
0x3f
;
ETH1394_PRINT
(
KERN_WARNING
,
dev
->
name
,
"Changing to broadcast channel %d...
\n
"
,
priv
->
broadcast_channel
);
priv
->
iso
=
hpsb_iso_recv_init
(
priv
->
host
,
8
*
4096
,
8
,
priv
->
broadcast_channel
,
1
,
ether1394_iso
);
if
(
priv
->
iso
==
NULL
)
{
ret
=
-
EAGAIN
;
goto
fail
;
}
}
if
(
hpsb_iso_recv_start
(
priv
->
iso
,
-
1
,
(
1
<<
3
),
-
1
)
<
0
)
{
ETH1394_PRINT
(
KERN_ERR
,
dev
->
name
,
"Could not start async reception
\n
"
);
hpsb_iso_shutdown
(
priv
->
iso
);
priv
->
bc_state
=
ETHER1394_BC_CLOSED
;
ret
=
-
EAGAIN
;
spin_unlock_irqrestore
(
&
priv
->
lock
,
flags
);
goto
fail
;
}
priv
->
bc_state
=
ETHER1394_BC_OPENED
;
}
spin_unlock_irqrestore
(
&
priv
->
lock
,
flags
);
if
((
skb
=
skb_share_check
(
skb
,
kmflags
))
==
NULL
)
{
ret
=
-
ENOMEM
;
goto
fail
;
...
...
@@ -654,8 +857,14 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev)
if
(
proto
==
__constant_htons
(
ETH_P_ARP
))
ether1394_arp_to_1394arp
(
skb
,
dev
);
ptask
=
kmem_cache_alloc
(
packet_task_cache
,
kmflags
);
if
(
ptask
==
NULL
)
{
ret
=
-
ENOMEM
;
goto
fail
;
}
/* Now add our encapsulation header */
ether1394_encapsulate
(
skb
,
dev
,
proto
);
ether1394_encapsulate
(
skb
,
dev
,
proto
,
ptask
);
/* TODO: The above encapsulate function needs to recognize when a
* packet needs to be split for a specified node. It should create
...
...
@@ -667,19 +876,13 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev)
* need this hack. */
spin_lock_irqsave
(
&
priv
->
lock
,
flags
);
addr
=
(
u64
)
priv
->
fifo_hi
[
dest_node
&
NODE_MASK
]
<<
32
|
priv
->
fifo_lo
[
dest_node
&
NODE_MASK
];
addr
=
(
u64
)
priv
->
fifo_hi
[
NODEID_TO_NODE
(
dest_node
)
]
<<
32
|
priv
->
fifo_lo
[
NODEID_TO_NODE
(
dest_node
)
];
spin_unlock_irqrestore
(
&
priv
->
lock
,
flags
);
if
(
!
addr
)
addr
=
ETHER1394_REGION_ADDR
;
ptask
=
kmem_cache_alloc
(
packet_task_cache
,
kmflags
);
if
(
ptask
==
NULL
)
{
ret
=
-
ENOMEM
;
goto
fail
;
}
ptask
->
skb
=
skb
;
ptask
->
addr
=
addr
;
ptask
->
dest_node
=
dest_node
;
...
...
@@ -702,7 +905,7 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev)
netif_wake_queue
(
dev
);
spin_unlock_irqrestore
(
&
priv
->
lock
,
flags
);
return
ret
;
return
0
;
/* returning non-zero causes serious problems */
}
/* Function for incoming 1394 packets */
...
...
@@ -738,6 +941,19 @@ static int __init ether1394_init_module (void)
static
void
__exit
ether1394_exit_module
(
void
)
{
struct
list_head
*
lh
;
struct
host_info
*
hi
;
struct
eth1394_priv
*
priv
;
lh
=
host_info_list
.
next
;
while
(
lh
!=
&
host_info_list
)
{
hi
=
list_entry
(
lh
,
struct
host_info
,
list
);
priv
=
(
struct
eth1394_priv
*
)
hi
->
dev
->
priv
;
if
(
priv
->
bc_state
!=
ETHER1394_BC_CLOSED
)
{
hpsb_iso_shutdown
(
priv
->
iso
);
}
lh
=
lh
->
next
;
}
hpsb_unregister_highlevel
(
hl_handle
);
kmem_cache_destroy
(
packet_task_cache
);
}
...
...
drivers/ieee1394/eth1394.h
View file @
356a8fd1
...
...
@@ -30,9 +30,16 @@
#define ETHER1394_REGION_ADDR 0xfffff0200000ULL
#define ETHER1394_REGION_ADDR_END (ETHER1394_REGION_ADDR + ETHER1394_REGION_ADDR_LEN)
/* GASP identifier numbers for IPv4 over IEEE 1394 */
#define ETHER1394_GASP_SPECIFIER_ID 0x00005E
#define ETHER1394_GASP_VERSION 1
/* Node set == 64 */
#define NODE_SET (ALL_NODES + 1)
enum
eth1394_bc_states
{
ETHER1394_BC_CLOSED
,
ETHER1394_BC_OPENED
,
ETHER1394_BC_CHECK
};
/* Private structure for our ethernet driver */
struct
eth1394_priv
{
struct
net_device_stats
stats
;
/* Device stats */
...
...
@@ -43,6 +50,9 @@ struct eth1394_priv {
u32
fifo_lo
[
ALL_NODES
];
/* 32bit lo fifo offset per node */
u64
eui
[
ALL_NODES
];
/* EUI-64 per node */
spinlock_t
lock
;
/* Private lock */
int
broadcast_channel
;
/* Async stream Broadcast Channel */
enum
eth1394_bc_states
bc_state
;
/* broadcast channel state */
struct
hpsb_iso
*
iso
;
/* Async stream recv handle */
};
struct
host_info
{
...
...
@@ -51,12 +61,15 @@ struct host_info {
struct
net_device
*
dev
;
};
typedef
enum
{
ETH1394_GASP
,
ETH1394_WRREQ
}
eth1394_tx_type
;
/* This is our task struct. It's used for the packet complete callback. */
struct
packet_task
{
struct
sk_buff
*
skb
;
/* Socket buffer we are sending */
nodeid_t
dest_node
;
/* Destination of the packet */
u64
addr
;
/* Address */
struct
hpsb_queue_struct
tq
;
/* The task */
eth1394_tx_type
tx_type
;
/* Send data via GASP or Write Req. */
};
/* IP1394 headers */
...
...
drivers/ieee1394/hosts.c
View file @
356a8fd1
...
...
@@ -71,9 +71,6 @@ int hpsb_ref_host(struct hpsb_host *host)
list_for_each
(
lh
,
&
hosts
)
{
if
(
host
==
list_entry
(
lh
,
struct
hpsb_host
,
host_list
))
{
if
(
try_module_get
(
host
->
driver
->
owner
))
{
/* we're doing this twice and don't seem
to undo it.. --hch */
(
void
)
try_module_get
(
host
->
driver
->
owner
);
host
->
refcount
++
;
retval
=
1
;
}
...
...
drivers/ieee1394/ieee1394-ioctl.h
View file @
356a8fd1
...
...
@@ -4,8 +4,8 @@
#ifndef __IEEE1394_IOCTL_H
#define __IEEE1394_IOCTL_H
#include <
asm
/ioctl.h>
#include <
asm
/types.h>
#include <
linux
/ioctl.h>
#include <
linux
/types.h>
/* AMDTP Gets 6 */
...
...
@@ -91,7 +91,7 @@
#define RAW1394_IOC_ISO_RECV_UNLISTEN_CHANNEL \
_IOW ('#', 0x23, unsigned char)
#define RAW1394_IOC_ISO_RECV_SET_CHANNEL_MASK \
_IOW ('#', 0x24, u64)
_IOW ('#', 0x24,
__
u64)
#define RAW1394_IOC_ISO_RECV_PACKETS \
_IOW ('#', 0x25, struct raw1394_iso_packets)
#define RAW1394_IOC_ISO_RECV_RELEASE_PACKETS \
...
...
drivers/ieee1394/ieee1394_core.c
View file @
356a8fd1
...
...
@@ -361,7 +361,7 @@ void hpsb_selfid_received(struct hpsb_host *host, quadlet_t sid)
host
->
topology_map
[
host
->
selfid_count
++
]
=
sid
;
}
else
{
HPSB_NOTICE
(
"Spurious SelfID packet (0x%08x) received from bus %d"
,
sid
,
(
host
->
node_id
&
BUS_MASK
)
>>
6
);
sid
,
NODEID_TO_BUS
(
host
->
node_id
)
);
}
}
...
...
@@ -396,9 +396,6 @@ void hpsb_selfid_complete(struct hpsb_host *host, int phyid, int isroot)
/* irm_id is kept up to date by check_selfids() */
if
(
host
->
irm_id
==
host
->
node_id
)
{
host
->
is_irm
=
1
;
host
->
is_busmgr
=
1
;
host
->
busmgr_id
=
host
->
node_id
;
host
->
csr
.
bus_manager_id
=
host
->
node_id
;
}
else
{
host
->
is_busmgr
=
0
;
host
->
is_irm
=
0
;
...
...
@@ -535,8 +532,8 @@ int hpsb_send_packet(struct hpsb_packet *packet)
if
(
packet
->
type
==
hpsb_async
&&
packet
->
node_id
!=
ALL_NODES
)
{
packet
->
speed_code
=
host
->
speed_map
[
(
host
->
node_id
&
NODE_MASK
)
*
64
+
(
packet
->
node_id
&
NODE_MASK
)];
host
->
speed_map
[
NODEID_TO_NODE
(
host
->
node_id
)
*
64
+
NODEID_TO_NODE
(
packet
->
node_id
)];
}
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
...
...
@@ -748,7 +745,7 @@ static void handle_incoming_packet(struct hpsb_host *host, int tcode,
addr
,
4
,
flags
);
if
(
!
write_acked
&&
(
((
data
[
0
]
>>
16
)
&
NODE_MASK
)
!=
NODE_MASK
)
&&
(
NODEID_TO_NODE
(
data
[
0
]
>>
16
)
!=
NODE_MASK
)
&&
(
rcode
>=
0
))
{
/* not a broadcast write, reply */
PREP_REPLY_PACKET
(
0
);
...
...
@@ -763,7 +760,7 @@ static void handle_incoming_packet(struct hpsb_host *host, int tcode,
addr
,
data
[
3
]
>>
16
,
flags
);
if
(
!
write_acked
&&
(
((
data
[
0
]
>>
16
)
&
NODE_MASK
)
!=
NODE_MASK
)
&&
(
NODEID_TO_NODE
(
data
[
0
]
>>
16
)
!=
NODE_MASK
)
&&
(
rcode
>=
0
))
{
/* not a broadcast write, reply */
PREP_REPLY_PACKET
(
0
);
...
...
@@ -1248,6 +1245,7 @@ EXPORT_SYMBOL(hpsb_read);
EXPORT_SYMBOL
(
hpsb_write
);
EXPORT_SYMBOL
(
hpsb_lock
);
EXPORT_SYMBOL
(
hpsb_lock64
);
EXPORT_SYMBOL
(
hpsb_send_gasp
);
EXPORT_SYMBOL
(
hpsb_packet_success
);
/** highlevel.c **/
...
...
drivers/ieee1394/ieee1394_transactions.c
View file @
356a8fd1
...
...
@@ -98,6 +98,17 @@ static void fill_phy_packet(struct hpsb_packet *packet, quadlet_t data)
packet
->
speed_code
=
SPEED_100
;
/* Force speed to be 100Mbps */
}
static
void
fill_async_stream_packet
(
struct
hpsb_packet
*
packet
,
int
length
,
int
channel
,
int
tag
,
int
sync
)
{
packet
->
header
[
0
]
=
(
length
<<
16
)
|
(
tag
<<
14
)
|
(
channel
<<
8
)
|
(
TCODE_STREAM_DATA
<<
4
)
|
sync
;
packet
->
header_size
=
4
;
packet
->
data_size
=
length
;
packet
->
type
=
hpsb_async
;
packet
->
tcode
=
TCODE_ISO_DATA
;
}
/**
* hpsb_get_tlabel - allocate a transaction label
...
...
@@ -495,7 +506,6 @@ int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation,
}
/* We need a hpsb_lock64 function for the 64 bit equivalent. Probably. */
int
hpsb_lock
(
struct
hpsb_host
*
host
,
nodeid_t
node
,
unsigned
int
generation
,
u64
addr
,
int
extcode
,
quadlet_t
*
data
,
quadlet_t
arg
)
{
...
...
@@ -558,3 +568,58 @@ int hpsb_lock64(struct hpsb_host *host, nodeid_t node, unsigned int generation,
return
retval
;
}
int
hpsb_send_gasp
(
struct
hpsb_host
*
host
,
int
channel
,
unsigned
int
generation
,
quadlet_t
*
buffer
,
size_t
length
,
u32
specifier_id
,
unsigned
int
version
)
{
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
int
i
;
#endif
struct
hpsb_packet
*
packet
;
int
retval
=
0
;
u16
specifier_id_hi
=
(
specifier_id
&
0x00ffff00
)
>>
8
;
u8
specifier_id_lo
=
specifier_id
&
0xff
;
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
HPSB_DEBUG
(
"Send GASP: channel = %d, length = %d"
,
channel
,
length
);
#endif
length
+=
8
;
packet
=
alloc_hpsb_packet
(
length
+
(
length
%
4
?
4
-
(
length
%
4
)
:
0
));
if
(
!
packet
)
return
-
ENOMEM
;
if
(
length
%
4
)
{
packet
->
data
[
length
/
4
]
=
0
;
}
packet
->
host
=
host
;
fill_async_stream_packet
(
packet
,
length
,
channel
,
3
,
0
);
packet
->
data
[
0
]
=
cpu_to_be32
((
host
->
node_id
<<
16
)
|
specifier_id_hi
);
packet
->
data
[
1
]
=
cpu_to_be32
((
specifier_id_lo
<<
24
)
|
(
version
&
0x00ffffff
));
memcpy
(
&
(
packet
->
data
[
2
]),
buffer
,
length
-
4
);
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
HPSB_DEBUG
(
"GASP: packet->header_size = %d"
,
packet
->
header_size
);
HPSB_DEBUG
(
"GASP: packet->data_size = %d"
,
packet
->
data_size
);
for
(
i
=
0
;
i
<
(
packet
->
data_size
/
4
);
i
++
)
HPSB_DEBUG
(
"GASP: data[%d]: 0x%08x"
,
i
*
4
,
be32_to_cpu
(
packet
->
data
[
i
]));
#endif
packet
->
generation
=
generation
;
packet
->
no_waiter
=
1
;
if
(
!
hpsb_send_packet
(
packet
))
{
free_hpsb_packet
(
packet
);
retval
=
-
EINVAL
;
}
return
retval
;
}
drivers/ieee1394/ieee1394_transactions.h
View file @
356a8fd1
...
...
@@ -55,5 +55,8 @@ int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation,
u64
addr
,
int
extcode
,
quadlet_t
*
data
,
quadlet_t
arg
);
int
hpsb_lock64
(
struct
hpsb_host
*
host
,
nodeid_t
node
,
unsigned
int
generation
,
u64
addr
,
int
extcode
,
octlet_t
*
data
,
octlet_t
arg
);
int
hpsb_send_gasp
(
struct
hpsb_host
*
host
,
int
channel
,
unsigned
int
generation
,
quadlet_t
*
buffer
,
size_t
length
,
u32
specifier_id
,
unsigned
int
version
);
#endif
/* _IEEE1394_TRANSACTIONS_H */
drivers/ieee1394/ieee1394_types.h
View file @
356a8fd1
...
...
@@ -97,14 +97,17 @@ typedef u64 nodeaddr_t;
typedef
u16
arm_length_t
;
#define BUS_MASK 0xffc0
#define BUS_SHIFT 6
#define NODE_MASK 0x003f
#define LOCAL_BUS 0xffc0
#define ALL_NODES 0x003f
#define NODEID_TO_BUS(nodeid) ((nodeid & BUS_MASK) >> BUS_SHIFT)
#define NODEID_TO_NODE(nodeid) (nodeid & NODE_MASK)
/* Can be used to consistently print a node/bus ID. */
#define NODE_BUS_FMT "%02d:%04d"
#define NODE_BUS_ARGS(nodeid) \
(nodeid & NODE_MASK), ((nodeid & BUS_MASK) >> 6)
#define NODE_BUS_FMT "%02d:%04d"
#define NODE_BUS_ARGS(nodeid) NODEID_TO_NODE(nodeid), NODEID_TO_BUS(nodeid)
#define HPSB_PRINT(level, fmt, args...) printk(level "ieee1394: " fmt "\n" , ## args)
...
...
drivers/ieee1394/nodemgr.c
View file @
356a8fd1
...
...
@@ -1210,6 +1210,52 @@ static void nodemgr_node_probe(struct hpsb_host *host)
return
;
}
/* Because we are a 1394a-2000 compliant IRM, we need to inform all the other
* nodes of the broadcast channel. (Really we're only setting the validity
* bit). */
static
void
nodemgr_do_irm_duties
(
struct
hpsb_host
*
host
)
{
quadlet_t
bc
;
if
(
!
host
->
is_irm
)
return
;
host
->
csr
.
broadcast_channel
|=
0x40000000
;
/* set validity bit */
bc
=
cpu_to_be32
(
host
->
csr
.
broadcast_channel
);
hpsb_write
(
host
,
LOCAL_BUS
|
ALL_NODES
,
get_hpsb_generation
(
host
),
(
CSR_REGISTER_BASE
|
CSR_BROADCAST_CHANNEL
),
&
bc
,
sizeof
(
quadlet_t
));
}
/* We need to ensure that if we are not the IRM, that the IRM node is capable of
* everything we can do, otherwise issue a bus reset and try to become the IRM
* ourselves. */
static
int
nodemgr_check_root_capability
(
struct
hpsb_host
*
host
)
{
quadlet_t
bc
;
int
status
;
if
(
host
->
is_irm
)
return
1
;
status
=
hpsb_read
(
host
,
LOCAL_BUS
|
(
host
->
irm_id
),
get_hpsb_generation
(
host
),
(
CSR_REGISTER_BASE
|
CSR_BROADCAST_CHANNEL
),
&
bc
,
sizeof
(
quadlet_t
));
if
(
status
<
0
||
!
(
be32_to_cpu
(
bc
)
&
0x80000000
))
{
/* The root node does not have a valid BROADCAST_CHANNEL
* register and we do, so reset the bus with force_root set */
HPSB_INFO
(
"Remote root is not IRM capable, resetting..."
);
hpsb_reset_bus
(
host
,
LONG_RESET_FORCE_ROOT
);
return
0
;
}
return
1
;
}
static
int
nodemgr_host_thread
(
void
*
__hi
)
{
struct
host_info
*
hi
=
(
struct
host_info
*
)
__hi
;
...
...
@@ -1217,12 +1263,21 @@ static int nodemgr_host_thread(void *__hi)
/* No userlevel access needed */
daemonize
(
"knodemgrd"
);
allow_signal
(
SIGTERM
);
/* Sit and wait for a signal to probe the nodes on the bus. This
* happens when we get a bus reset. */
while
(
!
down_interruptible
(
&
hi
->
reset_sem
)
&&
!
down_interruptible
(
&
nodemgr_serialize
))
{
if
(
!
nodemgr_check_root_capability
(
hi
->
host
))
{
/* Do nothing, we are resetting */
up
(
&
nodemgr_serialize
);
continue
;
}
nodemgr_node_probe
(
hi
->
host
);
nodemgr_do_irm_duties
(
hi
->
host
);
up
(
&
nodemgr_serialize
);
}
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
...
...
drivers/ieee1394/ohci1394.c
View file @
356a8fd1
...
...
@@ -31,9 +31,9 @@
*
* Things implemented, but still in test phase:
* . Iso Transmit
* . Async Stream Packets Transmit (Receive done via Iso interface)
*
* Things not implemented:
* . Async Stream Packets
* . DMA error recovery
*
* Known bugs:
...
...
@@ -160,7 +160,7 @@ printk(level "%s: " fmt "\n" , OHCI1394_DRIVER_NAME , ## args)
printk(level "%s_%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args)
static
char
version
[]
__devinitdata
=
"$Rev:
762
$ Ben Collins <bcollins@debian.org>"
;
"$Rev:
801
$ Ben Collins <bcollins@debian.org>"
;
/* Module Parameters */
MODULE_PARM
(
phys_dma
,
"i"
);
...
...
@@ -649,18 +649,31 @@ static void insert_packet(struct ti_ohci *ohci,
}
else
{
d
->
prg_cpu
[
idx
]
->
data
[
0
]
=
packet
->
speed_code
<<
16
|
(
packet
->
header
[
0
]
&
0xFFFF
);
d
->
prg_cpu
[
idx
]
->
data
[
1
]
=
(
packet
->
header
[
1
]
&
0xFFFF
)
|
(
packet
->
header
[
0
]
&
0xFFFF0000
);
d
->
prg_cpu
[
idx
]
->
data
[
2
]
=
packet
->
header
[
2
];
d
->
prg_cpu
[
idx
]
->
data
[
3
]
=
packet
->
header
[
3
];
if
(
packet
->
tcode
==
TCODE_ISO_DATA
)
{
/* Sending an async stream packet */
d
->
prg_cpu
[
idx
]
->
data
[
1
]
=
packet
->
header
[
0
]
&
0xFFFF0000
;
}
else
{
/* Sending a normal async request or response */
d
->
prg_cpu
[
idx
]
->
data
[
1
]
=
(
packet
->
header
[
1
]
&
0xFFFF
)
|
(
packet
->
header
[
0
]
&
0xFFFF0000
);
d
->
prg_cpu
[
idx
]
->
data
[
2
]
=
packet
->
header
[
2
];
d
->
prg_cpu
[
idx
]
->
data
[
3
]
=
packet
->
header
[
3
];
}
packet_swab
(
d
->
prg_cpu
[
idx
]
->
data
,
packet
->
tcode
);
}
if
(
packet
->
data_size
)
{
/* block transmit */
d
->
prg_cpu
[
idx
]
->
begin
.
control
=
cpu_to_le32
(
DMA_CTL_OUTPUT_MORE
|
DMA_CTL_IMMEDIATE
|
0x10
);
if
(
packet
->
tcode
==
TCODE_STREAM_DATA
){
d
->
prg_cpu
[
idx
]
->
begin
.
control
=
cpu_to_le32
(
DMA_CTL_OUTPUT_MORE
|
DMA_CTL_IMMEDIATE
|
0x8
);
}
else
{
d
->
prg_cpu
[
idx
]
->
begin
.
control
=
cpu_to_le32
(
DMA_CTL_OUTPUT_MORE
|
DMA_CTL_IMMEDIATE
|
0x10
);
}
d
->
prg_cpu
[
idx
]
->
end
.
control
=
cpu_to_le32
(
DMA_CTL_OUTPUT_LAST
|
DMA_CTL_IRQ
|
...
...
@@ -830,7 +843,7 @@ static int ohci_transmit(struct hpsb_host *host, struct hpsb_packet *packet)
/* Decide whether we have an iso, a request, or a response packet */
if
(
packet
->
type
==
hpsb_raw
)
d
=
&
ohci
->
at_req_context
;
else
if
(
packet
->
tcode
==
TCODE_ISO_DATA
)
{
else
if
(
(
packet
->
tcode
==
TCODE_ISO_DATA
)
&&
(
packet
->
type
==
hpsb_iso
)
)
{
/* The legacy IT DMA context is initialized on first
* use. However, the alloc cannot be run from
* interrupt context, so we bail out if that is the
...
...
@@ -856,7 +869,7 @@ static int ohci_transmit(struct hpsb_host *host, struct hpsb_packet *packet)
}
d
=
&
ohci
->
it_legacy_context
;
}
else
if
(
packet
->
tcode
&
0x02
)
}
else
if
(
(
packet
->
tcode
&
0x02
)
&&
(
packet
->
tcode
!=
TCODE_ISO_DATA
)
)
d
=
&
ohci
->
at_resp_context
;
else
d
=
&
ohci
->
at_req_context
;
...
...
@@ -1295,6 +1308,8 @@ static void ohci_iso_recv_program(struct hpsb_iso *iso)
u32
*
prev_branch
=
NULL
;
for
(
blk
=
0
;
blk
<
recv
->
nblocks
;
blk
++
)
{
u32
control
;
/* the DMA descriptor */
struct
dma_cmd
*
cmd
=
&
recv
->
block
[
blk
];
...
...
@@ -1305,29 +1320,29 @@ static void ohci_iso_recv_program(struct hpsb_iso *iso)
unsigned
long
buf_offset
=
blk
*
recv
->
buf_stride
;
if
(
recv
->
dma_mode
==
BUFFER_FILL_MODE
)
{
c
md
->
c
ontrol
=
2
<<
28
;
/* INPUT_MORE */
control
=
2
<<
28
;
/* INPUT_MORE */
}
else
{
c
md
->
c
ontrol
=
3
<<
28
;
/* INPUT_LAST */
control
=
3
<<
28
;
/* INPUT_LAST */
}
c
md
->
c
ontrol
|=
8
<<
24
;
/* s = 1, update xferStatus and resCount */
control
|=
8
<<
24
;
/* s = 1, update xferStatus and resCount */
/* interrupt on last block, and at intervals */
if
(
blk
==
recv
->
nblocks
-
1
||
(
blk
%
recv
->
block_irq_interval
)
==
0
)
{
c
md
->
c
ontrol
|=
3
<<
20
;
/* want interrupt */
control
|=
3
<<
20
;
/* want interrupt */
}
c
md
->
c
ontrol
|=
3
<<
18
;
/* enable branch to address */
c
md
->
c
ontrol
|=
recv
->
buf_stride
;
control
|=
3
<<
18
;
/* enable branch to address */
control
|=
recv
->
buf_stride
;
cmd
->
address
=
dma_region_offset_to_bus
(
&
iso
->
data_buf
,
buf_offset
);
cmd
->
control
=
cpu_to_le32
(
control
);
cmd
->
address
=
cpu_to_le32
(
dma_region_offset_to_bus
(
&
iso
->
data_buf
,
buf_offset
));
cmd
->
branchAddress
=
0
;
/* filled in on next loop */
cmd
->
status
=
recv
->
buf_stride
;
cmd
->
status
=
cpu_to_le32
(
recv
->
buf_stride
)
;
/* link the previous descriptor to this one */
if
(
prev_branch
)
{
*
prev_branch
=
dma_prog_region_offset_to_bus
(
&
recv
->
prog
,
prog_offset
);
*
prev_branch
|=
1
;
/* set Z=1 */
*
prev_branch
=
cpu_to_le32
(
dma_prog_region_offset_to_bus
(
&
recv
->
prog
,
prog_offset
)
|
1
);
}
prev_branch
=
&
cmd
->
branchAddress
;
...
...
@@ -1485,18 +1500,18 @@ static void ohci_iso_recv_release_block(struct ohci_iso_recv *recv, int block)
/* 'next' becomes the new end of the DMA chain,
so disable branch and enable interrupt */
next
->
branchAddress
=
0
;
next
->
control
|=
3
<<
20
;
next
->
control
|=
cpu_to_le32
(
3
<<
20
)
;
/* link prev to next */
prev
->
branchAddress
=
dma_prog_region_offset_to_bus
(
&
recv
->
prog
,
sizeof
(
struct
dma_cmd
)
*
next_i
)
|
1
;
/* Z=1 */
prev
->
branchAddress
=
cpu_to_le32
(
dma_prog_region_offset_to_bus
(
&
recv
->
prog
,
sizeof
(
struct
dma_cmd
)
*
next_i
)
|
1
)
;
/* Z=1 */
/* disable interrupt on previous DMA descriptor, except at intervals */
if
((
prev_i
%
recv
->
block_irq_interval
)
==
0
)
{
prev
->
control
|=
3
<<
20
;
/* enable interrupt */
prev
->
control
|=
cpu_to_le32
(
3
<<
20
)
;
/* enable interrupt */
}
else
{
prev
->
control
&=
~
(
3
<<
20
);
/* disable interrupt */
prev
->
control
&=
cpu_to_le32
(
~
(
3
<<
20
)
);
/* disable interrupt */
}
wmb
();
...
...
@@ -1720,8 +1735,8 @@ static void ohci_iso_recv_packetperbuf_task(unsigned long data)
struct
dma_cmd
*
il
=
((
struct
dma_cmd
*
)
recv
->
prog
.
kvirt
)
+
iso
->
pkt_dma
;
/* check the DMA descriptor for new writes to xferStatus */
u16
xferstatus
=
il
->
status
>>
16
;
u16
rescount
=
il
->
status
&
0xFFFF
;
u16
xferstatus
=
le32_to_cpu
(
il
->
status
)
>>
16
;
u16
rescount
=
le32_to_cpu
(
il
->
status
)
&
0xFFFF
;
unsigned
char
event
=
xferstatus
&
0x1F
;
...
...
@@ -1903,7 +1918,7 @@ static void ohci_iso_xmit_task(unsigned long data)
struct
iso_xmit_cmd
*
cmd
=
dma_region_i
(
&
xmit
->
prog
,
struct
iso_xmit_cmd
,
iso
->
pkt_dma
);
/* check for new writes to xferStatus */
u16
xferstatus
=
cmd
->
output_last
.
status
>>
16
;
u16
xferstatus
=
le32_to_cpu
(
cmd
->
output_last
.
status
)
>>
16
;
u8
event
=
xferstatus
&
0x1F
;
if
(
!
event
)
{
...
...
@@ -1919,7 +1934,7 @@ static void ohci_iso_xmit_task(unsigned long data)
wake
=
1
;
/* parse cycle */
cycle
=
cmd
->
output_last
.
status
&
0x1FFF
;
cycle
=
le32_to_cpu
(
cmd
->
output_last
.
status
)
&
0x1FFF
;
/* tell the subsystem the packet has gone out */
hpsb_iso_packet_sent
(
iso
,
cycle
,
event
!=
0x11
);
...
...
@@ -1972,7 +1987,7 @@ static int ohci_iso_xmit_queue(struct hpsb_iso *iso, struct hpsb_iso_packet_info
/* set up the OUTPUT_MORE_IMMEDIATE descriptor */
memset
(
next
,
0
,
sizeof
(
struct
iso_xmit_cmd
));
next
->
output_more_immediate
.
control
=
0x02000008
;
next
->
output_more_immediate
.
control
=
cpu_to_le32
(
0x02000008
)
;
/* ISO packet header is embedded in the OUTPUT_MORE_IMMEDIATE */
...
...
@@ -1990,28 +2005,28 @@ static int ohci_iso_xmit_queue(struct hpsb_iso *iso, struct hpsb_iso_packet_info
next
->
iso_hdr
[
7
]
=
len
>>
8
;
/* set up the OUTPUT_LAST */
next
->
output_last
.
control
=
1
<<
28
;
next
->
output_last
.
control
|=
1
<<
27
;
/* update timeStamp */
next
->
output_last
.
control
|=
3
<<
20
;
/* want interrupt */
next
->
output_last
.
control
|=
3
<<
18
;
/* enable branch */
next
->
output_last
.
control
|=
len
;
next
->
output_last
.
control
=
cpu_to_le32
(
1
<<
28
)
;
next
->
output_last
.
control
|=
cpu_to_le32
(
1
<<
27
)
;
/* update timeStamp */
next
->
output_last
.
control
|=
cpu_to_le32
(
3
<<
20
)
;
/* want interrupt */
next
->
output_last
.
control
|=
cpu_to_le32
(
3
<<
18
)
;
/* enable branch */
next
->
output_last
.
control
|=
cpu_to_le32
(
len
)
;
/* payload bus address */
next
->
output_last
.
address
=
dma_region_offset_to_bus
(
&
iso
->
data_buf
,
offset
);
next
->
output_last
.
address
=
cpu_to_le32
(
dma_region_offset_to_bus
(
&
iso
->
data_buf
,
offset
)
);
/* leave branchAddress at zero for now */
/* re-write the previous DMA descriptor to chain to this one */
/* set prev branch address to point to next (Z=3) */
prev
->
output_last
.
branchAddress
=
dma_prog_region_offset_to_bus
(
&
xmit
->
prog
,
sizeof
(
struct
iso_xmit_cmd
)
*
next_i
)
|
3
;
prev
->
output_last
.
branchAddress
=
cpu_to_le32
(
dma_prog_region_offset_to_bus
(
&
xmit
->
prog
,
sizeof
(
struct
iso_xmit_cmd
)
*
next_i
)
|
3
)
;
/* disable interrupt, unless required by the IRQ interval */
if
(
prev_i
%
iso
->
irq_interval
)
{
prev
->
output_last
.
control
&=
~
(
3
<<
20
);
/* no interrupt */
prev
->
output_last
.
control
&=
cpu_to_le32
(
~
(
3
<<
20
)
);
/* no interrupt */
}
else
{
prev
->
output_last
.
control
|=
3
<<
20
;
/* enable interrupt */
prev
->
output_last
.
control
|=
cpu_to_le32
(
3
<<
20
)
;
/* enable interrupt */
}
wmb
();
...
...
@@ -3473,10 +3488,10 @@ static void ohci1394_pci_remove(struct pci_dev *pdev)
static
struct
pci_device_id
ohci1394_pci_tbl
[]
__devinitdata
=
{
{
.
class
=
PCI_CLASS_FIREWIRE_OHCI
,
.
class_mask
=
0x00ffffff
,
.
vendor
=
PCI_ANY_ID
,
.
device
=
PCI_ANY_ID
,
.
class
=
PCI_CLASS_FIREWIRE_OHCI
,
.
class_mask
=
~
0
,
.
vendor
=
PCI_ANY_ID
,
.
device
=
PCI_ANY_ID
,
.
subvendor
=
PCI_ANY_ID
,
.
subdevice
=
PCI_ANY_ID
,
},
...
...
drivers/ieee1394/raw1394.c
View file @
356a8fd1
...
...
@@ -238,7 +238,7 @@ static void remove_host(struct hpsb_host *host)
list_del
(
&
hi
->
list
);
host_count
--
;
/*
FIXME: addressranges should be removed
FIXME: address
ranges should be removed
and fileinfo states should be initialized
(including setting generation to
internal-generation ...)
...
...
@@ -281,8 +281,8 @@ static void host_reset(struct hpsb_host *host)
req
->
req
.
misc
=
(
host
->
node_id
<<
16
)
|
host
->
node_count
;
if
(
fi
->
protocol_version
>
3
)
{
req
->
req
.
misc
|=
(
(
host
->
irm_id
&
NODE_MASK
)
<<
8
);
req
->
req
.
misc
|=
(
NODEID_TO_NODE
(
host
->
irm_id
)
<<
8
);
}
queue_complete_req
(
req
);
...
...
@@ -571,8 +571,7 @@ static int state_initialized(struct file_info *fi, struct pending_request *req)
req
->
req
.
misc
=
(
fi
->
host
->
node_id
<<
16
)
|
fi
->
host
->
node_count
;
if
(
fi
->
protocol_version
>
3
)
{
req
->
req
.
misc
|=
(
fi
->
host
->
irm_id
&
NODE_MASK
)
<<
8
;
req
->
req
.
misc
|=
NODEID_TO_NODE
(
fi
->
host
->
irm_id
)
<<
8
;
}
}
else
{
req
->
req
.
error
=
RAW1394_ERROR_INVALID_ARG
;
...
...
drivers/ieee1394/sbp2.c
View file @
356a8fd1
...
...
@@ -27,30 +27,6 @@
* driver. It also registers as a SCSI lower-level driver in order to accept
* SCSI commands for transport using SBP-2.
*
*
* Driver Loading:
*
* Currently, the SBP-2 driver is supported only as a module. Because the
* Linux SCSI stack is not Plug-N-Play aware, module load order is
* important. Assuming the SCSI core drivers are either built into the
* kernel or already loaded as modules, you should load the IEEE-1394 modules
* in the following order:
*
* ieee1394 (e.g. insmod ieee1394)
* ohci1394 (e.g. insmod ohci1394)
* sbp2 (e.g. insmod sbp2)
*
* The SBP-2 driver will attempt to discover any attached SBP-2 devices when first
* loaded, or after any IEEE-1394 bus reset (e.g. a hot-plug). It will then print
* out a debug message indicating if it was able to discover a SBP-2 device.
*
* Currently, the SBP-2 driver will catch any attached SBP-2 devices during the
* initial scsi bus scan (when the driver is first loaded). To add or remove
* SBP-2 devices "after" this initial scan (i.e. if you plug-in or un-plug a
* device after the SBP-2 driver is loaded), you must either use the scsi procfs
* add-single-device, remove-single-device, or a shell script such as
* rescan-scsi-bus.sh.
*
* The easiest way to add/detect new SBP-2 devices is to run the shell script
* rescan-scsi-bus.sh (or re-load the SBP-2 driver). This script may be
* found at:
...
...
@@ -136,14 +112,6 @@
* - Error Handling: SCSI aborts and bus reset requests are handled somewhat
* but the code needs additional debugging.
*
* - Module: The SBP-2 driver is currently only supported as a module. It would not take
* much work to allow it to be compiled into the kernel, but you'd have to
* add some init code to the kernel to support this... and modules are much
* more flexible anyway. ;-)
*
* - Hot-plugging: Interaction with the SCSI stack and support for hot-plugging could
* stand some improvement.
*
*
* History:
*
...
...
@@ -295,10 +263,11 @@
* 04/23/02 - Fix for Sony CD-ROM drives. Only send fetch agent reset to sbp2 device if it
* returns the dead bit in status. Thanks to Chandan (chandan@toad.net) for this one.
* 04/27/02 - Fix sbp2 login problem on SMP systems, enable real spinlocks by default. (JSG)
* 06/09/02 - Don't force 36-b
u
te SCSI inquiry, but leave in a define for badly behaved devices. (JSG)
* 06/09/02 - Don't force 36-b
y
te SCSI inquiry, but leave in a define for badly behaved devices. (JSG)
* 02/04/03 - Fixed a SMP deadlock (don't hold sbp2_command_lock while calling sbp2scsi_complete_command).
* Also save/restore irq flags in sbp2scsi_complete_command - Sancho Dauskardt <sda@bdit.de>
* 02/06/03 - Removed spinlock debugging; use kernel stuff instead (sda)
* 02/10/03 - Adopt to new hot-plug aware SCSI inferface (hch@lst.de)
*
*/
...
...
@@ -350,7 +319,7 @@
#include "sbp2.h"
static
char
version
[]
__devinitdata
=
"$Rev: 7
79
$ James Goodwin <jamesg@filanet.com>"
;
"$Rev: 7
97
$ James Goodwin <jamesg@filanet.com>"
;
/*
* Module load parameter definitions
...
...
@@ -497,6 +466,15 @@ static u32 global_outstanding_dmas = 0;
* Globals
*/
static
void
sbp2scsi_complete_all_commands
(
struct
sbp2scsi_host_info
*
hi
,
struct
scsi_id_instance_data
*
scsi_id
,
u32
status
);
static
void
sbp2scsi_complete_command
(
struct
sbp2scsi_host_info
*
hi
,
struct
scsi_id_instance_data
*
scsi_id
,
u32
scsi_status
,
Scsi_Cmnd
*
SCpnt
,
void
(
*
done
)(
Scsi_Cmnd
*
));
static
Scsi_Host_Template
scsi_driver_template
;
static
u8
sbp2_speedto_maxrec
[]
=
{
0x7
,
0x8
,
0x9
};
...
...
@@ -822,7 +800,7 @@ static void sbp2util_free_command_dma(struct sbp2_command_info *command)
{
struct
sbp2scsi_host_info
*
hi
;
hi
=
(
struct
sbp2scsi_host_info
*
)
command
->
Current_SCpnt
->
device
->
host
->
hostdata
[
0
]
;
hi
=
(
struct
sbp2scsi_host_info
*
)
&
command
->
Current_SCpnt
->
device
->
host
->
hostdata
;
if
(
hi
==
NULL
)
{
printk
(
KERN_ERR
"%s: hi == NULL
\n
"
,
__FUNCTION__
);
...
...
@@ -871,59 +849,6 @@ static void sbp2util_mark_command_completed(struct scsi_id_instance_data *scsi_i
* IEEE-1394 core driver stack related section
*********************************************/
/*
* This function is called at SCSI init in order to register our driver
* with the IEEE-1394 stack.
*/
int
sbp2_init
(
void
)
{
SBP2_DEBUG
(
"sbp2_init"
);
/*
* Register our high level driver with 1394 stack
*/
sbp2_hl_handle
=
hpsb_register_highlevel
(
SBP2_DEVICE_NAME
,
&
sbp2_hl_ops
);
if
(
sbp2_hl_handle
==
NULL
)
{
SBP2_ERR
(
"sbp2 failed to register with ieee1394 highlevel"
);
return
(
-
ENOMEM
);
}
/*
* Register our sbp2 status address space...
*/
hpsb_register_addrspace
(
sbp2_hl_handle
,
&
sbp2_ops
,
SBP2_STATUS_FIFO_ADDRESS
,
SBP2_STATUS_FIFO_ADDRESS
+
SBP2_STATUS_FIFO_ENTRY_TO_OFFSET
(
SBP2SCSI_MAX_SCSI_IDS
+
1
));
/*
* Handle data movement if physical dma is not enabled/supported on host controller
*/
#ifdef CONFIG_IEEE1394_SBP2_PHYS_DMA
hpsb_register_addrspace
(
sbp2_hl_handle
,
&
sbp2_physdma_ops
,
0x0ULL
,
0xfffffffcULL
);
#endif
hpsb_register_protocol
(
&
sbp2_driver
);
return
0
;
}
/*
* This function is called from cleanup module, or during shut-down, in
* order to unregister our driver.
*/
void
sbp2_cleanup
(
void
)
{
SBP2_DEBUG
(
"sbp2_cleanup"
);
hpsb_unregister_protocol
(
&
sbp2_driver
);
if
(
sbp2_hl_handle
)
{
hpsb_unregister_highlevel
(
sbp2_hl_handle
);
sbp2_hl_handle
=
NULL
;
}
}
static
int
sbp2_probe
(
struct
unit_directory
*
ud
)
{
struct
sbp2scsi_host_info
*
hi
;
...
...
@@ -999,35 +924,44 @@ static void sbp2_add_host(struct hpsb_host *host)
{
struct
sbp2scsi_host_info
*
hi
;
unsigned
long
flags
;
struct
Scsi_Host
*
scsi_host
;
SBP2_DEBUG
(
"sbp2_add_host"
);
/* Allocate some memory for our host info structure */
hi
=
(
struct
sbp2scsi_host_info
*
)
kmalloc
(
sizeof
(
struct
sbp2scsi_host_info
),
in_interrupt
()
?
SLAB_ATOMIC
:
SLAB_KERNEL
);
if
(
hi
==
NULL
)
{
SBP2_ERR
(
"out of memory in sbp2_add_host"
);
/* Register our host with the SCSI stack. */
scsi_host
=
scsi_register
(
&
scsi_driver_template
,
sizeof
(
struct
sbp2scsi_host_info
));
if
(
!
scsi_host
)
{
SBP2_ERR
(
"failed to register scsi host"
);
return
;
}
/* Initialize some host stuff */
hi
=
(
struct
sbp2scsi_host_info
*
)
&
scsi_host
->
hostdata
;
memset
(
hi
,
0
,
sizeof
(
struct
sbp2scsi_host_info
));
hi
->
scsi_host
=
scsi_host
;
INIT_LIST_HEAD
(
&
hi
->
list
);
hi
->
host
=
host
;
hi
->
sbp2_command_lock
=
SPIN_LOCK_UNLOCKED
;
hi
->
scsi_host
->
max_id
=
SBP2SCSI_MAX_SCSI_IDS
;
spin_lock_irqsave
(
&
sbp2_host_info_lock
,
flags
);
list_add_tail
(
&
hi
->
list
,
&
sbp2_host_info_list
);
spin_unlock_irqrestore
(
&
sbp2_host_info_lock
,
flags
);
/* Register our host with the SCSI stack. */
hi
->
scsi_host
=
scsi_register
(
&
scsi_driver_template
,
sizeof
(
void
*
));
if
(
hi
->
scsi_host
)
{
hi
->
scsi_host
->
hostdata
[
0
]
=
(
unsigned
long
)
hi
;
hi
->
scsi_host
->
max_id
=
SBP2SCSI_MAX_SCSI_IDS
;
/*
* XXX(hch): Hopefully the ieee1394 code will be converted
* to the driver model at some point. Until that happens
* we'll have to pass in NULL here.
*/
if
(
scsi_add_host
(
hi
->
scsi_host
,
NULL
))
{
SBP2_ERR
(
"failed to add scsi host"
);
spin_lock_irqsave
(
&
sbp2_host_info_lock
,
flags
);
list_del
(
&
hi
->
list
);
spin_unlock_irqrestore
(
&
sbp2_host_info_lock
,
flags
);
scsi_unregister
(
hi
->
scsi_host
);
}
scsi_driver_template
.
present
++
;
return
;
}
...
...
@@ -1079,16 +1013,15 @@ static void sbp2_remove_host(struct hpsb_host *host)
SBP2_DEBUG
(
"sbp2_remove_host"
);
spin_lock_irqsave
(
&
sbp2_host_info_lock
,
flags
);
hi
=
sbp2_find_host_info
(
host
);
if
(
hi
!=
NULL
)
{
if
(
hi
)
list_del
(
&
hi
->
list
);
kfree
(
hi
);
}
else
SBP2_ERR
(
"attempt to remove unknown host %p"
,
host
);
spin_unlock_irqrestore
(
&
sbp2_host_info_lock
,
flags
);
if
(
hi
)
{
scsi_remove_host
(
hi
->
scsi_host
);
scsi_unregister
(
hi
->
scsi_host
);
}
}
/*
...
...
@@ -1098,6 +1031,7 @@ static void sbp2_remove_host(struct hpsb_host *host)
static
int
sbp2_start_device
(
struct
sbp2scsi_host_info
*
hi
,
struct
unit_directory
*
ud
)
{
struct
scsi_id_instance_data
*
scsi_id
=
NULL
;
struct
scsi_device
*
sdev
;
struct
node_entry
*
ne
;
int
i
;
...
...
@@ -1203,7 +1137,7 @@ static int sbp2_start_device(struct sbp2scsi_host_info *hi, struct unit_director
/*
* Find an empty spot to stick our scsi id instance data.
*/
for
(
i
=
0
;
i
<
SBP2SCSI_MAX_SCSI_IDS
;
i
++
)
{
for
(
i
=
0
;
i
<
hi
->
scsi_host
->
max_id
;
i
++
)
{
if
(
!
hi
->
scsi_id
[
i
])
{
hi
->
scsi_id
[
i
]
=
scsi_id
;
scsi_id
->
id
=
i
;
...
...
@@ -1224,7 +1158,7 @@ static int sbp2_start_device(struct sbp2scsi_host_info *hi, struct unit_director
/*
* Make sure we are not out of space
*/
if
(
i
==
SBP2SCSI_MAX_SCSI_IDS
)
{
if
(
i
==
hi
->
scsi_host
->
max_id
)
{
SBP2_ERR
(
"No slots left for SBP-2 device"
);
sbp2_remove_device
(
hi
,
scsi_id
);
return
-
EBUSY
;
...
...
@@ -1256,6 +1190,13 @@ static int sbp2_start_device(struct sbp2scsi_host_info *hi, struct unit_director
*/
sbp2_max_speed_and_size
(
hi
,
scsi_id
);
/* Add this device to the scsi layer now */
sdev
=
scsi_add_device
(
hi
->
scsi_host
,
0
,
scsi_id
->
id
,
0
);
if
(
IS_ERR
(
sdev
))
{
SBP2_ERR
(
"scsi_add_device failed"
);
return
PTR_ERR
(
sdev
);
}
return
0
;
}
...
...
@@ -1265,13 +1206,21 @@ static int sbp2_start_device(struct sbp2scsi_host_info *hi, struct unit_director
static
void
sbp2_remove_device
(
struct
sbp2scsi_host_info
*
hi
,
struct
scsi_id_instance_data
*
scsi_id
)
{
struct
scsi_device
*
sdev
=
scsi_find_device
(
hi
->
scsi_host
,
0
,
scsi_id
->
id
,
0
);
SBP2_DEBUG
(
"sbp2_remove_device"
);
/* Complete any pending commands with selection timeout */
sbp2scsi_complete_all_commands
(
hi
,
scsi_id
,
DID_NO_CONNECT
);
/* Remove it from the scsi layer now */
if
(
scsi_remove_device
(
sdev
))
SBP2_ERR
(
"scsi_remove_device failed"
);
sbp2util_remove_command_orb_pool
(
scsi_id
,
hi
);
hi
->
scsi_id
[
scsi_id
->
id
]
=
NULL
;
if
(
scsi_id
->
login_response
)
{
pci_free_consistent
(
hi
->
host
->
pdev
,
sizeof
(
struct
sbp2_login_response
),
...
...
@@ -1305,7 +1254,7 @@ static void sbp2_remove_device(struct sbp2scsi_host_info *hi,
}
SBP2_DEBUG
(
"SBP-2 device removed, SCSI ID = %d"
,
scsi_id
->
id
);
hi
->
scsi_id
[
scsi_id
->
id
]
=
NULL
;
kfree
(
scsi_id
);
}
...
...
@@ -1793,8 +1742,8 @@ static int sbp2_max_speed_and_size(struct sbp2scsi_host_info *hi, struct scsi_id
SBP2_DEBUG
(
"sbp2_max_speed_and_size"
);
/* Initial setting comes from the hosts speed map */
scsi_id
->
speed_code
=
hi
->
host
->
speed_map
[
(
hi
->
host
->
node_id
&
NODE_MASK
)
*
64
+
(
scsi_id
->
ne
->
nodeid
&
NODE_MASK
)];
scsi_id
->
speed_code
=
hi
->
host
->
speed_map
[
NODEID_TO_NODE
(
hi
->
host
->
node_id
)
*
64
+
NODEID_TO_NODE
(
scsi_id
->
ne
->
nodeid
)];
/* Bump down our speed if the user requested it */
if
(
scsi_id
->
speed_code
>
sbp2_max_speed
)
{
...
...
@@ -2661,7 +2610,7 @@ static int sbp2scsi_queuecommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
/*
* Pull our host info and scsi id instance data from the scsi command
*/
hi
=
(
struct
sbp2scsi_host_info
*
)
SCpnt
->
device
->
host
->
hostdata
[
0
]
;
hi
=
(
struct
sbp2scsi_host_info
*
)
&
SCpnt
->
device
->
host
->
hostdata
;
if
(
!
hi
)
{
SBP2_ERR
(
"sbp2scsi_host_info is NULL - this is bad!"
);
...
...
@@ -2766,8 +2715,10 @@ static void sbp2scsi_complete_all_commands(struct sbp2scsi_host_info *hi,
*
* This can be called in interrupt context.
*/
static
void
sbp2scsi_complete_command
(
struct
sbp2scsi_host_info
*
hi
,
struct
scsi_id_instance_data
*
scsi_id
,
u32
scsi_status
,
Scsi_Cmnd
*
SCpnt
,
void
(
*
done
)(
Scsi_Cmnd
*
))
static
void
sbp2scsi_complete_command
(
struct
sbp2scsi_host_info
*
hi
,
struct
scsi_id_instance_data
*
scsi_id
,
u32
scsi_status
,
Scsi_Cmnd
*
SCpnt
,
void
(
*
done
)(
Scsi_Cmnd
*
))
{
unsigned
long
flags
;
...
...
@@ -2888,7 +2839,7 @@ static void sbp2scsi_complete_command(struct sbp2scsi_host_info *hi, struct scsi
*/
static
int
sbp2scsi_abort
(
Scsi_Cmnd
*
SCpnt
)
{
struct
sbp2scsi_host_info
*
hi
=
(
struct
sbp2scsi_host_info
*
)
SCpnt
->
device
->
host
->
hostdata
[
0
]
;
struct
sbp2scsi_host_info
*
hi
=
(
struct
sbp2scsi_host_info
*
)
&
SCpnt
->
device
->
host
->
hostdata
;
struct
scsi_id_instance_data
*
scsi_id
=
hi
->
scsi_id
[
SCpnt
->
device
->
id
];
struct
sbp2_command_info
*
command
;
unsigned
long
flags
;
...
...
@@ -2938,7 +2889,7 @@ static int sbp2scsi_abort (Scsi_Cmnd *SCpnt)
*/
static
int
sbp2scsi_reset
(
Scsi_Cmnd
*
SCpnt
)
{
struct
sbp2scsi_host_info
*
hi
=
(
struct
sbp2scsi_host_info
*
)
SCpnt
->
device
->
host
->
hostdata
[
0
]
;
struct
sbp2scsi_host_info
*
hi
=
(
struct
sbp2scsi_host_info
*
)
&
SCpnt
->
device
->
host
->
hostdata
;
struct
scsi_id_instance_data
*
scsi_id
=
hi
->
scsi_id
[
SCpnt
->
device
->
id
];
SBP2_ERR
(
"reset requested"
);
...
...
@@ -2951,93 +2902,81 @@ static int sbp2scsi_reset (Scsi_Cmnd *SCpnt)
return
(
SUCCESS
);
}
/*
* Called by scsi stack to get bios parameters (used by fdisk, and at boot).
*/
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,43)
static
int
sbp2scsi_biosparam
(
struct
scsi_device
*
sdev
,
struct
block_device
*
dev
,
sector_t
capacity
,
int
geom
[])
static
const
char
*
sbp2scsi_info
(
struct
Scsi_Host
*
host
)
{
#else
static
int
sbp2scsi_biosparam
(
Scsi_Disk
*
disk
,
kdev_t
dev
,
int
geom
[])
return
"SCSI emulation for for IEEE-1394 Storage Devices"
;
}
/* Called for contents of procfs */
#define SPRINTF(args...) \
do { if (pos < buffer+length) pos += sprintf(pos, ## args); } while (0)
static
int
sbp2scsi_proc_info
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
length
,
int
hostno
,
int
inout
)
{
unsigned
capacity
=
disk
->
capacity
;
#endif
int
heads
,
sectors
,
cylinders
;
Scsi_Device
*
scd
;
struct
Scsi_Host
*
host
;
struct
sbp2scsi_host_info
*
hi
;
char
*
pos
=
buffer
;
SBP2_DEBUG
(
"Request for bios parameters"
);
/* if someone is sending us data, just throw it away */
if
(
inout
)
return
length
;
h
eads
=
64
;
sectors
=
32
;
cylinders
=
(
int
)
capacity
/
(
heads
*
sectors
)
;
h
ost
=
scsi_host_hn_get
(
hostno
)
;
if
(
!
host
)
/* if we couldn't find it, we return an error */
return
-
ESRCH
;
if
(
cylinders
>
1024
)
{
heads
=
255
;
sectors
=
63
;
cylinders
=
(
int
)
capacity
/
(
heads
*
sectors
);
}
hi
=
sbp2_find_host_info_scsi
(
host
);
if
(
!
hi
)
/* shouldn't happen, but... */
return
-
ESRCH
;
geom
[
0
]
=
heads
;
geom
[
1
]
=
sectors
;
geom
[
2
]
=
cylinders
;
SPRINTF
(
"Host scsi%d : SBP-2 IEEE-1394 (%s)
\n
"
,
hostno
,
hi
->
host
->
driver
->
name
)
;
SPRINTF
(
"Driver version : %s
\n
"
,
version
)
;
return
(
0
);
}
SPRINTF
(
"
\n
Module options :
\n
"
);
SPRINTF
(
" sbp2_max_speed : %s
\n
"
,
hpsb_speedto_str
[
sbp2_max_speed
]);
SPRINTF
(
" sbp2_max_sectors : %d
\n
"
,
sbp2_max_sectors
);
SPRINTF
(
" sbp2_serialize_io : %s
\n
"
,
sbp2_serialize_io
?
"yes"
:
"no"
);
SPRINTF
(
" sbp2_exclusive_login : %s
\n
"
,
sbp2_exclusive_login
?
"yes"
:
"no"
);
/*
* Called by scsi stack after scsi driver is registered
*/
static
int
sbp2scsi_detect
(
Scsi_Host_Template
*
tpnt
)
{
SBP2_DEBUG
(
"sbp2scsi_detect"
);
SPRINTF
(
"
\n
Attached devices : %s
\n
"
,
!
list_empty
(
&
host
->
my_devices
)
?
""
:
"none"
);
/*
* Call sbp2_init to register with the ieee1394 stack. This
* results in a callback to sbp2_add_host for each ieee1394
* host controller currently registered, and for each of those
* we register a scsi host with the scsi stack.
*/
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
spin_unlock_irq
(
&
io_request_lock
);
sbp2_init
();
spin_lock_irq
(
&
io_request_lock
);
#else
sbp2_init
();
#endif
list_for_each_entry
(
scd
,
&
host
->
my_devices
,
siblings
)
{
int
i
;
/* We return the number of hosts registered. */
return
scsi_driver_template
.
present
;
}
SPRINTF
(
" [Channel: %02d, Id: %02d, Lun: %02d] "
,
scd
->
channel
,
scd
->
id
,
scd
->
lun
);
SPRINTF
(
"%s "
,
(
scd
->
type
<
MAX_SCSI_DEVICE_CODE
)
?
scsi_device_types
[(
short
)
scd
->
type
]
:
"Unknown device"
);
for
(
i
=
0
;
(
i
<
8
)
&&
(
scd
->
vendor
[
i
]
>=
0x20
);
i
++
)
SPRINTF
(
"%c"
,
scd
->
vendor
[
i
]);
/*
* Called for contents of procfs
*/
static
const
char
*
sbp2scsi_info
(
struct
Scsi_Host
*
host
)
{
struct
sbp2scsi_host_info
*
hi
=
sbp2_find_host_info_scsi
(
host
);
static
char
info
[
1024
];
SPRINTF
(
" "
);
if
(
!
hi
)
/* shouldn't happen, but... */
return
"IEEE-1394 SBP-2 protocol driver"
;
sprintf
(
info
,
"IEEE-1394 SBP-2 protocol driver (host: %s)
\n
%s
\n
"
"SBP-2 module load options:
\n
"
"- Max speed supported: %s
\n
"
"- Max sectors per I/O supported: %d
\n
"
"- Serialized I/O (debug): %s
\n
"
"- Exclusive login: %s"
,
hi
->
host
->
driver
->
name
,
version
,
hpsb_speedto_str
[
sbp2_max_speed
],
sbp2_max_sectors
,
sbp2_serialize_io
?
"yes"
:
"no"
,
sbp2_exclusive_login
?
"yes"
:
"no"
);
return
info
;
}
for
(
i
=
0
;
(
i
<
16
)
&&
(
scd
->
model
[
i
]
>=
0x20
);
i
++
)
SPRINTF
(
"%c"
,
scd
->
model
[
i
]);
SPRINTF
(
"
\n
"
);
}
SPRINTF
(
"
\n
"
);
/* release the reference count on this host */
scsi_host_put
(
host
);
/* Calculate start of next buffer, and return value. */
*
start
=
buffer
+
offset
;
if
((
pos
-
buffer
)
<
offset
)
return
(
0
);
else
if
((
pos
-
buffer
-
offset
)
<
length
)
return
(
pos
-
buffer
-
offset
);
else
return
(
length
);
}
MODULE_AUTHOR
(
"James Goodwin <jamesg@filanet.com>"
);
MODULE_DESCRIPTION
(
"IEEE-1394 SBP-2 protocol driver"
);
...
...
@@ -3046,25 +2985,23 @@ MODULE_LICENSE("GPL");
/* SCSI host template */
static
Scsi_Host_Template
scsi_driver_template
=
{
.
name
=
"IEEE-1394 SBP-2 protocol driver"
,
.
info
=
sbp2scsi_info
,
.
detect
=
sbp2scsi_detect
,
.
queuecommand
=
sbp2scsi_queuecommand
,
.
eh_abort_handler
=
sbp2scsi_abort
,
.
eh_device_reset_handler
=
sbp2scsi_reset
,
.
eh_bus_reset_handler
=
sbp2scsi_reset
,
.
eh_host_reset_handler
=
sbp2scsi_reset
,
.
bios_param
=
sbp2scsi_biosparam
,
.
this_id
=
-
1
,
.
sg_tablesize
=
SG_ALL
,
.
use_clustering
=
ENABLE_CLUSTERING
,
.
cmd_per_lun
=
SBP2_MAX_CMDS_PER_LUN
,
.
can_queue
=
SBP2_MAX_SCSI_QUEUE
,
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
.
use_new_eh_code
=
TRUE
,
#endif
.
emulated
=
1
,
.
proc_name
=
SBP2_DEVICE_NAME
,
.
module
=
THIS_MODULE
,
.
name
=
"SBP-2 IEEE-1394"
,
.
proc_name
=
SBP2_DEVICE_NAME
,
.
info
=
sbp2scsi_info
,
.
proc_info
=
sbp2scsi_proc_info
,
.
queuecommand
=
sbp2scsi_queuecommand
,
.
eh_abort_handler
=
sbp2scsi_abort
,
.
eh_device_reset_handler
=
sbp2scsi_reset
,
.
eh_bus_reset_handler
=
sbp2scsi_reset
,
.
eh_host_reset_handler
=
sbp2scsi_reset
,
.
this_id
=
-
1
,
.
sg_tablesize
=
SG_ALL
,
.
use_clustering
=
ENABLE_CLUSTERING
,
.
cmd_per_lun
=
SBP2_MAX_CMDS_PER_LUN
,
.
can_queue
=
SBP2_MAX_SCSI_QUEUE
,
.
emulated
=
1
,
.
highmem_io
=
1
,
};
static
int
sbp2_module_init
(
void
)
...
...
@@ -3084,23 +3021,36 @@ static int sbp2_module_init(void)
*/
scsi_driver_template
.
max_sectors
=
sbp2_max_sectors
;
/*
* Ideally we would register our scsi_driver_template with the
* scsi stack and after that register with the ieee1394 stack
* and process the add_host callbacks. However, the detect
* function in the scsi host template requires that we find at
* least one host, so we "nest" the registrations by calling
* sbp2_init from the detect function.
* Register our high level driver with 1394 stack
*/
scsi_driver_template
.
module
=
THIS_MODULE
;
if
(
SCSI_REGISTER_HOST
(
&
scsi_driver_template
)
||
!
scsi_driver_template
.
present
)
{
SBP2_ERR
(
"Please load the lower level IEEE-1394 driver "
"(e.g. ohci1394) before sbp2..."
);
sbp2_cleanup
();
return
-
ENODEV
;
sbp2_hl_handle
=
hpsb_register_highlevel
(
SBP2_DEVICE_NAME
,
&
sbp2_hl_ops
);
if
(
!
sbp2_hl_handle
)
{
SBP2_ERR
(
"sbp2 failed to register with ieee1394 highlevel"
);
return
(
-
ENOMEM
);
}
/*
* Register our sbp2 status address space...
*/
hpsb_register_addrspace
(
sbp2_hl_handle
,
&
sbp2_ops
,
SBP2_STATUS_FIFO_ADDRESS
,
SBP2_STATUS_FIFO_ADDRESS
+
SBP2_STATUS_FIFO_ENTRY_TO_OFFSET
(
SBP2SCSI_MAX_SCSI_IDS
+
1
));
/*
* Handle data movement if physical dma is not enabled/supported
* on host controller
*/
#ifdef CONFIG_IEEE1394_SBP2_PHYS_DMA
hpsb_register_addrspace
(
sbp2_hl_handle
,
&
sbp2_physdma_ops
,
0x0ULL
,
0xfffffffcULL
);
#endif
hpsb_register_protocol
(
&
sbp2_driver
);
return
0
;
}
...
...
@@ -3108,17 +3058,9 @@ static void __exit sbp2_module_exit(void)
{
SBP2_DEBUG
(
"sbp2_module_exit"
);
/*
* On module unload we unregister with the ieee1394 stack
* which results in remove_host callbacks for all ieee1394
* host controllers. In the callbacks we unregister the
* corresponding scsi hosts.
*/
sbp2_cleanup
();
if
(
SCSI_UNREGISTER_HOST
(
&
scsi_driver_template
))
SBP2_ERR
(
"sbp2_module_exit: couldn't unregister scsi driver"
);
hpsb_unregister_protocol
(
&
sbp2_driver
);
if
(
sbp2_hl_handle
)
hpsb_unregister_highlevel
(
sbp2_hl_handle
);
}
module_init
(
sbp2_module_init
);
...
...
drivers/ieee1394/sbp2.h
View file @
356a8fd1
...
...
@@ -22,15 +22,6 @@
#ifndef SBP2_H
#define SBP2_H
/* Some compatibility code */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
#define SCSI_REGISTER_HOST(tmpl) scsi_register_module(MODULE_SCSI_HA, tmpl)
#define SCSI_UNREGISTER_HOST(tmpl) scsi_unregister_module(MODULE_SCSI_HA, tmpl)
#else
#define SCSI_REGISTER_HOST(tmpl) scsi_register_host(tmpl)
#define SCSI_UNREGISTER_HOST(tmpl) scsi_unregister_host(tmpl)
#endif
#define SBP2_DEVICE_NAME "sbp2"
/*
...
...
@@ -442,8 +433,6 @@ static void sbp2util_mark_command_completed(struct scsi_id_instance_data *scsi_i
static
void
sbp2_add_host
(
struct
hpsb_host
*
host
);
static
struct
sbp2scsi_host_info
*
sbp2_find_host_info
(
struct
hpsb_host
*
host
);
static
void
sbp2_remove_host
(
struct
hpsb_host
*
host
);
int
sbp2_init
(
void
);
void
sbp2_cleanup
(
void
);
static
int
sbp2_probe
(
struct
unit_directory
*
ud
);
static
void
sbp2_disconnect
(
struct
unit_directory
*
ud
);
static
void
sbp2_update
(
struct
unit_directory
*
ud
);
...
...
@@ -487,23 +476,4 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id);
static
int
sbp2_set_busy_timeout
(
struct
sbp2scsi_host_info
*
hi
,
struct
scsi_id_instance_data
*
scsi_id
);
static
int
sbp2_max_speed_and_size
(
struct
sbp2scsi_host_info
*
hi
,
struct
scsi_id_instance_data
*
scsi_id
);
/*
* Scsi interface related prototypes
*/
static
int
sbp2scsi_detect
(
Scsi_Host_Template
*
tpnt
);
static
const
char
*
sbp2scsi_info
(
struct
Scsi_Host
*
host
);
void
sbp2scsi_setup
(
char
*
str
,
int
*
ints
);
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,44)
static
int
sbp2scsi_biosparam
(
struct
scsi_device
*
sdev
,
struct
block_device
*
dev
,
sector_t
capacity
,
int
geom
[]);
#else
static
int
sbp2scsi_biosparam
(
Scsi_Disk
*
disk
,
kdev_t
dev
,
int
geom
[]);
#endif
static
int
sbp2scsi_abort
(
Scsi_Cmnd
*
SCpnt
);
static
int
sbp2scsi_reset
(
Scsi_Cmnd
*
SCpnt
);
static
int
sbp2scsi_queuecommand
(
Scsi_Cmnd
*
SCpnt
,
void
(
*
done
)(
Scsi_Cmnd
*
));
static
void
sbp2scsi_complete_all_commands
(
struct
sbp2scsi_host_info
*
hi
,
struct
scsi_id_instance_data
*
scsi_id
,
u32
status
);
static
void
sbp2scsi_complete_command
(
struct
sbp2scsi_host_info
*
hi
,
struct
scsi_id_instance_data
*
scsi_id
,
u32
scsi_status
,
Scsi_Cmnd
*
SCpnt
,
void
(
*
done
)(
Scsi_Cmnd
*
));
#endif
/* SBP2_H */
drivers/ieee1394/video1394.c
View file @
356a8fd1
...
...
@@ -43,6 +43,8 @@
#include <linux/vmalloc.h>
#include <linux/timex.h>
#include <linux/mm.h>
#include <linux/ioctl32.h>
#include <linux/compat.h>
#include "ieee1394.h"
#include "ieee1394_types.h"
...
...
@@ -1338,24 +1340,152 @@ MODULE_DESCRIPTION("driver for digital video on OHCI board");
MODULE_SUPPORTED_DEVICE
(
VIDEO1394_DRIVER_NAME
);
MODULE_LICENSE
(
"GPL"
);
#ifdef CONFIG_COMPAT
#define VIDEO1394_IOC32_LISTEN_QUEUE_BUFFER \
_IOW ('#', 0x12, struct video1394_wait32)
#define VIDEO1394_IOC32_LISTEN_WAIT_BUFFER \
_IOWR('#', 0x13, struct video1394_wait32)
#define VIDEO1394_IOC32_TALK_WAIT_BUFFER \
_IOW ('#', 0x17, struct video1394_wait32)
#define VIDEO1394_IOC32_LISTEN_POLL_BUFFER \
_IOWR('#', 0x18, struct video1394_wait32)
struct
video1394_wait32
{
u32
channel
;
u32
buffer
;
struct
compat_timeval
filltime
;
};
static
int
video1394_wr_wait32
(
unsigned
int
fd
,
unsigned
int
cmd
,
unsigned
long
arg
,
struct
file
*
file
)
{
struct
video1394_wait32
wait32
;
struct
video1394_wait
wait
;
mm_segment_t
old_fs
;
int
ret
;
if
(
file
->
f_op
->
ioctl
!=
video1394_ioctl
)
return
-
EFAULT
;
if
(
copy_from_user
(
&
wait32
,
(
void
*
)
arg
,
sizeof
(
wait32
)))
return
-
EFAULT
;
wait
.
channel
=
wait32
.
channel
;
wait
.
buffer
=
wait32
.
buffer
;
wait
.
filltime
.
tv_sec
=
(
time_t
)
wait32
.
filltime
.
tv_sec
;
wait
.
filltime
.
tv_usec
=
(
suseconds_t
)
wait32
.
filltime
.
tv_usec
;
old_fs
=
get_fs
();
set_fs
(
KERNEL_DS
);
if
(
cmd
==
VIDEO1394_IOC32_LISTEN_WAIT_BUFFER
)
ret
=
video1394_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
VIDEO1394_IOC_LISTEN_WAIT_BUFFER
,
(
unsigned
long
)
&
wait
);
else
ret
=
video1394_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
VIDEO1394_IOC_LISTEN_POLL_BUFFER
,
(
unsigned
long
)
&
wait
);
set_fs
(
old_fs
);
if
(
!
ret
)
{
wait32
.
channel
=
wait
.
channel
;
wait32
.
buffer
=
wait
.
buffer
;
wait32
.
filltime
.
tv_sec
=
(
int
)
wait
.
filltime
.
tv_sec
;
wait32
.
filltime
.
tv_usec
=
(
int
)
wait
.
filltime
.
tv_usec
;
if
(
copy_to_user
((
struct
video1394_wait32
*
)
arg
,
&
wait32
,
sizeof
(
wait32
)))
ret
=
-
EFAULT
;
}
return
ret
;
}
static
int
video1394_w_wait32
(
unsigned
int
fd
,
unsigned
int
cmd
,
unsigned
long
arg
,
struct
file
*
file
)
{
struct
video1394_wait32
wait32
;
struct
video1394_wait
wait
;
mm_segment_t
old_fs
;
int
ret
;
if
(
file
->
f_op
->
ioctl
!=
video1394_ioctl
)
return
-
EFAULT
;
if
(
copy_from_user
(
&
wait32
,
(
void
*
)
arg
,
sizeof
(
wait32
)))
return
-
EFAULT
;
wait
.
channel
=
wait32
.
channel
;
wait
.
buffer
=
wait32
.
buffer
;
wait
.
filltime
.
tv_sec
=
(
time_t
)
wait32
.
filltime
.
tv_sec
;
wait
.
filltime
.
tv_usec
=
(
suseconds_t
)
wait32
.
filltime
.
tv_usec
;
old_fs
=
get_fs
();
set_fs
(
KERNEL_DS
);
if
(
cmd
==
VIDEO1394_IOC32_LISTEN_QUEUE_BUFFER
)
ret
=
video1394_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
VIDEO1394_IOC_LISTEN_QUEUE_BUFFER
,
(
unsigned
long
)
&
wait
);
else
ret
=
video1394_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
VIDEO1394_IOC_TALK_WAIT_BUFFER
,
(
unsigned
long
)
&
wait
);
set_fs
(
old_fs
);
return
ret
;
}
static
int
video1394_queue_buf32
(
unsigned
int
fd
,
unsigned
int
cmd
,
unsigned
long
arg
,
struct
file
*
file
)
{
if
(
file
->
f_op
->
ioctl
!=
video1394_ioctl
)
return
-
EFAULT
;
return
-
EFAULT
;
return
video1394_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
VIDEO1394_IOC_TALK_QUEUE_BUFFER
,
arg
);
}
#endif
/* CONFIG_COMPAT */
static
void
__exit
video1394_exit_module
(
void
)
{
#ifdef CONFIG_COMPAT
int
ret
;
ret
=
unregister_ioctl32_conversion
(
VIDEO1394_IOC_LISTEN_CHANNEL
);
ret
|=
unregister_ioctl32_conversion
(
VIDEO1394_IOC_UNLISTEN_CHANNEL
);
ret
|=
unregister_ioctl32_conversion
(
VIDEO1394_IOC_TALK_CHANNEL
);
ret
|=
unregister_ioctl32_conversion
(
VIDEO1394_IOC_UNTALK_CHANNEL
);
ret
|=
unregister_ioctl32_conversion
(
VIDEO1394_IOC32_LISTEN_QUEUE_BUFFER
);
ret
|=
unregister_ioctl32_conversion
(
VIDEO1394_IOC32_LISTEN_WAIT_BUFFER
);
ret
|=
unregister_ioctl32_conversion
(
VIDEO1394_IOC_TALK_QUEUE_BUFFER
);
ret
|=
unregister_ioctl32_conversion
(
VIDEO1394_IOC32_TALK_WAIT_BUFFER
);
ret
|=
unregister_ioctl32_conversion
(
VIDEO1394_IOC32_LISTEN_POLL_BUFFER
);
if
(
ret
)
PRINT_G
(
KERN_INFO
,
"Error unregistering ioctl32 translations"
);
#endif
hpsb_unregister_highlevel
(
hl_handle
);
devfs_unregister
(
devfs_handle
);
ieee1394_unregister_chardev
(
IEEE1394_MINOR_BLOCK_VIDEO1394
);
PRINT_G
(
KERN_INFO
,
"Removed "
VIDEO1394_DRIVER_NAME
" module"
);
}
static
int
__init
video1394_init_module
(
void
)
{
if
(
ieee1394_register_chardev
(
IEEE1394_MINOR_BLOCK_VIDEO1394
,
THIS_MODULE
,
&
video1394_fops
))
{
int
ret
;
ret
=
ieee1394_register_chardev
(
IEEE1394_MINOR_BLOCK_VIDEO1394
,
THIS_MODULE
,
&
video1394_fops
);
if
(
ret
)
{
PRINT_G
(
KERN_ERR
,
"video1394: unable to get minor device block"
);
return
-
EIO
;
}
return
-
EIO
;
}
devfs_handle
=
devfs_mk_dir
(
NULL
,
VIDEO1394_DRIVER_NAME
,
NULL
);
hl_handle
=
hpsb_register_highlevel
(
VIDEO1394_DRIVER_NAME
,
&
hl_ops
);
...
...
@@ -1366,9 +1496,32 @@ static int __init video1394_init_module (void)
return
-
ENOMEM
;
}
#ifdef CONFIG_COMPAT
/* First the compatible ones */
ret
=
register_ioctl32_conversion
(
VIDEO1394_IOC_LISTEN_CHANNEL
,
NULL
);
ret
|=
register_ioctl32_conversion
(
VIDEO1394_IOC_UNLISTEN_CHANNEL
,
NULL
);
ret
|=
register_ioctl32_conversion
(
VIDEO1394_IOC_TALK_CHANNEL
,
NULL
);
ret
|=
register_ioctl32_conversion
(
VIDEO1394_IOC_UNTALK_CHANNEL
,
NULL
);
/* These need translation */
ret
|=
register_ioctl32_conversion
(
VIDEO1394_IOC32_LISTEN_QUEUE_BUFFER
,
video1394_w_wait32
);
ret
|=
register_ioctl32_conversion
(
VIDEO1394_IOC32_LISTEN_WAIT_BUFFER
,
video1394_wr_wait32
);
ret
|=
register_ioctl32_conversion
(
VIDEO1394_IOC_TALK_QUEUE_BUFFER
,
video1394_queue_buf32
);
ret
|=
register_ioctl32_conversion
(
VIDEO1394_IOC32_TALK_WAIT_BUFFER
,
video1394_w_wait32
);
ret
|=
register_ioctl32_conversion
(
VIDEO1394_IOC32_LISTEN_POLL_BUFFER
,
video1394_wr_wait32
);
if
(
ret
)
PRINT_G
(
KERN_INFO
,
"Error registering ioctl32 translations"
);
#endif
PRINT_G
(
KERN_INFO
,
"Installed "
VIDEO1394_DRIVER_NAME
" module"
);
return
0
;
}
module_init
(
video1394_init_module
);
module_exit
(
video1394_exit_module
);
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment