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
db3e9f28
Commit
db3e9f28
authored
Jun 04, 2003
by
Paul Mackerras
Browse files
Options
Browse Files
Download
Plain Diff
Merge samba.org:/home/paulus/kernel/linux-2.5
into samba.org:/home/paulus/kernel/for-linus-ppc
parents
5d999784
9683c74d
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
446 additions
and
282 deletions
+446
-282
arch/sparc64/defconfig
arch/sparc64/defconfig
+7
-0
drivers/ieee1394/eth1394.c
drivers/ieee1394/eth1394.c
+342
-166
drivers/ieee1394/eth1394.h
drivers/ieee1394/eth1394.h
+18
-4
drivers/ieee1394/ieee1394.h
drivers/ieee1394/ieee1394.h
+0
-1
drivers/ieee1394/ieee1394_core.c
drivers/ieee1394/ieee1394_core.c
+0
-2
drivers/ieee1394/iso.c
drivers/ieee1394/iso.c
+1
-0
drivers/ieee1394/sbp2.c
drivers/ieee1394/sbp2.c
+5
-3
fs/eventpoll.c
fs/eventpoll.c
+55
-77
sound/core/ioctl32/pcm32.c
sound/core/ioctl32/pcm32.c
+5
-9
sound/core/ioctl32/rawmidi32.c
sound/core/ioctl32/rawmidi32.c
+3
-7
sound/core/ioctl32/timer32.c
sound/core/ioctl32/timer32.c
+4
-9
sound/drivers/vx/vx_core.c
sound/drivers/vx/vx_core.c
+1
-0
sound/sparc/cs4231.c
sound/sparc/cs4231.c
+5
-4
No files found.
arch/sparc64/defconfig
View file @
db3e9f28
...
@@ -16,6 +16,9 @@ CONFIG_SYSVIPC=y
...
@@ -16,6 +16,9 @@ CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
CONFIG_SYSCTL=y
CONFIG_LOG_BUF_SHIFT=15
CONFIG_LOG_BUF_SHIFT=15
# CONFIG_EMBEDDED is not set
CONFIG_FUTEX=y
CONFIG_EPOLL=y
#
#
# Loadable module support
# Loadable module support
...
@@ -795,6 +798,7 @@ CONFIG_IRDA_FAST_RR=y
...
@@ -795,6 +798,7 @@ CONFIG_IRDA_FAST_RR=y
# CONFIG_WINBOND_FIR is not set
# CONFIG_WINBOND_FIR is not set
# CONFIG_TOSHIBA_OLD is not set
# CONFIG_TOSHIBA_OLD is not set
# CONFIG_TOSHIBA_FIR is not set
# CONFIG_TOSHIBA_FIR is not set
# CONFIG_SMC_IRCC_OLD is not set
# CONFIG_SMC_IRCC_FIR is not set
# CONFIG_SMC_IRCC_FIR is not set
# CONFIG_ALI_FIR is not set
# CONFIG_ALI_FIR is not set
# CONFIG_VLSI_FIR is not set
# CONFIG_VLSI_FIR is not set
...
@@ -959,6 +963,8 @@ CONFIG_VFAT_FS=m
...
@@ -959,6 +963,8 @@ CONFIG_VFAT_FS=m
CONFIG_PROC_FS=y
CONFIG_PROC_FS=y
# CONFIG_DEVFS_FS is not set
# CONFIG_DEVFS_FS is not set
CONFIG_DEVPTS_FS=y
CONFIG_DEVPTS_FS=y
CONFIG_DEVPTS_FS_XATTR=y
# CONFIG_DEVPTS_FS_SECURITY is not set
# CONFIG_TMPFS is not set
# CONFIG_TMPFS is not set
CONFIG_RAMFS=y
CONFIG_RAMFS=y
...
@@ -1111,6 +1117,7 @@ CONFIG_SND_ICE1712=m
...
@@ -1111,6 +1117,7 @@ CONFIG_SND_ICE1712=m
CONFIG_SND_INTEL8X0=m
CONFIG_SND_INTEL8X0=m
CONFIG_SND_SONICVIBES=m
CONFIG_SND_SONICVIBES=m
# CONFIG_SND_VIA82XX is not set
# CONFIG_SND_VIA82XX is not set
CONFIG_SND_VX222=m
#
#
# ALSA USB devices
# ALSA USB devices
...
...
drivers/ieee1394/eth1394.c
View file @
db3e9f28
...
@@ -29,12 +29,11 @@
...
@@ -29,12 +29,11 @@
*
*
* TODO:
* TODO:
* RFC 2734 related:
* RFC 2734 related:
* - Add support for broadcast messages
* - Use EUI instead of node id in internal ARP tables
* - Add Config ROM entry
* - Add Config ROM entry
* - Add MCAP and multicast
* - Add MCAP and multicast
*
*
* Non-RFC 2734 related:
* Non-RFC 2734 related:
* - Fix bug related to fragmented broadcast datagrams
* - Move generic GASP reception to core 1394 code
* - Move generic GASP reception to core 1394 code
* - Convert kmalloc/kfree for link fragments to use kmem_cache_* instead
* - Convert kmalloc/kfree for link fragments to use kmem_cache_* instead
* - Stability improvements
* - Stability improvements
...
@@ -73,6 +72,7 @@
...
@@ -73,6 +72,7 @@
#include "ieee1394.h"
#include "ieee1394.h"
#include "highlevel.h"
#include "highlevel.h"
#include "iso.h"
#include "iso.h"
#include "nodemgr.h"
#include "eth1394.h"
#include "eth1394.h"
#define ETH1394_PRINT_G(level, fmt, args...) \
#define ETH1394_PRINT_G(level, fmt, args...) \
...
@@ -86,7 +86,7 @@
...
@@ -86,7 +86,7 @@
#define TRACE() printk(KERN_ERR "eth1394:%s[%d] ---- TRACE\n", __FUNCTION__, __LINE__)
#define TRACE() printk(KERN_ERR "eth1394:%s[%d] ---- TRACE\n", __FUNCTION__, __LINE__)
static
char
version
[]
__devinitdata
=
static
char
version
[]
__devinitdata
=
"$Rev: 9
38
$ Ben Collins <bcollins@debian.org>"
;
"$Rev: 9
45
$ Ben Collins <bcollins@debian.org>"
;
struct
fragment_info
{
struct
fragment_info
{
struct
list_head
list
;
struct
list_head
list
;
...
@@ -119,22 +119,39 @@ static const int hdr_type_len[] = {
...
@@ -119,22 +119,39 @@ static const int hdr_type_len[] = {
sizeof
(
struct
eth1394_sf_hdr
)
sizeof
(
struct
eth1394_sf_hdr
)
};
};
static
const
u16
eth1394_speedto_maxpayload
[]
=
{
/* S100, S200, S400, S800, S1600, S3200 */
512
,
1024
,
2048
,
4096
,
8192
,
16384
};
MODULE_AUTHOR
(
"Ben Collins (bcollins@debian.org)"
);
MODULE_AUTHOR
(
"Ben Collins (bcollins@debian.org)"
);
MODULE_DESCRIPTION
(
"IEEE 1394 IPv4 Driver (IPv4-over-1394 as per RFC 2734)"
);
MODULE_DESCRIPTION
(
"IEEE 1394 IPv4 Driver (IPv4-over-1394 as per RFC 2734)"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_LICENSE
(
"GPL"
);
/* The max_partial_datagrams parameter is the maximum number of fragmented
datagrams
/* The max_partial_datagrams parameter is the maximum number of fragmented
*
per node that eth1394 will keep in memory. Providing an upper bound allows us to
*
datagrams per node that eth1394 will keep in memory. Providing an upper
*
limit the amount of memory that partial datagrams consume in the event that some
*
bound allows us to limit the amount of memory that partial datagrams
*
partial datagrams are never completed. This should probably change to a sysctl
*
consume in the event that some partial datagrams are never completed. This
* item or the like if possible.
*
should probably change to a sysctl
item or the like if possible.
*/
*/
MODULE_PARM
(
max_partial_datagrams
,
"i"
);
MODULE_PARM
(
max_partial_datagrams
,
"i"
);
MODULE_PARM_DESC
(
max_partial_datagrams
,
MODULE_PARM_DESC
(
max_partial_datagrams
,
"Maximum number of partially received fragmented datagrams (default = 25)."
);
"Maximum number of partially received fragmented datagrams "
"(default = 25)."
);
static
int
max_partial_datagrams
=
25
;
static
int
max_partial_datagrams
=
25
;
static
int
ether1394_header
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
,
unsigned
short
type
,
void
*
daddr
,
void
*
saddr
,
unsigned
len
);
static
int
ether1394_rebuild_header
(
struct
sk_buff
*
skb
);
static
int
ether1394_header_parse
(
struct
sk_buff
*
skb
,
unsigned
char
*
haddr
);
static
int
ether1394_header_cache
(
struct
neighbour
*
neigh
,
struct
hh_cache
*
hh
);
static
void
ether1394_header_cache_update
(
struct
hh_cache
*
hh
,
struct
net_device
*
dev
,
unsigned
char
*
haddr
);
static
int
ether1394_mac_addr
(
struct
net_device
*
dev
,
void
*
p
);
static
inline
void
purge_partial_datagram
(
struct
list_head
*
old
);
static
inline
void
purge_partial_datagram
(
struct
list_head
*
old
);
static
int
ether1394_tx
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
);
static
int
ether1394_tx
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
);
static
void
ether1394_iso
(
struct
hpsb_iso
*
iso
);
static
void
ether1394_iso
(
struct
hpsb_iso
*
iso
);
...
@@ -258,73 +275,34 @@ static void ether1394_tx_timeout (struct net_device *dev)
...
@@ -258,73 +275,34 @@ static void ether1394_tx_timeout (struct net_device *dev)
netif_wake_queue
(
dev
);
netif_wake_queue
(
dev
);
}
}
/* Convert a standard ARP packet to 1394 ARP. The first 8 bytes (the
* entire arphdr) is the same format as the ip1394 header, so they
* overlap. The rest needs to be munged a bit. The remainder of the
* arphdr is formatted based on hwaddr len and ipaddr len. We know what
* they'll be, so it's easy to judge. */
static
inline
void
ether1394_arp_to_1394arp
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
)
{
struct
eth1394_priv
*
priv
=
(
struct
eth1394_priv
*
)(
dev
->
priv
);
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
;
unsigned
char
arp_data
[
2
*
(
dev
->
addr_len
+
4
)];
/* Copy the main data that we need */
memcpy
(
arp_data
,
arp_ptr
+
sizeof
(
struct
arphdr
),
sizeof
(
arp_data
));
/* Extend the buffer enough for our new header */
skb_put
(
skb
,
sizeof
(
struct
eth1394_arp
)
-
(
sizeof
(
arp_data
)
+
sizeof
(
struct
arphdr
)));
#define PROCESS_MEMBER(ptr,val,len) \
memcpy (val, ptr, len); ptr += len
arp_ptr
=
arp_data
+
arp1394
->
hw_addr_len
;
PROCESS_MEMBER
(
arp_ptr
,
&
arp1394
->
sip
,
arp1394
->
ip_addr_len
);
arp_ptr
+=
arp1394
->
hw_addr_len
;
PROCESS_MEMBER
(
arp_ptr
,
&
arp1394
->
tip
,
arp1394
->
ip_addr_len
);
#undef PROCESS_MEMBER
/* Now add our own flavor of arp header fields to the orig one */
arp1394
->
hw_addr_len
=
IP1394_HW_ADDR_LEN
;
arp1394
->
hw_type
=
__constant_htons
(
ARPHRD_IEEE1394
);
arp1394
->
s_uniq_id
=
cpu_to_le64
(
priv
->
eui
[
phy_id
]);
arp1394
->
max_rec
=
priv
->
max_rec
[
phy_id
];
arp1394
->
sspd
=
priv
->
sspd
[
phy_id
];
arp1394
->
fifo_hi
=
htons
(
priv
->
fifo_hi
[
phy_id
]);
arp1394
->
fifo_lo
=
htonl
(
priv
->
fifo_lo
[
phy_id
]);
return
;
}
static
int
ether1394_change_mtu
(
struct
net_device
*
dev
,
int
new_mtu
)
static
int
ether1394_change_mtu
(
struct
net_device
*
dev
,
int
new_mtu
)
{
{
if
((
new_mtu
<
68
)
||
(
new_mtu
>
ETHER1394_REGION_ADDR_LEN
))
struct
eth1394_priv
*
priv
=
(
struct
eth1394_priv
*
)
dev
->
priv
;
int
phy_id
=
NODEID_TO_NODE
(
priv
->
host
->
node_id
);
if
((
new_mtu
<
68
)
||
(
new_mtu
>
(
priv
->
maxpayload
[
phy_id
]
-
(
sizeof
(
union
eth1394_hdr
)
+
ETHER1394_GASP_OVERHEAD
))))
return
-
EINVAL
;
return
-
EINVAL
;
dev
->
mtu
=
new_mtu
;
dev
->
mtu
=
new_mtu
;
return
0
;
return
0
;
}
}
static
inline
void
ether1394_register_limits
(
int
nodeid
,
unsigned
char
max_rec
,
static
inline
void
ether1394_register_limits
(
int
nodeid
,
u16
maxpayload
,
unsigned
char
sspd
,
u64
eui
,
u16
fifo_hi
,
unsigned
char
sspd
,
u64
eui
,
u64
fifo
,
u32
fifo_lo
,
struct
eth1394_priv
*
priv
)
struct
eth1394_priv
*
priv
)
{
{
if
(
nodeid
<
0
||
nodeid
>=
ALL_NODES
)
{
if
(
nodeid
<
0
||
nodeid
>=
ALL_NODES
)
{
ETH1394_PRINT_G
(
KERN_ERR
,
"Cannot register invalid nodeid %d
\n
"
,
nodeid
);
ETH1394_PRINT_G
(
KERN_ERR
,
"Cannot register invalid nodeid %d
\n
"
,
nodeid
);
return
;
return
;
}
}
priv
->
max_rec
[
nodeid
]
=
max_rec
;
priv
->
maxpayload
[
nodeid
]
=
maxpayload
;
priv
->
sspd
[
nodeid
]
=
sspd
;
priv
->
sspd
[
nodeid
]
=
sspd
;
priv
->
fifo_hi
[
nodeid
]
=
fifo_hi
;
priv
->
fifo
[
nodeid
]
=
fifo
;
priv
->
fifo_lo
[
nodeid
]
=
fifo_lo
;
priv
->
eui
[
nodeid
]
=
eui
;
priv
->
eui
[
nodeid
]
=
eui
;
priv
->
max
_rec
[
ALL_NODES
]
=
min
(
priv
->
max_rec
[
ALL_NODES
],
max_rec
);
priv
->
max
payload
[
ALL_NODES
]
=
min
(
priv
->
maxpayload
[
ALL_NODES
],
maxpayload
);
priv
->
sspd
[
ALL_NODES
]
=
min
(
priv
->
sspd
[
ALL_NODES
],
sspd
);
priv
->
sspd
[
ALL_NODES
]
=
min
(
priv
->
sspd
[
ALL_NODES
],
sspd
);
return
;
return
;
...
@@ -335,34 +313,44 @@ static void ether1394_reset_priv (struct net_device *dev, int set_mtu)
...
@@ -335,34 +313,44 @@ static void ether1394_reset_priv (struct net_device *dev, int set_mtu)
unsigned
long
flags
;
unsigned
long
flags
;
int
i
;
int
i
;
struct
eth1394_priv
*
priv
=
(
struct
eth1394_priv
*
)
dev
->
priv
;
struct
eth1394_priv
*
priv
=
(
struct
eth1394_priv
*
)
dev
->
priv
;
int
phy_id
=
NODEID_TO_NODE
(
priv
->
host
->
node_id
);
struct
hpsb_host
*
host
=
priv
->
host
;
struct
hpsb_host
*
host
=
priv
->
host
;
int
phy_id
=
NODEID_TO_NODE
(
host
->
node_id
);
u64
guid
=
*
((
u64
*
)
&
(
host
->
csr
.
rom
[
3
]));
u16
maxpayload
=
1
<<
(((
be32_to_cpu
(
host
->
csr
.
rom
[
2
])
>>
12
)
&
0xf
)
+
1
);
spin_lock_irqsave
(
&
priv
->
lock
,
flags
);
spin_lock_irqsave
(
&
priv
->
lock
,
flags
);
/* Clear the speed/payload/offset tables */
/* Clear the speed/payload/offset tables */
memset
(
priv
->
max
_rec
,
8
,
sizeof
(
priv
->
max_rec
));
memset
(
priv
->
max
payload
,
0
,
sizeof
(
priv
->
maxpayload
));
memset
(
priv
->
sspd
,
0
,
sizeof
(
priv
->
sspd
));
memset
(
priv
->
sspd
,
0
,
sizeof
(
priv
->
sspd
));
memset
(
priv
->
fifo_hi
,
0
,
sizeof
(
priv
->
fifo_hi
));
memset
(
priv
->
fifo
,
0
,
sizeof
(
priv
->
fifo
));
memset
(
priv
->
fifo_lo
,
0
,
sizeof
(
priv
->
fifo_lo
));
#if 0
/* Compile this out to make testing of fragmented broadcast datagrams
* easier. */
priv->sspd[ALL_NODES] = SPEED_MAX;
priv->maxpayload[ALL_NODES] = eth1394_speedto_maxpayload[SPEED_MAX];
#else
priv
->
sspd
[
ALL_NODES
]
=
SPEED_100
;
priv
->
maxpayload
[
ALL_NODES
]
=
eth1394_speedto_maxpayload
[
SPEED_100
];
#endif
priv
->
bc_state
=
ETHER1394_BC_CHECK
;
priv
->
bc_state
=
ETHER1394_BC_CHECK
;
/* Register our limits now */
/* Register our limits now */
ether1394_register_limits
(
phy_id
,
(
be32_to_cpu
(
host
->
csr
.
rom
[
2
])
>>
12
)
&
0xf
,
ether1394_register_limits
(
phy_id
,
maxpayload
,
host
->
speed_map
[(
phy_id
<<
6
)
+
phy_id
],
host
->
speed_map
[(
phy_id
<<
6
)
+
phy_id
],
(
u64
)(((
u64
)
be32_to_cpu
(
host
->
csr
.
rom
[
3
])
<<
32
)
|
guid
,
ETHER1394_REGION_ADDR
,
priv
);
be32_to_cpu
(
host
->
csr
.
rom
[
4
])),
ETHER1394_REGION_ADDR
>>
32
,
/* We'll use our maxpayload as the default mtu */
ETHER1394_REGION_ADDR
&
0xffffffff
,
priv
);
if
(
set_mtu
)
{
dev
->
mtu
=
priv
->
maxpayload
[
phy_id
]
-
(
sizeof
(
union
eth1394_hdr
)
+
/* We'll use our max_rec as the default mtu */
ETHER1394_GASP_OVERHEAD
);
if
(
set_mtu
)
dev
->
mtu
=
(
1
<<
(
priv
->
max_rec
[
phy_id
]
+
1
))
-
/* Set our hardware address while we're at it */
(
sizeof
(
union
eth1394_hdr
)
+
ETHER1394_OVERHEAD
);
*
(
u64
*
)
dev
->
dev_addr
=
guid
;
*
(
u64
*
)
dev
->
broadcast
=
~
0x0ULL
;
/* Set our hardware address while we're at it */
}
*
(
nodeid_t
*
)
dev
->
dev_addr
=
htons
(
host
->
node_id
);
spin_unlock_irqrestore
(
&
priv
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
priv
->
lock
,
flags
);
...
@@ -392,11 +380,20 @@ static int ether1394_init_dev (struct net_device *dev)
...
@@ -392,11 +380,20 @@ static int ether1394_init_dev (struct net_device *dev)
dev
->
tx_timeout
=
ether1394_tx_timeout
;
dev
->
tx_timeout
=
ether1394_tx_timeout
;
dev
->
change_mtu
=
ether1394_change_mtu
;
dev
->
change_mtu
=
ether1394_change_mtu
;
dev
->
hard_header
=
ether1394_header
;
dev
->
rebuild_header
=
ether1394_rebuild_header
;
dev
->
hard_header_cache
=
ether1394_header_cache
;
dev
->
header_cache_update
=
ether1394_header_cache_update
;
dev
->
hard_header_parse
=
ether1394_header_parse
;
dev
->
set_mac_address
=
ether1394_mac_addr
;
/* Some constants */
/* Some constants */
dev
->
watchdog_timeo
=
ETHER1394_TIMEOUT
;
dev
->
watchdog_timeo
=
ETHER1394_TIMEOUT
;
dev
->
flags
=
IFF_BROADCAST
;
/*
TODO: Support MCAP
*/
dev
->
flags
=
IFF_BROADCAST
;
/*
| IFF_MULTICAST someday
*/
dev
->
features
=
NETIF_F_NO_CSUM
|
NETIF_F_SG
|
NETIF_F_HIGHDMA
|
NETIF_F_FRAGLIST
;
dev
->
features
=
NETIF_F_NO_CSUM
|
NETIF_F_SG
|
NETIF_F_HIGHDMA
|
NETIF_F_FRAGLIST
;
dev
->
addr_len
=
2
;
dev
->
addr_len
=
ETH1394_ALEN
;
dev
->
hard_header_len
=
ETH1394_HLEN
;
dev
->
type
=
ARPHRD_IEEE1394
;
ether1394_reset_priv
(
dev
,
1
);
ether1394_reset_priv
(
dev
,
1
);
...
@@ -419,6 +416,9 @@ static void ether1394_add_host (struct hpsb_host *host)
...
@@ -419,6 +416,9 @@ static void ether1394_add_host (struct hpsb_host *host)
if
(
version_printed
++
==
0
)
if
(
version_printed
++
==
0
)
ETH1394_PRINT_G
(
KERN_INFO
,
"%s
\n
"
,
version
);
ETH1394_PRINT_G
(
KERN_INFO
,
"%s
\n
"
,
version
);
/* We should really have our own alloc_hpsbdev() function in
* net_init.c instead of calling the one for ethernet then hijacking
* it for ourselves. That way we'd be a real networking device. */
dev
=
alloc_etherdev
(
sizeof
(
struct
eth1394_priv
));
dev
=
alloc_etherdev
(
sizeof
(
struct
eth1394_priv
));
if
(
dev
==
NULL
)
if
(
dev
==
NULL
)
...
@@ -468,7 +468,7 @@ static void ether1394_add_host (struct hpsb_host *host)
...
@@ -468,7 +468,7 @@ static void ether1394_add_host (struct hpsb_host *host)
out:
out:
if
(
dev
!=
NULL
)
if
(
dev
!=
NULL
)
kfree
(
dev
);
dev
=
NULL
;
kfree
(
dev
)
;
if
(
hi
)
if
(
hi
)
hpsb_destroy_hostinfo
(
&
eth1394_highlevel
,
host
);
hpsb_destroy_hostinfo
(
&
eth1394_highlevel
,
host
);
...
@@ -489,7 +489,7 @@ static void ether1394_remove_host (struct hpsb_host *host)
...
@@ -489,7 +489,7 @@ static void ether1394_remove_host (struct hpsb_host *host)
unregister_netdev
(
hi
->
dev
);
unregister_netdev
(
hi
->
dev
);
hpsb_iso_shutdown
(
priv
->
iso
);
hpsb_iso_shutdown
(
priv
->
iso
);
kfree
(
hi
->
dev
);
hi
->
dev
=
NULL
;
kfree
(
hi
->
dev
)
;
}
}
return
;
return
;
...
@@ -513,31 +513,140 @@ static void ether1394_host_reset (struct hpsb_host *host)
...
@@ -513,31 +513,140 @@ static void ether1394_host_reset (struct hpsb_host *host)
netif_wake_queue
(
dev
);
netif_wake_queue
(
dev
);
}
}
/******************************************
* HW Header net device functions
******************************************/
/* These functions have been adapted from net/ethernet/eth.c */
/* Create a fake MAC header for an arbitrary protocol layer.
* saddr=NULL means use device source address
* daddr=NULL means leave destination address (eg unresolved arp). */
static
int
ether1394_header
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
,
unsigned
short
type
,
void
*
daddr
,
void
*
saddr
,
unsigned
len
)
{
struct
eth1394hdr
*
eth
=
(
struct
eth1394hdr
*
)
skb_push
(
skb
,
ETH1394_HLEN
);
eth
->
h_proto
=
htons
(
type
);
if
(
dev
->
flags
&
(
IFF_LOOPBACK
|
IFF_NOARP
))
{
memset
(
eth
->
h_dest
,
0
,
dev
->
addr_len
);
return
(
dev
->
hard_header_len
);
}
if
(
daddr
)
{
memcpy
(
eth
->
h_dest
,
daddr
,
dev
->
addr_len
);
return
dev
->
hard_header_len
;
}
return
-
dev
->
hard_header_len
;
}
/* Rebuild the faked MAC header. This is called after an ARP
* (or in future other address resolution) has completed on this
* sk_buff. We now let ARP fill in the other fields.
*
* This routine CANNOT use cached dst->neigh!
* Really, it is used only when dst->neigh is wrong.
*/
static
int
ether1394_rebuild_header
(
struct
sk_buff
*
skb
)
{
struct
eth1394hdr
*
eth
=
(
struct
eth1394hdr
*
)
skb
->
data
;
struct
net_device
*
dev
=
skb
->
dev
;
switch
(
eth
->
h_proto
)
{
#ifdef CONFIG_INET
case
__constant_htons
(
ETH_P_IP
):
return
arp_find
((
unsigned
char
*
)
&
eth
->
h_dest
,
skb
);
#endif
default:
printk
(
KERN_DEBUG
"%s: unable to resolve type %X addresses.
\n
"
,
dev
->
name
,
(
int
)
eth
->
h_proto
);
break
;
}
return
0
;
}
static
int
ether1394_header_parse
(
struct
sk_buff
*
skb
,
unsigned
char
*
haddr
)
{
struct
net_device
*
dev
=
skb
->
dev
;
memcpy
(
haddr
,
dev
->
dev_addr
,
ETH1394_ALEN
);
return
ETH_ALEN
;
}
static
int
ether1394_header_cache
(
struct
neighbour
*
neigh
,
struct
hh_cache
*
hh
)
{
unsigned
short
type
=
hh
->
hh_type
;
struct
eth1394hdr
*
eth
=
(
struct
eth1394hdr
*
)(((
u8
*
)
hh
->
hh_data
)
+
6
);
struct
net_device
*
dev
=
neigh
->
dev
;
if
(
type
==
__constant_htons
(
ETH_P_802_3
))
{
return
-
1
;
}
eth
->
h_proto
=
type
;
memcpy
(
eth
->
h_dest
,
neigh
->
ha
,
dev
->
addr_len
);
hh
->
hh_len
=
ETH1394_HLEN
;
return
0
;
}
/* Called by Address Resolution module to notify changes in address. */
static
void
ether1394_header_cache_update
(
struct
hh_cache
*
hh
,
struct
net_device
*
dev
,
unsigned
char
*
haddr
)
{
memcpy
(((
u8
*
)
hh
->
hh_data
)
+
6
,
haddr
,
dev
->
addr_len
);
}
static
int
ether1394_mac_addr
(
struct
net_device
*
dev
,
void
*
p
)
{
if
(
netif_running
(
dev
))
return
-
EBUSY
;
/* Not going to allow setting the MAC address, we really need to use
* the real one suppliled by the hardware */
return
-
EINVAL
;
}
/******************************************
/******************************************
* Datagram reception code
* Datagram reception code
******************************************/
******************************************/
/* Copied from net/ethernet/eth.c */
/* Copied from net/ethernet/eth.c */
static
inline
unsigned
short
ether1394_type_trans
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
)
static
inline
u16
ether1394_type_trans
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
)
{
{
struct
ethhdr
*
eth
;
struct
eth
1394
hdr
*
eth
;
unsigned
char
*
rawp
;
unsigned
char
*
rawp
;
skb
->
mac
.
raw
=
skb
->
data
;
skb
->
mac
.
raw
=
skb
->
data
;
skb_pull
(
skb
,
ETH_HLEN
);
skb_pull
(
skb
,
ETH
1394
_HLEN
);
eth
=
skb
->
mac
.
ethernet
;
eth
=
(
struct
eth1394hdr
*
)
skb
->
mac
.
raw
;
#if 0
if
(
*
eth
->
h_dest
&
1
)
{
if
(
*
eth
->
h_dest
&
1
)
{
if
(
memcmp
(
eth
->
h_dest
,
dev
->
broadcast
,
dev
->
addr_len
)
==
0
)
if
(
memcmp
(
eth
->
h_dest
,
dev
->
broadcast
,
dev
->
addr_len
)
==
0
)
skb
->
pkt_type
=
PACKET_BROADCAST
;
skb
->
pkt_type
=
PACKET_BROADCAST
;
#if 0
else
else
skb->pkt_type = PACKET_MULTICAST;
skb->pkt_type = PACKET_MULTICAST;
#endif
}
else
{
}
else
{
if
(
memcmp
(
eth
->
h_dest
,
dev
->
dev_addr
,
dev
->
addr_len
))
if
(
memcmp
(
eth
->
h_dest
,
dev
->
dev_addr
,
dev
->
addr_len
))
skb
->
pkt_type
=
PACKET_OTHERHOST
;
skb
->
pkt_type
=
PACKET_OTHERHOST
;
}
}
#endif
if
(
ntohs
(
eth
->
h_proto
)
>=
1536
)
if
(
ntohs
(
eth
->
h_proto
)
>=
1536
)
return
eth
->
h_proto
;
return
eth
->
h_proto
;
...
@@ -551,56 +660,72 @@ static inline unsigned short ether1394_type_trans(struct sk_buff *skb, struct ne
...
@@ -551,56 +660,72 @@ static inline unsigned short ether1394_type_trans(struct sk_buff *skb, struct ne
/* Parse an encapsulated IP1394 header into an ethernet frame packet.
/* Parse an encapsulated IP1394 header into an ethernet frame packet.
* We also perform ARP translation here, if need be. */
* We also perform ARP translation here, if need be. */
static
inline
unsigned
short
ether1394_parse_encap
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
,
static
inline
u16
ether1394_parse_encap
(
struct
sk_buff
*
skb
,
nodeid_t
srcid
,
nodeid_t
destid
,
u16
ether_type
)
struct
net_device
*
dev
,
nodeid_t
srcid
,
nodeid_t
destid
,
u16
ether_type
)
{
{
unsigned
char
src_hw
[
ETH_ALEN
],
dest_hw
[
ETH_ALEN
];
struct
eth1394_priv
*
priv
=
(
struct
eth1394_priv
*
)
dev
->
priv
;
u64
dest_hw
;
unsigned
short
ret
=
0
;
unsigned
short
ret
=
0
;
/* Setup our hw addresses. We use these to build the
/* Setup our hw addresses. We use these to build the
* ethernet header. */
* ethernet header. */
*
(
u16
*
)
dest_hw
=
htons
(
destid
);
if
(
destid
==
(
LOCAL_BUS
|
ALL_NODES
))
*
(
u16
*
)
src_hw
=
htons
(
srcid
);
dest_hw
=
~
0ULL
;
/* broadcast */
else
dest_hw
=
priv
->
eui
[
NODEID_TO_NODE
(
destid
)];
/* If this is an ARP packet, convert it. First, we want to make
/* If this is an ARP packet, convert it. First, we want to make
* use of some of the fields, since they tell us a little bit
* use of some of the fields, since they tell us a little bit
* about the sending machine. */
* about the sending machine. */
if
(
ether_type
==
__constant_htons
(
ETH_P_ARP
))
{
if
(
ether_type
==
__constant_htons
(
ETH_P_ARP
))
{
unsigned
long
flags
;
unsigned
long
flags
;
u16
phy_id
=
NODEID_TO_NODE
(
srcid
);
struct
eth1394_arp
*
arp1394
=
(
struct
eth1394_arp
*
)
skb
->
data
;
struct
eth1394_priv
*
priv
=
(
struct
eth1394_priv
*
)
dev
->
priv
;
struct
eth1394_arp
arp1394
;
struct
arphdr
*
arp
=
(
struct
arphdr
*
)
skb
->
data
;
struct
arphdr
*
arp
=
(
struct
arphdr
*
)
skb
->
data
;
unsigned
char
*
arp_ptr
=
(
unsigned
char
*
)(
arp
+
1
);
unsigned
char
*
arp_ptr
=
(
unsigned
char
*
)(
arp
+
1
);
u64
fifo_addr
=
(
u64
)
ntohs
(
arp1394
->
fifo_hi
)
<<
32
|
ntohl
(
arp1394
->
fifo_lo
);
u8
host_max_rec
=
(
be32_to_cpu
(
priv
->
host
->
csr
.
rom
[
2
])
>>
12
)
&
0xf
;
u8
max_rec
=
min
(
host_max_rec
,
(
u8
)(
arp1394
->
max_rec
));
u16
maxpayload
=
min
(
eth1394_speedto_maxpayload
[
arp1394
->
sspd
],
(
u16
)(
1
<<
(
max_rec
+
1
)));
memcpy
(
&
arp1394
,
arp
,
sizeof
(
struct
eth1394_arp
));
/* Update our speed/payload/fifo_offset table */
/* Update our speed/payload/fifo_offset table */
spin_lock_irqsave
(
&
priv
->
lock
,
flags
);
spin_lock_irqsave
(
&
priv
->
lock
,
flags
);
ether1394_register_limits
(
phy_id
,
arp1394
.
max_rec
,
arp1394
.
sspd
,
ether1394_register_limits
(
NODEID_TO_NODE
(
srcid
),
maxpayload
,
le64_to_cpu
(
arp1394
.
s_uniq_id
),
arp1394
->
sspd
,
arp1394
->
s_uniq_id
,
ntohs
(
arp1394
.
fifo_hi
),
fifo_addr
,
priv
);
ntohl
(
arp1394
.
fifo_lo
),
priv
);
spin_unlock_irqrestore
(
&
priv
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
priv
->
lock
,
flags
);
#define PROCESS_MEMBER(ptr,val,len) \
/* Now that we're done with the 1394 specific stuff, we'll
memcpy (ptr, val, len); ptr += len
* need to alter some of the data. Believe it or not, all
PROCESS_MEMBER
(
arp_ptr
,
src_hw
,
dev
->
addr_len
);
* that needs to be done is sender_IP_address needs to be
PROCESS_MEMBER
(
arp_ptr
,
&
arp1394
.
sip
,
4
);
* moved, the destination hardware address get stuffed
PROCESS_MEMBER
(
arp_ptr
,
dest_hw
,
dev
->
addr_len
);
* in and the hardware address length set to 8.
PROCESS_MEMBER
(
arp_ptr
,
&
arp1394
.
tip
,
4
);
*
#undef PROCESS_MEMBER
* IMPORTANT: The code below overwrites 1394 specific data
* needed above data so keep the call to
arp
->
ar_hln
=
dev
->
addr_len
;
* ether1394_register_limits() before munging the data for the
arp
->
ar_hrd
=
__constant_htons
(
ARPHRD_ETHER
);
* higher level IP stack. */
skb_trim
(
skb
,
sizeof
(
struct
arphdr
)
+
2
*
(
dev
->
addr_len
+
4
));
arp
->
ar_hln
=
8
;
arp_ptr
+=
arp
->
ar_hln
;
/* skip over sender unique id */
*
(
u32
*
)
arp_ptr
=
arp1394
->
sip
;
/* move sender IP addr */
arp_ptr
+=
arp
->
ar_pln
;
/* skip over sender IP addr */
if
(
arp
->
ar_op
==
1
)
/* just set ARP req target unique ID to 0 */
memset
(
arp_ptr
,
0
,
ETH1394_ALEN
);
else
memcpy
(
arp_ptr
,
dev
->
dev_addr
,
ETH1394_ALEN
);
}
}
/* Now add the ethernet header. */
/* Now add the ethernet header. */
if
(
dev
->
hard_header
(
skb
,
dev
,
__constant_ntohs
(
ether_type
),
if
(
dev
->
hard_header
(
skb
,
dev
,
__constant_ntohs
(
ether_type
),
dest_hw
,
src_hw
,
skb
->
len
)
>=
0
)
&
dest_hw
,
NULL
,
skb
->
len
)
>=
0
)
ret
=
ether1394_type_trans
(
skb
,
dev
);
ret
=
ether1394_type_trans
(
skb
,
dev
);
return
ret
;
return
ret
;
...
@@ -651,7 +776,7 @@ static inline int new_fragment(struct list_head *frag_info, int offset, int len)
...
@@ -651,7 +776,7 @@ static inline int new_fragment(struct list_head *frag_info, int offset, int len)
/* glue fragments together */
/* glue fragments together */
fi
->
len
+=
fi2
->
len
;
fi
->
len
+=
fi2
->
len
;
list_del
(
lh
->
next
);
list_del
(
lh
->
next
);
kfree
(
fi2
);
fi2
=
NULL
;
kfree
(
fi2
);
}
}
return
0
;
return
0
;
}
else
if
((
offset
+
len
)
==
fi
->
offset
)
{
}
else
if
((
offset
+
len
)
==
fi
->
offset
)
{
...
@@ -664,7 +789,7 @@ static inline int new_fragment(struct list_head *frag_info, int offset, int len)
...
@@ -664,7 +789,7 @@ static inline int new_fragment(struct list_head *frag_info, int offset, int len)
/* glue fragments together */
/* glue fragments together */
fi2
->
len
+=
fi
->
len
;
fi2
->
len
+=
fi
->
len
;
list_del
(
lh
);
list_del
(
lh
);
kfree
(
fi
);
fi
=
NULL
;
kfree
(
fi
);
}
}
return
0
;
return
0
;
}
else
if
(
offset
>
(
fi
->
offset
+
fi
->
len
))
{
}
else
if
(
offset
>
(
fi
->
offset
+
fi
->
len
))
{
...
@@ -701,7 +826,7 @@ static inline int new_partial_datagram(struct net_device *dev,
...
@@ -701,7 +826,7 @@ static inline int new_partial_datagram(struct net_device *dev,
INIT_LIST_HEAD
(
&
new
->
frag_info
);
INIT_LIST_HEAD
(
&
new
->
frag_info
);
if
(
new_fragment
(
&
new
->
frag_info
,
frag_off
,
frag_len
)
<
0
)
{
if
(
new_fragment
(
&
new
->
frag_info
,
frag_off
,
frag_len
)
<
0
)
{
kfree
(
new
);
new
=
NULL
;
kfree
(
new
);
return
-
ENOMEM
;
return
-
ENOMEM
;
}
}
...
@@ -713,8 +838,8 @@ static inline int new_partial_datagram(struct net_device *dev,
...
@@ -713,8 +838,8 @@ static inline int new_partial_datagram(struct net_device *dev,
struct
fragment_info
*
fi
=
list_entry
(
new
->
frag_info
.
next
,
struct
fragment_info
*
fi
=
list_entry
(
new
->
frag_info
.
next
,
struct
fragment_info
,
struct
fragment_info
,
list
);
list
);
kfree
(
fi
);
fi
=
NULL
;
kfree
(
fi
);
kfree
(
new
);
new
=
NULL
;
kfree
(
new
);
return
-
ENOMEM
;
return
-
ENOMEM
;
}
}
...
@@ -754,11 +879,11 @@ static inline void purge_partial_datagram(struct list_head *old)
...
@@ -754,11 +879,11 @@ static inline void purge_partial_datagram(struct list_head *old)
list_for_each_safe
(
lh
,
n
,
&
pd
->
frag_info
)
{
list_for_each_safe
(
lh
,
n
,
&
pd
->
frag_info
)
{
struct
fragment_info
*
fi
=
list_entry
(
lh
,
struct
fragment_info
,
list
);
struct
fragment_info
*
fi
=
list_entry
(
lh
,
struct
fragment_info
,
list
);
list_del
(
lh
);
list_del
(
lh
);
kfree
(
fi
);
fi
=
NULL
;
kfree
(
fi
);
}
}
list_del
(
old
);
list_del
(
old
);
kfree_skb
(
pd
->
skb
);
pd
->
skb
=
NULL
;
kfree_skb
(
pd
->
skb
);
kfree
(
pd
);
pd
=
NULL
;
kfree
(
pd
);
}
}
static
inline
int
is_datagram_complete
(
struct
list_head
*
lh
,
int
dg_size
)
static
inline
int
is_datagram_complete
(
struct
list_head
*
lh
,
int
dg_size
)
...
@@ -805,11 +930,6 @@ static int ether1394_data_handler(struct net_device *dev, int srcid, int destid,
...
@@ -805,11 +930,6 @@ static int ether1394_data_handler(struct net_device *dev, int srcid, int destid,
memcpy
(
skb_put
(
skb
,
len
-
hdr_len
),
buf
+
hdr_len
,
len
-
hdr_len
);
memcpy
(
skb_put
(
skb
,
len
-
hdr_len
),
buf
+
hdr_len
,
len
-
hdr_len
);
ether_type
=
hdr
->
uf
.
ether_type
;
ether_type
=
hdr
->
uf
.
ether_type
;
}
else
{
}
else
{
#if 0
return 0;
}
if(0) {
#endif
/* A datagram fragment has been received, now the fun begins. */
/* A datagram fragment has been received, now the fun begins. */
struct
list_head
*
pdgl
,
*
lh
;
struct
list_head
*
pdgl
,
*
lh
;
...
@@ -836,7 +956,6 @@ static int ether1394_data_handler(struct net_device *dev, int srcid, int destid,
...
@@ -836,7 +956,6 @@ static int ether1394_data_handler(struct net_device *dev, int srcid, int destid,
dg_size
=
hdr
->
sf
.
dg_size
;
dg_size
=
hdr
->
sf
.
dg_size
;
fg_off
=
hdr
->
sf
.
fg_off
;
fg_off
=
hdr
->
sf
.
fg_off
;
}
}
spin_lock_irqsave
(
&
pdg
->
lock
,
flags
);
spin_lock_irqsave
(
&
pdg
->
lock
,
flags
);
pdgl
=
&
(
pdg
->
list
);
pdgl
=
&
(
pdg
->
list
);
...
@@ -1010,7 +1129,8 @@ static void ether1394_iso(struct hpsb_iso *iso)
...
@@ -1010,7 +1129,8 @@ static void ether1394_iso(struct hpsb_iso *iso)
/* This packet is not for us */
/* This packet is not for us */
continue
;
continue
;
}
}
ether1394_data_handler
(
dev
,
source_id
,
iso
->
host
->
node_id
,
buf
,
len
);
ether1394_data_handler
(
dev
,
source_id
,
LOCAL_BUS
|
ALL_NODES
,
buf
,
len
);
}
}
hpsb_iso_recv_release_packets
(
iso
,
i
);
hpsb_iso_recv_release_packets
(
iso
,
i
);
...
@@ -1022,6 +1142,39 @@ static void ether1394_iso(struct hpsb_iso *iso)
...
@@ -1022,6 +1142,39 @@ static void ether1394_iso(struct hpsb_iso *iso)
* Datagram transmission code
* Datagram transmission code
******************************************/
******************************************/
/* Convert a standard ARP packet to 1394 ARP. The first 8 bytes (the entire
* arphdr) is the same format as the ip1394 header, so they overlap. The rest
* needs to be munged a bit. The remainder of the arphdr is formatted based
* on hwaddr len and ipaddr len. We know what they'll be, so it's easy to
* judge.
*
* Now that the EUI is used for the hardware address all we need to do to make
* this work for 1394 is to insert 2 quadlets that contain max_rec size,
* speed, and unicast FIFO address information between the sender_unique_id
* and the IP addresses.
*/
static
inline
void
ether1394_arp_to_1394arp
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
)
{
struct
eth1394_priv
*
priv
=
(
struct
eth1394_priv
*
)(
dev
->
priv
);
u16
phy_id
=
NODEID_TO_NODE
(
priv
->
host
->
node_id
);
struct
arphdr
*
arp
=
(
struct
arphdr
*
)
skb
->
data
;
unsigned
char
*
arp_ptr
=
(
unsigned
char
*
)(
arp
+
1
);
struct
eth1394_arp
*
arp1394
=
(
struct
eth1394_arp
*
)
skb
->
data
;
/* Believe it or not, all that need to happen is sender IP get moved
* and set hw_addr_len, max_rec, sspd, fifo_hi and fifo_lo. */
arp1394
->
hw_addr_len
=
16
;
arp1394
->
sip
=
*
(
u32
*
)(
arp_ptr
+
ETH1394_ALEN
);
arp1394
->
max_rec
=
(
be32_to_cpu
(
priv
->
host
->
csr
.
rom
[
2
])
>>
12
)
&
0xf
;
arp1394
->
sspd
=
priv
->
sspd
[
phy_id
];
arp1394
->
fifo_hi
=
htons
(
priv
->
fifo
[
phy_id
]
>>
32
);
arp1394
->
fifo_lo
=
htonl
(
priv
->
fifo
[
phy_id
]
&
~
0x0
);
return
;
}
/* We need to encapsulate the standard header with our own. We use the
/* We need to encapsulate the standard header with our own. We use the
* ethernet header's proto for our own. */
* ethernet header's proto for our own. */
static
inline
unsigned
int
ether1394_encapsulate_prep
(
unsigned
int
max_payload
,
static
inline
unsigned
int
ether1394_encapsulate_prep
(
unsigned
int
max_payload
,
...
@@ -1042,7 +1195,6 @@ static inline unsigned int ether1394_encapsulate_prep(unsigned int max_payload,
...
@@ -1042,7 +1195,6 @@ static inline unsigned int ether1394_encapsulate_prep(unsigned int max_payload,
hdr
->
ff
.
dgl
=
dgl
;
hdr
->
ff
.
dgl
=
dgl
;
adj_max_payload
=
max_payload
-
hdr_type_len
[
ETH1394_HDR_LF_FF
];
adj_max_payload
=
max_payload
-
hdr_type_len
[
ETH1394_HDR_LF_FF
];
}
}
return
((
dg_size
+
(
adj_max_payload
-
1
))
/
adj_max_payload
);
return
((
dg_size
+
(
adj_max_payload
-
1
))
/
adj_max_payload
);
}
}
...
@@ -1132,27 +1284,33 @@ static inline int ether1394_prep_write_packet(struct hpsb_packet *p,
...
@@ -1132,27 +1284,33 @@ static inline int ether1394_prep_write_packet(struct hpsb_packet *p,
}
}
static
inline
void
ether1394_prep_gasp_packet
(
struct
hpsb_packet
*
p
,
static
inline
void
ether1394_prep_gasp_packet
(
struct
hpsb_packet
*
p
,
struct
hpsb_host
*
host
,
struct
eth1394_priv
*
priv
,
struct
sk_buff
*
skb
,
int
length
)
struct
sk_buff
*
skb
,
int
length
)
{
{
p
->
header_size
=
4
;
p
->
header_size
=
4
;
p
->
tcode
=
TCODE_STREAM_DATA
;
p
->
tcode
=
TCODE_STREAM_DATA
;
p
->
header
[
0
]
=
(
length
<<
16
)
|
(
3
<<
14
)
p
->
header
[
0
]
=
(
length
<<
16
)
|
(
3
<<
14
)
|
((
host
->
csr
.
broadcast_channel
&
0x3f
)
<<
8
)
|
((
priv
->
broadcast_channel
)
<<
8
)
|
(
TCODE_STREAM_DATA
<<
4
);
|
(
TCODE_STREAM_DATA
<<
4
);
p
->
data_size
=
length
;
p
->
data_size
=
length
;
p
->
data
=
(
quadlet_t
*
)
skb_push
(
skb
,
2
*
sizeof
(
quadlet_t
))
;
p
->
data
=
(
(
quadlet_t
*
)
skb
->
data
)
-
2
;
p
->
data
[
0
]
=
cpu_to_be32
((
host
->
node_id
<<
16
)
|
p
->
data
[
0
]
=
cpu_to_be32
((
priv
->
host
->
node_id
<<
16
)
|
ETHER1394_GASP_SPECIFIER_ID_HI
);
ETHER1394_GASP_SPECIFIER_ID_HI
);
p
->
data
[
1
]
=
cpu_to_be32
((
ETHER1394_GASP_SPECIFIER_ID_LO
<<
24
)
|
p
->
data
[
1
]
=
cpu_to_be32
((
ETHER1394_GASP_SPECIFIER_ID_LO
<<
24
)
|
ETHER1394_GASP_VERSION
);
ETHER1394_GASP_VERSION
);
/* Setting the node id to ALL_NODES (not LOCAL_BUS | ALL_NODES)
* prevents hpsb_send_packet() from setting the speed to an arbitrary
* value based on packet->node_id if packet->node_id is not set. */
p
->
node_id
=
ALL_NODES
;
p
->
speed_code
=
priv
->
sspd
[
ALL_NODES
];
}
}
static
inline
void
ether1394_free_packet
(
struct
hpsb_packet
*
packet
)
static
inline
void
ether1394_free_packet
(
struct
hpsb_packet
*
packet
)
{
{
packet
->
data
=
NULL
;
packet
->
data
=
NULL
;
free_hpsb_packet
(
packet
);
packet
=
NULL
;
free_hpsb_packet
(
packet
);
}
}
static
void
ether1394_complete_cb
(
void
*
__ptask
);
static
void
ether1394_complete_cb
(
void
*
__ptask
);
...
@@ -1168,8 +1326,7 @@ static int ether1394_send_packet(struct packet_task *ptask, unsigned int tx_len)
...
@@ -1168,8 +1326,7 @@ static int ether1394_send_packet(struct packet_task *ptask, unsigned int tx_len)
if
(
ptask
->
tx_type
==
ETH1394_GASP
)
{
if
(
ptask
->
tx_type
==
ETH1394_GASP
)
{
int
length
=
tx_len
+
(
2
*
sizeof
(
quadlet_t
));
int
length
=
tx_len
+
(
2
*
sizeof
(
quadlet_t
));
ether1394_prep_gasp_packet
(
packet
,
priv
->
host
,
ether1394_prep_gasp_packet
(
packet
,
priv
,
ptask
->
skb
,
length
);
ptask
->
skb
,
length
);
}
else
{
}
else
{
if
(
ether1394_prep_write_packet
(
packet
,
priv
->
host
,
if
(
ether1394_prep_write_packet
(
packet
,
priv
->
host
,
...
@@ -1212,8 +1369,8 @@ static inline void ether1394_dg_complete(struct packet_task *ptask, int fail)
...
@@ -1212,8 +1369,8 @@ static inline void ether1394_dg_complete(struct packet_task *ptask, int fail)
spin_unlock_irqrestore
(
&
priv
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
priv
->
lock
,
flags
);
}
}
dev_kfree_skb_any
(
skb
);
skb
=
NULL
;
dev_kfree_skb_any
(
skb
);
kmem_cache_free
(
packet_task_cache
,
ptask
);
ptask
=
NULL
;
kmem_cache_free
(
packet_task_cache
,
ptask
);
}
}
...
@@ -1230,7 +1387,7 @@ static void ether1394_complete_cb(void *__ptask)
...
@@ -1230,7 +1387,7 @@ static void ether1394_complete_cb(void *__ptask)
hpsb_free_tlabel
(
packet
);
hpsb_free_tlabel
(
packet
);
}
}
ether1394_free_packet
(
packet
);
packet
=
ptask
->
packet
=
NULL
;
ether1394_free_packet
(
packet
);
ptask
->
outstanding_pkts
--
;
ptask
->
outstanding_pkts
--
;
if
(
ptask
->
outstanding_pkts
>
0
&&
!
fail
)
if
(
ptask
->
outstanding_pkts
>
0
&&
!
fail
)
...
@@ -1253,7 +1410,7 @@ static void ether1394_complete_cb(void *__ptask)
...
@@ -1253,7 +1410,7 @@ static void ether1394_complete_cb(void *__ptask)
static
int
ether1394_tx
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
)
static
int
ether1394_tx
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
)
{
{
int
kmflags
=
in_interrupt
()
?
GFP_ATOMIC
:
GFP_KERNEL
;
int
kmflags
=
in_interrupt
()
?
GFP_ATOMIC
:
GFP_KERNEL
;
struct
ethhdr
*
eth
;
struct
eth
1394
hdr
*
eth
;
struct
eth1394_priv
*
priv
=
(
struct
eth1394_priv
*
)
dev
->
priv
;
struct
eth1394_priv
*
priv
=
(
struct
eth1394_priv
*
)
dev
->
priv
;
int
proto
;
int
proto
;
unsigned
long
flags
;
unsigned
long
flags
;
...
@@ -1265,6 +1422,7 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev)
...
@@ -1265,6 +1422,7 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev)
u16
dg_size
;
u16
dg_size
;
u16
dgl
;
u16
dgl
;
struct
packet_task
*
ptask
;
struct
packet_task
*
ptask
;
struct
node_entry
*
ne
;
ptask
=
kmem_cache_alloc
(
packet_task_cache
,
kmflags
);
ptask
=
kmem_cache_alloc
(
packet_task_cache
,
kmflags
);
if
(
ptask
==
NULL
)
{
if
(
ptask
==
NULL
)
{
...
@@ -1295,34 +1453,44 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev)
...
@@ -1295,34 +1453,44 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev)
goto
fail
;
goto
fail
;
}
}
/* Get rid of the ethernet header, but save a pointer */
/* Get rid of the fake eth1394 header, but save a pointer */
eth
=
(
struct
ethhdr
*
)
skb
->
data
;
eth
=
(
struct
eth1394hdr
*
)
skb
->
data
;
skb_pull
(
skb
,
ETH_HLEN
);
skb_pull
(
skb
,
ETH1394_HLEN
);
ne
=
hpsb_guid_get_entry
(
be64_to_cpu
(
*
(
u64
*
)
eth
->
h_dest
));
if
(
!
ne
)
dest_node
=
LOCAL_BUS
|
ALL_NODES
;
else
dest_node
=
ne
->
nodeid
;
/* Save the destination id, and proto for our encapsulation, then
* toss the ethernet header aside like the cheap whore it is. */
dest_node
=
ntohs
(
*
(
nodeid_t
*
)(
eth
->
h_dest
));
proto
=
eth
->
h_proto
;
proto
=
eth
->
h_proto
;
/* If this is an ARP packet, convert it */
/* If this is an ARP packet, convert it */
if
(
proto
==
__constant_htons
(
ETH_P_ARP
))
if
(
proto
==
__constant_htons
(
ETH_P_ARP
))
ether1394_arp_to_1394arp
(
skb
,
dev
);
ether1394_arp_to_1394arp
(
skb
,
dev
);
max_payload
=
1
<<
(
min
(
priv
->
max_rec
[
NODEID_TO_NODE
(
priv
->
host
->
node_id
)],
max_payload
=
priv
->
maxpayload
[
NODEID_TO_NODE
(
dest_node
)];
priv
->
max_rec
[
NODEID_TO_NODE
(
dest_node
)])
+
1
);
if
(
max_payload
<
512
)
/* This check should be unnecessary, but we'll keep it for safety for
* a while longer. */
if
(
max_payload
<
512
)
{
ETH1394_PRINT
(
KERN_WARNING
,
dev
->
name
,
"max_payload too small: %d (setting to 512)
\n
"
,
max_payload
);
max_payload
=
512
;
max_payload
=
512
;
}
/* Set the transmission type for the packet. Right now only ARP
/* Set the transmission type for the packet. ARP packets and IP
* packets are sent via GASP. IP broadcast and IP multicast are not
* broadcast packets are sent via GASP, however, we cheat a little bit
* yet supported properly, they too should use GASP. */
* when detecting IP broadcast packets. This will need to change when
switch
(
proto
)
{
* we switch from using node id for the hardware address to the EUI
case
__constant_htons
(
ETH_P_ARP
):
* which we should be using instead. IP multicast is not yet
* supported. */
if
((
memcmp
(
eth
->
h_dest
,
dev
->
broadcast
,
ETH1394_ALEN
)
==
0
)
||
(
proto
==
__constant_htons
(
ETH_P_ARP
)))
{
tx_type
=
ETH1394_GASP
;
tx_type
=
ETH1394_GASP
;
max_payload
-=
ETHER1394_OVERHEAD
;
max_payload
-=
ETHER1394_GASP_OVERHEAD
;
break
;
}
else
{
default:
tx_type
=
ETH1394_WRREQ
;
tx_type
=
ETH1394_WRREQ
;
}
}
...
@@ -1345,9 +1513,17 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev)
...
@@ -1345,9 +1513,17 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev)
if
(
tx_type
!=
ETH1394_GASP
)
{
if
(
tx_type
!=
ETH1394_GASP
)
{
u64
addr
;
u64
addr
;
/* This test is just temporary until ConfigROM support has
* been added to eth1394. Until then, we need an ARP packet
* after a bus reset from the current destination node so that
* we can get FIFO information. */
if
(
priv
->
fifo
[
NODEID_TO_NODE
(
dest_node
)]
==
0ULL
)
{
ret
=
-
EAGAIN
;
goto
fail
;
}
spin_lock_irqsave
(
&
priv
->
lock
,
flags
);
spin_lock_irqsave
(
&
priv
->
lock
,
flags
);
addr
=
(
u64
)
priv
->
fifo_hi
[
NODEID_TO_NODE
(
dest_node
)]
<<
32
|
addr
=
priv
->
fifo
[
NODEID_TO_NODE
(
dest_node
)];
priv
->
fifo_lo
[
NODEID_TO_NODE
(
dest_node
)];
spin_unlock_irqrestore
(
&
priv
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
priv
->
lock
,
flags
);
ptask
->
addr
=
addr
;
ptask
->
addr
=
addr
;
...
@@ -1370,11 +1546,11 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev)
...
@@ -1370,11 +1546,11 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev)
return
0
;
return
0
;
fail:
fail:
if
(
ptask
->
packet
)
if
(
ptask
->
packet
)
ether1394_free_packet
(
ptask
->
packet
);
ptask
->
packet
=
NULL
;
ether1394_free_packet
(
ptask
->
packet
);
if
(
ptask
)
if
(
ptask
)
kmem_cache_free
(
packet_task_cache
,
ptask
);
ptask
=
NULL
;
kmem_cache_free
(
packet_task_cache
,
ptask
);
if
(
skb
!=
NULL
)
{
if
(
skb
!=
NULL
)
{
dev_kfree_skb
(
skb
);
skb
=
NULL
;
dev_kfree_skb
(
skb
);
}
}
spin_lock_irqsave
(
&
priv
->
lock
,
flags
);
spin_lock_irqsave
(
&
priv
->
lock
,
flags
);
...
...
drivers/ieee1394/eth1394.h
View file @
db3e9f28
...
@@ -38,7 +38,7 @@
...
@@ -38,7 +38,7 @@
#define ETHER1394_GASP_SPECIFIER_ID_LO (ETHER1394_GASP_SPECIFIER_ID & 0xff)
#define ETHER1394_GASP_SPECIFIER_ID_LO (ETHER1394_GASP_SPECIFIER_ID & 0xff)
#define ETHER1394_GASP_VERSION 1
#define ETHER1394_GASP_VERSION 1
#define ETHER1394_OVERHEAD (2 * sizeof(quadlet_t))
/* GASP header overhead */
#define ETHER1394_
GASP_
OVERHEAD (2 * sizeof(quadlet_t))
/* GASP header overhead */
/* Node set == 64 */
/* Node set == 64 */
#define NODE_SET (ALL_NODES + 1)
#define NODE_SET (ALL_NODES + 1)
...
@@ -56,10 +56,9 @@ struct pdg_list {
...
@@ -56,10 +56,9 @@ struct pdg_list {
struct
eth1394_priv
{
struct
eth1394_priv
{
struct
net_device_stats
stats
;
/* Device stats */
struct
net_device_stats
stats
;
/* Device stats */
struct
hpsb_host
*
host
;
/* The card for this dev */
struct
hpsb_host
*
host
;
/* The card for this dev */
u
nsigned
char
max_rec
[
NODE_SET
];
/* Max payload per node */
u
16
maxpayload
[
NODE_SET
];
/* Max payload per node */
unsigned
char
sspd
[
NODE_SET
];
/* Max speed per node */
unsigned
char
sspd
[
NODE_SET
];
/* Max speed per node */
u16
fifo_hi
[
ALL_NODES
];
/* 16bit hi fifo offset per node */
u64
fifo
[
ALL_NODES
];
/* FIFO offset per node */
u32
fifo_lo
[
ALL_NODES
];
/* 32bit lo fifo offset per node */
u64
eui
[
ALL_NODES
];
/* EUI-64 per node */
u64
eui
[
ALL_NODES
];
/* EUI-64 per node */
spinlock_t
lock
;
/* Private lock */
spinlock_t
lock
;
/* Private lock */
int
broadcast_channel
;
/* Async stream Broadcast Channel */
int
broadcast_channel
;
/* Async stream Broadcast Channel */
...
@@ -74,6 +73,21 @@ struct host_info {
...
@@ -74,6 +73,21 @@ struct host_info {
struct
net_device
*
dev
;
struct
net_device
*
dev
;
};
};
/* Define a fake hardware header format for the networking core. Note that
* header size cannot exceed 16 bytes as that is the size of the header cache.
* Also, we do not need the source address in the header so we omit it and
* keep the header to under 16 bytes */
#define ETH1394_ALEN (8)
#define ETH1394_HLEN (10)
struct
eth1394hdr
{
unsigned
char
h_dest
[
ETH1394_ALEN
];
/* destination eth1394 addr */
unsigned
short
h_proto
;
/* packet type ID field */
}
__attribute__
((
packed
));
typedef
enum
{
ETH1394_GASP
,
ETH1394_WRREQ
}
eth1394_tx_type
;
typedef
enum
{
ETH1394_GASP
,
ETH1394_WRREQ
}
eth1394_tx_type
;
/* IP1394 headers */
/* IP1394 headers */
...
...
drivers/ieee1394/ieee1394.h
View file @
db3e9f28
...
@@ -57,7 +57,6 @@
...
@@ -57,7 +57,6 @@
/* Maps speed values above to a string representation */
/* Maps speed values above to a string representation */
extern
const
char
*
hpsb_speedto_str
[];
extern
const
char
*
hpsb_speedto_str
[];
extern
const
u8
hpsb_speedto_maxrec
[];
#define SELFID_PWRCL_NO_POWER 0x0
#define SELFID_PWRCL_NO_POWER 0x0
...
...
drivers/ieee1394/ieee1394_core.c
View file @
db3e9f28
...
@@ -61,7 +61,6 @@ static kmem_cache_t *hpsb_packet_cache;
...
@@ -61,7 +61,6 @@ static kmem_cache_t *hpsb_packet_cache;
/* Some globals used */
/* Some globals used */
const
char
*
hpsb_speedto_str
[]
=
{
"S100"
,
"S200"
,
"S400"
,
"S800"
,
"S1600"
,
"S3200"
};
const
char
*
hpsb_speedto_str
[]
=
{
"S100"
,
"S200"
,
"S400"
,
"S800"
,
"S1600"
,
"S3200"
};
const
u8
hpsb_speedto_maxrec
[]
=
{
0x7
,
0x8
,
0x9
,
0x10
,
0x11
,
0x12
};
static
void
dump_packet
(
const
char
*
text
,
quadlet_t
*
data
,
int
size
)
static
void
dump_packet
(
const
char
*
text
,
quadlet_t
*
data
,
int
size
)
{
{
...
@@ -1246,7 +1245,6 @@ EXPORT_SYMBOL(hpsb_unref_host);
...
@@ -1246,7 +1245,6 @@ EXPORT_SYMBOL(hpsb_unref_host);
/** ieee1394_core.c **/
/** ieee1394_core.c **/
EXPORT_SYMBOL
(
hpsb_speedto_str
);
EXPORT_SYMBOL
(
hpsb_speedto_str
);
EXPORT_SYMBOL
(
hpsb_speedto_maxrec
);
EXPORT_SYMBOL
(
hpsb_set_packet_complete_task
);
EXPORT_SYMBOL
(
hpsb_set_packet_complete_task
);
EXPORT_SYMBOL
(
alloc_hpsb_packet
);
EXPORT_SYMBOL
(
alloc_hpsb_packet
);
EXPORT_SYMBOL
(
free_hpsb_packet
);
EXPORT_SYMBOL
(
free_hpsb_packet
);
...
...
drivers/ieee1394/iso.c
View file @
db3e9f28
...
@@ -10,6 +10,7 @@
...
@@ -10,6 +10,7 @@
*/
*/
#include <linux/slab.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include "iso.h"
#include "iso.h"
void
hpsb_iso_stop
(
struct
hpsb_iso
*
iso
)
void
hpsb_iso_stop
(
struct
hpsb_iso
*
iso
)
...
...
drivers/ieee1394/sbp2.c
View file @
db3e9f28
...
@@ -79,7 +79,7 @@
...
@@ -79,7 +79,7 @@
#include "sbp2.h"
#include "sbp2.h"
static
char
version
[]
__devinitdata
=
static
char
version
[]
__devinitdata
=
"$Rev: 9
38
$ Ben Collins <bcollins@debian.org>"
;
"$Rev: 9
42
$ Ben Collins <bcollins@debian.org>"
;
/*
/*
* Module load parameter definitions
* Module load parameter definitions
...
@@ -230,6 +230,8 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id,
...
@@ -230,6 +230,8 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id,
static
Scsi_Host_Template
scsi_driver_template
;
static
Scsi_Host_Template
scsi_driver_template
;
const
u8
sbp2_speedto_max_payload
[]
=
{
0x7
,
0x8
,
0x9
,
0xA
,
0xB
,
0xC
};
static
struct
hpsb_highlevel
sbp2_highlevel
=
{
static
struct
hpsb_highlevel
sbp2_highlevel
=
{
.
name
=
SBP2_DEVICE_NAME
,
.
name
=
SBP2_DEVICE_NAME
,
.
remove_host
=
sbp2_remove_host
,
.
remove_host
=
sbp2_remove_host
,
...
@@ -779,7 +781,7 @@ static int sbp2_start_ud(struct sbp2scsi_host_info *hi, struct unit_directory *u
...
@@ -779,7 +781,7 @@ static int sbp2_start_ud(struct sbp2scsi_host_info *hi, struct unit_directory *u
scsi_id
->
ne
=
ud
->
ne
;
scsi_id
->
ne
=
ud
->
ne
;
scsi_id
->
hi
=
hi
;
scsi_id
->
hi
=
hi
;
scsi_id
->
speed_code
=
SPEED_100
;
scsi_id
->
speed_code
=
SPEED_100
;
scsi_id
->
max_payload_size
=
hpsb_speedto_maxrec
[
SPEED_100
];
scsi_id
->
max_payload_size
=
sbp2_speedto_max_payload
[
SPEED_100
];
atomic_set
(
&
scsi_id
->
sbp2_login_complete
,
0
);
atomic_set
(
&
scsi_id
->
sbp2_login_complete
,
0
);
INIT_LIST_HEAD
(
&
scsi_id
->
sbp2_command_orb_inuse
);
INIT_LIST_HEAD
(
&
scsi_id
->
sbp2_command_orb_inuse
);
INIT_LIST_HEAD
(
&
scsi_id
->
sbp2_command_orb_completed
);
INIT_LIST_HEAD
(
&
scsi_id
->
sbp2_command_orb_completed
);
...
@@ -1690,7 +1692,7 @@ static int sbp2_max_speed_and_size(struct scsi_id_instance_data *scsi_id)
...
@@ -1690,7 +1692,7 @@ static int sbp2_max_speed_and_size(struct scsi_id_instance_data *scsi_id)
/* Payload size is the lesser of what our speed supports and what
/* Payload size is the lesser of what our speed supports and what
* our host supports. */
* our host supports. */
scsi_id
->
max_payload_size
=
min
(
hpsb_speedto_maxrec
[
scsi_id
->
speed_code
],
scsi_id
->
max_payload_size
=
min
(
sbp2_speedto_max_payload
[
scsi_id
->
speed_code
],
(
u8
)(((
be32_to_cpu
(
hi
->
host
->
csr
.
rom
[
2
])
>>
12
)
&
0xf
)
-
1
));
(
u8
)(((
be32_to_cpu
(
hi
->
host
->
csr
.
rom
[
2
])
>>
12
)
&
0xf
)
-
1
));
SBP2_ERR
(
"Node["
NODE_BUS_FMT
"]: Max speed [%s] - Max payload [%u]"
,
SBP2_ERR
(
"Node["
NODE_BUS_FMT
"]: Max speed [%s] - Max payload [%u]"
,
...
...
fs/eventpoll.c
View file @
db3e9f28
...
@@ -150,6 +150,14 @@ struct eventpoll {
...
@@ -150,6 +150,14 @@ struct eventpoll {
/* Protect the this structure access */
/* Protect the this structure access */
rwlock_t
lock
;
rwlock_t
lock
;
/*
* This semaphore is used to ensure that files are not removed
* while epoll is using them. This is read-held during the event
* collection loop and it is write-held during the file cleanup
* path, the epoll file exit code and the ctl operations.
*/
struct
rw_semaphore
sem
;
/* Wait queue used by sys_epoll_wait() */
/* Wait queue used by sys_epoll_wait() */
wait_queue_head_t
wq
;
wait_queue_head_t
wq
;
...
@@ -279,16 +287,6 @@ static struct super_block *eventpollfs_get_sb(struct file_system_type *fs_type,
...
@@ -279,16 +287,6 @@ static struct super_block *eventpollfs_get_sb(struct file_system_type *fs_type,
/* Safe wake up implementation */
/* Safe wake up implementation */
static
struct
poll_safewake
psw
;
static
struct
poll_safewake
psw
;
/*
* This semaphore is used to ensure that files are not removed
* while epoll is using them. Namely the f_op->poll(), since
* it has to be called from outside the lock, must be protected.
* This is read-held during the event transfer loop to userspace
* and it is write-held during the file cleanup path and the epoll
* file exit code.
*/
static
struct
rw_semaphore
epsem
;
/* Slab cache used to allocate "struct epitem" */
/* Slab cache used to allocate "struct epitem" */
static
kmem_cache_t
*
epi_cache
;
static
kmem_cache_t
*
epi_cache
;
...
@@ -357,15 +355,14 @@ static void ep_poll_safewake(struct poll_safewake *psw, wait_queue_head_t *wq)
...
@@ -357,15 +355,14 @@ static void ep_poll_safewake(struct poll_safewake *psw, wait_queue_head_t *wq)
list_for_each
(
lnk
,
lsthead
)
{
list_for_each
(
lnk
,
lsthead
)
{
tncur
=
list_entry
(
lnk
,
struct
wake_task_node
,
llink
);
tncur
=
list_entry
(
lnk
,
struct
wake_task_node
,
llink
);
if
(
tncur
->
task
==
this_task
)
{
if
(
tncur
->
wq
==
wq
||
if
(
tncur
->
wq
==
wq
||
++
wake_nests
>
EP_MAX_POLLWAKE_NESTS
)
{
(
tncur
->
task
==
this_task
&&
++
wake_nests
>
EP_MAX_POLLWAKE_NESTS
))
{
/*
/*
* Ops ... loop detected or maximum nest level reached.
* Ops ... loop detected or maximum nest level reached.
* We abort this wake by breaking the cycle itself.
* We abort this wake by breaking the cycle itself.
*/
*/
spin_unlock_irqrestore
(
&
psw
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
psw
->
lock
,
flags
);
return
;
return
;
}
}
}
}
}
...
@@ -437,14 +434,15 @@ void eventpoll_release(struct file *file)
...
@@ -437,14 +434,15 @@ void eventpoll_release(struct file *file)
* The only hit might come from ep_free() but by holding the semaphore
* The only hit might come from ep_free() but by holding the semaphore
* will correctly serialize the operation.
* will correctly serialize the operation.
*/
*/
down_write
(
&
epsem
);
while
(
!
list_empty
(
lsthead
))
{
while
(
!
list_empty
(
lsthead
))
{
epi
=
list_entry
(
lsthead
->
next
,
struct
epitem
,
fllink
);
epi
=
list_entry
(
lsthead
->
next
,
struct
epitem
,
fllink
);
EP_LIST_DEL
(
&
epi
->
fllink
);
EP_LIST_DEL
(
&
epi
->
fllink
);
down_write
(
&
epi
->
ep
->
sem
);
ep_remove
(
epi
->
ep
,
epi
);
ep_remove
(
epi
->
ep
,
epi
);
up_write
(
&
epi
->
ep
->
sem
);
}
}
up_write
(
&
epsem
);
}
}
...
@@ -568,9 +566,18 @@ asmlinkage long sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event *even
...
@@ -568,9 +566,18 @@ asmlinkage long sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event *even
error
=
-
EEXIST
;
error
=
-
EEXIST
;
break
;
break
;
case
EPOLL_CTL_DEL
:
case
EPOLL_CTL_DEL
:
if
(
epi
)
if
(
epi
)
{
/*
* We need to protect the remove operation because another
* thread might be doing an epoll_wait() and using the
* target file.
*/
down_write
(
&
ep
->
sem
);
error
=
ep_remove
(
ep
,
epi
);
error
=
ep_remove
(
ep
,
epi
);
else
up_write
(
&
ep
->
sem
);
}
else
error
=
-
ENOENT
;
error
=
-
ENOENT
;
break
;
break
;
case
EPOLL_CTL_MOD
:
case
EPOLL_CTL_MOD
:
...
@@ -703,10 +710,6 @@ static int ep_getfd(int *efd, struct inode **einode, struct file **efile)
...
@@ -703,10 +710,6 @@ static int ep_getfd(int *efd, struct inode **einode, struct file **efile)
file
->
f_vfsmnt
=
mntget
(
eventpoll_mnt
);
file
->
f_vfsmnt
=
mntget
(
eventpoll_mnt
);
file
->
f_dentry
=
dget
(
dentry
);
file
->
f_dentry
=
dget
(
dentry
);
/*
* Initialize the file as read/write because it could be used
* with write() to add/remove/change interest sets.
*/
file
->
f_pos
=
0
;
file
->
f_pos
=
0
;
file
->
f_flags
=
O_RDONLY
;
file
->
f_flags
=
O_RDONLY
;
file
->
f_op
=
&
eventpoll_fops
;
file
->
f_op
=
&
eventpoll_fops
;
...
@@ -815,6 +818,7 @@ static int ep_init(struct eventpoll *ep, unsigned int hashbits)
...
@@ -815,6 +818,7 @@ static int ep_init(struct eventpoll *ep, unsigned int hashbits)
unsigned
int
i
,
hsize
;
unsigned
int
i
,
hsize
;
rwlock_init
(
&
ep
->
lock
);
rwlock_init
(
&
ep
->
lock
);
init_rwsem
(
&
ep
->
sem
);
init_waitqueue_head
(
&
ep
->
wq
);
init_waitqueue_head
(
&
ep
->
wq
);
init_waitqueue_head
(
&
ep
->
poll_wait
);
init_waitqueue_head
(
&
ep
->
poll_wait
);
INIT_LIST_HEAD
(
&
ep
->
rdllist
);
INIT_LIST_HEAD
(
&
ep
->
rdllist
);
...
@@ -841,11 +845,15 @@ static void ep_free(struct eventpoll *ep)
...
@@ -841,11 +845,15 @@ static void ep_free(struct eventpoll *ep)
struct
list_head
*
lsthead
,
*
lnk
;
struct
list_head
*
lsthead
,
*
lnk
;
struct
epitem
*
epi
;
struct
epitem
*
epi
;
/* We need to release all tasks waiting for these file */
if
(
waitqueue_active
(
&
ep
->
poll_wait
))
ep_poll_safewake
(
&
psw
,
&
ep
->
poll_wait
);
/*
/*
* We need to lock this because we could be hit by
* We need to lock this because we could be hit by
* eventpoll_release() while we're freeing the "struct eventpoll".
* eventpoll_release() while we're freeing the "struct eventpoll".
*/
*/
down_write
(
&
epsem
);
down_write
(
&
ep
->
sem
);
/*
/*
* Walks through the whole hash by unregistering poll callbacks.
* Walks through the whole hash by unregistering poll callbacks.
...
@@ -863,7 +871,7 @@ static void ep_free(struct eventpoll *ep)
...
@@ -863,7 +871,7 @@ static void ep_free(struct eventpoll *ep)
/*
/*
* Walks through the whole hash by freeing each "struct epitem". At this
* Walks through the whole hash by freeing each "struct epitem". At this
* point we are sure no poll callbacks will be lingering around, and also by
* point we are sure no poll callbacks will be lingering around, and also by
* write-holding "
ep
sem" we can be sure that no file cleanup code will hit
* write-holding "sem" we can be sure that no file cleanup code will hit
* us during this operation. So we can avoid the lock on "ep->lock".
* us during this operation. So we can avoid the lock on "ep->lock".
*/
*/
for
(
i
=
0
,
hsize
=
1
<<
ep
->
hashbits
;
i
<
hsize
;
i
++
)
{
for
(
i
=
0
,
hsize
=
1
<<
ep
->
hashbits
;
i
<
hsize
;
i
++
)
{
...
@@ -876,7 +884,7 @@ static void ep_free(struct eventpoll *ep)
...
@@ -876,7 +884,7 @@ static void ep_free(struct eventpoll *ep)
}
}
}
}
up_write
(
&
epsem
);
up_write
(
&
ep
->
sem
);
/* Free hash pages */
/* Free hash pages */
ep_free_pages
(
ep
->
hpages
,
EP_HASH_PAGES
(
ep
->
hashbits
));
ep_free_pages
(
ep
->
hpages
,
EP_HASH_PAGES
(
ep
->
hashbits
));
...
@@ -1337,20 +1345,6 @@ static int ep_collect_ready_items(struct eventpoll *ep, struct list_head *txlist
...
@@ -1337,20 +1345,6 @@ static int ep_collect_ready_items(struct eventpoll *ep, struct list_head *txlist
/* If this file is already in the ready list we exit soon */
/* If this file is already in the ready list we exit soon */
if
(
!
EP_IS_LINKED
(
&
epi
->
txlink
))
{
if
(
!
EP_IS_LINKED
(
&
epi
->
txlink
))
{
/*
* We need to increase the usage count of the "struct epitem" because
* another thread might call EPOLL_CTL_DEL on this target and make the
* object to vanish underneath our nose.
*/
ep_use_epitem
(
epi
);
/*
* We need to increase the usage count of the "struct file" because
* another thread might call close() on this target and make the file
* to vanish before we will be able to call f_op->poll().
*/
get_file
(
epi
->
file
);
/*
/*
* This is initialized in this way so that the default
* This is initialized in this way so that the default
* behaviour of the reinjecting code will be to push back
* behaviour of the reinjecting code will be to push back
...
@@ -1389,19 +1383,21 @@ static int ep_send_events(struct eventpoll *ep, struct list_head *txlist,
...
@@ -1389,19 +1383,21 @@ static int ep_send_events(struct eventpoll *ep, struct list_head *txlist,
struct
epitem
*
epi
;
struct
epitem
*
epi
;
struct
epoll_event
event
[
EP_MAX_BUF_EVENTS
];
struct
epoll_event
event
[
EP_MAX_BUF_EVENTS
];
/*
* We can loop without lock because this is a task private list.
* The test done during the collection loop will guarantee us that
* another task will not try to collect this file. Also, items
* cannot vanish during the loop because we are holding "sem".
*/
list_for_each
(
lnk
,
txlist
)
{
list_for_each
(
lnk
,
txlist
)
{
epi
=
list_entry
(
lnk
,
struct
epitem
,
txlink
);
epi
=
list_entry
(
lnk
,
struct
epitem
,
txlink
);
/* Get the ready file event set */
revents
=
epi
->
file
->
f_op
->
poll
(
epi
->
file
,
NULL
);
/*
/*
* Release the file usage before checking the event mask.
* Get the ready file event set. We can safely use the file
* In case this call will lead to the file removal, its
* because we are holding the "sem" in read and this will
* ->event.events member has been already set to zero and
* guarantee that both the file and the item will not vanish.
* this will make the event to be dropped.
*/
*/
fput
(
epi
->
file
);
revents
=
epi
->
file
->
f_op
->
poll
(
epi
->
file
,
NULL
);
/*
/*
* Set the return event set for the current file descriptor.
* Set the return event set for the current file descriptor.
...
@@ -1416,17 +1412,8 @@ static int ep_send_events(struct eventpoll *ep, struct list_head *txlist,
...
@@ -1416,17 +1412,8 @@ static int ep_send_events(struct eventpoll *ep, struct list_head *txlist,
eventbuf
++
;
eventbuf
++
;
if
(
eventbuf
==
EP_MAX_BUF_EVENTS
)
{
if
(
eventbuf
==
EP_MAX_BUF_EVENTS
)
{
if
(
__copy_to_user
(
&
events
[
eventcnt
],
event
,
if
(
__copy_to_user
(
&
events
[
eventcnt
],
event
,
eventbuf
*
sizeof
(
struct
epoll_event
)))
{
eventbuf
*
sizeof
(
struct
epoll_event
)))
/*
* We need to complete the loop to decrement the file
* usage before returning from this function.
*/
for
(
lnk
=
lnk
->
next
;
lnk
!=
txlist
;
lnk
=
lnk
->
next
)
{
epi
=
list_entry
(
lnk
,
struct
epitem
,
txlink
);
fput
(
epi
->
file
);
}
return
-
EFAULT
;
return
-
EFAULT
;
}
eventcnt
+=
eventbuf
;
eventcnt
+=
eventbuf
;
eventbuf
=
0
;
eventbuf
=
0
;
}
}
...
@@ -1447,7 +1434,8 @@ static int ep_send_events(struct eventpoll *ep, struct list_head *txlist,
...
@@ -1447,7 +1434,8 @@ static int ep_send_events(struct eventpoll *ep, struct list_head *txlist,
/*
/*
* Walk through the transfer list we collected with ep_collect_ready_items()
* Walk through the transfer list we collected with ep_collect_ready_items()
* and, if 1) the item is still "alive" 2) its event set is not empty 3) it's
* and, if 1) the item is still "alive" 2) its event set is not empty 3) it's
* not already linked, links it to the ready list.
* not already linked, links it to the ready list. Same as above, we are holding
* "sem" so items cannot vanish underneath our nose.
*/
*/
static
void
ep_reinject_items
(
struct
eventpoll
*
ep
,
struct
list_head
*
txlist
)
static
void
ep_reinject_items
(
struct
eventpoll
*
ep
,
struct
list_head
*
txlist
)
{
{
...
@@ -1475,8 +1463,6 @@ static void ep_reinject_items(struct eventpoll *ep, struct list_head *txlist)
...
@@ -1475,8 +1463,6 @@ static void ep_reinject_items(struct eventpoll *ep, struct list_head *txlist)
list_add_tail
(
&
epi
->
rdllink
,
&
ep
->
rdllist
);
list_add_tail
(
&
epi
->
rdllink
,
&
ep
->
rdllist
);
ricnt
++
;
ricnt
++
;
}
}
ep_release_epitem
(
epi
);
}
}
if
(
ricnt
)
{
if
(
ricnt
)
{
...
@@ -1510,17 +1496,12 @@ static int ep_events_transfer(struct eventpoll *ep, struct epoll_event *events,
...
@@ -1510,17 +1496,12 @@ static int ep_events_transfer(struct eventpoll *ep, struct epoll_event *events,
/*
/*
* We need to lock this because we could be hit by
* We need to lock this because we could be hit by
* eventpoll_release() while we're transfering
* eventpoll_release() and epoll_ctl(EPOLL_CTL_DEL).
* events to userspace. Read-holding "epsem" will lock
* out eventpoll_release() during the whole
* transfer loop and this will garantie us that the
* file will not vanish underneath our nose when
* we will call f_op->poll() from ep_send_events().
*/
*/
down_read
(
&
epsem
);
down_read
(
&
ep
->
sem
);
/* Collect/extract ready items */
/* Collect/extract ready items */
if
(
ep_collect_ready_items
(
ep
,
&
txlist
,
maxevents
))
{
if
(
ep_collect_ready_items
(
ep
,
&
txlist
,
maxevents
)
>
0
)
{
/* Build result set in userspace */
/* Build result set in userspace */
eventcnt
=
ep_send_events
(
ep
,
&
txlist
,
events
);
eventcnt
=
ep_send_events
(
ep
,
&
txlist
,
events
);
...
@@ -1528,7 +1509,7 @@ static int ep_events_transfer(struct eventpoll *ep, struct epoll_event *events,
...
@@ -1528,7 +1509,7 @@ static int ep_events_transfer(struct eventpoll *ep, struct epoll_event *events,
ep_reinject_items
(
ep
,
&
txlist
);
ep_reinject_items
(
ep
,
&
txlist
);
}
}
up_read
(
&
epsem
);
up_read
(
&
ep
->
sem
);
return
eventcnt
;
return
eventcnt
;
}
}
...
@@ -1652,9 +1633,6 @@ static int __init eventpoll_init(void)
...
@@ -1652,9 +1633,6 @@ static int __init eventpoll_init(void)
{
{
int
error
;
int
error
;
/* Initialize the semaphore used to syncronize the file cleanup code */
init_rwsem
(
&
epsem
);
/* Initialize the structure used to perform safe poll wait head wake ups */
/* Initialize the structure used to perform safe poll wait head wake ups */
ep_poll_safewake_init
(
&
psw
);
ep_poll_safewake_init
(
&
psw
);
...
...
sound/core/ioctl32/pcm32.c
View file @
db3e9f28
...
@@ -21,6 +21,7 @@
...
@@ -21,6 +21,7 @@
#include <sound/driver.h>
#include <sound/driver.h>
#include <linux/time.h>
#include <linux/time.h>
#include <linux/slab.h>
#include <linux/slab.h>
#include <linux/compat.h>
#include <sound/core.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm.h>
#include "ioctl32.h"
#include "ioctl32.h"
...
@@ -136,15 +137,10 @@ struct sndrv_pcm_channel_info32 {
...
@@ -136,15 +137,10 @@ struct sndrv_pcm_channel_info32 {
COPY(step);\
COPY(step);\
}
}
struct
timeval32
{
s32
tv_sec
;
s32
tv_usec
;
}
__attribute__
((
packed
));
struct
sndrv_pcm_status32
{
struct
sndrv_pcm_status32
{
s32
state
;
s32
state
;
struct
timeval32
trigger_tstamp
;
struct
compat_timespec
trigger_tstamp
;
struct
timeval32
tstamp
;
struct
compat_timespec
tstamp
;
u32
appl_ptr
;
u32
appl_ptr
;
u32
hw_ptr
;
u32
hw_ptr
;
s32
delay
;
s32
delay
;
...
@@ -159,9 +155,9 @@ struct sndrv_pcm_status32 {
...
@@ -159,9 +155,9 @@ struct sndrv_pcm_status32 {
{\
{\
COPY(state);\
COPY(state);\
COPY(trigger_tstamp.tv_sec);\
COPY(trigger_tstamp.tv_sec);\
COPY(trigger_tstamp.tv_
u
sec);\
COPY(trigger_tstamp.tv_
n
sec);\
COPY(tstamp.tv_sec);\
COPY(tstamp.tv_sec);\
COPY(tstamp.tv_
u
sec);\
COPY(tstamp.tv_
n
sec);\
COPY(appl_ptr);\
COPY(appl_ptr);\
COPY(hw_ptr);\
COPY(hw_ptr);\
COPY(delay);\
COPY(delay);\
...
...
sound/core/ioctl32/rawmidi32.c
View file @
db3e9f28
...
@@ -21,6 +21,7 @@
...
@@ -21,6 +21,7 @@
#include <sound/driver.h>
#include <sound/driver.h>
#include <linux/time.h>
#include <linux/time.h>
#include <linux/fs.h>
#include <linux/fs.h>
#include <linux/compat.h>
#include <sound/core.h>
#include <sound/core.h>
#include <sound/rawmidi.h>
#include <sound/rawmidi.h>
#include <asm/uaccess.h>
#include <asm/uaccess.h>
...
@@ -42,14 +43,9 @@ struct sndrv_rawmidi_params32 {
...
@@ -42,14 +43,9 @@ struct sndrv_rawmidi_params32 {
COPY(no_active_sensing);\
COPY(no_active_sensing);\
}
}
struct
timeval32
{
s32
tv_sec
;
s32
tv_usec
;
}
__attribute__
((
packed
));
struct
sndrv_rawmidi_status32
{
struct
sndrv_rawmidi_status32
{
s32
stream
;
s32
stream
;
struct
timeval32
tstamp
;
struct
compat_timespec
tstamp
;
u32
avail
;
u32
avail
;
u32
xruns
;
u32
xruns
;
unsigned
char
reserved
[
16
];
unsigned
char
reserved
[
16
];
...
@@ -59,7 +55,7 @@ struct sndrv_rawmidi_status32 {
...
@@ -59,7 +55,7 @@ struct sndrv_rawmidi_status32 {
{\
{\
COPY(stream);\
COPY(stream);\
COPY(tstamp.tv_sec);\
COPY(tstamp.tv_sec);\
COPY(tstamp.tv_
u
sec);\
COPY(tstamp.tv_
n
sec);\
COPY(avail);\
COPY(avail);\
COPY(xruns);\
COPY(xruns);\
}
}
...
...
sound/core/ioctl32/timer32.c
View file @
db3e9f28
...
@@ -21,6 +21,7 @@
...
@@ -21,6 +21,7 @@
#include <sound/driver.h>
#include <sound/driver.h>
#include <linux/time.h>
#include <linux/time.h>
#include <linux/fs.h>
#include <linux/fs.h>
#include <linux/compat.h>
#include <sound/core.h>
#include <sound/core.h>
#include <sound/timer.h>
#include <sound/timer.h>
#include <asm/uaccess.h>
#include <asm/uaccess.h>
...
@@ -31,7 +32,7 @@ struct sndrv_timer_info32 {
...
@@ -31,7 +32,7 @@ struct sndrv_timer_info32 {
s32
card
;
s32
card
;
unsigned
char
id
[
64
];
unsigned
char
id
[
64
];
unsigned
char
name
[
80
];
unsigned
char
name
[
80
];
u32
ticks
;
u32
reserved0
;
u32
resolution
;
u32
resolution
;
unsigned
char
reserved
[
64
];
unsigned
char
reserved
[
64
];
};
};
...
@@ -42,17 +43,11 @@ struct sndrv_timer_info32 {
...
@@ -42,17 +43,11 @@ struct sndrv_timer_info32 {
COPY(card);\
COPY(card);\
memcpy(dst->id, src->id, sizeof(src->id));\
memcpy(dst->id, src->id, sizeof(src->id));\
memcpy(dst->name, src->name, sizeof(src->name));\
memcpy(dst->name, src->name, sizeof(src->name));\
COPY(ticks);\
COPY(resolution);\
COPY(resolution);\
}
}
struct
timeval32
{
s32
tv_sec
;
s32
tv_usec
;
};
struct
sndrv_timer_status32
{
struct
sndrv_timer_status32
{
struct
timeval32
tstamp
;
struct
compat_timespec
tstamp
;
u32
resolution
;
u32
resolution
;
u32
lost
;
u32
lost
;
u32
overrun
;
u32
overrun
;
...
@@ -63,7 +58,7 @@ struct sndrv_timer_status32 {
...
@@ -63,7 +58,7 @@ struct sndrv_timer_status32 {
#define CVT_sndrv_timer_status()\
#define CVT_sndrv_timer_status()\
{\
{\
COPY(tstamp.tv_sec);\
COPY(tstamp.tv_sec);\
COPY(tstamp.tv_
u
sec);\
COPY(tstamp.tv_
n
sec);\
COPY(resolution);\
COPY(resolution);\
COPY(lost);\
COPY(lost);\
COPY(overrun);\
COPY(overrun);\
...
...
sound/drivers/vx/vx_core.c
View file @
db3e9f28
...
@@ -24,6 +24,7 @@
...
@@ -24,6 +24,7 @@
#include <linux/delay.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <sound/core.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm.h>
#include <sound/asoundef.h>
#include <sound/asoundef.h>
...
...
sound/sparc/cs4231.c
View file @
db3e9f28
...
@@ -716,10 +716,12 @@ static int snd_cs4231_trigger(snd_pcm_substream_t *substream, int cmd)
...
@@ -716,10 +716,12 @@ static int snd_cs4231_trigger(snd_pcm_substream_t *substream, int cmd)
case
SNDRV_PCM_TRIGGER_STOP
:
case
SNDRV_PCM_TRIGGER_STOP
:
{
{
unsigned
int
what
=
0
;
unsigned
int
what
=
0
;
snd_pcm_substream_t
*
s
=
substream
;
snd_pcm_substream_t
*
s
;
struct
list_head
*
pos
;
unsigned
long
flags
;
unsigned
long
flags
;
do
{
snd_pcm_group_for_each
(
pos
,
substream
)
{
s
=
snd_pcm_group_substream_entry
(
pos
);
if
(
s
==
chip
->
playback_substream
)
{
if
(
s
==
chip
->
playback_substream
)
{
what
|=
CS4231_PLAYBACK_ENABLE
;
what
|=
CS4231_PLAYBACK_ENABLE
;
snd_pcm_trigger_done
(
s
,
substream
);
snd_pcm_trigger_done
(
s
,
substream
);
...
@@ -727,8 +729,7 @@ static int snd_cs4231_trigger(snd_pcm_substream_t *substream, int cmd)
...
@@ -727,8 +729,7 @@ static int snd_cs4231_trigger(snd_pcm_substream_t *substream, int cmd)
what
|=
CS4231_RECORD_ENABLE
;
what
|=
CS4231_RECORD_ENABLE
;
snd_pcm_trigger_done
(
s
,
substream
);
snd_pcm_trigger_done
(
s
,
substream
);
}
}
s
=
s
->
link_next
;
}
}
while
(
s
!=
substream
);
#if 0
#if 0
printk("TRIGGER: what[%x] on(%d)\n",
printk("TRIGGER: what[%x] on(%d)\n",
...
...
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