Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
07900f7a
Commit
07900f7a
authored
Jun 08, 2002
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://ldm.bkbits.net/linux-2.5
into home.transmeta.com:/home/torvalds/v2.5/linux
parents
6bd20e27
59fb29c6
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
64 additions
and
51 deletions
+64
-51
drivers/base/base.h
drivers/base/base.h
+2
-2
drivers/base/bus.c
drivers/base/bus.c
+3
-2
drivers/base/core.c
drivers/base/core.c
+41
-26
drivers/base/driver.c
drivers/base/driver.c
+14
-17
drivers/pci/pci-driver.c
drivers/pci/pci-driver.c
+3
-3
include/linux/device.h
include/linux/device.h
+1
-1
No files found.
drivers/base/base.h
View file @
07900f7a
...
...
@@ -18,5 +18,5 @@ extern void device_remove_dir(struct device * dev);
extern
int
device_bus_link
(
struct
device
*
dev
);
extern
int
driver_
bind
(
struct
device_driver
*
drv
);
extern
void
driver_
unbind
(
struct
device_driver
*
drv
);
extern
int
driver_
attach
(
struct
device_driver
*
drv
);
extern
void
driver_
detach
(
struct
device_driver
*
drv
);
drivers/base/bus.c
View file @
07900f7a
...
...
@@ -167,12 +167,13 @@ static int bus_make_dir(struct bus_type * bus)
int
bus_register
(
struct
bus_type
*
bus
)
{
spin_lock
(
&
device_lock
);
rwlock_init
(
&
bus
->
lock
);
INIT_LIST_HEAD
(
&
bus
->
devices
);
INIT_LIST_HEAD
(
&
bus
->
drivers
);
list_add_tail
(
&
bus
->
node
,
&
bus_driver_list
);
atomic_set
(
&
bus
->
refcount
,
2
);
spin_lock
(
&
device_lock
);
list_add_tail
(
&
bus
->
node
,
&
bus_driver_list
);
spin_unlock
(
&
device_lock
);
pr_debug
(
"bus type '%s' registered
\n
"
,
bus
->
name
);
...
...
drivers/base/core.c
View file @
07900f7a
...
...
@@ -31,7 +31,7 @@ spinlock_t device_lock = SPIN_LOCK_UNLOCKED;
* @dev: device
* @drv: driver
*
* We're here because the bus's
bind
callback returned success for this
* We're here because the bus's
match
callback returned success for this
* pair. We call the driver's probe callback to verify they're really a
* match made in heaven.
*
...
...
@@ -67,60 +67,74 @@ static int found_match(struct device * dev, struct device_driver * drv)
}
/**
*
bind_device
- try to associated device with a driver
*
device_attach
- try to associated device with a driver
* @drv: current driver to try
* @data: device in disguise
*
* This function is used as a callback to bus_for_each_drv.
* It calls the bus's
::bind
callback to check if the driver supports
* It calls the bus's
match
callback to check if the driver supports
* the device. If so, it calls the found_match() function above to
* take care of all the details.
*/
static
int
do_device_
bind
(
struct
device_driver
*
drv
,
void
*
data
)
static
int
do_device_
attach
(
struct
device_driver
*
drv
,
void
*
data
)
{
struct
device
*
dev
=
(
struct
device
*
)
data
;
int
error
=
0
;
if
(
!
dev
->
driver
)
{
if
(
drv
->
bus
->
bind
&&
drv
->
bus
->
bind
(
dev
,
drv
))
if
(
drv
->
bus
->
match
&&
drv
->
bus
->
match
(
dev
,
drv
))
error
=
found_match
(
dev
,
drv
);
}
return
error
;
}
static
int
device_
bind
(
struct
device
*
dev
)
static
int
device_
attach
(
struct
device
*
dev
)
{
int
error
=
0
;
if
(
dev
->
bus
)
error
=
bus_for_each_drv
(
dev
->
bus
,
dev
,
do_device_
bind
);
error
=
bus_for_each_drv
(
dev
->
bus
,
dev
,
do_device_
attach
);
return
error
;
}
static
void
device_
unbind
(
struct
device
*
dev
)
static
void
device_
detach
(
struct
device
*
dev
)
{
/* unbind from driver */
if
(
dev
->
driver
&&
dev
->
driver
->
remove
)
dev
->
driver
->
remove
(
dev
);
struct
device_driver
*
drv
;
if
(
dev
->
driver
)
{
lock_device
(
dev
);
drv
=
dev
->
driver
;
dev
->
driver
=
NULL
;
unlock_device
(
dev
);
write_lock
(
&
drv
->
lock
);
list_del_init
(
&
dev
->
driver_list
);
write_unlock
(
&
drv
->
lock
);
/* detach from driver */
if
(
drv
->
remove
)
drv
->
remove
(
dev
);
put_driver
(
drv
);
}
}
static
int
do_driver_
bind
(
struct
device
*
dev
,
void
*
data
)
static
int
do_driver_
attach
(
struct
device
*
dev
,
void
*
data
)
{
struct
device_driver
*
drv
=
(
struct
device_driver
*
)
data
;
int
error
=
0
;
if
(
!
dev
->
driver
)
{
if
(
dev
->
bus
->
bind
&&
dev
->
bus
->
bind
(
dev
,
drv
))
if
(
dev
->
bus
->
match
&&
dev
->
bus
->
match
(
dev
,
drv
))
error
=
found_match
(
dev
,
drv
);
}
return
error
;
}
int
driver_
bind
(
struct
device_driver
*
drv
)
int
driver_
attach
(
struct
device_driver
*
drv
)
{
return
bus_for_each_dev
(
drv
->
bus
,
drv
,
do_driver_
bind
);
return
bus_for_each_dev
(
drv
->
bus
,
drv
,
do_driver_
attach
);
}
static
int
do_driver_
unbind
(
struct
device
*
dev
,
struct
device_driver
*
drv
)
static
int
do_driver_
detach
(
struct
device
*
dev
,
struct
device_driver
*
drv
)
{
lock_device
(
dev
);
if
(
dev
->
driver
==
drv
)
{
...
...
@@ -133,31 +147,32 @@ static int do_driver_unbind(struct device * dev, struct device_driver * drv)
return
0
;
}
void
driver_
unbind
(
struct
device_driver
*
drv
)
void
driver_
detach
(
struct
device_driver
*
drv
)
{
struct
device
*
next
;
struct
device
*
dev
=
NULL
;
struct
list_head
*
node
;
int
error
=
0
;
read
_lock
(
&
drv
->
lock
);
write
_lock
(
&
drv
->
lock
);
node
=
drv
->
devices
.
next
;
while
(
node
!=
&
drv
->
devices
)
{
next
=
list_entry
(
node
,
struct
device
,
driver_list
);
get_device
(
next
);
read_unlock
(
&
drv
->
lock
);
list_del_init
(
&
next
->
driver_list
);
write_unlock
(
&
drv
->
lock
);
if
(
dev
)
put_device
(
dev
);
dev
=
next
;
if
((
error
=
do_driver_
unbind
(
dev
,
drv
)))
{
if
((
error
=
do_driver_
detach
(
dev
,
drv
)))
{
put_device
(
dev
);
break
;
}
read
_lock
(
&
drv
->
lock
);
node
=
d
ev
->
driver_list
.
next
;
write
_lock
(
&
drv
->
lock
);
node
=
d
rv
->
devices
.
next
;
}
read
_unlock
(
&
drv
->
lock
);
write
_unlock
(
&
drv
->
lock
);
if
(
dev
)
put_device
(
dev
);
}
...
...
@@ -181,13 +196,13 @@ int device_register(struct device *dev)
if
(
!
dev
||
!
strlen
(
dev
->
bus_id
))
return
-
EINVAL
;
spin_lock
(
&
device_lock
);
INIT_LIST_HEAD
(
&
dev
->
node
);
INIT_LIST_HEAD
(
&
dev
->
children
);
INIT_LIST_HEAD
(
&
dev
->
g_list
);
spin_lock_init
(
&
dev
->
lock
);
atomic_set
(
&
dev
->
refcount
,
2
);
spin_lock
(
&
device_lock
);
if
(
dev
!=
&
device_root
)
{
if
(
!
dev
->
parent
)
dev
->
parent
=
&
device_root
;
...
...
@@ -212,7 +227,7 @@ int device_register(struct device *dev)
bus_add_device
(
dev
);
/* bind to driver */
device_
bind
(
dev
);
device_
attach
(
dev
);
/* notify platform of device entry */
if
(
platform_notify
)
...
...
@@ -246,7 +261,7 @@ void put_device(struct device * dev)
if
(
platform_notify_remove
)
platform_notify_remove
(
dev
);
device_
unbind
(
dev
);
device_
detach
(
dev
);
bus_remove_device
(
dev
);
/* remove the driverfs directory */
...
...
drivers/base/driver.c
View file @
07900f7a
...
...
@@ -74,33 +74,27 @@ int driver_register(struct device_driver * drv)
list_add
(
&
drv
->
bus_list
,
&
drv
->
bus
->
drivers
);
write_unlock
(
&
drv
->
bus
->
lock
);
driver_make_dir
(
drv
);
driver_
bind
(
drv
);
driver_
attach
(
drv
);
put_driver
(
drv
);
return
0
;
}
static
void
__remove_driver
(
struct
device_driver
*
drv
)
{
if
(
drv
->
bus
)
{
pr_debug
(
"Unregistering driver '%s' from bus '%s'
\n
"
,
drv
->
name
,
drv
->
bus
->
name
);
driver_unbind
(
drv
);
write_lock
(
&
drv
->
bus
->
lock
);
list_del_init
(
&
drv
->
bus_list
);
write_unlock
(
&
drv
->
bus
->
lock
);
driverfs_remove_dir
(
&
drv
->
dir
);
put_bus
(
drv
->
bus
);
}
pr_debug
(
"Unregistering driver '%s' from bus '%s'
\n
"
,
drv
->
name
,
drv
->
bus
->
name
);
driver_detach
(
drv
);
driverfs_remove_dir
(
&
drv
->
dir
);
if
(
drv
->
release
)
drv
->
release
(
drv
);
put_bus
(
drv
->
bus
);
}
void
remove_driver
(
struct
device_driver
*
drv
)
{
spin_lock
(
&
device_
lock
);
write_lock
(
&
drv
->
bus
->
lock
);
atomic_set
(
&
drv
->
refcount
,
0
);
spin_unlock
(
&
device_lock
);
list_del_init
(
&
drv
->
bus_list
);
write_unlock
(
&
drv
->
bus
->
lock
);
__remove_driver
(
drv
);
}
...
...
@@ -110,10 +104,13 @@ void remove_driver(struct device_driver * drv)
*/
void
put_driver
(
struct
device_driver
*
drv
)
{
if
(
!
atomic_dec_and_lock
(
&
drv
->
refcount
,
&
device_lock
))
write_lock
(
&
drv
->
bus
->
lock
);
if
(
!
atomic_dec_and_test
(
&
drv
->
refcount
))
{
write_unlock
(
&
drv
->
bus
->
lock
);
return
;
spin_unlock
(
&
device_lock
);
}
list_del_init
(
&
drv
->
bus_list
);
write_unlock
(
&
drv
->
bus
->
lock
);
__remove_driver
(
drv
);
}
...
...
drivers/pci/pci-driver.c
View file @
07900f7a
...
...
@@ -165,7 +165,7 @@ pci_dev_driver(const struct pci_dev *dev)
}
/**
* pci_bus_
bind
- Tell if a PCI device structure has a matching PCI device id structure
* pci_bus_
match
- Tell if a PCI device structure has a matching PCI device id structure
* @ids: array of PCI device id structures to search in
* @dev: the PCI device structure to match against
*
...
...
@@ -173,7 +173,7 @@ pci_dev_driver(const struct pci_dev *dev)
* system is in its list of supported devices.Returns the matching
* pci_device_id structure or %NULL if there is no match.
*/
static
int
pci_bus_
bind
(
struct
device
*
dev
,
struct
device_driver
*
drv
)
static
int
pci_bus_
match
(
struct
device
*
dev
,
struct
device_driver
*
drv
)
{
struct
pci_dev
*
pci_dev
=
list_entry
(
dev
,
struct
pci_dev
,
dev
);
struct
pci_driver
*
pci_drv
=
list_entry
(
drv
,
struct
pci_driver
,
driver
);
...
...
@@ -196,7 +196,7 @@ static int pci_bus_bind(struct device * dev, struct device_driver * drv)
struct
bus_type
pci_bus_type
=
{
name:
"pci"
,
bind:
pci_bus_bind
,
match:
pci_bus_match
,
};
static
int
__init
pci_driver_init
(
void
)
...
...
include/linux/device.h
View file @
07900f7a
...
...
@@ -64,7 +64,7 @@ struct bus_type {
struct
driver_dir_entry
device_dir
;
struct
driver_dir_entry
driver_dir
;
int
(
*
bind
)
(
struct
device
*
dev
,
struct
device_driver
*
drv
);
int
(
*
match
)
(
struct
device
*
dev
,
struct
device_driver
*
drv
);
};
...
...
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