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
b3f00969
Commit
b3f00969
authored
Mar 07, 2003
by
Anton Blanchard
Browse files
Options
Browse Files
Download
Plain Diff
Merge samba.org:/scratch/anton/linux-2.5
into samba.org:/scratch/anton/sfr
parents
76b23457
ebd158e7
Changes
49
Show whitespace changes
Inline
Side-by-side
Showing
49 changed files
with
1308 additions
and
553 deletions
+1308
-553
Documentation/ioctl-number.txt
Documentation/ioctl-number.txt
+1
-0
Makefile
Makefile
+1
-1
drivers/base/Makefile
drivers/base/Makefile
+1
-1
drivers/base/bus.c
drivers/base/bus.c
+1
-2
drivers/base/class.c
drivers/base/class.c
+1
-3
drivers/base/core.c
drivers/base/core.c
+1
-3
drivers/base/cpu.c
drivers/base/cpu.c
+1
-2
drivers/base/firmware.c
drivers/base/firmware.c
+1
-3
drivers/base/init.c
drivers/base/init.c
+34
-0
drivers/base/platform.c
drivers/base/platform.c
+22
-4
drivers/base/sys.c
drivers/base/sys.c
+1
-2
drivers/ieee1394/Makefile
drivers/ieee1394/Makefile
+0
-7
drivers/ieee1394/amdtp.c
drivers/ieee1394/amdtp.c
+27
-2
drivers/ieee1394/dma.c
drivers/ieee1394/dma.c
+1
-0
drivers/ieee1394/dv1394.c
drivers/ieee1394/dv1394.c
+134
-7
drivers/ieee1394/eth1394.c
drivers/ieee1394/eth1394.c
+244
-28
drivers/ieee1394/eth1394.h
drivers/ieee1394/eth1394.h
+13
-0
drivers/ieee1394/hosts.c
drivers/ieee1394/hosts.c
+0
-3
drivers/ieee1394/ieee1394-ioctl.h
drivers/ieee1394/ieee1394-ioctl.h
+3
-3
drivers/ieee1394/ieee1394_core.c
drivers/ieee1394/ieee1394_core.c
+6
-8
drivers/ieee1394/ieee1394_transactions.c
drivers/ieee1394/ieee1394_transactions.c
+66
-1
drivers/ieee1394/ieee1394_transactions.h
drivers/ieee1394/ieee1394_transactions.h
+3
-0
drivers/ieee1394/ieee1394_types.h
drivers/ieee1394/ieee1394_types.h
+6
-3
drivers/ieee1394/nodemgr.c
drivers/ieee1394/nodemgr.c
+56
-1
drivers/ieee1394/ohci1394.c
drivers/ieee1394/ohci1394.c
+62
-47
drivers/ieee1394/raw1394.c
drivers/ieee1394/raw1394.c
+4
-5
drivers/ieee1394/sbp2.c
drivers/ieee1394/sbp2.c
+177
-235
drivers/ieee1394/sbp2.h
drivers/ieee1394/sbp2.h
+0
-30
drivers/ieee1394/video1394.c
drivers/ieee1394/video1394.c
+159
-6
drivers/net/dgrs.c
drivers/net/dgrs.c
+2
-2
drivers/net/shaper.c
drivers/net/shaper.c
+3
-3
drivers/net/sis900.c
drivers/net/sis900.c
+1
-1
drivers/scsi/qlogicfc.c
drivers/scsi/qlogicfc.c
+1
-1
fs/dcache.c
fs/dcache.c
+32
-51
fs/filesystems.c
fs/filesystems.c
+78
-14
fs/fs-writeback.c
fs/fs-writeback.c
+1
-1
fs/hugetlbfs/inode.c
fs/hugetlbfs/inode.c
+3
-3
fs/inode.c
fs/inode.c
+40
-48
fs/namespace.c
fs/namespace.c
+2
-0
fs/super.c
fs/super.c
+1
-1
fs/sysfs/bin.c
fs/sysfs/bin.c
+1
-0
fs/sysfs/mount.c
fs/sysfs/mount.c
+1
-3
include/linux/dcache.h
include/linux/dcache.h
+10
-10
include/linux/fs.h
include/linux/fs.h
+5
-2
include/linux/if_shaper.h
include/linux/if_shaper.h
+1
-1
include/linux/list.h
include/linux/list.h
+92
-0
include/linux/tty.h
include/linux/tty.h
+1
-1
init/main.c
init/main.c
+3
-0
net/sunrpc/rpc_pipe.c
net/sunrpc/rpc_pipe.c
+4
-4
No files found.
Documentation/ioctl-number.txt
View file @
b3f00969
...
...
@@ -72,6 +72,7 @@ Code Seq# Include File Comments
linux/blkpg.h
0x20 all drivers/cdrom/cm206.h
0x22 all scsi/sg.h
'#' 00-3F IEEE 1394 Subsystem Block for the entire subsystem
'1' 00-1F <linux/timepps.h> PPS kit from Ulrich Windl
<ftp://ftp.de.kernel.org/pub/linux/daemons/ntp/PPS/>
'6' 00-10 <asm-i386/processor.h> Intel IA32 microcode update driver
...
...
Makefile
View file @
b3f00969
VERSION
=
2
PATCHLEVEL
=
5
SUBLEVEL
=
6
3
SUBLEVEL
=
6
4
EXTRAVERSION
=
# *DOCUMENTATION*
...
...
drivers/base/Makefile
View file @
b3f00969
...
...
@@ -2,7 +2,7 @@
obj-y
:=
core.o sys.o interface.o power.o bus.o
\
driver.o class.o intf.o platform.o
\
cpu.o firmware.o
cpu.o firmware.o
init.o
obj-$(CONFIG_NUMA)
+=
node.o memblk.o
obj-y
+=
fs/
obj-$(CONFIG_HOTPLUG)
+=
hotplug.o
drivers/base/bus.c
View file @
b3f00969
...
...
@@ -544,12 +544,11 @@ void bus_unregister(struct bus_type * bus)
subsystem_unregister
(
&
bus
->
subsys
);
}
static
int
__init
bus_subsy
s_init
(
void
)
int
__init
buse
s_init
(
void
)
{
return
subsystem_register
(
&
bus_subsys
);
}
core_initcall
(
bus_subsys_init
);
EXPORT_SYMBOL
(
bus_for_each_dev
);
EXPORT_SYMBOL
(
bus_for_each_drv
);
...
...
drivers/base/class.c
View file @
b3f00969
...
...
@@ -266,13 +266,11 @@ void devclass_unregister(struct device_class * cls)
subsystem_unregister
(
&
cls
->
subsys
);
}
static
int
__init
class_subsy
s_init
(
void
)
int
__init
classe
s_init
(
void
)
{
return
subsystem_register
(
&
class_subsys
);
}
core_initcall
(
class_subsys_init
);
EXPORT_SYMBOL
(
devclass_create_file
);
EXPORT_SYMBOL
(
devclass_remove_file
);
EXPORT_SYMBOL
(
devclass_register
);
...
...
drivers/base/core.c
View file @
b3f00969
...
...
@@ -309,13 +309,11 @@ void device_unregister(struct device * dev)
put_device
(
dev
);
}
static
int
__init
device_subsy
s_init
(
void
)
int
__init
device
s_init
(
void
)
{
return
subsystem_register
(
&
devices_subsys
);
}
core_initcall
(
device_subsys_init
);
EXPORT_SYMBOL
(
device_initialize
);
EXPORT_SYMBOL
(
device_add
);
EXPORT_SYMBOL
(
device_register
);
...
...
drivers/base/cpu.c
View file @
b3f00969
...
...
@@ -46,9 +46,8 @@ int __init register_cpu(struct cpu *cpu, int num, struct node *root)
}
static
int
__init
register_cpu_type
(
void
)
int
__init
cpu_dev_init
(
void
)
{
devclass_register
(
&
cpu_devclass
);
return
driver_register
(
&
cpu_driver
);
}
postcore_initcall
(
register_cpu_type
);
drivers/base/firmware.c
View file @
b3f00969
...
...
@@ -19,12 +19,10 @@ void firmware_unregister(struct subsystem * s)
subsystem_unregister
(
s
);
}
static
int
__init
firmware_init
(
void
)
int
__init
firmware_init
(
void
)
{
return
subsystem_register
(
&
firmware_subsys
);
}
core_initcall
(
firmware_init
);
EXPORT_SYMBOL
(
firmware_register
);
EXPORT_SYMBOL
(
firmware_unregister
);
drivers/base/init.c
0 → 100644
View file @
b3f00969
#include <linux/device.h>
#include <linux/init.h>
extern
int
devices_init
(
void
);
extern
int
buses_init
(
void
);
extern
int
classes_init
(
void
);
extern
int
firmware_init
(
void
);
extern
int
platform_bus_init
(
void
);
extern
int
sys_bus_init
(
void
);
extern
int
cpu_dev_init
(
void
);
/**
* driver_init - initialize driver model.
*
* Call the driver model init functions to initialize their
* subsystems. Called early from init/main.c.
*/
void
__init
driver_init
(
void
)
{
/* These are the core pieces */
devices_init
();
buses_init
();
classes_init
();
firmware_init
();
/* These are also core pieces, but must come after the
* core core pieces.
*/
platform_bus_init
();
sys_bus_init
();
cpu_dev_init
();
}
drivers/base/platform.c
View file @
b3f00969
...
...
@@ -42,8 +42,28 @@ void platform_device_unregister(struct platform_device * pdev)
device_unregister
(
&
pdev
->
dev
);
}
/**
* platform_match - bind platform device to platform driver.
* @dev: device.
* @drv: driver.
*
* Platform device IDs are assumed to be encoded like this:
* "<name><instance>", where <name> is a short description of the
* type of device, like "pci" or "floppy", and <instance> is the
* enumerated instance of the device, like '0' or '42'.
* Driver IDs are simply "<name>".
* So, extract the <name> from the device, and compare it against
* the name of the driver. Return whether they match or not.
*/
static
int
platform_match
(
struct
device
*
dev
,
struct
device_driver
*
drv
)
{
char
name
[
BUS_ID_SIZE
];
if
(
sscanf
(
dev
->
bus_id
,
"%s"
,
name
))
return
(
strcmp
(
name
,
drv
->
name
)
==
0
);
return
0
;
}
...
...
@@ -52,13 +72,11 @@ struct bus_type platform_bus_type = {
.
match
=
platform_match
,
};
static
int
__init
platform_bus_init
(
void
)
int
__init
platform_bus_init
(
void
)
{
device_register
(
&
legacy_bus
);
return
bus_register
(
&
platform_bus_type
);
}
postcore_initcall
(
platform_bus_init
);
EXPORT_SYMBOL
(
platform_device_register
);
EXPORT_SYMBOL
(
platform_device_unregister
);
drivers/base/sys.c
View file @
b3f00969
...
...
@@ -138,13 +138,12 @@ struct bus_type system_bus_type = {
.
name
=
"system"
,
};
static
in
t
sys_bus_init
(
void
)
int
__ini
t
sys_bus_init
(
void
)
{
bus_register
(
&
system_bus_type
);
return
device_register
(
&
system_bus
);
}
postcore_initcall
(
sys_bus_init
);
EXPORT_SYMBOL
(
system_bus_type
);
EXPORT_SYMBOL
(
sys_device_register
);
EXPORT_SYMBOL
(
sys_device_unregister
);
drivers/ieee1394/Makefile
View file @
b3f00969
...
...
@@ -18,13 +18,6 @@ obj-$(CONFIG_IEEE1394_CMP) += cmp.o
clean-files
:=
oui.c
ieee1394.o
:
$(ieee1394-objs)
$(LD)
$(LDFLAGS)
-r
-o
$@
$
(
ieee1394-objs
)
ifeq
($(obj),)
obj
=
.
endif
$(obj)/oui.o
:
$(obj)/oui.c
$(obj)/oui.c
:
$(obj)/oui.db $(obj)/oui2c.sh
$(CONFIG_SHELL)
$(obj)
/oui2c.sh <
$(obj)
/oui.db
>
$(obj)
/oui.c
drivers/ieee1394/amdtp.c
View file @
b3f00969
...
...
@@ -74,6 +74,8 @@
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/poll.h>
#include <linux/ioctl32.h>
#include <linux/compat.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
...
...
@@ -1262,8 +1264,11 @@ MODULE_LICENSE("GPL");
static
int
__init
amdtp_init_module
(
void
)
{
if
(
ieee1394_register_chardev
(
IEEE1394_MINOR_BLOCK_AMDTP
,
THIS_MODULE
,
&
amdtp_fops
))
{
int
ret
;
ret
=
ieee1394_register_chardev
(
IEEE1394_MINOR_BLOCK_AMDTP
,
THIS_MODULE
,
&
amdtp_fops
);
if
(
ret
)
{
HPSB_ERR
(
"amdtp: unable to get minor device block"
);
return
-
EIO
;
}
...
...
@@ -1276,6 +1281,15 @@ static int __init amdtp_init_module (void)
return
-
EIO
;
}
#ifdef CONFIG_COMPAT
ret
=
register_ioctl32_conversion
(
AMDTP_IOC_CHANNEL
,
NULL
);
ret
|=
register_ioctl32_conversion
(
AMDTP_IOC_PLUG
,
NULL
);
ret
|=
register_ioctl32_conversion
(
AMDTP_IOC_PING
,
NULL
);
ret
|=
register_ioctl32_conversion
(
AMDTP_IOC_ZAP
,
NULL
);
if
(
ret
)
HPSB_ERR
(
"amdtp: Error registering ioctl32 translations"
);
#endif
HPSB_INFO
(
"Loaded AMDTP driver"
);
return
0
;
...
...
@@ -1283,6 +1297,17 @@ static int __init amdtp_init_module (void)
static
void
__exit
amdtp_exit_module
(
void
)
{
#ifdef CONFIG_COMPAT
int
ret
;
ret
=
unregister_ioctl32_conversion
(
AMDTP_IOC_CHANNEL
);
ret
|=
unregister_ioctl32_conversion
(
AMDTP_IOC_PLUG
);
ret
|=
unregister_ioctl32_conversion
(
AMDTP_IOC_PING
);
ret
|=
unregister_ioctl32_conversion
(
AMDTP_IOC_ZAP
);
if
(
ret
)
HPSB_ERR
(
"amdtp: Error unregistering ioctl32 translations"
);
#endif
hpsb_unregister_highlevel
(
amdtp_highlevel
);
ieee1394_unregister_chardev
(
IEEE1394_MINOR_BLOCK_AMDTP
);
...
...
drivers/ieee1394/dma.c
View file @
b3f00969
...
...
@@ -10,6 +10,7 @@
#include <linux/module.h>
#include <linux/vmalloc.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include "dma.h"
/* dma_prog_region */
...
...
drivers/ieee1394/dv1394.c
View file @
b3f00969
...
...
@@ -111,6 +111,8 @@
#include <linux/wrapper.h>
#include <linux/vmalloc.h>
#include <linux/string.h>
#include <linux/ioctl32.h>
#include <linux/compat.h>
#include "ieee1394.h"
#include "ieee1394_types.h"
...
...
@@ -2701,7 +2703,7 @@ static void dv1394_remove_host (struct hpsb_host *host)
struct
ti_ohci
*
ohci
;
struct
video_card
*
video
=
NULL
;
unsigned
long
flags
;
struct
list_head
*
lh
;
struct
list_head
*
lh
,
*
templh
;
char
buf
[
32
];
int
n
;
...
...
@@ -2715,7 +2717,7 @@ static void dv1394_remove_host (struct hpsb_host *host)
/* find the corresponding video_cards */
spin_lock_irqsave
(
&
dv1394_cards_lock
,
flags
);
if
(
!
list_empty
(
&
dv1394_cards
))
{
list_for_each
(
lh
,
&
dv1394_cards
)
{
list_for_each
_safe
(
lh
,
temp
lh
,
&
dv1394_cards
)
{
video
=
list_entry
(
lh
,
struct
video_card
,
list
);
if
((
video
->
id
>>
2
)
==
ohci
->
id
)
dv1394_un_init
(
video
);
...
...
@@ -2907,6 +2909,98 @@ static struct hpsb_highlevel_ops hl_ops = {
.
host_reset
=
dv1394_host_reset
,
};
#ifdef CONFIG_COMPAT
#define DV1394_IOC32_INIT _IOW('#', 0x06, struct dv1394_init32)
#define DV1394_IOC32_GET_STATUS _IOR('#', 0x0c, struct dv1394_status32)
struct
dv1394_init32
{
u32
api_version
;
u32
channel
;
u32
n_frames
;
u32
format
;
u32
cip_n
;
u32
cip_d
;
u32
syt_offset
;
};
struct
dv1394_status32
{
struct
dv1394_init32
init
;
s32
active_frame
;
u32
first_clear_frame
;
u32
n_clear_frames
;
u32
dropped_frames
;
};
static
int
handle_dv1394_init
(
unsigned
int
fd
,
unsigned
int
cmd
,
unsigned
long
arg
,
struct
file
*
file
)
{
struct
dv1394_init32
dv32
;
struct
dv1394_init
dv
;
mm_segment_t
old_fs
;
int
ret
;
if
(
file
->
f_op
->
ioctl
!=
dv1394_ioctl
)
return
-
EFAULT
;
if
(
copy_from_user
(
&
dv32
,
(
void
*
)
arg
,
sizeof
(
dv32
)))
return
-
EFAULT
;
dv
.
api_version
=
dv32
.
api_version
;
dv
.
channel
=
dv32
.
channel
;
dv
.
n_frames
=
dv32
.
n_frames
;
dv
.
format
=
dv32
.
format
;
dv
.
cip_n
=
(
unsigned
long
)
dv32
.
cip_n
;
dv
.
cip_d
=
(
unsigned
long
)
dv32
.
cip_d
;
dv
.
syt_offset
=
dv32
.
syt_offset
;
old_fs
=
get_fs
();
set_fs
(
KERNEL_DS
);
ret
=
dv1394_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
DV1394_IOC_INIT
,
(
unsigned
long
)
&
dv
);
set_fs
(
old_fs
);
return
ret
;
}
static
int
handle_dv1394_get_status
(
unsigned
int
fd
,
unsigned
int
cmd
,
unsigned
long
arg
,
struct
file
*
file
)
{
struct
dv1394_status32
dv32
;
struct
dv1394_status
dv
;
mm_segment_t
old_fs
;
int
ret
;
if
(
file
->
f_op
->
ioctl
!=
dv1394_ioctl
)
return
-
EFAULT
;
old_fs
=
get_fs
();
set_fs
(
KERNEL_DS
);
ret
=
dv1394_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
DV1394_IOC_GET_STATUS
,
(
unsigned
long
)
&
dv
);
set_fs
(
old_fs
);
if
(
!
ret
)
{
dv32
.
init
.
api_version
=
dv
.
init
.
api_version
;
dv32
.
init
.
channel
=
dv
.
init
.
channel
;
dv32
.
init
.
n_frames
=
dv
.
init
.
n_frames
;
dv32
.
init
.
format
=
dv
.
init
.
format
;
dv32
.
init
.
cip_n
=
(
u32
)
dv
.
init
.
cip_n
;
dv32
.
init
.
cip_d
=
(
u32
)
dv
.
init
.
cip_d
;
dv32
.
init
.
syt_offset
=
dv
.
init
.
syt_offset
;
dv32
.
active_frame
=
dv
.
active_frame
;
dv32
.
first_clear_frame
=
dv
.
first_clear_frame
;
dv32
.
n_clear_frames
=
dv
.
n_clear_frames
;
dv32
.
dropped_frames
=
dv
.
dropped_frames
;
if
(
copy_to_user
((
struct
dv1394_status32
*
)
arg
,
&
dv32
,
sizeof
(
dv32
)))
ret
=
-
EFAULT
;
}
return
ret
;
}
#endif
/* CONFIG_COMPAT */
/*** KERNEL MODULE HANDLERS ************************************************/
...
...
@@ -2917,6 +3011,20 @@ MODULE_LICENSE("GPL");
static
void
__exit
dv1394_exit_module
(
void
)
{
#ifdef CONFIG_COMPAT
int
ret
;
ret
=
unregister_ioctl32_conversion
(
DV1394_IOC_SHUTDOWN
);
ret
|=
unregister_ioctl32_conversion
(
DV1394_IOC_SUBMIT_FRAMES
);
ret
|=
unregister_ioctl32_conversion
(
DV1394_IOC_WAIT_FRAMES
);
ret
|=
unregister_ioctl32_conversion
(
DV1394_IOC_RECEIVE_FRAMES
);
ret
|=
unregister_ioctl32_conversion
(
DV1394_IOC_START_RECEIVE
);
ret
|=
unregister_ioctl32_conversion
(
DV1394_IOC32_INIT
);
ret
|=
unregister_ioctl32_conversion
(
DV1394_IOC32_GET_STATUS
);
if
(
ret
)
printk
(
KERN_ERR
"dv1394: Error unregistering ioctl32 translations
\n
"
);
#endif
hpsb_unregister_highlevel
(
hl_handle
);
ieee1394_unregister_chardev
(
IEEE1394_MINOR_BLOCK_DV1394
);
#ifdef CONFIG_DEVFS_FS
...
...
@@ -2929,14 +3037,18 @@ static void __exit dv1394_exit_module(void)
static
int
__init
dv1394_init_module
(
void
)
{
if
(
ieee1394_register_chardev
(
IEEE1394_MINOR_BLOCK_DV1394
,
THIS_MODULE
,
&
dv1394_fops
))
{
int
ret
;
ret
=
ieee1394_register_chardev
(
IEEE1394_MINOR_BLOCK_DV1394
,
THIS_MODULE
,
&
dv1394_fops
);
if
(
ret
)
{
printk
(
KERN_ERR
"dv1394: unable to register character device
\n
"
);
return
-
EIO
;
}
#ifdef CONFIG_DEVFS_FS
if
(
dv1394_devfs_add_dir
(
"dv"
,
NULL
,
NULL
)
<
0
)
{
ret
=
dv1394_devfs_add_dir
(
"dv"
,
NULL
,
NULL
);
if
(
ret
<
0
)
{
printk
(
KERN_ERR
"dv1394: unable to create /dev/ieee1394/dv
\n
"
);
ieee1394_unregister_chardev
(
IEEE1394_MINOR_BLOCK_DV1394
);
return
-
ENOMEM
;
...
...
@@ -2944,7 +3056,8 @@ static int __init dv1394_init_module(void)
#endif
#ifdef CONFIG_PROC_FS
if
(
dv1394_procfs_add_dir
(
"dv"
,
NULL
,
NULL
)
<
0
)
{
ret
=
dv1394_procfs_add_dir
(
"dv"
,
NULL
,
NULL
);
if
(
ret
<
0
)
{
printk
(
KERN_ERR
"dv1394: unable to create /proc/bus/ieee1394/dv
\n
"
);
ieee1394_unregister_chardev
(
IEEE1394_MINOR_BLOCK_DV1394
);
#ifdef CONFIG_DEVFS_FS
...
...
@@ -2967,9 +3080,23 @@ static int __init dv1394_init_module(void)
return
-
ENOMEM
;
}
#ifdef CONFIG_COMPAT
/* First compatible ones */
ret
=
register_ioctl32_conversion
(
DV1394_IOC_SHUTDOWN
,
NULL
);
ret
|=
register_ioctl32_conversion
(
DV1394_IOC_SUBMIT_FRAMES
,
NULL
);
ret
|=
register_ioctl32_conversion
(
DV1394_IOC_WAIT_FRAMES
,
NULL
);
ret
|=
register_ioctl32_conversion
(
DV1394_IOC_RECEIVE_FRAMES
,
NULL
);
ret
|=
register_ioctl32_conversion
(
DV1394_IOC_START_RECEIVE
,
NULL
);
/* These need to be handled by translation */
ret
|=
register_ioctl32_conversion
(
DV1394_IOC32_INIT
,
handle_dv1394_init
);
ret
|=
register_ioctl32_conversion
(
DV1394_IOC32_GET_STATUS
,
handle_dv1394_get_status
);
if
(
ret
)
printk
(
KERN_ERR
"dv1394: Error registering ioctl32 translations
\n
"
);
#endif
return
0
;
}
module_init
(
dv1394_init_module
);
module_exit
(
dv1394_exit_module
);
drivers/ieee1394/eth1394.c
View file @
b3f00969
...
...
@@ -65,6 +65,7 @@
#include "ieee1394_transactions.h"
#include "ieee1394.h"
#include "highlevel.h"
#include "iso.h"
#include "eth1394.h"
#define ETH1394_PRINT_G(level, fmt, args...) \
...
...
@@ -77,7 +78,7 @@
printk(KERN_ERR fmt, ## args)
static
char
version
[]
__devinitdata
=
"$Rev:
770
$ Ben Collins <bcollins@debian.org>"
;
"$Rev:
806
$ Ben Collins <bcollins@debian.org>"
;
/* Our ieee1394 highlevel driver */
#define ETHER1394_DRIVER_NAME "ether1394"
...
...
@@ -101,6 +102,9 @@ MODULE_AUTHOR("Ben Collins (bcollins@debian.org)");
MODULE_DESCRIPTION
(
"IEEE 1394 IPv4 Driver (IPv4-over-1394 as per RFC 2734)"
);
MODULE_LICENSE
(
"GPL"
);
static
void
ether1394_iso
(
struct
hpsb_iso
*
iso
);
/* Find our host_info struct for a given host pointer. Must be called
* under spinlock. */
static
inline
struct
host_info
*
find_host_info
(
struct
hpsb_host
*
host
)
...
...
@@ -178,15 +182,26 @@ static void ether1394_tx_timeout (struct net_device *dev)
* XXX: This is where we need to create a list of skb's for fragmented
* packets. */
static
inline
void
ether1394_encapsulate
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
,
int
proto
)
int
proto
,
struct
packet_task
*
ptask
)
{
union
eth1394_hdr
*
hdr
=
(
union
eth1394_hdr
*
)
skb_push
(
skb
,
hdr_type_len
[
ETH1394_HDR_LF_UF
]);
hdr
->
words
.
word1
=
0
;
hdr
->
common
.
lf
=
ETH1394_HDR_LF_UF
;
hdr
->
words
.
word1
=
htons
(
hdr
->
words
.
word1
);
hdr
->
uf
.
ether_type
=
proto
;
/* Set the transmission type for the packet. Right now only ARP
* packets are sent via GASP. IP broadcast and IP multicast are not
* yet supported properly, they too should use GASP. */
switch
(
proto
)
{
case
__constant_htons
(
ETH_P_ARP
):
ptask
->
tx_type
=
ETH1394_GASP
;
break
;
default:
ptask
->
tx_type
=
ETH1394_WRREQ
;
}
return
;
}
...
...
@@ -199,14 +214,14 @@ static inline void ether1394_arp_to_1394arp (struct sk_buff *skb, struct net_dev
{
struct
eth1394_priv
*
priv
=
(
struct
eth1394_priv
*
)(
dev
->
priv
);
u16
phy_id
=
priv
->
host
->
node_id
&
NODE_MASK
;
u16
phy_id
=
NODEID_TO_NODE
(
priv
->
host
->
node_id
)
;
unsigned
char
*
arp_ptr
=
(
unsigned
char
*
)
skb
->
data
;
struct
eth1394_arp
*
arp1394
=
(
struct
eth1394_arp
*
)
skb
->
data
;
unsigned
char
arp_data
[
2
*
(
dev
->
addr_len
+
4
)];
/* Copy the main data that we need */
arp_ptr
=
memcpy
(
arp_data
,
arp_ptr
+
sizeof
(
struct
arphdr
),
sizeof
(
arp_data
));
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
)
-
...
...
@@ -214,7 +229,7 @@ static inline void ether1394_arp_to_1394arp (struct sk_buff *skb, struct net_dev
#define PROCESS_MEMBER(ptr,val,len) \
memcpy (val, ptr, len); ptr += len
arp_ptr
+=
arp1394
->
hw_addr_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
);
...
...
@@ -279,7 +294,8 @@ static void ether1394_reset_priv (struct net_device *dev, int set_mtu)
{
unsigned
long
flags
;
struct
eth1394_priv
*
priv
=
(
struct
eth1394_priv
*
)
dev
->
priv
;
int
phy_id
=
priv
->
host
->
node_id
&
NODE_MASK
;
int
phy_id
=
NODEID_TO_NODE
(
priv
->
host
->
node_id
);
struct
hpsb_host
*
host
=
priv
->
host
;
spin_lock_irqsave
(
&
priv
->
lock
,
flags
);
...
...
@@ -289,20 +305,23 @@ static void ether1394_reset_priv (struct net_device *dev, int set_mtu)
memset
(
priv
->
fifo_hi
,
0
,
sizeof
(
priv
->
fifo_hi
));
memset
(
priv
->
fifo_lo
,
0
,
sizeof
(
priv
->
fifo_lo
));
priv
->
bc_state
=
ETHER1394_BC_CHECK
;
/* Register our limits now */
ether1394_register_limits
(
phy_id
,
(
be32_to_cpu
(
priv
->
host
->
csr
.
rom
[
2
])
>>
12
)
&
0xf
,
priv
->
host
->
speed_map
[(
phy_id
<<
6
)
+
phy_id
],
(
u64
)(((
u64
)
be32_to_cpu
(
priv
->
host
->
csr
.
rom
[
3
])
<<
32
)
|
be32_to_cpu
(
priv
->
host
->
csr
.
rom
[
4
])),
ether1394_register_limits
(
phy_id
,
(
be32_to_cpu
(
host
->
csr
.
rom
[
2
])
>>
12
)
&
0xf
,
host
->
speed_map
[(
phy_id
<<
6
)
+
phy_id
],
(
u64
)(((
u64
)
be32_to_cpu
(
host
->
csr
.
rom
[
3
])
<<
32
)
|
be32_to_cpu
(
host
->
csr
.
rom
[
4
])),
ETHER1394_REGION_ADDR
>>
32
,
ETHER1394_REGION_ADDR
&
0xffffffff
,
priv
);
/* We'll use our max_rec as the default mtu */
if
(
set_mtu
)
dev
->
mtu
=
(
1
<<
(
priv
->
max_rec
[
phy_id
]
+
1
))
-
sizeof
(
union
eth1394_hdr
);
dev
->
mtu
=
(
1
<<
(
priv
->
max_rec
[
phy_id
]
+
1
))
-
/* mtu = max_rec - */
(
sizeof
(
union
eth1394_hdr
)
+
8
);
/* (hdr + GASP) */
/* Set our hardware address while we're at it */
*
(
nodeid_t
*
)
dev
->
dev_addr
=
htons
(
priv
->
host
->
node_id
);
*
(
nodeid_t
*
)
dev
->
dev_addr
=
htons
(
host
->
node_id
);
spin_unlock_irqrestore
(
&
priv
->
lock
,
flags
);
}
...
...
@@ -383,6 +402,15 @@ static void ether1394_add_host (struct hpsb_host *host)
list_add_tail
(
&
hi
->
list
,
&
host_info_list
);
spin_unlock_irq
(
&
host_info_lock
);
/* Ignore validity in hopes that it will be set in the future. It'll
* check it on transmit. */
priv
->
broadcast_channel
=
host
->
csr
.
broadcast_channel
&
0x3f
;
priv
->
iso
=
hpsb_iso_recv_init
(
host
,
8
*
4096
,
8
,
priv
->
broadcast_channel
,
1
,
ether1394_iso
);
if
(
priv
->
iso
==
NULL
)
{
priv
->
bc_state
=
ETHER1394_BC_CLOSED
;
}
return
;
out:
...
...
@@ -396,11 +424,14 @@ static void ether1394_add_host (struct hpsb_host *host)
/* Remove a card from our list */
static
void
ether1394_remove_host
(
struct
hpsb_host
*
host
)
{
struct
eth1394_priv
*
priv
;
struct
host_info
*
hi
;
spin_lock_irq
(
&
host_info_lock
);
hi
=
find_host_info
(
host
);
if
(
hi
!=
NULL
)
{
priv
=
(
struct
eth1394_priv
*
)
hi
->
dev
->
priv
;
priv
->
bc_state
=
ETHER1394_BC_CLOSED
;
unregister_netdev
(
hi
->
dev
);
kfree
(
hi
->
dev
);
list_del
(
&
hi
->
list
);
...
...
@@ -480,7 +511,7 @@ static inline unsigned short ether1394_parse_encap (struct sk_buff *skb, struct
* about the sending machine. */
if
(
hdr
->
uf
.
ether_type
==
__constant_htons
(
ETH_P_ARP
))
{
unsigned
long
flags
;
u16
phy_id
=
srcid
&
NODE_MASK
;
u16
phy_id
=
NODEID_TO_NODE
(
srcid
)
;
struct
eth1394_priv
*
priv
=
(
struct
eth1394_priv
*
)
dev
->
priv
;
struct
eth1394_arp
arp1394
;
...
...
@@ -498,7 +529,7 @@ static inline unsigned short ether1394_parse_encap (struct sk_buff *skb, struct
spin_unlock_irqrestore
(
&
priv
->
lock
,
flags
);
#define PROCESS_MEMBER(ptr,val,len) \
ptr = memcpy (ptr, val, len) +
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
);
...
...
@@ -591,6 +622,104 @@ static int ether1394_write (struct hpsb_host *host, int srcid, int destid,
return
RCODE_COMPLETE
;
}
static
void
ether1394_iso
(
struct
hpsb_iso
*
iso
)
{
struct
sk_buff
*
skb
;
quadlet_t
*
data
;
char
*
buf
;
int
flags
;
struct
net_device
*
dev
=
ether1394_find_dev
(
iso
->
host
);
struct
eth1394_priv
*
priv
;
unsigned
int
len
;
u32
specifier_id
;
u16
source_id
;
int
i
;
int
nready
;
if
(
dev
==
NULL
)
{
ETH1394_PRINT_G
(
KERN_ERR
,
"Could not find net device for host %s
\n
"
,
iso
->
host
->
driver
->
name
);
return
;
}
nready
=
hpsb_iso_n_ready
(
iso
);
for
(
i
=
0
;
i
<
nready
;
i
++
)
{
struct
hpsb_iso_packet_info
*
info
=
&
iso
->
infos
[
iso
->
first_packet
+
i
];
data
=
(
quadlet_t
*
)
(
iso
->
data_buf
.
kvirt
+
info
->
offset
);
/* skip over GASP header */
buf
=
(
char
*
)
data
+
8
;
len
=
info
->
len
-
8
;
specifier_id
=
(((
be32_to_cpu
(
data
[
0
])
&
0xffff
)
<<
8
)
|
((
be32_to_cpu
(
data
[
1
])
&
0xff000000
)
>>
24
));
source_id
=
be32_to_cpu
(
data
[
0
])
>>
16
;
priv
=
(
struct
eth1394_priv
*
)
dev
->
priv
;
if
(
info
->
channel
!=
priv
->
broadcast_channel
||
specifier_id
!=
ETHER1394_GASP_SPECIFIER_ID
)
{
/* This packet is not for us */
continue
;
}
/* A packet has been received by the ieee1394 bus. Build an skbuff
* around it so we can pass it to the high level network layer. */
skb
=
dev_alloc_skb
(
len
+
dev
->
hard_header_len
+
15
);
if
(
!
skb
)
{
HPSB_PRINT
(
KERN_ERR
,
"ether1394 rx: low on mem
\n
"
);
priv
->
stats
.
rx_dropped
++
;
break
;
}
skb_reserve
(
skb
,
(
dev
->
hard_header_len
+
15
)
&
~
15
);
memcpy
(
skb_put
(
skb
,
len
),
buf
,
len
);
/* Write metadata, and then pass to the receive level */
skb
->
dev
=
dev
;
skb
->
ip_summed
=
CHECKSUM_UNNECESSARY
;
/* don't check it */
/* Parse the encapsulation header. This actually does the job of
* converting to an ethernet frame header, aswell as arp
* conversion if needed. ARP conversion is easier in this
* direction, since we are using ethernet as our backend. */
skb
->
protocol
=
ether1394_parse_encap
(
skb
,
dev
,
source_id
,
LOCAL_BUS
|
ALL_NODES
);
spin_lock_irqsave
(
&
priv
->
lock
,
flags
);
if
(
!
skb
->
protocol
)
{
priv
->
stats
.
rx_errors
++
;
priv
->
stats
.
rx_dropped
++
;
dev_kfree_skb_any
(
skb
);
goto
bad_proto
;
}
netif_stop_queue
(
dev
);
if
(
netif_rx
(
skb
)
==
NET_RX_DROP
)
{
priv
->
stats
.
rx_errors
++
;
priv
->
stats
.
rx_dropped
++
;
goto
bad_proto
;
}
/* Statistics */
priv
->
stats
.
rx_packets
++
;
priv
->
stats
.
rx_bytes
+=
skb
->
len
;
bad_proto:
spin_unlock_irqrestore
(
&
priv
->
lock
,
flags
);
}
hpsb_iso_recv_release_packets
(
iso
,
i
);
netif_start_queue
(
dev
);
dev
->
last_rx
=
jiffies
;
return
;
}
/* This function is our scheduled write */
static
void
hpsb_write_sched
(
void
*
__ptask
)
{
...
...
@@ -599,12 +728,25 @@ static void hpsb_write_sched (void *__ptask)
struct
net_device
*
dev
=
ptask
->
skb
->
dev
;
struct
eth1394_priv
*
priv
=
(
struct
eth1394_priv
*
)
dev
->
priv
;
unsigned
long
flags
;
int
status
;
if
(
ptask
->
tx_type
==
ETH1394_GASP
)
{
status
=
hpsb_send_gasp
(
priv
->
host
,
priv
->
broadcast_channel
,
get_hpsb_generation
(
priv
->
host
),
(
quadlet_t
*
)
skb
->
data
,
skb
->
len
,
ETHER1394_GASP_SPECIFIER_ID
,
ETHER1394_GASP_VERSION
);
}
else
{
status
=
hpsb_write
(
priv
->
host
,
ptask
->
dest_node
,
get_hpsb_generation
(
priv
->
host
),
ptask
->
addr
,
(
quadlet_t
*
)
skb
->
data
,
skb
->
len
);
}
/* Statistics */
spin_lock_irqsave
(
&
priv
->
lock
,
flags
);
if
(
!
hpsb_write
(
priv
->
host
,
ptask
->
dest_node
,
get_hpsb_generation
(
priv
->
host
),
ptask
->
addr
,
(
quadlet_t
*
)
skb
->
data
,
skb
->
len
))
{
if
(
!
status
)
{
priv
->
stats
.
tx_bytes
+=
skb
->
len
;
priv
->
stats
.
tx_packets
++
;
}
else
{
...
...
@@ -636,6 +778,67 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev)
struct
packet_task
*
ptask
=
NULL
;
int
ret
=
0
;
spin_lock_irqsave
(
&
priv
->
lock
,
flags
);
if
(
priv
->
bc_state
==
ETHER1394_BC_CLOSED
)
{
ETH1394_PRINT
(
KERN_ERR
,
dev
->
name
,
"Cannot send packet, no broadcast channel available."
);
ret
=
-
EAGAIN
;
goto
fail
;
}
/* First time sending? Need a broadcast channel for ARP and for
* listening on */
if
(
priv
->
bc_state
==
ETHER1394_BC_CHECK
)
{
quadlet_t
bc
;
/* Get the local copy of the broadcast channel and check its
* validity (the IRM should validate it for us) */
bc
=
priv
->
host
->
csr
.
broadcast_channel
;
if
((
bc
&
0xc0000000
)
!=
0xc0000000
)
{
/* broadcast channel not validated yet */
ETH1394_PRINT
(
KERN_WARNING
,
dev
->
name
,
"Error BROADCAST_CHANNEL register valid "
"bit not set, can't send IP traffic
\n
"
);
hpsb_iso_shutdown
(
priv
->
iso
);
priv
->
bc_state
=
ETHER1394_BC_CLOSED
;
ret
=
-
EAGAIN
;
spin_unlock_irqrestore
(
&
priv
->
lock
,
flags
);
goto
fail
;
}
if
(
priv
->
broadcast_channel
!=
(
bc
&
0x3f
))
{
/* This really shouldn't be possible, but just in case
* the IEEE 1394 spec changes regarding broadcast
* channels in the future. */
hpsb_iso_shutdown
(
priv
->
iso
);
priv
->
broadcast_channel
=
bc
&
0x3f
;
ETH1394_PRINT
(
KERN_WARNING
,
dev
->
name
,
"Changing to broadcast channel %d...
\n
"
,
priv
->
broadcast_channel
);
priv
->
iso
=
hpsb_iso_recv_init
(
priv
->
host
,
8
*
4096
,
8
,
priv
->
broadcast_channel
,
1
,
ether1394_iso
);
if
(
priv
->
iso
==
NULL
)
{
ret
=
-
EAGAIN
;
goto
fail
;
}
}
if
(
hpsb_iso_recv_start
(
priv
->
iso
,
-
1
,
(
1
<<
3
),
-
1
)
<
0
)
{
ETH1394_PRINT
(
KERN_ERR
,
dev
->
name
,
"Could not start async reception
\n
"
);
hpsb_iso_shutdown
(
priv
->
iso
);
priv
->
bc_state
=
ETHER1394_BC_CLOSED
;
ret
=
-
EAGAIN
;
spin_unlock_irqrestore
(
&
priv
->
lock
,
flags
);
goto
fail
;
}
priv
->
bc_state
=
ETHER1394_BC_OPENED
;
}
spin_unlock_irqrestore
(
&
priv
->
lock
,
flags
);
if
((
skb
=
skb_share_check
(
skb
,
kmflags
))
==
NULL
)
{
ret
=
-
ENOMEM
;
goto
fail
;
...
...
@@ -654,8 +857,14 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev)
if
(
proto
==
__constant_htons
(
ETH_P_ARP
))
ether1394_arp_to_1394arp
(
skb
,
dev
);
ptask
=
kmem_cache_alloc
(
packet_task_cache
,
kmflags
);
if
(
ptask
==
NULL
)
{
ret
=
-
ENOMEM
;
goto
fail
;
}
/* Now add our encapsulation header */
ether1394_encapsulate
(
skb
,
dev
,
proto
);
ether1394_encapsulate
(
skb
,
dev
,
proto
,
ptask
);
/* TODO: The above encapsulate function needs to recognize when a
* packet needs to be split for a specified node. It should create
...
...
@@ -667,19 +876,13 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev)
* need this hack. */
spin_lock_irqsave
(
&
priv
->
lock
,
flags
);
addr
=
(
u64
)
priv
->
fifo_hi
[
dest_node
&
NODE_MASK
]
<<
32
|
priv
->
fifo_lo
[
dest_node
&
NODE_MASK
];
addr
=
(
u64
)
priv
->
fifo_hi
[
NODEID_TO_NODE
(
dest_node
)
]
<<
32
|
priv
->
fifo_lo
[
NODEID_TO_NODE
(
dest_node
)
];
spin_unlock_irqrestore
(
&
priv
->
lock
,
flags
);
if
(
!
addr
)
addr
=
ETHER1394_REGION_ADDR
;
ptask
=
kmem_cache_alloc
(
packet_task_cache
,
kmflags
);
if
(
ptask
==
NULL
)
{
ret
=
-
ENOMEM
;
goto
fail
;
}
ptask
->
skb
=
skb
;
ptask
->
addr
=
addr
;
ptask
->
dest_node
=
dest_node
;
...
...
@@ -702,7 +905,7 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev)
netif_wake_queue
(
dev
);
spin_unlock_irqrestore
(
&
priv
->
lock
,
flags
);
return
ret
;
return
0
;
/* returning non-zero causes serious problems */
}
/* Function for incoming 1394 packets */
...
...
@@ -738,6 +941,19 @@ static int __init ether1394_init_module (void)
static
void
__exit
ether1394_exit_module
(
void
)
{
struct
list_head
*
lh
;
struct
host_info
*
hi
;
struct
eth1394_priv
*
priv
;
lh
=
host_info_list
.
next
;
while
(
lh
!=
&
host_info_list
)
{
hi
=
list_entry
(
lh
,
struct
host_info
,
list
);
priv
=
(
struct
eth1394_priv
*
)
hi
->
dev
->
priv
;
if
(
priv
->
bc_state
!=
ETHER1394_BC_CLOSED
)
{
hpsb_iso_shutdown
(
priv
->
iso
);
}
lh
=
lh
->
next
;
}
hpsb_unregister_highlevel
(
hl_handle
);
kmem_cache_destroy
(
packet_task_cache
);
}
...
...
drivers/ieee1394/eth1394.h
View file @
b3f00969
...
...
@@ -30,9 +30,16 @@
#define ETHER1394_REGION_ADDR 0xfffff0200000ULL
#define ETHER1394_REGION_ADDR_END (ETHER1394_REGION_ADDR + ETHER1394_REGION_ADDR_LEN)
/* GASP identifier numbers for IPv4 over IEEE 1394 */
#define ETHER1394_GASP_SPECIFIER_ID 0x00005E
#define ETHER1394_GASP_VERSION 1
/* Node set == 64 */
#define NODE_SET (ALL_NODES + 1)
enum
eth1394_bc_states
{
ETHER1394_BC_CLOSED
,
ETHER1394_BC_OPENED
,
ETHER1394_BC_CHECK
};
/* Private structure for our ethernet driver */
struct
eth1394_priv
{
struct
net_device_stats
stats
;
/* Device stats */
...
...
@@ -43,6 +50,9 @@ struct eth1394_priv {
u32
fifo_lo
[
ALL_NODES
];
/* 32bit lo fifo offset per node */
u64
eui
[
ALL_NODES
];
/* EUI-64 per node */
spinlock_t
lock
;
/* Private lock */
int
broadcast_channel
;
/* Async stream Broadcast Channel */
enum
eth1394_bc_states
bc_state
;
/* broadcast channel state */
struct
hpsb_iso
*
iso
;
/* Async stream recv handle */
};
struct
host_info
{
...
...
@@ -51,12 +61,15 @@ struct host_info {
struct
net_device
*
dev
;
};
typedef
enum
{
ETH1394_GASP
,
ETH1394_WRREQ
}
eth1394_tx_type
;
/* This is our task struct. It's used for the packet complete callback. */
struct
packet_task
{
struct
sk_buff
*
skb
;
/* Socket buffer we are sending */
nodeid_t
dest_node
;
/* Destination of the packet */
u64
addr
;
/* Address */
struct
hpsb_queue_struct
tq
;
/* The task */
eth1394_tx_type
tx_type
;
/* Send data via GASP or Write Req. */
};
/* IP1394 headers */
...
...
drivers/ieee1394/hosts.c
View file @
b3f00969
...
...
@@ -71,9 +71,6 @@ int hpsb_ref_host(struct hpsb_host *host)
list_for_each
(
lh
,
&
hosts
)
{
if
(
host
==
list_entry
(
lh
,
struct
hpsb_host
,
host_list
))
{
if
(
try_module_get
(
host
->
driver
->
owner
))
{
/* we're doing this twice and don't seem
to undo it.. --hch */
(
void
)
try_module_get
(
host
->
driver
->
owner
);
host
->
refcount
++
;
retval
=
1
;
}
...
...
drivers/ieee1394/ieee1394-ioctl.h
View file @
b3f00969
...
...
@@ -4,8 +4,8 @@
#ifndef __IEEE1394_IOCTL_H
#define __IEEE1394_IOCTL_H
#include <
asm
/ioctl.h>
#include <
asm
/types.h>
#include <
linux
/ioctl.h>
#include <
linux
/types.h>
/* AMDTP Gets 6 */
...
...
@@ -91,7 +91,7 @@
#define RAW1394_IOC_ISO_RECV_UNLISTEN_CHANNEL \
_IOW ('#', 0x23, unsigned char)
#define RAW1394_IOC_ISO_RECV_SET_CHANNEL_MASK \
_IOW ('#', 0x24, u64)
_IOW ('#', 0x24,
__
u64)
#define RAW1394_IOC_ISO_RECV_PACKETS \
_IOW ('#', 0x25, struct raw1394_iso_packets)
#define RAW1394_IOC_ISO_RECV_RELEASE_PACKETS \
...
...
drivers/ieee1394/ieee1394_core.c
View file @
b3f00969
...
...
@@ -361,7 +361,7 @@ void hpsb_selfid_received(struct hpsb_host *host, quadlet_t sid)
host
->
topology_map
[
host
->
selfid_count
++
]
=
sid
;
}
else
{
HPSB_NOTICE
(
"Spurious SelfID packet (0x%08x) received from bus %d"
,
sid
,
(
host
->
node_id
&
BUS_MASK
)
>>
6
);
sid
,
NODEID_TO_BUS
(
host
->
node_id
)
);
}
}
...
...
@@ -396,9 +396,6 @@ void hpsb_selfid_complete(struct hpsb_host *host, int phyid, int isroot)
/* irm_id is kept up to date by check_selfids() */
if
(
host
->
irm_id
==
host
->
node_id
)
{
host
->
is_irm
=
1
;
host
->
is_busmgr
=
1
;
host
->
busmgr_id
=
host
->
node_id
;
host
->
csr
.
bus_manager_id
=
host
->
node_id
;
}
else
{
host
->
is_busmgr
=
0
;
host
->
is_irm
=
0
;
...
...
@@ -535,8 +532,8 @@ int hpsb_send_packet(struct hpsb_packet *packet)
if
(
packet
->
type
==
hpsb_async
&&
packet
->
node_id
!=
ALL_NODES
)
{
packet
->
speed_code
=
host
->
speed_map
[
(
host
->
node_id
&
NODE_MASK
)
*
64
+
(
packet
->
node_id
&
NODE_MASK
)];
host
->
speed_map
[
NODEID_TO_NODE
(
host
->
node_id
)
*
64
+
NODEID_TO_NODE
(
packet
->
node_id
)];
}
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
...
...
@@ -748,7 +745,7 @@ static void handle_incoming_packet(struct hpsb_host *host, int tcode,
addr
,
4
,
flags
);
if
(
!
write_acked
&&
(
((
data
[
0
]
>>
16
)
&
NODE_MASK
)
!=
NODE_MASK
)
&&
(
NODEID_TO_NODE
(
data
[
0
]
>>
16
)
!=
NODE_MASK
)
&&
(
rcode
>=
0
))
{
/* not a broadcast write, reply */
PREP_REPLY_PACKET
(
0
);
...
...
@@ -763,7 +760,7 @@ static void handle_incoming_packet(struct hpsb_host *host, int tcode,
addr
,
data
[
3
]
>>
16
,
flags
);
if
(
!
write_acked
&&
(
((
data
[
0
]
>>
16
)
&
NODE_MASK
)
!=
NODE_MASK
)
&&
(
NODEID_TO_NODE
(
data
[
0
]
>>
16
)
!=
NODE_MASK
)
&&
(
rcode
>=
0
))
{
/* not a broadcast write, reply */
PREP_REPLY_PACKET
(
0
);
...
...
@@ -1248,6 +1245,7 @@ EXPORT_SYMBOL(hpsb_read);
EXPORT_SYMBOL
(
hpsb_write
);
EXPORT_SYMBOL
(
hpsb_lock
);
EXPORT_SYMBOL
(
hpsb_lock64
);
EXPORT_SYMBOL
(
hpsb_send_gasp
);
EXPORT_SYMBOL
(
hpsb_packet_success
);
/** highlevel.c **/
...
...
drivers/ieee1394/ieee1394_transactions.c
View file @
b3f00969
...
...
@@ -98,6 +98,17 @@ static void fill_phy_packet(struct hpsb_packet *packet, quadlet_t data)
packet
->
speed_code
=
SPEED_100
;
/* Force speed to be 100Mbps */
}
static
void
fill_async_stream_packet
(
struct
hpsb_packet
*
packet
,
int
length
,
int
channel
,
int
tag
,
int
sync
)
{
packet
->
header
[
0
]
=
(
length
<<
16
)
|
(
tag
<<
14
)
|
(
channel
<<
8
)
|
(
TCODE_STREAM_DATA
<<
4
)
|
sync
;
packet
->
header_size
=
4
;
packet
->
data_size
=
length
;
packet
->
type
=
hpsb_async
;
packet
->
tcode
=
TCODE_ISO_DATA
;
}
/**
* hpsb_get_tlabel - allocate a transaction label
...
...
@@ -495,7 +506,6 @@ int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation,
}
/* We need a hpsb_lock64 function for the 64 bit equivalent. Probably. */
int
hpsb_lock
(
struct
hpsb_host
*
host
,
nodeid_t
node
,
unsigned
int
generation
,
u64
addr
,
int
extcode
,
quadlet_t
*
data
,
quadlet_t
arg
)
{
...
...
@@ -558,3 +568,58 @@ int hpsb_lock64(struct hpsb_host *host, nodeid_t node, unsigned int generation,
return
retval
;
}
int
hpsb_send_gasp
(
struct
hpsb_host
*
host
,
int
channel
,
unsigned
int
generation
,
quadlet_t
*
buffer
,
size_t
length
,
u32
specifier_id
,
unsigned
int
version
)
{
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
int
i
;
#endif
struct
hpsb_packet
*
packet
;
int
retval
=
0
;
u16
specifier_id_hi
=
(
specifier_id
&
0x00ffff00
)
>>
8
;
u8
specifier_id_lo
=
specifier_id
&
0xff
;
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
HPSB_DEBUG
(
"Send GASP: channel = %d, length = %d"
,
channel
,
length
);
#endif
length
+=
8
;
packet
=
alloc_hpsb_packet
(
length
+
(
length
%
4
?
4
-
(
length
%
4
)
:
0
));
if
(
!
packet
)
return
-
ENOMEM
;
if
(
length
%
4
)
{
packet
->
data
[
length
/
4
]
=
0
;
}
packet
->
host
=
host
;
fill_async_stream_packet
(
packet
,
length
,
channel
,
3
,
0
);
packet
->
data
[
0
]
=
cpu_to_be32
((
host
->
node_id
<<
16
)
|
specifier_id_hi
);
packet
->
data
[
1
]
=
cpu_to_be32
((
specifier_id_lo
<<
24
)
|
(
version
&
0x00ffffff
));
memcpy
(
&
(
packet
->
data
[
2
]),
buffer
,
length
-
4
);
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
HPSB_DEBUG
(
"GASP: packet->header_size = %d"
,
packet
->
header_size
);
HPSB_DEBUG
(
"GASP: packet->data_size = %d"
,
packet
->
data_size
);
for
(
i
=
0
;
i
<
(
packet
->
data_size
/
4
);
i
++
)
HPSB_DEBUG
(
"GASP: data[%d]: 0x%08x"
,
i
*
4
,
be32_to_cpu
(
packet
->
data
[
i
]));
#endif
packet
->
generation
=
generation
;
packet
->
no_waiter
=
1
;
if
(
!
hpsb_send_packet
(
packet
))
{
free_hpsb_packet
(
packet
);
retval
=
-
EINVAL
;
}
return
retval
;
}
drivers/ieee1394/ieee1394_transactions.h
View file @
b3f00969
...
...
@@ -55,5 +55,8 @@ int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation,
u64
addr
,
int
extcode
,
quadlet_t
*
data
,
quadlet_t
arg
);
int
hpsb_lock64
(
struct
hpsb_host
*
host
,
nodeid_t
node
,
unsigned
int
generation
,
u64
addr
,
int
extcode
,
octlet_t
*
data
,
octlet_t
arg
);
int
hpsb_send_gasp
(
struct
hpsb_host
*
host
,
int
channel
,
unsigned
int
generation
,
quadlet_t
*
buffer
,
size_t
length
,
u32
specifier_id
,
unsigned
int
version
);
#endif
/* _IEEE1394_TRANSACTIONS_H */
drivers/ieee1394/ieee1394_types.h
View file @
b3f00969
...
...
@@ -97,14 +97,17 @@ typedef u64 nodeaddr_t;
typedef
u16
arm_length_t
;
#define BUS_MASK 0xffc0
#define BUS_SHIFT 6
#define NODE_MASK 0x003f
#define LOCAL_BUS 0xffc0
#define ALL_NODES 0x003f
#define NODEID_TO_BUS(nodeid) ((nodeid & BUS_MASK) >> BUS_SHIFT)
#define NODEID_TO_NODE(nodeid) (nodeid & NODE_MASK)
/* Can be used to consistently print a node/bus ID. */
#define NODE_BUS_FMT "%02d:%04d"
#define NODE_BUS_ARGS(nodeid) \
(nodeid & NODE_MASK), ((nodeid & BUS_MASK) >> 6)
#define NODE_BUS_ARGS(nodeid) NODEID_TO_NODE(nodeid), NODEID_TO_BUS(nodeid)
#define HPSB_PRINT(level, fmt, args...) printk(level "ieee1394: " fmt "\n" , ## args)
...
...
drivers/ieee1394/nodemgr.c
View file @
b3f00969
...
...
@@ -1210,6 +1210,52 @@ static void nodemgr_node_probe(struct hpsb_host *host)
return
;
}
/* Because we are a 1394a-2000 compliant IRM, we need to inform all the other
* nodes of the broadcast channel. (Really we're only setting the validity
* bit). */
static
void
nodemgr_do_irm_duties
(
struct
hpsb_host
*
host
)
{
quadlet_t
bc
;
if
(
!
host
->
is_irm
)
return
;
host
->
csr
.
broadcast_channel
|=
0x40000000
;
/* set validity bit */
bc
=
cpu_to_be32
(
host
->
csr
.
broadcast_channel
);
hpsb_write
(
host
,
LOCAL_BUS
|
ALL_NODES
,
get_hpsb_generation
(
host
),
(
CSR_REGISTER_BASE
|
CSR_BROADCAST_CHANNEL
),
&
bc
,
sizeof
(
quadlet_t
));
}
/* We need to ensure that if we are not the IRM, that the IRM node is capable of
* everything we can do, otherwise issue a bus reset and try to become the IRM
* ourselves. */
static
int
nodemgr_check_root_capability
(
struct
hpsb_host
*
host
)
{
quadlet_t
bc
;
int
status
;
if
(
host
->
is_irm
)
return
1
;
status
=
hpsb_read
(
host
,
LOCAL_BUS
|
(
host
->
irm_id
),
get_hpsb_generation
(
host
),
(
CSR_REGISTER_BASE
|
CSR_BROADCAST_CHANNEL
),
&
bc
,
sizeof
(
quadlet_t
));
if
(
status
<
0
||
!
(
be32_to_cpu
(
bc
)
&
0x80000000
))
{
/* The root node does not have a valid BROADCAST_CHANNEL
* register and we do, so reset the bus with force_root set */
HPSB_INFO
(
"Remote root is not IRM capable, resetting..."
);
hpsb_reset_bus
(
host
,
LONG_RESET_FORCE_ROOT
);
return
0
;
}
return
1
;
}
static
int
nodemgr_host_thread
(
void
*
__hi
)
{
struct
host_info
*
hi
=
(
struct
host_info
*
)
__hi
;
...
...
@@ -1222,7 +1268,16 @@ static int nodemgr_host_thread(void *__hi)
* happens when we get a bus reset. */
while
(
!
down_interruptible
(
&
hi
->
reset_sem
)
&&
!
down_interruptible
(
&
nodemgr_serialize
))
{
if
(
!
nodemgr_check_root_capability
(
hi
->
host
))
{
/* Do nothing, we are resetting */
up
(
&
nodemgr_serialize
);
continue
;
}
nodemgr_node_probe
(
hi
->
host
);
nodemgr_do_irm_duties
(
hi
->
host
);
up
(
&
nodemgr_serialize
);
}
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
...
...
drivers/ieee1394/ohci1394.c
View file @
b3f00969
...
...
@@ -31,9 +31,9 @@
*
* Things implemented, but still in test phase:
* . Iso Transmit
* . Async Stream Packets Transmit (Receive done via Iso interface)
*
* Things not implemented:
* . Async Stream Packets
* . DMA error recovery
*
* Known bugs:
...
...
@@ -160,7 +160,7 @@ printk(level "%s: " fmt "\n" , OHCI1394_DRIVER_NAME , ## args)
printk(level "%s_%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args)
static
char
version
[]
__devinitdata
=
"$Rev:
762
$ Ben Collins <bcollins@debian.org>"
;
"$Rev:
801
$ Ben Collins <bcollins@debian.org>"
;
/* Module Parameters */
MODULE_PARM
(
phys_dma
,
"i"
);
...
...
@@ -649,18 +649,31 @@ static void insert_packet(struct ti_ohci *ohci,
}
else
{
d
->
prg_cpu
[
idx
]
->
data
[
0
]
=
packet
->
speed_code
<<
16
|
(
packet
->
header
[
0
]
&
0xFFFF
);
if
(
packet
->
tcode
==
TCODE_ISO_DATA
)
{
/* Sending an async stream packet */
d
->
prg_cpu
[
idx
]
->
data
[
1
]
=
packet
->
header
[
0
]
&
0xFFFF0000
;
}
else
{
/* Sending a normal async request or response */
d
->
prg_cpu
[
idx
]
->
data
[
1
]
=
(
packet
->
header
[
1
]
&
0xFFFF
)
|
(
packet
->
header
[
0
]
&
0xFFFF0000
);
d
->
prg_cpu
[
idx
]
->
data
[
2
]
=
packet
->
header
[
2
];
d
->
prg_cpu
[
idx
]
->
data
[
3
]
=
packet
->
header
[
3
];
}
packet_swab
(
d
->
prg_cpu
[
idx
]
->
data
,
packet
->
tcode
);
}
if
(
packet
->
data_size
)
{
/* block transmit */
if
(
packet
->
tcode
==
TCODE_STREAM_DATA
){
d
->
prg_cpu
[
idx
]
->
begin
.
control
=
cpu_to_le32
(
DMA_CTL_OUTPUT_MORE
|
DMA_CTL_IMMEDIATE
|
0x8
);
}
else
{
d
->
prg_cpu
[
idx
]
->
begin
.
control
=
cpu_to_le32
(
DMA_CTL_OUTPUT_MORE
|
DMA_CTL_IMMEDIATE
|
0x10
);
}
d
->
prg_cpu
[
idx
]
->
end
.
control
=
cpu_to_le32
(
DMA_CTL_OUTPUT_LAST
|
DMA_CTL_IRQ
|
...
...
@@ -830,7 +843,7 @@ static int ohci_transmit(struct hpsb_host *host, struct hpsb_packet *packet)
/* Decide whether we have an iso, a request, or a response packet */
if
(
packet
->
type
==
hpsb_raw
)
d
=
&
ohci
->
at_req_context
;
else
if
(
packet
->
tcode
==
TCODE_ISO_DATA
)
{
else
if
(
(
packet
->
tcode
==
TCODE_ISO_DATA
)
&&
(
packet
->
type
==
hpsb_iso
)
)
{
/* The legacy IT DMA context is initialized on first
* use. However, the alloc cannot be run from
* interrupt context, so we bail out if that is the
...
...
@@ -856,7 +869,7 @@ static int ohci_transmit(struct hpsb_host *host, struct hpsb_packet *packet)
}
d
=
&
ohci
->
it_legacy_context
;
}
else
if
(
packet
->
tcode
&
0x02
)
}
else
if
(
(
packet
->
tcode
&
0x02
)
&&
(
packet
->
tcode
!=
TCODE_ISO_DATA
)
)
d
=
&
ohci
->
at_resp_context
;
else
d
=
&
ohci
->
at_req_context
;
...
...
@@ -1295,6 +1308,8 @@ static void ohci_iso_recv_program(struct hpsb_iso *iso)
u32
*
prev_branch
=
NULL
;
for
(
blk
=
0
;
blk
<
recv
->
nblocks
;
blk
++
)
{
u32
control
;
/* the DMA descriptor */
struct
dma_cmd
*
cmd
=
&
recv
->
block
[
blk
];
...
...
@@ -1305,29 +1320,29 @@ static void ohci_iso_recv_program(struct hpsb_iso *iso)
unsigned
long
buf_offset
=
blk
*
recv
->
buf_stride
;
if
(
recv
->
dma_mode
==
BUFFER_FILL_MODE
)
{
c
md
->
c
ontrol
=
2
<<
28
;
/* INPUT_MORE */
control
=
2
<<
28
;
/* INPUT_MORE */
}
else
{
c
md
->
c
ontrol
=
3
<<
28
;
/* INPUT_LAST */
control
=
3
<<
28
;
/* INPUT_LAST */
}
c
md
->
c
ontrol
|=
8
<<
24
;
/* s = 1, update xferStatus and resCount */
control
|=
8
<<
24
;
/* s = 1, update xferStatus and resCount */
/* interrupt on last block, and at intervals */
if
(
blk
==
recv
->
nblocks
-
1
||
(
blk
%
recv
->
block_irq_interval
)
==
0
)
{
c
md
->
c
ontrol
|=
3
<<
20
;
/* want interrupt */
control
|=
3
<<
20
;
/* want interrupt */
}
c
md
->
c
ontrol
|=
3
<<
18
;
/* enable branch to address */
c
md
->
c
ontrol
|=
recv
->
buf_stride
;
control
|=
3
<<
18
;
/* enable branch to address */
control
|=
recv
->
buf_stride
;
cmd
->
address
=
dma_region_offset_to_bus
(
&
iso
->
data_buf
,
buf_offset
);
cmd
->
control
=
cpu_to_le32
(
control
);
cmd
->
address
=
cpu_to_le32
(
dma_region_offset_to_bus
(
&
iso
->
data_buf
,
buf_offset
));
cmd
->
branchAddress
=
0
;
/* filled in on next loop */
cmd
->
status
=
recv
->
buf_stride
;
cmd
->
status
=
cpu_to_le32
(
recv
->
buf_stride
)
;
/* link the previous descriptor to this one */
if
(
prev_branch
)
{
*
prev_branch
=
dma_prog_region_offset_to_bus
(
&
recv
->
prog
,
prog_offset
);
*
prev_branch
|=
1
;
/* set Z=1 */
*
prev_branch
=
cpu_to_le32
(
dma_prog_region_offset_to_bus
(
&
recv
->
prog
,
prog_offset
)
|
1
);
}
prev_branch
=
&
cmd
->
branchAddress
;
...
...
@@ -1485,18 +1500,18 @@ static void ohci_iso_recv_release_block(struct ohci_iso_recv *recv, int block)
/* 'next' becomes the new end of the DMA chain,
so disable branch and enable interrupt */
next
->
branchAddress
=
0
;
next
->
control
|=
3
<<
20
;
next
->
control
|=
cpu_to_le32
(
3
<<
20
)
;
/* link prev to next */
prev
->
branchAddress
=
dma_prog_region_offset_to_bus
(
&
recv
->
prog
,
prev
->
branchAddress
=
cpu_to_le32
(
dma_prog_region_offset_to_bus
(
&
recv
->
prog
,
sizeof
(
struct
dma_cmd
)
*
next_i
)
|
1
;
/* Z=1 */
|
1
)
;
/* Z=1 */
/* disable interrupt on previous DMA descriptor, except at intervals */
if
((
prev_i
%
recv
->
block_irq_interval
)
==
0
)
{
prev
->
control
|=
3
<<
20
;
/* enable interrupt */
prev
->
control
|=
cpu_to_le32
(
3
<<
20
)
;
/* enable interrupt */
}
else
{
prev
->
control
&=
~
(
3
<<
20
);
/* disable interrupt */
prev
->
control
&=
cpu_to_le32
(
~
(
3
<<
20
)
);
/* disable interrupt */
}
wmb
();
...
...
@@ -1720,8 +1735,8 @@ static void ohci_iso_recv_packetperbuf_task(unsigned long data)
struct
dma_cmd
*
il
=
((
struct
dma_cmd
*
)
recv
->
prog
.
kvirt
)
+
iso
->
pkt_dma
;
/* check the DMA descriptor for new writes to xferStatus */
u16
xferstatus
=
il
->
status
>>
16
;
u16
rescount
=
il
->
status
&
0xFFFF
;
u16
xferstatus
=
le32_to_cpu
(
il
->
status
)
>>
16
;
u16
rescount
=
le32_to_cpu
(
il
->
status
)
&
0xFFFF
;
unsigned
char
event
=
xferstatus
&
0x1F
;
...
...
@@ -1903,7 +1918,7 @@ static void ohci_iso_xmit_task(unsigned long data)
struct
iso_xmit_cmd
*
cmd
=
dma_region_i
(
&
xmit
->
prog
,
struct
iso_xmit_cmd
,
iso
->
pkt_dma
);
/* check for new writes to xferStatus */
u16
xferstatus
=
cmd
->
output_last
.
status
>>
16
;
u16
xferstatus
=
le32_to_cpu
(
cmd
->
output_last
.
status
)
>>
16
;
u8
event
=
xferstatus
&
0x1F
;
if
(
!
event
)
{
...
...
@@ -1919,7 +1934,7 @@ static void ohci_iso_xmit_task(unsigned long data)
wake
=
1
;
/* parse cycle */
cycle
=
cmd
->
output_last
.
status
&
0x1FFF
;
cycle
=
le32_to_cpu
(
cmd
->
output_last
.
status
)
&
0x1FFF
;
/* tell the subsystem the packet has gone out */
hpsb_iso_packet_sent
(
iso
,
cycle
,
event
!=
0x11
);
...
...
@@ -1972,7 +1987,7 @@ static int ohci_iso_xmit_queue(struct hpsb_iso *iso, struct hpsb_iso_packet_info
/* set up the OUTPUT_MORE_IMMEDIATE descriptor */
memset
(
next
,
0
,
sizeof
(
struct
iso_xmit_cmd
));
next
->
output_more_immediate
.
control
=
0x02000008
;
next
->
output_more_immediate
.
control
=
cpu_to_le32
(
0x02000008
)
;
/* ISO packet header is embedded in the OUTPUT_MORE_IMMEDIATE */
...
...
@@ -1990,28 +2005,28 @@ static int ohci_iso_xmit_queue(struct hpsb_iso *iso, struct hpsb_iso_packet_info
next
->
iso_hdr
[
7
]
=
len
>>
8
;
/* set up the OUTPUT_LAST */
next
->
output_last
.
control
=
1
<<
28
;
next
->
output_last
.
control
|=
1
<<
27
;
/* update timeStamp */
next
->
output_last
.
control
|=
3
<<
20
;
/* want interrupt */
next
->
output_last
.
control
|=
3
<<
18
;
/* enable branch */
next
->
output_last
.
control
|=
len
;
next
->
output_last
.
control
=
cpu_to_le32
(
1
<<
28
)
;
next
->
output_last
.
control
|=
cpu_to_le32
(
1
<<
27
)
;
/* update timeStamp */
next
->
output_last
.
control
|=
cpu_to_le32
(
3
<<
20
)
;
/* want interrupt */
next
->
output_last
.
control
|=
cpu_to_le32
(
3
<<
18
)
;
/* enable branch */
next
->
output_last
.
control
|=
cpu_to_le32
(
len
)
;
/* payload bus address */
next
->
output_last
.
address
=
dma_region_offset_to_bus
(
&
iso
->
data_buf
,
offset
);
next
->
output_last
.
address
=
cpu_to_le32
(
dma_region_offset_to_bus
(
&
iso
->
data_buf
,
offset
)
);
/* leave branchAddress at zero for now */
/* re-write the previous DMA descriptor to chain to this one */
/* set prev branch address to point to next (Z=3) */
prev
->
output_last
.
branchAddress
=
dma_prog_region_offset_to_bus
(
&
xmit
->
prog
,
sizeof
(
struct
iso_xmit_cmd
)
*
next_i
)
|
3
;
prev
->
output_last
.
branchAddress
=
cpu_to_le32
(
dma_prog_region_offset_to_bus
(
&
xmit
->
prog
,
sizeof
(
struct
iso_xmit_cmd
)
*
next_i
)
|
3
)
;
/* disable interrupt, unless required by the IRQ interval */
if
(
prev_i
%
iso
->
irq_interval
)
{
prev
->
output_last
.
control
&=
~
(
3
<<
20
);
/* no interrupt */
prev
->
output_last
.
control
&=
cpu_to_le32
(
~
(
3
<<
20
)
);
/* no interrupt */
}
else
{
prev
->
output_last
.
control
|=
3
<<
20
;
/* enable interrupt */
prev
->
output_last
.
control
|=
cpu_to_le32
(
3
<<
20
)
;
/* enable interrupt */
}
wmb
();
...
...
@@ -3474,7 +3489,7 @@ static void ohci1394_pci_remove(struct pci_dev *pdev)
static
struct
pci_device_id
ohci1394_pci_tbl
[]
__devinitdata
=
{
{
.
class
=
PCI_CLASS_FIREWIRE_OHCI
,
.
class_mask
=
0x00ffffff
,
.
class_mask
=
~
0
,
.
vendor
=
PCI_ANY_ID
,
.
device
=
PCI_ANY_ID
,
.
subvendor
=
PCI_ANY_ID
,
...
...
drivers/ieee1394/raw1394.c
View file @
b3f00969
...
...
@@ -238,7 +238,7 @@ static void remove_host(struct hpsb_host *host)
list_del
(
&
hi
->
list
);
host_count
--
;
/*
FIXME: addressranges should be removed
FIXME: address
ranges should be removed
and fileinfo states should be initialized
(including setting generation to
internal-generation ...)
...
...
@@ -281,8 +281,8 @@ static void host_reset(struct hpsb_host *host)
req
->
req
.
misc
=
(
host
->
node_id
<<
16
)
|
host
->
node_count
;
if
(
fi
->
protocol_version
>
3
)
{
req
->
req
.
misc
|=
(
(
host
->
irm_id
&
NODE_MASK
)
<<
8
);
req
->
req
.
misc
|=
(
NODEID_TO_NODE
(
host
->
irm_id
)
<<
8
);
}
queue_complete_req
(
req
);
...
...
@@ -571,8 +571,7 @@ static int state_initialized(struct file_info *fi, struct pending_request *req)
req
->
req
.
misc
=
(
fi
->
host
->
node_id
<<
16
)
|
fi
->
host
->
node_count
;
if
(
fi
->
protocol_version
>
3
)
{
req
->
req
.
misc
|=
(
fi
->
host
->
irm_id
&
NODE_MASK
)
<<
8
;
req
->
req
.
misc
|=
NODEID_TO_NODE
(
fi
->
host
->
irm_id
)
<<
8
;
}
}
else
{
req
->
req
.
error
=
RAW1394_ERROR_INVALID_ARG
;
...
...
drivers/ieee1394/sbp2.c
View file @
b3f00969
...
...
@@ -27,30 +27,6 @@
* driver. It also registers as a SCSI lower-level driver in order to accept
* SCSI commands for transport using SBP-2.
*
*
* Driver Loading:
*
* Currently, the SBP-2 driver is supported only as a module. Because the
* Linux SCSI stack is not Plug-N-Play aware, module load order is
* important. Assuming the SCSI core drivers are either built into the
* kernel or already loaded as modules, you should load the IEEE-1394 modules
* in the following order:
*
* ieee1394 (e.g. insmod ieee1394)
* ohci1394 (e.g. insmod ohci1394)
* sbp2 (e.g. insmod sbp2)
*
* The SBP-2 driver will attempt to discover any attached SBP-2 devices when first
* loaded, or after any IEEE-1394 bus reset (e.g. a hot-plug). It will then print
* out a debug message indicating if it was able to discover a SBP-2 device.
*
* Currently, the SBP-2 driver will catch any attached SBP-2 devices during the
* initial scsi bus scan (when the driver is first loaded). To add or remove
* SBP-2 devices "after" this initial scan (i.e. if you plug-in or un-plug a
* device after the SBP-2 driver is loaded), you must either use the scsi procfs
* add-single-device, remove-single-device, or a shell script such as
* rescan-scsi-bus.sh.
*
* The easiest way to add/detect new SBP-2 devices is to run the shell script
* rescan-scsi-bus.sh (or re-load the SBP-2 driver). This script may be
* found at:
...
...
@@ -136,14 +112,6 @@
* - Error Handling: SCSI aborts and bus reset requests are handled somewhat
* but the code needs additional debugging.
*
* - Module: The SBP-2 driver is currently only supported as a module. It would not take
* much work to allow it to be compiled into the kernel, but you'd have to
* add some init code to the kernel to support this... and modules are much
* more flexible anyway. ;-)
*
* - Hot-plugging: Interaction with the SCSI stack and support for hot-plugging could
* stand some improvement.
*
*
* History:
*
...
...
@@ -295,10 +263,11 @@
* 04/23/02 - Fix for Sony CD-ROM drives. Only send fetch agent reset to sbp2 device if it
* returns the dead bit in status. Thanks to Chandan (chandan@toad.net) for this one.
* 04/27/02 - Fix sbp2 login problem on SMP systems, enable real spinlocks by default. (JSG)
* 06/09/02 - Don't force 36-b
u
te SCSI inquiry, but leave in a define for badly behaved devices. (JSG)
* 06/09/02 - Don't force 36-b
y
te SCSI inquiry, but leave in a define for badly behaved devices. (JSG)
* 02/04/03 - Fixed a SMP deadlock (don't hold sbp2_command_lock while calling sbp2scsi_complete_command).
* Also save/restore irq flags in sbp2scsi_complete_command - Sancho Dauskardt <sda@bdit.de>
* 02/06/03 - Removed spinlock debugging; use kernel stuff instead (sda)
* 02/10/03 - Adopt to new hot-plug aware SCSI inferface (hch@lst.de)
*
*/
...
...
@@ -350,7 +319,7 @@
#include "sbp2.h"
static
char
version
[]
__devinitdata
=
"$Rev: 7
79
$ James Goodwin <jamesg@filanet.com>"
;
"$Rev: 7
97
$ James Goodwin <jamesg@filanet.com>"
;
/*
* Module load parameter definitions
...
...
@@ -497,6 +466,15 @@ static u32 global_outstanding_dmas = 0;
* Globals
*/
static
void
sbp2scsi_complete_all_commands
(
struct
sbp2scsi_host_info
*
hi
,
struct
scsi_id_instance_data
*
scsi_id
,
u32
status
);
static
void
sbp2scsi_complete_command
(
struct
sbp2scsi_host_info
*
hi
,
struct
scsi_id_instance_data
*
scsi_id
,
u32
scsi_status
,
Scsi_Cmnd
*
SCpnt
,
void
(
*
done
)(
Scsi_Cmnd
*
));
static
Scsi_Host_Template
scsi_driver_template
;
static
u8
sbp2_speedto_maxrec
[]
=
{
0x7
,
0x8
,
0x9
};
...
...
@@ -822,7 +800,7 @@ static void sbp2util_free_command_dma(struct sbp2_command_info *command)
{
struct
sbp2scsi_host_info
*
hi
;
hi
=
(
struct
sbp2scsi_host_info
*
)
command
->
Current_SCpnt
->
device
->
host
->
hostdata
[
0
]
;
hi
=
(
struct
sbp2scsi_host_info
*
)
&
command
->
Current_SCpnt
->
device
->
host
->
hostdata
;
if
(
hi
==
NULL
)
{
printk
(
KERN_ERR
"%s: hi == NULL
\n
"
,
__FUNCTION__
);
...
...
@@ -871,59 +849,6 @@ static void sbp2util_mark_command_completed(struct scsi_id_instance_data *scsi_i
* IEEE-1394 core driver stack related section
*********************************************/
/*
* This function is called at SCSI init in order to register our driver
* with the IEEE-1394 stack.
*/
int
sbp2_init
(
void
)
{
SBP2_DEBUG
(
"sbp2_init"
);
/*
* Register our high level driver with 1394 stack
*/
sbp2_hl_handle
=
hpsb_register_highlevel
(
SBP2_DEVICE_NAME
,
&
sbp2_hl_ops
);
if
(
sbp2_hl_handle
==
NULL
)
{
SBP2_ERR
(
"sbp2 failed to register with ieee1394 highlevel"
);
return
(
-
ENOMEM
);
}
/*
* Register our sbp2 status address space...
*/
hpsb_register_addrspace
(
sbp2_hl_handle
,
&
sbp2_ops
,
SBP2_STATUS_FIFO_ADDRESS
,
SBP2_STATUS_FIFO_ADDRESS
+
SBP2_STATUS_FIFO_ENTRY_TO_OFFSET
(
SBP2SCSI_MAX_SCSI_IDS
+
1
));
/*
* Handle data movement if physical dma is not enabled/supported on host controller
*/
#ifdef CONFIG_IEEE1394_SBP2_PHYS_DMA
hpsb_register_addrspace
(
sbp2_hl_handle
,
&
sbp2_physdma_ops
,
0x0ULL
,
0xfffffffcULL
);
#endif
hpsb_register_protocol
(
&
sbp2_driver
);
return
0
;
}
/*
* This function is called from cleanup module, or during shut-down, in
* order to unregister our driver.
*/
void
sbp2_cleanup
(
void
)
{
SBP2_DEBUG
(
"sbp2_cleanup"
);
hpsb_unregister_protocol
(
&
sbp2_driver
);
if
(
sbp2_hl_handle
)
{
hpsb_unregister_highlevel
(
sbp2_hl_handle
);
sbp2_hl_handle
=
NULL
;
}
}
static
int
sbp2_probe
(
struct
unit_directory
*
ud
)
{
struct
sbp2scsi_host_info
*
hi
;
...
...
@@ -999,35 +924,44 @@ static void sbp2_add_host(struct hpsb_host *host)
{
struct
sbp2scsi_host_info
*
hi
;
unsigned
long
flags
;
struct
Scsi_Host
*
scsi_host
;
SBP2_DEBUG
(
"sbp2_add_host"
);
/* Allocate some memory for our host info structure */
hi
=
(
struct
sbp2scsi_host_info
*
)
kmalloc
(
sizeof
(
struct
sbp2scsi_host_info
),
in_interrupt
()
?
SLAB_ATOMIC
:
SLAB_KERNEL
);
if
(
hi
==
NULL
)
{
SBP2_ERR
(
"out of memory in sbp2_add_host"
);
/* Register our host with the SCSI stack. */
scsi_host
=
scsi_register
(
&
scsi_driver_template
,
sizeof
(
struct
sbp2scsi_host_info
));
if
(
!
scsi_host
)
{
SBP2_ERR
(
"failed to register scsi host"
);
return
;
}
/* Initialize some host stuff */
hi
=
(
struct
sbp2scsi_host_info
*
)
&
scsi_host
->
hostdata
;
memset
(
hi
,
0
,
sizeof
(
struct
sbp2scsi_host_info
));
hi
->
scsi_host
=
scsi_host
;
INIT_LIST_HEAD
(
&
hi
->
list
);
hi
->
host
=
host
;
hi
->
sbp2_command_lock
=
SPIN_LOCK_UNLOCKED
;
hi
->
scsi_host
->
max_id
=
SBP2SCSI_MAX_SCSI_IDS
;
spin_lock_irqsave
(
&
sbp2_host_info_lock
,
flags
);
list_add_tail
(
&
hi
->
list
,
&
sbp2_host_info_list
);
spin_unlock_irqrestore
(
&
sbp2_host_info_lock
,
flags
);
/* Register our host with the SCSI stack. */
hi
->
scsi_host
=
scsi_register
(
&
scsi_driver_template
,
sizeof
(
void
*
));
if
(
hi
->
scsi_host
)
{
hi
->
scsi_host
->
hostdata
[
0
]
=
(
unsigned
long
)
hi
;
hi
->
scsi_host
->
max_id
=
SBP2SCSI_MAX_SCSI_IDS
;
/*
* XXX(hch): Hopefully the ieee1394 code will be converted
* to the driver model at some point. Until that happens
* we'll have to pass in NULL here.
*/
if
(
scsi_add_host
(
hi
->
scsi_host
,
NULL
))
{
SBP2_ERR
(
"failed to add scsi host"
);
spin_lock_irqsave
(
&
sbp2_host_info_lock
,
flags
);
list_del
(
&
hi
->
list
);
spin_unlock_irqrestore
(
&
sbp2_host_info_lock
,
flags
);
scsi_unregister
(
hi
->
scsi_host
);
}
scsi_driver_template
.
present
++
;
return
;
}
...
...
@@ -1079,16 +1013,15 @@ static void sbp2_remove_host(struct hpsb_host *host)
SBP2_DEBUG
(
"sbp2_remove_host"
);
spin_lock_irqsave
(
&
sbp2_host_info_lock
,
flags
);
hi
=
sbp2_find_host_info
(
host
);
if
(
hi
!=
NULL
)
{
if
(
hi
)
list_del
(
&
hi
->
list
);
kfree
(
hi
);
}
else
SBP2_ERR
(
"attempt to remove unknown host %p"
,
host
);
spin_unlock_irqrestore
(
&
sbp2_host_info_lock
,
flags
);
if
(
hi
)
{
scsi_remove_host
(
hi
->
scsi_host
);
scsi_unregister
(
hi
->
scsi_host
);
}
}
/*
...
...
@@ -1098,6 +1031,7 @@ static void sbp2_remove_host(struct hpsb_host *host)
static
int
sbp2_start_device
(
struct
sbp2scsi_host_info
*
hi
,
struct
unit_directory
*
ud
)
{
struct
scsi_id_instance_data
*
scsi_id
=
NULL
;
struct
scsi_device
*
sdev
;
struct
node_entry
*
ne
;
int
i
;
...
...
@@ -1203,7 +1137,7 @@ static int sbp2_start_device(struct sbp2scsi_host_info *hi, struct unit_director
/*
* Find an empty spot to stick our scsi id instance data.
*/
for
(
i
=
0
;
i
<
SBP2SCSI_MAX_SCSI_IDS
;
i
++
)
{
for
(
i
=
0
;
i
<
hi
->
scsi_host
->
max_id
;
i
++
)
{
if
(
!
hi
->
scsi_id
[
i
])
{
hi
->
scsi_id
[
i
]
=
scsi_id
;
scsi_id
->
id
=
i
;
...
...
@@ -1224,7 +1158,7 @@ static int sbp2_start_device(struct sbp2scsi_host_info *hi, struct unit_director
/*
* Make sure we are not out of space
*/
if
(
i
==
SBP2SCSI_MAX_SCSI_IDS
)
{
if
(
i
==
hi
->
scsi_host
->
max_id
)
{
SBP2_ERR
(
"No slots left for SBP-2 device"
);
sbp2_remove_device
(
hi
,
scsi_id
);
return
-
EBUSY
;
...
...
@@ -1256,6 +1190,13 @@ static int sbp2_start_device(struct sbp2scsi_host_info *hi, struct unit_director
*/
sbp2_max_speed_and_size
(
hi
,
scsi_id
);
/* Add this device to the scsi layer now */
sdev
=
scsi_add_device
(
hi
->
scsi_host
,
0
,
scsi_id
->
id
,
0
);
if
(
IS_ERR
(
sdev
))
{
SBP2_ERR
(
"scsi_add_device failed"
);
return
PTR_ERR
(
sdev
);
}
return
0
;
}
...
...
@@ -1265,13 +1206,21 @@ static int sbp2_start_device(struct sbp2scsi_host_info *hi, struct unit_director
static
void
sbp2_remove_device
(
struct
sbp2scsi_host_info
*
hi
,
struct
scsi_id_instance_data
*
scsi_id
)
{
struct
scsi_device
*
sdev
=
scsi_find_device
(
hi
->
scsi_host
,
0
,
scsi_id
->
id
,
0
);
SBP2_DEBUG
(
"sbp2_remove_device"
);
/* Complete any pending commands with selection timeout */
sbp2scsi_complete_all_commands
(
hi
,
scsi_id
,
DID_NO_CONNECT
);
/* Remove it from the scsi layer now */
if
(
scsi_remove_device
(
sdev
))
SBP2_ERR
(
"scsi_remove_device failed"
);
sbp2util_remove_command_orb_pool
(
scsi_id
,
hi
);
hi
->
scsi_id
[
scsi_id
->
id
]
=
NULL
;
if
(
scsi_id
->
login_response
)
{
pci_free_consistent
(
hi
->
host
->
pdev
,
sizeof
(
struct
sbp2_login_response
),
...
...
@@ -1305,7 +1254,7 @@ static void sbp2_remove_device(struct sbp2scsi_host_info *hi,
}
SBP2_DEBUG
(
"SBP-2 device removed, SCSI ID = %d"
,
scsi_id
->
id
);
hi
->
scsi_id
[
scsi_id
->
id
]
=
NULL
;
kfree
(
scsi_id
);
}
...
...
@@ -1793,8 +1742,8 @@ static int sbp2_max_speed_and_size(struct sbp2scsi_host_info *hi, struct scsi_id
SBP2_DEBUG
(
"sbp2_max_speed_and_size"
);
/* Initial setting comes from the hosts speed map */
scsi_id
->
speed_code
=
hi
->
host
->
speed_map
[
(
hi
->
host
->
node_id
&
NODE_MASK
)
*
64
+
(
scsi_id
->
ne
->
nodeid
&
NODE_MASK
)];
scsi_id
->
speed_code
=
hi
->
host
->
speed_map
[
NODEID_TO_NODE
(
hi
->
host
->
node_id
)
*
64
+
NODEID_TO_NODE
(
scsi_id
->
ne
->
nodeid
)];
/* Bump down our speed if the user requested it */
if
(
scsi_id
->
speed_code
>
sbp2_max_speed
)
{
...
...
@@ -2661,7 +2610,7 @@ static int sbp2scsi_queuecommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
/*
* Pull our host info and scsi id instance data from the scsi command
*/
hi
=
(
struct
sbp2scsi_host_info
*
)
SCpnt
->
device
->
host
->
hostdata
[
0
]
;
hi
=
(
struct
sbp2scsi_host_info
*
)
&
SCpnt
->
device
->
host
->
hostdata
;
if
(
!
hi
)
{
SBP2_ERR
(
"sbp2scsi_host_info is NULL - this is bad!"
);
...
...
@@ -2766,8 +2715,10 @@ static void sbp2scsi_complete_all_commands(struct sbp2scsi_host_info *hi,
*
* This can be called in interrupt context.
*/
static
void
sbp2scsi_complete_command
(
struct
sbp2scsi_host_info
*
hi
,
struct
scsi_id_instance_data
*
scsi_id
,
u32
scsi_status
,
Scsi_Cmnd
*
SCpnt
,
void
(
*
done
)(
Scsi_Cmnd
*
))
static
void
sbp2scsi_complete_command
(
struct
sbp2scsi_host_info
*
hi
,
struct
scsi_id_instance_data
*
scsi_id
,
u32
scsi_status
,
Scsi_Cmnd
*
SCpnt
,
void
(
*
done
)(
Scsi_Cmnd
*
))
{
unsigned
long
flags
;
...
...
@@ -2888,7 +2839,7 @@ static void sbp2scsi_complete_command(struct sbp2scsi_host_info *hi, struct scsi
*/
static
int
sbp2scsi_abort
(
Scsi_Cmnd
*
SCpnt
)
{
struct
sbp2scsi_host_info
*
hi
=
(
struct
sbp2scsi_host_info
*
)
SCpnt
->
device
->
host
->
hostdata
[
0
]
;
struct
sbp2scsi_host_info
*
hi
=
(
struct
sbp2scsi_host_info
*
)
&
SCpnt
->
device
->
host
->
hostdata
;
struct
scsi_id_instance_data
*
scsi_id
=
hi
->
scsi_id
[
SCpnt
->
device
->
id
];
struct
sbp2_command_info
*
command
;
unsigned
long
flags
;
...
...
@@ -2938,7 +2889,7 @@ static int sbp2scsi_abort (Scsi_Cmnd *SCpnt)
*/
static
int
sbp2scsi_reset
(
Scsi_Cmnd
*
SCpnt
)
{
struct
sbp2scsi_host_info
*
hi
=
(
struct
sbp2scsi_host_info
*
)
SCpnt
->
device
->
host
->
hostdata
[
0
]
;
struct
sbp2scsi_host_info
*
hi
=
(
struct
sbp2scsi_host_info
*
)
&
SCpnt
->
device
->
host
->
hostdata
;
struct
scsi_id_instance_data
*
scsi_id
=
hi
->
scsi_id
[
SCpnt
->
device
->
id
];
SBP2_ERR
(
"reset requested"
);
...
...
@@ -2951,93 +2902,81 @@ static int sbp2scsi_reset (Scsi_Cmnd *SCpnt)
return
(
SUCCESS
);
}
/*
* Called by scsi stack to get bios parameters (used by fdisk, and at boot).
*/
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,43)
static
int
sbp2scsi_biosparam
(
struct
scsi_device
*
sdev
,
struct
block_device
*
dev
,
sector_t
capacity
,
int
geom
[])
static
const
char
*
sbp2scsi_info
(
struct
Scsi_Host
*
host
)
{
#else
static
int
sbp2scsi_biosparam
(
Scsi_Disk
*
disk
,
kdev_t
dev
,
int
geom
[])
return
"SCSI emulation for for IEEE-1394 Storage Devices"
;
}
/* Called for contents of procfs */
#define SPRINTF(args...) \
do { if (pos < buffer+length) pos += sprintf(pos, ## args); } while (0)
static
int
sbp2scsi_proc_info
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
length
,
int
hostno
,
int
inout
)
{
unsigned
capacity
=
disk
->
capacity
;
#endif
int
heads
,
sectors
,
cylinders
;
Scsi_Device
*
scd
;
struct
Scsi_Host
*
host
;
struct
sbp2scsi_host_info
*
hi
;
char
*
pos
=
buffer
;
SBP2_DEBUG
(
"Request for bios parameters"
);
/* if someone is sending us data, just throw it away */
if
(
inout
)
return
length
;
h
eads
=
64
;
sectors
=
32
;
cylinders
=
(
int
)
capacity
/
(
heads
*
sectors
)
;
h
ost
=
scsi_host_hn_get
(
hostno
)
;
if
(
!
host
)
/* if we couldn't find it, we return an error */
return
-
ESRCH
;
if
(
cylinders
>
1024
)
{
heads
=
255
;
sectors
=
63
;
cylinders
=
(
int
)
capacity
/
(
heads
*
sectors
);
}
hi
=
sbp2_find_host_info_scsi
(
host
);
if
(
!
hi
)
/* shouldn't happen, but... */
return
-
ESRCH
;
geom
[
0
]
=
heads
;
geom
[
1
]
=
sectors
;
geom
[
2
]
=
cylinders
;
SPRINTF
(
"Host scsi%d : SBP-2 IEEE-1394 (%s)
\n
"
,
hostno
,
hi
->
host
->
driver
->
name
)
;
SPRINTF
(
"Driver version : %s
\n
"
,
version
)
;
return
(
0
);
}
SPRINTF
(
"
\n
Module options :
\n
"
);
SPRINTF
(
" sbp2_max_speed : %s
\n
"
,
hpsb_speedto_str
[
sbp2_max_speed
]);
SPRINTF
(
" sbp2_max_sectors : %d
\n
"
,
sbp2_max_sectors
);
SPRINTF
(
" sbp2_serialize_io : %s
\n
"
,
sbp2_serialize_io
?
"yes"
:
"no"
);
SPRINTF
(
" sbp2_exclusive_login : %s
\n
"
,
sbp2_exclusive_login
?
"yes"
:
"no"
);
/*
* Called by scsi stack after scsi driver is registered
*/
static
int
sbp2scsi_detect
(
Scsi_Host_Template
*
tpnt
)
{
SBP2_DEBUG
(
"sbp2scsi_detect"
);
SPRINTF
(
"
\n
Attached devices : %s
\n
"
,
!
list_empty
(
&
host
->
my_devices
)
?
""
:
"none"
);
/*
* Call sbp2_init to register with the ieee1394 stack. This
* results in a callback to sbp2_add_host for each ieee1394
* host controller currently registered, and for each of those
* we register a scsi host with the scsi stack.
*/
list_for_each_entry
(
scd
,
&
host
->
my_devices
,
siblings
)
{
int
i
;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
spin_unlock_irq
(
&
io_request_lock
);
sbp2_init
();
spin_lock_irq
(
&
io_request_lock
);
#else
sbp2_init
();
#endif
SPRINTF
(
" [Channel: %02d, Id: %02d, Lun: %02d] "
,
scd
->
channel
,
scd
->
id
,
scd
->
lun
);
SPRINTF
(
"%s "
,
(
scd
->
type
<
MAX_SCSI_DEVICE_CODE
)
?
scsi_device_types
[(
short
)
scd
->
type
]
:
"Unknown device"
);
/* We return the number of hosts registered. */
return
scsi_driver_template
.
present
;
}
for
(
i
=
0
;
(
i
<
8
)
&&
(
scd
->
vendor
[
i
]
>=
0x20
);
i
++
)
SPRINTF
(
"%c"
,
scd
->
vendor
[
i
]);
SPRINTF
(
" "
);
/*
* Called for contents of procfs
*/
static
const
char
*
sbp2scsi_info
(
struct
Scsi_Host
*
host
)
{
struct
sbp2scsi_host_info
*
hi
=
sbp2_find_host_info_scsi
(
host
);
static
char
info
[
1024
];
for
(
i
=
0
;
(
i
<
16
)
&&
(
scd
->
model
[
i
]
>=
0x20
);
i
++
)
SPRINTF
(
"%c"
,
scd
->
model
[
i
]);
if
(
!
hi
)
/* shouldn't happen, but... */
return
"IEEE-1394 SBP-2 protocol driver"
;
sprintf
(
info
,
"IEEE-1394 SBP-2 protocol driver (host: %s)
\n
%s
\n
"
"SBP-2 module load options:
\n
"
"- Max speed supported: %s
\n
"
"- Max sectors per I/O supported: %d
\n
"
"- Serialized I/O (debug): %s
\n
"
"- Exclusive login: %s"
,
hi
->
host
->
driver
->
name
,
version
,
hpsb_speedto_str
[
sbp2_max_speed
],
sbp2_max_sectors
,
sbp2_serialize_io
?
"yes"
:
"no"
,
sbp2_exclusive_login
?
"yes"
:
"no"
);
return
info
;
}
SPRINTF
(
"
\n
"
);
}
SPRINTF
(
"
\n
"
);
/* release the reference count on this host */
scsi_host_put
(
host
);
/* Calculate start of next buffer, and return value. */
*
start
=
buffer
+
offset
;
if
((
pos
-
buffer
)
<
offset
)
return
(
0
);
else
if
((
pos
-
buffer
-
offset
)
<
length
)
return
(
pos
-
buffer
-
offset
);
else
return
(
length
);
}
MODULE_AUTHOR
(
"James Goodwin <jamesg@filanet.com>"
);
MODULE_DESCRIPTION
(
"IEEE-1394 SBP-2 protocol driver"
);
...
...
@@ -3046,25 +2985,23 @@ MODULE_LICENSE("GPL");
/* SCSI host template */
static
Scsi_Host_Template
scsi_driver_template
=
{
.
name
=
"IEEE-1394 SBP-2 protocol driver"
,
.
module
=
THIS_MODULE
,
.
name
=
"SBP-2 IEEE-1394"
,
.
proc_name
=
SBP2_DEVICE_NAME
,
.
info
=
sbp2scsi_info
,
.
detect
=
sbp2scsi_detect
,
.
proc_info
=
sbp2scsi_proc_info
,
.
queuecommand
=
sbp2scsi_queuecommand
,
.
eh_abort_handler
=
sbp2scsi_abort
,
.
eh_device_reset_handler
=
sbp2scsi_reset
,
.
eh_device_reset_handler
=
sbp2scsi_reset
,
.
eh_bus_reset_handler
=
sbp2scsi_reset
,
.
eh_host_reset_handler
=
sbp2scsi_reset
,
.
bios_param
=
sbp2scsi_biosparam
,
.
eh_host_reset_handler
=
sbp2scsi_reset
,
.
this_id
=
-
1
,
.
sg_tablesize
=
SG_ALL
,
.
use_clustering
=
ENABLE_CLUSTERING
,
.
cmd_per_lun
=
SBP2_MAX_CMDS_PER_LUN
,
.
can_queue
=
SBP2_MAX_SCSI_QUEUE
,
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
.
use_new_eh_code
=
TRUE
,
#endif
.
emulated
=
1
,
.
proc_name
=
SBP2_DEVICE_NAME
,
.
highmem_io
=
1
,
};
static
int
sbp2_module_init
(
void
)
...
...
@@ -3084,23 +3021,36 @@ static int sbp2_module_init(void)
*/
scsi_driver_template
.
max_sectors
=
sbp2_max_sectors
;
/*
* Ideally we would register our scsi_driver_template with the
* scsi stack and after that register with the ieee1394 stack
* and process the add_host callbacks. However, the detect
* function in the scsi host template requires that we find at
* least one host, so we "nest" the registrations by calling
* sbp2_init from the detect function.
* Register our high level driver with 1394 stack
*/
scsi_driver_template
.
module
=
THIS_MODULE
;
if
(
SCSI_REGISTER_HOST
(
&
scsi_driver_template
)
||
!
scsi_driver_template
.
present
)
{
SBP2_ERR
(
"Please load the lower level IEEE-1394 driver "
"(e.g. ohci1394) before sbp2..."
);
sbp2_cleanup
();
return
-
ENODEV
;
sbp2_hl_handle
=
hpsb_register_highlevel
(
SBP2_DEVICE_NAME
,
&
sbp2_hl_ops
);
if
(
!
sbp2_hl_handle
)
{
SBP2_ERR
(
"sbp2 failed to register with ieee1394 highlevel"
);
return
(
-
ENOMEM
);
}
/*
* Register our sbp2 status address space...
*/
hpsb_register_addrspace
(
sbp2_hl_handle
,
&
sbp2_ops
,
SBP2_STATUS_FIFO_ADDRESS
,
SBP2_STATUS_FIFO_ADDRESS
+
SBP2_STATUS_FIFO_ENTRY_TO_OFFSET
(
SBP2SCSI_MAX_SCSI_IDS
+
1
));
/*
* Handle data movement if physical dma is not enabled/supported
* on host controller
*/
#ifdef CONFIG_IEEE1394_SBP2_PHYS_DMA
hpsb_register_addrspace
(
sbp2_hl_handle
,
&
sbp2_physdma_ops
,
0x0ULL
,
0xfffffffcULL
);
#endif
hpsb_register_protocol
(
&
sbp2_driver
);
return
0
;
}
...
...
@@ -3108,17 +3058,9 @@ static void __exit sbp2_module_exit(void)
{
SBP2_DEBUG
(
"sbp2_module_exit"
);
/*
* On module unload we unregister with the ieee1394 stack
* which results in remove_host callbacks for all ieee1394
* host controllers. In the callbacks we unregister the
* corresponding scsi hosts.
*/
sbp2_cleanup
();
if
(
SCSI_UNREGISTER_HOST
(
&
scsi_driver_template
))
SBP2_ERR
(
"sbp2_module_exit: couldn't unregister scsi driver"
);
hpsb_unregister_protocol
(
&
sbp2_driver
);
if
(
sbp2_hl_handle
)
hpsb_unregister_highlevel
(
sbp2_hl_handle
);
}
module_init
(
sbp2_module_init
);
...
...
drivers/ieee1394/sbp2.h
View file @
b3f00969
...
...
@@ -22,15 +22,6 @@
#ifndef SBP2_H
#define SBP2_H
/* Some compatibility code */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
#define SCSI_REGISTER_HOST(tmpl) scsi_register_module(MODULE_SCSI_HA, tmpl)
#define SCSI_UNREGISTER_HOST(tmpl) scsi_unregister_module(MODULE_SCSI_HA, tmpl)
#else
#define SCSI_REGISTER_HOST(tmpl) scsi_register_host(tmpl)
#define SCSI_UNREGISTER_HOST(tmpl) scsi_unregister_host(tmpl)
#endif
#define SBP2_DEVICE_NAME "sbp2"
/*
...
...
@@ -442,8 +433,6 @@ static void sbp2util_mark_command_completed(struct scsi_id_instance_data *scsi_i
static
void
sbp2_add_host
(
struct
hpsb_host
*
host
);
static
struct
sbp2scsi_host_info
*
sbp2_find_host_info
(
struct
hpsb_host
*
host
);
static
void
sbp2_remove_host
(
struct
hpsb_host
*
host
);
int
sbp2_init
(
void
);
void
sbp2_cleanup
(
void
);
static
int
sbp2_probe
(
struct
unit_directory
*
ud
);
static
void
sbp2_disconnect
(
struct
unit_directory
*
ud
);
static
void
sbp2_update
(
struct
unit_directory
*
ud
);
...
...
@@ -487,23 +476,4 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id);
static
int
sbp2_set_busy_timeout
(
struct
sbp2scsi_host_info
*
hi
,
struct
scsi_id_instance_data
*
scsi_id
);
static
int
sbp2_max_speed_and_size
(
struct
sbp2scsi_host_info
*
hi
,
struct
scsi_id_instance_data
*
scsi_id
);
/*
* Scsi interface related prototypes
*/
static
int
sbp2scsi_detect
(
Scsi_Host_Template
*
tpnt
);
static
const
char
*
sbp2scsi_info
(
struct
Scsi_Host
*
host
);
void
sbp2scsi_setup
(
char
*
str
,
int
*
ints
);
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,44)
static
int
sbp2scsi_biosparam
(
struct
scsi_device
*
sdev
,
struct
block_device
*
dev
,
sector_t
capacity
,
int
geom
[]);
#else
static
int
sbp2scsi_biosparam
(
Scsi_Disk
*
disk
,
kdev_t
dev
,
int
geom
[]);
#endif
static
int
sbp2scsi_abort
(
Scsi_Cmnd
*
SCpnt
);
static
int
sbp2scsi_reset
(
Scsi_Cmnd
*
SCpnt
);
static
int
sbp2scsi_queuecommand
(
Scsi_Cmnd
*
SCpnt
,
void
(
*
done
)(
Scsi_Cmnd
*
));
static
void
sbp2scsi_complete_all_commands
(
struct
sbp2scsi_host_info
*
hi
,
struct
scsi_id_instance_data
*
scsi_id
,
u32
status
);
static
void
sbp2scsi_complete_command
(
struct
sbp2scsi_host_info
*
hi
,
struct
scsi_id_instance_data
*
scsi_id
,
u32
scsi_status
,
Scsi_Cmnd
*
SCpnt
,
void
(
*
done
)(
Scsi_Cmnd
*
));
#endif
/* SBP2_H */
drivers/ieee1394/video1394.c
View file @
b3f00969
...
...
@@ -43,6 +43,8 @@
#include <linux/vmalloc.h>
#include <linux/timex.h>
#include <linux/mm.h>
#include <linux/ioctl32.h>
#include <linux/compat.h>
#include "ieee1394.h"
#include "ieee1394_types.h"
...
...
@@ -1338,8 +1340,133 @@ MODULE_DESCRIPTION("driver for digital video on OHCI board");
MODULE_SUPPORTED_DEVICE
(
VIDEO1394_DRIVER_NAME
);
MODULE_LICENSE
(
"GPL"
);
#ifdef CONFIG_COMPAT
#define VIDEO1394_IOC32_LISTEN_QUEUE_BUFFER \
_IOW ('#', 0x12, struct video1394_wait32)
#define VIDEO1394_IOC32_LISTEN_WAIT_BUFFER \
_IOWR('#', 0x13, struct video1394_wait32)
#define VIDEO1394_IOC32_TALK_WAIT_BUFFER \
_IOW ('#', 0x17, struct video1394_wait32)
#define VIDEO1394_IOC32_LISTEN_POLL_BUFFER \
_IOWR('#', 0x18, struct video1394_wait32)
struct
video1394_wait32
{
u32
channel
;
u32
buffer
;
struct
compat_timeval
filltime
;
};
static
int
video1394_wr_wait32
(
unsigned
int
fd
,
unsigned
int
cmd
,
unsigned
long
arg
,
struct
file
*
file
)
{
struct
video1394_wait32
wait32
;
struct
video1394_wait
wait
;
mm_segment_t
old_fs
;
int
ret
;
if
(
file
->
f_op
->
ioctl
!=
video1394_ioctl
)
return
-
EFAULT
;
if
(
copy_from_user
(
&
wait32
,
(
void
*
)
arg
,
sizeof
(
wait32
)))
return
-
EFAULT
;
wait
.
channel
=
wait32
.
channel
;
wait
.
buffer
=
wait32
.
buffer
;
wait
.
filltime
.
tv_sec
=
(
time_t
)
wait32
.
filltime
.
tv_sec
;
wait
.
filltime
.
tv_usec
=
(
suseconds_t
)
wait32
.
filltime
.
tv_usec
;
old_fs
=
get_fs
();
set_fs
(
KERNEL_DS
);
if
(
cmd
==
VIDEO1394_IOC32_LISTEN_WAIT_BUFFER
)
ret
=
video1394_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
VIDEO1394_IOC_LISTEN_WAIT_BUFFER
,
(
unsigned
long
)
&
wait
);
else
ret
=
video1394_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
VIDEO1394_IOC_LISTEN_POLL_BUFFER
,
(
unsigned
long
)
&
wait
);
set_fs
(
old_fs
);
if
(
!
ret
)
{
wait32
.
channel
=
wait
.
channel
;
wait32
.
buffer
=
wait
.
buffer
;
wait32
.
filltime
.
tv_sec
=
(
int
)
wait
.
filltime
.
tv_sec
;
wait32
.
filltime
.
tv_usec
=
(
int
)
wait
.
filltime
.
tv_usec
;
if
(
copy_to_user
((
struct
video1394_wait32
*
)
arg
,
&
wait32
,
sizeof
(
wait32
)))
ret
=
-
EFAULT
;
}
return
ret
;
}
static
int
video1394_w_wait32
(
unsigned
int
fd
,
unsigned
int
cmd
,
unsigned
long
arg
,
struct
file
*
file
)
{
struct
video1394_wait32
wait32
;
struct
video1394_wait
wait
;
mm_segment_t
old_fs
;
int
ret
;
if
(
file
->
f_op
->
ioctl
!=
video1394_ioctl
)
return
-
EFAULT
;
if
(
copy_from_user
(
&
wait32
,
(
void
*
)
arg
,
sizeof
(
wait32
)))
return
-
EFAULT
;
wait
.
channel
=
wait32
.
channel
;
wait
.
buffer
=
wait32
.
buffer
;
wait
.
filltime
.
tv_sec
=
(
time_t
)
wait32
.
filltime
.
tv_sec
;
wait
.
filltime
.
tv_usec
=
(
suseconds_t
)
wait32
.
filltime
.
tv_usec
;
old_fs
=
get_fs
();
set_fs
(
KERNEL_DS
);
if
(
cmd
==
VIDEO1394_IOC32_LISTEN_QUEUE_BUFFER
)
ret
=
video1394_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
VIDEO1394_IOC_LISTEN_QUEUE_BUFFER
,
(
unsigned
long
)
&
wait
);
else
ret
=
video1394_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
VIDEO1394_IOC_TALK_WAIT_BUFFER
,
(
unsigned
long
)
&
wait
);
set_fs
(
old_fs
);
return
ret
;
}
static
int
video1394_queue_buf32
(
unsigned
int
fd
,
unsigned
int
cmd
,
unsigned
long
arg
,
struct
file
*
file
)
{
if
(
file
->
f_op
->
ioctl
!=
video1394_ioctl
)
return
-
EFAULT
;
return
-
EFAULT
;
return
video1394_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
VIDEO1394_IOC_TALK_QUEUE_BUFFER
,
arg
);
}
#endif
/* CONFIG_COMPAT */
static
void
__exit
video1394_exit_module
(
void
)
{
#ifdef CONFIG_COMPAT
int
ret
;
ret
=
unregister_ioctl32_conversion
(
VIDEO1394_IOC_LISTEN_CHANNEL
);
ret
|=
unregister_ioctl32_conversion
(
VIDEO1394_IOC_UNLISTEN_CHANNEL
);
ret
|=
unregister_ioctl32_conversion
(
VIDEO1394_IOC_TALK_CHANNEL
);
ret
|=
unregister_ioctl32_conversion
(
VIDEO1394_IOC_UNTALK_CHANNEL
);
ret
|=
unregister_ioctl32_conversion
(
VIDEO1394_IOC32_LISTEN_QUEUE_BUFFER
);
ret
|=
unregister_ioctl32_conversion
(
VIDEO1394_IOC32_LISTEN_WAIT_BUFFER
);
ret
|=
unregister_ioctl32_conversion
(
VIDEO1394_IOC_TALK_QUEUE_BUFFER
);
ret
|=
unregister_ioctl32_conversion
(
VIDEO1394_IOC32_TALK_WAIT_BUFFER
);
ret
|=
unregister_ioctl32_conversion
(
VIDEO1394_IOC32_LISTEN_POLL_BUFFER
);
if
(
ret
)
PRINT_G
(
KERN_INFO
,
"Error unregistering ioctl32 translations"
);
#endif
hpsb_unregister_highlevel
(
hl_handle
);
devfs_unregister
(
devfs_handle
);
...
...
@@ -1350,8 +1477,11 @@ static void __exit video1394_exit_module (void)
static
int
__init
video1394_init_module
(
void
)
{
if
(
ieee1394_register_chardev
(
IEEE1394_MINOR_BLOCK_VIDEO1394
,
THIS_MODULE
,
&
video1394_fops
))
{
int
ret
;
ret
=
ieee1394_register_chardev
(
IEEE1394_MINOR_BLOCK_VIDEO1394
,
THIS_MODULE
,
&
video1394_fops
);
if
(
ret
)
{
PRINT_G
(
KERN_ERR
,
"video1394: unable to get minor device block"
);
return
-
EIO
;
}
...
...
@@ -1366,9 +1496,32 @@ static int __init video1394_init_module (void)
return
-
ENOMEM
;
}
#ifdef CONFIG_COMPAT
/* First the compatible ones */
ret
=
register_ioctl32_conversion
(
VIDEO1394_IOC_LISTEN_CHANNEL
,
NULL
);
ret
|=
register_ioctl32_conversion
(
VIDEO1394_IOC_UNLISTEN_CHANNEL
,
NULL
);
ret
|=
register_ioctl32_conversion
(
VIDEO1394_IOC_TALK_CHANNEL
,
NULL
);
ret
|=
register_ioctl32_conversion
(
VIDEO1394_IOC_UNTALK_CHANNEL
,
NULL
);
/* These need translation */
ret
|=
register_ioctl32_conversion
(
VIDEO1394_IOC32_LISTEN_QUEUE_BUFFER
,
video1394_w_wait32
);
ret
|=
register_ioctl32_conversion
(
VIDEO1394_IOC32_LISTEN_WAIT_BUFFER
,
video1394_wr_wait32
);
ret
|=
register_ioctl32_conversion
(
VIDEO1394_IOC_TALK_QUEUE_BUFFER
,
video1394_queue_buf32
);
ret
|=
register_ioctl32_conversion
(
VIDEO1394_IOC32_TALK_WAIT_BUFFER
,
video1394_w_wait32
);
ret
|=
register_ioctl32_conversion
(
VIDEO1394_IOC32_LISTEN_POLL_BUFFER
,
video1394_wr_wait32
);
if
(
ret
)
PRINT_G
(
KERN_INFO
,
"Error registering ioctl32 translations"
);
#endif
PRINT_G
(
KERN_INFO
,
"Installed "
VIDEO1394_DRIVER_NAME
" module"
);
return
0
;
}
module_init
(
video1394_init_module
);
module_exit
(
video1394_exit_module
);
drivers/net/dgrs.c
View file @
b3f00969
...
...
@@ -981,7 +981,7 @@ dgrs_download(struct net_device *dev0)
{
DGRS_PRIV
*
priv0
=
(
DGRS_PRIV
*
)
dev0
->
priv
;
int
is
;
int
i
;
unsigned
long
i
;
static
int
iv2is
[
16
]
=
{
0
,
0
,
0
,
ES4H_IS_INT3
,
...
...
@@ -1140,7 +1140,7 @@ int __init
dgrs_probe1
(
struct
net_device
*
dev
)
{
DGRS_PRIV
*
priv
=
(
DGRS_PRIV
*
)
dev
->
priv
;
int
i
;
unsigned
long
i
;
int
rc
;
printk
(
"%s: Digi RightSwitch io=%lx mem=%lx irq=%d plx=%lx dma=%lx
\n
"
,
...
...
drivers/net/shaper.c
View file @
b3f00969
...
...
@@ -88,10 +88,10 @@
#include <net/arp.h>
struct
shaper_cb
{
unsigned
long
shapeclock
;
/* Time it should go out */
unsigned
long
shapestamp
;
/* Stamp for shaper */
__u32
shapelatency
;
/* Latency on frame */
__u32
shapeclock
;
/* Time it should go out */
__u32
shapelen
;
/* Frame length in clocks */
__u32
shapestamp
;
/* Stamp for shaper */
__u16
shapepend
;
/* Pending */
};
#define SHAPERCB(skb) ((struct shaper_cb *) ((skb)->cb))
...
...
@@ -335,7 +335,7 @@ static void shaper_kick(struct shaper *shaper)
*/
if
(
sh_debug
)
printk
(
"Clock = %d, jiffies = %ld
\n
"
,
SHAPERCB
(
skb
)
->
shapeclock
,
jiffies
);
printk
(
"Clock = %
l
d, jiffies = %ld
\n
"
,
SHAPERCB
(
skb
)
->
shapeclock
,
jiffies
);
if
(
time_before_eq
(
SHAPERCB
(
skb
)
->
shapeclock
-
jiffies
,
SHAPER_BURST
))
{
/*
...
...
drivers/net/sis900.c
View file @
b3f00969
...
...
@@ -509,7 +509,7 @@ static int __init sis900_mii_probe (struct net_device * net_dev)
{
struct
sis900_private
*
sis_priv
=
net_dev
->
priv
;
u16
poll_bit
=
MII_STAT_LINK
,
status
=
0
;
unsigned
int
timeout
=
jiffies
+
5
*
HZ
;
unsigned
long
timeout
=
jiffies
+
5
*
HZ
;
int
phy_addr
;
u8
revision
;
...
...
drivers/scsi/qlogicfc.c
View file @
b3f00969
...
...
@@ -694,7 +694,7 @@ static inline void isp2x00_disable_irqs(struct Scsi_Host *host)
int
isp2x00_detect
(
Scsi_Host_Template
*
tmpt
)
{
int
hosts
=
0
;
int
wait_time
;
unsigned
long
wait_time
;
struct
Scsi_Host
*
host
=
NULL
;
struct
isp2x00_hostdata
*
hostdata
;
struct
pci_dev
*
pdev
;
...
...
fs/dcache.c
View file @
b3f00969
...
...
@@ -47,16 +47,8 @@ static kmem_cache_t *dentry_cache;
static
unsigned
int
d_hash_mask
;
static
unsigned
int
d_hash_shift
;
static
struct
list_head
*
dentry_hashtable
;
static
struct
h
list_head
*
dentry_hashtable
;
static
LIST_HEAD
(
dentry_unused
);
static
int
max_dentries
;
static
void
*
hashtable_end
;
static
inline
int
is_bucket
(
void
*
addr
)
{
return
((
addr
<
(
void
*
)
dentry_hashtable
)
||
(
addr
>
hashtable_end
)
?
0
:
1
);
}
/* Statistics gathering. */
struct
dentry_stat_t
dentry_stat
=
{
...
...
@@ -292,6 +284,7 @@ struct dentry * d_find_alias(struct inode *inode)
while
(
next
!=
head
)
{
tmp
=
next
;
next
=
tmp
->
next
;
prefetch
(
next
);
alias
=
list_entry
(
tmp
,
struct
dentry
,
d_alias
);
if
(
!
d_unhashed
(
alias
))
{
if
(
alias
->
d_flags
&
DCACHE_DISCONNECTED
)
...
...
@@ -378,6 +371,7 @@ static void prune_dcache(int count)
if
(
tmp
==
&
dentry_unused
)
break
;
list_del_init
(
tmp
);
prefetch
(
dentry_unused
.
prev
);
dentry_stat
.
nr_unused
--
;
dentry
=
list_entry
(
tmp
,
struct
dentry
,
d_lru
);
...
...
@@ -603,15 +597,15 @@ void shrink_dcache_parent(struct dentry * parent)
* done under dcache_lock.
*
*/
void
shrink_dcache_anon
(
struct
list_head
*
head
)
void
shrink_dcache_anon
(
struct
h
list_head
*
head
)
{
struct
list_head
*
lp
;
struct
hlist_node
*
lp
;
int
found
;
do
{
found
=
0
;
spin_lock
(
&
dcache_lock
);
list_for_each
(
lp
,
head
)
{
struct
dentry
*
this
=
list_entry
(
lp
,
struct
dentry
,
d_hash
);
h
list_for_each
(
lp
,
head
)
{
struct
dentry
*
this
=
h
list_entry
(
lp
,
struct
dentry
,
d_hash
);
list_del
(
&
this
->
d_lru
);
/* don't add non zero d_count dentries
...
...
@@ -727,7 +721,7 @@ struct dentry * d_alloc(struct dentry * parent, const struct qstr *name)
dentry
->
d_mounted
=
0
;
dentry
->
d_cookie
=
NULL
;
dentry
->
d_bucket
=
NULL
;
INIT_
LIST_HEAD
(
&
dentry
->
d_hash
);
INIT_
HLIST_NODE
(
&
dentry
->
d_hash
);
INIT_LIST_HEAD
(
&
dentry
->
d_lru
);
INIT_LIST_HEAD
(
&
dentry
->
d_subdirs
);
INIT_LIST_HEAD
(
&
dentry
->
d_alias
);
...
...
@@ -797,7 +791,7 @@ struct dentry * d_alloc_root(struct inode * root_inode)
return
res
;
}
static
inline
struct
list_head
*
d_hash
(
struct
dentry
*
parent
,
unsigned
long
hash
)
static
inline
struct
h
list_head
*
d_hash
(
struct
dentry
*
parent
,
unsigned
long
hash
)
{
hash
+=
(
unsigned
long
)
parent
/
L1_CACHE_BYTES
;
hash
=
hash
^
(
hash
>>
D_HASHBITS
);
...
...
@@ -860,7 +854,7 @@ struct dentry * d_alloc_anon(struct inode *inode)
res
->
d_flags
|=
DCACHE_DISCONNECTED
;
res
->
d_vfs_flags
&=
~
DCACHE_UNHASHED
;
list_add
(
&
res
->
d_alias
,
&
inode
->
i_dentry
);
list_ad
d
(
&
res
->
d_hash
,
&
inode
->
i_sb
->
s_anon
);
hlist_add_hea
d
(
&
res
->
d_hash
,
&
inode
->
i_sb
->
s_anon
);
spin_unlock
(
&
res
->
d_lock
);
}
inode
=
NULL
;
/* don't drop reference */
...
...
@@ -947,21 +941,21 @@ struct dentry * d_lookup(struct dentry * parent, struct qstr * name)
unsigned
int
len
=
name
->
len
;
unsigned
int
hash
=
name
->
hash
;
const
unsigned
char
*
str
=
name
->
name
;
struct
list_head
*
head
=
d_hash
(
parent
,
hash
);
struct
h
list_head
*
head
=
d_hash
(
parent
,
hash
);
struct
dentry
*
found
=
NULL
;
struct
list_head
*
tmp
;
int
lookup_count
=
0
;
struct
hlist_node
*
node
;
rcu_read_lock
();
/* lookup is terminated when flow reaches any bucket head */
for
(
tmp
=
head
->
next
;
!
is_bucket
(
tmp
);
tmp
=
tmp
->
next
)
{
hlist_for_each
(
node
,
head
)
{
struct
dentry
*
dentry
;
unsigned
long
move_count
;
struct
qstr
*
qstr
;
prefetch
(
node
->
next
);
smp_read_barrier_depends
();
dentry
=
list_entry
(
tmp
,
struct
dentry
,
d_hash
);
dentry
=
hlist_entry
(
node
,
struct
dentry
,
d_hash
);
/* if lookup ends up in a different bucket
* due to concurrent rename, fail it
...
...
@@ -969,12 +963,6 @@ struct dentry * d_lookup(struct dentry * parent, struct qstr * name)
if
(
unlikely
(
dentry
->
d_bucket
!=
head
))
break
;
/* to avoid race if dentry keep coming back to original
* bucket due to double moves
*/
if
(
unlikely
(
++
lookup_count
>
max_dentries
))
break
;
/*
* We must take a snapshot of d_move_count followed by
* read memory barrier before any search key comparison
...
...
@@ -1034,7 +1022,8 @@ int d_validate(struct dentry *dentry, struct dentry *dparent)
unsigned
long
dent_addr
=
(
unsigned
long
)
dentry
;
unsigned
long
min_addr
=
PAGE_OFFSET
;
unsigned
long
align_mask
=
0x0F
;
struct
list_head
*
base
,
*
lhp
;
struct
hlist_head
*
base
;
struct
hlist_node
*
lhp
;
if
(
dent_addr
<
min_addr
)
goto
out
;
...
...
@@ -1050,12 +1039,13 @@ int d_validate(struct dentry *dentry, struct dentry *dparent)
goto
out
;
spin_lock
(
&
dcache_lock
);
lhp
=
base
=
d_hash
(
dparent
,
dentry
->
d_name
.
hash
);
while
((
lhp
=
lhp
->
next
)
!=
base
)
{
base
=
d_hash
(
dparent
,
dentry
->
d_name
.
hash
);
hlist_for_each
(
lhp
,
base
)
{
prefetch
(
lhp
->
next
);
/* read_barrier_depends() not required for d_hash list
* as it is parsed under dcache_lock
*/
if
(
dentry
==
list_entry
(
lhp
,
struct
dentry
,
d_hash
))
{
if
(
dentry
==
h
list_entry
(
lhp
,
struct
dentry
,
d_hash
))
{
__dget_locked
(
dentry
);
spin_unlock
(
&
dcache_lock
);
return
1
;
...
...
@@ -1116,12 +1106,11 @@ void d_delete(struct dentry * dentry)
void
d_rehash
(
struct
dentry
*
entry
)
{
struct
list_head
*
list
=
d_hash
(
entry
->
d_parent
,
entry
->
d_name
.
hash
);
struct
h
list_head
*
list
=
d_hash
(
entry
->
d_parent
,
entry
->
d_name
.
hash
);
spin_lock
(
&
dcache_lock
);
if
(
!
list_empty
(
&
entry
->
d_hash
)
&&
!
d_unhashed
(
entry
))
BUG
();
entry
->
d_vfs_flags
&=
~
DCACHE_UNHASHED
;
entry
->
d_bucket
=
list
;
list_ad
d_rcu
(
&
entry
->
d_hash
,
list
);
hlist_add_hea
d_rcu
(
&
entry
->
d_hash
,
list
);
spin_unlock
(
&
dcache_lock
);
}
...
...
@@ -1174,10 +1163,6 @@ static inline void switch_names(struct dentry * dentry, struct dentry * target)
* We could be nicer about the deleted file, and let it show
* up under the name it got deleted rather than the name that
* deleted it.
*
* Careful with the hash switch. The hash switch depends on
* the fact that any list-entry can be a head of the list.
* Think about it.
*/
/**
...
...
@@ -1200,8 +1185,8 @@ void d_move(struct dentry * dentry, struct dentry * target)
/* Move the dentry to the target hash queue, if on different bucket */
if
(
dentry
->
d_bucket
!=
target
->
d_bucket
)
{
dentry
->
d_bucket
=
target
->
d_bucket
;
list_del_rcu
(
&
dentry
->
d_hash
);
list_add_rcu
(
&
dentry
->
d_hash
,
&
target
->
d_hash
);
h
list_del_rcu
(
&
dentry
->
d_hash
);
hlist_add_head_rcu
(
&
dentry
->
d_hash
,
target
->
d_bucket
);
}
/* Unhash the target: dput() will then get rid of it */
...
...
@@ -1284,6 +1269,7 @@ static char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
continue
;
}
parent
=
dentry
->
d_parent
;
prefetch
(
parent
);
namelen
=
dentry
->
d_name
.
len
;
buflen
-=
namelen
+
1
;
if
(
buflen
<
0
)
...
...
@@ -1503,7 +1489,7 @@ ino_t find_inode_number(struct dentry *dir, struct qstr *name)
static
void
__init
dcache_init
(
unsigned
long
mempages
)
{
struct
list_head
*
d
;
struct
h
list_head
*
d
;
unsigned
long
order
;
unsigned
int
nr_hash
;
int
i
;
...
...
@@ -1524,15 +1510,12 @@ static void __init dcache_init(unsigned long mempages)
if
(
!
dentry_cache
)
panic
(
"Cannot create dentry cache"
);
/* approximate maximum number of dentries in one hash bucket */
max_dentries
=
(
mempages
*
(
PAGE_SIZE
/
sizeof
(
struct
dentry
)));
set_shrinker
(
DEFAULT_SEEKS
,
shrink_dcache_memory
);
#if PAGE_SHIFT < 13
mempages
>>=
(
13
-
PAGE_SHIFT
);
#endif
mempages
*=
sizeof
(
struct
list_head
);
mempages
*=
sizeof
(
struct
h
list_head
);
for
(
order
=
0
;
((
1UL
<<
order
)
<<
PAGE_SHIFT
)
<
mempages
;
order
++
)
;
...
...
@@ -1540,7 +1523,7 @@ static void __init dcache_init(unsigned long mempages)
unsigned
long
tmp
;
nr_hash
=
(
1UL
<<
order
)
*
PAGE_SIZE
/
sizeof
(
struct
list_head
);
sizeof
(
struct
h
list_head
);
d_hash_mask
=
(
nr_hash
-
1
);
tmp
=
nr_hash
;
...
...
@@ -1548,7 +1531,7 @@ static void __init dcache_init(unsigned long mempages)
while
((
tmp
>>=
1UL
)
!=
0UL
)
d_hash_shift
++
;
dentry_hashtable
=
(
struct
list_head
*
)
dentry_hashtable
=
(
struct
h
list_head
*
)
__get_free_pages
(
GFP_ATOMIC
,
order
);
}
while
(
dentry_hashtable
==
NULL
&&
--
order
>=
0
);
...
...
@@ -1558,12 +1541,10 @@ static void __init dcache_init(unsigned long mempages)
if
(
!
dentry_hashtable
)
panic
(
"Failed to allocate dcache hash table
\n
"
);
hashtable_end
=
dentry_hashtable
+
nr_hash
;
d
=
dentry_hashtable
;
i
=
nr_hash
;
do
{
INIT_LIST_HEAD
(
d
);
INIT_
H
LIST_HEAD
(
d
);
d
++
;
i
--
;
}
while
(
i
);
...
...
fs/filesystems.c
View file @
b3f00969
...
...
@@ -9,6 +9,7 @@
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/kmod.h>
#include <linux/init.h>
#include <linux/module.h>
#include <asm/uaccess.h>
...
...
@@ -58,6 +59,38 @@ static struct file_system_type **find_filesystem(const char *name)
return
p
;
}
/* define fs_subsys */
static
decl_subsys
(
fs
,
NULL
);
static
int
register_fs_subsys
(
struct
file_system_type
*
fs
)
{
struct
subsystem
*
sub
=
&
fs
->
subsys
;
snprintf
(
sub
->
kset
.
kobj
.
name
,
KOBJ_NAME_LEN
,
"%s"
,
fs
->
name
);
subsys_set_kset
(
fs
,
fs_subsys
);
return
subsystem_register
(
sub
);
}
static
int
unlink_fs
(
struct
file_system_type
*
fs
)
{
struct
file_system_type
**
tmp
;
write_lock
(
&
file_systems_lock
);
tmp
=
&
file_systems
;
while
(
*
tmp
)
{
if
(
fs
==
*
tmp
)
{
*
tmp
=
fs
->
next
;
fs
->
next
=
NULL
;
write_unlock
(
&
file_systems_lock
);
return
0
;
}
tmp
=
&
(
*
tmp
)
->
next
;
}
write_unlock
(
&
file_systems_lock
);
return
-
EINVAL
;
}
/**
* register_filesystem - register a new filesystem
* @fs: the file system structure
...
...
@@ -88,6 +121,14 @@ int register_filesystem(struct file_system_type * fs)
else
*
p
=
fs
;
write_unlock
(
&
file_systems_lock
);
if
(
!
res
)
{
/* we implicitly possess reference to @fs during registration,
* so it cannot be unregister from under us. */
if
(
register_fs_subsys
(
fs
))
printk
(
KERN_WARNING
"Failed to register '%s' in sysfs
\n
"
,
fs
->
name
);
}
return
res
;
}
...
...
@@ -105,21 +146,44 @@ int register_filesystem(struct file_system_type * fs)
int
unregister_filesystem
(
struct
file_system_type
*
fs
)
{
struct
file_system_type
**
tmp
;
int
res
;
write_lock
(
&
file_systems_lock
);
tmp
=
&
file_systems
;
while
(
*
tmp
)
{
if
(
fs
==
*
tmp
)
{
*
tmp
=
fs
->
next
;
fs
->
next
=
NULL
;
write_unlock
(
&
file_systems_lock
);
return
0
;
}
tmp
=
&
(
*
tmp
)
->
next
;
}
write_unlock
(
&
file_systems_lock
);
return
-
EINVAL
;
res
=
unlink_fs
(
fs
);
if
(
!
res
)
subsystem_unregister
(
&
fs
->
subsys
);
return
res
;
}
extern
int
sysfs_init
(
void
);
/**
* fs_subsys_init - initialize sysfs and fs subsystem.
*
* In order to register filesystems in sysfs, it has to be
* initialized. Also, we need the base fs filesystem, so the
* registered filesystems have a home.
*
* During sysfs_init(), the registration of sysfs into itself
* will fail, since it's not mounted yet. To make sure that
* sysfs does show up, we re-register sysfs's embedded subsystem,
* which will get added, since sysfs is now mounted.
*/
void
__init
fs_subsys_init
(
void
)
{
struct
file_system_type
**
p
;
/* make sure sysfs is up and running */
sysfs_init
();
/* register fs_subsys */
subsystem_register
(
&
fs_subsys
);
p
=
find_filesystem
(
"sysfs"
);
if
(
p
)
/* make sure it's registered */
register_fs_subsys
(
*
p
);
}
static
int
fs_index
(
const
char
*
__name
)
...
...
fs/fs-writeback.c
View file @
b3f00969
...
...
@@ -90,7 +90,7 @@ void __mark_inode_dirty(struct inode *inode, int flags)
* Only add valid (hashed) inodes to the superblock's
* dirty list. Add blockdev inodes as well.
*/
if
(
list_empty
(
&
inode
->
i_hash
)
&&
!
S_ISBLK
(
inode
->
i_mode
))
if
(
hlist_unhashed
(
&
inode
->
i_hash
)
&&
!
S_ISBLK
(
inode
->
i_mode
))
goto
out
;
/*
...
...
fs/hugetlbfs/inode.c
View file @
b3f00969
...
...
@@ -189,7 +189,7 @@ void truncate_hugepages(struct address_space *mapping, loff_t lstart)
static
void
hugetlbfs_delete_inode
(
struct
inode
*
inode
)
{
list_del_init
(
&
inode
->
i_hash
);
h
list_del_init
(
&
inode
->
i_hash
);
list_del_init
(
&
inode
->
i_list
);
inode
->
i_state
|=
I_FREEING
;
inodes_stat
.
nr_inodes
--
;
...
...
@@ -208,7 +208,7 @@ static void hugetlbfs_forget_inode(struct inode *inode)
{
struct
super_block
*
super_block
=
inode
->
i_sb
;
if
(
list_empty
(
&
inode
->
i_hash
))
if
(
hlist_unhashed
(
&
inode
->
i_hash
))
goto
out_truncate
;
if
(
!
(
inode
->
i_state
&
(
I_DIRTY
|
I_LOCK
)))
{
...
...
@@ -223,7 +223,7 @@ static void hugetlbfs_forget_inode(struct inode *inode)
/* write_inode_now() ? */
inodes_stat
.
nr_unused
--
;
list_del_init
(
&
inode
->
i_hash
);
h
list_del_init
(
&
inode
->
i_hash
);
out_truncate:
list_del_init
(
&
inode
->
i_list
);
inode
->
i_state
|=
I_FREEING
;
...
...
fs/inode.c
View file @
b3f00969
...
...
@@ -69,8 +69,8 @@ static unsigned int i_hash_shift;
LIST_HEAD
(
inode_in_use
);
LIST_HEAD
(
inode_unused
);
static
struct
list_head
*
inode_hashtable
;
static
LIST_HEAD
(
anon_hash_chain
);
/* for inodes with NULL i_sb */
static
struct
h
list_head
*
inode_hashtable
;
static
H
LIST_HEAD
(
anon_hash_chain
);
/* for inodes with NULL i_sb */
/*
* A simple spinlock to protect the list manipulations.
...
...
@@ -172,7 +172,7 @@ void destroy_inode(struct inode *inode)
void
inode_init_once
(
struct
inode
*
inode
)
{
memset
(
inode
,
0
,
sizeof
(
*
inode
));
INIT_
LIST_HEAD
(
&
inode
->
i_hash
);
INIT_
HLIST_NODE
(
&
inode
->
i_hash
);
INIT_LIST_HEAD
(
&
inode
->
i_data
.
clean_pages
);
INIT_LIST_HEAD
(
&
inode
->
i_data
.
dirty_pages
);
INIT_LIST_HEAD
(
&
inode
->
i_data
.
locked_pages
);
...
...
@@ -294,7 +294,7 @@ static int invalidate_list(struct list_head *head, struct super_block * sb, stru
continue
;
invalidate_inode_buffers
(
inode
);
if
(
!
atomic_read
(
&
inode
->
i_count
))
{
list_del_init
(
&
inode
->
i_hash
);
h
list_del_init
(
&
inode
->
i_hash
);
list_del
(
&
inode
->
i_list
);
list_add
(
&
inode
->
i_list
,
dispose
);
inode
->
i_state
|=
I_FREEING
;
...
...
@@ -435,7 +435,7 @@ static void prune_icache(int nr_to_scan)
if
(
!
can_unuse
(
inode
))
continue
;
}
list_del_init
(
&
inode
->
i_hash
);
h
list_del_init
(
&
inode
->
i_hash
);
list_move
(
&
inode
->
i_list
,
&
freeable
);
inode
->
i_state
|=
I_FREEING
;
nr_pruned
++
;
...
...
@@ -476,50 +476,42 @@ static int shrink_icache_memory(int nr, unsigned int gfp_mask)
* by hand after calling find_inode now! This simplifies iunique and won't
* add any additional branch in the common code.
*/
static
struct
inode
*
find_inode
(
struct
super_block
*
sb
,
struct
list_head
*
head
,
int
(
*
test
)(
struct
inode
*
,
void
*
),
void
*
data
)
static
struct
inode
*
find_inode
(
struct
super_block
*
sb
,
struct
h
list_head
*
head
,
int
(
*
test
)(
struct
inode
*
,
void
*
),
void
*
data
)
{
struct
list_head
*
tmp
;
struct
inode
*
inode
;
struct
hlist_node
*
node
;
struct
inode
*
inode
=
NULL
;
tmp
=
head
;
for
(;;)
{
tmp
=
tmp
->
next
;
inode
=
NULL
;
if
(
tmp
==
head
)
break
;
inode
=
list_entry
(
tmp
,
struct
inode
,
i_hash
);
hlist_for_each
(
node
,
head
)
{
prefetch
(
node
->
next
);
inode
=
hlist_entry
(
node
,
struct
inode
,
i_hash
);
if
(
inode
->
i_sb
!=
sb
)
continue
;
if
(
!
test
(
inode
,
data
))
continue
;
break
;
}
return
inode
;
return
node
?
inode
:
NULL
;
}
/*
* find_inode_fast is the fast path version of find_inode, see the comment at
* iget_locked for details.
*/
static
struct
inode
*
find_inode_fast
(
struct
super_block
*
sb
,
struct
list_head
*
head
,
unsigned
long
ino
)
static
struct
inode
*
find_inode_fast
(
struct
super_block
*
sb
,
struct
h
list_head
*
head
,
unsigned
long
ino
)
{
struct
list_head
*
tmp
;
struct
inode
*
inode
;
struct
hlist_node
*
node
;
struct
inode
*
inode
=
NULL
;
tmp
=
head
;
for
(;;)
{
tmp
=
tmp
->
next
;
inode
=
NULL
;
if
(
tmp
==
head
)
break
;
inode
=
list_entry
(
tmp
,
struct
inode
,
i_hash
);
hlist_for_each
(
node
,
head
)
{
prefetch
(
node
->
next
);
inode
=
list_entry
(
node
,
struct
inode
,
i_hash
);
if
(
inode
->
i_ino
!=
ino
)
continue
;
if
(
inode
->
i_sb
!=
sb
)
continue
;
break
;
}
return
inode
;
return
node
?
inode
:
NULL
;
}
/**
...
...
@@ -569,7 +561,7 @@ EXPORT_SYMBOL(unlock_new_inode);
* We no longer cache the sb_flags in i_flags - see fs.h
* -- rmk@arm.uk.linux.org
*/
static
struct
inode
*
get_new_inode
(
struct
super_block
*
sb
,
struct
list_head
*
head
,
int
(
*
test
)(
struct
inode
*
,
void
*
),
int
(
*
set
)(
struct
inode
*
,
void
*
),
void
*
data
)
static
struct
inode
*
get_new_inode
(
struct
super_block
*
sb
,
struct
h
list_head
*
head
,
int
(
*
test
)(
struct
inode
*
,
void
*
),
int
(
*
set
)(
struct
inode
*
,
void
*
),
void
*
data
)
{
struct
inode
*
inode
;
...
...
@@ -586,7 +578,7 @@ static struct inode * get_new_inode(struct super_block *sb, struct list_head *he
inodes_stat
.
nr_inodes
++
;
list_add
(
&
inode
->
i_list
,
&
inode_in_use
);
list_ad
d
(
&
inode
->
i_hash
,
head
);
hlist_add_hea
d
(
&
inode
->
i_hash
,
head
);
inode
->
i_state
=
I_LOCK
|
I_NEW
;
spin_unlock
(
&
inode_lock
);
...
...
@@ -619,7 +611,7 @@ static struct inode * get_new_inode(struct super_block *sb, struct list_head *he
* get_new_inode_fast is the fast path version of get_new_inode, see the
* comment at iget_locked for details.
*/
static
struct
inode
*
get_new_inode_fast
(
struct
super_block
*
sb
,
struct
list_head
*
head
,
unsigned
long
ino
)
static
struct
inode
*
get_new_inode_fast
(
struct
super_block
*
sb
,
struct
h
list_head
*
head
,
unsigned
long
ino
)
{
struct
inode
*
inode
;
...
...
@@ -634,7 +626,7 @@ static struct inode * get_new_inode_fast(struct super_block *sb, struct list_hea
inode
->
i_ino
=
ino
;
inodes_stat
.
nr_inodes
++
;
list_add
(
&
inode
->
i_list
,
&
inode_in_use
);
list_ad
d
(
&
inode
->
i_hash
,
head
);
hlist_add_hea
d
(
&
inode
->
i_hash
,
head
);
inode
->
i_state
=
I_LOCK
|
I_NEW
;
spin_unlock
(
&
inode_lock
);
...
...
@@ -686,7 +678,7 @@ ino_t iunique(struct super_block *sb, ino_t max_reserved)
{
static
ino_t
counter
=
0
;
struct
inode
*
inode
;
struct
list_head
*
head
;
struct
h
list_head
*
head
;
ino_t
res
;
spin_lock
(
&
inode_lock
);
retry:
...
...
@@ -740,7 +732,7 @@ struct inode *igrab(struct inode *inode)
* Note, @test is called with the inode_lock held, so can't sleep.
*/
static
inline
struct
inode
*
ifind
(
struct
super_block
*
sb
,
struct
list_head
*
head
,
int
(
*
test
)(
struct
inode
*
,
void
*
),
struct
h
list_head
*
head
,
int
(
*
test
)(
struct
inode
*
,
void
*
),
void
*
data
)
{
struct
inode
*
inode
;
...
...
@@ -772,7 +764,7 @@ static inline struct inode *ifind(struct super_block *sb,
* Otherwise NULL is returned.
*/
static
inline
struct
inode
*
ifind_fast
(
struct
super_block
*
sb
,
struct
list_head
*
head
,
unsigned
long
ino
)
struct
h
list_head
*
head
,
unsigned
long
ino
)
{
struct
inode
*
inode
;
...
...
@@ -810,7 +802,7 @@ static inline struct inode *ifind_fast(struct super_block *sb,
struct
inode
*
ilookup5
(
struct
super_block
*
sb
,
unsigned
long
hashval
,
int
(
*
test
)(
struct
inode
*
,
void
*
),
void
*
data
)
{
struct
list_head
*
head
=
inode_hashtable
+
hash
(
sb
,
hashval
);
struct
h
list_head
*
head
=
inode_hashtable
+
hash
(
sb
,
hashval
);
return
ifind
(
sb
,
head
,
test
,
data
);
}
...
...
@@ -832,7 +824,7 @@ EXPORT_SYMBOL(ilookup5);
*/
struct
inode
*
ilookup
(
struct
super_block
*
sb
,
unsigned
long
ino
)
{
struct
list_head
*
head
=
inode_hashtable
+
hash
(
sb
,
ino
);
struct
h
list_head
*
head
=
inode_hashtable
+
hash
(
sb
,
ino
);
return
ifind_fast
(
sb
,
head
,
ino
);
}
...
...
@@ -864,7 +856,7 @@ struct inode *iget5_locked(struct super_block *sb, unsigned long hashval,
int
(
*
test
)(
struct
inode
*
,
void
*
),
int
(
*
set
)(
struct
inode
*
,
void
*
),
void
*
data
)
{
struct
list_head
*
head
=
inode_hashtable
+
hash
(
sb
,
hashval
);
struct
h
list_head
*
head
=
inode_hashtable
+
hash
(
sb
,
hashval
);
struct
inode
*
inode
;
inode
=
ifind
(
sb
,
head
,
test
,
data
);
...
...
@@ -897,7 +889,7 @@ EXPORT_SYMBOL(iget5_locked);
*/
struct
inode
*
iget_locked
(
struct
super_block
*
sb
,
unsigned
long
ino
)
{
struct
list_head
*
head
=
inode_hashtable
+
hash
(
sb
,
ino
);
struct
h
list_head
*
head
=
inode_hashtable
+
hash
(
sb
,
ino
);
struct
inode
*
inode
;
inode
=
ifind_fast
(
sb
,
head
,
ino
);
...
...
@@ -923,11 +915,11 @@ EXPORT_SYMBOL(iget_locked);
void
__insert_inode_hash
(
struct
inode
*
inode
,
unsigned
long
hashval
)
{
struct
list_head
*
head
=
&
anon_hash_chain
;
struct
h
list_head
*
head
=
&
anon_hash_chain
;
if
(
inode
->
i_sb
)
head
=
inode_hashtable
+
hash
(
inode
->
i_sb
,
hashval
);
spin_lock
(
&
inode_lock
);
list_ad
d
(
&
inode
->
i_hash
,
head
);
hlist_add_hea
d
(
&
inode
->
i_hash
,
head
);
spin_unlock
(
&
inode_lock
);
}
...
...
@@ -941,7 +933,7 @@ void __insert_inode_hash(struct inode *inode, unsigned long hashval)
void
remove_inode_hash
(
struct
inode
*
inode
)
{
spin_lock
(
&
inode_lock
);
list_del_init
(
&
inode
->
i_hash
);
h
list_del_init
(
&
inode
->
i_hash
);
spin_unlock
(
&
inode_lock
);
}
...
...
@@ -949,7 +941,7 @@ void generic_delete_inode(struct inode *inode)
{
struct
super_operations
*
op
=
inode
->
i_sb
->
s_op
;
list_del_init
(
&
inode
->
i_hash
);
h
list_del_init
(
&
inode
->
i_hash
);
list_del_init
(
&
inode
->
i_list
);
inode
->
i_state
|=
I_FREEING
;
inodes_stat
.
nr_inodes
--
;
...
...
@@ -978,7 +970,7 @@ static void generic_forget_inode(struct inode *inode)
{
struct
super_block
*
sb
=
inode
->
i_sb
;
if
(
!
list_empty
(
&
inode
->
i_hash
))
{
if
(
!
hlist_unhashed
(
&
inode
->
i_hash
))
{
if
(
!
(
inode
->
i_state
&
(
I_DIRTY
|
I_LOCK
)))
{
list_del
(
&
inode
->
i_list
);
list_add
(
&
inode
->
i_list
,
&
inode_unused
);
...
...
@@ -990,7 +982,7 @@ static void generic_forget_inode(struct inode *inode)
write_inode_now
(
inode
,
1
);
spin_lock
(
&
inode_lock
);
inodes_stat
.
nr_unused
--
;
list_del_init
(
&
inode
->
i_hash
);
h
list_del_init
(
&
inode
->
i_hash
);
}
list_del_init
(
&
inode
->
i_list
);
inode
->
i_state
|=
I_FREEING
;
...
...
@@ -1236,7 +1228,7 @@ void wake_up_inode(struct inode *inode)
*/
void
__init
inode_init
(
unsigned
long
mempages
)
{
struct
list_head
*
head
;
struct
h
list_head
*
head
;
unsigned
long
order
;
unsigned
int
nr_hash
;
int
i
;
...
...
@@ -1253,7 +1245,7 @@ void __init inode_init(unsigned long mempages)
unsigned
long
tmp
;
nr_hash
=
(
1UL
<<
order
)
*
PAGE_SIZE
/
sizeof
(
struct
list_head
);
sizeof
(
struct
h
list_head
);
i_hash_mask
=
(
nr_hash
-
1
);
tmp
=
nr_hash
;
...
...
@@ -1261,7 +1253,7 @@ void __init inode_init(unsigned long mempages)
while
((
tmp
>>=
1UL
)
!=
0UL
)
i_hash_shift
++
;
inode_hashtable
=
(
struct
list_head
*
)
inode_hashtable
=
(
struct
h
list_head
*
)
__get_free_pages
(
GFP_ATOMIC
,
order
);
}
while
(
inode_hashtable
==
NULL
&&
--
order
>=
0
);
...
...
@@ -1274,7 +1266,7 @@ void __init inode_init(unsigned long mempages)
head
=
inode_hashtable
;
i
=
nr_hash
;
do
{
INIT_LIST_HEAD
(
head
);
INIT_
H
LIST_HEAD
(
head
);
head
++
;
i
--
;
}
while
(
i
);
...
...
fs/namespace.c
View file @
b3f00969
...
...
@@ -26,6 +26,7 @@
extern
struct
vfsmount
*
do_kern_mount
(
const
char
*
type
,
int
flags
,
char
*
name
,
void
*
data
);
extern
int
do_remount_sb
(
struct
super_block
*
sb
,
int
flags
,
void
*
data
);
extern
int
__init
init_rootfs
(
void
);
extern
int
__init
fs_subsys_init
(
void
);
static
struct
list_head
*
mount_hashtable
;
static
int
hash_mask
,
hash_bits
;
...
...
@@ -1132,6 +1133,7 @@ void __init mnt_init(unsigned long mempages)
d
++
;
i
--
;
}
while
(
i
);
fs_subsys_init
();
init_rootfs
();
init_mount_tree
();
}
fs/super.c
View file @
b3f00969
...
...
@@ -63,7 +63,7 @@ static struct super_block *alloc_super(void)
INIT_LIST_HEAD
(
&
s
->
s_io
);
INIT_LIST_HEAD
(
&
s
->
s_files
);
INIT_LIST_HEAD
(
&
s
->
s_instances
);
INIT_LIST_HEAD
(
&
s
->
s_anon
);
INIT_
H
LIST_HEAD
(
&
s
->
s_anon
);
init_rwsem
(
&
s
->
s_umount
);
sema_init
(
&
s
->
s_lock
,
1
);
down_write
(
&
s
->
s_umount
);
...
...
fs/sysfs/bin.c
View file @
b3f00969
...
...
@@ -226,6 +226,7 @@ int sysfs_create_bin_file(struct kobject * kobj, struct bin_attribute * attr)
int
sysfs_remove_bin_file
(
struct
kobject
*
kobj
,
struct
bin_attribute
*
attr
)
{
sysfs_hash_and_remove
(
kobj
->
dentry
,
attr
->
attr
.
name
);
return
0
;
}
EXPORT_SYMBOL
(
sysfs_create_bin_file
);
...
...
fs/sysfs/mount.c
View file @
b3f00969
...
...
@@ -66,7 +66,7 @@ static struct file_system_type sysfs_fs_type = {
.
kill_sb
=
kill_litter_super
,
};
static
int
__init
sysfs_init
(
void
)
int
__init
sysfs_init
(
void
)
{
int
err
;
...
...
@@ -81,5 +81,3 @@ static int __init sysfs_init(void)
}
return
err
;
}
core_initcall
(
sysfs_init
);
include/linux/dcache.h
View file @
b3f00969
...
...
@@ -76,25 +76,25 @@ struct dentry {
atomic_t
d_count
;
unsigned
long
d_vfs_flags
;
/* moved here to be on same cacheline */
spinlock_t
d_lock
;
/* per dentry lock */
unsigned
int
d_flags
;
unsigned
long
d_move_count
;
/* to indicated moved dentry while lockless lookup */
struct
inode
*
d_inode
;
/* Where the name belongs to - NULL is negative */
struct
dentry
*
d_parent
;
/* parent directory */
struct
list_head
*
d_bucket
;
/* lookup hash bucket */
struct
list_head
d_hash
;
/* lookup hash list */
struct
list_head
d_lru
;
/* LRU list */
struct
list_head
d_child
;
/* child of parent list */
struct
list_head
d_subdirs
;
/* our children */
struct
list_head
d_alias
;
/* inode alias list */
int
d_mounted
;
struct
qstr
d_name
;
struct
qstr
*
d_qstr
;
/* quick str ptr used in lockless lookup and concurrent d_move */
unsigned
long
d_time
;
/* used by d_revalidate */
struct
dentry_operations
*
d_op
;
struct
super_block
*
d_sb
;
/* The root of the dentry tree */
unsigned
int
d_flags
;
int
d_mounted
;
void
*
d_fsdata
;
/* fs-specific data */
struct
rcu_head
d_rcu
;
struct
dcookie_struct
*
d_cookie
;
/* cookie, if any */
unsigned
long
d_move_count
;
/* to indicated moved dentry while lockless lookup */
struct
qstr
*
d_qstr
;
/* quick str ptr used in lockless lookup and concurrent d_move */
struct
dentry
*
d_parent
;
/* parent directory */
struct
qstr
d_name
;
struct
hlist_node
d_hash
;
/* lookup hash list */
struct
hlist_head
*
d_bucket
;
/* lookup hash bucket */
unsigned
char
d_iname
[
DNAME_INLINE_LEN_MIN
];
/* small names */
}
____cacheline_aligned
;
...
...
@@ -171,7 +171,7 @@ extern rwlock_t dparent_lock;
static
__inline__
void
__d_drop
(
struct
dentry
*
dentry
)
{
dentry
->
d_vfs_flags
|=
DCACHE_UNHASHED
;
list_del_rcu
(
&
dentry
->
d_hash
);
h
list_del_rcu
(
&
dentry
->
d_hash
);
}
static
__inline__
void
d_drop
(
struct
dentry
*
dentry
)
...
...
@@ -198,7 +198,7 @@ extern struct dentry * d_alloc_anon(struct inode *);
extern
struct
dentry
*
d_splice_alias
(
struct
inode
*
,
struct
dentry
*
);
extern
void
shrink_dcache_sb
(
struct
super_block
*
);
extern
void
shrink_dcache_parent
(
struct
dentry
*
);
extern
void
shrink_dcache_anon
(
struct
list_head
*
);
extern
void
shrink_dcache_anon
(
struct
h
list_head
*
);
extern
int
d_invalidate
(
struct
dentry
*
);
/* only used at mount-time */
...
...
include/linux/fs.h
View file @
b3f00969
...
...
@@ -18,6 +18,7 @@
#include <linux/stat.h>
#include <linux/cache.h>
#include <linux/radix-tree.h>
#include <linux/kobject.h>
#include <asm/atomic.h>
struct
iovec
;
...
...
@@ -353,7 +354,7 @@ struct block_device {
};
struct
inode
{
struct
list_head
i_hash
;
struct
hlist_node
i_hash
;
struct
list_head
i_list
;
struct
list_head
i_dentry
;
unsigned
long
i_ino
;
...
...
@@ -601,7 +602,7 @@ struct super_block {
struct
list_head
s_dirty
;
/* dirty inodes */
struct
list_head
s_io
;
/* parked for writeback */
struct
list_head
s_anon
;
/* anonymous dentries for (nfs) exporting */
struct
h
list_head
s_anon
;
/* anonymous dentries for (nfs) exporting */
struct
list_head
s_files
;
struct
block_device
*
s_bdev
;
...
...
@@ -610,6 +611,7 @@ struct super_block {
char
s_id
[
32
];
/* Informational name */
struct
kobject
kobj
;
/* anchor for sysfs */
void
*
s_fs_info
;
/* Filesystem private info */
/*
...
...
@@ -913,6 +915,7 @@ struct export_operations {
struct
file_system_type
{
const
char
*
name
;
struct
subsystem
subsys
;
int
fs_flags
;
struct
super_block
*
(
*
get_sb
)
(
struct
file_system_type
*
,
int
,
char
*
,
void
*
);
void
(
*
kill_sb
)
(
struct
super_block
*
);
...
...
include/linux/if_shaper.h
View file @
b3f00969
...
...
@@ -21,7 +21,7 @@ struct shaper
__u32
bitspersec
;
__u32
shapelatency
;
__u32
shapeclock
;
__u32
recovery
;
/* Time we can next clock a packet out on
unsigned
long
recovery
;
/* Time we can next clock a packet out on
an empty queue */
unsigned
long
locked
;
struct
net_device_stats
stats
;
...
...
include/linux/list.h
View file @
b3f00969
...
...
@@ -319,6 +319,98 @@ static inline void list_splice_init(struct list_head *list,
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, ({ read_barrier_depends(); 0;}), n = pos->next)
/*
* Double linked lists with a single pointer list head.
* Mostly useful for hash tables where the two pointer list head is
* too wasteful.
* You lose the ability to access the tail in O(1).
*/
struct
hlist_head
{
struct
hlist_node
*
first
;
};
struct
hlist_node
{
struct
hlist_node
*
next
,
**
pprev
;
};
#define HLIST_HEAD_INIT { .first = NULL }
#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL }
#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
#define INIT_HLIST_NODE(ptr) ((ptr)->next = NULL, (ptr)->pprev = NULL)
static
__inline__
int
hlist_unhashed
(
struct
hlist_node
*
h
)
{
return
!
h
->
pprev
;
}
static
__inline__
int
hlist_empty
(
struct
hlist_head
*
h
)
{
return
!
h
->
first
;
}
static
__inline__
void
__hlist_del
(
struct
hlist_node
*
n
)
{
struct
hlist_node
*
next
=
n
->
next
;
struct
hlist_node
**
pprev
=
n
->
pprev
;
*
pprev
=
next
;
if
(
next
)
next
->
pprev
=
pprev
;
}
static
__inline__
void
hlist_del
(
struct
hlist_node
*
n
)
{
if
(
n
->
pprev
)
__hlist_del
(
n
);
}
#define hlist_del_rcu hlist_del
/* list_del_rcu is identical too? */
static
__inline__
void
hlist_del_init
(
struct
hlist_node
*
n
)
{
if
(
n
->
pprev
)
{
__hlist_del
(
n
);
INIT_HLIST_NODE
(
n
);
}
}
static
__inline__
void
hlist_add_head
(
struct
hlist_node
*
n
,
struct
hlist_head
*
h
)
{
struct
hlist_node
*
first
=
h
->
first
;
n
->
next
=
first
;
if
(
first
)
first
->
pprev
=
&
n
->
next
;
h
->
first
=
n
;
n
->
pprev
=
&
h
->
first
;
}
static
__inline__
void
hlist_add_head_rcu
(
struct
hlist_node
*
n
,
struct
hlist_head
*
h
)
{
struct
hlist_node
*
first
=
h
->
first
;
n
->
next
=
first
;
n
->
pprev
=
&
h
->
first
;
smp_wmb
();
if
(
first
)
first
->
pprev
=
&
n
->
next
;
h
->
first
=
n
;
}
/* next must be != NULL */
static
__inline__
void
hlist_add_before
(
struct
hlist_node
*
n
,
struct
hlist_node
*
next
)
{
n
->
pprev
=
next
->
pprev
;
n
->
next
=
next
;
next
->
pprev
=
&
n
->
next
;
*
(
n
->
pprev
)
=
n
;
}
#define hlist_entry(ptr, type, member) container_of(ptr,type,member)
/* Cannot easily do prefetch unfortunately */
#define hlist_for_each(pos, head) \
for (pos = (head)->first; pos; \
pos = pos->next)
#else
#warning "don't include kernel headers in userspace"
#endif
/* __KERNEL__ */
...
...
include/linux/tty.h
View file @
b3f00969
...
...
@@ -294,7 +294,7 @@ struct tty_struct {
unsigned
char
lnext
:
1
,
erasing
:
1
,
raw
:
1
,
real_raw
:
1
,
icanon
:
1
;
unsigned
char
closing
:
1
;
unsigned
short
minimum_to_wake
;
unsigned
overrun_time
;
unsigned
long
overrun_time
;
int
num_overrun
;
unsigned
long
process_char_map
[
256
/
(
8
*
sizeof
(
unsigned
long
))];
char
*
read_buf
;
...
...
init/main.c
View file @
b3f00969
...
...
@@ -71,6 +71,7 @@ extern void pte_chain_init(void);
extern
void
radix_tree_init
(
void
);
extern
void
free_initmem
(
void
);
extern
void
populate_rootfs
(
void
);
extern
void
driver_init
(
void
);
#ifdef CONFIG_TC
extern
void
tc_init
(
void
);
...
...
@@ -476,6 +477,8 @@ static void __init do_initcalls(void)
*/
static
void
__init
do_basic_setup
(
void
)
{
driver_init
();
#ifdef CONFIG_SYSCTL
sysctl_init
();
#endif
...
...
net/sunrpc/rpc_pipe.c
View file @
b3f00969
...
...
@@ -479,7 +479,7 @@ static void
rpc_depopulate
(
struct
dentry
*
parent
)
{
struct
inode
*
dir
=
parent
->
d_inode
;
LIST_HEAD
(
head
);
H
LIST_HEAD
(
head
);
struct
list_head
*
pos
,
*
next
;
struct
dentry
*
dentry
;
...
...
@@ -490,12 +490,12 @@ rpc_depopulate(struct dentry *parent)
if
(
!
d_unhashed
(
dentry
))
{
dget_locked
(
dentry
);
__d_drop
(
dentry
);
list_ad
d
(
&
dentry
->
d_hash
,
&
head
);
hlist_add_hea
d
(
&
dentry
->
d_hash
,
&
head
);
}
}
spin_unlock
(
&
dcache_lock
);
while
(
!
list_empty
(
&
head
))
{
dentry
=
list_entry
(
head
.
nex
t
,
struct
dentry
,
d_hash
);
while
(
!
h
list_empty
(
&
head
))
{
dentry
=
list_entry
(
head
.
firs
t
,
struct
dentry
,
d_hash
);
/* Private list, so no dcache_lock needed and use __d_drop */
__d_drop
(
dentry
);
if
(
dentry
->
d_inode
)
{
...
...
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