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
9f7d733d
Commit
9f7d733d
authored
Aug 25, 2004
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://kernel.bkbits.net/gregkh/linux/driver-2.6
into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents
ec03a9f4
18788716
Changes
31
Show whitespace changes
Inline
Side-by-side
Showing
31 changed files
with
259 additions
and
223 deletions
+259
-223
CREDITS
CREDITS
+6
-0
Documentation/driver-model/bus.txt
Documentation/driver-model/bus.txt
+21
-53
Documentation/i2c/sysfs-interface
Documentation/i2c/sysfs-interface
+1
-1
MAINTAINERS
MAINTAINERS
+30
-0
drivers/base/class.c
drivers/base/class.c
+7
-2
drivers/char/tty_io.c
drivers/char/tty_io.c
+16
-6
drivers/i2c/busses/i2c-keywest.c
drivers/i2c/busses/i2c-keywest.c
+2
-0
drivers/i2c/chips/asb100.c
drivers/i2c/chips/asb100.c
+2
-2
drivers/i2c/chips/it87.c
drivers/i2c/chips/it87.c
+2
-2
drivers/i2c/chips/lm78.c
drivers/i2c/chips/lm78.c
+2
-2
drivers/i2c/chips/lm85.c
drivers/i2c/chips/lm85.c
+2
-2
drivers/i2c/chips/w83627hf.c
drivers/i2c/chips/w83627hf.c
+2
-2
drivers/i2c/chips/w83781d.c
drivers/i2c/chips/w83781d.c
+2
-2
drivers/pci/pci-driver.c
drivers/pci/pci-driver.c
+3
-4
drivers/pci/probe.c
drivers/pci/probe.c
+6
-0
drivers/pci/remove.c
drivers/pci/remove.c
+13
-7
drivers/scsi/sd.c
drivers/scsi/sd.c
+5
-7
drivers/scsi/sr.c
drivers/scsi/sr.c
+5
-7
drivers/usb/core/config.c
drivers/usb/core/config.c
+4
-3
drivers/usb/core/message.c
drivers/usb/core/message.c
+1
-1
drivers/usb/core/urb.c
drivers/usb/core/urb.c
+2
-2
drivers/usb/core/usb.h
drivers/usb/core/usb.h
+1
-0
drivers/usb/host/ehci-mem.c
drivers/usb/host/ehci-mem.c
+2
-2
drivers/usb/serial/usb-serial.c
drivers/usb/serial/usb-serial.c
+62
-68
include/linux/device.h
include/linux/device.h
+0
-1
include/linux/kobject.h
include/linux/kobject.h
+4
-1
include/linux/kref.h
include/linux/kref.h
+3
-6
include/linux/pci.h
include/linux/pci.h
+1
-1
lib/Makefile
lib/Makefile
+1
-4
lib/kobject.c
lib/kobject.c
+38
-19
lib/kref.c
lib/kref.c
+13
-16
No files found.
CREDITS
View file @
9f7d733d
...
...
@@ -735,6 +735,12 @@ S: Schimmelsrain 1
S: D-69231 Rauenberg
S: Germany
N: Jean Delvare
E: khali@linux-fr.org
W: http://khali.linux-fr.org/
D: Several hardware monitoring drivers
S: France
N: Peter Denison
E: peterd@pnd-pc.demon.co.uk
W: http://www.pnd-pc.demon.co.uk/promise/
...
...
Documentation/driver-model/bus.txt
View file @
9f7d733d
...
...
@@ -6,19 +6,20 @@ Definition
struct bus_type {
char * name;
rwlock_t lock;
atomic_t refcount;
struct list_head node
;
struct list_head device
s;
struct list_head driver
s;
struct subsystem subsys
;
struct kset driver
s;
struct kset device
s;
struct driver_dir_entry dir
;
struct driver_dir_entry device_dir
;
struct driver_dir_entry driver_dir
;
struct bus_attribute * bus_attrs
;
struct device_attribute * dev_attrs
;
struct driver_attribute * drv_attrs
;
int (*match) (struct device * dev, struct device_driver * drv);
struct device (*add) (struct device * parent, char * bus_id);
int (*match)(struct device * dev, struct device_driver * drv);
int (*hotplug) (struct device *dev, char **envp,
int num_envp, char *buffer, int buffer_size);
int (*suspend)(struct device * dev, u32 state);
int (*resume)(struct device * dev);
};
int bus_register(struct bus_type * bus);
...
...
@@ -47,7 +48,7 @@ Registration
When a bus driver is initialized, it calls bus_register. This
initializes the rest of the fields in the bus object and inserts it
into a global list of bus types. Once the bus object is registered,
the fields in it
(e.g. the rwlock_t)
are usable by the bus driver.
the fields in it are usable by the bus driver.
Callbacks
...
...
@@ -71,40 +72,6 @@ When a driver is registered with the bus, the bus's list of devices is
iterated over, and the match callback is called for each device that
does not have a driver associated with it.
add(): Adding a child device
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The add callback is available to notify the bus about a child device
at a particular location.
The parent parameter is the parent device of the child to be added. If
parent == NULL, the bus should add the device as a child of a default
parent device or as a child of the root. This policy decision is up to
the bus driver.
The format of the bus_id field should be consistent with the format of
the bus_id field of the rest of the devices on the bus. This requires
the caller to know the format.
On return, the bus driver should return a pointer to the device that
was created. If the device was not created, the bus driver should
return an appropriate error code. Refer to include/linux/err.h for
helper functions to encode errors. Some sample code:
struct device * pci_bus_add(struct device * parent, char * bus_id)
{
...
/* the device already exists */
return ERR_PTR(-EEXIST);
...
}
The caller can check the return value using IS_ERR():
struct device * newdev = pci_bus_type.add(parent,bus_id);
if (IS_ERR(newdev)) {
...
}
Device and Driver Lists
...
...
@@ -118,10 +85,11 @@ necessary.
The LDM core provides helper functions for iterating over each list.
int bus_for_each_dev(struct bus_type * bus, void * data,
int (*callback)(struct device * dev, void * data));
int bus_for_each_drv(struct bus_type * bus, void * data,
int (*callback)(struct device_driver * drv, void * data));
int bus_for_each_dev(struct bus_type * bus, struct device * start, void * data,
int (*fn)(struct device *, void *));
int bus_for_each_drv(struct bus_type * bus, struct device_driver * start,
void * data, int (*fn)(struct device_driver *, void *));
These helpers iterate over the respective list, and call the callback
for each device or driver in the list. All list accesses are
...
...
@@ -169,8 +137,8 @@ Exporting Attributes
~~~~~~~~~~~~~~~~~~~~
struct bus_attribute {
struct attribute attr;
ssize_t (*show)(struct bus_type *, char * buf, size_t count, loff_t of
f);
ssize_t (*store)(struct bus_type *, const char * buf, size_t count, loff_t off
);
ssize_t (*show)(struct bus_type *, char * bu
f);
ssize_t (*store)(struct bus_type *, const char * buf, size_t count
);
};
Bus drivers can export attributes using the BUS_ATTR macro that works
...
...
Documentation/i2c/sysfs-interface
View file @
9f7d733d
...
...
@@ -104,7 +104,7 @@ in[0-8]_input Voltage input value.
in7_* varies
in8_* varies
in0_ref
CPU core reference voltage.
cpu[0-1]_vid
CPU core reference voltage.
Unit: millivolt
Read only.
Not always correct.
...
...
MAINTAINERS
View file @
9f7d733d
...
...
@@ -199,6 +199,12 @@ M: Thorsten Knabe <linux@thorsten-knabe.de>
W: http://linux.thorsten-knabe.de
S: Maintained
ADM1025 HARDWARE MONITOR DRIVER
P: Jean Delvare
M: khali@linux-fr.org
L: sensors@stimpy.netroedge.com
S: Maintained
ADT746X FAN DRIVER
P: Colin Leroy
M: colin@colino.net
...
...
@@ -1327,6 +1333,18 @@ L: linux-security-module@wirex.com
W: http://lsm.immunix.org
S: Supported
LM83 HARDWARE MONITOR DRIVER
P: Jean Delvare
M: khali@linux-fr.org
L: sensors@stimpy.netroedge.com
S: Maintained
LM90 HARDWARE MONITOR DRIVER
P: Jean Delvare
M: khali@linux-fr.org
L: sensors@stimpy.netroedge.com
S: Maintained
LOGICAL DISK MANAGER SUPPORT (LDM, Windows 2000/XP Dynamic Disks)
P: Richard Russon (FlatCap)
M: ldm@flatcap.org
...
...
@@ -1906,6 +1924,12 @@ M: thomas@winischhofer.net
W: http://www.winischhofer.net/linuxsisvga.shtml
S: Maintained
SMSC47M1 HARDWARE MONITOR DRIVER
P: Jean Delvare
M: khali@linux-fr.org
L: sensors@stimpy.netroedge.com
S: Odd Fixes
SMB FILESYSTEM
P: Urban Widmark
M: urban@teststation.com
...
...
@@ -2410,6 +2434,12 @@ M: johnpol@2ka.mipt.ru
L: sensors@stimpy.netroedge.com
S: Maintained
W83L785TS HARDWARE MONITOR DRIVER
P: Jean Delvare
M: khali@linux-fr.org
L: sensors@stimpy.netroedge.com
S: Odd Fixes
WAN ROUTER & SANGOMA WANPIPE DRIVERS & API (X.25, FRAME RELAY, PPP, CISCO HDLC)
P: Nenad Corbic
M: ncorbic@sangoma.com
...
...
drivers/base/class.c
View file @
9f7d733d
...
...
@@ -349,14 +349,19 @@ void class_device_initialize(struct class_device *class_dev)
int
class_device_add
(
struct
class_device
*
class_dev
)
{
struct
class
*
parent
;
struct
class
*
parent
=
NULL
;
struct
class_interface
*
class_intf
;
int
error
;
class_dev
=
class_device_get
(
class_dev
);
if
(
!
class_dev
||
!
strlen
(
class_dev
->
class_id
)
)
if
(
!
class_dev
)
return
-
EINVAL
;
if
(
!
strlen
(
class_dev
->
class_id
))
{
error
=
-
EINVAL
;
goto
register_done
;
}
parent
=
class_get
(
class_dev
->
class
);
pr_debug
(
"CLASS: registering class device: ID = '%s'
\n
"
,
...
...
drivers/char/tty_io.c
View file @
9f7d733d
...
...
@@ -763,6 +763,17 @@ ssize_t redirected_tty_write(struct file * file, const char __user * buf, size_t
return
tty_write
(
file
,
buf
,
count
,
ppos
);
}
static
char
ptychar
[]
=
"pqrstuvwxyzabcde"
;
static
inline
void
pty_line_name
(
struct
tty_driver
*
driver
,
int
index
,
char
*
p
)
{
int
i
=
index
+
driver
->
name_base
;
/* ->name is initialized to "ttyp", but "tty" is expected */
sprintf
(
p
,
"%s%c%x"
,
driver
->
subtype
==
PTY_TYPE_SLAVE
?
"tty"
:
driver
->
name
,
ptychar
[
i
>>
4
&
0xf
],
i
&
0xf
);
}
static
inline
void
tty_line_name
(
struct
tty_driver
*
driver
,
int
index
,
char
*
p
)
{
sprintf
(
p
,
"%s%d"
,
driver
->
name
,
index
+
driver
->
name_base
);
...
...
@@ -2175,6 +2186,7 @@ static struct class_simple *tty_class;
void
tty_register_device
(
struct
tty_driver
*
driver
,
unsigned
index
,
struct
device
*
device
)
{
char
name
[
64
];
dev_t
dev
=
MKDEV
(
driver
->
major
,
driver
->
minor_start
)
+
index
;
if
(
index
>=
driver
->
num
)
{
...
...
@@ -2186,13 +2198,11 @@ void tty_register_device(struct tty_driver *driver, unsigned index,
devfs_mk_cdev
(
dev
,
S_IFCHR
|
S_IRUSR
|
S_IWUSR
,
"%s%d"
,
driver
->
devfs_name
,
index
+
driver
->
name_base
);
/* we don't care about the ptys */
/* how nice to hide this behind some crappy interface.. */
if
(
driver
->
type
!=
TTY_DRIVER_TYPE_PTY
)
{
char
name
[
64
];
if
(
driver
->
type
==
TTY_DRIVER_TYPE_PTY
)
pty_line_name
(
driver
,
index
,
name
);
else
tty_line_name
(
driver
,
index
,
name
);
class_simple_device_add
(
tty_class
,
dev
,
device
,
name
);
}
}
/**
...
...
drivers/i2c/busses/i2c-keywest.c
View file @
9f7d733d
...
...
@@ -618,6 +618,8 @@ create_iface(struct device_node *np, struct device *dev)
chan
->
iface
=
iface
;
chan
->
chan_no
=
i
;
chan
->
adapter
.
id
=
I2C_ALGO_SMBUS
;
if
(
i
==
1
)
chan
->
adapter
.
class
=
I2C_CLASS_HWMON
;
chan
->
adapter
.
algo
=
&
keywest_algorithm
;
chan
->
adapter
.
algo_data
=
NULL
;
chan
->
adapter
.
client_register
=
NULL
;
...
...
drivers/i2c/chips/asb100.c
View file @
9f7d733d
...
...
@@ -520,9 +520,9 @@ static ssize_t show_vid(struct device *dev, char *buf)
return
sprintf
(
buf
,
"%d
\n
"
,
vid_from_reg
(
data
->
vid
,
data
->
vrm
));
}
static
DEVICE_ATTR
(
in0_ref
,
S_IRUGO
,
show_vid
,
NULL
);
static
DEVICE_ATTR
(
cpu0_vid
,
S_IRUGO
,
show_vid
,
NULL
);
#define device_create_file_vid(client) \
device_create_file(&client->dev, &dev_attr_
in0_ref
)
device_create_file(&client->dev, &dev_attr_
cpu0_vid
)
/* VRM */
static
ssize_t
show_vrm
(
struct
device
*
dev
,
char
*
buf
)
...
...
drivers/i2c/chips/it87.c
View file @
9f7d733d
...
...
@@ -571,9 +571,9 @@ show_vid_reg(struct device *dev, char *buf)
struct
it87_data
*
data
=
it87_update_device
(
dev
);
return
sprintf
(
buf
,
"%ld
\n
"
,
(
long
)
vid_from_reg
(
data
->
vid
,
data
->
vrm
));
}
static
DEVICE_ATTR
(
in0_ref
,
S_IRUGO
,
show_vid_reg
,
NULL
);
static
DEVICE_ATTR
(
cpu0_vid
,
S_IRUGO
,
show_vid_reg
,
NULL
);
#define device_create_file_vid(client) \
device_create_file(&client->dev, &dev_attr_
in0_ref
)
device_create_file(&client->dev, &dev_attr_
cpu0_vid
)
/* This function is called when:
* it87_driver is inserted (when this module is loaded), for each
...
...
drivers/i2c/chips/lm78.c
View file @
9f7d733d
...
...
@@ -423,7 +423,7 @@ static ssize_t show_vid(struct device *dev, char *buf)
struct
lm78_data
*
data
=
lm78_update_device
(
dev
);
return
sprintf
(
buf
,
"%d
\n
"
,
VID_FROM_REG
(
data
->
vid
));
}
static
DEVICE_ATTR
(
in0_ref
,
S_IRUGO
,
show_vid
,
NULL
);
static
DEVICE_ATTR
(
cpu0_vid
,
S_IRUGO
,
show_vid
,
NULL
);
/* Alarms */
static
ssize_t
show_alarms
(
struct
device
*
dev
,
char
*
buf
)
...
...
@@ -615,7 +615,7 @@ int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
device_create_file
(
&
new_client
->
dev
,
&
dev_attr_fan3_min
);
device_create_file
(
&
new_client
->
dev
,
&
dev_attr_fan3_div
);
device_create_file
(
&
new_client
->
dev
,
&
dev_attr_alarms
);
device_create_file
(
&
new_client
->
dev
,
&
dev_attr_
in0_ref
);
device_create_file
(
&
new_client
->
dev
,
&
dev_attr_
cpu0_vid
);
return
0
;
...
...
drivers/i2c/chips/lm85.c
View file @
9f7d733d
...
...
@@ -465,7 +465,7 @@ static ssize_t show_vid_reg(struct device *dev, char *buf)
return
sprintf
(
buf
,
"%ld
\n
"
,
(
long
)
vid_from_reg
(
data
->
vid
,
data
->
vrm
));
}
static
DEVICE_ATTR
(
in0_ref
,
S_IRUGO
,
show_vid_reg
,
NULL
);
static
DEVICE_ATTR
(
cpu0_vid
,
S_IRUGO
,
show_vid_reg
,
NULL
);
static
ssize_t
show_vrm_reg
(
struct
device
*
dev
,
char
*
buf
)
{
...
...
@@ -874,7 +874,7 @@ int lm85_detect(struct i2c_adapter *adapter, int address,
device_create_file
(
&
new_client
->
dev
,
&
dev_attr_temp2_max
);
device_create_file
(
&
new_client
->
dev
,
&
dev_attr_temp3_max
);
device_create_file
(
&
new_client
->
dev
,
&
dev_attr_vrm
);
device_create_file
(
&
new_client
->
dev
,
&
dev_attr_
in0_ref
);
device_create_file
(
&
new_client
->
dev
,
&
dev_attr_
cpu0_vid
);
device_create_file
(
&
new_client
->
dev
,
&
dev_attr_alarms
);
return
0
;
...
...
drivers/i2c/chips/w83627hf.c
View file @
9f7d733d
...
...
@@ -635,9 +635,9 @@ show_vid_reg(struct device *dev, char *buf)
struct
w83627hf_data
*
data
=
w83627hf_update_device
(
dev
);
return
sprintf
(
buf
,
"%ld
\n
"
,
(
long
)
vid_from_reg
(
data
->
vid
,
data
->
vrm
));
}
static
DEVICE_ATTR
(
in0_ref
,
S_IRUGO
,
show_vid_reg
,
NULL
);
static
DEVICE_ATTR
(
cpu0_vid
,
S_IRUGO
,
show_vid_reg
,
NULL
);
#define device_create_file_vid(client) \
device_create_file(&client->dev, &dev_attr_
in0_ref
)
device_create_file(&client->dev, &dev_attr_
cpu0_vid
)
static
ssize_t
show_vrm_reg
(
struct
device
*
dev
,
char
*
buf
)
...
...
drivers/i2c/chips/w83781d.c
View file @
9f7d733d
...
...
@@ -503,9 +503,9 @@ show_vid_reg(struct device *dev, char *buf)
}
static
DEVICE_ATTR
(
in0_ref
,
S_IRUGO
,
show_vid_reg
,
NULL
);
DEVICE_ATTR
(
cpu0_vid
,
S_IRUGO
,
show_vid_reg
,
NULL
);
#define device_create_file_vid(client) \
device_create_file(&client->dev, &dev_attr_
in0_ref
);
device_create_file(&client->dev, &dev_attr_
cpu0_vid
);
static
ssize_t
show_vrm_reg
(
struct
device
*
dev
,
char
*
buf
)
{
...
...
drivers/pci/pci-driver.c
View file @
9f7d733d
...
...
@@ -390,10 +390,9 @@ pci_populate_driver_dir(struct pci_driver *drv)
* pci_register_driver - register a new pci driver
* @drv: the driver structure to register
*
* Adds the driver structure to the list of registered drivers
* Returns the number of pci devices which were claimed by the driver
* during registration. The driver remains registered even if the
* return value is zero.
* Adds the driver structure to the list of registered drivers.
* Returns a negative value on error. The driver remains registered
* even if no device was claimed during registration.
*/
int
pci_register_driver
(
struct
pci_driver
*
drv
)
...
...
drivers/pci/probe.c
View file @
9f7d733d
...
...
@@ -571,6 +571,11 @@ static int pci_cfg_space_size(struct pci_dev *dev)
return
PCI_CFG_SPACE_SIZE
;
}
static
void
pci_release_bus_bridge_dev
(
struct
device
*
dev
)
{
kfree
(
dev
);
}
/*
* Read the config data for a PCI device, sanity-check it
* and fill in the dev structure...
...
...
@@ -772,6 +777,7 @@ struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus,
memset
(
dev
,
0
,
sizeof
(
*
dev
));
dev
->
parent
=
parent
;
dev
->
release
=
pci_release_bus_bridge_dev
;
sprintf
(
dev
->
bus_id
,
"pci%04x:%02x"
,
pci_domain_nr
(
b
),
bus
);
device_register
(
dev
);
b
->
bridge
=
get_device
(
dev
);
...
...
drivers/pci/remove.c
View file @
9f7d733d
...
...
@@ -59,6 +59,18 @@ int pci_remove_device_safe(struct pci_dev *dev)
}
EXPORT_SYMBOL
(
pci_remove_device_safe
);
void
pci_remove_bus
(
struct
pci_bus
*
b
)
{
pci_proc_detach_bus
(
b
);
spin_lock
(
&
pci_bus_lock
);
list_del
(
&
b
->
node
);
spin_unlock
(
&
pci_bus_lock
);
class_device_unregister
(
&
b
->
class_dev
);
}
EXPORT_SYMBOL
(
pci_remove_bus
);
/**
* pci_remove_bus_device - remove a PCI device and any children
* @dev: the device to remove
...
...
@@ -77,13 +89,7 @@ void pci_remove_bus_device(struct pci_dev *dev)
struct
pci_bus
*
b
=
dev
->
subordinate
;
pci_remove_behind_bridge
(
dev
);
pci_proc_detach_bus
(
b
);
spin_lock
(
&
pci_bus_lock
);
list_del
(
&
b
->
node
);
spin_unlock
(
&
pci_bus_lock
);
class_device_unregister
(
&
b
->
class_dev
);
pci_remove_bus
(
b
);
dev
->
subordinate
=
NULL
;
}
...
...
drivers/scsi/sd.c
View file @
9f7d733d
...
...
@@ -182,16 +182,14 @@ static struct scsi_disk *scsi_disk_get(struct gendisk *disk)
if
(
disk
->
private_data
==
NULL
)
goto
out
;
sdkp
=
scsi_disk
(
disk
);
if
(
!
kref_get
(
&
sdkp
->
kref
))
goto
out_sdkp
;
kref_get
(
&
sdkp
->
kref
);
if
(
scsi_device_get
(
sdkp
->
device
))
goto
out_put
;
up
(
&
sd_ref_sem
);
return
sdkp
;
out_put:
kref_put
(
&
sdkp
->
kref
);
out_sdkp:
kref_put
(
&
sdkp
->
kref
,
scsi_disk_release
);
sdkp
=
NULL
;
out:
up
(
&
sd_ref_sem
);
...
...
@@ -202,7 +200,7 @@ static void scsi_disk_put(struct scsi_disk *sdkp)
{
down
(
&
sd_ref_sem
);
scsi_device_put
(
sdkp
->
device
);
kref_put
(
&
sdkp
->
kref
);
kref_put
(
&
sdkp
->
kref
,
scsi_disk_release
);
up
(
&
sd_ref_sem
);
}
...
...
@@ -1420,7 +1418,7 @@ static int sd_probe(struct device *dev)
goto
out
;
memset
(
sdkp
,
0
,
sizeof
(
*
sdkp
));
kref_init
(
&
sdkp
->
kref
,
scsi_disk_release
);
kref_init
(
&
sdkp
->
kref
);
/* Note: We can accomodate 64 partitions, but the genhd code
* assumes partitions allocate consecutive minors, which they don't.
...
...
@@ -1522,7 +1520,7 @@ static int sd_remove(struct device *dev)
del_gendisk
(
sdkp
->
disk
);
sd_shutdown
(
dev
);
down
(
&
sd_ref_sem
);
kref_put
(
&
sdkp
->
kref
);
kref_put
(
&
sdkp
->
kref
,
scsi_disk_release
);
up
(
&
sd_ref_sem
);
return
0
;
...
...
drivers/scsi/sr.c
View file @
9f7d733d
...
...
@@ -140,15 +140,13 @@ static inline struct scsi_cd *scsi_cd_get(struct gendisk *disk)
if
(
disk
->
private_data
==
NULL
)
goto
out
;
cd
=
scsi_cd
(
disk
);
if
(
!
kref_get
(
&
cd
->
kref
))
goto
out_null
;
kref_get
(
&
cd
->
kref
);
if
(
scsi_device_get
(
cd
->
device
))
goto
out_put
;
goto
out
;
out_put:
kref_put
(
&
cd
->
kref
);
out_null:
kref_put
(
&
cd
->
kref
,
sr_kref_release
);
cd
=
NULL
;
out:
up
(
&
sr_ref_sem
);
...
...
@@ -159,7 +157,7 @@ static inline void scsi_cd_put(struct scsi_cd *cd)
{
down
(
&
sr_ref_sem
);
scsi_device_put
(
cd
->
device
);
kref_put
(
&
cd
->
kref
);
kref_put
(
&
cd
->
kref
,
sr_kref_release
);
up
(
&
sr_ref_sem
);
}
...
...
@@ -576,7 +574,7 @@ static int sr_probe(struct device *dev)
goto
fail
;
memset
(
cd
,
0
,
sizeof
(
*
cd
));
kref_init
(
&
cd
->
kref
,
sr_kref_release
);
kref_init
(
&
cd
->
kref
);
disk
=
alloc_disk
(
1
);
if
(
!
disk
)
...
...
@@ -937,7 +935,7 @@ static int sr_remove(struct device *dev)
del_gendisk
(
cd
->
disk
);
down
(
&
sr_ref_sem
);
kref_put
(
&
cd
->
kref
);
kref_put
(
&
cd
->
kref
,
sr_kref_release
);
up
(
&
sr_ref_sem
);
return
0
;
...
...
drivers/usb/core/config.c
View file @
9f7d733d
...
...
@@ -106,7 +106,7 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
return
buffer
-
buffer0
+
i
;
}
static
void
usb_release_interface_cache
(
struct
kref
*
ref
)
void
usb_release_interface_cache
(
struct
kref
*
ref
)
{
struct
usb_interface_cache
*
intfc
=
ref_to_usb_interface_cache
(
ref
);
int
j
;
...
...
@@ -356,7 +356,7 @@ int usb_parse_configuration(struct device *ddev, int cfgidx,
if
(
!
intfc
)
return
-
ENOMEM
;
memset
(
intfc
,
0
,
len
);
kref_init
(
&
intfc
->
ref
,
usb_release_interface_cache
);
kref_init
(
&
intfc
->
ref
);
}
/* Skip over any Class Specific or Vendor Specific descriptors;
...
...
@@ -422,7 +422,8 @@ void usb_destroy_configuration(struct usb_device *dev)
for
(
i
=
0
;
i
<
cf
->
desc
.
bNumInterfaces
;
i
++
)
{
if
(
cf
->
intf_cache
[
i
])
kref_put
(
&
cf
->
intf_cache
[
i
]
->
ref
);
kref_put
(
&
cf
->
intf_cache
[
i
]
->
ref
,
usb_release_interface_cache
);
}
}
kfree
(
dev
->
config
);
...
...
drivers/usb/core/message.c
View file @
9f7d733d
...
...
@@ -1196,7 +1196,7 @@ static void release_interface(struct device *dev)
struct
usb_interface_cache
*
intfc
=
altsetting_to_usb_interface_cache
(
intf
->
altsetting
);
kref_put
(
&
intfc
->
ref
);
kref_put
(
&
intfc
->
ref
,
usb_release_interface_cache
);
kfree
(
intf
);
}
...
...
drivers/usb/core/urb.c
View file @
9f7d733d
...
...
@@ -39,7 +39,7 @@ void usb_init_urb(struct urb *urb)
{
if
(
urb
)
{
memset
(
urb
,
0
,
sizeof
(
*
urb
));
kref_init
(
&
urb
->
kref
,
urb_destroy
);
kref_init
(
&
urb
->
kref
);
spin_lock_init
(
&
urb
->
lock
);
}
}
...
...
@@ -88,7 +88,7 @@ struct urb *usb_alloc_urb(int iso_packets, int mem_flags)
void
usb_free_urb
(
struct
urb
*
urb
)
{
if
(
urb
)
kref_put
(
&
urb
->
kref
);
kref_put
(
&
urb
->
kref
,
urb_destroy
);
}
/**
...
...
drivers/usb/core/usb.h
View file @
9f7d733d
...
...
@@ -10,6 +10,7 @@ extern int usb_unbind_interface (struct device *dev);
extern
void
usb_disable_endpoint
(
struct
usb_device
*
dev
,
unsigned
int
epaddr
);
extern
void
usb_disable_interface
(
struct
usb_device
*
dev
,
struct
usb_interface
*
intf
);
extern
void
usb_release_interface_cache
(
struct
kref
*
ref
);
extern
void
usb_disable_device
(
struct
usb_device
*
dev
,
int
skip_ep0
);
extern
void
usb_enable_endpoint
(
struct
usb_device
*
dev
,
...
...
drivers/usb/host/ehci-mem.c
View file @
9f7d733d
...
...
@@ -114,7 +114,7 @@ static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, int flags)
return
qh
;
memset
(
qh
,
0
,
sizeof
*
qh
);
kref_init
(
&
qh
->
kref
,
qh_destroy
);
kref_init
(
&
qh
->
kref
);
qh
->
ehci
=
ehci
;
qh
->
qh_dma
=
dma
;
// INIT_LIST_HEAD (&qh->qh_list);
...
...
@@ -139,7 +139,7 @@ static inline struct ehci_qh *qh_get (struct ehci_qh *qh)
static
inline
void
qh_put
(
struct
ehci_qh
*
qh
)
{
kref_put
(
&
qh
->
kref
);
kref_put
(
&
qh
->
kref
,
qh_destroy
);
}
/*-------------------------------------------------------------------------*/
...
...
drivers/usb/serial/usb-serial.c
View file @
9f7d733d
...
...
@@ -421,6 +421,63 @@ static void return_serial (struct usb_serial *serial)
return
;
}
static
void
destroy_serial
(
struct
kref
*
kref
)
{
struct
usb_serial
*
serial
;
struct
usb_serial_port
*
port
;
int
i
;
serial
=
to_usb_serial
(
kref
);
dbg
(
"%s - %s"
,
__FUNCTION__
,
serial
->
type
->
name
);
serial
->
type
->
shutdown
(
serial
);
/* return the minor range that this device had */
return_serial
(
serial
);
for
(
i
=
0
;
i
<
serial
->
num_ports
;
++
i
)
serial
->
port
[
i
]
->
open_count
=
0
;
/* the ports are cleaned up and released in port_release() */
for
(
i
=
0
;
i
<
serial
->
num_ports
;
++
i
)
if
(
serial
->
port
[
i
]
->
dev
.
parent
!=
NULL
)
{
device_unregister
(
&
serial
->
port
[
i
]
->
dev
);
serial
->
port
[
i
]
=
NULL
;
}
/* If this is a "fake" port, we have to clean it up here, as it will
* not get cleaned up in port_release() as it was never registered with
* the driver core */
if
(
serial
->
num_ports
<
serial
->
num_port_pointers
)
{
for
(
i
=
serial
->
num_ports
;
i
<
serial
->
num_port_pointers
;
++
i
)
{
port
=
serial
->
port
[
i
];
if
(
!
port
)
continue
;
if
(
port
->
read_urb
)
{
usb_unlink_urb
(
port
->
read_urb
);
usb_free_urb
(
port
->
read_urb
);
}
if
(
port
->
write_urb
)
{
usb_unlink_urb
(
port
->
write_urb
);
usb_free_urb
(
port
->
write_urb
);
}
if
(
port
->
interrupt_in_urb
)
{
usb_unlink_urb
(
port
->
interrupt_in_urb
);
usb_free_urb
(
port
->
interrupt_in_urb
);
}
kfree
(
port
->
bulk_in_buffer
);
kfree
(
port
->
bulk_out_buffer
);
kfree
(
port
->
interrupt_in_buffer
);
}
}
usb_put_dev
(
serial
->
dev
);
/* free up any memory that we allocated */
kfree
(
serial
);
}
/*****************************************************************************
* Driver tty interface functions
*****************************************************************************/
...
...
@@ -465,7 +522,7 @@ static int serial_open (struct tty_struct *tty, struct file * filp)
if
(
retval
)
{
port
->
open_count
=
0
;
module_put
(
serial
->
type
->
owner
);
kref_put
(
&
serial
->
kref
);
kref_put
(
&
serial
->
kref
,
destroy_serial
);
}
}
bailout:
...
...
@@ -496,7 +553,7 @@ static void serial_close(struct tty_struct *tty, struct file * filp)
}
module_put
(
port
->
serial
->
type
->
owner
);
kref_put
(
&
port
->
serial
->
kref
);
kref_put
(
&
port
->
serial
->
kref
,
destroy_serial
);
}
static
int
serial_write
(
struct
tty_struct
*
tty
,
int
from_user
,
const
unsigned
char
*
buf
,
int
count
)
...
...
@@ -654,13 +711,6 @@ static void serial_break (struct tty_struct *tty, int break_state)
;
}
static
void
serial_shutdown
(
struct
usb_serial
*
serial
)
{
dbg
(
"%s"
,
__FUNCTION__
);
serial
->
type
->
shutdown
(
serial
);
}
static
int
serial_read_proc
(
char
*
page
,
char
**
start
,
off_t
off
,
int
count
,
int
*
eof
,
void
*
data
)
{
struct
usb_serial
*
serial
;
...
...
@@ -694,7 +744,7 @@ static int serial_read_proc (char *page, char **start, off_t off, int count, int
begin
+=
length
;
length
=
0
;
}
kref_put
(
&
serial
->
kref
);
kref_put
(
&
serial
->
kref
,
destroy_serial
);
}
*
eof
=
1
;
done:
...
...
@@ -763,62 +813,6 @@ void usb_serial_port_softint(void *private)
wake_up_interruptible
(
&
tty
->
write_wait
);
}
static
void
destroy_serial
(
struct
kref
*
kref
)
{
struct
usb_serial
*
serial
;
struct
usb_serial_port
*
port
;
int
i
;
serial
=
to_usb_serial
(
kref
);
dbg
(
"%s - %s"
,
__FUNCTION__
,
serial
->
type
->
name
);
serial_shutdown
(
serial
);
/* return the minor range that this device had */
return_serial
(
serial
);
for
(
i
=
0
;
i
<
serial
->
num_ports
;
++
i
)
serial
->
port
[
i
]
->
open_count
=
0
;
/* the ports are cleaned up and released in port_release() */
for
(
i
=
0
;
i
<
serial
->
num_ports
;
++
i
)
if
(
serial
->
port
[
i
]
->
dev
.
parent
!=
NULL
)
{
device_unregister
(
&
serial
->
port
[
i
]
->
dev
);
serial
->
port
[
i
]
=
NULL
;
}
/* If this is a "fake" port, we have to clean it up here, as it will
* not get cleaned up in port_release() as it was never registered with
* the driver core */
if
(
serial
->
num_ports
<
serial
->
num_port_pointers
)
{
for
(
i
=
serial
->
num_ports
;
i
<
serial
->
num_port_pointers
;
++
i
)
{
port
=
serial
->
port
[
i
];
if
(
!
port
)
continue
;
if
(
port
->
read_urb
)
{
usb_unlink_urb
(
port
->
read_urb
);
usb_free_urb
(
port
->
read_urb
);
}
if
(
port
->
write_urb
)
{
usb_unlink_urb
(
port
->
write_urb
);
usb_free_urb
(
port
->
write_urb
);
}
if
(
port
->
interrupt_in_urb
)
{
usb_unlink_urb
(
port
->
interrupt_in_urb
);
usb_free_urb
(
port
->
interrupt_in_urb
);
}
kfree
(
port
->
bulk_in_buffer
);
kfree
(
port
->
bulk_out_buffer
);
kfree
(
port
->
interrupt_in_buffer
);
}
}
usb_put_dev
(
serial
->
dev
);
/* free up any memory that we allocated */
kfree
(
serial
);
}
static
void
port_release
(
struct
device
*
dev
)
{
struct
usb_serial_port
*
port
=
to_usb_serial_port
(
dev
);
...
...
@@ -859,7 +853,7 @@ static struct usb_serial * create_serial (struct usb_device *dev,
serial
->
interface
=
interface
;
serial
->
vendor
=
dev
->
descriptor
.
idVendor
;
serial
->
product
=
dev
->
descriptor
.
idProduct
;
kref_init
(
&
serial
->
kref
,
destroy_serial
);
kref_init
(
&
serial
->
kref
);
return
serial
;
}
...
...
@@ -1209,7 +1203,7 @@ void usb_serial_disconnect(struct usb_interface *interface)
if
(
serial
)
{
/* let the last holder of this object
* cause it to be cleaned up */
kref_put
(
&
serial
->
kref
);
kref_put
(
&
serial
->
kref
,
destroy_serial
);
}
dev_info
(
dev
,
"device disconnected
\n
"
);
}
...
...
include/linux/device.h
View file @
9f7d733d
...
...
@@ -59,7 +59,6 @@ struct bus_type {
struct
driver_attribute
*
drv_attrs
;
int
(
*
match
)(
struct
device
*
dev
,
struct
device_driver
*
drv
);
struct
device
*
(
*
add
)
(
struct
device
*
parent
,
char
*
bus_id
);
int
(
*
hotplug
)
(
struct
device
*
dev
,
char
**
envp
,
int
num_envp
,
char
*
buffer
,
int
buffer_size
);
int
(
*
suspend
)(
struct
device
*
dev
,
u32
state
);
...
...
include/linux/kobject.h
View file @
9f7d733d
...
...
@@ -19,6 +19,7 @@
#include <linux/list.h>
#include <linux/sysfs.h>
#include <linux/rwsem.h>
#include <linux/kref.h>
#include <asm/atomic.h>
#define KOBJ_NAME_LEN 20
...
...
@@ -26,7 +27,7 @@
struct
kobject
{
char
*
k_name
;
char
name
[
KOBJ_NAME_LEN
];
atomic_t
refcount
;
struct
kref
kref
;
struct
list_head
entry
;
struct
kobject
*
parent
;
struct
kset
*
kset
;
...
...
@@ -58,6 +59,8 @@ extern void kobject_put(struct kobject *);
extern
void
kobject_hotplug
(
const
char
*
action
,
struct
kobject
*
);
extern
char
*
kobject_get_path
(
struct
kset
*
,
struct
kobject
*
,
int
);
struct
kobj_type
{
void
(
*
release
)(
struct
kobject
*
);
struct
sysfs_ops
*
sysfs_ops
;
...
...
include/linux/kref.h
View file @
9f7d733d
...
...
@@ -18,15 +18,12 @@
#include <linux/types.h>
#include <asm/atomic.h>
struct
kref
{
atomic_t
refcount
;
void
(
*
release
)(
struct
kref
*
kref
);
};
void
kref_init
(
struct
kref
*
kref
,
void
(
*
release
)(
struct
kref
*
));
struct
kref
*
kref_get
(
struct
kref
*
kref
);
void
kref_put
(
struct
kref
*
kref
);
void
kref_init
(
struct
kref
*
kref
);
void
kref_get
(
struct
kref
*
kref
);
void
kref_put
(
struct
kref
*
kref
,
void
(
*
release
)
(
struct
kref
*
kref
));
#endif
/* _KREF_H_ */
include/linux/pci.h
View file @
9f7d733d
...
...
@@ -712,7 +712,7 @@ struct resource *pci_find_parent_resource(const struct pci_dev *dev, struct reso
int
pci_get_interrupt_pin
(
struct
pci_dev
*
dev
,
struct
pci_dev
**
bridge
);
extern
struct
pci_dev
*
pci_dev_get
(
struct
pci_dev
*
dev
);
extern
void
pci_dev_put
(
struct
pci_dev
*
dev
);
extern
void
pci_remove_bus
(
struct
pci_bus
*
b
);
extern
void
pci_remove_bus_device
(
struct
pci_dev
*
dev
);
/* Generic PCI functions exported to card drivers */
...
...
lib/Makefile
View file @
9f7d733d
...
...
@@ -5,12 +5,9 @@
lib-y
:=
errno.o ctype.o string.o vsprintf.o cmdline.o
\
bust_spinlocks.o rbtree.o radix-tree.o dump_stack.o
\
kobject.o idr.o div64.o parser.o int_sqrt.o
\
kobject.o
kref.o
idr.o div64.o parser.o int_sqrt.o
\
bitmap.o extable.o
# hack for now till some static code uses krefs, then it can move up above...
obj-y
+=
kref.o
lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK)
+=
rwsem-spinlock.o
lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM)
+=
rwsem.o
...
...
lib/kobject.c
View file @
9f7d733d
...
...
@@ -58,14 +58,11 @@ static int create_dir(struct kobject * kobj)
return
error
;
}
static
inline
struct
kobject
*
to_kobj
(
struct
list_head
*
entry
)
{
return
container_of
(
entry
,
struct
kobject
,
entry
);
}
#ifdef CONFIG_HOTPLUG
static
int
get_kobj_path_length
(
struct
kset
*
kset
,
struct
kobject
*
kobj
)
{
int
length
=
1
;
...
...
@@ -98,6 +95,31 @@ static void fill_kobj_path(struct kset *kset, struct kobject *kobj, char *path,
pr_debug
(
"%s: path = '%s'
\n
"
,
__FUNCTION__
,
path
);
}
/**
* kobject_get_path - generate and return the path associated with a given kobj
* and kset pair. The result must be freed by the caller with kfree().
*
* @kset: kset in question, with which to build the path
* @kobj: kobject in question, with which to build the path
* @gfp_mask: the allocation type used to allocate the path
*/
char
*
kobject_get_path
(
struct
kset
*
kset
,
struct
kobject
*
kobj
,
int
gfp_mask
)
{
char
*
path
;
int
len
;
len
=
get_kobj_path_length
(
kset
,
kobj
);
path
=
kmalloc
(
len
,
gfp_mask
);
if
(
!
path
)
return
NULL
;
memset
(
path
,
0x00
,
len
);
fill_kobj_path
(
kset
,
kobj
,
path
,
len
);
return
path
;
}
#ifdef CONFIG_HOTPLUG
#define BUFFER_SIZE 1024
/* should be enough memory for the env */
#define NUM_ENVP 32
/* number of env pointers */
static
unsigned
long
sequence_num
;
...
...
@@ -112,7 +134,6 @@ static void kset_hotplug(const char *action, struct kset *kset,
char
*
scratch
;
int
i
=
0
;
int
retval
;
int
kobj_path_length
;
char
*
kobj_path
=
NULL
;
char
*
name
=
NULL
;
unsigned
long
seq
;
...
...
@@ -163,12 +184,9 @@ static void kset_hotplug(const char *action, struct kset *kset,
envp
[
i
++
]
=
scratch
;
scratch
+=
sprintf
(
scratch
,
"SEQNUM=%ld"
,
seq
)
+
1
;
kobj_path_length
=
get_kobj_path_length
(
kset
,
kobj
);
kobj_path
=
kmalloc
(
kobj_path_length
,
GFP_KERNEL
);
kobj_path
=
kobject_get_path
(
kset
,
kobj
,
GFP_KERNEL
);
if
(
!
kobj_path
)
goto
exit
;
memset
(
kobj_path
,
0x00
,
kobj_path_length
);
fill_kobj_path
(
kset
,
kobj
,
kobj_path
,
kobj_path_length
);
envp
[
i
++
]
=
scratch
;
scratch
+=
sprintf
(
scratch
,
"DEVPATH=%s"
,
kobj_path
)
+
1
;
...
...
@@ -225,10 +243,9 @@ void kobject_hotplug(const char *action, struct kobject *kobj)
* kobject_init - initialize object.
* @kobj: object in question.
*/
void
kobject_init
(
struct
kobject
*
kobj
)
{
atomic_set
(
&
kobj
->
refcount
,
1
);
kref_init
(
&
kobj
->
kref
);
INIT_LIST_HEAD
(
&
kobj
->
entry
);
kobj
->
kset
=
kset_get
(
kobj
->
kset
);
}
...
...
@@ -325,7 +342,7 @@ int kobject_register(struct kobject * kobj)
* @kobj: object.
* @name: name.
*
* If strlen(name)
<
KOBJ_NAME_LEN, then use a dynamically allocated
* If strlen(name)
>=
KOBJ_NAME_LEN, then use a dynamically allocated
* string that @kobj->k_name points to. Otherwise, use the static
* @kobj->name array.
*/
...
...
@@ -429,10 +446,8 @@ void kobject_unregister(struct kobject * kobj)
struct
kobject
*
kobject_get
(
struct
kobject
*
kobj
)
{
if
(
kobj
)
{
WARN_ON
(
!
atomic_read
(
&
kobj
->
refcount
));
atomic_inc
(
&
kobj
->
refcount
);
}
if
(
kobj
)
kref_get
(
&
kobj
->
kref
);
return
kobj
;
}
...
...
@@ -459,17 +474,21 @@ void kobject_cleanup(struct kobject * kobj)
kobject_put
(
parent
);
}
static
void
kobject_release
(
struct
kref
*
kref
)
{
kobject_cleanup
(
container_of
(
kref
,
struct
kobject
,
kref
));
}
/**
* kobject_put - decrement refcount for object.
* @kobj: object.
*
* Decrement the refcount, and if 0, call kobject_cleanup().
*/
void
kobject_put
(
struct
kobject
*
kobj
)
{
if
(
atomic_dec_and_test
(
&
kobj
->
refcount
)
)
k
object_cleanup
(
kobj
);
if
(
kobj
)
k
ref_put
(
&
kobj
->
kref
,
kobject_release
);
}
...
...
@@ -626,7 +645,7 @@ void subsys_remove_file(struct subsystem * s, struct subsys_attribute * a)
}
}
EXPORT_SYMBOL
(
kobject_get_path
);
EXPORT_SYMBOL
(
kobject_init
);
EXPORT_SYMBOL
(
kobject_register
);
EXPORT_SYMBOL
(
kobject_unregister
);
...
...
lib/kref.c
View file @
9f7d733d
...
...
@@ -11,48 +11,45 @@
*
*/
/* #define DEBUG */
#include <linux/kref.h>
#include <linux/module.h>
/**
* kref_init - initialize object.
* @kref: object in question.
* @release: pointer to a function that will clean up the object
* when the last reference to the object is released.
* This pointer is required.
*/
void
kref_init
(
struct
kref
*
kref
,
void
(
*
release
)(
struct
kref
*
kref
)
)
void
kref_init
(
struct
kref
*
kref
)
{
WARN_ON
(
release
==
NULL
);
atomic_set
(
&
kref
->
refcount
,
1
);
kref
->
release
=
release
;
}
/**
* kref_get - increment refcount for object.
* @kref: object.
*/
struct
kref
*
kref_get
(
struct
kref
*
kref
)
void
kref_get
(
struct
kref
*
kref
)
{
WARN_ON
(
!
atomic_read
(
&
kref
->
refcount
));
atomic_inc
(
&
kref
->
refcount
);
return
kref
;
}
/**
* kref_put - decrement refcount for object.
* @kref: object.
* @release: pointer to the function that will clean up the object when the
* last reference to the object is released.
* This pointer is required, and it is not acceptable to pass kfree
* in as this function.
*
* Decrement the refcount, and if 0, call
kref->
release().
* Decrement the refcount, and if 0, call release().
*/
void
kref_put
(
struct
kref
*
kref
)
void
kref_put
(
struct
kref
*
kref
,
void
(
*
release
)
(
struct
kref
*
kref
)
)
{
if
(
atomic_dec_and_test
(
&
kref
->
refcount
))
{
pr_debug
(
"kref cleaning up
\n
"
);
kref
->
release
(
kref
);
}
WARN_ON
(
release
==
NULL
);
WARN_ON
(
release
==
(
void
(
*
)(
struct
kref
*
))
kfree
);
if
(
atomic_dec_and_test
(
&
kref
->
refcount
))
release
(
kref
);
}
EXPORT_SYMBOL
(
kref_init
);
...
...
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