Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
8a51beef
Commit
8a51beef
authored
Apr 22, 2004
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://kernel.bkbits.net/davem/net-2.6
into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents
88d0505c
c8682fb0
Changes
18
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
282 additions
and
172 deletions
+282
-172
drivers/base/firmware_class.c
drivers/base/firmware_class.c
+1
-1
drivers/char/tipar.c
drivers/char/tipar.c
+1
-1
drivers/i2c/chips/eeprom.c
drivers/i2c/chips/eeprom.c
+1
-0
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/qla2xxx/qla_os.c
+2
-0
drivers/usb/class/cdc-acm.c
drivers/usb/class/cdc-acm.c
+51
-38
drivers/usb/core/hcd-pci.c
drivers/usb/core/hcd-pci.c
+5
-0
drivers/usb/gadget/ether.c
drivers/usb/gadget/ether.c
+28
-21
drivers/usb/gadget/rndis.c
drivers/usb/gadget/rndis.c
+87
-48
drivers/usb/gadget/rndis.h
drivers/usb/gadget/rndis.h
+5
-2
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-hcd.c
+14
-3
drivers/usb/host/ehci-hub.c
drivers/usb/host/ehci-hub.c
+10
-6
drivers/usb/host/uhci-hcd.c
drivers/usb/host/uhci-hcd.c
+22
-14
drivers/usb/misc/tiglusb.c
drivers/usb/misc/tiglusb.c
+26
-26
drivers/usb/net/usbnet.c
drivers/usb/net/usbnet.c
+5
-1
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio.c
+2
-2
drivers/usb/storage/dpcm.c
drivers/usb/storage/dpcm.c
+6
-3
fs/sysfs/bin.c
fs/sysfs/bin.c
+13
-3
fs/sysfs/symlink.c
fs/sysfs/symlink.c
+3
-3
No files found.
drivers/base/firmware_class.c
View file @
8a51beef
...
@@ -254,7 +254,7 @@ firmware_data_write(struct kobject *kobj,
...
@@ -254,7 +254,7 @@ firmware_data_write(struct kobject *kobj,
return
retval
;
return
retval
;
}
}
static
struct
bin_attribute
firmware_attr_data_tmpl
=
{
static
struct
bin_attribute
firmware_attr_data_tmpl
=
{
.
attr
=
{.
name
=
"data"
,
.
mode
=
0644
},
.
attr
=
{.
name
=
"data"
,
.
mode
=
0644
,
.
owner
=
THIS_MODULE
},
.
size
=
0
,
.
size
=
0
,
.
read
=
firmware_data_read
,
.
read
=
firmware_data_read
,
.
write
=
firmware_data_write
,
.
write
=
firmware_data_write
,
...
...
drivers/char/tipar.c
View file @
8a51beef
...
@@ -121,7 +121,7 @@ init_ti_parallel(int minor)
...
@@ -121,7 +121,7 @@ init_ti_parallel(int minor)
/* ----- global defines ----------------------------------------------- */
/* ----- global defines ----------------------------------------------- */
#define START(x) { x
=jiffies+HZ/(timeout/10)
; }
#define START(x) { x
= jiffies + (HZ * timeout) / 10
; }
#define WAIT(x) { \
#define WAIT(x) { \
if (time_before((x), jiffies)) return -1; \
if (time_before((x), jiffies)) return -1; \
if (need_resched()) schedule(); }
if (need_resched()) schedule(); }
...
...
drivers/i2c/chips/eeprom.c
View file @
8a51beef
...
@@ -155,6 +155,7 @@ static struct bin_attribute eeprom_attr = {
...
@@ -155,6 +155,7 @@ static struct bin_attribute eeprom_attr = {
.
attr
=
{
.
attr
=
{
.
name
=
"eeprom"
,
.
name
=
"eeprom"
,
.
mode
=
S_IRUGO
,
.
mode
=
S_IRUGO
,
.
owner
=
THIS_MODULE
,
},
},
.
size
=
EEPROM_SIZE
,
.
size
=
EEPROM_SIZE
,
.
read
=
eeprom_read
,
.
read
=
eeprom_read
,
...
...
drivers/scsi/qla2xxx/qla_os.c
View file @
8a51beef
...
@@ -402,6 +402,7 @@ static struct bin_attribute sysfs_fw_dump_attr = {
...
@@ -402,6 +402,7 @@ static struct bin_attribute sysfs_fw_dump_attr = {
.
attr
=
{
.
attr
=
{
.
name
=
"fw_dump"
,
.
name
=
"fw_dump"
,
.
mode
=
S_IRUSR
|
S_IWUSR
,
.
mode
=
S_IRUSR
|
S_IWUSR
,
.
owner
=
THIS_MODULE
,
},
},
.
size
=
0
,
.
size
=
0
,
.
read
=
qla2x00_sysfs_read_fw_dump
,
.
read
=
qla2x00_sysfs_read_fw_dump
,
...
@@ -415,6 +416,7 @@ static struct bin_attribute sysfs_nvram_attr = {
...
@@ -415,6 +416,7 @@ static struct bin_attribute sysfs_nvram_attr = {
.
attr
=
{
.
attr
=
{
.
name
=
"nvram"
,
.
name
=
"nvram"
,
.
mode
=
S_IRUSR
|
S_IWUSR
,
.
mode
=
S_IRUSR
|
S_IWUSR
,
.
owner
=
THIS_MODULE
,
},
},
.
size
=
sizeof
(
nvram_t
),
.
size
=
sizeof
(
nvram_t
),
.
read
=
qla2x00_sysfs_read_nvram
,
.
read
=
qla2x00_sysfs_read_nvram
,
...
...
drivers/usb/class/cdc-acm.c
View file @
8a51beef
...
@@ -573,53 +573,61 @@ static int acm_probe (struct usb_interface *intf,
...
@@ -573,53 +573,61 @@ static int acm_probe (struct usb_interface *intf,
struct
usb_device
*
dev
;
struct
usb_device
*
dev
;
struct
acm
*
acm
;
struct
acm
*
acm
;
struct
usb_host_config
*
cfacm
;
struct
usb_host_config
*
cfacm
;
struct
usb_interface
*
data
;
struct
usb_interface
*
data
=
NULL
;
struct
usb_host_interface
*
ifcom
,
*
ifdata
;
struct
usb_host_interface
*
ifcom
,
*
ifdata
=
NULL
;
struct
usb_endpoint_descriptor
*
epctrl
,
*
epread
,
*
epwrite
;
struct
usb_endpoint_descriptor
*
epctrl
=
NULL
;
struct
usb_endpoint_descriptor
*
epread
=
NULL
;
struct
usb_endpoint_descriptor
*
epwrite
=
NULL
;
int
readsize
,
ctrlsize
,
minor
,
j
;
int
readsize
,
ctrlsize
,
minor
,
j
;
unsigned
char
*
buf
;
unsigned
char
*
buf
;
dev
=
interface_to_usbdev
(
intf
);
dev
=
interface_to_usbdev
(
intf
);
cfacm
=
dev
->
actconfig
;
cfacm
=
dev
->
actconfig
;
for
(
j
=
0
;
j
<
cfacm
->
desc
.
bNumInterfaces
-
1
;
j
++
)
{
/* We know we're probe()d with the control interface. */
ifcom
=
intf
->
cur_altsetting
;
if
(
usb_interface_claimed
(
cfacm
->
interface
[
j
])
||
usb_interface_claimed
(
cfacm
->
interface
[
j
+
1
]))
continue
;
/* We know we're probe()d with the control interface.
/* ACM doesn't guarantee the data interface is
* FIXME ACM doesn't guarantee the data interface is
* adjacent to the control interface, or that if one
* adjacent to the control interface, or that if one
* is there it's not for call management ... so
use
* is there it's not for call management ... so
find
*
the cdc union descriptor whenever there is one.
*
it
*/
*/
ifcom
=
intf
->
cur_altsetting
;
for
(
j
=
0
;
j
<
cfacm
->
desc
.
bNumInterfaces
;
j
++
)
{
if
(
intf
==
cfacm
->
interface
[
j
])
{
ifdata
=
cfacm
->
interface
[
j
+
1
]
->
cur_altsetting
;
data
=
cfacm
->
interface
[
j
+
1
];
}
else
if
(
intf
==
cfacm
->
interface
[
j
+
1
])
{
ifdata
=
cfacm
->
interface
[
j
]
->
cur_altsetting
;
ifdata
=
cfacm
->
interface
[
j
]
->
cur_altsetting
;
data
=
cfacm
->
interface
[
j
];
data
=
cfacm
->
interface
[
j
];
}
else
continue
;
if
(
ifdata
->
desc
.
bInterfaceClass
!=
10
||
ifdata
->
desc
.
bNumEndpoints
<
2
)
if
(
ifdata
->
desc
.
bInterfaceClass
==
10
&&
continue
;
ifdata
->
desc
.
bNumEndpoints
==
2
)
{
epctrl
=
&
ifcom
->
endpoint
[
0
].
desc
;
epctrl
=
&
ifcom
->
endpoint
[
0
].
desc
;
epread
=
&
ifdata
->
endpoint
[
0
].
desc
;
epread
=
&
ifdata
->
endpoint
[
0
].
desc
;
epwrite
=
&
ifdata
->
endpoint
[
1
].
desc
;
epwrite
=
&
ifdata
->
endpoint
[
1
].
desc
;
if
((
epctrl
->
bEndpointAddress
&
0x80
)
!=
0x80
||
(
epctrl
->
bmAttributes
&
3
)
!=
3
||
(
epread
->
bmAttributes
&
3
)
!=
2
||
(
epwrite
->
bmAttributes
&
3
)
!=
2
||
((
epread
->
bEndpointAddress
&
0x80
)
^
(
epwrite
->
bEndpointAddress
&
0x80
))
!=
0x80
)
goto
next_interface
;
if
((
epread
->
bEndpointAddress
&
0x80
)
!=
0x80
)
{
epread
=
&
ifdata
->
endpoint
[
1
].
desc
;
epwrite
=
&
ifdata
->
endpoint
[
0
].
desc
;
}
dbg
(
"found data interface at %d
\n
"
,
j
);
break
;
}
else
{
next_interface:
ifdata
=
NULL
;
data
=
NULL
;
}
}
if
((
epctrl
->
bEndpointAddress
&
0x80
)
!=
0x80
||
(
epctrl
->
bmAttributes
&
3
)
!=
3
||
/* there's been a problem */
(
epread
->
bmAttributes
&
3
)
!=
2
||
(
epwrite
->
bmAttributes
&
3
)
!=
2
||
if
(
!
ifdata
)
{
((
epread
->
bEndpointAddress
&
0x80
)
^
(
epwrite
->
bEndpointAddress
&
0x80
))
!=
0x80
)
dbg
(
"interface not found (%p)
\n
"
,
ifdata
);
continue
;
return
-
ENODEV
;
if
((
epread
->
bEndpointAddress
&
0x80
)
!=
0x80
)
{
epread
=
&
ifdata
->
endpoint
[
1
].
desc
;
epwrite
=
&
ifdata
->
endpoint
[
0
].
desc
;
}
}
for
(
minor
=
0
;
minor
<
ACM_TTY_MINORS
&&
acm_table
[
minor
];
minor
++
);
for
(
minor
=
0
;
minor
<
ACM_TTY_MINORS
&&
acm_table
[
minor
];
minor
++
);
...
@@ -696,16 +704,21 @@ static int acm_probe (struct usb_interface *intf,
...
@@ -696,16 +704,21 @@ static int acm_probe (struct usb_interface *intf,
acm
->
line
.
databits
=
8
;
acm
->
line
.
databits
=
8
;
acm_set_line
(
acm
,
&
acm
->
line
);
acm_set_line
(
acm
,
&
acm
->
line
);
usb_driver_claim_interface
(
&
acm_driver
,
data
,
acm
);
if
(
(
j
=
usb_driver_claim_interface
(
&
acm_driver
,
data
,
acm
))
!=
0
)
{
err
(
"claim failed"
);
usb_free_urb
(
acm
->
ctrlurb
);
usb_free_urb
(
acm
->
readurb
);
usb_free_urb
(
acm
->
writeurb
);
kfree
(
acm
);
kfree
(
buf
);
return
j
;
}
tty_register_device
(
acm_tty_driver
,
minor
,
&
intf
->
dev
);
tty_register_device
(
acm_tty_driver
,
minor
,
&
intf
->
dev
);
acm_table
[
minor
]
=
acm
;
acm_table
[
minor
]
=
acm
;
usb_set_intfdata
(
intf
,
acm
);
usb_set_intfdata
(
intf
,
acm
);
return
0
;
return
0
;
}
return
-
EIO
;
}
}
static
void
acm_disconnect
(
struct
usb_interface
*
intf
)
static
void
acm_disconnect
(
struct
usb_interface
*
intf
)
...
...
drivers/usb/core/hcd-pci.c
View file @
8a51beef
...
@@ -284,6 +284,11 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, u32 state)
...
@@ -284,6 +284,11 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, u32 state)
dev_dbg
(
hcd
->
self
.
controller
,
"suspend D%d --> D%d
\n
"
,
dev_dbg
(
hcd
->
self
.
controller
,
"suspend D%d --> D%d
\n
"
,
dev
->
current_state
,
state
);
dev
->
current_state
,
state
);
if
(
pci_find_capability
(
dev
,
PCI_CAP_ID_PM
))
{
dev_dbg
(
hcd
->
self
.
controller
,
"No PM capability
\n
"
);
return
0
;
}
switch
(
hcd
->
state
)
{
switch
(
hcd
->
state
)
{
case
USB_STATE_HALT
:
case
USB_STATE_HALT
:
dev_dbg
(
hcd
->
self
.
controller
,
"halted; hcd not suspended
\n
"
);
dev_dbg
(
hcd
->
self
.
controller
,
"halted; hcd not suspended
\n
"
);
...
...
drivers/usb/gadget/ether.c
View file @
8a51beef
...
@@ -120,6 +120,7 @@ struct eth_dev {
...
@@ -120,6 +120,7 @@ struct eth_dev {
unsigned
long
todo
;
unsigned
long
todo
;
#define WORK_RX_MEMORY 0
#define WORK_RX_MEMORY 0
int
rndis_config
;
int
rndis_config
;
u8
host_mac
[
ETH_ALEN
];
};
};
/* This version autoconfigures as much as possible at run-time.
/* This version autoconfigures as much as possible at run-time.
...
@@ -159,9 +160,8 @@ static const char *EP_STATUS_NAME;
...
@@ -159,9 +160,8 @@ static const char *EP_STATUS_NAME;
/* For hardware that can talk RNDIS and either of the above protocols,
/* For hardware that can talk RNDIS and either of the above protocols,
* use this ID ... the windows INF files will know it. Unless it's
* use this ID ... the windows INF files will know it. Unless it's
* used with CDC Ethernet, Linux hosts will need updates to choose the
* used with CDC Ethernet, Linux 2.4 hosts will need updates to choose
* non-MSFT configuration, either in the kernel (2.4) or else from a
* the non-RNDIS configuration.
* hotplug script (2.6).
*/
*/
#define RNDIS_VENDOR_NUM 0x0525
/* NetChip */
#define RNDIS_VENDOR_NUM 0x0525
/* NetChip */
#define RNDIS_PRODUCT_NUM 0xa4a2
/* Ethernet/RNDIS Gadget */
#define RNDIS_PRODUCT_NUM 0xa4a2
/* Ethernet/RNDIS Gadget */
...
@@ -1334,8 +1334,10 @@ static void rndis_command_complete (struct usb_ep *ep, struct usb_request *req)
...
@@ -1334,8 +1334,10 @@ static void rndis_command_complete (struct usb_ep *ep, struct usb_request *req)
struct
eth_dev
*
dev
=
ep
->
driver_data
;
struct
eth_dev
*
dev
=
ep
->
driver_data
;
/* received RNDIS command from CDC_SEND_ENCAPSULATED_COMMAND */
/* received RNDIS command from CDC_SEND_ENCAPSULATED_COMMAND */
spin_lock
(
&
dev
->
lock
);
if
(
rndis_msg_parser
(
dev
->
rndis_config
,
(
u8
*
)
req
->
buf
))
if
(
rndis_msg_parser
(
dev
->
rndis_config
,
(
u8
*
)
req
->
buf
))
ERROR
(
dev
,
"%s: rndis parse error
\n
"
,
__FUNCTION__
);
ERROR
(
dev
,
"%s: rndis parse error
\n
"
,
__FUNCTION__
);
spin_unlock
(
&
dev
->
lock
);
}
}
#endif
/* RNDIS */
#endif
/* RNDIS */
...
@@ -1486,14 +1488,14 @@ eth_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
...
@@ -1486,14 +1488,14 @@ eth_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
||
!
dev
->
config
||
!
dev
->
config
||
ctrl
->
wIndex
>
1
)
||
ctrl
->
wIndex
>
1
)
break
;
break
;
if
(
!
dev
->
cdc
&&
ctrl
->
wIndex
!=
0
)
if
(
!
(
dev
->
cdc
||
dev
->
rndis
)
&&
ctrl
->
wIndex
!=
0
)
break
;
break
;
/*
i
f carrier is on, data interface is active. */
/*
for CDC, if
f carrier is on, data interface is active. */
*
(
u8
*
)
req
->
buf
=
if
(
dev
->
rndis
||
ctrl
->
wIndex
!=
1
)
((
ctrl
->
wIndex
==
1
)
&&
netif_carrier_ok
(
dev
->
net
))
*
(
u8
*
)
req
->
buf
=
0
;
?
1
else
:
0
,
*
(
u8
*
)
req
->
buf
=
netif_carrier_ok
(
dev
->
net
)
?
1
:
0
;
value
=
min
(
ctrl
->
wLength
,
(
u16
)
1
);
value
=
min
(
ctrl
->
wLength
,
(
u16
)
1
);
break
;
break
;
...
@@ -1552,6 +1554,7 @@ eth_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
...
@@ -1552,6 +1554,7 @@ eth_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
memcpy
(
req
->
buf
,
buf
,
value
);
memcpy
(
req
->
buf
,
buf
,
value
);
req
->
complete
=
rndis_response_complete
;
req
->
complete
=
rndis_response_complete
;
}
}
/* else stalls ... spec says to avoid that */
}
}
break
;
break
;
#endif
/* RNDIS */
#endif
/* RNDIS */
...
@@ -1590,6 +1593,8 @@ eth_disconnect (struct usb_gadget *gadget)
...
@@ -1590,6 +1593,8 @@ eth_disconnect (struct usb_gadget *gadget)
eth_reset_config
(
dev
);
eth_reset_config
(
dev
);
spin_unlock_irqrestore
(
&
dev
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
dev
->
lock
,
flags
);
/* FIXME RNDIS should enter RNDIS_UNINITIALIZED */
/* next we may get setup() calls to enumerate new connections;
/* next we may get setup() calls to enumerate new connections;
* or an unbind() during shutdown (including removing module).
* or an unbind() during shutdown (including removing module).
*/
*/
...
@@ -2376,19 +2381,19 @@ eth_bind (struct usb_gadget *gadget)
...
@@ -2376,19 +2381,19 @@ eth_bind (struct usb_gadget *gadget)
*/
*/
random_ether_addr
(
net
->
dev_addr
);
random_ether_addr
(
net
->
dev_addr
);
#ifdef DEV_CONFIG_CDC
/* ... another address for the host, on the other end of the
/* ... another address for the host, on the other end of the
* link, gets exported through CDC (see CDC spec table 41)
* link, gets exported through CDC (see CDC spec table 41)
* and RNDIS.
*/
*/
if
(
cdc
)
{
if
(
cdc
||
rndis
)
{
u8
node_id
[
ETH_ALEN
];
random_ether_addr
(
dev
->
host_mac
);
#ifdef DEV_CONFIG_CDC
random_ether_addr
(
node_id
);
snprintf
(
ethaddr
,
sizeof
ethaddr
,
"%02X%02X%02X%02X%02X%02X"
,
snprintf
(
ethaddr
,
sizeof
ethaddr
,
"%02X%02X%02X%02X%02X%02X"
,
node_id
[
0
],
node_id
[
1
],
node_id
[
2
],
dev
->
host_mac
[
0
],
dev
->
host_mac
[
1
],
node_id
[
3
],
node_id
[
4
],
node_id
[
5
]);
dev
->
host_mac
[
2
],
dev
->
host_mac
[
3
],
}
dev
->
host_mac
[
4
],
dev
->
host_mac
[
5
]);
#endif
#endif
}
if
(
rndis
)
{
if
(
rndis
)
{
status
=
rndis_init
();
status
=
rndis_init
();
...
@@ -2448,10 +2453,11 @@ eth_bind (struct usb_gadget *gadget)
...
@@ -2448,10 +2453,11 @@ eth_bind (struct usb_gadget *gadget)
net
->
dev_addr
[
2
],
net
->
dev_addr
[
3
],
net
->
dev_addr
[
2
],
net
->
dev_addr
[
3
],
net
->
dev_addr
[
4
],
net
->
dev_addr
[
5
]);
net
->
dev_addr
[
4
],
net
->
dev_addr
[
5
]);
#ifdef DEV_CONFIG_CDC
if
(
cdc
||
rndis
)
if
(
cdc
)
INFO
(
dev
,
"HOST MAC %02x:%02x:%02x:%02x:%02x:%02x
\n
"
,
INFO
(
dev
,
"CDC host enet %s
\n
"
,
ethaddr
);
dev
->
host_mac
[
0
],
dev
->
host_mac
[
1
],
#endif
dev
->
host_mac
[
2
],
dev
->
host_mac
[
3
],
dev
->
host_mac
[
4
],
dev
->
host_mac
[
5
]);
#ifdef CONFIG_USB_ETH_RNDIS
#ifdef CONFIG_USB_ETH_RNDIS
if
(
rndis
)
{
if
(
rndis
)
{
...
@@ -2468,6 +2474,7 @@ eth_bind (struct usb_gadget *gadget)
...
@@ -2468,6 +2474,7 @@ eth_bind (struct usb_gadget *gadget)
}
}
/* these set up a lot of the OIDs that RNDIS needs */
/* these set up a lot of the OIDs that RNDIS needs */
rndis_set_host_mac
(
dev
->
rndis_config
,
dev
->
host_mac
);
if
(
rndis_set_param_dev
(
dev
->
rndis_config
,
dev
->
net
,
if
(
rndis_set_param_dev
(
dev
->
rndis_config
,
dev
->
net
,
&
dev
->
stats
))
&
dev
->
stats
))
goto
fail0
;
goto
fail0
;
...
...
drivers/usb/gadget/rndis.c
View file @
8a51beef
...
@@ -37,6 +37,16 @@
...
@@ -37,6 +37,16 @@
#include "rndis.h"
#include "rndis.h"
/* The driver for your USB chip needs to support ep0 OUT to work with
* RNDIS, plus the same three descriptors as CDC Ethernet.
*
* Windows hosts need an INF file like Documentation/usb/linux.inf
*/
#ifndef __LITTLE_ENDIAN
#warning this code is missing all cpu_to_leXX() calls ...
#endif
#if 0
#if 0
#define DEBUG if (rndis_debug) printk
#define DEBUG if (rndis_debug) printk
static int rndis_debug = 0;
static int rndis_debug = 0;
...
@@ -89,8 +99,12 @@ static u32 devFlags2currentFilter (struct net_device *dev)
...
@@ -89,8 +99,12 @@ static u32 devFlags2currentFilter (struct net_device *dev)
static
void
currentFilter2devFlags
(
u32
currentFilter
,
struct
net_device
*
dev
)
static
void
currentFilter2devFlags
(
u32
currentFilter
,
struct
net_device
*
dev
)
{
{
/* FIXME the filter is supposed to control what gets
* forwarded from gadget to host; but dev->flags controls
* reporting from host to gadget ...
*/
#if 0
if (!dev) return;
if (!dev) return;
if (currentFilter & NDIS_PACKET_TYPE_MULTICAST)
if (currentFilter & NDIS_PACKET_TYPE_MULTICAST)
dev->flags |= IFF_MULTICAST;
dev->flags |= IFF_MULTICAST;
if (currentFilter & NDIS_PACKET_TYPE_BROADCAST)
if (currentFilter & NDIS_PACKET_TYPE_BROADCAST)
...
@@ -99,8 +113,13 @@ static void currentFilter2devFlags (u32 currentFilter, struct net_device *dev)
...
@@ -99,8 +113,13 @@ static void currentFilter2devFlags (u32 currentFilter, struct net_device *dev)
dev->flags |= IFF_ALLMULTI;
dev->flags |= IFF_ALLMULTI;
if (currentFilter & NDIS_PACKET_TYPE_PROMISCUOUS)
if (currentFilter & NDIS_PACKET_TYPE_PROMISCUOUS)
dev->flags |= IFF_PROMISC;
dev->flags |= IFF_PROMISC;
#endif
}
}
/* FIXME OMITTED OIDs, that RNDIS-on-USB "must" support, include
* - power management (OID_PNP_CAPABILITIES, ...)
* - network wakeup (OID_PNP_ENABLE_WAKE_UP, ...)
*/
/* NDIS Functions */
/* NDIS Functions */
static
int
gen_ndis_query_resp
(
int
configNr
,
u32
OID
,
rndis_resp_t
*
r
)
static
int
gen_ndis_query_resp
(
int
configNr
,
u32
OID
,
rndis_resp_t
*
r
)
...
@@ -114,8 +133,6 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
...
@@ -114,8 +133,6 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
if
(
!
resp
)
return
-
ENOMEM
;
if
(
!
resp
)
return
-
ENOMEM
;
if
(
!
resp
)
return
-
ENOMEM
;
switch
(
OID
)
{
switch
(
OID
)
{
/* mandatory */
/* mandatory */
case
OID_GEN_SUPPORTED_LIST
:
case
OID_GEN_SUPPORTED_LIST
:
...
@@ -178,7 +195,8 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
...
@@ -178,7 +195,8 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
case
OID_GEN_LINK_SPEED
:
case
OID_GEN_LINK_SPEED
:
DEBUG
(
"%s: OID_GEN_LINK_SPEED
\n
"
,
__FUNCTION__
);
DEBUG
(
"%s: OID_GEN_LINK_SPEED
\n
"
,
__FUNCTION__
);
length
=
4
;
length
=
4
;
if
(
rndis_per_dev_params
[
configNr
].
media_state
)
if
(
rndis_per_dev_params
[
configNr
].
media_state
==
NDIS_MEDIA_STATE_DISCONNECTED
)
*
((
u32
*
)
resp
+
6
)
=
0
;
*
((
u32
*
)
resp
+
6
)
=
0
;
else
else
*
((
u32
*
)
resp
+
6
)
=
rndis_per_dev_params
[
configNr
].
speed
;
*
((
u32
*
)
resp
+
6
)
=
rndis_per_dev_params
[
configNr
].
speed
;
...
@@ -611,15 +629,10 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
...
@@ -611,15 +629,10 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
case
OID_802_3_PERMANENT_ADDRESS
:
case
OID_802_3_PERMANENT_ADDRESS
:
DEBUG
(
"%s: OID_802_3_PERMANENT_ADDRESS
\n
"
,
__FUNCTION__
);
DEBUG
(
"%s: OID_802_3_PERMANENT_ADDRESS
\n
"
,
__FUNCTION__
);
if
(
rndis_per_dev_params
[
configNr
].
dev
)
{
if
(
rndis_per_dev_params
[
configNr
].
dev
)
{
length
=
6
;
length
=
ETH_ALEN
;
memcpy
((
u8
*
)
resp
+
24
,
memcpy
((
u8
*
)
resp
+
24
,
rndis_per_dev_params
[
configNr
].
dev
->
dev_addr
,
rndis_per_dev_params
[
configNr
].
host_mac
,
length
);
length
);
/*
* we need a MAC address and hope that
* (our MAC + 1) is not in use
*/
*
((
u8
*
)
resp
+
29
)
+=
1
;
retval
=
0
;
retval
=
0
;
}
else
{
}
else
{
*
((
u32
*
)
resp
+
6
)
=
0
;
*
((
u32
*
)
resp
+
6
)
=
0
;
...
@@ -631,15 +644,10 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
...
@@ -631,15 +644,10 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
case
OID_802_3_CURRENT_ADDRESS
:
case
OID_802_3_CURRENT_ADDRESS
:
DEBUG
(
"%s: OID_802_3_CURRENT_ADDRESS
\n
"
,
__FUNCTION__
);
DEBUG
(
"%s: OID_802_3_CURRENT_ADDRESS
\n
"
,
__FUNCTION__
);
if
(
rndis_per_dev_params
[
configNr
].
dev
)
{
if
(
rndis_per_dev_params
[
configNr
].
dev
)
{
length
=
6
;
length
=
ETH_ALEN
;
memcpy
((
u8
*
)
resp
+
24
,
memcpy
((
u8
*
)
resp
+
24
,
rndis_per_dev_params
[
configNr
].
dev
->
dev_addr
,
rndis_per_dev_params
[
configNr
].
host_mac
,
length
);
length
);
/*
* we need a MAC address and hope that
* (our MAC + 1) is not in use
*/
*
((
u8
*
)
resp
+
29
)
+=
1
;
retval
=
0
;
retval
=
0
;
}
}
break
;
break
;
...
@@ -746,22 +754,38 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
...
@@ -746,22 +754,38 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
rndis_set_cmplt_type
*
resp
;
rndis_set_cmplt_type
*
resp
;
int
i
,
retval
=
-
ENOTSUPP
;
int
i
,
retval
=
-
ENOTSUPP
;
struct
rndis_config_parameter
*
param
;
struct
rndis_config_parameter
*
param
;
struct
rndis_params
*
params
;
if
(
!
r
)
return
-
ENOMEM
;
u8
*
cp
;
if
(
!
r
)
return
-
ENOMEM
;
resp
=
(
rndis_set_cmplt_type
*
)
r
->
buf
;
resp
=
(
rndis_set_cmplt_type
*
)
r
->
buf
;
if
(
!
resp
)
if
(
!
resp
)
return
-
ENOMEM
;
return
-
ENOMEM
;
cp
=
(
u8
*
)
resp
;
switch
(
OID
)
{
switch
(
OID
)
{
case
OID_GEN_CURRENT_PACKET_FILTER
:
case
OID_GEN_CURRENT_PACKET_FILTER
:
DEBUG
(
"%s: OID_GEN_CURRENT_PACKET_FILTER
\n
"
,
__FUNCTION__
);
DEBUG
(
"%s: OID_GEN_CURRENT_PACKET_FILTER
\n
"
,
__FUNCTION__
);
currentFilter2devFlags
((
u32
)
((
u8
*
)
resp
+
28
),
params
=
&
rndis_per_dev_params
[
configNr
];
rndis_per_dev_params
[
configNr
].
dev
);
currentFilter2devFlags
(
cp
[
28
],
params
->
dev
);
retval
=
0
;
retval
=
0
;
if
((
u32
)
((
u8
*
)
resp
+
28
))
rndis_per_dev_params
[
configNr
].
state
=
RNDIS_INITIALIZED
;
/* this call has a significant side effect: it's
else
* what makes the packet flow start and stop, like
rndis_per_dev_params
[
configNr
].
state
=
RNDIS_UNINITIALIZED
;
* activating the CDC Ethernet altsetting.
*/
if
(
cp
[
28
])
{
params
->
state
=
RNDIS_DATA_INITIALIZED
;
netif_carrier_on
(
params
->
dev
);
if
(
netif_running
(
params
->
dev
))
netif_wake_queue
(
params
->
dev
);
}
else
{
params
->
state
=
RNDIS_INITIALIZED
;
netif_carrier_off
(
params
->
dev
);
netif_stop_queue
(
params
->
dev
);
}
break
;
break
;
case
OID_802_3_MULTICAST_LIST
:
case
OID_802_3_MULTICAST_LIST
:
...
@@ -937,10 +961,9 @@ static int rndis_keepalive_response (int configNr,
...
@@ -937,10 +961,9 @@ static int rndis_keepalive_response (int configNr,
{
{
rndis_keepalive_cmplt_type
*
resp
;
rndis_keepalive_cmplt_type
*
resp
;
rndis_resp_t
*
r
;
rndis_resp_t
*
r
;
/* respond only in RNDIS_INITIALIZED state */
/* host "should" check only in RNDIS_DATA_INITIALIZED state */
if
(
rndis_per_dev_params
[
configNr
].
state
!=
RNDIS_INITIALIZED
)
return
0
;
r
=
rndis_add_response
(
configNr
,
sizeof
(
rndis_keepalive_cmplt_type
));
r
=
rndis_add_response
(
configNr
,
sizeof
(
rndis_keepalive_cmplt_type
));
resp
=
(
rndis_keepalive_cmplt_type
*
)
r
->
buf
;
resp
=
(
rndis_keepalive_cmplt_type
*
)
r
->
buf
;
if
(
!
resp
)
return
-
ENOMEM
;
if
(
!
resp
)
return
-
ENOMEM
;
...
@@ -1004,35 +1027,48 @@ int rndis_signal_disconnect (int configNr)
...
@@ -1004,35 +1027,48 @@ int rndis_signal_disconnect (int configNr)
RNDIS_STATUS_MEDIA_DISCONNECT
);
RNDIS_STATUS_MEDIA_DISCONNECT
);
}
}
void
rndis_set_host_mac
(
int
configNr
,
const
u8
*
addr
)
{
rndis_per_dev_params
[
configNr
].
host_mac
=
addr
;
}
/*
/*
* Message Parser
* Message Parser
*/
*/
int
rndis_msg_parser
(
u8
configNr
,
u8
*
buf
)
int
rndis_msg_parser
(
u8
configNr
,
u8
*
buf
)
{
{
u32
MsgType
,
MsgLength
,
*
tmp
;
u32
MsgType
,
MsgLength
,
*
tmp
;
struct
rndis_params
*
params
;
if
(
!
buf
)
return
-
ENOMEM
;
if
(
!
buf
)
return
-
ENOMEM
;
tmp
=
(
u32
*
)
buf
;
tmp
=
(
u32
*
)
buf
;
MsgType
=
*
tmp
;
MsgType
=
*
tmp
;
MsgLength
=
*
(
tmp
+
1
);
MsgLength
=
*
(
tmp
+
1
);
if
(
configNr
>=
RNDIS_MAX_CONFIGS
)
return
-
ENOTSUPP
;
if
(
configNr
>=
RNDIS_MAX_CONFIGS
)
return
-
ENOTSUPP
;
params
=
&
rndis_per_dev_params
[
configNr
];
/* For USB: responses may take up to 10 seconds */
switch
(
MsgType
)
switch
(
MsgType
)
{
{
case
REMOTE_NDIS_INI
Z
IALIZE_MSG
:
case
REMOTE_NDIS_INI
T
IALIZE_MSG
:
DEBUG
(
KERN_INFO
"%s: REMOTE_NDIS_INI
Z
IALIZE_MSG
\n
"
,
DEBUG
(
KERN_INFO
"%s: REMOTE_NDIS_INI
T
IALIZE_MSG
\n
"
,
__FUNCTION__
);
__FUNCTION__
);
rndis_per_dev_params
[
configNr
].
state
=
RNDIS_INITIALIZED
;
params
->
state
=
RNDIS_INITIALIZED
;
return
rndis_init_response
(
configNr
,
return
rndis_init_response
(
configNr
,
(
rndis_init_msg_type
*
)
buf
);
(
rndis_init_msg_type
*
)
buf
);
break
;
case
REMOTE_NDIS_HALT_MSG
:
case
REMOTE_NDIS_HALT_MSG
:
DEBUG
(
KERN_INFO
"%s: REMOTE_NDIS_HALT_MSG
\n
"
,
DEBUG
(
KERN_INFO
"%s: REMOTE_NDIS_HALT_MSG
\n
"
,
__FUNCTION__
);
__FUNCTION__
);
rndis_per_dev_params
[
configNr
].
state
=
RNDIS_UNINITIALIZED
;
params
->
state
=
RNDIS_UNINITIALIZED
;
if
(
params
->
dev
)
{
netif_carrier_off
(
params
->
dev
);
netif_stop_queue
(
params
->
dev
);
}
return
0
;
return
0
;
case
REMOTE_NDIS_QUERY_MSG
:
case
REMOTE_NDIS_QUERY_MSG
:
...
@@ -1040,29 +1076,26 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
...
@@ -1040,29 +1076,26 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
__FUNCTION__
);
__FUNCTION__
);
return
rndis_query_response
(
configNr
,
return
rndis_query_response
(
configNr
,
(
rndis_query_msg_type
*
)
buf
);
(
rndis_query_msg_type
*
)
buf
);
break
;
case
REMOTE_NDIS_SET_MSG
:
case
REMOTE_NDIS_SET_MSG
:
DEBUG
(
KERN_INFO
"%s: REMOTE_NDIS_SET_MSG
\n
"
,
DEBUG
(
KERN_INFO
"%s: REMOTE_NDIS_SET_MSG
\n
"
,
__FUNCTION__
);
__FUNCTION__
);
return
rndis_set_response
(
configNr
,
return
rndis_set_response
(
configNr
,
(
rndis_set_msg_type
*
)
buf
);
(
rndis_set_msg_type
*
)
buf
);
break
;
case
REMOTE_NDIS_RESET_MSG
:
case
REMOTE_NDIS_RESET_MSG
:
DEBUG
(
KERN_INFO
"%s: REMOTE_NDIS_RESET_MSG
\n
"
,
DEBUG
(
KERN_INFO
"%s: REMOTE_NDIS_RESET_MSG
\n
"
,
__FUNCTION__
);
__FUNCTION__
);
return
rndis_reset_response
(
configNr
,
return
rndis_reset_response
(
configNr
,
(
rndis_reset_msg_type
*
)
buf
);
(
rndis_reset_msg_type
*
)
buf
);
break
;
case
REMOTE_NDIS_KEEPALIVE_MSG
:
case
REMOTE_NDIS_KEEPALIVE_MSG
:
/* For USB: host does this every 5 seconds */
DEBUG
(
KERN_INFO
"%s: REMOTE_NDIS_KEEPALIVE_MSG
\n
"
,
DEBUG
(
KERN_INFO
"%s: REMOTE_NDIS_KEEPALIVE_MSG
\n
"
,
__FUNCTION__
);
__FUNCTION__
);
return
rndis_keepalive_response
(
configNr
,
return
rndis_keepalive_response
(
configNr
,
(
rndis_keepalive_msg_type
*
)
(
rndis_keepalive_msg_type
*
)
buf
);
buf
);
break
;
default:
default:
printk
(
KERN_ERR
"%s: unknown RNDIS Message Type 0x%08X
\n
"
,
printk
(
KERN_ERR
"%s: unknown RNDIS Message Type 0x%08X
\n
"
,
...
@@ -1240,9 +1273,15 @@ int rndis_proc_read (char *page, char **start, off_t off, int count, int *eof,
...
@@ -1240,9 +1273,15 @@ int rndis_proc_read (char *page, char **start, off_t off, int count, int *eof,
"vendor ID : 0x%08X
\n
"
"vendor ID : 0x%08X
\n
"
"vendor : %s
\n
"
,
"vendor : %s
\n
"
,
param
->
confignr
,
(
param
->
used
)
?
"y"
:
"n"
,
param
->
confignr
,
(
param
->
used
)
?
"y"
:
"n"
,
(
param
->
state
)
({
char
*
s
=
"?"
;
?
"RNDIS_INITIALIZED"
switch
(
param
->
state
)
{
:
"RNDIS_UNINITIALIZED"
,
case
RNDIS_UNINITIALIZED
:
s
=
"RNDIS_UNINITIALIZED"
;
break
;
case
RNDIS_INITIALIZED
:
s
=
"RNDIS_INITIALIZED"
;
break
;
case
RNDIS_DATA_INITIALIZED
:
s
=
"RNDIS_DATA_INITIALIZED"
;
break
;
};
s
;
}),
param
->
medium
,
param
->
medium
,
(
param
->
media_state
)
?
0
:
param
->
speed
*
100
,
(
param
->
media_state
)
?
0
:
param
->
speed
*
100
,
(
param
->
media_state
)
?
"disconnected"
:
"connected"
,
(
param
->
media_state
)
?
"disconnected"
:
"connected"
,
...
@@ -1353,7 +1392,7 @@ int __init rndis_init (void)
...
@@ -1353,7 +1392,7 @@ int __init rndis_init (void)
return
0
;
return
0
;
}
}
void
__exit
rndis_exit
(
void
)
void
rndis_exit
(
void
)
{
{
u8
i
;
u8
i
;
char
name
[
4
];
char
name
[
4
];
...
...
drivers/usb/gadget/rndis.h
View file @
8a51beef
...
@@ -38,7 +38,7 @@
...
@@ -38,7 +38,7 @@
*/
*/
/* Message Set for Connectionless (802.3) Devices */
/* Message Set for Connectionless (802.3) Devices */
#define REMOTE_NDIS_INI
Z
IALIZE_MSG 0x00000002U
/* Initialize device */
#define REMOTE_NDIS_INI
T
IALIZE_MSG 0x00000002U
/* Initialize device */
#define REMOTE_NDIS_HALT_MSG 0x00000003U
#define REMOTE_NDIS_HALT_MSG 0x00000003U
#define REMOTE_NDIS_QUERY_MSG 0x00000004U
#define REMOTE_NDIS_QUERY_MSG 0x00000004U
#define REMOTE_NDIS_SET_MSG 0x00000005U
#define REMOTE_NDIS_SET_MSG 0x00000005U
...
@@ -280,6 +280,7 @@ typedef struct rndis_params
...
@@ -280,6 +280,7 @@ typedef struct rndis_params
u32
medium
;
u32
medium
;
u32
speed
;
u32
speed
;
u32
media_state
;
u32
media_state
;
const
u8
*
host_mac
;
struct
net_device
*
dev
;
struct
net_device
*
dev
;
struct
net_device_stats
*
stats
;
struct
net_device_stats
*
stats
;
u32
vendorID
;
u32
vendorID
;
...
@@ -301,11 +302,13 @@ void rndis_add_hdr (struct sk_buff *skb);
...
@@ -301,11 +302,13 @@ void rndis_add_hdr (struct sk_buff *skb);
int
rndis_rm_hdr
(
u8
*
buf
,
u32
*
length
);
int
rndis_rm_hdr
(
u8
*
buf
,
u32
*
length
);
u8
*
rndis_get_next_response
(
int
configNr
,
u32
*
length
);
u8
*
rndis_get_next_response
(
int
configNr
,
u32
*
length
);
void
rndis_free_response
(
int
configNr
,
u8
*
buf
);
void
rndis_free_response
(
int
configNr
,
u8
*
buf
);
int
rndis_signal_connect
(
int
configNr
);
int
rndis_signal_connect
(
int
configNr
);
int
rndis_signal_disconnect
(
int
configNr
);
int
rndis_signal_disconnect
(
int
configNr
);
int
rndis_state
(
int
configNr
);
int
rndis_state
(
int
configNr
);
extern
void
rndis_set_host_mac
(
int
configNr
,
const
u8
*
addr
);
int
__init
rndis_init
(
void
);
int
__init
rndis_init
(
void
);
void
__exit
rndis_exit
(
void
);
void
rndis_exit
(
void
);
#endif
/* _LINUX_RNDIS_H */
#endif
/* _LINUX_RNDIS_H */
drivers/usb/host/ehci-hcd.c
View file @
8a51beef
...
@@ -330,6 +330,7 @@ static int ehci_hc_reset (struct usb_hcd *hcd)
...
@@ -330,6 +330,7 @@ static int ehci_hc_reset (struct usb_hcd *hcd)
{
{
struct
ehci_hcd
*
ehci
=
hcd_to_ehci
(
hcd
);
struct
ehci_hcd
*
ehci
=
hcd_to_ehci
(
hcd
);
u32
temp
;
u32
temp
;
unsigned
count
=
256
/
4
;
spin_lock_init
(
&
ehci
->
lock
);
spin_lock_init
(
&
ehci
->
lock
);
...
@@ -345,16 +346,21 @@ static int ehci_hc_reset (struct usb_hcd *hcd)
...
@@ -345,16 +346,21 @@ static int ehci_hc_reset (struct usb_hcd *hcd)
temp
=
HCC_EXT_CAPS
(
readl
(
&
ehci
->
caps
->
hcc_params
));
temp
=
HCC_EXT_CAPS
(
readl
(
&
ehci
->
caps
->
hcc_params
));
else
else
temp
=
0
;
temp
=
0
;
while
(
temp
)
{
while
(
temp
&&
count
--
)
{
u32
cap
;
u32
cap
;
pci_read_config_dword
(
to_pci_dev
(
ehci
->
hcd
.
self
.
controller
),
temp
,
&
cap
);
pci_read_config_dword
(
to_pci_dev
(
ehci
->
hcd
.
self
.
controller
),
temp
,
&
cap
);
ehci_dbg
(
ehci
,
"capability %04x at %02x
\n
"
,
cap
,
temp
);
ehci_dbg
(
ehci
,
"capability %04x at %02x
\n
"
,
cap
,
temp
);
switch
(
cap
&
0xff
)
{
switch
(
cap
&
0xff
)
{
case
1
:
/* BIOS/SMM/... handoff */
case
1
:
/* BIOS/SMM/... handoff */
if
(
bios_handoff
(
ehci
,
temp
,
cap
)
!=
0
)
if
(
bios_handoff
(
ehci
,
temp
,
cap
)
!=
0
)
return
-
EOPNOTSUPP
;
return
-
EOPNOTSUPP
;
break
;
break
;
case
0x0a
:
/* appendix C */
ehci_dbg
(
ehci
,
"debug registers, BAR %d offset %d
\n
"
,
(
cap
>>
29
)
&
0x07
,
(
cap
>>
16
)
&
0x0fff
);
break
;
case
0
:
/* illegal reserved capability */
case
0
:
/* illegal reserved capability */
ehci_warn
(
ehci
,
"illegal capability!
\n
"
);
ehci_warn
(
ehci
,
"illegal capability!
\n
"
);
cap
=
0
;
cap
=
0
;
...
@@ -364,6 +370,10 @@ static int ehci_hc_reset (struct usb_hcd *hcd)
...
@@ -364,6 +370,10 @@ static int ehci_hc_reset (struct usb_hcd *hcd)
}
}
temp
=
(
cap
>>
8
)
&
0xff
;
temp
=
(
cap
>>
8
)
&
0xff
;
}
}
if
(
!
count
)
{
ehci_err
(
ehci
,
"bogus capabilities ... PCI problems!
\n
"
);
return
-
EIO
;
}
#endif
#endif
/* cache this readonly data; minimize PCI reads */
/* cache this readonly data; minimize PCI reads */
...
@@ -577,7 +587,8 @@ static void ehci_stop (struct usb_hcd *hcd)
...
@@ -577,7 +587,8 @@ static void ehci_stop (struct usb_hcd *hcd)
/* root hub is shut down separately (first, when possible) */
/* root hub is shut down separately (first, when possible) */
spin_lock_irq
(
&
ehci
->
lock
);
spin_lock_irq
(
&
ehci
->
lock
);
ehci_work
(
ehci
,
NULL
);
if
(
ehci
->
async
)
ehci_work
(
ehci
,
NULL
);
spin_unlock_irq
(
&
ehci
->
lock
);
spin_unlock_irq
(
&
ehci
->
lock
);
ehci_mem_cleanup
(
ehci
);
ehci_mem_cleanup
(
ehci
);
...
...
drivers/usb/host/ehci-hub.c
View file @
8a51beef
...
@@ -252,14 +252,18 @@ static int ehci_hub_control (
...
@@ -252,14 +252,18 @@ static int ehci_hub_control (
/* force reset to complete */
/* force reset to complete */
writel
(
temp
&
~
PORT_RESET
,
writel
(
temp
&
~
PORT_RESET
,
&
ehci
->
regs
->
port_status
[
wIndex
]);
&
ehci
->
regs
->
port_status
[
wIndex
]);
do
{
retval
=
handshake
(
temp
=
readl
(
&
ehci
->
regs
->
port_status
[
wIndex
],
&
ehci
->
regs
->
port_status
[
wIndex
]);
PORT_RESET
,
0
,
500
);
udelay
(
10
);
if
(
retval
!=
0
)
{
}
while
(
temp
&
PORT_RESET
);
ehci_err
(
ehci
,
"port %d reset error %d
\n
"
,
wIndex
+
1
,
retval
);
goto
error
;
}
/* see what we found out */
/* see what we found out */
temp
=
check_reset_complete
(
ehci
,
wIndex
,
temp
);
temp
=
check_reset_complete
(
ehci
,
wIndex
,
readl
(
&
ehci
->
regs
->
port_status
[
wIndex
]));
}
}
// don't show wPortStatus if it's owned by a companion hc
// don't show wPortStatus if it's owned by a companion hc
...
...
drivers/usb/host/uhci-hcd.c
View file @
8a51beef
...
@@ -382,6 +382,7 @@ static void uhci_insert_qh(struct uhci_hcd *uhci, struct uhci_qh *skelqh, struct
...
@@ -382,6 +382,7 @@ static void uhci_insert_qh(struct uhci_hcd *uhci, struct uhci_qh *skelqh, struct
static
void
uhci_remove_qh
(
struct
uhci_hcd
*
uhci
,
struct
uhci_qh
*
qh
)
static
void
uhci_remove_qh
(
struct
uhci_hcd
*
uhci
,
struct
uhci_qh
*
qh
)
{
{
struct
uhci_qh
*
pqh
;
struct
uhci_qh
*
pqh
;
__u32
newlink
;
if
(
!
qh
)
if
(
!
qh
)
return
;
return
;
...
@@ -390,8 +391,24 @@ static void uhci_remove_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
...
@@ -390,8 +391,24 @@ static void uhci_remove_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
* Only go through the hoops if it's actually linked in
* Only go through the hoops if it's actually linked in
*/
*/
if
(
!
list_empty
(
&
qh
->
list
))
{
if
(
!
list_empty
(
&
qh
->
list
))
{
pqh
=
list_entry
(
qh
->
list
.
prev
,
struct
uhci_qh
,
list
);
/* If our queue is nonempty, make the next URB the head */
if
(
!
list_empty
(
&
qh
->
urbp
->
queue_list
))
{
struct
urb_priv
*
nurbp
;
nurbp
=
list_entry
(
qh
->
urbp
->
queue_list
.
next
,
struct
urb_priv
,
queue_list
);
nurbp
->
queued
=
0
;
list_add
(
&
nurbp
->
qh
->
list
,
&
qh
->
list
);
newlink
=
cpu_to_le32
(
nurbp
->
qh
->
dma_handle
)
|
UHCI_PTR_QH
;
}
else
newlink
=
qh
->
link
;
/* Fix up the previous QH's queue to link to either
* the new head of this queue or the start of the
* next endpoint's queue. */
pqh
=
list_entry
(
qh
->
list
.
prev
,
struct
uhci_qh
,
list
);
pqh
->
link
=
newlink
;
if
(
pqh
->
urbp
)
{
if
(
pqh
->
urbp
)
{
struct
list_head
*
head
,
*
tmp
;
struct
list_head
*
head
,
*
tmp
;
...
@@ -403,28 +420,19 @@ static void uhci_remove_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
...
@@ -403,28 +420,19 @@ static void uhci_remove_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
tmp
=
tmp
->
next
;
tmp
=
tmp
->
next
;
turbp
->
qh
->
link
=
qh
->
link
;
turbp
->
qh
->
link
=
new
link
;
}
}
}
}
pqh
->
link
=
qh
->
link
;
mb
();
mb
();
/* Leave qh->link in case the HC is on the QH now, it will */
/* Leave qh->link in case the HC is on the QH now, it will */
/* continue the rest of the schedule */
/* continue the rest of the schedule */
qh
->
element
=
UHCI_PTR_TERM
;
qh
->
element
=
UHCI_PTR_TERM
;
/* If our queue is nonempty, make the next URB the head */
if
(
!
list_empty
(
&
qh
->
urbp
->
queue_list
))
{
struct
urb_priv
*
nurbp
;
nurbp
=
list_entry
(
qh
->
urbp
->
queue_list
.
next
,
struct
urb_priv
,
queue_list
);
nurbp
->
queued
=
0
;
list_add_tail
(
&
nurbp
->
qh
->
list
,
&
qh
->
list
);
}
list_del_init
(
&
qh
->
list
);
list_del_init
(
&
qh
->
list
);
}
}
list_del_init
(
&
qh
->
urbp
->
queue_list
);
qh
->
urbp
=
NULL
;
qh
->
urbp
=
NULL
;
/* Check to see if the remove list is empty. Set the IOC bit */
/* Check to see if the remove list is empty. Set the IOC bit */
...
@@ -579,7 +587,7 @@ static void uhci_delete_queued_urb(struct uhci_hcd *uhci, struct urb *urb)
...
@@ -579,7 +587,7 @@ static void uhci_delete_queued_urb(struct uhci_hcd *uhci, struct urb *urb)
pltd
->
link
=
UHCI_PTR_TERM
;
pltd
->
link
=
UHCI_PTR_TERM
;
}
}
list_del_init
(
&
urbp
->
queue_list
);
/* urbp->queue_list is handled in uhci_remove_qh() */
}
}
static
struct
urb_priv
*
uhci_alloc_urb_priv
(
struct
uhci_hcd
*
uhci
,
struct
urb
*
urb
)
static
struct
urb_priv
*
uhci_alloc_urb_priv
(
struct
uhci_hcd
*
uhci
,
struct
urb
*
urb
)
...
...
drivers/usb/misc/tiglusb.c
View file @
8a51beef
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
* tiglusb -- Texas Instruments' USB GraphLink (aka SilverLink) driver.
* tiglusb -- Texas Instruments' USB GraphLink (aka SilverLink) driver.
* Target: Texas Instruments graphing calculators (http://lpg.ticalc.org).
* Target: Texas Instruments graphing calculators (http://lpg.ticalc.org).
*
*
* Copyright (C) 2001-200
2
:
* Copyright (C) 2001-200
4
:
* Romain Lievin <roms@lpg.ticalc.org>
* Romain Lievin <roms@lpg.ticalc.org>
* Julien BLACHE <jb@technologeek.org>
* Julien BLACHE <jb@technologeek.org>
* under the terms of the GNU General Public License.
* under the terms of the GNU General Public License.
...
@@ -20,6 +20,8 @@
...
@@ -20,6 +20,8 @@
* 1.04, Julien: clean-up & fixes; Romain: 2.4 backport.
* 1.04, Julien: clean-up & fixes; Romain: 2.4 backport.
* 1.05, Randy Dunlap: bug fix with the timeout parameter (divide-by-zero).
* 1.05, Randy Dunlap: bug fix with the timeout parameter (divide-by-zero).
* 1.06, Romain: synched with 2.5, version/firmware changed (confusing).
* 1.06, Romain: synched with 2.5, version/firmware changed (confusing).
* 1.07, Romain: fixed bad use of usb_clear_halt (invalid argument);
* timeout argument checked in ioctl + clean-up.
*/
*/
#include <linux/module.h>
#include <linux/module.h>
...
@@ -38,8 +40,8 @@
...
@@ -38,8 +40,8 @@
/*
/*
* Version Information
* Version Information
*/
*/
#define DRIVER_VERSION "1.0
6
"
#define DRIVER_VERSION "1.0
7
"
#define DRIVER_AUTHOR "Romain Lievin <roms@
lpg.ticalc.org
> & Julien Blache <jb@jblache.org>"
#define DRIVER_AUTHOR "Romain Lievin <roms@
tilp.info
> & Julien Blache <jb@jblache.org>"
#define DRIVER_DESC "TI-GRAPH LINK USB (aka SilverLink) driver"
#define DRIVER_DESC "TI-GRAPH LINK USB (aka SilverLink) driver"
#define DRIVER_LICENSE "GPL"
#define DRIVER_LICENSE "GPL"
...
@@ -72,15 +74,15 @@ clear_pipes (struct usb_device *dev)
...
@@ -72,15 +74,15 @@ clear_pipes (struct usb_device *dev)
{
{
unsigned
int
pipe
;
unsigned
int
pipe
;
pipe
=
usb_sndbulkpipe
(
dev
,
1
);
pipe
=
usb_sndbulkpipe
(
dev
,
2
);
if
(
usb_clear_halt
(
dev
,
usb_pipeendpoint
(
pipe
)
))
{
if
(
usb_clear_halt
(
dev
,
pipe
))
{
err
(
"clear_pipe (
r
), request failed"
);
err
(
"clear_pipe (
w
), request failed"
);
return
-
1
;
return
-
1
;
}
}
pipe
=
usb_
sndbulkpipe
(
dev
,
2
);
pipe
=
usb_
rcvbulkpipe
(
dev
,
1
);
if
(
usb_clear_halt
(
dev
,
usb_pipeendpoint
(
pipe
)
))
{
if
(
usb_clear_halt
(
dev
,
pipe
))
{
err
(
"clear_pipe (
w
), request failed"
);
err
(
"clear_pipe (
r
), request failed"
);
return
-
1
;
return
-
1
;
}
}
...
@@ -181,17 +183,16 @@ tiglusb_read (struct file *filp, char __user *buf, size_t count, loff_t * f_pos)
...
@@ -181,17 +183,16 @@ tiglusb_read (struct file *filp, char __user *buf, size_t count, loff_t * f_pos)
pipe
=
usb_rcvbulkpipe
(
s
->
dev
,
1
);
pipe
=
usb_rcvbulkpipe
(
s
->
dev
,
1
);
result
=
usb_bulk_msg
(
s
->
dev
,
pipe
,
buffer
,
bytes_to_read
,
result
=
usb_bulk_msg
(
s
->
dev
,
pipe
,
buffer
,
bytes_to_read
,
&
bytes_read
,
HZ
*
10
/
timeout
);
&
bytes_read
,
(
HZ
*
timeout
)
/
10
);
if
(
result
==
-
ETIMEDOUT
)
{
/* NAK */
if
(
result
==
-
ETIMEDOUT
)
{
/* NAK */
ret
=
result
;
if
(
!
bytes_read
)
if
(
!
bytes_read
)
{
dbg
(
"quirk !"
);
dbg
(
"quirk !"
);
}
warn
(
"tiglusb_read, NAK received."
);
warn
(
"tiglusb_read, NAK received."
);
ret
=
result
;
goto
out
;
goto
out
;
}
else
if
(
result
==
-
EPIPE
)
{
/* STALL -- shouldn't happen */
}
else
if
(
result
==
-
EPIPE
)
{
/* STALL -- shouldn't happen */
warn
(
"clear_halt request to remove STALL condition."
);
warn
(
"clear_halt request to remove STALL condition."
);
if
(
usb_clear_halt
(
s
->
dev
,
usb_pipeendpoint
(
pipe
)
))
if
(
usb_clear_halt
(
s
->
dev
,
pipe
))
err
(
"clear_halt, request failed"
);
err
(
"clear_halt, request failed"
);
clear_device
(
s
->
dev
);
clear_device
(
s
->
dev
);
ret
=
result
;
ret
=
result
;
...
@@ -243,7 +244,7 @@ tiglusb_write (struct file *filp, const char __user *buf, size_t count, loff_t *
...
@@ -243,7 +244,7 @@ tiglusb_write (struct file *filp, const char __user *buf, size_t count, loff_t *
pipe
=
usb_sndbulkpipe
(
s
->
dev
,
2
);
pipe
=
usb_sndbulkpipe
(
s
->
dev
,
2
);
result
=
usb_bulk_msg
(
s
->
dev
,
pipe
,
buffer
,
bytes_to_write
,
result
=
usb_bulk_msg
(
s
->
dev
,
pipe
,
buffer
,
bytes_to_write
,
&
bytes_written
,
HZ
*
10
/
timeout
);
&
bytes_written
,
(
HZ
*
timeout
)
/
10
);
if
(
result
==
-
ETIMEDOUT
)
{
/* NAK */
if
(
result
==
-
ETIMEDOUT
)
{
/* NAK */
warn
(
"tiglusb_write, NAK received."
);
warn
(
"tiglusb_write, NAK received."
);
...
@@ -251,7 +252,7 @@ tiglusb_write (struct file *filp, const char __user *buf, size_t count, loff_t *
...
@@ -251,7 +252,7 @@ tiglusb_write (struct file *filp, const char __user *buf, size_t count, loff_t *
goto
out
;
goto
out
;
}
else
if
(
result
==
-
EPIPE
)
{
/* STALL -- shouldn't happen */
}
else
if
(
result
==
-
EPIPE
)
{
/* STALL -- shouldn't happen */
warn
(
"clear_halt request to remove STALL condition."
);
warn
(
"clear_halt request to remove STALL condition."
);
if
(
usb_clear_halt
(
s
->
dev
,
usb_pipeendpoint
(
pipe
)
))
if
(
usb_clear_halt
(
s
->
dev
,
pipe
))
err
(
"clear_halt, request failed"
);
err
(
"clear_halt, request failed"
);
clear_device
(
s
->
dev
);
clear_device
(
s
->
dev
);
ret
=
result
;
ret
=
result
;
...
@@ -292,15 +293,16 @@ tiglusb_ioctl (struct inode *inode, struct file *filp,
...
@@ -292,15 +293,16 @@ tiglusb_ioctl (struct inode *inode, struct file *filp,
switch
(
cmd
)
{
switch
(
cmd
)
{
case
IOCTL_TIUSB_TIMEOUT
:
case
IOCTL_TIUSB_TIMEOUT
:
timeout
=
arg
;
// timeout value in tenth of seconds
if
(
arg
>
0
)
timeout
=
arg
;
else
ret
=
-
EINVAL
;
break
;
break
;
case
IOCTL_TIUSB_RESET_DEVICE
:
case
IOCTL_TIUSB_RESET_DEVICE
:
dbg
(
"IOCTL_TIGLUSB_RESET_DEVICE"
);
if
(
clear_device
(
s
->
dev
))
if
(
clear_device
(
s
->
dev
))
ret
=
-
EIO
;
ret
=
-
EIO
;
break
;
break
;
case
IOCTL_TIUSB_RESET_PIPES
:
case
IOCTL_TIUSB_RESET_PIPES
:
dbg
(
"IOCTL_TIGLUSB_RESET_PIPES"
);
if
(
clear_pipes
(
s
->
dev
))
if
(
clear_pipes
(
s
->
dev
))
ret
=
-
EIO
;
ret
=
-
EIO
;
break
;
break
;
...
@@ -447,7 +449,7 @@ static struct usb_driver tiglusb_driver = {
...
@@ -447,7 +449,7 @@ static struct usb_driver tiglusb_driver = {
#ifndef MODULE
#ifndef MODULE
/*
/*
* You can use 'tiusb=timeout'
* You can use 'tiusb=timeout'
to set timeout.
*/
*/
static
int
__init
static
int
__init
tiglusb_setup
(
char
*
str
)
tiglusb_setup
(
char
*
str
)
...
@@ -457,10 +459,11 @@ tiglusb_setup (char *str)
...
@@ -457,10 +459,11 @@ tiglusb_setup (char *str)
str
=
get_options
(
str
,
ARRAY_SIZE
(
ints
),
ints
);
str
=
get_options
(
str
,
ARRAY_SIZE
(
ints
),
ints
);
if
(
ints
[
0
]
>
0
)
{
if
(
ints
[
0
]
>
0
)
{
timeout
=
ints
[
1
];
if
(
ints
[
1
]
>
0
)
timeout
=
ints
[
1
];
else
info
(
"tiglusb: wrong timeout value (0), using default value."
);
}
}
if
(
timeout
<=
0
)
timeout
=
TIMAXTIME
;
return
1
;
return
1
;
}
}
...
@@ -502,9 +505,6 @@ tiglusb_init (void)
...
@@ -502,9 +505,6 @@ tiglusb_init (void)
info
(
DRIVER_DESC
", version "
DRIVER_VERSION
);
info
(
DRIVER_DESC
", version "
DRIVER_VERSION
);
if
(
timeout
<=
0
)
timeout
=
TIMAXTIME
;
return
0
;
return
0
;
}
}
...
...
drivers/usb/net/usbnet.c
View file @
8a51beef
...
@@ -2107,8 +2107,12 @@ pl_set_QuickLink_features (struct usbnet *dev, int val)
...
@@ -2107,8 +2107,12 @@ pl_set_QuickLink_features (struct usbnet *dev, int val)
static
int
pl_reset
(
struct
usbnet
*
dev
)
static
int
pl_reset
(
struct
usbnet
*
dev
)
{
{
return
pl_set_QuickLink_features
(
dev
,
/* some units seem to need this reset, others reject it utterly.
* FIXME be more like "naplink" or windows drivers.
*/
(
void
)
pl_set_QuickLink_features
(
dev
,
PL_S_EN
|
PL_RESET_OUT
|
PL_RESET_IN
|
PL_PEER_E
);
PL_S_EN
|
PL_RESET_OUT
|
PL_RESET_IN
|
PL_PEER_E
);
return
0
;
}
}
static
const
struct
driver_info
prolific_info
=
{
static
const
struct
driver_info
prolific_info
=
{
...
...
drivers/usb/serial/ftdi_sio.c
View file @
8a51beef
...
@@ -463,8 +463,6 @@ static struct usb_device_id id_table_FT232BM [] = {
...
@@ -463,8 +463,6 @@ static struct usb_device_id id_table_FT232BM [] = {
{
USB_DEVICE_VER
(
FTDI_VID
,
LINX_FUTURE_2_PID
,
0x400
,
0xffff
)
},
{
USB_DEVICE_VER
(
FTDI_VID
,
LINX_FUTURE_2_PID
,
0x400
,
0xffff
)
},
{
USB_DEVICE
(
FTDI_VID
,
FTDI_CCSICDU20_0_PID
)
},
{
USB_DEVICE
(
FTDI_VID
,
FTDI_CCSICDU20_0_PID
)
},
{
USB_DEVICE
(
FTDI_VID
,
FTDI_CCSICDU40_1_PID
)
},
{
USB_DEVICE
(
FTDI_VID
,
FTDI_CCSICDU40_1_PID
)
},
{
USB_DEVICE
(
FTDI_VID
,
FTDI_CCSICDU20_0_PID
)
},
{
USB_DEVICE
(
FTDI_VID
,
FTDI_CCSICDU40_1_PID
)
},
{
}
/* Terminating entry */
{
}
/* Terminating entry */
};
};
...
@@ -566,6 +564,8 @@ static struct usb_device_id id_table_combined [] = {
...
@@ -566,6 +564,8 @@ static struct usb_device_id id_table_combined [] = {
{
USB_DEVICE_VER
(
FTDI_VID
,
LINX_FUTURE_0_PID
,
0x400
,
0xffff
)
},
{
USB_DEVICE_VER
(
FTDI_VID
,
LINX_FUTURE_0_PID
,
0x400
,
0xffff
)
},
{
USB_DEVICE_VER
(
FTDI_VID
,
LINX_FUTURE_1_PID
,
0x400
,
0xffff
)
},
{
USB_DEVICE_VER
(
FTDI_VID
,
LINX_FUTURE_1_PID
,
0x400
,
0xffff
)
},
{
USB_DEVICE_VER
(
FTDI_VID
,
LINX_FUTURE_2_PID
,
0x400
,
0xffff
)
},
{
USB_DEVICE_VER
(
FTDI_VID
,
LINX_FUTURE_2_PID
,
0x400
,
0xffff
)
},
{
USB_DEVICE
(
FTDI_VID
,
FTDI_CCSICDU20_0_PID
)
},
{
USB_DEVICE
(
FTDI_VID
,
FTDI_CCSICDU40_1_PID
)
},
{
USB_DEVICE
(
FTDI_VID
,
INSIDE_ACCESSO
)
},
{
USB_DEVICE
(
FTDI_VID
,
INSIDE_ACCESSO
)
},
{
}
/* Terminating entry */
{
}
/* Terminating entry */
};
};
...
...
drivers/usb/storage/dpcm.c
View file @
8a51beef
...
@@ -56,7 +56,8 @@ int dpcm_transport(Scsi_Cmnd *srb, struct us_data *us)
...
@@ -56,7 +56,8 @@ int dpcm_transport(Scsi_Cmnd *srb, struct us_data *us)
/*
/*
* LUN 0 corresponds to the CompactFlash card reader.
* LUN 0 corresponds to the CompactFlash card reader.
*/
*/
return
usb_stor_CB_transport
(
srb
,
us
);
ret
=
usb_stor_CB_transport
(
srb
,
us
);
break
;
#ifdef CONFIG_USB_STORAGE_SDDR09
#ifdef CONFIG_USB_STORAGE_SDDR09
case
1
:
case
1
:
...
@@ -71,12 +72,14 @@ int dpcm_transport(Scsi_Cmnd *srb, struct us_data *us)
...
@@ -71,12 +72,14 @@ int dpcm_transport(Scsi_Cmnd *srb, struct us_data *us)
srb
->
device
->
lun
=
0
;
us
->
srb
->
device
->
lun
=
0
;
srb
->
device
->
lun
=
0
;
us
->
srb
->
device
->
lun
=
0
;
ret
=
sddr09_transport
(
srb
,
us
);
ret
=
sddr09_transport
(
srb
,
us
);
srb
->
device
->
lun
=
1
;
us
->
srb
->
device
->
lun
=
1
;
srb
->
device
->
lun
=
1
;
us
->
srb
->
device
->
lun
=
1
;
break
;
return
ret
;
#endif
#endif
default:
default:
US_DEBUGP
(
"dpcm_transport: Invalid LUN %d
\n
"
,
srb
->
device
->
lun
);
US_DEBUGP
(
"dpcm_transport: Invalid LUN %d
\n
"
,
srb
->
device
->
lun
);
return
USB_STOR_TRANSPORT_ERROR
;
ret
=
USB_STOR_TRANSPORT_ERROR
;
break
;
}
}
return
ret
;
}
}
fs/sysfs/bin.c
View file @
8a51beef
...
@@ -101,19 +101,27 @@ static int open(struct inode * inode, struct file * file)
...
@@ -101,19 +101,27 @@ static int open(struct inode * inode, struct file * file)
if
(
!
kobj
||
!
attr
)
if
(
!
kobj
||
!
attr
)
goto
Done
;
goto
Done
;
/* Grab the module reference for this attribute if we have one */
error
=
-
ENODEV
;
if
(
!
try_module_get
(
attr
->
attr
.
owner
))
goto
Done
;
error
=
-
EACCES
;
error
=
-
EACCES
;
if
((
file
->
f_mode
&
FMODE_WRITE
)
&&
!
attr
->
write
)
if
((
file
->
f_mode
&
FMODE_WRITE
)
&&
!
attr
->
write
)
goto
Done
;
goto
Error
;
if
((
file
->
f_mode
&
FMODE_READ
)
&&
!
attr
->
read
)
if
((
file
->
f_mode
&
FMODE_READ
)
&&
!
attr
->
read
)
goto
Done
;
goto
Error
;
error
=
-
ENOMEM
;
error
=
-
ENOMEM
;
file
->
private_data
=
kmalloc
(
PAGE_SIZE
,
GFP_KERNEL
);
file
->
private_data
=
kmalloc
(
PAGE_SIZE
,
GFP_KERNEL
);
if
(
!
file
->
private_data
)
if
(
!
file
->
private_data
)
goto
Done
;
goto
Error
;
error
=
0
;
error
=
0
;
goto
Done
;
Error:
module_put
(
attr
->
attr
.
owner
);
Done:
Done:
if
(
error
&&
kobj
)
if
(
error
&&
kobj
)
kobject_put
(
kobj
);
kobject_put
(
kobj
);
...
@@ -123,10 +131,12 @@ static int open(struct inode * inode, struct file * file)
...
@@ -123,10 +131,12 @@ static int open(struct inode * inode, struct file * file)
static
int
release
(
struct
inode
*
inode
,
struct
file
*
file
)
static
int
release
(
struct
inode
*
inode
,
struct
file
*
file
)
{
{
struct
kobject
*
kobj
=
file
->
f_dentry
->
d_parent
->
d_fsdata
;
struct
kobject
*
kobj
=
file
->
f_dentry
->
d_parent
->
d_fsdata
;
struct
bin_attribute
*
attr
=
file
->
f_dentry
->
d_fsdata
;
u8
*
buffer
=
file
->
private_data
;
u8
*
buffer
=
file
->
private_data
;
if
(
kobj
)
if
(
kobj
)
kobject_put
(
kobj
);
kobject_put
(
kobj
);
module_put
(
attr
->
attr
.
owner
);
kfree
(
buffer
);
kfree
(
buffer
);
return
0
;
return
0
;
}
}
...
...
fs/sysfs/symlink.c
View file @
8a51beef
...
@@ -42,7 +42,7 @@ static int object_path_length(struct kobject * kobj)
...
@@ -42,7 +42,7 @@ static int object_path_length(struct kobject * kobj)
struct
kobject
*
p
=
kobj
;
struct
kobject
*
p
=
kobj
;
int
length
=
1
;
int
length
=
1
;
do
{
do
{
length
+=
strlen
(
p
->
name
)
+
1
;
length
+=
strlen
(
kobject_name
(
p
)
)
+
1
;
p
=
p
->
parent
;
p
=
p
->
parent
;
}
while
(
p
);
}
while
(
p
);
return
length
;
return
length
;
...
@@ -54,11 +54,11 @@ static void fill_object_path(struct kobject * kobj, char * buffer, int length)
...
@@ -54,11 +54,11 @@ static void fill_object_path(struct kobject * kobj, char * buffer, int length)
--
length
;
--
length
;
for
(
p
=
kobj
;
p
;
p
=
p
->
parent
)
{
for
(
p
=
kobj
;
p
;
p
=
p
->
parent
)
{
int
cur
=
strlen
(
p
->
name
);
int
cur
=
strlen
(
kobject_name
(
p
)
);
/* back up enough to print this bus id with '/' */
/* back up enough to print this bus id with '/' */
length
-=
cur
;
length
-=
cur
;
strncpy
(
buffer
+
length
,
p
->
name
,
cur
);
strncpy
(
buffer
+
length
,
kobject_name
(
p
)
,
cur
);
*
(
buffer
+
--
length
)
=
'/'
;
*
(
buffer
+
--
length
)
=
'/'
;
}
}
}
}
...
...
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