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
fddb48b9
Commit
fddb48b9
authored
Sep 26, 2002
by
Greg Kroah-Hartman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
converted USB to use the driver core's hotplug call.
parent
7b5eb7a9
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
81 additions
and
82 deletions
+81
-82
drivers/usb/core/usb.c
drivers/usb/core/usb.c
+81
-82
No files found.
drivers/usb/core/usb.c
View file @
fddb48b9
...
...
@@ -510,57 +510,42 @@ static int usb_device_match (struct device *dev, struct device_driver *drv)
* cases, we know no other thread can recycle our address, since we must
* already have been serialized enough to prevent that.
*/
static
void
call_policy
(
char
*
verb
,
struct
usb_device
*
dev
)
static
int
usb_hotplug
(
struct
device
*
dev
,
char
**
envp
,
int
num_envp
,
char
*
buffer
,
int
buffer_size
)
{
char
*
argv
[
3
],
**
envp
,
*
buf
,
*
scratch
;
int
i
=
0
,
value
;
struct
usb_interface
*
intf
;
struct
usb_device
*
usb_dev
;
char
*
scratch
;
int
i
=
0
;
int
length
=
0
;
if
(
!
hotplug_path
[
0
])
return
;
if
(
in_interrupt
())
{
dbg
(
"In_interrupt"
);
return
;
}
if
(
!
current
->
fs
->
root
)
{
/* statically linked USB is initted rather early */
dbg
(
"call_policy %s, num %d -- no FS yet"
,
verb
,
dev
->
devnum
);
return
;
}
if
(
dev
->
devnum
<
0
)
{
dbg
(
"device already deleted ??"
);
return
;
}
if
(
!
(
envp
=
(
char
**
)
kmalloc
(
20
*
sizeof
(
char
*
),
GFP_KERNEL
)))
{
dbg
(
"enomem"
);
return
;
}
if
(
!
(
buf
=
kmalloc
(
256
,
GFP_KERNEL
)))
{
kfree
(
envp
);
dbg
(
"enomem2"
);
return
;
}
dbg
(
"%s"
,
__FUNCTION__
);
/* only one standardized param to hotplug command: type */
argv
[
0
]
=
hotplug_path
;
argv
[
1
]
=
"usb"
;
argv
[
2
]
=
0
;
if
(
!
dev
)
return
-
ENODEV
;
/*
minimal command environmen
t */
envp
[
i
++
]
=
"HOME=/"
;
envp
[
i
++
]
=
"PATH=/sbin:/bin:/usr/sbin:/usr/bin"
;
/*
check for generic driver, we do not call do hotplug calls for i
t */
if
(
dev
->
driver
==
&
usb_generic_driver
)
return
-
ENODEV
;
#ifdef DEBUG
/* hint that policy agent should enter no-stdout debug mode */
envp
[
i
++
]
=
"DEBUG=kernel"
;
#endif
/* extensible set of named bus-specific parameters,
* supporting multiple driver selection algorithms.
*/
scratch
=
buf
;
intf
=
to_usb_interface
(
dev
);
if
(
!
intf
)
return
-
ENODEV
;
/* action: add, remove */
envp
[
i
++
]
=
scratch
;
scratch
+=
sprintf
(
scratch
,
"ACTION=%s"
,
verb
)
+
1
;
usb_dev
=
interface_to_usbdev
(
intf
);
if
(
!
usb_dev
)
return
-
ENODEV
;
if
(
usb_dev
->
devnum
<
0
)
{
dbg
(
"device already deleted ??"
);
return
-
ENODEV
;
}
if
(
!
usb_dev
->
bus
)
{
dbg
(
"bus already removed?"
);
return
-
ENODEV
;
}
scratch
=
buffer
;
#ifdef CONFIG_USB_DEVICEFS
/* If this is available, userspace programs can directly read
...
...
@@ -569,27 +554,48 @@ static void call_policy (char *verb, struct usb_device *dev)
*
* FIXME reduce hardwired intelligence here
*/
envp
[
i
++
]
=
"DEVFS=/proc/bus/usb"
;
envp
[
i
++
]
=
scratch
;
scratch
+=
sprintf
(
scratch
,
"DEVICE=/proc/bus/usb/%03d/%03d"
,
dev
->
bus
->
busnum
,
dev
->
devnum
)
+
1
;
length
+=
snprintf
(
scratch
,
buffer_size
-
length
,
"%s"
,
"DEVFS=/proc/bus/usb"
);
if
((
buffer_size
-
length
<=
0
)
||
(
i
>=
num_envp
))
return
-
ENOMEM
;
++
length
;
scratch
+=
length
;
envp
[
i
++
]
=
scratch
;
length
+=
snprintf
(
scratch
,
buffer_size
-
length
,
"DEVICE=/proc/bus/usb/%03d/%03d"
,
usb_dev
->
bus
->
busnum
,
usb_dev
->
devnum
);
if
((
buffer_size
-
length
<=
0
)
||
(
i
>=
num_envp
))
return
-
ENOMEM
;
++
length
;
scratch
+=
length
;
#endif
/* per-device configuration hacks are common */
envp
[
i
++
]
=
scratch
;
scratch
+=
sprintf
(
scratch
,
"PRODUCT=%x/%x/%x"
,
dev
->
descriptor
.
idVendor
,
dev
->
descriptor
.
idProduct
,
dev
->
descriptor
.
bcdDevice
)
+
1
;
length
+=
snprintf
(
scratch
,
buffer_size
-
length
,
"PRODUCT=%x/%x/%x"
,
usb_dev
->
descriptor
.
idVendor
,
usb_dev
->
descriptor
.
idProduct
,
usb_dev
->
descriptor
.
bcdDevice
);
if
((
buffer_size
-
length
<=
0
)
||
(
i
>=
num_envp
))
return
-
ENOMEM
;
++
length
;
scratch
+=
length
;
/* class-based driver binding models */
envp
[
i
++
]
=
scratch
;
scratch
+=
sprintf
(
scratch
,
"TYPE=%d/%d/%d"
,
dev
->
descriptor
.
bDeviceClass
,
dev
->
descriptor
.
bDeviceSubClass
,
dev
->
descriptor
.
bDeviceProtocol
)
+
1
;
if
(
dev
->
descriptor
.
bDeviceClass
==
0
)
{
int
alt
=
dev
->
actconfig
->
interface
[
0
].
act_altsetting
;
length
+=
snprintf
(
scratch
,
buffer_size
-
length
,
"TYPE=%d/%d/%d"
,
usb_dev
->
descriptor
.
bDeviceClass
,
usb_dev
->
descriptor
.
bDeviceSubClass
,
usb_dev
->
descriptor
.
bDeviceProtocol
);
if
((
buffer_size
-
length
<=
0
)
||
(
i
>=
num_envp
))
return
-
ENOMEM
;
++
length
;
scratch
+=
length
;
if
(
usb_dev
->
descriptor
.
bDeviceClass
==
0
)
{
int
alt
=
intf
->
act_altsetting
;
/* a simple/common case: one config, one interface, one driver
* with current altsetting being a reasonable setting.
...
...
@@ -597,31 +603,29 @@ static void call_policy (char *verb, struct usb_device *dev)
* device-specific binding policies.
*/
envp
[
i
++
]
=
scratch
;
scratch
+=
sprintf
(
scratch
,
"INTERFACE=%d/%d/%d"
,
dev
->
actconfig
->
interface
[
0
].
altsetting
[
alt
].
bInterfaceClass
,
dev
->
actconfig
->
interface
[
0
].
altsetting
[
alt
].
bInterfaceSubClass
,
dev
->
actconfig
->
interface
[
0
].
altsetting
[
alt
].
bInterfaceProtocol
)
+
1
;
/* INTERFACE-0, INTERFACE-1, ... ? */
length
+=
snprintf
(
scratch
,
buffer_size
-
length
,
"INTERFACE=%d/%d/%d"
,
intf
->
altsetting
[
alt
].
bInterfaceClass
,
intf
->
altsetting
[
alt
].
bInterfaceSubClass
,
intf
->
altsetting
[
alt
].
bInterfaceProtocol
);
if
((
buffer_size
-
length
<=
0
)
||
(
i
>=
num_envp
))
return
-
ENOMEM
;
++
length
;
scratch
+=
length
;
}
envp
[
i
++
]
=
0
;
/* assert: (scratch - buf) < sizeof buf */
/* NOTE: user mode daemons can call the agents too */
dbg
(
"kusbd: %s %s %d"
,
argv
[
0
],
verb
,
dev
->
devnum
);
value
=
call_usermodehelper
(
argv
[
0
],
argv
,
envp
);
kfree
(
buf
);
kfree
(
envp
);
if
(
value
!=
0
)
dbg
(
"kusbd policy returned 0x%x"
,
value
);
return
0
;
}
#else
static
inline
void
call_policy
(
char
*
verb
,
struct
usb_device
*
dev
)
{
}
static
int
usb_hotplug
(
struct
device
*
dev
,
char
**
envp
,
char
*
buffer
,
int
buffer_size
)
{
return
-
ENODEV
;
}
#endif
/* CONFIG_HOTPLUG */
...
...
@@ -894,9 +898,6 @@ void usb_disconnect(struct usb_device **pdev)
put_device
(
&
dev
->
dev
);
}
/* Let policy agent unload modules etc */
call_policy
(
"remove"
,
dev
);
/* Decrement the reference count, it'll auto free everything when */
/* it hits 0 which could very well be now */
usb_put_dev
(
dev
);
...
...
@@ -1174,9 +1175,6 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
/* add a /proc/bus/usb entry */
usbfs_add_device
(
dev
);
/* userspace may load modules and/or configure further */
call_policy
(
"add"
,
dev
);
return
0
;
}
...
...
@@ -1439,6 +1437,7 @@ void usb_buffer_unmap_sg (struct usb_device *dev, unsigned pipe,
struct
bus_type
usb_bus_type
=
{
.
name
=
"usb"
,
.
match
=
usb_device_match
,
.
hotplug
=
usb_hotplug
,
};
/*
...
...
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