Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
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
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
CONFIG_LOG_BUF_SHIFT=15
# CONFIG_EMBEDDED is not set
CONFIG_FUTEX=y
CONFIG_EPOLL=y
#
# Loadable module support
...
...
@@ -795,6 +798,7 @@ CONFIG_IRDA_FAST_RR=y
# CONFIG_WINBOND_FIR is not set
# CONFIG_TOSHIBA_OLD is not set
# CONFIG_TOSHIBA_FIR is not set
# CONFIG_SMC_IRCC_OLD is not set
# CONFIG_SMC_IRCC_FIR is not set
# CONFIG_ALI_FIR is not set
# CONFIG_VLSI_FIR is not set
...
...
@@ -959,6 +963,8 @@ CONFIG_VFAT_FS=m
CONFIG_PROC_FS=y
# CONFIG_DEVFS_FS is not set
CONFIG_DEVPTS_FS=y
CONFIG_DEVPTS_FS_XATTR=y
# CONFIG_DEVPTS_FS_SECURITY is not set
# CONFIG_TMPFS is not set
CONFIG_RAMFS=y
...
...
@@ -1111,6 +1117,7 @@ CONFIG_SND_ICE1712=m
CONFIG_SND_INTEL8X0=m
CONFIG_SND_SONICVIBES=m
# CONFIG_SND_VIA82XX is not set
CONFIG_SND_VX222=m
#
# ALSA USB devices
...
...
drivers/ieee1394/eth1394.c
View file @
db3e9f28
...
...
@@ -29,12 +29,11 @@
*
* TODO:
* RFC 2734 related:
* - Add support for broadcast messages
* - Use EUI instead of node id in internal ARP tables
* - Add Config ROM entry
* - Add MCAP and multicast
*
* Non-RFC 2734 related:
* - Fix bug related to fragmented broadcast datagrams
* - Move generic GASP reception to core 1394 code
* - Convert kmalloc/kfree for link fragments to use kmem_cache_* instead
* - Stability improvements
...
...
@@ -73,6 +72,7 @@
#include "ieee1394.h"
#include "highlevel.h"
#include "iso.h"
#include "nodemgr.h"
#include "eth1394.h"
#define ETH1394_PRINT_G(level, fmt, args...) \
...
...
@@ -86,7 +86,7 @@
#define TRACE() printk(KERN_ERR "eth1394:%s[%d] ---- TRACE\n", __FUNCTION__, __LINE__)
static
char
version
[]
__devinitdata
=
"$Rev: 9
38
$ Ben Collins <bcollins@debian.org>"
;
"$Rev: 9
45
$ Ben Collins <bcollins@debian.org>"
;
struct
fragment_info
{
struct
list_head
list
;
...
...
@@ -119,22 +119,39 @@ static const int hdr_type_len[] = {
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_DESCRIPTION
(
"IEEE 1394 IPv4 Driver (IPv4-over-1394 as per RFC 2734)"
);
MODULE_LICENSE
(
"GPL"
);
/* The max_partial_datagrams parameter is the maximum number of fragmented
datagrams
*
per node that eth1394 will keep in memory. Providing an upper bound allows us to
*
limit the amount of memory that partial datagrams consume in the event that some
*
partial datagrams are never completed. This should probably change to a sysctl
* item or the like if possible.
/* The max_partial_datagrams parameter is the maximum number of fragmented
*
datagrams per node that eth1394 will keep in memory. Providing an upper
*
bound allows us to limit the amount of memory that partial datagrams
*
consume in the event that some partial datagrams are never completed. This
*
should probably change to a sysctl
item or the like if possible.
*/
MODULE_PARM
(
max_partial_datagrams
,
"i"
);
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
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
int
ether1394_tx
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
);
static
void
ether1394_iso
(
struct
hpsb_iso
*
iso
);
...
...
@@ -258,73 +275,34 @@ static void ether1394_tx_timeout (struct net_device *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
)
{
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
;
dev
->
mtu
=
new_mtu
;
return
0
;
}
static
inline
void
ether1394_register_limits
(
int
nodeid
,
unsigned
char
max_rec
,
unsigned
char
sspd
,
u64
eui
,
u16
fifo_hi
,
u32
fifo_lo
,
struct
eth1394_priv
*
priv
)
static
inline
void
ether1394_register_limits
(
int
nodeid
,
u16
maxpayload
,
unsigned
char
sspd
,
u64
eui
,
u64
fifo
,
struct
eth1394_priv
*
priv
)
{
if
(
nodeid
<
0
||
nodeid
>=
ALL_NODES
)
{
ETH1394_PRINT_G
(
KERN_ERR
,
"Cannot register invalid nodeid %d
\n
"
,
nodeid
);
return
;
}
priv
->
max_rec
[
nodeid
]
=
max_rec
;
priv
->
sspd
[
nodeid
]
=
sspd
;
priv
->
fifo_hi
[
nodeid
]
=
fifo_hi
;
priv
->
fifo_lo
[
nodeid
]
=
fifo_lo
;
priv
->
eui
[
nodeid
]
=
eui
;
priv
->
maxpayload
[
nodeid
]
=
maxpayload
;
priv
->
sspd
[
nodeid
]
=
sspd
;
priv
->
fifo
[
nodeid
]
=
fifo
;
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
);
return
;
...
...
@@ -335,34 +313,44 @@ static void ether1394_reset_priv (struct net_device *dev, int set_mtu)
unsigned
long
flags
;
int
i
;
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
;
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
);
/* 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
->
fifo_hi
,
0
,
sizeof
(
priv
->
fifo_hi
));
memset
(
priv
->
fifo_lo
,
0
,
sizeof
(
priv
->
fifo_lo
));
memset
(
priv
->
fifo
,
0
,
sizeof
(
priv
->
fifo
));
#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
;
/* Register our limits now */
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
)
+
ETHER1394_OVERHEAD
);
/* Set our hardware address while we're at it */
*
(
nodeid_t
*
)
dev
->
dev_addr
=
htons
(
host
->
node_id
);
ether1394_register_limits
(
phy_id
,
maxpayload
,
host
->
speed_map
[(
phy_id
<<
6
)
+
phy_id
],
guid
,
ETHER1394_REGION_ADDR
,
priv
);
/* We'll use our maxpayload as the default mtu */
if
(
set_mtu
)
{
dev
->
mtu
=
priv
->
maxpayload
[
phy_id
]
-
(
sizeof
(
union
eth1394_hdr
)
+
ETHER1394_GASP_OVERHEAD
);
/* Set our hardware address while we're at it */
*
(
u64
*
)
dev
->
dev_addr
=
guid
;
*
(
u64
*
)
dev
->
broadcast
=
~
0x0ULL
;
}
spin_unlock_irqrestore
(
&
priv
->
lock
,
flags
);
...
...
@@ -392,11 +380,20 @@ static int ether1394_init_dev (struct net_device *dev)
dev
->
tx_timeout
=
ether1394_tx_timeout
;
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 */
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
->
addr_len
=
2
;
dev
->
addr_len
=
ETH1394_ALEN
;
dev
->
hard_header_len
=
ETH1394_HLEN
;
dev
->
type
=
ARPHRD_IEEE1394
;
ether1394_reset_priv
(
dev
,
1
);
...
...
@@ -419,6 +416,9 @@ static void ether1394_add_host (struct hpsb_host *host)
if
(
version_printed
++
==
0
)
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
));
if
(
dev
==
NULL
)
...
...
@@ -468,7 +468,7 @@ static void ether1394_add_host (struct hpsb_host *host)
out:
if
(
dev
!=
NULL
)
kfree
(
dev
);
dev
=
NULL
;
kfree
(
dev
)
;
if
(
hi
)
hpsb_destroy_hostinfo
(
&
eth1394_highlevel
,
host
);
...
...
@@ -489,7 +489,7 @@ static void ether1394_remove_host (struct hpsb_host *host)
unregister_netdev
(
hi
->
dev
);
hpsb_iso_shutdown
(
priv
->
iso
);
kfree
(
hi
->
dev
);
hi
->
dev
=
NULL
;
kfree
(
hi
->
dev
)
;
}
return
;
...
...
@@ -513,31 +513,140 @@ static void ether1394_host_reset (struct hpsb_host *host)
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
******************************************/
/* 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
;
skb
->
mac
.
raw
=
skb
->
data
;
skb_pull
(
skb
,
ETH_HLEN
);
eth
=
skb
->
mac
.
ethernet
;
#if 0
skb_pull
(
skb
,
ETH
1394
_HLEN
);
eth
=
(
struct
eth1394hdr
*
)
skb
->
mac
.
raw
;
if
(
*
eth
->
h_dest
&
1
)
{
if
(
memcmp
(
eth
->
h_dest
,
dev
->
broadcast
,
dev
->
addr_len
)
==
0
)
skb
->
pkt_type
=
PACKET_BROADCAST
;
#if 0
else
skb->pkt_type = PACKET_MULTICAST;
#endif
}
else
{
if
(
memcmp
(
eth
->
h_dest
,
dev
->
dev_addr
,
dev
->
addr_len
))
skb
->
pkt_type
=
PACKET_OTHERHOST
;
}
#endif
if
(
ntohs
(
eth
->
h_proto
)
>=
1536
)
return
eth
->
h_proto
;
...
...
@@ -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.
* We also perform ARP translation here, if need be. */
static
inline
unsigned
short
ether1394_parse_encap
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
,
nodeid_t
srcid
,
nodeid_t
destid
,
u16
ether_type
)
static
inline
u16
ether1394_parse_encap
(
struct
sk_buff
*
skb
,
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
;
/* Setup our hw addresses. We use these to build the
* ethernet header. */
*
(
u16
*
)
dest_hw
=
htons
(
destid
);
*
(
u16
*
)
src_hw
=
htons
(
srcid
);
if
(
destid
==
(
LOCAL_BUS
|
ALL_NODES
))
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
* use of some of the fields, since they tell us a little bit
* about the sending machine. */
if
(
ether_type
==
__constant_htons
(
ETH_P_ARP
))
{
unsigned
long
flags
;
u16
phy_id
=
NODEID_TO_NODE
(
srcid
);
struct
eth1394_priv
*
priv
=
(
struct
eth1394_priv
*
)
dev
->
priv
;
struct
eth1394_arp
arp1394
;
struct
eth1394_arp
*
arp1394
=
(
struct
eth1394_arp
*
)
skb
->
data
;
struct
arphdr
*
arp
=
(
struct
arphdr
*
)
skb
->
data
;
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 */
spin_lock_irqsave
(
&
priv
->
lock
,
flags
);
ether1394_register_limits
(
phy_id
,
arp1394
.
max_rec
,
arp1394
.
sspd
,
le64_to_cpu
(
arp1394
.
s_uniq_id
),
ntohs
(
arp1394
.
fifo_hi
),
ntohl
(
arp1394
.
fifo_lo
),
priv
);
ether1394_register_limits
(
NODEID_TO_NODE
(
srcid
),
maxpayload
,
arp1394
->
sspd
,
arp1394
->
s_uniq_id
,
fifo_addr
,
priv
);
spin_unlock_irqrestore
(
&
priv
->
lock
,
flags
);
#define PROCESS_MEMBER(ptr,val,len) \
memcpy (ptr, val, len); ptr += len
PROCESS_MEMBER
(
arp_ptr
,
src_hw
,
dev
->
addr_len
);
PROCESS_MEMBER
(
arp_ptr
,
&
arp1394
.
sip
,
4
);
PROCESS_MEMBER
(
arp_ptr
,
dest_hw
,
dev
->
addr_len
);
PROCESS_MEMBER
(
arp_ptr
,
&
arp1394
.
tip
,
4
);
#undef PROCESS_MEMBER
arp
->
ar_hln
=
dev
->
addr_len
;
arp
->
ar_hrd
=
__constant_htons
(
ARPHRD_ETHER
);
skb_trim
(
skb
,
sizeof
(
struct
arphdr
)
+
2
*
(
dev
->
addr_len
+
4
));
/* Now that we're done with the 1394 specific stuff, we'll
* need to alter some of the data. Believe it or not, all
* that needs to be done is sender_IP_address needs to be
* moved, the destination hardware address get stuffed
* in and the hardware address length set to 8.
*
* IMPORTANT: The code below overwrites 1394 specific data
* needed above data so keep the call to
* ether1394_register_limits() before munging the data for the
* higher level IP stack. */
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. */
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
);
return
ret
;
...
...
@@ -651,7 +776,7 @@ static inline int new_fragment(struct list_head *frag_info, int offset, int len)
/* glue fragments together */
fi
->
len
+=
fi2
->
len
;
list_del
(
lh
->
next
);
kfree
(
fi2
);
fi2
=
NULL
;
kfree
(
fi2
);
}
return
0
;
}
else
if
((
offset
+
len
)
==
fi
->
offset
)
{
...
...
@@ -664,7 +789,7 @@ static inline int new_fragment(struct list_head *frag_info, int offset, int len)
/* glue fragments together */
fi2
->
len
+=
fi
->
len
;
list_del
(
lh
);
kfree
(
fi
);
fi
=
NULL
;
kfree
(
fi
);
}
return
0
;
}
else
if
(
offset
>
(
fi
->
offset
+
fi
->
len
))
{
...
...
@@ -701,7 +826,7 @@ static inline int new_partial_datagram(struct net_device *dev,
INIT_LIST_HEAD
(
&
new
->
frag_info
);
if
(
new_fragment
(
&
new
->
frag_info
,
frag_off
,
frag_len
)
<
0
)
{
kfree
(
new
);
new
=
NULL
;
kfree
(
new
);
return
-
ENOMEM
;
}
...
...
@@ -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
,
list
);
kfree
(
fi
);
fi
=
NULL
;
kfree
(
new
);
new
=
NULL
;
kfree
(
fi
);
kfree
(
new
);
return
-
ENOMEM
;
}
...
...
@@ -754,11 +879,11 @@ static inline void purge_partial_datagram(struct list_head *old)
list_for_each_safe
(
lh
,
n
,
&
pd
->
frag_info
)
{
struct
fragment_info
*
fi
=
list_entry
(
lh
,
struct
fragment_info
,
list
);
list_del
(
lh
);
kfree
(
fi
);
fi
=
NULL
;
kfree
(
fi
);
}
list_del
(
old
);
kfree_skb
(
pd
->
skb
);
pd
->
skb
=
NULL
;
kfree
(
pd
);
pd
=
NULL
;
kfree_skb
(
pd
->
skb
);
kfree
(
pd
);
}
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,
memcpy
(
skb_put
(
skb
,
len
-
hdr_len
),
buf
+
hdr_len
,
len
-
hdr_len
);
ether_type
=
hdr
->
uf
.
ether_type
;
}
else
{
#if 0
return 0;
}
if(0) {
#endif
/* A datagram fragment has been received, now the fun begins. */
struct
list_head
*
pdgl
,
*
lh
;
...
...
@@ -836,7 +956,6 @@ static int ether1394_data_handler(struct net_device *dev, int srcid, int destid,
dg_size
=
hdr
->
sf
.
dg_size
;
fg_off
=
hdr
->
sf
.
fg_off
;
}
spin_lock_irqsave
(
&
pdg
->
lock
,
flags
);
pdgl
=
&
(
pdg
->
list
);
...
...
@@ -1010,7 +1129,8 @@ static void ether1394_iso(struct hpsb_iso *iso)
/* This packet is not for us */
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
);
...
...
@@ -1022,6 +1142,39 @@ static void ether1394_iso(struct hpsb_iso *iso)
* 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
* ethernet header's proto for our own. */
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
;
adj_max_payload
=
max_payload
-
hdr_type_len
[
ETH1394_HDR_LF_FF
];
}
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,
}
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
)
{
p
->
header_size
=
4
;
p
->
tcode
=
TCODE_STREAM_DATA
;
p
->
header
[
0
]
=
(
length
<<
16
)
|
(
3
<<
14
)
|
((
host
->
csr
.
broadcast_channel
&
0x3f
)
<<
8
)
|
((
priv
->
broadcast_channel
)
<<
8
)
|
(
TCODE_STREAM_DATA
<<
4
);
p
->
data_size
=
length
;
p
->
data
=
(
quadlet_t
*
)
skb_push
(
skb
,
2
*
sizeof
(
quadlet_t
))
;
p
->
data
[
0
]
=
cpu_to_be32
((
host
->
node_id
<<
16
)
|
p
->
data
=
(
(
quadlet_t
*
)
skb
->
data
)
-
2
;
p
->
data
[
0
]
=
cpu_to_be32
((
priv
->
host
->
node_id
<<
16
)
|
ETHER1394_GASP_SPECIFIER_ID_HI
);
p
->
data
[
1
]
=
cpu_to_be32
((
ETHER1394_GASP_SPECIFIER_ID_LO
<<
24
)
|
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
)
{
packet
->
data
=
NULL
;
free_hpsb_packet
(
packet
);
packet
=
NULL
;
free_hpsb_packet
(
packet
);
}
static
void
ether1394_complete_cb
(
void
*
__ptask
);
...
...
@@ -1168,8 +1326,7 @@ static int ether1394_send_packet(struct packet_task *ptask, unsigned int tx_len)
if
(
ptask
->
tx_type
==
ETH1394_GASP
)
{
int
length
=
tx_len
+
(
2
*
sizeof
(
quadlet_t
));
ether1394_prep_gasp_packet
(
packet
,
priv
->
host
,
ptask
->
skb
,
length
);
ether1394_prep_gasp_packet
(
packet
,
priv
,
ptask
->
skb
,
length
);
}
else
{
if
(
ether1394_prep_write_packet
(
packet
,
priv
->
host
,
...
...
@@ -1212,8 +1369,8 @@ static inline void ether1394_dg_complete(struct packet_task *ptask, int fail)
spin_unlock_irqrestore
(
&
priv
->
lock
,
flags
);
}
dev_kfree_skb_any
(
skb
);
skb
=
NULL
;
kmem_cache_free
(
packet_task_cache
,
ptask
);
ptask
=
NULL
;
dev_kfree_skb_any
(
skb
);
kmem_cache_free
(
packet_task_cache
,
ptask
);
}
...
...
@@ -1230,7 +1387,7 @@ static void ether1394_complete_cb(void *__ptask)
hpsb_free_tlabel
(
packet
);
}
ether1394_free_packet
(
packet
);
packet
=
ptask
->
packet
=
NULL
;
ether1394_free_packet
(
packet
);
ptask
->
outstanding_pkts
--
;
if
(
ptask
->
outstanding_pkts
>
0
&&
!
fail
)
...
...
@@ -1253,7 +1410,7 @@ static void ether1394_complete_cb(void *__ptask)
static
int
ether1394_tx
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
)
{
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
;
int
proto
;
unsigned
long
flags
;
...
...
@@ -1265,6 +1422,7 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev)
u16
dg_size
;
u16
dgl
;
struct
packet_task
*
ptask
;
struct
node_entry
*
ne
;
ptask
=
kmem_cache_alloc
(
packet_task_cache
,
kmflags
);
if
(
ptask
==
NULL
)
{
...
...
@@ -1295,34 +1453,44 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev)
goto
fail
;
}
/* Get rid of the ethernet header, but save a pointer */
eth
=
(
struct
ethhdr
*
)
skb
->
data
;
skb_pull
(
skb
,
ETH_HLEN
);
/* Get rid of the fake eth1394 header, but save a pointer */
eth
=
(
struct
eth1394hdr
*
)
skb
->
data
;
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
;
/* If this is an ARP packet, convert it */
if
(
proto
==
__constant_htons
(
ETH_P_ARP
))
ether1394_arp_to_1394arp
(
skb
,
dev
);
max_payload
=
1
<<
(
min
(
priv
->
max_rec
[
NODEID_TO_NODE
(
priv
->
host
->
node_id
)],
priv
->
max_rec
[
NODEID_TO_NODE
(
dest_node
)])
+
1
);
max_payload
=
priv
->
maxpayload
[
NODEID_TO_NODE
(
dest_node
)];
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
;
}
/* 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
):
/* Set the transmission type for the packet. ARP packets and IP
* broadcast packets are sent via GASP, however, we cheat a little bit
* when detecting IP broadcast packets. This will need to change when
* we switch from using node id for the hardware address to the EUI
* 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
;
max_payload
-=
ETHER1394_OVERHEAD
;
break
;
default:
max_payload
-=
ETHER1394_GASP_OVERHEAD
;
}
else
{
tx_type
=
ETH1394_WRREQ
;
}
...
...
@@ -1345,9 +1513,17 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev)
if
(
tx_type
!=
ETH1394_GASP
)
{
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
);
addr
=
(
u64
)
priv
->
fifo_hi
[
NODEID_TO_NODE
(
dest_node
)]
<<
32
|
priv
->
fifo_lo
[
NODEID_TO_NODE
(
dest_node
)];
addr
=
priv
->
fifo
[
NODEID_TO_NODE
(
dest_node
)];
spin_unlock_irqrestore
(
&
priv
->
lock
,
flags
);
ptask
->
addr
=
addr
;
...
...
@@ -1370,11 +1546,11 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev)
return
0
;
fail:
if
(
ptask
->
packet
)
ether1394_free_packet
(
ptask
->
packet
);
ptask
->
packet
=
NULL
;
ether1394_free_packet
(
ptask
->
packet
);
if
(
ptask
)
kmem_cache_free
(
packet_task_cache
,
ptask
);
ptask
=
NULL
;
kmem_cache_free
(
packet_task_cache
,
ptask
);
if
(
skb
!=
NULL
)
{
dev_kfree_skb
(
skb
);
skb
=
NULL
;
dev_kfree_skb
(
skb
);
}
spin_lock_irqsave
(
&
priv
->
lock
,
flags
);
...
...
drivers/ieee1394/eth1394.h
View file @
db3e9f28
...
...
@@ -38,7 +38,7 @@
#define ETHER1394_GASP_SPECIFIER_ID_LO (ETHER1394_GASP_SPECIFIER_ID & 0xff)
#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 */
#define NODE_SET (ALL_NODES + 1)
...
...
@@ -56,10 +56,9 @@ struct pdg_list {
struct
eth1394_priv
{
struct
net_device_stats
stats
;
/* Device stats */
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 */
u16
fifo_hi
[
ALL_NODES
];
/* 16bit hi fifo offset per node */
u32
fifo_lo
[
ALL_NODES
];
/* 32bit lo fifo offset per node */
u64
fifo
[
ALL_NODES
];
/* FIFO offset per node */
u64
eui
[
ALL_NODES
];
/* EUI-64 per node */
spinlock_t
lock
;
/* Private lock */
int
broadcast_channel
;
/* Async stream Broadcast Channel */
...
...
@@ -74,6 +73,21 @@ struct host_info {
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
;
/* IP1394 headers */
...
...
drivers/ieee1394/ieee1394.h
View file @
db3e9f28
...
...
@@ -57,7 +57,6 @@
/* Maps speed values above to a string representation */
extern
const
char
*
hpsb_speedto_str
[];
extern
const
u8
hpsb_speedto_maxrec
[];
#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;
/* Some globals used */
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
)
{
...
...
@@ -1246,7 +1245,6 @@ EXPORT_SYMBOL(hpsb_unref_host);
/** ieee1394_core.c **/
EXPORT_SYMBOL
(
hpsb_speedto_str
);
EXPORT_SYMBOL
(
hpsb_speedto_maxrec
);
EXPORT_SYMBOL
(
hpsb_set_packet_complete_task
);
EXPORT_SYMBOL
(
alloc_hpsb_packet
);
EXPORT_SYMBOL
(
free_hpsb_packet
);
...
...
drivers/ieee1394/iso.c
View file @
db3e9f28
...
...
@@ -10,6 +10,7 @@
*/
#include <linux/slab.h>
#include <linux/sched.h>
#include "iso.h"
void
hpsb_iso_stop
(
struct
hpsb_iso
*
iso
)
...
...
drivers/ieee1394/sbp2.c
View file @
db3e9f28
...
...
@@ -79,7 +79,7 @@
#include "sbp2.h"
static
char
version
[]
__devinitdata
=
"$Rev: 9
38
$ Ben Collins <bcollins@debian.org>"
;
"$Rev: 9
42
$ Ben Collins <bcollins@debian.org>"
;
/*
* Module load parameter definitions
...
...
@@ -230,6 +230,8 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id,
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
=
{
.
name
=
SBP2_DEVICE_NAME
,
.
remove_host
=
sbp2_remove_host
,
...
...
@@ -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
->
hi
=
hi
;
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
);
INIT_LIST_HEAD
(
&
scsi_id
->
sbp2_command_orb_inuse
);
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)
/* Payload size is the lesser of what our speed supports and what
* 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
));
SBP2_ERR
(
"Node["
NODE_BUS_FMT
"]: Max speed [%s] - Max payload [%u]"
,
...
...
fs/eventpoll.c
View file @
db3e9f28
...
...
@@ -150,6 +150,14 @@ struct eventpoll {
/* Protect the this structure access */
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_head_t
wq
;
...
...
@@ -279,16 +287,6 @@ static struct super_block *eventpollfs_get_sb(struct file_system_type *fs_type,
/* Safe wake up implementation */
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" */
static
kmem_cache_t
*
epi_cache
;
...
...
@@ -357,15 +355,14 @@ static void ep_poll_safewake(struct poll_safewake *psw, wait_queue_head_t *wq)
list_for_each
(
lnk
,
lsthead
)
{
tncur
=
list_entry
(
lnk
,
struct
wake_task_node
,
llink
);
if
(
tncur
->
task
==
this_task
)
{
if
(
tncur
->
wq
==
wq
||
++
wake_nests
>
EP_MAX_POLLWAKE_NESTS
)
{
/*
* Ops ... loop detected or maximum nest level reached.
* We abort this wake by breaking the cycle itself.
*/
spin_unlock_irqrestore
(
&
psw
->
lock
,
flags
);
return
;
}
if
(
tncur
->
wq
==
wq
||
(
tncur
->
task
==
this_task
&&
++
wake_nests
>
EP_MAX_POLLWAKE_NESTS
))
{
/*
* Ops ... loop detected or maximum nest level reached.
* We abort this wake by breaking the cycle itself.
*/
spin_unlock_irqrestore
(
&
psw
->
lock
,
flags
);
return
;
}
}
...
...
@@ -437,14 +434,15 @@ void eventpoll_release(struct file *file)
* The only hit might come from ep_free() but by holding the semaphore
* will correctly serialize the operation.
*/
down_write
(
&
epsem
);
while
(
!
list_empty
(
lsthead
))
{
epi
=
list_entry
(
lsthead
->
next
,
struct
epitem
,
fllink
);
EP_LIST_DEL
(
&
epi
->
fllink
);
down_write
(
&
epi
->
ep
->
sem
);
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
error
=
-
EEXIST
;
break
;
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
);
else
up_write
(
&
ep
->
sem
);
}
else
error
=
-
ENOENT
;
break
;
case
EPOLL_CTL_MOD
:
...
...
@@ -703,10 +710,6 @@ static int ep_getfd(int *efd, struct inode **einode, struct file **efile)
file
->
f_vfsmnt
=
mntget
(
eventpoll_mnt
);
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_flags
=
O_RDONLY
;
file
->
f_op
=
&
eventpoll_fops
;
...
...
@@ -815,6 +818,7 @@ static int ep_init(struct eventpoll *ep, unsigned int hashbits)
unsigned
int
i
,
hsize
;
rwlock_init
(
&
ep
->
lock
);
init_rwsem
(
&
ep
->
sem
);
init_waitqueue_head
(
&
ep
->
wq
);
init_waitqueue_head
(
&
ep
->
poll_wait
);
INIT_LIST_HEAD
(
&
ep
->
rdllist
);
...
...
@@ -841,11 +845,15 @@ static void ep_free(struct eventpoll *ep)
struct
list_head
*
lsthead
,
*
lnk
;
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
* 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.
...
...
@@ -863,7 +871,7 @@ static void ep_free(struct eventpoll *ep)
/*
* 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
* 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".
*/
for
(
i
=
0
,
hsize
=
1
<<
ep
->
hashbits
;
i
<
hsize
;
i
++
)
{
...
...
@@ -876,7 +884,7 @@ static void ep_free(struct eventpoll *ep)
}
}
up_write
(
&
epsem
);
up_write
(
&
ep
->
sem
);
/* Free hash pages */
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
/* If this file is already in the ready list we exit soon */
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
* 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,
struct
epitem
*
epi
;
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
)
{
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.
* In case this call will lead to the file removal, its
* ->event.events member has been already set to zero and
* this will make the event to be dropped.
* Get the ready file event set. We can safely use the file
* because we are holding the "sem" in read and this will
* guarantee that both the file and the item will not vanish.
*/
fput
(
epi
->
file
);
revents
=
epi
->
file
->
f_op
->
poll
(
epi
->
file
,
NULL
);
/*
* 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,
eventbuf
++
;
if
(
eventbuf
==
EP_MAX_BUF_EVENTS
)
{
if
(
__copy_to_user
(
&
events
[
eventcnt
],
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
);
}
eventbuf
*
sizeof
(
struct
epoll_event
)))
return
-
EFAULT
;
}
eventcnt
+=
eventbuf
;
eventbuf
=
0
;
}
...
...
@@ -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()
* 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
)
{
...
...
@@ -1475,8 +1463,6 @@ static void ep_reinject_items(struct eventpoll *ep, struct list_head *txlist)
list_add_tail
(
&
epi
->
rdllink
,
&
ep
->
rdllist
);
ricnt
++
;
}
ep_release_epitem
(
epi
);
}
if
(
ricnt
)
{
...
...
@@ -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
* eventpoll_release() while we're transfering
* 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().
* eventpoll_release() and epoll_ctl(EPOLL_CTL_DEL).
*/
down_read
(
&
epsem
);
down_read
(
&
ep
->
sem
);
/* 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 */
eventcnt
=
ep_send_events
(
ep
,
&
txlist
,
events
);
...
...
@@ -1528,7 +1509,7 @@ static int ep_events_transfer(struct eventpoll *ep, struct epoll_event *events,
ep_reinject_items
(
ep
,
&
txlist
);
}
up_read
(
&
epsem
);
up_read
(
&
ep
->
sem
);
return
eventcnt
;
}
...
...
@@ -1652,9 +1633,6 @@ static int __init eventpoll_init(void)
{
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 */
ep_poll_safewake_init
(
&
psw
);
...
...
sound/core/ioctl32/pcm32.c
View file @
db3e9f28
...
...
@@ -21,6 +21,7 @@
#include <sound/driver.h>
#include <linux/time.h>
#include <linux/slab.h>
#include <linux/compat.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include "ioctl32.h"
...
...
@@ -136,15 +137,10 @@ struct sndrv_pcm_channel_info32 {
COPY(step);\
}
struct
timeval32
{
s32
tv_sec
;
s32
tv_usec
;
}
__attribute__
((
packed
));
struct
sndrv_pcm_status32
{
s32
state
;
struct
timeval32
trigger_tstamp
;
struct
timeval32
tstamp
;
struct
compat_timespec
trigger_tstamp
;
struct
compat_timespec
tstamp
;
u32
appl_ptr
;
u32
hw_ptr
;
s32
delay
;
...
...
@@ -159,9 +155,9 @@ struct sndrv_pcm_status32 {
{\
COPY(state);\
COPY(trigger_tstamp.tv_sec);\
COPY(trigger_tstamp.tv_
u
sec);\
COPY(trigger_tstamp.tv_
n
sec);\
COPY(tstamp.tv_sec);\
COPY(tstamp.tv_
u
sec);\
COPY(tstamp.tv_
n
sec);\
COPY(appl_ptr);\
COPY(hw_ptr);\
COPY(delay);\
...
...
sound/core/ioctl32/rawmidi32.c
View file @
db3e9f28
...
...
@@ -21,6 +21,7 @@
#include <sound/driver.h>
#include <linux/time.h>
#include <linux/fs.h>
#include <linux/compat.h>
#include <sound/core.h>
#include <sound/rawmidi.h>
#include <asm/uaccess.h>
...
...
@@ -42,14 +43,9 @@ struct sndrv_rawmidi_params32 {
COPY(no_active_sensing);\
}
struct
timeval32
{
s32
tv_sec
;
s32
tv_usec
;
}
__attribute__
((
packed
));
struct
sndrv_rawmidi_status32
{
s32
stream
;
struct
timeval32
tstamp
;
struct
compat_timespec
tstamp
;
u32
avail
;
u32
xruns
;
unsigned
char
reserved
[
16
];
...
...
@@ -59,7 +55,7 @@ struct sndrv_rawmidi_status32 {
{\
COPY(stream);\
COPY(tstamp.tv_sec);\
COPY(tstamp.tv_
u
sec);\
COPY(tstamp.tv_
n
sec);\
COPY(avail);\
COPY(xruns);\
}
...
...
sound/core/ioctl32/timer32.c
View file @
db3e9f28
...
...
@@ -21,6 +21,7 @@
#include <sound/driver.h>
#include <linux/time.h>
#include <linux/fs.h>
#include <linux/compat.h>
#include <sound/core.h>
#include <sound/timer.h>
#include <asm/uaccess.h>
...
...
@@ -31,7 +32,7 @@ struct sndrv_timer_info32 {
s32
card
;
unsigned
char
id
[
64
];
unsigned
char
name
[
80
];
u32
ticks
;
u32
reserved0
;
u32
resolution
;
unsigned
char
reserved
[
64
];
};
...
...
@@ -42,17 +43,11 @@ struct sndrv_timer_info32 {
COPY(card);\
memcpy(dst->id, src->id, sizeof(src->id));\
memcpy(dst->name, src->name, sizeof(src->name));\
COPY(ticks);\
COPY(resolution);\
}
struct
timeval32
{
s32
tv_sec
;
s32
tv_usec
;
};
struct
sndrv_timer_status32
{
struct
timeval32
tstamp
;
struct
compat_timespec
tstamp
;
u32
resolution
;
u32
lost
;
u32
overrun
;
...
...
@@ -63,7 +58,7 @@ struct sndrv_timer_status32 {
#define CVT_sndrv_timer_status()\
{\
COPY(tstamp.tv_sec);\
COPY(tstamp.tv_
u
sec);\
COPY(tstamp.tv_
n
sec);\
COPY(resolution);\
COPY(lost);\
COPY(overrun);\
...
...
sound/drivers/vx/vx_core.c
View file @
db3e9f28
...
...
@@ -24,6 +24,7 @@
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <sound/core.h>
#include <sound/pcm.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)
case
SNDRV_PCM_TRIGGER_STOP
:
{
unsigned
int
what
=
0
;
snd_pcm_substream_t
*
s
=
substream
;
snd_pcm_substream_t
*
s
;
struct
list_head
*
pos
;
unsigned
long
flags
;
do
{
snd_pcm_group_for_each
(
pos
,
substream
)
{
s
=
snd_pcm_group_substream_entry
(
pos
);
if
(
s
==
chip
->
playback_substream
)
{
what
|=
CS4231_PLAYBACK_ENABLE
;
snd_pcm_trigger_done
(
s
,
substream
);
...
...
@@ -727,8 +729,7 @@ static int snd_cs4231_trigger(snd_pcm_substream_t *substream, int cmd)
what
|=
CS4231_RECORD_ENABLE
;
snd_pcm_trigger_done
(
s
,
substream
);
}
s
=
s
->
link_next
;
}
while
(
s
!=
substream
);
}
#if 0
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