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
40aafff3
Commit
40aafff3
authored
Jun 01, 2003
by
Greg Kroah-Hartman
Browse files
Options
Browse Files
Download
Plain Diff
Merge kroah.com:/home/greg/linux/BK/bleed-2.5
into kroah.com:/home/greg/linux/BK/gregkh-2.5
parents
4a07c099
cdbe443d
Changes
21
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
265 additions
and
184 deletions
+265
-184
drivers/usb/Makefile
drivers/usb/Makefile
+0
-3
drivers/usb/core/hub.c
drivers/usb/core/hub.c
+3
-1
drivers/usb/core/usb.c
drivers/usb/core/usb.c
+65
-0
drivers/usb/misc/rio500.c
drivers/usb/misc/rio500.c
+10
-6
drivers/usb/serial/Kconfig
drivers/usb/serial/Kconfig
+1
-0
drivers/usb/serial/kobil_sct.c
drivers/usb/serial/kobil_sct.c
+36
-17
drivers/usb/storage/datafab.c
drivers/usb/storage/datafab.c
+1
-1
drivers/usb/storage/freecom.c
drivers/usb/storage/freecom.c
+3
-3
drivers/usb/storage/initializers.c
drivers/usb/storage/initializers.c
+1
-1
drivers/usb/storage/initializers.h
drivers/usb/storage/initializers.h
+1
-0
drivers/usb/storage/isd200.c
drivers/usb/storage/isd200.c
+10
-10
drivers/usb/storage/jumpshot.c
drivers/usb/storage/jumpshot.c
+1
-1
drivers/usb/storage/protocol.c
drivers/usb/storage/protocol.c
+4
-5
drivers/usb/storage/scsiglue.c
drivers/usb/storage/scsiglue.c
+25
-15
drivers/usb/storage/transport.c
drivers/usb/storage/transport.c
+77
-52
drivers/usb/storage/transport.h
drivers/usb/storage/transport.h
+2
-2
drivers/usb/storage/usb.c
drivers/usb/storage/usb.c
+11
-6
drivers/usb/storage/usb.h
drivers/usb/storage/usb.h
+1
-1
include/linux/usb.h
include/linux/usb.h
+2
-0
security/Kconfig
security/Kconfig
+1
-1
security/root_plug.c
security/root_plug.c
+10
-59
No files found.
drivers/usb/Makefile
View file @
40aafff3
...
...
@@ -59,6 +59,3 @@ obj-$(CONFIG_USB_TEST) += misc/
obj-$(CONFIG_USB_TIGL)
+=
misc/
obj-$(CONFIG_USB_USS720)
+=
misc/
obj-$(CONFIG_USB_NET2280)
+=
gadget/
obj-$(CONFIG_USB_ZERO)
+=
gadget/
obj-$(CONFIG_USB_ETH)
+=
gadget/
drivers/usb/core/hub.c
View file @
40aafff3
...
...
@@ -756,7 +756,7 @@ static int usb_hub_port_reset(struct usb_device *hub, int port,
return
-
1
;
}
void
usb_hub_port_disable
(
struct
usb_device
*
hub
,
int
port
)
int
usb_hub_port_disable
(
struct
usb_device
*
hub
,
int
port
)
{
int
ret
;
...
...
@@ -764,6 +764,8 @@ void usb_hub_port_disable(struct usb_device *hub, int port)
if
(
ret
)
dev_err
(
hubdev
(
hub
),
"cannot disable port %d (err = %d)
\n
"
,
port
+
1
,
ret
);
return
ret
;
}
/* USB 2.0 spec, 7.1.7.3 / fig 7-29:
...
...
drivers/usb/core/usb.c
View file @
40aafff3
...
...
@@ -731,6 +731,70 @@ static void usb_release_dev(struct device *dev)
}
static
struct
usb_device
*
match_device
(
struct
usb_device
*
dev
,
u16
vendor_id
,
u16
product_id
)
{
struct
usb_device
*
ret_dev
=
NULL
;
int
child
;
dbg
(
"looking at vendor %d, product %d"
,
dev
->
descriptor
.
idVendor
,
dev
->
descriptor
.
idProduct
);
/* see if this device matches */
if
((
dev
->
descriptor
.
idVendor
==
vendor_id
)
&&
(
dev
->
descriptor
.
idProduct
==
product_id
))
{
dbg
(
"found the device!"
);
ret_dev
=
usb_get_dev
(
dev
);
goto
exit
;
}
/* look through all of the children of this device */
for
(
child
=
0
;
child
<
dev
->
maxchild
;
++
child
)
{
if
(
dev
->
children
[
child
])
{
ret_dev
=
match_device
(
dev
->
children
[
child
],
vendor_id
,
product_id
);
if
(
ret_dev
)
goto
exit
;
}
}
exit:
return
ret_dev
;
}
/**
* usb_find_device - find a specific usb device in the system
* @vendor_id: the vendor id of the device to find
* @product_id: the product id of the device to find
*
* Returns a pointer to a struct usb_device if such a specified usb
* device is present in the system currently. The usage count of the
* device will be incremented if a device is found. Make sure to call
* usb_put_dev() when the caller is finished with the device.
*
* If a device with the specified vendor and product id is not found,
* NULL is returned.
*/
struct
usb_device
*
usb_find_device
(
u16
vendor_id
,
u16
product_id
)
{
struct
list_head
*
buslist
;
struct
usb_bus
*
bus
;
struct
usb_device
*
dev
=
NULL
;
down
(
&
usb_bus_list_lock
);
for
(
buslist
=
usb_bus_list
.
next
;
buslist
!=
&
usb_bus_list
;
buslist
=
buslist
->
next
)
{
bus
=
container_of
(
buslist
,
struct
usb_bus
,
bus_list
);
dev
=
match_device
(
bus
->
root_hub
,
vendor_id
,
product_id
);
if
(
dev
)
goto
exit
;
}
exit:
up
(
&
usb_bus_list_lock
);
return
dev
;
}
/**
* usb_get_current_frame_number - return current bus frame number
* @dev: the device whose bus is being queried
...
...
@@ -1510,6 +1574,7 @@ EXPORT_SYMBOL(usb_disconnect);
EXPORT_SYMBOL
(
__usb_get_extra_descriptor
);
EXPORT_SYMBOL
(
usb_find_device
);
EXPORT_SYMBOL
(
usb_get_current_frame_number
);
EXPORT_SYMBOL
(
usb_buffer_alloc
);
...
...
drivers/usb/misc/rio500.c
View file @
40aafff3
...
...
@@ -23,6 +23,9 @@
*
* Based upon mouse.c (Brad Keryan) and printer.c (Michael Gee).
*
* Changelog:
* 30/05/2003 replaced lock/unlock kernel with up/down
* Daniele Bellucci bellucda@tiscali.it
* */
#include <linux/module.h>
...
...
@@ -75,17 +78,17 @@ static int open_rio(struct inode *inode, struct file *file)
{
struct
rio_usb_data
*
rio
=
&
rio_instance
;
lock_kernel
(
);
down
(
&
(
rio
->
lock
)
);
if
(
rio
->
isopen
||
!
rio
->
present
)
{
u
nlock_kernel
(
);
u
p
(
&
(
rio
->
lock
)
);
return
-
EBUSY
;
}
rio
->
isopen
=
1
;
init_waitqueue_head
(
&
rio
->
wait_q
);
u
nlock_kernel
(
);
u
p
(
&
(
rio
->
lock
)
);
info
(
"Rio opened."
);
...
...
@@ -460,7 +463,6 @@ static int probe_rio(struct usb_interface *intf,
return
-
ENOMEM
;
}
rio
->
present
=
1
;
rio
->
rio_dev
=
dev
;
if
(
!
(
rio
->
obuf
=
(
char
*
)
kmalloc
(
OBUF_SIZE
,
GFP_KERNEL
)))
{
...
...
@@ -481,6 +483,8 @@ static int probe_rio(struct usb_interface *intf,
init_MUTEX
(
&
(
rio
->
lock
));
usb_set_intfdata
(
intf
,
rio
);
rio
->
present
=
1
;
return
0
;
}
...
...
@@ -525,7 +529,7 @@ static struct usb_driver rio_driver = {
.
id_table
=
rio_table
,
};
in
t
usb_rio_init
(
void
)
static
int
__ini
t
usb_rio_init
(
void
)
{
if
(
usb_register
(
&
rio_driver
)
<
0
)
return
-
1
;
...
...
@@ -536,7 +540,7 @@ int usb_rio_init(void)
}
void
usb_rio_cleanup
(
void
)
static
void
__exit
usb_rio_cleanup
(
void
)
{
struct
rio_usb_data
*
rio
=
&
rio_instance
;
...
...
drivers/usb/serial/Kconfig
View file @
40aafff3
...
...
@@ -351,6 +351,7 @@ config USB_SERIAL_KOBIL_SCT
- USB TWIN
- KAAN Standard Plus
- KAAN SIM
- SecOVID Reader Plus
- B1 Professional
- KAAN Professional
...
...
drivers/usb/serial/kobil_sct.c
View file @
40aafff3
...
...
@@ -21,7 +21,8 @@
* Supported readers: USB TWIN, KAAN Standard Plus and SecOVID Reader Plus
* (Adapter K), B1 Professional and KAAN Professional (Adapter B)
*
* TODO: High baudrates
* (28/05/2003) tw
* Add support for KAAN SIM
*
* (12/09/2002) tw
* Adapted to 2.5.
...
...
@@ -58,7 +59,7 @@
#include "usb-serial.h"
/* Version Information */
#define DRIVER_VERSION "
12/09/2002
"
#define DRIVER_VERSION "
28/05/2003
"
#define DRIVER_AUTHOR "KOBIL Systems GmbH - http://www.kobil.com"
#define DRIVER_DESC "KOBIL USB Smart Card Terminal Driver (experimental)"
...
...
@@ -66,6 +67,7 @@
#define KOBIL_ADAPTER_B_PRODUCT_ID 0x2011
#define KOBIL_ADAPTER_K_PRODUCT_ID 0x2012
#define KOBIL_USBTWIN_PRODUCT_ID 0x0078
#define KOBIL_KAAN_SIM_PRODUCT_ID 0x0081
#define KOBIL_TIMEOUT 500
#define KOBIL_BUF_LENGTH 300
...
...
@@ -92,12 +94,22 @@ static struct usb_device_id id_table [] = {
{
USB_DEVICE
(
KOBIL_VENDOR_ID
,
KOBIL_ADAPTER_B_PRODUCT_ID
)
},
{
USB_DEVICE
(
KOBIL_VENDOR_ID
,
KOBIL_ADAPTER_K_PRODUCT_ID
)
},
{
USB_DEVICE
(
KOBIL_VENDOR_ID
,
KOBIL_USBTWIN_PRODUCT_ID
)
},
{
USB_DEVICE
(
KOBIL_VENDOR_ID
,
KOBIL_KAAN_SIM_PRODUCT_ID
)
},
{
}
/* Terminating entry */
};
MODULE_DEVICE_TABLE
(
usb
,
id_table
);
static
struct
usb_driver
kobil_driver
=
{
.
owner
=
THIS_MODULE
,
.
name
=
"kobil"
,
.
probe
=
usb_serial_probe
,
.
disconnect
=
usb_serial_disconnect
,
.
id_table
=
id_table
,
};
struct
usb_serial_device_type
kobil_device
=
{
.
owner
=
THIS_MODULE
,
.
name
=
"KOBIL USB smart card terminal"
,
...
...
@@ -161,6 +173,9 @@ static int kobil_startup (struct usb_serial *serial)
case
KOBIL_USBTWIN_PRODUCT_ID
:
printk
(
KERN_DEBUG
"KOBIL USBTWIN detected
\n
"
);
break
;
case
KOBIL_KAAN_SIM_PRODUCT_ID
:
printk
(
KERN_DEBUG
"KOBIL KAAN SIM detected
\n
"
);
break
;
}
usb_set_serial_port_data
(
serial
->
port
,
priv
);
...
...
@@ -353,7 +368,7 @@ static void kobil_read_int_callback( struct urb *purb, struct pt_regs *regs)
struct
usb_serial_port
*
port
=
(
struct
usb_serial_port
*
)
purb
->
context
;
struct
tty_struct
*
tty
;
unsigned
char
*
data
=
purb
->
transfer_buffer
;
char
*
dbg_data
;
//
char *dbg_data;
dbg
(
"%s - port %d"
,
__FUNCTION__
,
port
->
number
);
...
...
@@ -366,16 +381,18 @@ static void kobil_read_int_callback( struct urb *purb, struct pt_regs *regs)
if
(
purb
->
actual_length
)
{
// BEGIN DEBUG
dbg_data
=
(
unsigned
char
*
)
kmalloc
((
3
*
purb
->
actual_length
+
10
)
*
sizeof
(
char
),
GFP_KERNEL
);
if
(
!
dbg_data
)
{
return
;
}
memset
(
dbg_data
,
0
,
(
3
*
purb
->
actual_length
+
10
));
for
(
i
=
0
;
i
<
purb
->
actual_length
;
i
++
)
{
sprintf
(
dbg_data
+
3
*
i
,
"%02X "
,
data
[
i
]);
}
dbg
(
" <-- %s"
,
dbg_data
);
kfree
(
dbg_data
);
/*
dbg_data = (unsigned char *) kmalloc((3 * purb->actual_length + 10) * sizeof(char), GFP_KERNEL);
if (! dbg_data) {
return;
}
memset(dbg_data, 0, (3 * purb->actual_length + 10));
for (i = 0; i < purb->actual_length; i++) {
sprintf(dbg_data +3*i, "%02X ", data[i]);
}
dbg(" <-- %s", dbg_data );
kfree(dbg_data);
*/
// END DEBUG
for
(
i
=
0
;
i
<
purb
->
actual_length
;
++
i
)
{
...
...
@@ -438,7 +455,7 @@ static int kobil_write (struct usb_serial_port *port, int from_user,
priv
->
filled
=
priv
->
filled
+
count
;
// only send complete block. TWIN and adapter K use the same protocol.
// only send complete block. TWIN
, KAAN SIM
and adapter K use the same protocol.
if
(
((
priv
->
device_type
!=
KOBIL_ADAPTER_B_PRODUCT_ID
)
&&
(
priv
->
filled
>
2
)
&&
(
priv
->
filled
>=
(
priv
->
buf
[
1
]
+
3
)))
||
((
priv
->
device_type
==
KOBIL_ADAPTER_B_PRODUCT_ID
)
&&
(
priv
->
filled
>
3
)
&&
(
priv
->
filled
>=
(
priv
->
buf
[
2
]
+
4
)))
)
{
...
...
@@ -503,7 +520,7 @@ static int kobil_tiocmget(struct usb_serial_port *port, struct file *file)
int
transfer_buffer_length
=
8
;
priv
=
usb_get_serial_port_data
(
port
);
if
(
priv
->
device_type
==
KOBIL_USBTWIN_PRODUCT_ID
)
{
if
(
(
priv
->
device_type
==
KOBIL_USBTWIN_PRODUCT_ID
)
||
(
priv
->
device_type
==
KOBIL_KAAN_SIM_PRODUCT_ID
)
)
{
// This device doesn't support ioctl calls
return
-
EINVAL
;
}
...
...
@@ -549,7 +566,7 @@ static int kobil_tiocmset(struct usb_serial_port *port, struct file *file,
int
transfer_buffer_length
=
8
;
priv
=
usb_get_serial_port_data
(
port
);
if
(
priv
->
device_type
==
KOBIL_USBTWIN_PRODUCT_ID
)
{
if
(
(
priv
->
device_type
==
KOBIL_USBTWIN_PRODUCT_ID
)
||
(
priv
->
device_type
==
KOBIL_KAAN_SIM_PRODUCT_ID
)
)
{
// This device doesn't support ioctl calls
return
-
EINVAL
;
}
...
...
@@ -616,7 +633,7 @@ static int kobil_ioctl(struct usb_serial_port *port, struct file *file,
char
*
settings
;
priv
=
usb_get_serial_port_data
(
port
);
if
(
priv
->
device_type
==
KOBIL_USBTWIN_PRODUCT_ID
)
{
if
(
(
priv
->
device_type
==
KOBIL_USBTWIN_PRODUCT_ID
)
||
(
priv
->
device_type
==
KOBIL_KAAN_SIM_PRODUCT_ID
)
)
{
// This device doesn't support ioctl calls
return
0
;
}
...
...
@@ -727,6 +744,7 @@ static int kobil_ioctl(struct usb_serial_port *port, struct file *file,
static
int
__init
kobil_init
(
void
)
{
usb_serial_register
(
&
kobil_device
);
usb_register
(
&
kobil_driver
);
info
(
DRIVER_VERSION
" "
DRIVER_AUTHOR
);
info
(
DRIVER_DESC
);
...
...
@@ -737,6 +755,7 @@ static int __init kobil_init (void)
static
void
__exit
kobil_exit
(
void
)
{
usb_deregister
(
&
kobil_driver
);
usb_serial_deregister
(
&
kobil_device
);
}
...
...
drivers/usb/storage/datafab.c
View file @
40aafff3
...
...
@@ -670,7 +670,7 @@ int datafab_transport(Scsi_Cmnd * srb, struct us_data *us)
srb
->
result
=
SUCCESS
;
}
else
{
info
->
sense_key
=
UNIT_ATTENTION
;
srb
->
result
=
CHECK_CONDITION
<<
1
;
srb
->
result
=
SAM_STAT_CHECK_CONDITION
;
}
return
rc
;
}
...
...
drivers/usb/storage/freecom.c
View file @
40aafff3
...
...
@@ -399,7 +399,7 @@ freecom_init (struct us_data *us)
}
}
result
=
usb_
control_msg
(
us
->
pusb_dev
,
us
->
recv_ctrl_pipe
,
result
=
usb_
stor_control_msg
(
us
,
us
->
recv_ctrl_pipe
,
0x4c
,
0xc0
,
0x4346
,
0x0
,
buffer
,
0x20
,
3
*
HZ
);
buffer
[
32
]
=
'\0'
;
US_DEBUGP
(
"String returned from FC init is: %s
\n
"
,
buffer
);
...
...
@@ -411,7 +411,7 @@ freecom_init (struct us_data *us)
*/
/* send reset */
result
=
usb_
control_msg
(
us
->
pusb_dev
,
us
->
send_ctrl_pipe
,
result
=
usb_
stor_control_msg
(
us
,
us
->
send_ctrl_pipe
,
0x4d
,
0x40
,
0x24d8
,
0x0
,
NULL
,
0x0
,
3
*
HZ
);
US_DEBUGP
(
"result from activate reset is %d
\n
"
,
result
);
...
...
@@ -419,7 +419,7 @@ freecom_init (struct us_data *us)
mdelay
(
250
);
/* clear reset */
result
=
usb_
control_msg
(
us
->
pusb_dev
,
us
->
send_ctrl_pipe
,
result
=
usb_
stor_control_msg
(
us
,
us
->
send_ctrl_pipe
,
0x4d
,
0x40
,
0x24f8
,
0x0
,
NULL
,
0x0
,
3
*
HZ
);
US_DEBUGP
(
"result from clear reset is %d
\n
"
,
result
);
...
...
drivers/usb/storage/initializers.c
View file @
40aafff3
...
...
@@ -50,7 +50,7 @@ int usb_stor_euscsi_init(struct us_data *us)
int
result
;
US_DEBUGP
(
"Attempting to init eUSCSI bridge...
\n
"
);
result
=
usb_
control_msg
(
us
->
pusb_dev
,
us
->
send_ctrl_pipe
,
result
=
usb_
stor_control_msg
(
us
,
us
->
send_ctrl_pipe
,
0x0C
,
USB_RECIP_INTERFACE
|
USB_TYPE_VENDOR
,
0x01
,
0x0
,
&
data
,
0x1
,
5
*
HZ
);
US_DEBUGP
(
"-- result is %d
\n
"
,
result
);
...
...
drivers/usb/storage/initializers.h
View file @
40aafff3
...
...
@@ -39,6 +39,7 @@
#include <linux/config.h>
#include "usb.h"
#include "transport.h"
/* This places the Shuttle/SCM USB<->SCSI bridge devices in multi-target
* mode */
...
...
drivers/usb/storage/isd200.c
View file @
40aafff3
...
...
@@ -558,7 +558,7 @@ void isd200_invoke_transport( struct us_data *us,
case
USB_STOR_TRANSPORT_GOOD
:
/* Indicate a good result */
srb
->
result
=
GOOD
<<
1
;
srb
->
result
=
SAM_STAT_GOOD
;
break
;
case
USB_STOR_TRANSPORT_FAILED
:
...
...
@@ -598,11 +598,11 @@ void isd200_invoke_transport( struct us_data *us,
}
if
(
result
==
ISD200_GOOD
)
{
isd200_build_sense
(
us
,
srb
);
srb
->
result
=
CHECK_CONDITION
<<
1
;
srb
->
result
=
SAM_STAT_CHECK_CONDITION
;
/* If things are really okay, then let's show that */
if
((
srb
->
sense_buffer
[
2
]
&
0xf
)
==
0x0
)
srb
->
result
=
GOOD
<<
1
;
srb
->
result
=
SAM_STAT_GOOD
;
}
else
srb
->
result
=
DID_ERROR
<<
16
;
}
...
...
@@ -611,7 +611,7 @@ void isd200_invoke_transport( struct us_data *us,
* condition, show that in the result code
*/
if
(
transferStatus
==
USB_STOR_TRANSPORT_FAILED
)
srb
->
result
=
CHECK_CONDITION
<<
1
;
srb
->
result
=
SAM_STAT_CHECK_CONDITION
;
}
#ifdef CONFIG_USB_STORAGE_DEBUG
...
...
@@ -1185,7 +1185,7 @@ int isd200_scsi_to_ata(Scsi_Cmnd *srb, struct us_data *us,
/* copy InquiryData */
isd200_data_copy
(
srb
,
(
char
*
)
&
info
->
InquiryData
,
srb
->
request_bufflen
);
srb
->
result
=
GOOD
<<
1
;
srb
->
result
=
SAM_STAT_GOOD
;
sendToTransport
=
FALSE
;
break
;
...
...
@@ -1205,7 +1205,7 @@ int isd200_scsi_to_ata(Scsi_Cmnd *srb, struct us_data *us,
srb
->
request_bufflen
=
0
;
}
else
{
US_DEBUGP
(
" Media Status not supported, just report okay
\n
"
);
srb
->
result
=
GOOD
<<
1
;
srb
->
result
=
SAM_STAT_GOOD
;
sendToTransport
=
FALSE
;
}
break
;
...
...
@@ -1226,7 +1226,7 @@ int isd200_scsi_to_ata(Scsi_Cmnd *srb, struct us_data *us,
srb
->
request_bufflen
=
0
;
}
else
{
US_DEBUGP
(
" Media Status not supported, just report okay
\n
"
);
srb
->
result
=
GOOD
<<
1
;
srb
->
result
=
SAM_STAT_GOOD
;
sendToTransport
=
FALSE
;
}
break
;
...
...
@@ -1252,7 +1252,7 @@ int isd200_scsi_to_ata(Scsi_Cmnd *srb, struct us_data *us,
srb
->
request_bufflen
=
sizeof
(
struct
read_capacity_data
);
isd200_data_copy
(
srb
,
(
char
*
)
&
readCapacityData
,
srb
->
request_bufflen
);
srb
->
result
=
GOOD
<<
1
;
srb
->
result
=
SAM_STAT_GOOD
;
sendToTransport
=
FALSE
;
}
break
;
...
...
@@ -1336,7 +1336,7 @@ int isd200_scsi_to_ata(Scsi_Cmnd *srb, struct us_data *us,
srb
->
request_bufflen
=
0
;
}
else
{
US_DEBUGP
(
" Not removeable media, just report okay
\n
"
);
srb
->
result
=
GOOD
<<
1
;
srb
->
result
=
SAM_STAT_GOOD
;
sendToTransport
=
FALSE
;
}
break
;
...
...
@@ -1365,7 +1365,7 @@ int isd200_scsi_to_ata(Scsi_Cmnd *srb, struct us_data *us,
srb
->
request_bufflen
=
0
;
}
else
{
US_DEBUGP
(
" Nothing to do, just report okay
\n
"
);
srb
->
result
=
GOOD
<<
1
;
srb
->
result
=
SAM_STAT_GOOD
;
sendToTransport
=
FALSE
;
}
break
;
...
...
drivers/usb/storage/jumpshot.c
View file @
40aafff3
...
...
@@ -611,7 +611,7 @@ int jumpshot_transport(Scsi_Cmnd * srb, struct us_data *us)
srb
->
result
=
SUCCESS
;
}
else
{
info
->
sense_key
=
UNIT_ATTENTION
;
srb
->
result
=
CHECK_CONDITION
<<
1
;
srb
->
result
=
SAM_STAT_CHECK_CONDITION
;
}
return
rc
;
}
...
...
drivers/usb/storage/protocol.c
View file @
40aafff3
...
...
@@ -137,8 +137,7 @@ void usb_stor_qic157_command(Scsi_Cmnd *srb, struct us_data *us)
/* send the command to the transport layer */
usb_stor_invoke_transport
(
srb
,
us
);
if
(
srb
->
result
==
GOOD
<<
1
)
{
if
(
srb
->
result
==
SAM_STAT_GOOD
)
{
/* fix the INQUIRY data if necessary */
fix_inquiry_data
(
srb
);
}
...
...
@@ -210,7 +209,7 @@ void usb_stor_ATAPI_command(Scsi_Cmnd *srb, struct us_data *us)
/* send the command to the transport layer */
usb_stor_invoke_transport
(
srb
,
us
);
if
(
srb
->
result
==
GOOD
<<
1
)
{
if
(
srb
->
result
==
SAM_STAT_GOOD
)
{
/* Fix the MODE_SENSE data if we translated the command */
if
(
old_cmnd
==
MODE_SENSE
)
...
...
@@ -307,7 +306,7 @@ void usb_stor_ufi_command(Scsi_Cmnd *srb, struct us_data *us)
/* send the command to the transport layer */
usb_stor_invoke_transport
(
srb
,
us
);
if
(
srb
->
result
==
GOOD
<<
1
)
{
if
(
srb
->
result
==
SAM_STAT_GOOD
)
{
/* Fix the MODE_SENSE data if we translated the command */
if
(
old_cmnd
==
MODE_SENSE
)
...
...
@@ -376,7 +375,7 @@ void usb_stor_transparent_scsi_command(Scsi_Cmnd *srb, struct us_data *us)
/* send the command to the transport layer */
usb_stor_invoke_transport
(
srb
,
us
);
if
(
srb
->
result
==
GOOD
<<
1
)
{
if
(
srb
->
result
==
SAM_STAT_GOOD
)
{
/* Fix the MODE_SENSE data if we translated the command */
if
((
us
->
flags
&
US_FL_MODE_XLATE
)
&&
(
old_cmnd
==
MODE_SENSE
))
...
...
drivers/usb/storage/scsiglue.c
View file @
40aafff3
...
...
@@ -219,7 +219,7 @@ static int usb_storage_device_reset( Scsi_Cmnd *srb )
int
state
=
atomic_read
(
&
us
->
sm_state
);
int
result
;
US_DEBUGP
(
"
device_reset() called
\n
"
);
US_DEBUGP
(
"
%s called
\n
"
,
__FUNCTION__
);
if
(
state
!=
US_STATE_IDLE
)
{
printk
(
KERN_ERR
USB_STORAGE
"Error in %s: "
"invalid state %d
\n
"
,
__FUNCTION__
,
state
);
...
...
@@ -245,39 +245,49 @@ static int usb_storage_device_reset( Scsi_Cmnd *srb )
return
result
;
}
/* This resets the device
port
*/
/* This resets the device
's USB port.
*/
/* It refuses to work if there's more than one interface in
this
device, so that other users are not affected. */
* the
device, so that other users are not affected. */
/* This is always called with scsi_lock(srb->host) held */
static
int
usb_storage_bus_reset
(
Scsi_Cmnd
*
srb
)
{
struct
us_data
*
us
;
struct
us_data
*
us
=
(
struct
us_data
*
)
srb
->
device
->
host
->
hostdata
[
0
];
int
state
=
atomic_read
(
&
us
->
sm_state
);
int
result
;
/* we use the usb_reset_device() function to handle this for us */
US_DEBUGP
(
"bus_reset() called
\n
"
);
US_DEBUGP
(
"%s called
\n
"
,
__FUNCTION__
);
if
(
state
!=
US_STATE_IDLE
)
{
printk
(
KERN_ERR
USB_STORAGE
"Error in %s: "
"invalid state %d
\n
"
,
__FUNCTION__
,
state
);
return
FAILED
;
}
/* set the state and release the lock */
atomic_set
(
&
us
->
sm_state
,
US_STATE_RESETTING
);
scsi_unlock
(
srb
->
device
->
host
);
us
=
(
struct
us_data
*
)
srb
->
device
->
host
->
hostdata
[
0
];
/* The USB subsystem doesn't handle synchronisation between
a device's several drivers. Therefore we reset only devices
with
one interface
which we of course own.
with
just one interface,
which we of course own.
*/
//FIXME: needs locking against config changes
if
(
us
->
pusb_dev
->
actconfig
->
desc
.
bNumInterfaces
==
1
)
{
/* attempt to reset the port */
if
(
us
->
pusb_dev
->
actconfig
->
desc
.
bNumInterfaces
==
1
)
{
/* lock the device and attempt to reset the port */
down
(
&
(
us
->
dev_semaphore
));
result
=
usb_reset_device
(
us
->
pusb_dev
);
up
(
&
(
us
->
dev_semaphore
));
US_DEBUGP
(
"usb_reset_device returns %d
\n
"
,
result
);
}
else
{
result
=
-
EBUSY
;
US_DEBUGP
(
"
cannot reset a multiinterface device. failing to reset.
\n
"
);
US_DEBUGP
(
"
Refusing to reset a multi-interface device
\n
"
);
}
US_DEBUGP
(
"bus_reset() complete
\n
"
);
/* lock access to the state and clear it */
scsi_lock
(
srb
->
device
->
host
);
atomic_set
(
&
us
->
sm_state
,
US_STATE_IDLE
);
return
result
<
0
?
FAILED
:
SUCCESS
;
}
...
...
drivers/usb/storage/transport.c
View file @
40aafff3
...
...
@@ -75,7 +75,7 @@
* below, which atomically tests-and-clears the URB_ACTIVE bit in us->flags
* to see if the current_urb needs to be stopped. Likewise, the SG_ACTIVE
* bit is tested to see if the current_sg scatter-gather request needs to be
* stopped.
* stopped.
The timeout callback routine does much the same thing.
*
* When a disconnect occurs, the DISCONNECTING bit in us->flags is set to
* prevent new URBs from being submitted, and usb_stor_stop_transport() is
...
...
@@ -109,6 +109,19 @@ static void usb_stor_blocking_completion(struct urb *urb, struct pt_regs *regs)
complete
(
urb_done_ptr
);
}
/* This is the timeout handler which will cancel an URB when its timeout
* expires.
*/
static
void
timeout_handler
(
unsigned
long
us_
)
{
struct
us_data
*
us
=
(
struct
us_data
*
)
us_
;
if
(
test_and_clear_bit
(
US_FLIDX_URB_ACTIVE
,
&
us
->
flags
))
{
US_DEBUGP
(
"Timeout -- cancelling URB
\n
"
);
usb_unlink_urb
(
us
->
current_urb
);
}
}
/* This is the common part of the URB message submission code
*
...
...
@@ -116,9 +129,10 @@ static void usb_stor_blocking_completion(struct urb *urb, struct pt_regs *regs)
* command _must_ pass through this function (or something like it) for the
* abort mechanisms to work properly.
*/
static
int
usb_stor_msg_common
(
struct
us_data
*
us
)
static
int
usb_stor_msg_common
(
struct
us_data
*
us
,
int
timeout
)
{
struct
completion
urb_done
;
struct
timer_list
to_timer
;
int
status
;
/* don't submit URBS during abort/disconnect processing */
...
...
@@ -155,24 +169,42 @@ static int usb_stor_msg_common(struct us_data *us)
usb_unlink_urb
(
us
->
current_urb
);
}
}
/* submit the timeout timer, if a timeout was requested */
if
(
timeout
>
0
)
{
init_timer
(
&
to_timer
);
to_timer
.
expires
=
jiffies
+
timeout
;
to_timer
.
function
=
timeout_handler
;
to_timer
.
data
=
(
unsigned
long
)
us
;
add_timer
(
&
to_timer
);
}
/* wait for the completion of the URB */
wait_for_completion
(
&
urb_done
);
clear_bit
(
US_FLIDX_URB_ACTIVE
,
&
us
->
flags
);
/* clean up the timeout timer */
if
(
timeout
>
0
)
del_timer_sync
(
&
to_timer
);
/* return the URB status */
return
us
->
current_urb
->
status
;
}
/* This is our function to emulate usb_control_msg() with enough control
* to make aborts/resets/timeouts work
/*
* Transfer one control message, with timeouts, and allowing early
* termination. Return codes are usual -Exxx, *not* USB_STOR_XFER_xxx.
*/
int
usb_stor_control_msg
(
struct
us_data
*
us
,
unsigned
int
pipe
,
u8
request
,
u8
requesttype
,
u16
value
,
u16
index
,
void
*
data
,
u16
size
)
u8
request
,
u8
requesttype
,
u16
value
,
u16
index
,
void
*
data
,
u16
size
,
int
timeout
)
{
int
status
;
US_DEBUGP
(
"%s: rq=%02x rqtype=%02x value=%04x index=%02x len=%u
\n
"
,
__FUNCTION__
,
request
,
requesttype
,
value
,
index
,
size
);
/* fill in the devrequest structure */
us
->
dr
->
bRequestType
=
requesttype
;
us
->
dr
->
bRequest
=
request
;
...
...
@@ -184,7 +216,7 @@ int usb_stor_control_msg(struct us_data *us, unsigned int pipe,
usb_fill_control_urb
(
us
->
current_urb
,
us
->
pusb_dev
,
pipe
,
(
unsigned
char
*
)
us
->
dr
,
data
,
size
,
usb_stor_blocking_completion
,
NULL
);
status
=
usb_stor_msg_common
(
us
);
status
=
usb_stor_msg_common
(
us
,
timeout
);
/* return the actual length of the data transferred if no error */
if
(
status
==
0
)
...
...
@@ -192,9 +224,9 @@ int usb_stor_control_msg(struct us_data *us, unsigned int pipe,
return
status
;
}
/* This is a version of usb_clear_halt() that
doesn't read the status from
*
the device -- this is because some devices crash their internal firmware
* when the status is requested after a halt.
/* This is a version of usb_clear_halt() that
allows early termination and
*
doesn't read the status from the device -- this is because some devices
*
crash their internal firmware
when the status is requested after a halt.
*
* A definitive list of these 'bad' devices is too difficult to maintain or
* make complete enough to be useful. This problem was first observed on the
...
...
@@ -214,12 +246,7 @@ int usb_stor_clear_halt(struct us_data *us, unsigned int pipe)
result
=
usb_stor_control_msg
(
us
,
us
->
send_ctrl_pipe
,
USB_REQ_CLEAR_FEATURE
,
USB_RECIP_ENDPOINT
,
0
,
endp
,
NULL
,
0
);
/* note: no 3*HZ timeout */
US_DEBUGP
(
"usb_stor_clear_halt: result=%d
\n
"
,
result
);
/* this is a failure case */
if
(
result
<
0
)
return
result
;
endp
,
NULL
,
0
,
3
*
HZ
);
/* reset the toggles and endpoint flags */
usb_endpoint_running
(
us
->
pusb_dev
,
usb_pipeendpoint
(
pipe
),
...
...
@@ -227,7 +254,8 @@ int usb_stor_clear_halt(struct us_data *us, unsigned int pipe)
usb_settoggle
(
us
->
pusb_dev
,
usb_pipeendpoint
(
pipe
),
usb_pipeout
(
pipe
),
0
);
return
0
;
US_DEBUGP
(
"%s: result = %d
\n
"
,
__FUNCTION__
,
result
);
return
result
;
}
...
...
@@ -317,7 +345,7 @@ int usb_stor_ctrl_transfer(struct us_data *us, unsigned int pipe,
usb_fill_control_urb
(
us
->
current_urb
,
us
->
pusb_dev
,
pipe
,
(
unsigned
char
*
)
us
->
dr
,
data
,
size
,
usb_stor_blocking_completion
,
NULL
);
result
=
usb_stor_msg_common
(
us
);
result
=
usb_stor_msg_common
(
us
,
0
);
return
interpret_urb_result
(
us
,
pipe
,
size
,
result
,
us
->
current_urb
->
actual_length
);
...
...
@@ -347,7 +375,7 @@ int usb_stor_intr_transfer(struct us_data *us, void *buf, unsigned int length)
usb_fill_int_urb
(
us
->
current_urb
,
us
->
pusb_dev
,
pipe
,
buf
,
maxp
,
usb_stor_blocking_completion
,
NULL
,
us
->
ep_bInterval
);
result
=
usb_stor_msg_common
(
us
);
result
=
usb_stor_msg_common
(
us
,
0
);
return
interpret_urb_result
(
us
,
pipe
,
length
,
result
,
us
->
current_urb
->
actual_length
);
...
...
@@ -368,7 +396,7 @@ int usb_stor_bulk_transfer_buf(struct us_data *us, unsigned int pipe,
/* fill and submit the URB */
usb_fill_bulk_urb
(
us
->
current_urb
,
us
->
pusb_dev
,
pipe
,
buf
,
length
,
usb_stor_blocking_completion
,
NULL
);
result
=
usb_stor_msg_common
(
us
);
result
=
usb_stor_msg_common
(
us
,
0
);
/* store the actual length of the data transferred */
if
(
act_len
)
...
...
@@ -490,7 +518,6 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us)
}
/* if there is a transport error, reset and don't auto-sense */
/* What if we want to abort during the reset? */
if
(
result
==
USB_STOR_TRANSPORT_ERROR
)
{
US_DEBUGP
(
"-- transport indicates error, resetting
\n
"
);
us
->
transport_reset
(
us
);
...
...
@@ -559,6 +586,7 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us)
unsigned
char
old_sc_data_direction
;
unsigned
char
old_cmd_len
;
unsigned
char
old_cmnd
[
MAX_COMMAND_SIZE
];
unsigned
long
old_serial_number
;
US_DEBUGP
(
"Issuing auto-REQUEST_SENSE
\n
"
);
...
...
@@ -594,6 +622,10 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us)
old_sg
=
srb
->
use_sg
;
srb
->
use_sg
=
0
;
/* change the serial number -- toggle the high bit*/
old_serial_number
=
srb
->
serial_number
;
srb
->
serial_number
^=
0x80000000
;
/* issue the auto-sense command */
temp_result
=
us
->
transport
(
us
->
srb
,
us
);
...
...
@@ -601,6 +633,7 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us)
srb
->
request_buffer
=
old_request_buffer
;
srb
->
request_bufflen
=
old_request_bufflen
;
srb
->
use_sg
=
old_sg
;
srb
->
serial_number
=
old_serial_number
;
srb
->
sc_data_direction
=
old_sc_data_direction
;
srb
->
cmd_len
=
old_cmd_len
;
memcpy
(
srb
->
cmnd
,
old_cmnd
,
MAX_COMMAND_SIZE
);
...
...
@@ -616,10 +649,8 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us)
* multi-target device, since failure of an
* auto-sense is perfectly valid
*/
if
(
!
(
us
->
flags
&
US_FL_SCM_MULT_TARG
))
{
/* What if we try to abort during the reset? */
if
(
!
(
us
->
flags
&
US_FL_SCM_MULT_TARG
))
us
->
transport_reset
(
us
);
}
srb
->
result
=
DID_ERROR
<<
16
;
return
;
}
...
...
@@ -638,19 +669,19 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us)
#endif
/* set the result so the higher layers expect this data */
srb
->
result
=
CHECK_CONDITION
<<
1
;
srb
->
result
=
SAM_STAT_CHECK_CONDITION
;
/* If things are really okay, then let's show that */
if
((
srb
->
sense_buffer
[
2
]
&
0xf
)
==
0x0
)
srb
->
result
=
GOOD
<<
1
;
srb
->
result
=
SAM_STAT_GOOD
;
}
else
/* if (need_auto_sense) */
srb
->
result
=
GOOD
<<
1
;
srb
->
result
=
SAM_STAT_GOOD
;
/* Regardless of auto-sense, if we _know_ we have an error
* condition, show that in the result code
*/
if
(
result
==
USB_STOR_TRANSPORT_FAILED
)
srb
->
result
=
CHECK_CONDITION
<<
1
;
srb
->
result
=
SAM_STAT_CHECK_CONDITION
;
/* If we think we're good, then make sure the sense data shows it.
* This is necessary because the auto-sense for some devices always
...
...
@@ -844,11 +875,8 @@ int usb_stor_Bulk_max_lun(struct us_data *us)
unsigned
char
data
;
int
result
;
/* Issue the command -- use usb_control_msg() because this is
* not a scsi queued-command. Also note that at this point the
* cached pipe values have not yet been stored. */
result
=
usb_control_msg
(
us
->
pusb_dev
,
usb_rcvctrlpipe
(
us
->
pusb_dev
,
0
),
/* issue the command */
result
=
usb_stor_control_msg
(
us
,
us
->
recv_ctrl_pipe
,
US_BULK_GET_MAX_LUN
,
USB_DIR_IN
|
USB_TYPE_CLASS
|
USB_RECIP_INTERFACE
,
...
...
@@ -982,43 +1010,40 @@ static int usb_stor_reset_common(struct us_data *us,
u16
value
,
u16
index
,
void
*
data
,
u16
size
)
{
int
result
;
int
result2
;
/* A 20-second timeout may seem rather long, but a LaCie
* StudioDrive USB2 device takes 16+ seconds to get going
* following a powerup or USB attach event. */
/* Use usb_control_msg() because this is not a queued-command */
result
=
usb_control_msg
(
us
->
pusb_dev
,
us
->
send_ctrl_pipe
,
result
=
usb_stor_control_msg
(
us
,
us
->
send_ctrl_pipe
,
request
,
requesttype
,
value
,
index
,
data
,
size
,
20
*
HZ
);
if
(
result
<
0
)
goto
Done
;
if
(
result
<
0
)
{
US_DEBUGP
(
"Soft reset failed: %d
\n
"
,
result
);
return
FAILED
;
}
/* long wait for reset */
/* long wait for reset, so unlock to allow disconnects */
up
(
&
us
->
dev_semaphore
);
set_current_state
(
TASK_UNINTERRUPTIBLE
);
schedule_timeout
(
HZ
*
6
);
set_current_state
(
TASK_RUNNING
);
down
(
&
us
->
dev_semaphore
);
/* Use usb_clear_halt() because this is not a queued-command */
US_DEBUGP
(
"Soft reset: clearing bulk-in endpoint halt
\n
"
);
result
=
usb_clear_halt
(
us
->
pusb_dev
,
us
->
recv_bulk_pipe
);
if
(
result
<
0
)
goto
Done
;
result
=
usb_stor_clear_halt
(
us
,
us
->
recv_bulk_pipe
);
US_DEBUGP
(
"Soft reset: clearing bulk-out endpoint halt
\n
"
);
result
=
usb_clear_halt
(
us
->
pusb_dev
,
us
->
send_bulk_pipe
);
Done:
result2
=
usb_stor_clear_halt
(
us
,
us
->
send_bulk_pipe
);
/* return a result code based on the result of the control message */
if
(
result
<
0
)
{
US_DEBUGP
(
"Soft reset failed: %d
\n
"
,
result
);
result
=
FAILED
;
}
else
{
US_DEBUGP
(
"Soft reset done
\n
"
);
result
=
SUCCESS
;
if
(
result
<
0
||
result2
<
0
)
{
US_DEBUGP
(
"Soft reset failed
\n
"
);
return
FAILED
;
}
return
result
;
US_DEBUGP
(
"Soft reset done
\n
"
);
return
SUCCESS
;
}
/* This issues a CB[I] Reset to the device in question
...
...
drivers/usb/storage/transport.h
View file @
40aafff3
...
...
@@ -160,9 +160,9 @@ extern void usb_stor_stop_transport(struct us_data*);
extern
int
usb_stor_control_msg
(
struct
us_data
*
us
,
unsigned
int
pipe
,
u8
request
,
u8
requesttype
,
u16
value
,
u16
index
,
void
*
data
,
u16
size
);
void
*
data
,
u16
size
,
int
timeout
);
extern
int
usb_stor_clear_halt
(
struct
us_data
*
us
,
unsigned
int
pipe
);
extern
int
usb_stor_clear_halt
(
struct
us_data
*
,
unsigned
int
pipe
);
extern
int
usb_stor_ctrl_transfer
(
struct
us_data
*
us
,
unsigned
int
pipe
,
u8
request
,
u8
requesttype
,
u16
value
,
u16
index
,
void
*
data
,
u16
size
);
...
...
drivers/usb/storage/usb.c
View file @
40aafff3
...
...
@@ -374,7 +374,7 @@ static int usb_stor_control_thread(void * __us)
memcpy
(
us
->
srb
->
sense_buffer
,
usb_stor_sense_invalidCDB
,
sizeof
(
usb_stor_sense_invalidCDB
));
us
->
srb
->
result
=
CHECK_CONDITION
<<
1
;
us
->
srb
->
result
=
SAM_STAT_CHECK_CONDITION
;
}
/* Handle those devices which need us to fake
...
...
@@ -387,7 +387,7 @@ static int usb_stor_control_thread(void * __us)
US_DEBUGP
(
"Faking INQUIRY command
\n
"
);
fill_inquiry_response
(
us
,
data_ptr
,
36
);
us
->
srb
->
result
=
GOOD
<<
1
;
us
->
srb
->
result
=
SAM_STAT_GOOD
;
}
/* we've got a command, let's do it! */
...
...
@@ -412,9 +412,11 @@ static int usb_stor_control_thread(void * __us)
US_DEBUGP
(
"scsi command aborted
\n
"
);
}
/* in case an abort request was received after the command
* completed, we must use a separate test to see whether
* we need to signal that the abort has finished */
/* If an abort request was received we need to signal that
* the abort has finished. The proper test for this is
* sm_state == US_STATE_ABORTING, not srb->result == DID_ABORT,
* because an abort request might be received after all the
* USB processing was complete. */
if
(
atomic_read
(
&
us
->
sm_state
)
==
US_STATE_ABORTING
)
complete
(
&
(
us
->
notify
));
...
...
@@ -715,7 +717,6 @@ static int storage_probe(struct usb_interface *intf,
us
->
transport_name
=
"Bulk"
;
us
->
transport
=
usb_stor_Bulk_transport
;
us
->
transport_reset
=
usb_stor_Bulk_reset
;
us
->
max_lun
=
usb_stor_Bulk_max_lun
(
us
);
break
;
#ifdef CONFIG_USB_STORAGE_HP8200e
...
...
@@ -842,6 +843,10 @@ static int storage_probe(struct usb_interface *intf,
if
(
usb_stor_allocate_urbs
(
us
))
goto
BadDevice
;
/* For bulk-only devices, determine the max LUN value */
if
(
us
->
protocol
==
US_PR_BULK
)
us
->
max_lun
=
usb_stor_Bulk_max_lun
(
us
);
/*
* Since this is a new device, we need to generate a scsi
* host definition, and register with the higher SCSI layers
...
...
drivers/usb/storage/usb.h
View file @
40aafff3
...
...
@@ -82,7 +82,7 @@ struct us_unusual_dev {
#define US_FLIDX_SG_ACTIVE 19
/* 0x00080000 current_sg is in use */
#define US_FLIDX_ABORTING 20
/* 0x00100000 abort is in progress */
#define US_FLIDX_DISCONNECTING 21
/* 0x00200000 disconnect in progress */
#define DONT_SUBMIT ((1UL << US_FLIDX_ABORTING) |
|
\
#define DONT_SUBMIT ((1UL << US_FLIDX_ABORTING) | \
(1UL << US_FLIDX_DISCONNECTING))
...
...
include/linux/usb.h
View file @
40aafff3
...
...
@@ -278,6 +278,8 @@ extern void usb_put_dev(struct usb_device *dev);
/* mostly for devices emulating SCSI over USB */
extern
int
usb_reset_device
(
struct
usb_device
*
dev
);
extern
struct
usb_device
*
usb_find_device
(
u16
vendor_id
,
u16
product_id
);
/* for drivers using iso endpoints */
extern
int
usb_get_current_frame_number
(
struct
usb_device
*
usb_dev
);
...
...
security/Kconfig
View file @
40aafff3
...
...
@@ -33,7 +33,7 @@ config SECURITY_CAPABILITIES
config
SECURITY_ROOTPLUG
tristate
"Root Plug Support"
depends
on
SECURITY
!=n
depends
on
USB
&&
SECURITY
!=n
help
This
is
a
sample
LSM
module
that
should
only
be
used
as
such
.
It
prevents
any
programs
running
with
egid
==
0
if
a
specific
...
...
security/root_plug.c
View file @
40aafff3
...
...
@@ -54,7 +54,7 @@ MODULE_PARM_DESC(debug, "Debug enabled or not");
#define MY_NAME "root_plug"
#endif
#define dbg(fmt, arg...) \
#define
root_
dbg(fmt, arg...) \
do { \
if (debug) \
printk(KERN_DEBUG "%s: %s: " fmt , \
...
...
@@ -62,70 +62,21 @@ MODULE_PARM_DESC(debug, "Debug enabled or not");
## arg); \
} while (0)
extern
struct
list_head
usb_bus_list
;
extern
struct
semaphore
usb_bus_list_lock
;
static
int
match_device
(
struct
usb_device
*
dev
)
{
int
retval
=
-
ENODEV
;
int
child
;
dbg
(
"looking at vendor %d, product %d
\n
"
,
dev
->
descriptor
.
idVendor
,
dev
->
descriptor
.
idProduct
);
/* see if this device matches */
if
((
dev
->
descriptor
.
idVendor
==
vendor_id
)
&&
(
dev
->
descriptor
.
idProduct
==
product_id
))
{
dbg
(
"found the device!
\n
"
);
retval
=
0
;
goto
exit
;
}
/* look through all of the children of this device */
for
(
child
=
0
;
child
<
dev
->
maxchild
;
++
child
)
{
if
(
dev
->
children
[
child
])
{
retval
=
match_device
(
dev
->
children
[
child
]);
if
(
retval
==
0
)
goto
exit
;
}
}
exit:
return
retval
;
}
static
int
find_usb_device
(
void
)
{
struct
list_head
*
buslist
;
struct
usb_bus
*
bus
;
int
retval
=
-
ENODEV
;
down
(
&
usb_bus_list_lock
);
for
(
buslist
=
usb_bus_list
.
next
;
buslist
!=
&
usb_bus_list
;
buslist
=
buslist
->
next
)
{
bus
=
container_of
(
buslist
,
struct
usb_bus
,
bus_list
);
retval
=
match_device
(
bus
->
root_hub
);
if
(
retval
==
0
)
goto
exit
;
}
exit:
up
(
&
usb_bus_list_lock
);
return
retval
;
}
static
int
rootplug_bprm_check_security
(
struct
linux_binprm
*
bprm
)
{
dbg
(
"file %s, e_uid = %d, e_gid = %d
\n
"
,
bprm
->
filename
,
bprm
->
e_uid
,
bprm
->
e_gid
);
struct
usb_device
*
dev
;
root_dbg
(
"file %s, e_uid = %d, e_gid = %d
\n
"
,
bprm
->
filename
,
bprm
->
e_uid
,
bprm
->
e_gid
);
if
(
bprm
->
e_gid
==
0
)
{
if
(
find_usb_device
()
!=
0
)
{
dbg
(
"e_gid = 0, and device not found, "
"task not allowed to run...
\n
"
);
dev
=
usb_find_device
(
vendor_id
,
product_id
);
if
(
!
dev
)
{
root_dbg
(
"e_gid = 0, and device not found, "
"task not allowed to run...
\n
"
);
return
-
EPERM
;
}
usb_put_dev
(
dev
);
}
return
0
;
...
...
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