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
26abb0a1
Commit
26abb0a1
authored
Feb 16, 2004
by
Ben Collins
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
IEEE1394(r1129): Initial support for reusing node entries over plug/unplug cycles
parent
93f136bc
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
205 additions
and
86 deletions
+205
-86
drivers/ieee1394/ieee1394_core.c
drivers/ieee1394/ieee1394_core.c
+2
-0
drivers/ieee1394/nodemgr.c
drivers/ieee1394/nodemgr.c
+197
-86
drivers/ieee1394/nodemgr.h
drivers/ieee1394/nodemgr.h
+6
-0
No files found.
drivers/ieee1394/ieee1394_core.c
View file @
26abb0a1
...
...
@@ -1008,6 +1008,7 @@ static int __init ieee1394_init(void)
0
,
0
,
NULL
,
NULL
);
bus_register
(
&
ieee1394_bus_type
);
bus_create_file
(
&
ieee1394_bus_type
,
&
bus_attr_destroy
);
if
(
init_csr
())
return
-
ENOMEM
;
...
...
@@ -1027,6 +1028,7 @@ static void __exit ieee1394_cleanup(void)
cleanup_csr
();
bus_remove_file
(
&
ieee1394_bus_type
,
&
bus_attr_destroy
);
bus_unregister
(
&
ieee1394_bus_type
);
kmem_cache_destroy
(
hpsb_packet_cache
);
...
...
drivers/ieee1394/nodemgr.c
View file @
26abb0a1
...
...
@@ -105,7 +105,6 @@ static struct csr1212_bus_ops nodemgr_csr_ops = {
static
DECLARE_MUTEX
(
nodemgr_serialize
);
struct
host_info
{
struct
hpsb_host
*
host
;
struct
list_head
list
;
...
...
@@ -115,19 +114,92 @@ struct host_info {
char
daemon_name
[
15
];
};
static
int
nodemgr_bus_match
(
struct
device
*
dev
,
struct
device_driver
*
drv
);
static
int
nodemgr_hotplug
(
struct
device
*
dev
,
char
**
envp
,
int
num_envp
,
char
*
buffer
,
int
buffer_size
);
static
void
nodemgr_resume_ne
(
struct
node_entry
*
ne
);
static
void
nodemgr_remove_ne
(
struct
node_entry
*
ne
);
static
struct
node_entry
*
find_entry_by_guid
(
u64
guid
);
struct
bus_type
ieee1394_bus_type
=
{
.
name
=
"ieee1394"
,
.
match
=
nodemgr_bus_match
,
.
hotplug
=
nodemgr_hotplug
,
};
static
struct
hpsb_highlevel
nodemgr_highlevel
;
static
int
nodemgr_driverdata_ne
;
static
int
nodemgr_driverdata_host
;
static
int
nodemgr_platform_data_ne
;
static
int
nodemgr_platform_data_ud
;
static
int
nodemgr_platform_data_host
;
static
int
nodemgr_generic_probe
(
struct
device
*
dev
)
{
return
-
ENODEV
;
}
static
struct
device_driver
nodemgr_driver_ne
=
{
.
name
=
"ieee1394_node"
,
.
bus
=
&
ieee1394_bus_type
,
.
probe
=
nodemgr_generic_probe
,
};
static
struct
device_driver
nodemgr_driver_host
=
{
.
name
=
"ieee1394_host"
,
.
bus
=
&
ieee1394_bus_type
,
.
probe
=
nodemgr_generic_probe
,
};
static
void
nodemgr_release_ud
(
struct
device
*
dev
)
{
struct
unit_directory
*
ud
=
container_of
(
dev
,
struct
unit_directory
,
device
);
if
(
ud
->
vendor_name_kv
)
csr1212_release_keyval
(
ud
->
vendor_name_kv
);
if
(
ud
->
model_name_kv
)
csr1212_release_keyval
(
ud
->
model_name_kv
);
kfree
(
ud
);
}
static
void
nodemgr_release_ne
(
struct
device
*
dev
)
{
struct
node_entry
*
ne
=
container_of
(
dev
,
struct
node_entry
,
device
);
if
(
ne
->
vendor_name_kv
)
csr1212_release_keyval
(
ne
->
vendor_name_kv
);
kfree
(
ne
);
}
static
void
nodemgr_release_host
(
struct
device
*
dev
)
{
struct
hpsb_host
*
host
=
container_of
(
dev
,
struct
hpsb_host
,
device
);
csr1212_destroy_csr
(
host
->
csr
.
rom
);
kfree
(
host
);
}
static
struct
device
nodemgr_dev_template_ud
=
{
.
bus
=
&
ieee1394_bus_type
,
.
release
=
nodemgr_release_ud
,
.
platform_data
=
&
nodemgr_platform_data_ud
,
};
static
struct
device
nodemgr_dev_template_ne
=
{
.
bus
=
&
ieee1394_bus_type
,
.
release
=
nodemgr_release_ne
,
.
driver
=
&
nodemgr_driver_ne
,
.
platform_data
=
&
nodemgr_platform_data_ne
,
};
struct
device
nodemgr_dev_template_host
=
{
.
bus
=
&
ieee1394_bus_type
,
.
release
=
nodemgr_release_host
,
.
driver
=
&
nodemgr_driver_host
,
.
platform_data
=
&
nodemgr_platform_data_host
,
};
...
...
@@ -221,6 +293,27 @@ static ssize_t fw_show_ne_tlabels_mask(struct device *dev, char *buf)
static
DEVICE_ATTR
(
tlabels_mask
,
S_IRUGO
,
fw_show_ne_tlabels_mask
,
NULL
);
static
ssize_t
fw_set_destroy
(
struct
bus_type
*
bus
,
const
char
*
buf
,
size_t
count
)
{
struct
node_entry
*
ne
;
u64
guid
=
(
u64
)
simple_strtoull
(
buf
,
NULL
,
16
);
ne
=
find_entry_by_guid
(
guid
);
if
(
ne
==
NULL
||
!
ne
->
in_limbo
)
return
-
EINVAL
;
nodemgr_remove_ne
(
ne
);
return
count
;
}
static
ssize_t
fw_get_destroy
(
struct
bus_type
*
bus
,
char
*
buf
)
{
return
sprintf
(
buf
,
"You can destroy in_limbo nodes by writing their GUID to this file
\n
"
);
}
BUS_ATTR
(
destroy
,
S_IWUGO
|
S_IRUGO
,
fw_get_destroy
,
fw_set_destroy
);
fw_attr
(
ne
,
struct
node_entry
,
capabilities
,
unsigned
int
,
"0x%06x
\n
"
)
fw_attr
(
ne
,
struct
node_entry
,
nodeid
,
unsigned
int
,
"0x%04x
\n
"
)
...
...
@@ -231,6 +324,7 @@ fw_attr(ne, struct node_entry, vendor_oui, const char *, "%s\n")
fw_attr
(
ne
,
struct
node_entry
,
guid
,
unsigned
long
long
,
"0x%016Lx
\n
"
)
fw_attr
(
ne
,
struct
node_entry
,
guid_vendor_id
,
unsigned
int
,
"0x%06x
\n
"
)
fw_attr
(
ne
,
struct
node_entry
,
guid_vendor_oui
,
const
char
*
,
"%s
\n
"
)
fw_attr
(
ne
,
struct
node_entry
,
in_limbo
,
int
,
"%d
\n
"
);
static
struct
device_attribute
*
const
fw_ne_attrs
[]
=
{
&
dev_attr_ne_guid
,
...
...
@@ -435,14 +529,17 @@ static int nodemgr_bus_match(struct device * dev, struct device_driver * drv)
struct
unit_directory
*
ud
;
struct
ieee1394_device_id
*
id
;
if
(
dev
->
driver_data
==
&
nodemgr_driverdata_ne
||
dev
->
driver_data
==
&
nodemgr_driverdata_host
||
drv
==
&
nodemgr_driver_ne
||
drv
==
&
nodemgr_driver_host
)
/* We only match unit directories, and ignore our internal drivers */
if
(
dev
->
platform_data
!=
&
nodemgr_platform_data_ud
||
drv
->
probe
==
nodemgr_generic_probe
)
return
0
;
ud
=
container_of
(
dev
,
struct
unit_directory
,
device
);
driver
=
container_of
(
drv
,
struct
hpsb_protocol_driver
,
driver
);
if
(
ud
->
ne
->
in_limbo
)
return
0
;
for
(
id
=
driver
->
id_table
;
id
->
match_flags
!=
0
;
id
++
)
{
if
((
id
->
match_flags
&
IEEE1394_MATCH_VENDOR_ID
)
&&
id
->
vendor_id
!=
ud
->
vendor_id
)
...
...
@@ -467,34 +564,6 @@ static int nodemgr_bus_match(struct device * dev, struct device_driver * drv)
}
static
void
nodemgr_release_ud
(
struct
device
*
dev
)
{
struct
unit_directory
*
ud
=
container_of
(
dev
,
struct
unit_directory
,
device
);
if
(
ud
->
vendor_name_kv
)
csr1212_release_keyval
(
ud
->
vendor_name_kv
);
if
(
ud
->
model_name_kv
)
csr1212_release_keyval
(
ud
->
model_name_kv
);
kfree
(
container_of
(
dev
,
struct
unit_directory
,
device
));
}
static
void
nodemgr_release_ne
(
struct
device
*
dev
)
{
struct
node_entry
*
ne
=
container_of
(
dev
,
struct
node_entry
,
device
);
if
(
ne
->
vendor_name_kv
)
csr1212_release_keyval
(
ne
->
vendor_name_kv
);
kfree
(
container_of
(
dev
,
struct
node_entry
,
device
));
}
static
void
nodemgr_release_host
(
struct
device
*
dev
)
{
struct
hpsb_host
*
host
=
container_of
(
dev
,
struct
hpsb_host
,
device
);
csr1212_destroy_csr
(
host
->
csr
.
rom
);
kfree
(
container_of
(
dev
,
struct
hpsb_host
,
device
));
}
static
void
nodemgr_remove_ud
(
struct
unit_directory
*
ud
)
{
struct
device
*
dev
=
&
ud
->
device
;
...
...
@@ -539,6 +608,9 @@ static void nodemgr_remove_ne(struct node_entry *ne)
struct
device
*
dev
=
&
ne
->
device
;
int
i
;
HPSB_DEBUG
(
"Node removed: ID:BUS["
NODE_BUS_FMT
"] GUID[%016Lx]"
,
NODE_BUS_ARGS
(
ne
->
host
,
ne
->
nodeid
),
(
unsigned
long
long
)
ne
->
guid
);
nodemgr_remove_node_uds
(
ne
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
fw_ne_attrs
);
i
++
)
...
...
@@ -547,6 +619,7 @@ static void nodemgr_remove_ne(struct node_entry *ne)
device_remove_file
(
dev
,
&
dev_attr_ne_guid_vendor_oui
);
device_remove_file
(
dev
,
&
dev_attr_ne_vendor_name_kv
);
device_remove_file
(
dev
,
&
dev_attr_ne_vendor_oui
);
device_remove_file
(
dev
,
&
dev_attr_ne_in_limbo
);
device_unregister
(
dev
);
}
...
...
@@ -572,38 +645,6 @@ static void nodemgr_remove_host_dev(struct device *dev)
}
static
struct
device
nodemgr_dev_template_ud
=
{
.
bus
=
&
ieee1394_bus_type
,
.
release
=
nodemgr_release_ud
,
};
static
struct
device
nodemgr_dev_template_ne
=
{
.
bus
=
&
ieee1394_bus_type
,
.
release
=
nodemgr_release_ne
,
.
driver
=
&
nodemgr_driver_ne
,
.
driver_data
=
&
nodemgr_driverdata_ne
,
};
struct
device
nodemgr_dev_template_host
=
{
.
bus
=
&
ieee1394_bus_type
,
.
release
=
nodemgr_release_host
,
.
driver
=
&
nodemgr_driver_host
,
.
driver_data
=
&
nodemgr_driverdata_host
,
};
static
int
nodemgr_hotplug
(
struct
device
*
dev
,
char
**
envp
,
int
num_envp
,
char
*
buffer
,
int
buffer_size
);
struct
bus_type
ieee1394_bus_type
=
{
.
name
=
"ieee1394"
,
.
match
=
nodemgr_bus_match
,
.
hotplug
=
nodemgr_hotplug
,
};
static
void
nodemgr_update_bus_options
(
struct
node_entry
*
ne
)
{
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
...
...
@@ -688,7 +729,7 @@ static int nodemgr_guid_search_cb(struct device *dev, void *__data)
struct
guid_search_baton
*
search
=
__data
;
struct
node_entry
*
ne
;
if
(
dev
->
driver_data
!=
&
nodemgr_driver
data_ne
)
if
(
dev
->
platform_data
!=
&
nodemgr_platform_
data_ne
)
return
0
;
ne
=
container_of
(
dev
,
struct
node_entry
,
device
);
...
...
@@ -725,7 +766,7 @@ static int nodemgr_nodeid_search_cb(struct device *dev, void *__data)
struct
nodeid_search_baton
*
search
=
__data
;
struct
node_entry
*
ne
;
if
(
dev
->
driver_data
!=
&
nodemgr_driver
data_ne
)
if
(
dev
->
platform_data
!=
&
nodemgr_platform_
data_ne
)
return
0
;
ne
=
container_of
(
dev
,
struct
node_entry
,
device
);
...
...
@@ -962,13 +1003,14 @@ static int nodemgr_hotplug(struct device *dev, char **envp, int num_envp,
if
(
!
dev
)
return
-
ENODEV
;
/* Have to check driver_data, since on remove, driver == NULL */
if
(
dev
->
driver_data
==
&
nodemgr_driverdata_ne
||
dev
->
driver_data
==
&
nodemgr_driverdata_host
)
if
(
dev
->
platform_data
!=
&
nodemgr_platform_data_ud
)
return
-
ENODEV
;
ud
=
container_of
(
dev
,
struct
unit_directory
,
device
);
if
(
ud
->
ne
->
in_limbo
)
return
-
ENODEV
;
scratch
=
buffer
;
#define PUT_ENVP(fmt,val) \
...
...
@@ -1073,6 +1115,9 @@ static void nodemgr_update_node(struct node_entry *ne, struct csr1212_csr *csr,
ne
->
needs_probe
=
1
;
}
if
(
ne
->
in_limbo
)
nodemgr_resume_ne
(
ne
);
/* Mark the node current */
ne
->
generation
=
generation
;
}
...
...
@@ -1125,6 +1170,12 @@ static void nodemgr_node_scan_one(struct host_info *hi,
guid
=
((
u64
)
be32_to_cpu
(
csr
->
bus_info_data
[
3
])
<<
32
)
|
be32_to_cpu
(
csr
->
bus_info_data
[
4
]);
ne
=
find_entry_by_guid
(
guid
);
if
(
ne
->
host
!=
host
&&
ne
->
in_limbo
)
{
/* Must have moved this device from one host to another */
nodemgr_remove_ne
(
ne
);
ne
=
NULL
;
}
if
(
!
ne
)
nodemgr_create_node
(
guid
,
csr
,
hi
,
nodeid
,
generation
);
else
...
...
@@ -1140,17 +1191,17 @@ struct cleanup_baton {
struct
node_entry
*
ne
;
};
static
int
nodemgr_
remove_node
(
struct
device
*
dev
,
void
*
__data
)
static
int
nodemgr_
check_node_cb
(
struct
device
*
dev
,
void
*
__data
)
{
struct
cleanup_baton
*
cleanup
=
__data
;
struct
node_entry
*
ne
;
if
(
dev
->
driver_data
!=
&
nodemgr_driver
data_ne
)
if
(
dev
->
platform_data
!=
&
nodemgr_platform_
data_ne
)
return
0
;
ne
=
container_of
(
dev
,
struct
node_entry
,
device
);
if
(
ne
->
host
!=
cleanup
->
host
)
if
(
ne
->
in_limbo
||
ne
->
host
!=
cleanup
->
host
)
return
0
;
if
(
ne
->
generation
!=
cleanup
->
generation
)
{
...
...
@@ -1172,12 +1223,12 @@ static int nodemgr_probe_ne_cb(struct device *dev, void *__data)
struct
host_info
*
hi
=
ne_cb_data
->
hi
;
struct
node_entry
*
ne
;
if
(
dev
->
driver_data
!=
&
nodemgr_driver
data_ne
)
if
(
dev
->
platform_data
!=
&
nodemgr_platform_
data_ne
)
return
0
;
ne
=
ne_cb_data
->
ne
=
container_of
(
dev
,
struct
node_entry
,
device
);
if
(
ne
->
host
!=
hi
->
host
)
if
(
ne
->
host
!=
hi
->
host
||
ne
->
in_limbo
)
return
0
;
/* We can't call nodemgr_process_root_directory() here because
...
...
@@ -1232,6 +1283,72 @@ static void nodemgr_node_scan(struct host_info *hi, int generation)
}
}
static
void
nodemgr_suspend_ud
(
struct
unit_directory
*
ud
)
{
struct
device
*
dev
;
list_for_each_entry
(
dev
,
&
ud
->
device
.
children
,
node
)
nodemgr_suspend_ud
(
container_of
(
dev
,
struct
unit_directory
,
device
));
if
(
ud
->
device
.
driver
)
{
int
ret
=
-
1
;
if
(
ud
->
device
.
driver
->
suspend
)
ret
=
ud
->
device
.
driver
->
suspend
(
&
ud
->
device
,
0
,
0
);
if
(
ret
)
{
dev
=
&
ud
->
device
;
down_write
(
&
dev
->
bus
->
subsys
.
rwsem
);
device_release_driver
(
dev
);
up_write
(
&
dev
->
bus
->
subsys
.
rwsem
);
}
}
}
static
void
nodemgr_suspend_ne
(
struct
node_entry
*
ne
)
{
struct
device
*
dev
;
HPSB_DEBUG
(
"Node suspended: ID:BUS["
NODE_BUS_FMT
"] GUID[%016Lx]"
,
NODE_BUS_ARGS
(
ne
->
host
,
ne
->
nodeid
),
(
unsigned
long
long
)
ne
->
guid
);
ne
->
in_limbo
=
1
;
device_create_file
(
&
ne
->
device
,
&
dev_attr_ne_in_limbo
);
list_for_each_entry
(
dev
,
&
ne
->
device
.
children
,
node
)
nodemgr_suspend_ud
(
container_of
(
dev
,
struct
unit_directory
,
device
));
}
static
void
nodemgr_resume_ud
(
struct
unit_directory
*
ud
)
{
struct
device
*
dev
;
list_for_each_entry
(
dev
,
&
ud
->
device
.
children
,
node
)
nodemgr_resume_ud
(
container_of
(
dev
,
struct
unit_directory
,
device
));
if
(
ud
->
device
.
driver
&&
ud
->
device
.
driver
->
resume
)
ud
->
device
.
driver
->
resume
(
&
ud
->
device
,
0
);
}
static
void
nodemgr_resume_ne
(
struct
node_entry
*
ne
)
{
struct
device
*
dev
;
ne
->
in_limbo
=
0
;
device_remove_file
(
&
ne
->
device
,
&
dev_attr_ne_in_limbo
);
list_for_each_entry
(
dev
,
&
ne
->
device
.
children
,
node
)
nodemgr_resume_ud
(
container_of
(
dev
,
struct
unit_directory
,
device
));
HPSB_DEBUG
(
"Node resumed: ID:BUS["
NODE_BUS_FMT
"] GUID[%016Lx]"
,
NODE_BUS_ARGS
(
ne
->
host
,
ne
->
nodeid
),
(
unsigned
long
long
)
ne
->
guid
);
}
static
void
nodemgr_node_probe
(
struct
host_info
*
hi
,
int
generation
)
{
struct
hpsb_host
*
host
=
hi
->
host
;
...
...
@@ -1269,16 +1386,10 @@ static void nodemgr_node_probe(struct host_info *hi, int generation)
cleanup
.
host
=
host
;
/* This will iterate until all devices that do not match
* the generation are
remov
ed. */
* the generation are
suspend
ed. */
while
(
bus_for_each_dev
(
&
ieee1394_bus_type
,
NULL
,
&
cleanup
,
nodemgr_remove_node
))
{
struct
node_entry
*
ne
=
cleanup
.
ne
;
HPSB_DEBUG
(
"Node removed: ID:BUS["
NODE_BUS_FMT
"] GUID[%016Lx]"
,
NODE_BUS_ARGS
(
host
,
ne
->
nodeid
),
(
unsigned
long
long
)
ne
->
guid
);
nodemgr_remove_ne
(
ne
);
}
nodemgr_check_node_cb
))
nodemgr_suspend_ne
(
cleanup
.
ne
);
/* Now let's tell the bus to rescan our devices. This may
* seem like overhead, but the driver-model core will only
...
...
@@ -1486,7 +1597,7 @@ static int nodemgr_for_each_host_cb(struct device *dev, void *__data)
struct
for_each_host_struct
*
host_data
=
__data
;
struct
hpsb_host
*
host
;
if
(
dev
->
driver_data
!=
&
nodemgr_driver
data_host
)
if
(
dev
->
platform_data
!=
&
nodemgr_platform_
data_host
)
return
0
;
host
=
container_of
(
dev
,
struct
hpsb_host
,
device
);
...
...
drivers/ieee1394/nodemgr.h
View file @
26abb0a1
...
...
@@ -101,6 +101,9 @@ struct node_entry {
struct
device
device
;
/* Means this node is not attached anymore */
int
in_limbo
;
struct
csr1212_csr
*
csr
;
};
...
...
@@ -188,4 +191,7 @@ void cleanup_ieee1394_nodemgr(void);
/* The template for a host device */
extern
struct
device
nodemgr_dev_template_host
;
/* Bus attribute to destroy limbo'd nodes */
extern
struct
bus_attribute
bus_attr_destroy
;
#endif
/* _IEEE1394_NODEMGR_H */
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