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
fa4229ad
Commit
fa4229ad
authored
Jan 12, 2003
by
Greg Kroah-Hartman
Browse files
Options
Browse Files
Download
Plain Diff
Merge kroah.com:/home/greg/linux/BK/bleeding_edge-2.5
into kroah.com:/home/greg/linux/BK/gregkh-2.5
parents
29b49883
0c546aea
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
250 additions
and
290 deletions
+250
-290
Documentation/usb/proc_usb_info.txt
Documentation/usb/proc_usb_info.txt
+1
-1
drivers/usb/class/Kconfig
drivers/usb/class/Kconfig
+2
-2
drivers/usb/class/audio.c
drivers/usb/class/audio.c
+4
-4
drivers/usb/class/usb-midi.c
drivers/usb/class/usb-midi.c
+6
-6
drivers/usb/input/xpad.c
drivers/usb/input/xpad.c
+3
-1
drivers/usb/misc/speedtouch.c
drivers/usb/misc/speedtouch.c
+36
-165
drivers/usb/serial/digi_acceleport.c
drivers/usb/serial/digi_acceleport.c
+4
-2
drivers/usb/serial/usb-serial.c
drivers/usb/serial/usb-serial.c
+1
-1
drivers/usb/serial/visor.c
drivers/usb/serial/visor.c
+148
-88
drivers/usb/serial/visor.h
drivers/usb/serial/visor.h
+30
-1
drivers/usb/storage/debug.c
drivers/usb/storage/debug.c
+14
-18
drivers/usb/usb-skeleton.c
drivers/usb/usb-skeleton.c
+1
-1
No files found.
Documentation/usb/proc_usb_info.txt
View file @
fa4229ad
...
@@ -23,7 +23,7 @@ and /proc/bus/usb/devices, as well as /proc/bus/usb/BBB/DDD files.
...
@@ -23,7 +23,7 @@ and /proc/bus/usb/devices, as well as /proc/bus/usb/BBB/DDD files.
to interact with USB devices.
to interact with USB devices.
There are a number of mount options supported by usbfs.
There are a number of mount options supported by usbfs.
Consult the source code (linux/drivers/usb/inode.c) for
Consult the source code (linux/drivers/usb/
core/
inode.c) for
information about those options.
information about those options.
**NOTE**: The filesystem has been renamed from "usbdevfs" to
**NOTE**: The filesystem has been renamed from "usbdevfs" to
...
...
drivers/usb/class/Kconfig
View file @
fa4229ad
...
@@ -27,8 +27,8 @@ config USB_BLUETOOTH_TTY
...
@@ -27,8 +27,8 @@ config USB_BLUETOOTH_TTY
device that can be used only by specialized Bluetooth HCI software.
device that can be used only by specialized Bluetooth HCI software.
Say Y here if you want to use OpenBT Bluetooth stack (available
Say Y here if you want to use OpenBT Bluetooth stack (available
at <http://developer.axis.com/software
/index.shtml>), or other TTY
at <http://developer.axis.com/software
>), or other TTY based
based
Bluetooth stacks, and want to connect a USB Bluetooth device
Bluetooth stacks, and want to connect a USB Bluetooth device
to your computer's USB port.
to your computer's USB port.
Do *not* enable this driver if you want to use generic Linux
Do *not* enable this driver if you want to use generic Linux
...
...
drivers/usb/class/audio.c
View file @
fa4229ad
...
@@ -1420,7 +1420,7 @@ static int usbout_start(struct usb_audiodev *as)
...
@@ -1420,7 +1420,7 @@ static int usbout_start(struct usb_audiodev *as)
urb
->
number_of_packets
=
DESCFRAMES
;
urb
->
number_of_packets
=
DESCFRAMES
;
urb
->
context
=
as
;
urb
->
context
=
as
;
urb
->
complete
=
usbout_completed
;
urb
->
complete
=
usbout_completed
;
if
(
!
usbout_prepare_desc
(
u
,
urb
)
&&
!
usb_submit_urb
(
urb
,
GFP_
KERNEL
))
if
(
!
usbout_prepare_desc
(
u
,
urb
)
&&
!
usb_submit_urb
(
urb
,
GFP_
ATOMIC
))
u
->
flags
|=
FLG_URB0RUNNING
;
u
->
flags
|=
FLG_URB0RUNNING
;
else
else
u
->
flags
&=
~
FLG_RUNNING
;
u
->
flags
&=
~
FLG_RUNNING
;
...
@@ -1433,7 +1433,7 @@ static int usbout_start(struct usb_audiodev *as)
...
@@ -1433,7 +1433,7 @@ static int usbout_start(struct usb_audiodev *as)
urb
->
number_of_packets
=
DESCFRAMES
;
urb
->
number_of_packets
=
DESCFRAMES
;
urb
->
context
=
as
;
urb
->
context
=
as
;
urb
->
complete
=
usbout_completed
;
urb
->
complete
=
usbout_completed
;
if
(
!
usbout_prepare_desc
(
u
,
urb
)
&&
!
usb_submit_urb
(
urb
,
GFP_
KERNEL
))
if
(
!
usbout_prepare_desc
(
u
,
urb
)
&&
!
usb_submit_urb
(
urb
,
GFP_
ATOMIC
))
u
->
flags
|=
FLG_URB1RUNNING
;
u
->
flags
|=
FLG_URB1RUNNING
;
else
else
u
->
flags
&=
~
FLG_RUNNING
;
u
->
flags
&=
~
FLG_RUNNING
;
...
@@ -1448,7 +1448,7 @@ static int usbout_start(struct usb_audiodev *as)
...
@@ -1448,7 +1448,7 @@ static int usbout_start(struct usb_audiodev *as)
urb
->
context
=
as
;
urb
->
context
=
as
;
urb
->
complete
=
usbout_sync_completed
;
urb
->
complete
=
usbout_sync_completed
;
/* stride: u->syncinterval */
/* stride: u->syncinterval */
if
(
!
usbout_sync_prepare_desc
(
u
,
urb
)
&&
!
usb_submit_urb
(
urb
,
GFP_
KERNEL
))
if
(
!
usbout_sync_prepare_desc
(
u
,
urb
)
&&
!
usb_submit_urb
(
urb
,
GFP_
ATOMIC
))
u
->
flags
|=
FLG_SYNC0RUNNING
;
u
->
flags
|=
FLG_SYNC0RUNNING
;
else
else
u
->
flags
&=
~
FLG_RUNNING
;
u
->
flags
&=
~
FLG_RUNNING
;
...
@@ -1462,7 +1462,7 @@ static int usbout_start(struct usb_audiodev *as)
...
@@ -1462,7 +1462,7 @@ static int usbout_start(struct usb_audiodev *as)
urb
->
context
=
as
;
urb
->
context
=
as
;
urb
->
complete
=
usbout_sync_completed
;
urb
->
complete
=
usbout_sync_completed
;
/* stride: u->syncinterval */
/* stride: u->syncinterval */
if
(
!
usbout_sync_prepare_desc
(
u
,
urb
)
&&
!
usb_submit_urb
(
urb
,
GFP_
KERNEL
))
if
(
!
usbout_sync_prepare_desc
(
u
,
urb
)
&&
!
usb_submit_urb
(
urb
,
GFP_
ATOMIC
))
u
->
flags
|=
FLG_SYNC1RUNNING
;
u
->
flags
|=
FLG_SYNC1RUNNING
;
else
else
u
->
flags
&=
~
FLG_RUNNING
;
u
->
flags
&=
~
FLG_RUNNING
;
...
...
drivers/usb/class/usb-midi.c
View file @
fa4229ad
...
@@ -337,7 +337,8 @@ static int usb_write( struct midi_out_endpoint *ep, unsigned char *buf, int len
...
@@ -337,7 +337,8 @@ static int usb_write( struct midi_out_endpoint *ep, unsigned char *buf, int len
if
(
status
)
{
if
(
status
)
{
printk
(
KERN_ERR
"usbmidi: Cannot submit urb (%d)
\n
"
,
status
);
printk
(
KERN_ERR
"usbmidi: Cannot submit urb (%d)
\n
"
,
status
);
ret
=
-
EFAULT
;
ret
=
-
EIO
;
goto
error
;
}
}
add_wait_queue
(
&
ep
->
wait
,
&
wait
);
add_wait_queue
(
&
ep
->
wait
,
&
wait
);
...
@@ -354,6 +355,7 @@ static int usb_write( struct midi_out_endpoint *ep, unsigned char *buf, int len
...
@@ -354,6 +355,7 @@ static int usb_write( struct midi_out_endpoint *ep, unsigned char *buf, int len
set_current_state
(
TASK_RUNNING
);
set_current_state
(
TASK_RUNNING
);
remove_wait_queue
(
&
ep
->
wait
,
&
wait
);
remove_wait_queue
(
&
ep
->
wait
,
&
wait
);
error:
return
ret
;
return
ret
;
}
}
...
@@ -369,7 +371,6 @@ static void usb_bulk_read(struct urb *urb, struct pt_regs *regs)
...
@@ -369,7 +371,6 @@ static void usb_bulk_read(struct urb *urb, struct pt_regs *regs)
struct
midi_in_endpoint
*
ep
=
(
struct
midi_in_endpoint
*
)(
urb
->
context
);
struct
midi_in_endpoint
*
ep
=
(
struct
midi_in_endpoint
*
)(
urb
->
context
);
unsigned
char
*
data
=
urb
->
transfer_buffer
;
unsigned
char
*
data
=
urb
->
transfer_buffer
;
int
i
,
j
,
wake
;
int
i
,
j
,
wake
;
unsigned
long
int
flags
;
if
(
!
ep
->
urbSubmitted
)
{
if
(
!
ep
->
urbSubmitted
)
{
return
;
return
;
...
@@ -377,7 +378,7 @@ static void usb_bulk_read(struct urb *urb, struct pt_regs *regs)
...
@@ -377,7 +378,7 @@ static void usb_bulk_read(struct urb *urb, struct pt_regs *regs)
if
(
(
urb
->
status
==
0
)
&&
(
urb
->
actual_length
>
0
)
)
{
if
(
(
urb
->
status
==
0
)
&&
(
urb
->
actual_length
>
0
)
)
{
wake
=
0
;
wake
=
0
;
spin_lock
_irqsave
(
&
ep
->
lock
,
flags
);
spin_lock
(
&
ep
->
lock
);
for
(
j
=
0
;
j
<
urb
->
actual_length
;
j
+=
4
)
{
for
(
j
=
0
;
j
<
urb
->
actual_length
;
j
+=
4
)
{
int
cin
=
(
data
[
j
]
>>
0
)
&
0xf
;
int
cin
=
(
data
[
j
]
>>
0
)
&
0xf
;
...
@@ -397,7 +398,7 @@ static void usb_bulk_read(struct urb *urb, struct pt_regs *regs)
...
@@ -397,7 +398,7 @@ static void usb_bulk_read(struct urb *urb, struct pt_regs *regs)
}
}
}
}
spin_unlock
_irqrestore
(
&
ep
->
lock
,
flags
);
spin_unlock
(
&
ep
->
lock
);
if
(
wake
)
{
if
(
wake
)
{
wake_up
(
&
ep
->
wait
);
wake_up
(
&
ep
->
wait
);
}
}
...
@@ -407,7 +408,7 @@ static void usb_bulk_read(struct urb *urb, struct pt_regs *regs)
...
@@ -407,7 +408,7 @@ static void usb_bulk_read(struct urb *urb, struct pt_regs *regs)
urb
->
dev
=
ep
->
usbdev
;
urb
->
dev
=
ep
->
usbdev
;
urb
->
actual_length
=
0
;
urb
->
actual_length
=
0
;
usb_submit_urb
(
urb
,
GFP_
KERNEL
);
usb_submit_urb
(
urb
,
GFP_
ATOMIC
);
}
}
...
@@ -855,7 +856,6 @@ static int usb_midi_open(struct inode *inode, struct file *file)
...
@@ -855,7 +856,6 @@ static int usb_midi_open(struct inode *inode, struct file *file)
add_wait_queue
(
&
open_wait
,
&
wait
);
add_wait_queue
(
&
open_wait
,
&
wait
);
up
(
&
open_sem
);
up
(
&
open_sem
);
schedule
();
schedule
();
__set_current_state
(
TASK_RUNNING
);
remove_wait_queue
(
&
open_wait
,
&
wait
);
remove_wait_queue
(
&
open_wait
,
&
wait
);
if
(
signal_pending
(
current
)
)
{
if
(
signal_pending
(
current
)
)
{
return
-
ERESTARTSYS
;
return
-
ERESTARTSYS
;
...
...
drivers/usb/input/xpad.c
View file @
fa4229ad
...
@@ -200,8 +200,10 @@ static int xpad_open (struct input_dev *dev)
...
@@ -200,8 +200,10 @@ static int xpad_open (struct input_dev *dev)
return
0
;
return
0
;
xpad
->
irq_in
->
dev
=
xpad
->
udev
;
xpad
->
irq_in
->
dev
=
xpad
->
udev
;
if
(
usb_submit_urb
(
xpad
->
irq_in
,
GFP_KERNEL
))
if
(
usb_submit_urb
(
xpad
->
irq_in
,
GFP_KERNEL
))
{
xpad
->
open_count
--
;
return
-
EIO
;
return
-
EIO
;
}
return
0
;
return
0
;
}
}
...
...
drivers/usb/misc/speedtouch.c
View file @
fa4229ad
...
@@ -57,6 +57,7 @@
...
@@ -57,6 +57,7 @@
#include <asm/uaccess.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
#include <linux/usb.h>
#include <linux/smp_lock.h>
#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/atm.h>
#include <linux/atm.h>
#include <linux/atmdev.h>
#include <linux/atmdev.h>
...
@@ -87,7 +88,6 @@
...
@@ -87,7 +88,6 @@
#define SPEEDTOUCH_VENDORID 0x06b9
#define SPEEDTOUCH_VENDORID 0x06b9
#define SPEEDTOUCH_PRODUCTID 0x4061
#define SPEEDTOUCH_PRODUCTID 0x4061
#define MAX_UDSL 1
#define UDSL_OBUF_SIZE 32768
#define UDSL_OBUF_SIZE 32768
#define UDSL_MINOR 48
#define UDSL_MINOR 48
#define UDSL_NUMBER_RCV_URBS 1
#define UDSL_NUMBER_RCV_URBS 1
...
@@ -137,33 +137,25 @@ struct udsl_usb_send_data_context {
...
@@ -137,33 +137,25 @@ struct udsl_usb_send_data_context {
*/
*/
struct
udsl_instance_data
{
struct
udsl_instance_data
{
int
minor
;
struct
tasklet_struct
recvqueue_tasklet
;
/* usb device part */
/* usb device part */
struct
usb_device
*
usb_dev
;
struct
usb_device
*
usb_dev
;
struct
udsl_data_ctx
*
rcvbufs
;
struct
udsl_data_ctx
*
rcvbufs
;
struct
sk_buff_head
sndqueue
;
struct
sk_buff_head
sndqueue
;
spinlock_t
sndqlock
;
struct
udsl_usb_send_data_context
send_ctx
[
UDSL_NUMBER_SND_URBS
];
struct
udsl_usb_send_data_context
send_ctx
[
UDSL_NUMBER_SND_URBS
];
int
data_started
;
int
data_started
;
/* atm device part */
/* atm device part */
struct
atm_dev
*
atm_dev
;
struct
atm_dev
*
atm_dev
;
struct
sk_buff_head
recvqueue
;
struct
sk_buff_head
recvqueue
;
spinlock_t
recvqlock
;
struct
atmsar_vcc_data
*
atmsar_vcc_list
;
struct
atmsar_vcc_data
*
atmsar_vcc_list
;
};
};
struct
udsl_instance_data
*
minor_data
[
MAX_UDSL
];
static
const
char
udsl_driver_name
[]
=
"Alcatel SpeedTouch USB"
;
static
const
char
udsl_driver_name
[]
=
"Alcatel SpeedTouch USB"
;
/* data thread */
DECLARE_WAIT_QUEUE_HEAD
(
udsl_wqh
);
static
DECLARE_COMPLETION
(
thread_grave
);
static
DECLARE_MUTEX
(
udsl_usb_ioctl_lock
);
static
DECLARE_MUTEX
(
udsl_usb_ioctl_lock
);
static
unsigned
int
datapid
;
#ifdef DEBUG_PACKET
#ifdef DEBUG_PACKET
int
udsl_print_packet
(
const
unsigned
char
*
data
,
int
len
);
int
udsl_print_packet
(
const
unsigned
char
*
data
,
int
len
);
...
@@ -178,7 +170,7 @@ static void udsl_atm_close (struct atm_vcc *vcc);
...
@@ -178,7 +170,7 @@ static void udsl_atm_close (struct atm_vcc *vcc);
static
int
udsl_atm_ioctl
(
struct
atm_dev
*
dev
,
unsigned
int
cmd
,
void
*
arg
);
static
int
udsl_atm_ioctl
(
struct
atm_dev
*
dev
,
unsigned
int
cmd
,
void
*
arg
);
static
int
udsl_atm_send
(
struct
atm_vcc
*
vcc
,
struct
sk_buff
*
skb
);
static
int
udsl_atm_send
(
struct
atm_vcc
*
vcc
,
struct
sk_buff
*
skb
);
int
udsl_atm_proc_read
(
struct
atm_dev
*
atm_dev
,
loff_t
*
pos
,
char
*
page
);
int
udsl_atm_proc_read
(
struct
atm_dev
*
atm_dev
,
loff_t
*
pos
,
char
*
page
);
void
udsl_atm_processqueue
(
struct
udsl_instance_data
*
instance
);
void
udsl_atm_processqueue
(
unsigned
long
data
);
static
struct
atmdev_ops
udsl_atm_devops
=
{
static
struct
atmdev_ops
udsl_atm_devops
=
{
.
open
=
udsl_atm_open
,
.
open
=
udsl_atm_open
,
...
@@ -244,19 +236,15 @@ void udsl_atm_stopdevice (struct udsl_instance_data *instance)
...
@@ -244,19 +236,15 @@ void udsl_atm_stopdevice (struct udsl_instance_data *instance)
struct
atm_vcc
*
walk
;
struct
atm_vcc
*
walk
;
struct
sk_buff
*
skb
;
struct
sk_buff
*
skb
;
struct
atm_dev
*
atm_dev
;
struct
atm_dev
*
atm_dev
;
unsigned
long
iflags
;
if
(
!
instance
->
atm_dev
)
if
(
!
instance
->
atm_dev
)
return
;
return
;
atm_dev
=
instance
->
atm_dev
;
atm_dev
=
instance
->
atm_dev
;
/* clean queue */
/* clean queue */
spin_lock_irqsave
(
&
instance
->
recvqlock
,
iflags
);
while
((
skb
=
skb_dequeue
(
&
instance
->
recvqueue
)))
while
(
!
skb_queue_empty
(
&
instance
->
recvqueue
))
{
skb
=
skb_dequeue
(
&
instance
->
recvqueue
);
dev_kfree_skb
(
skb
);
dev_kfree_skb
(
skb
);
};
spin_unlock_irqrestore
(
&
instance
->
recvqlock
,
iflags
);
atm_dev
->
signal
=
ATM_PHY_SIG_LOST
;
atm_dev
->
signal
=
ATM_PHY_SIG_LOST
;
walk
=
atm_dev
->
vccs
;
walk
=
atm_dev
->
vccs
;
...
@@ -296,12 +284,13 @@ struct sk_buff *udsl_atm_alloc_tx (struct atm_vcc *vcc, unsigned int size)
...
@@ -296,12 +284,13 @@ struct sk_buff *udsl_atm_alloc_tx (struct atm_vcc *vcc, unsigned int size)
int
udsl_atm_proc_read
(
struct
atm_dev
*
atm_dev
,
loff_t
*
pos
,
char
*
page
)
int
udsl_atm_proc_read
(
struct
atm_dev
*
atm_dev
,
loff_t
*
pos
,
char
*
page
)
{
{
struct
udsl_instance_data
*
instance
=
(
struct
udsl_instance_data
*
)
atm_dev
->
dev_data
;
struct
udsl_instance_data
*
instance
=
atm_dev
->
dev_data
;
int
left
=
*
pos
;
int
left
=
*
pos
;
if
(
!
left
--
)
if
(
!
left
--
)
return
sprintf
(
page
,
"Speed Touch USB:%d (%02x:%02x:%02x:%02x:%02x:%02x)
\n
"
,
return
sprintf
(
page
,
"Speed Touch USB %s-%s (%02x:%02x:%02x:%02x:%02x:%02x)
\n
"
,
instance
->
minor
,
atm_dev
->
esi
[
0
],
atm_dev
->
esi
[
1
],
atm_dev
->
esi
[
2
],
instance
->
usb_dev
->
bus
->
bus_name
,
instance
->
usb_dev
->
devpath
,
atm_dev
->
esi
[
0
],
atm_dev
->
esi
[
1
],
atm_dev
->
esi
[
2
],
atm_dev
->
esi
[
3
],
atm_dev
->
esi
[
4
],
atm_dev
->
esi
[
5
]);
atm_dev
->
esi
[
3
],
atm_dev
->
esi
[
4
],
atm_dev
->
esi
[
5
]);
if
(
!
left
--
)
if
(
!
left
--
)
...
@@ -330,8 +319,8 @@ int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t * pos, char *page)
...
@@ -330,8 +319,8 @@ int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t * pos, char *page)
****************************************************************************/
****************************************************************************/
int
udsl_atm_send
(
struct
atm_vcc
*
vcc
,
struct
sk_buff
*
skb
)
int
udsl_atm_send
(
struct
atm_vcc
*
vcc
,
struct
sk_buff
*
skb
)
{
{
struct
udsl_atm_dev_data
*
dev_data
=
(
struct
udsl_atm_dev_data
*
)
vcc
->
dev_data
;
struct
udsl_atm_dev_data
*
dev_data
=
vcc
->
dev_data
;
struct
udsl_instance_data
*
instance
=
(
struct
udsl_instance_data
*
)
vcc
->
dev
->
dev_data
;
struct
udsl_instance_data
*
instance
=
vcc
->
dev
->
dev_data
;
struct
sk_buff
*
new
=
NULL
;
struct
sk_buff
*
new
=
NULL
;
int
err
;
int
err
;
...
@@ -372,25 +361,15 @@ int udsl_atm_send (struct atm_vcc *vcc, struct sk_buff *skb)
...
@@ -372,25 +361,15 @@ int udsl_atm_send (struct atm_vcc *vcc, struct sk_buff *skb)
};
};
void
udsl_atm_processqueue
(
struct
udsl_instance_data
*
instance
)
void
udsl_atm_processqueue
(
unsigned
long
data
)
{
{
struct
udsl_instance_data
*
instance
=
(
struct
udsl_instance_data
*
)
data
;
struct
atmsar_vcc_data
*
atmsar_vcc
=
NULL
;
struct
atmsar_vcc_data
*
atmsar_vcc
=
NULL
;
struct
sk_buff
*
new
=
NULL
,
*
skb
=
NULL
,
*
tmp
=
NULL
;
struct
sk_buff
*
new
=
NULL
,
*
skb
=
NULL
,
*
tmp
=
NULL
;
unsigned
long
iflags
;
/* quick check */
spin_lock_irqsave
(
&
instance
->
recvqlock
,
iflags
);
if
(
skb_queue_empty
(
&
instance
->
recvqueue
))
{
spin_unlock_irqrestore
(
&
instance
->
recvqlock
,
iflags
);
return
;
}
PDEBUG
(
"udsl_atm_processqueue entered
\n
"
);
PDEBUG
(
"udsl_atm_processqueue entered
\n
"
);
while
(
!
skb_queue_empty
(
&
instance
->
recvqueue
))
{
while
((
skb
=
skb_dequeue
(
&
instance
->
recvqueue
)))
{
skb
=
skb_dequeue
(
&
instance
->
recvqueue
);
spin_unlock_irqrestore
(
&
instance
->
recvqlock
,
iflags
);
PDEBUG
(
"skb = %p, skb->len = %d
\n
"
,
skb
,
skb
->
len
);
PDEBUG
(
"skb = %p, skb->len = %d
\n
"
,
skb
,
skb
->
len
);
PACKETDEBUG
(
skb
->
data
,
skb
->
len
);
PACKETDEBUG
(
skb
->
data
,
skb
->
len
);
...
@@ -430,73 +409,11 @@ void udsl_atm_processqueue (struct udsl_instance_data *instance)
...
@@ -430,73 +409,11 @@ void udsl_atm_processqueue (struct udsl_instance_data *instance)
}
}
};
};
dev_kfree_skb
(
skb
);
dev_kfree_skb
(
skb
);
spin_lock_irqsave
(
&
instance
->
recvqlock
,
iflags
);
};
};
spin_unlock_irqrestore
(
&
instance
->
recvqlock
,
iflags
);
PDEBUG
(
"udsl_atm_processqueue successfull
\n
"
);
PDEBUG
(
"udsl_atm_processqueue successfull
\n
"
);
}
}
int
udsl_atm_processqueue_thread
(
void
*
data
)
{
int
i
=
0
;
DECLARE_WAITQUEUE
(
wait
,
current
);
lock_kernel
();
daemonize
();
/* Setup a nice name */
strcpy
(
current
->
comm
,
"kSpeedSARd"
);
add_wait_queue
(
&
udsl_wqh
,
&
wait
);
set_current_state
(
TASK_INTERRUPTIBLE
);
for
(;;)
{
schedule
();
if
(
signal_pending
(
current
))
break
;
PDEBUG
(
"SpeedSARd awoke
\n
"
);
retry:
for
(
i
=
0
;
i
<
MAX_UDSL
;
i
++
)
if
(
minor_data
[
i
])
udsl_atm_processqueue
(
minor_data
[
i
]);
set_current_state
(
TASK_INTERRUPTIBLE
);
/* we must check for data recieved and restart processing if there's any */
for
(
i
=
0
;
i
<
MAX_UDSL
;
i
++
)
{
spin_lock_irq
(
&
minor_data
[
i
]
->
recvqlock
);
if
(
!
skb_queue_empty
(
&
minor_data
[
i
]
->
recvqueue
))
{
spin_unlock_irq
(
&
minor_data
[
i
]
->
recvqlock
);
set_current_state
(
TASK_RUNNING
);
goto
retry
;
}
else
{
spin_unlock_irq
(
&
minor_data
[
i
]
->
recvqlock
);
}
}
};
set_current_state
(
TASK_RUNNING
);
remove_wait_queue
(
&
udsl_wqh
,
&
wait
);
PDEBUG
(
"SpeedSARd is exiting
\n
"
);
complete_and_exit
(
&
thread_grave
,
0
);
return
0
;
//never reached
}
void
udsl_atm_sar_start
(
void
)
{
datapid
=
kernel_thread
(
udsl_atm_processqueue_thread
,
(
void
*
)
NULL
,
CLONE_FS
|
CLONE_FILES
|
CLONE_SIGHAND
);
}
void
udsl_atm_sar_stop
(
void
)
{
int
ret
;
/* Kill the thread */
ret
=
kill_proc
(
datapid
,
SIGTERM
,
1
);
if
(
!
ret
)
{
wait_for_completion
(
&
thread_grave
);
}
}
/***************************************************************************
/***************************************************************************
*
*
...
@@ -506,7 +423,7 @@ void udsl_atm_sar_stop (void)
...
@@ -506,7 +423,7 @@ void udsl_atm_sar_stop (void)
int
udsl_atm_open
(
struct
atm_vcc
*
vcc
,
short
vpi
,
int
vci
)
int
udsl_atm_open
(
struct
atm_vcc
*
vcc
,
short
vpi
,
int
vci
)
{
{
struct
udsl_atm_dev_data
*
dev_data
;
struct
udsl_atm_dev_data
*
dev_data
;
struct
udsl_instance_data
*
instance
=
(
struct
udsl_instance_data
*
)
vcc
->
dev
->
dev_data
;
struct
udsl_instance_data
*
instance
=
vcc
->
dev
->
dev_data
;
PDEBUG
(
"udsl_atm_open called
\n
"
);
PDEBUG
(
"udsl_atm_open called
\n
"
);
...
@@ -515,8 +432,7 @@ int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci)
...
@@ -515,8 +432,7 @@ int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci)
return
-
EINVAL
;
return
-
EINVAL
;
MOD_INC_USE_COUNT
;
MOD_INC_USE_COUNT
;
dev_data
=
dev_data
=
kmalloc
(
sizeof
(
struct
udsl_atm_dev_data
),
GFP_KERNEL
);
(
struct
udsl_atm_dev_data
*
)
kmalloc
(
sizeof
(
struct
udsl_atm_dev_data
),
GFP_KERNEL
);
if
(
!
dev_data
)
if
(
!
dev_data
)
return
-
ENOMEM
;
return
-
ENOMEM
;
...
@@ -544,8 +460,8 @@ int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci)
...
@@ -544,8 +460,8 @@ int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci)
void
udsl_atm_close
(
struct
atm_vcc
*
vcc
)
void
udsl_atm_close
(
struct
atm_vcc
*
vcc
)
{
{
struct
udsl_atm_dev_data
*
dev_data
=
(
struct
udsl_atm_dev_data
*
)
vcc
->
dev_data
;
struct
udsl_atm_dev_data
*
dev_data
=
vcc
->
dev_data
;
struct
udsl_instance_data
*
instance
=
(
struct
udsl_instance_data
*
)
vcc
->
dev
->
dev_data
;
struct
udsl_instance_data
*
instance
=
vcc
->
dev
->
dev_data
;
PDEBUG
(
"udsl_atm_close called
\n
"
);
PDEBUG
(
"udsl_atm_close called
\n
"
);
...
@@ -596,7 +512,7 @@ struct udsl_cb {
...
@@ -596,7 +512,7 @@ struct udsl_cb {
static
void
udsl_usb_send_data_complete
(
struct
urb
*
urb
,
struct
pt_regs
*
regs
)
static
void
udsl_usb_send_data_complete
(
struct
urb
*
urb
,
struct
pt_regs
*
regs
)
{
{
struct
udsl_usb_send_data_context
*
ctx
=
(
struct
udsl_usb_send_data_context
*
)
urb
->
context
;
struct
udsl_usb_send_data_context
*
ctx
=
urb
->
context
;
struct
udsl_instance_data
*
instance
=
ctx
->
instance
;
struct
udsl_instance_data
*
instance
=
ctx
->
instance
;
int
err
;
int
err
;
...
@@ -604,17 +520,12 @@ static void udsl_usb_send_data_complete (struct urb *urb, struct pt_regs *regs)
...
@@ -604,17 +520,12 @@ static void udsl_usb_send_data_complete (struct urb *urb, struct pt_regs *regs)
ctx
->
skb
,
urb
->
status
);
ctx
->
skb
,
urb
->
status
);
ctx
->
vcc
->
pop
(
ctx
->
vcc
,
ctx
->
skb
);
ctx
->
vcc
->
pop
(
ctx
->
vcc
,
ctx
->
skb
);
ctx
->
skb
=
NULL
;
spin_lock
(
&
instance
->
sndqlock
);
if
(
!
(
ctx
->
skb
=
skb_dequeue
(
&
(
instance
->
sndqueue
))))
if
(
skb_queue_empty
(
&
instance
->
sndqueue
))
{
spin_unlock
(
&
instance
->
sndqlock
);
return
;
return
;
}
/* submit next skb */
/* submit next skb */
ctx
->
skb
=
skb_dequeue
(
&
(
instance
->
sndqueue
));
ctx
->
vcc
=
((
struct
udsl_cb
*
)
(
ctx
->
skb
->
cb
))
->
vcc
;
ctx
->
vcc
=
((
struct
udsl_cb
*
)
(
ctx
->
skb
->
cb
))
->
vcc
;
spin_unlock
(
&
instance
->
sndqlock
);
usb_fill_bulk_urb
(
urb
,
usb_fill_bulk_urb
(
urb
,
instance
->
usb_dev
,
instance
->
usb_dev
,
usb_sndbulkpipe
(
instance
->
usb_dev
,
UDSL_ENDPOINT_DATA_OUT
),
usb_sndbulkpipe
(
instance
->
usb_dev
,
UDSL_ENDPOINT_DATA_OUT
),
...
@@ -661,13 +572,13 @@ int udsl_usb_send_data (struct udsl_instance_data *instance, struct atm_vcc *vcc
...
@@ -661,13 +572,13 @@ int udsl_usb_send_data (struct udsl_instance_data *instance, struct atm_vcc *vcc
PACKETDEBUG
(
skb
->
data
,
skb
->
len
);
PACKETDEBUG
(
skb
->
data
,
skb
->
len
);
spin_lock_irqsave
(
&
instance
->
sndqlock
,
flags
);
spin_lock_irqsave
(
&
instance
->
sndq
ueue
.
lock
,
flags
);
((
struct
udsl_cb
*
)
skb
->
cb
)
->
vcc
=
vcc
;
((
struct
udsl_cb
*
)
skb
->
cb
)
->
vcc
=
vcc
;
/* we are already queueing */
/* we are already queueing */
if
(
!
skb_queue_empty
(
&
instance
->
sndqueue
))
{
if
(
!
skb_queue_empty
(
&
instance
->
sndqueue
))
{
skb_queue_tail
(
&
instance
->
sndqueue
,
skb
);
__
skb_queue_tail
(
&
instance
->
sndqueue
,
skb
);
spin_unlock_irqrestore
(
&
instance
->
sndqlock
,
flags
);
spin_unlock_irqrestore
(
&
instance
->
sndq
ueue
.
lock
,
flags
);
PDEBUG
(
"udsl_usb_send_data: already queing, skb (0x%p) queued
\n
"
,
skb
);
PDEBUG
(
"udsl_usb_send_data: already queing, skb (0x%p) queued
\n
"
,
skb
);
return
0
;
return
0
;
}
}
...
@@ -678,8 +589,8 @@ int udsl_usb_send_data (struct udsl_instance_data *instance, struct atm_vcc *vcc
...
@@ -678,8 +589,8 @@ int udsl_usb_send_data (struct udsl_instance_data *instance, struct atm_vcc *vcc
/* we must start queueing */
/* we must start queueing */
if
(
i
==
UDSL_NUMBER_SND_URBS
)
{
if
(
i
==
UDSL_NUMBER_SND_URBS
)
{
skb_queue_tail
(
&
instance
->
sndqueue
,
skb
);
__
skb_queue_tail
(
&
instance
->
sndqueue
,
skb
);
spin_unlock_irqrestore
(
&
instance
->
sndqlock
,
flags
);
spin_unlock_irqrestore
(
&
instance
->
sndq
ueue
.
lock
,
flags
);
PDEBUG
(
"udsl_usb_send_data: skb (0x%p) queued
\n
"
,
skb
);
PDEBUG
(
"udsl_usb_send_data: skb (0x%p) queued
\n
"
,
skb
);
return
0
;
return
0
;
};
};
...
@@ -690,7 +601,7 @@ int udsl_usb_send_data (struct udsl_instance_data *instance, struct atm_vcc *vcc
...
@@ -690,7 +601,7 @@ int udsl_usb_send_data (struct udsl_instance_data *instance, struct atm_vcc *vcc
instance
->
send_ctx
[
i
].
vcc
=
vcc
;
instance
->
send_ctx
[
i
].
vcc
=
vcc
;
instance
->
send_ctx
[
i
].
instance
=
instance
;
instance
->
send_ctx
[
i
].
instance
=
instance
;
spin_unlock_irqrestore
(
&
instance
->
sndqlock
,
flags
);
spin_unlock_irqrestore
(
&
instance
->
sndq
ueue
.
lock
,
flags
);
/* submit packet */
/* submit packet */
usb_fill_bulk_urb
(
urb
,
usb_fill_bulk_urb
(
urb
,
...
@@ -722,7 +633,7 @@ void udsl_usb_data_receive (struct urb *urb, struct pt_regs *regs)
...
@@ -722,7 +633,7 @@ void udsl_usb_data_receive (struct urb *urb, struct pt_regs *regs)
PDEBUG
(
"udsl_usb_receive_data entered, got packet %p with length %d an status %d
\n
"
,
urb
,
PDEBUG
(
"udsl_usb_receive_data entered, got packet %p with length %d an status %d
\n
"
,
urb
,
urb
->
actual_length
,
urb
->
status
);
urb
->
actual_length
,
urb
->
status
);
ctx
=
(
struct
udsl_data_ctx
*
)
urb
->
context
;
ctx
=
urb
->
context
;
if
(
!
ctx
||
!
ctx
->
skb
)
if
(
!
ctx
||
!
ctx
->
skb
)
return
;
return
;
...
@@ -736,10 +647,8 @@ void udsl_usb_data_receive (struct urb *urb, struct pt_regs *regs)
...
@@ -736,10 +647,8 @@ void udsl_usb_data_receive (struct urb *urb, struct pt_regs *regs)
skb_put
(
ctx
->
skb
,
urb
->
actual_length
);
skb_put
(
ctx
->
skb
,
urb
->
actual_length
);
/* queue the skb for processing and wake the SAR */
/* queue the skb for processing and wake the SAR */
spin_lock
(
&
instance
->
recvqlock
);
skb_queue_tail
(
&
instance
->
recvqueue
,
ctx
->
skb
);
skb_queue_tail
(
&
instance
->
recvqueue
,
ctx
->
skb
);
spin_unlock
(
&
instance
->
recvqlock
);
tasklet_schedule
(
&
instance
->
recvqueue_tasklet
);
wake_up
(
&
udsl_wqh
);
/* get a new skb */
/* get a new skb */
ctx
->
skb
=
dev_alloc_skb
(
UDSL_RECEIVE_BUFFER_SIZE
);
ctx
->
skb
=
dev_alloc_skb
(
UDSL_RECEIVE_BUFFER_SIZE
);
if
(
!
ctx
->
skb
)
{
if
(
!
ctx
->
skb
)
{
...
@@ -781,9 +690,7 @@ int udsl_usb_data_init (struct udsl_instance_data *instance)
...
@@ -781,9 +690,7 @@ int udsl_usb_data_init (struct udsl_instance_data *instance)
usb_maxpacket
(
instance
->
usb_dev
,
usb_maxpacket
(
instance
->
usb_dev
,
usb_sndbulkpipe
(
instance
->
usb_dev
,
UDSL_ENDPOINT_DATA_OUT
),
0
));
usb_sndbulkpipe
(
instance
->
usb_dev
,
UDSL_ENDPOINT_DATA_OUT
),
0
));
instance
->
rcvbufs
=
instance
->
rcvbufs
=
kmalloc
(
sizeof
(
struct
udsl_data_ctx
)
*
UDSL_NUMBER_RCV_URBS
,
GFP_KERNEL
);
(
struct
udsl_data_ctx
*
)
kmalloc
(
sizeof
(
struct
udsl_data_ctx
)
*
UDSL_NUMBER_RCV_URBS
,
GFP_KERNEL
);
if
(
!
instance
->
rcvbufs
)
if
(
!
instance
->
rcvbufs
)
return
-
ENOMEM
;
return
-
ENOMEM
;
...
@@ -902,18 +809,8 @@ static int udsl_usb_data_exit (struct udsl_instance_data *instance)
...
@@ -902,18 +809,8 @@ static int udsl_usb_data_exit (struct udsl_instance_data *instance)
static
int
udsl_usb_ioctl
(
struct
usb_interface
*
intf
,
unsigned
int
code
,
void
*
user_data
)
static
int
udsl_usb_ioctl
(
struct
usb_interface
*
intf
,
unsigned
int
code
,
void
*
user_data
)
{
{
struct
usb_device
*
dev
=
interface_to_usbdev
(
intf
);
struct
udsl_instance_data
*
instance
=
usb_get_intfdata
(
intf
);
struct
udsl_instance_data
*
instance
;
int
retval
;
int
i
,
retval
;
for
(
i
=
0
;
i
<
MAX_UDSL
;
i
++
)
if
(
minor_data
[
i
]
&&
(
minor_data
[
i
]
->
usb_dev
==
dev
))
break
;
if
(
i
==
MAX_UDSL
)
return
-
EINVAL
;
instance
=
minor_data
[
i
];
down
(
&
udsl_usb_ioctl_lock
);
down
(
&
udsl_usb_ioctl_lock
);
switch
(
code
)
{
switch
(
code
)
{
...
@@ -950,16 +847,7 @@ static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_i
...
@@ -950,16 +847,7 @@ static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_i
MOD_INC_USE_COUNT
;
MOD_INC_USE_COUNT
;
for
(
i
=
0
;
i
<
MAX_UDSL
;
i
++
)
PDEBUG
(
"Device Accepted
\n
"
);
if
(
minor_data
[
i
]
==
NULL
)
break
;
if
(
i
>=
MAX_UDSL
)
{
printk
(
KERN_INFO
"No minor table space available for SpeedTouch USB
\n
"
);
return
-
ENOMEM
;
};
PDEBUG
(
"Device Accepted, assigning minor %d
\n
"
,
i
);
/* device init */
/* device init */
instance
=
kmalloc
(
sizeof
(
struct
udsl_instance_data
),
GFP_KERNEL
);
instance
=
kmalloc
(
sizeof
(
struct
udsl_instance_data
),
GFP_KERNEL
);
...
@@ -970,11 +858,9 @@ static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_i
...
@@ -970,11 +858,9 @@ static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_i
/* initialize structure */
/* initialize structure */
memset
(
instance
,
0
,
sizeof
(
struct
udsl_instance_data
));
memset
(
instance
,
0
,
sizeof
(
struct
udsl_instance_data
));
instance
->
minor
=
i
;
instance
->
usb_dev
=
dev
;
instance
->
usb_dev
=
dev
;
instance
->
rcvbufs
=
NULL
;
instance
->
rcvbufs
=
NULL
;
spin_lock_init
(
&
instance
->
sndqlock
);
tasklet_init
(
&
instance
->
recvqueue_tasklet
,
udsl_atm_processqueue
,
(
unsigned
long
)
instance
);
spin_lock_init
(
&
instance
->
recvqlock
);
udsl_atm_startdevice
(
instance
,
&
udsl_atm_devops
);
udsl_atm_startdevice
(
instance
,
&
udsl_atm_devops
);
...
@@ -987,8 +873,6 @@ static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_i
...
@@ -987,8 +873,6 @@ static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_i
mac
[
5
]);
mac
[
5
]);
udsl_atm_set_mac
(
instance
,
mac
);
udsl_atm_set_mac
(
instance
,
mac
);
minor_data
[
instance
->
minor
]
=
instance
;
usb_set_intfdata
(
intf
,
instance
);
usb_set_intfdata
(
intf
,
instance
);
return
0
;
return
0
;
}
}
...
@@ -996,11 +880,11 @@ static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_i
...
@@ -996,11 +880,11 @@ static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_i
static
void
udsl_usb_disconnect
(
struct
usb_interface
*
intf
)
static
void
udsl_usb_disconnect
(
struct
usb_interface
*
intf
)
{
{
struct
udsl_instance_data
*
instance
=
usb_get_intfdata
(
intf
);
struct
udsl_instance_data
*
instance
=
usb_get_intfdata
(
intf
);
int
i
;
PDEBUG
(
"disconnecting
\n
"
);
usb_set_intfdata
(
intf
,
NULL
);
usb_set_intfdata
(
intf
,
NULL
);
if
(
instance
)
{
if
(
instance
)
{
i
=
instance
->
minor
;
/* unlinking receive buffers */
/* unlinking receive buffers */
udsl_usb_data_exit
(
instance
);
udsl_usb_data_exit
(
instance
);
...
@@ -1008,10 +892,7 @@ static void udsl_usb_disconnect (struct usb_interface *intf)
...
@@ -1008,10 +892,7 @@ static void udsl_usb_disconnect (struct usb_interface *intf)
if
(
instance
->
atm_dev
)
if
(
instance
->
atm_dev
)
udsl_atm_stopdevice
(
instance
);
udsl_atm_stopdevice
(
instance
);
PDEBUG
(
"disconnecting minor %d
\n
"
,
i
);
kfree
(
instance
);
kfree
(
instance
);
minor_data
[
i
]
=
NULL
;
MOD_DEC_USE_COUNT
;
MOD_DEC_USE_COUNT
;
}
}
...
@@ -1025,23 +906,13 @@ static void udsl_usb_disconnect (struct usb_interface *intf)
...
@@ -1025,23 +906,13 @@ static void udsl_usb_disconnect (struct usb_interface *intf)
static
int
__init
udsl_usb_init
(
void
)
static
int
__init
udsl_usb_init
(
void
)
{
{
int
i
;
PDEBUG
(
"Initializing SpeedTouch Driver Version "
DRIVER_VERSION
"
\n
"
);
PDEBUG
(
"Initializing SpeedTouch Driver Version "
DRIVER_VERSION
"
\n
"
);
for
(
i
=
0
;
i
<
MAX_UDSL
;
i
++
)
minor_data
[
i
]
=
NULL
;
init_waitqueue_head
(
&
udsl_wqh
);
udsl_atm_sar_start
();
return
usb_register
(
&
udsl_usb_driver
);
return
usb_register
(
&
udsl_usb_driver
);
}
}
static
void
__exit
udsl_usb_cleanup
(
void
)
static
void
__exit
udsl_usb_cleanup
(
void
)
{
{
/* killing threads */
udsl_atm_sar_stop
();
usb_deregister
(
&
udsl_usb_driver
);
usb_deregister
(
&
udsl_usb_driver
);
}
}
...
...
drivers/usb/serial/digi_acceleport.c
View file @
fa4229ad
...
@@ -507,7 +507,8 @@ static struct usb_driver digi_driver = {
...
@@ -507,7 +507,8 @@ static struct usb_driver digi_driver = {
static
struct
usb_serial_device_type
digi_acceleport_2_device
=
{
static
struct
usb_serial_device_type
digi_acceleport_2_device
=
{
.
owner
=
THIS_MODULE
,
.
owner
=
THIS_MODULE
,
.
name
=
"Digi USB"
,
.
name
=
"Digi 2 port USB adapter"
,
.
short_name
=
"digi_2"
,
.
id_table
=
id_table_2
,
.
id_table
=
id_table_2
,
.
num_interrupt_in
=
0
,
.
num_interrupt_in
=
0
,
.
num_bulk_in
=
4
,
.
num_bulk_in
=
4
,
...
@@ -531,7 +532,8 @@ static struct usb_serial_device_type digi_acceleport_2_device = {
...
@@ -531,7 +532,8 @@ static struct usb_serial_device_type digi_acceleport_2_device = {
static
struct
usb_serial_device_type
digi_acceleport_4_device
=
{
static
struct
usb_serial_device_type
digi_acceleport_4_device
=
{
.
owner
=
THIS_MODULE
,
.
owner
=
THIS_MODULE
,
.
name
=
"Digi USB"
,
.
name
=
"Digi 4 port USB adapter"
,
.
short_name
=
"digi_4"
,
.
id_table
=
id_table_4
,
.
id_table
=
id_table_4
,
.
num_interrupt_in
=
0
,
.
num_interrupt_in
=
0
,
.
num_bulk_in
=
5
,
.
num_bulk_in
=
5
,
...
...
drivers/usb/serial/usb-serial.c
View file @
fa4229ad
...
@@ -910,7 +910,7 @@ int usb_serial_probe(struct usb_interface *interface,
...
@@ -910,7 +910,7 @@ int usb_serial_probe(struct usb_interface *interface,
kfree
(
serial
);
kfree
(
serial
);
return
-
EIO
;
return
-
EIO
;
}
}
retval
=
type
->
probe
(
serial
,
id
);
retval
=
type
->
probe
(
serial
,
id
_pattern
);
module_put
(
type
->
owner
);
module_put
(
type
->
owner
);
if
(
retval
<
0
)
{
if
(
retval
<
0
)
{
...
...
drivers/usb/serial/visor.c
View file @
fa4229ad
...
@@ -177,24 +177,40 @@ static void visor_write_bulk_callback (struct urb *urb, struct pt_regs *regs);
...
@@ -177,24 +177,40 @@ static void visor_write_bulk_callback (struct urb *urb, struct pt_regs *regs);
static
void
visor_read_bulk_callback
(
struct
urb
*
urb
,
struct
pt_regs
*
regs
);
static
void
visor_read_bulk_callback
(
struct
urb
*
urb
,
struct
pt_regs
*
regs
);
static
void
visor_read_int_callback
(
struct
urb
*
urb
,
struct
pt_regs
*
regs
);
static
void
visor_read_int_callback
(
struct
urb
*
urb
,
struct
pt_regs
*
regs
);
static
int
clie_3_5_startup
(
struct
usb_serial
*
serial
);
static
int
clie_3_5_startup
(
struct
usb_serial
*
serial
);
static
int
palm_os_3_probe
(
struct
usb_serial
*
serial
,
const
struct
usb_device_id
*
id
);
static
int
palm_os_4_probe
(
struct
usb_serial
*
serial
,
const
struct
usb_device_id
*
id
);
static
struct
usb_device_id
id_table
[]
=
{
static
struct
usb_device_id
id_table
[]
=
{
{
USB_DEVICE
(
PALM_VENDOR_ID
,
PALM_M500_ID
)
},
{
USB_DEVICE
(
HANDSPRING_VENDOR_ID
,
HANDSPRING_VISOR_ID
),
{
USB_DEVICE
(
PALM_VENDOR_ID
,
PALM_M505_ID
)
},
.
driver_info
=
(
unsigned
int
)
&
palm_os_3_probe
},
{
USB_DEVICE
(
PALM_VENDOR_ID
,
PALM_M515_ID
)
},
{
USB_DEVICE
(
HANDSPRING_VENDOR_ID
,
HANDSPRING_TREO_ID
),
{
USB_DEVICE
(
PALM_VENDOR_ID
,
PALM_I705_ID
)
},
.
driver_info
=
(
unsigned
int
)
&
palm_os_4_probe
},
{
USB_DEVICE
(
PALM_VENDOR_ID
,
PALM_M125_ID
)
},
{
USB_DEVICE
(
PALM_VENDOR_ID
,
PALM_M500_ID
),
{
USB_DEVICE
(
PALM_VENDOR_ID
,
PALM_M130_ID
)
},
.
driver_info
=
(
unsigned
int
)
&
palm_os_4_probe
},
{
USB_DEVICE
(
PALM_VENDOR_ID
,
PALM_TUNGSTEN_T_ID
)
},
{
USB_DEVICE
(
PALM_VENDOR_ID
,
PALM_M505_ID
),
{
USB_DEVICE
(
PALM_VENDOR_ID
,
PALM_TUNGSTEN_Z_ID
)
},
.
driver_info
=
(
unsigned
int
)
&
palm_os_4_probe
},
{
USB_DEVICE
(
PALM_VENDOR_ID
,
PALM_ZIRE_ID
)
},
{
USB_DEVICE
(
PALM_VENDOR_ID
,
PALM_M515_ID
),
{
USB_DEVICE
(
HANDSPRING_VENDOR_ID
,
HANDSPRING_VISOR_ID
)
},
.
driver_info
=
(
unsigned
int
)
&
palm_os_4_probe
},
{
USB_DEVICE
(
HANDSPRING_VENDOR_ID
,
HANDSPRING_TREO_ID
)
},
{
USB_DEVICE
(
PALM_VENDOR_ID
,
PALM_I705_ID
),
{
USB_DEVICE
(
SONY_VENDOR_ID
,
SONY_CLIE_4_0_ID
)
},
.
driver_info
=
(
unsigned
int
)
&
palm_os_4_probe
},
{
USB_DEVICE
(
SONY_VENDOR_ID
,
SONY_CLIE_S360_ID
)
},
{
USB_DEVICE
(
PALM_VENDOR_ID
,
PALM_M125_ID
),
.
driver_info
=
(
unsigned
int
)
&
palm_os_4_probe
},
{
USB_DEVICE
(
PALM_VENDOR_ID
,
PALM_M130_ID
),
.
driver_info
=
(
unsigned
int
)
&
palm_os_4_probe
},
{
USB_DEVICE
(
PALM_VENDOR_ID
,
PALM_TUNGSTEN_T_ID
),
.
driver_info
=
(
unsigned
int
)
&
palm_os_4_probe
},
{
USB_DEVICE
(
PALM_VENDOR_ID
,
PALM_TUNGSTEN_Z_ID
),
.
driver_info
=
(
unsigned
int
)
&
palm_os_4_probe
},
{
USB_DEVICE
(
PALM_VENDOR_ID
,
PALM_ZIRE_ID
),
.
driver_info
=
(
unsigned
int
)
&
palm_os_4_probe
},
{
USB_DEVICE
(
SONY_VENDOR_ID
,
SONY_CLIE_4_0_ID
),
.
driver_info
=
(
unsigned
int
)
&
palm_os_4_probe
},
{
USB_DEVICE
(
SONY_VENDOR_ID
,
SONY_CLIE_S360_ID
),
.
driver_info
=
(
unsigned
int
)
&
palm_os_4_probe
},
{
USB_DEVICE
(
SONY_VENDOR_ID
,
SONY_CLIE_4_1_ID
)
},
{
USB_DEVICE
(
SONY_VENDOR_ID
,
SONY_CLIE_4_1_ID
)
},
{
USB_DEVICE
(
SONY_VENDOR_ID
,
SONY_CLIE_NX60_ID
)
},
{
USB_DEVICE
(
SONY_VENDOR_ID
,
SONY_CLIE_NX60_ID
),
.
driver_info
=
(
unsigned
int
)
&
palm_os_4_probe
},
{
}
/* Terminating entry */
{
}
/* Terminating entry */
};
};
...
@@ -600,101 +616,145 @@ static void visor_unthrottle (struct usb_serial_port *port)
...
@@ -600,101 +616,145 @@ static void visor_unthrottle (struct usb_serial_port *port)
dev_err
(
&
port
->
dev
,
"%s - failed submitting read urb, error %d
\n
"
,
__FUNCTION__
,
result
);
dev_err
(
&
port
->
dev
,
"%s - failed submitting read urb, error %d
\n
"
,
__FUNCTION__
,
result
);
}
}
static
int
visor
_probe
(
struct
usb_serial
*
serial
,
const
struct
usb_device_id
*
id
)
static
int
palm_os_3
_probe
(
struct
usb_serial
*
serial
,
const
struct
usb_device_id
*
id
)
{
{
struct
device
*
dev
=
&
serial
->
dev
->
dev
;
struct
device
*
dev
=
&
serial
->
dev
->
dev
;
int
response
;
struct
visor_connection_info
*
connection_info
;
unsigned
char
*
transfer_buffer
;
char
*
string
;
int
retval
=
0
;
int
i
;
int
i
;
int
num_ports
;
int
num_ports
;
unsigned
char
*
transfer_buffer
=
kmalloc
(
256
,
GFP_KERNEL
);
dbg
(
"%s"
,
__FUNCTION__
);
transfer_buffer
=
kmalloc
(
sizeof
(
*
connection_info
),
GFP_KERNEL
);
if
(
!
transfer_buffer
)
{
if
(
!
transfer_buffer
)
{
dev_err
(
dev
,
"%s - kmalloc(%d) failed.
\n
"
,
__FUNCTION__
,
256
);
dev_err
(
dev
,
"%s - kmalloc(%d) failed.
\n
"
,
__FUNCTION__
,
sizeof
(
*
connection_info
));
return
-
ENOMEM
;
return
-
ENOMEM
;
}
}
dbg
(
"%s"
,
__FUNCTION__
);
dbg
(
"%s - Set config to 1"
,
__FUNCTION__
);
usb_set_configuration
(
serial
->
dev
,
1
);
/* send a get connection info request */
/* send a get connection info request */
response
=
usb_control_msg
(
serial
->
dev
,
usb_rcvctrlpipe
(
serial
->
dev
,
0
),
VISOR_GET_CONNECTION_INFORMATION
,
retval
=
usb_control_msg
(
serial
->
dev
,
0xc2
,
0x0000
,
0x0000
,
transfer_buffer
,
0x12
,
300
);
usb_rcvctrlpipe
(
serial
->
dev
,
0
),
if
(
response
<
0
)
{
VISOR_GET_CONNECTION_INFORMATION
,
dev_err
(
dev
,
"%s - error getting connection information
\n
"
,
__FUNCTION__
);
0xc2
,
0x0000
,
0x0000
,
transfer_buffer
,
}
else
{
sizeof
(
*
connection_info
),
300
);
struct
visor_connection_info
*
connection_info
=
(
struct
visor_connection_info
*
)
transfer_buffer
;
if
(
retval
<
0
)
{
char
*
string
;
dev_err
(
dev
,
"%s - error %d getting connection information
\n
"
,
__FUNCTION__
,
retval
);
le16_to_cpus
(
&
connection_info
->
num_ports
);
goto
exit
;
num_ports
=
connection_info
->
num_ports
;
dev_info
(
dev
,
"%s: Number of ports: %d
\n
"
,
serial
->
type
->
name
,
connection_info
->
num_ports
);
for
(
i
=
0
;
i
<
num_ports
;
++
i
)
{
switch
(
connection_info
->
connections
[
i
].
port_function_id
)
{
case
VISOR_FUNCTION_GENERIC
:
string
=
"Generic"
;
break
;
case
VISOR_FUNCTION_DEBUGGER
:
string
=
"Debugger"
;
break
;
case
VISOR_FUNCTION_HOTSYNC
:
string
=
"HotSync"
;
break
;
case
VISOR_FUNCTION_CONSOLE
:
string
=
"Console"
;
break
;
case
VISOR_FUNCTION_REMOTE_FILE_SYS
:
string
=
"Remote File System"
;
break
;
default:
string
=
"unknown"
;
break
;
}
dev_info
(
dev
,
"%s: port %d, is for %s use
\n
"
,
serial
->
type
->
name
,
connection_info
->
connections
[
i
].
port
,
string
);
/* save off our num_ports info so that we can use it in the calc_num_ports call */
usb_set_serial_data
(
serial
,
(
void
*
)(
long
)
num_ports
);
}
}
}
if
((
serial
->
dev
->
descriptor
.
idVendor
==
PALM_VENDOR_ID
)
||
connection_info
=
(
struct
visor_connection_info
*
)
transfer_buffer
;
((
serial
->
dev
->
descriptor
.
idVendor
==
SONY_VENDOR_ID
)
&&
(
serial
->
dev
->
descriptor
.
idProduct
!=
SONY_CLIE_4_1_ID
)))
{
le16_to_cpus
(
&
connection_info
->
num_ports
);
/* Palm OS 4.0 Hack */
num_ports
=
connection_info
->
num_ports
;
response
=
usb_control_msg
(
serial
->
dev
,
usb_rcvctrlpipe
(
serial
->
dev
,
0
),
/* handle devices that report invalid stuff here */
PALM_GET_SOME_UNKNOWN_INFORMATION
,
if
(
num_ports
>
2
)
0xc2
,
0x0000
,
0x0000
,
transfer_buffer
,
num_ports
=
2
;
0x14
,
300
);
dev_info
(
dev
,
"%s: Number of ports: %d
\n
"
,
serial
->
type
->
name
,
if
(
response
<
0
)
{
connection_info
->
num_ports
);
dev_err
(
dev
,
"%s - error getting first unknown palm command
\n
"
,
__FUNCTION__
);
}
else
{
for
(
i
=
0
;
i
<
num_ports
;
++
i
)
{
usb_serial_debug_data
(
__FILE__
,
__FUNCTION__
,
0x14
,
transfer_buffer
);
switch
(
connection_info
->
connections
[
i
].
port_function_id
)
{
}
case
VISOR_FUNCTION_GENERIC
:
response
=
usb_control_msg
(
serial
->
dev
,
usb_rcvctrlpipe
(
serial
->
dev
,
0
),
string
=
"Generic"
;
PALM_GET_SOME_UNKNOWN_INFORMATION
,
break
;
0xc2
,
0x0000
,
0x0000
,
transfer_buffer
,
case
VISOR_FUNCTION_DEBUGGER
:
0x14
,
300
);
string
=
"Debugger"
;
if
(
response
<
0
)
{
break
;
dev_err
(
dev
,
"%s - error getting second unknown palm command
\n
"
,
__FUNCTION__
);
case
VISOR_FUNCTION_HOTSYNC
:
}
else
{
string
=
"HotSync"
;
usb_serial_debug_data
(
__FILE__
,
__FUNCTION__
,
0x14
,
transfer_buffer
);
break
;
case
VISOR_FUNCTION_CONSOLE
:
string
=
"Console"
;
break
;
case
VISOR_FUNCTION_REMOTE_FILE_SYS
:
string
=
"Remote File System"
;
break
;
default:
string
=
"unknown"
;
break
;
}
}
dev_info
(
dev
,
"%s: port %d, is for %s use
\n
"
,
serial
->
type
->
name
,
connection_info
->
connections
[
i
].
port
,
string
);
}
}
/*
* save off our num_ports info so that we can use it in the
* calc_num_ports callback
*/
usb_set_serial_data
(
serial
,
(
void
*
)(
long
)
num_ports
);
/* ask for the number of bytes available, but ignore the response as it is broken */
/* ask for the number of bytes available, but ignore the response as it is broken */
response
=
usb_control_msg
(
serial
->
dev
,
usb_rcvctrlpipe
(
serial
->
dev
,
0
),
VISOR_REQUEST_BYTES_AVAILABLE
,
retval
=
usb_control_msg
(
serial
->
dev
,
0xc2
,
0x0000
,
0x0005
,
transfer_buffer
,
0x02
,
300
);
usb_rcvctrlpipe
(
serial
->
dev
,
0
),
if
(
response
<
0
)
{
VISOR_REQUEST_BYTES_AVAILABLE
,
dev_err
(
dev
,
"%s - error getting bytes available request
\n
"
,
__FUNCTION__
);
0xc2
,
0x0000
,
0x0005
,
transfer_buffer
,
}
0x02
,
300
);
if
(
retval
<
0
)
dev_err
(
dev
,
"%s - error %d getting bytes available request
\n
"
,
__FUNCTION__
,
retval
);
retval
=
0
;
exit:
kfree
(
transfer_buffer
);
kfree
(
transfer_buffer
);
/* continue on with initialization */
return
retval
;
}
static
int
palm_os_4_probe
(
struct
usb_serial
*
serial
,
const
struct
usb_device_id
*
id
)
{
struct
device
*
dev
=
&
serial
->
dev
->
dev
;
struct
palm_ext_connection_info
*
connection_info
;
unsigned
char
*
transfer_buffer
;
int
retval
;
dbg
(
"%s"
,
__FUNCTION__
);
transfer_buffer
=
kmalloc
(
sizeof
(
*
connection_info
),
GFP_KERNEL
);
if
(
!
transfer_buffer
)
{
dev_err
(
dev
,
"%s - kmalloc(%d) failed.
\n
"
,
__FUNCTION__
,
sizeof
(
*
connection_info
));
return
-
ENOMEM
;
}
retval
=
usb_control_msg
(
serial
->
dev
,
usb_rcvctrlpipe
(
serial
->
dev
,
0
),
PALM_GET_EXT_CONNECTION_INFORMATION
,
0xc2
,
0x0000
,
0x0000
,
transfer_buffer
,
sizeof
(
*
connection_info
),
300
);
if
(
retval
<
0
)
dev_err
(
dev
,
"%s - error %d getting connection info
\n
"
,
__FUNCTION__
,
retval
);
else
usb_serial_debug_data
(
__FILE__
,
__FUNCTION__
,
0x14
,
transfer_buffer
);
kfree
(
transfer_buffer
);
return
0
;
return
0
;
}
}
static
int
visor_probe
(
struct
usb_serial
*
serial
,
const
struct
usb_device_id
*
id
)
{
int
retval
=
0
;
int
(
*
startup
)
(
struct
usb_serial
*
serial
,
const
struct
usb_device_id
*
id
);
dbg
(
"%s"
,
__FUNCTION__
);
dbg
(
"%s - Set config to 1"
,
__FUNCTION__
);
usb_set_configuration
(
serial
->
dev
,
1
);
if
(
id
->
driver_info
)
{
startup
=
(
void
*
)
id
->
driver_info
;
retval
=
startup
(
serial
,
id
);
}
return
retval
;
}
static
int
visor_calc_num_ports
(
struct
usb_serial
*
serial
)
static
int
visor_calc_num_ports
(
struct
usb_serial
*
serial
)
{
{
int
num_ports
=
(
int
)(
long
)(
usb_get_serial_data
(
serial
));
int
num_ports
=
(
int
)(
long
)(
usb_get_serial_data
(
serial
));
...
...
drivers/usb/serial/visor.h
View file @
fa4229ad
...
@@ -94,7 +94,36 @@ struct visor_connection_info {
...
@@ -94,7 +94,36 @@ struct visor_connection_info {
* PALM_GET_SOME_UNKNOWN_INFORMATION is sent by the host during enumeration to
* PALM_GET_SOME_UNKNOWN_INFORMATION is sent by the host during enumeration to
* get some information from the M series devices, that is currently unknown.
* get some information from the M series devices, that is currently unknown.
****************************************************************************/
****************************************************************************/
#define PALM_GET_SOME_UNKNOWN_INFORMATION 0x04
#define PALM_GET_EXT_CONNECTION_INFORMATION 0x04
/**
* struct palm_ext_connection_info - return data from a PALM_GET_EXT_CONNECTION_INFORMATION request
* @num_ports: maximum number of functions/connections in use
* @endpoint_numbers_different: will be 1 if in and out endpoints numbers are
* different, otherwise it is 0. If value is 1, then
* connections.end_point_info is non-zero. If value is 0, then
* connections.port contains the endpoint number, which is the same for in
* and out.
* @port_function_id: contains the creator id of the applicaton that opened
* this connection.
* @port: contains the in/out endpoint number. Is 0 if in and out endpoint
* numbers are different.
* @end_point_info: high nubbe is in endpoint and low nibble will indicate out
* endpoint. Is 0 if in and out endpoints are the same.
*
* The maximum number of connections currently supported is 2
*/
struct
palm_ext_connection_info
{
__u8
num_ports
;
__u8
endpoint_numbers_different
;
__u16
reserved1
;
struct
{
__u32
port_function_id
;
__u8
port
;
__u8
end_point_info
;
__u16
reserved
;
}
connections
[
2
];
};
#endif
#endif
drivers/usb/storage/debug.c
View file @
fa4229ad
...
@@ -49,6 +49,7 @@
...
@@ -49,6 +49,7 @@
void
usb_stor_show_command
(
Scsi_Cmnd
*
srb
)
void
usb_stor_show_command
(
Scsi_Cmnd
*
srb
)
{
{
char
*
what
=
NULL
;
char
*
what
=
NULL
;
int
i
;
switch
(
srb
->
cmnd
[
0
])
{
switch
(
srb
->
cmnd
[
0
])
{
case
TEST_UNIT_READY
:
what
=
"TEST_UNIT_READY"
;
break
;
case
TEST_UNIT_READY
:
what
=
"TEST_UNIT_READY"
;
break
;
...
@@ -143,29 +144,25 @@ void usb_stor_show_command(Scsi_Cmnd *srb)
...
@@ -143,29 +144,25 @@ void usb_stor_show_command(Scsi_Cmnd *srb)
default:
what
=
"(unknown command)"
;
break
;
default:
what
=
"(unknown command)"
;
break
;
}
}
US_DEBUGP
(
"Command %s (%d bytes)
\n
"
,
what
,
srb
->
cmd_len
);
US_DEBUGP
(
"Command %s (%d bytes)
\n
"
,
what
,
srb
->
cmd_len
);
US_DEBUGP
(
"%02x %02x %02x %02x "
US_DEBUGP
(
""
);
"%02x %02x %02x %02x "
for
(
i
=
0
;
i
<
srb
->
cmd_len
&&
i
<
16
;
i
++
)
"%02x %02x %02x %02x
\n
"
,
US_DEBUGPX
(
" %02x"
,
srb
->
cmnd
[
i
]);
srb
->
cmnd
[
0
],
srb
->
cmnd
[
1
],
srb
->
cmnd
[
2
],
srb
->
cmnd
[
3
],
US_DEBUGPX
(
"
\n
"
);
srb
->
cmnd
[
4
],
srb
->
cmnd
[
5
],
srb
->
cmnd
[
6
],
srb
->
cmnd
[
7
],
srb
->
cmnd
[
8
],
srb
->
cmnd
[
9
],
srb
->
cmnd
[
10
],
srb
->
cmnd
[
11
]);
}
}
void
usb_stor_print_Scsi_Cmnd
(
Scsi_Cmnd
*
cmd
)
void
usb_stor_print_Scsi_Cmnd
(
Scsi_Cmnd
*
cmd
)
{
{
int
i
=
0
,
bufferSize
=
cmd
->
request_bufflen
;
int
i
=
0
,
bufferSize
=
cmd
->
request_bufflen
;
u8
*
buffer
=
cmd
->
request_buffer
;
u8
*
buffer
=
cmd
->
request_buffer
;
struct
scatterlist
*
sg
=
(
struct
scatterlist
*
)
cmd
->
request_buffer
;
struct
scatterlist
*
sg
=
(
struct
scatterlist
*
)
cmd
->
request_buffer
;
US_DEBUGP
(
"Dumping information about %p.
\n
"
,
cmd
);
US_DEBUGP
(
"Dumping information about %p.
\n
"
,
cmd
);
US_DEBUGP
(
"cmd->cmnd[0] value is %d.
\n
"
,
cmd
->
cmnd
[
0
]
);
US_DEBUGP
(
"cmd->cmnd[0] value is %d.
\n
"
,
cmd
->
cmnd
[
0
]);
US_DEBUGP
(
"(MODE_SENSE is %d and MODE_SENSE_10 is %d)
\n
"
,
US_DEBUGP
(
"(MODE_SENSE is %d and MODE_SENSE_10 is %d)
\n
"
,
MODE_SENSE
,
MODE_SENSE_10
);
MODE_SENSE
,
MODE_SENSE_10
);
US_DEBUGP
(
"buffer is %p with length %d.
\n
"
,
buffer
,
bufferSize
);
US_DEBUGP
(
"buffer is %p with length %d.
\n
"
,
buffer
,
bufferSize
);
for
(
i
=
0
;
i
<
bufferSize
;
i
+=
16
)
for
(
i
=
0
;
i
<
bufferSize
;
i
+=
16
)
{
{
US_DEBUGP
(
"%02x %02x %02x %02x %02x %02x %02x %02x
\n
"
US_DEBUGP
(
"%02x %02x %02x %02x %02x %02x %02x %02x
\n
"
"%02x %02x %02x %02x %02x %02x %02x %02x
\n
"
,
"%02x %02x %02x %02x %02x %02x %02x %02x
\n
"
,
buffer
[
i
],
buffer
[
i
],
...
@@ -187,8 +184,7 @@ void usb_stor_print_Scsi_Cmnd( Scsi_Cmnd* cmd )
...
@@ -187,8 +184,7 @@ void usb_stor_print_Scsi_Cmnd( Scsi_Cmnd* cmd )
}
}
US_DEBUGP
(
"Buffer has %d scatterlists.
\n
"
,
cmd
->
use_sg
);
US_DEBUGP
(
"Buffer has %d scatterlists.
\n
"
,
cmd
->
use_sg
);
for
(
i
=
0
;
i
<
cmd
->
use_sg
;
i
++
)
for
(
i
=
0
;
i
<
cmd
->
use_sg
;
i
++
)
{
{
char
*
adr
=
sg_address
(
sg
[
i
]);
char
*
adr
=
sg_address
(
sg
[
i
]);
US_DEBUGP
(
"Length of scatterlist %d is %d.
\n
"
,
i
,
sg
[
i
].
length
);
US_DEBUGP
(
"Length of scatterlist %d is %d.
\n
"
,
i
,
sg
[
i
].
length
);
...
...
drivers/usb/usb-skeleton.c
View file @
fa4229ad
...
@@ -86,7 +86,7 @@ MODULE_DEVICE_TABLE (usb, skel_table);
...
@@ -86,7 +86,7 @@ MODULE_DEVICE_TABLE (usb, skel_table);
#define USB_SKEL_MINOR_BASE 0
#define USB_SKEL_MINOR_BASE 0
#else
#else
/* Get a minor range for your devices from the usb maintainer */
/* Get a minor range for your devices from the usb maintainer */
#define USB_SKEL_MINOR_BASE
200
#define USB_SKEL_MINOR_BASE
192
#endif
#endif
/* Structure to hold all of our device specific stuff */
/* Structure to hold all of our device specific stuff */
...
...
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