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
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