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
Kirill Smelkov
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