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
77060bee
Commit
77060bee
authored
Dec 08, 2002
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
2140dbb5
db8f65c8
Changes
19
Show whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
1247 additions
and
475 deletions
+1247
-475
drivers/usb/class/usb-midi.h
drivers/usb/class/usb-midi.h
+2
-2
drivers/usb/core/devio.c
drivers/usb/core/devio.c
+8
-4
drivers/usb/host/ehci-q.c
drivers/usb/host/ehci-q.c
+10
-5
drivers/usb/image/hpusbscsi.h
drivers/usb/image/hpusbscsi.h
+16
-16
drivers/usb/media/dsbr100.c
drivers/usb/media/dsbr100.c
+2
-1
drivers/usb/serial/Kconfig
drivers/usb/serial/Kconfig
+19
-0
drivers/usb/serial/Makefile
drivers/usb/serial/Makefile
+1
-0
drivers/usb/serial/io_tables.h
drivers/usb/serial/io_tables.h
+76
-76
drivers/usb/serial/keyspan.h
drivers/usb/serial/keyspan.h
+182
-182
drivers/usb/serial/kobil_sct.c
drivers/usb/serial/kobil_sct.c
+727
-0
drivers/usb/serial/kobil_sct.h
drivers/usb/serial/kobil_sct.h
+60
-0
drivers/usb/serial/safe_serial.c
drivers/usb/serial/safe_serial.c
+6
-6
drivers/usb/serial/visor.c
drivers/usb/serial/visor.c
+59
-4
drivers/usb/serial/visor.h
drivers/usb/serial/visor.h
+1
-0
drivers/usb/storage/transport.c
drivers/usb/storage/transport.c
+58
-105
drivers/usb/storage/transport.h
drivers/usb/storage/transport.h
+4
-1
drivers/usb/storage/usb.c
drivers/usb/storage/usb.c
+12
-64
drivers/usb/storage/usb.h
drivers/usb/storage/usb.h
+3
-8
sound/usb/usbmidi.c
sound/usb/usbmidi.c
+1
-1
No files found.
drivers/usb/class/usb-midi.h
View file @
77060bee
...
...
@@ -123,8 +123,8 @@ static struct usb_midi_device usb_midi_devices[] = {
/* for Hot-Plugging */
static
struct
usb_device_id
usb_midi_ids
[]
=
{
{
match_flags
:
(
USB_DEVICE_ID_MATCH_INT_CLASS
|
USB_DEVICE_ID_MATCH_INT_SUBCLASS
),
bInterfaceClass:
USB_CLASS_AUDIO
,
bInterfaceSubClass
:
USB_SUBCLASS_MIDISTREAMING
},
{
.
match_flags
=
(
USB_DEVICE_ID_MATCH_INT_CLASS
|
USB_DEVICE_ID_MATCH_INT_SUBCLASS
),
.
bInterfaceClass
=
USB_CLASS_AUDIO
,
.
bInterfaceSubClass
=
USB_SUBCLASS_MIDISTREAMING
},
{
USB_DEVICE
(
USB_VENDOR_ID_ROLAND
,
USBMIDI_ROLAND_UM1
)
},
{
USB_DEVICE
(
USB_VENDOR_ID_ROLAND
,
USBMIDI_ROLAND_UM2
)
},
{
USB_DEVICE
(
USB_VENDOR_ID_ROLAND
,
USBMIDI_ROLAND_UA100G
)
},
...
...
drivers/usb/core/devio.c
View file @
77060bee
...
...
@@ -484,14 +484,17 @@ static int usbdev_open(struct inode *inode, struct file *file)
* and the hub thread have the kernel lock
* (still acquire the kernel lock for safety)
*/
ret
=
-
ENOMEM
;
if
(
!
(
ps
=
kmalloc
(
sizeof
(
struct
dev_state
),
GFP_KERNEL
)))
goto
out_nolock
;
lock_kernel
();
ret
=
-
ENOENT
;
dev
=
inode
->
u
.
generic_ip
;
if
(
!
dev
)
goto
out
;
ret
=
-
ENOMEM
;
if
(
!
(
ps
=
kmalloc
(
sizeof
(
struct
dev_state
),
GFP_KERNEL
)))
if
(
!
dev
)
{
kfree
(
ps
);
goto
out
;
}
ret
=
0
;
ps
->
dev
=
dev
;
ps
->
file
=
file
;
...
...
@@ -509,6 +512,7 @@ static int usbdev_open(struct inode *inode, struct file *file)
file
->
private_data
=
ps
;
out:
unlock_kernel
();
out_nolock:
return
ret
;
}
...
...
drivers/usb/host/ehci-q.c
View file @
77060bee
...
...
@@ -978,14 +978,19 @@ scan_async (struct ehci_hcd *ehci)
do
{
/* clean any finished work for this qh */
if
(
!
list_empty
(
&
qh
->
qtd_list
))
{
// dbg_qh ("scan_async", ehci, qh);
qh
=
qh_get
(
qh
);
int
temp
;
/* concurrent unlink could happen here */
count
+=
qh_completions
(
ehci
,
qh
);
/* unlinks could happen here; completion
* reporting drops the lock.
*/
qh
=
qh_get
(
qh
);
temp
=
qh_completions
(
ehci
,
qh
);
qh_put
(
ehci
,
qh
);
if
(
temp
!=
0
)
{
count
+=
temp
;
goto
rescan
;
}
}
/* unlink idle entries, reducing HC PCI usage as
* well as HCD schedule-scanning costs.
...
...
drivers/usb/image/hpusbscsi.h
View file @
77060bee
...
...
@@ -65,22 +65,22 @@ static int hpusbscsi_scsi_abort (Scsi_Cmnd *srb);
static
void
issue_request_sense
(
struct
hpusbscsi
*
hpusbscsi
);
static
Scsi_Host_Template
hpusbscsi_scsi_host_template
=
{
name:
"hpusbscsi"
,
detect:
hpusbscsi_scsi_detect
,
//
release:
hpusbscsi_scsi_release,
queuecommand:
hpusbscsi_scsi_queuecommand
,
eh_abort_handler:
hpusbscsi_scsi_abort
,
eh_host_reset_handler:
hpusbscsi_scsi_host_reset
,
sg_tablesize:
SG_ALL
,
can_queue:
1
,
this_id:
-
1
,
cmd_per_lun:
1
,
present:
0
,
unchecked_isa_dma:
FALSE
,
use_clustering:
TRUE
,
emulated:
TRUE
.
name
=
"hpusbscsi"
,
.
detect
=
hpusbscsi_scsi_detect
,
//
.release =
hpusbscsi_scsi_release,
.
queuecommand
=
hpusbscsi_scsi_queuecommand
,
.
eh_abort_handler
=
hpusbscsi_scsi_abort
,
.
eh_host_reset_handler
=
hpusbscsi_scsi_host_reset
,
.
sg_tablesize
=
SG_ALL
,
.
can_queue
=
1
,
.
this_id
=
-
1
,
.
cmd_per_lun
=
1
,
.
present
=
0
,
.
unchecked_isa_dma
=
FALSE
,
.
use_clustering
=
TRUE
,
.
emulated
=
TRUE
};
/* defines for internal driver state */
...
...
drivers/usb/media/dsbr100.c
View file @
77060bee
...
...
@@ -265,7 +265,8 @@ static int usb_dsbr100_do_ioctl(struct inode *inode, struct file *file,
case
VIDIOCSFREQ
:
{
int
*
freq
=
arg
;
*
freq
=
radio
->
curfreq
;
radio
->
curfreq
=
*
freq
;
if
(
dsbr100_setfreq
(
radio
,
radio
->
curfreq
)
==-
1
)
warn
(
"set frequency failed"
);
return
0
;
...
...
drivers/usb/serial/Kconfig
View file @
77060bee
...
...
@@ -326,6 +326,25 @@ config USB_SERIAL_KLSI
The module will be called kl5kusb105.o. If you want to compile it as
a module, say M here and read <file:Documentation/modules.txt>.
config USB_SERIAL_KOBIL_SCT
tristate "USB KOBIL chipcard reader (EXPERIMENTAL)"
depends on USB_SERIAL && EXPERIMENTAL
---help---
Say Y here if you want to use one of the following KOBIL USB chipcard
readers:
- USB TWIN
- KAAN Standard Plus
- SecOVID Reader Plus
- B1 Professional
- KAAN Professional
Note that you need a current CT-API.
This code is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module will be called kobil_sct.o. If you want to compile it as
a module, say M here and read <file:Documentation/modules.txt>.
config USB_SERIAL_MCT_U232
tristate "USB MCT Single Port Serial Driver"
depends on USB_SERIAL
...
...
drivers/usb/serial/Makefile
View file @
77060bee
...
...
@@ -24,6 +24,7 @@ obj-$(CONFIG_USB_SERIAL_MCT_U232) += mct_u232.o
obj-$(CONFIG_USB_SERIAL_EDGEPORT)
+=
io_edgeport.o
obj-$(CONFIG_USB_SERIAL_EDGEPORT_TI)
+=
io_ti.o
obj-$(CONFIG_USB_SERIAL_PL2303)
+=
pl2303.o
obj-$(CONFIG_USB_SERIAL_KOBIL_SCT)
+=
kobil_sct.o
obj-$(CONFIG_USB_SERIAL_CYBERJACK)
+=
cyberjack.o
obj-$(CONFIG_USB_SERIAL_IR)
+=
ir-usb.o
obj-$(CONFIG_USB_SERIAL_KLSI)
+=
kl5kusb105.o
...
...
drivers/usb/serial/io_tables.h
View file @
77060bee
...
...
@@ -98,91 +98,91 @@ static struct usb_device_id id_table_combined [] = {
MODULE_DEVICE_TABLE
(
usb
,
id_table_combined
);
static
struct
usb_serial_device_type
edgeport_1port_device
=
{
owner:
THIS_MODULE
,
name:
"Edgeport 1 port adapter"
,
id_table:
edgeport_1port_id_table
,
num_interrupt_in:
1
,
num_bulk_in:
1
,
num_bulk_out:
1
,
num_ports:
1
,
open:
edge_open
,
close:
edge_close
,
throttle:
edge_throttle
,
unthrottle:
edge_unthrottle
,
attach:
edge_startup
,
shutdown:
edge_shutdown
,
ioctl:
edge_ioctl
,
set_termios:
edge_set_termios
,
write:
edge_write
,
write_room:
edge_write_room
,
chars_in_buffer:
edge_chars_in_buffer
,
break_ctl:
edge_break
,
.
owner
=
THIS_MODULE
,
.
name
=
"Edgeport 1 port adapter"
,
.
id_table
=
edgeport_1port_id_table
,
.
num_interrupt_in
=
1
,
.
num_bulk_in
=
1
,
.
num_bulk_out
=
1
,
.
num_ports
=
1
,
.
open
=
edge_open
,
.
close
=
edge_close
,
.
throttle
=
edge_throttle
,
.
unthrottle
=
edge_unthrottle
,
.
attach
=
edge_startup
,
.
shutdown
=
edge_shutdown
,
.
ioctl
=
edge_ioctl
,
.
set_termios
=
edge_set_termios
,
.
write
=
edge_write
,
.
write_room
=
edge_write_room
,
.
chars_in_buffer
=
edge_chars_in_buffer
,
.
break_ctl
=
edge_break
,
};
static
struct
usb_serial_device_type
edgeport_2port_device
=
{
owner:
THIS_MODULE
,
name:
"Edgeport 2 port adapter"
,
id_table:
edgeport_2port_id_table
,
num_interrupt_in:
1
,
num_bulk_in:
1
,
num_bulk_out:
1
,
num_ports:
2
,
open:
edge_open
,
close:
edge_close
,
throttle:
edge_throttle
,
unthrottle:
edge_unthrottle
,
attach:
edge_startup
,
shutdown:
edge_shutdown
,
ioctl:
edge_ioctl
,
set_termios:
edge_set_termios
,
write:
edge_write
,
write_room:
edge_write_room
,
chars_in_buffer:
edge_chars_in_buffer
,
break_ctl:
edge_break
,
.
owner
=
THIS_MODULE
,
.
name
=
"Edgeport 2 port adapter"
,
.
id_table
=
edgeport_2port_id_table
,
.
num_interrupt_in
=
1
,
.
num_bulk_in
=
1
,
.
num_bulk_out
=
1
,
.
num_ports
=
2
,
.
open
=
edge_open
,
.
close
=
edge_close
,
.
throttle
=
edge_throttle
,
.
unthrottle
=
edge_unthrottle
,
.
attach
=
edge_startup
,
.
shutdown
=
edge_shutdown
,
.
ioctl
=
edge_ioctl
,
.
set_termios
=
edge_set_termios
,
.
write
=
edge_write
,
.
write_room
=
edge_write_room
,
.
chars_in_buffer
=
edge_chars_in_buffer
,
.
break_ctl
=
edge_break
,
};
static
struct
usb_serial_device_type
edgeport_4port_device
=
{
owner:
THIS_MODULE
,
name:
"Edgeport 4 port adapter"
,
id_table:
edgeport_4port_id_table
,
num_interrupt_in:
1
,
num_bulk_in:
1
,
num_bulk_out:
1
,
num_ports:
4
,
open:
edge_open
,
close:
edge_close
,
throttle:
edge_throttle
,
unthrottle:
edge_unthrottle
,
attach:
edge_startup
,
shutdown:
edge_shutdown
,
ioctl:
edge_ioctl
,
set_termios:
edge_set_termios
,
write:
edge_write
,
write_room:
edge_write_room
,
chars_in_buffer:
edge_chars_in_buffer
,
break_ctl:
edge_break
,
.
owner
=
THIS_MODULE
,
.
name
=
"Edgeport 4 port adapter"
,
.
id_table
=
edgeport_4port_id_table
,
.
num_interrupt_in
=
1
,
.
num_bulk_in
=
1
,
.
num_bulk_out
=
1
,
.
num_ports
=
4
,
.
open
=
edge_open
,
.
close
=
edge_close
,
.
throttle
=
edge_throttle
,
.
unthrottle
=
edge_unthrottle
,
.
attach
=
edge_startup
,
.
shutdown
=
edge_shutdown
,
.
ioctl
=
edge_ioctl
,
.
set_termios
=
edge_set_termios
,
.
write
=
edge_write
,
.
write_room
=
edge_write_room
,
.
chars_in_buffer
=
edge_chars_in_buffer
,
.
break_ctl
=
edge_break
,
};
static
struct
usb_serial_device_type
edgeport_8port_device
=
{
owner:
THIS_MODULE
,
name:
"Edgeport 8 port adapter"
,
id_table:
edgeport_8port_id_table
,
num_interrupt_in:
1
,
num_bulk_in:
1
,
num_bulk_out:
1
,
num_ports:
8
,
open:
edge_open
,
close:
edge_close
,
throttle:
edge_throttle
,
unthrottle:
edge_unthrottle
,
attach:
edge_startup
,
shutdown:
edge_shutdown
,
ioctl:
edge_ioctl
,
set_termios:
edge_set_termios
,
write:
edge_write
,
write_room:
edge_write_room
,
chars_in_buffer:
edge_chars_in_buffer
,
break_ctl:
edge_break
,
.
owner
=
THIS_MODULE
,
.
name
=
"Edgeport 8 port adapter"
,
.
id_table
=
edgeport_8port_id_table
,
.
num_interrupt_in
=
1
,
.
num_bulk_in
=
1
,
.
num_bulk_out
=
1
,
.
num_ports
=
8
,
.
open
=
edge_open
,
.
close
=
edge_close
,
.
throttle
=
edge_throttle
,
.
unthrottle
=
edge_unthrottle
,
.
attach
=
edge_startup
,
.
shutdown
=
edge_shutdown
,
.
ioctl
=
edge_ioctl
,
.
set_termios
=
edge_set_termios
,
.
write
=
edge_write
,
.
write_room
=
edge_write_room
,
.
chars_in_buffer
=
edge_chars_in_buffer
,
.
break_ctl
=
edge_break
,
};
#endif
...
...
drivers/usb/serial/keyspan.h
View file @
77060bee
...
...
@@ -249,149 +249,149 @@ struct keyspan_device_details {
in Keyspan's documentation) */
static
const
struct
keyspan_device_details
usa18x_device_details
=
{
product_id:
keyspan_usa18x_product_id
,
msg_format:
msg_usa26
,
num_ports:
1
,
indat_endp_flip:
0
,
outdat_endp_flip:
1
,
indat_endpoints:
{
0x81
},
outdat_endpoints:
{
0x01
},
inack_endpoints:
{
0x85
},
outcont_endpoints:
{
0x05
},
instat_endpoint:
0x87
,
glocont_endpoint:
0x07
,
calculate_baud_rate:
keyspan_usa19w_calc_baud
,
baudclk:
KEYSPAN_USA18X_BAUDCLK
,
.
product_id
=
keyspan_usa18x_product_id
,
.
msg_format
=
msg_usa26
,
.
num_ports
=
1
,
.
indat_endp_flip
=
0
,
.
outdat_endp_flip
=
1
,
.
indat_endpoints
=
{
0x81
},
.
outdat_endpoints
=
{
0x01
},
.
inack_endpoints
=
{
0x85
},
.
outcont_endpoints
=
{
0x05
},
.
instat_endpoint
=
0x87
,
.
glocont_endpoint
=
0x07
,
.
calculate_baud_rate
=
keyspan_usa19w_calc_baud
,
.
baudclk
=
KEYSPAN_USA18X_BAUDCLK
,
};
static
const
struct
keyspan_device_details
usa19_device_details
=
{
product_id:
keyspan_usa19_product_id
,
msg_format:
msg_usa28
,
num_ports:
1
,
indat_endp_flip:
1
,
outdat_endp_flip:
1
,
indat_endpoints:
{
0x81
},
outdat_endpoints:
{
0x01
},
inack_endpoints:
{
0x83
},
outcont_endpoints:
{
0x03
},
instat_endpoint:
0x84
,
glocont_endpoint:
-
1
,
calculate_baud_rate:
keyspan_usa19_calc_baud
,
baudclk:
KEYSPAN_USA19_BAUDCLK
,
.
product_id
=
keyspan_usa19_product_id
,
.
msg_format
=
msg_usa28
,
.
num_ports
=
1
,
.
indat_endp_flip
=
1
,
.
outdat_endp_flip
=
1
,
.
indat_endpoints
=
{
0x81
},
.
outdat_endpoints
=
{
0x01
},
.
inack_endpoints
=
{
0x83
},
.
outcont_endpoints
=
{
0x03
},
.
instat_endpoint
=
0x84
,
.
glocont_endpoint
=
-
1
,
.
calculate_baud_rate
=
keyspan_usa19_calc_baud
,
.
baudclk
=
KEYSPAN_USA19_BAUDCLK
,
};
static
const
struct
keyspan_device_details
usa19qi_device_details
=
{
product_id:
keyspan_usa19qi_product_id
,
msg_format:
msg_usa28
,
num_ports:
1
,
indat_endp_flip:
1
,
outdat_endp_flip:
1
,
indat_endpoints:
{
0x81
},
outdat_endpoints:
{
0x01
},
inack_endpoints:
{
0x83
},
outcont_endpoints:
{
0x03
},
instat_endpoint:
0x84
,
glocont_endpoint:
-
1
,
calculate_baud_rate:
keyspan_usa28_calc_baud
,
baudclk:
KEYSPAN_USA19_BAUDCLK
,
.
product_id
=
keyspan_usa19qi_product_id
,
.
msg_format
=
msg_usa28
,
.
num_ports
=
1
,
.
indat_endp_flip
=
1
,
.
outdat_endp_flip
=
1
,
.
indat_endpoints
=
{
0x81
},
.
outdat_endpoints
=
{
0x01
},
.
inack_endpoints
=
{
0x83
},
.
outcont_endpoints
=
{
0x03
},
.
instat_endpoint
=
0x84
,
.
glocont_endpoint
=
-
1
,
.
calculate_baud_rate
=
keyspan_usa28_calc_baud
,
.
baudclk
=
KEYSPAN_USA19_BAUDCLK
,
};
static
const
struct
keyspan_device_details
usa19qw_device_details
=
{
product_id:
keyspan_usa19qw_product_id
,
msg_format:
msg_usa26
,
num_ports:
1
,
indat_endp_flip:
0
,
outdat_endp_flip:
1
,
indat_endpoints:
{
0x81
},
outdat_endpoints:
{
0x01
},
inack_endpoints:
{
0x85
},
outcont_endpoints:
{
0x05
},
instat_endpoint:
0x87
,
glocont_endpoint:
0x07
,
calculate_baud_rate:
keyspan_usa19w_calc_baud
,
baudclk:
KEYSPAN_USA19W_BAUDCLK
,
.
product_id
=
keyspan_usa19qw_product_id
,
.
msg_format
=
msg_usa26
,
.
num_ports
=
1
,
.
indat_endp_flip
=
0
,
.
outdat_endp_flip
=
1
,
.
indat_endpoints
=
{
0x81
},
.
outdat_endpoints
=
{
0x01
},
.
inack_endpoints
=
{
0x85
},
.
outcont_endpoints
=
{
0x05
},
.
instat_endpoint
=
0x87
,
.
glocont_endpoint
=
0x07
,
.
calculate_baud_rate
=
keyspan_usa19w_calc_baud
,
.
baudclk
=
KEYSPAN_USA19W_BAUDCLK
,
};
static
const
struct
keyspan_device_details
usa19w_device_details
=
{
product_id:
keyspan_usa19w_product_id
,
msg_format:
msg_usa26
,
num_ports:
1
,
indat_endp_flip:
0
,
outdat_endp_flip:
1
,
indat_endpoints:
{
0x81
},
outdat_endpoints:
{
0x01
},
inack_endpoints:
{
0x85
},
outcont_endpoints:
{
0x05
},
instat_endpoint:
0x87
,
glocont_endpoint:
0x07
,
calculate_baud_rate:
keyspan_usa19w_calc_baud
,
baudclk:
KEYSPAN_USA19W_BAUDCLK
,
.
product_id
=
keyspan_usa19w_product_id
,
.
msg_format
=
msg_usa26
,
.
num_ports
=
1
,
.
indat_endp_flip
=
0
,
.
outdat_endp_flip
=
1
,
.
indat_endpoints
=
{
0x81
},
.
outdat_endpoints
=
{
0x01
},
.
inack_endpoints
=
{
0x85
},
.
outcont_endpoints
=
{
0x05
},
.
instat_endpoint
=
0x87
,
.
glocont_endpoint
=
0x07
,
.
calculate_baud_rate
=
keyspan_usa19w_calc_baud
,
.
baudclk
=
KEYSPAN_USA19W_BAUDCLK
,
};
static
const
struct
keyspan_device_details
usa28_device_details
=
{
product_id:
keyspan_usa28_product_id
,
msg_format:
msg_usa28
,
num_ports:
2
,
indat_endp_flip:
1
,
outdat_endp_flip:
1
,
indat_endpoints:
{
0x81
,
0x83
},
outdat_endpoints:
{
0x01
,
0x03
},
inack_endpoints:
{
0x85
,
0x86
},
outcont_endpoints:
{
0x05
,
0x06
},
instat_endpoint:
0x87
,
glocont_endpoint:
0x07
,
calculate_baud_rate:
keyspan_usa28_calc_baud
,
baudclk:
KEYSPAN_USA28_BAUDCLK
,
.
product_id
=
keyspan_usa28_product_id
,
.
msg_format
=
msg_usa28
,
.
num_ports
=
2
,
.
indat_endp_flip
=
1
,
.
outdat_endp_flip
=
1
,
.
indat_endpoints
=
{
0x81
,
0x83
},
.
outdat_endpoints
=
{
0x01
,
0x03
},
.
inack_endpoints
=
{
0x85
,
0x86
},
.
outcont_endpoints
=
{
0x05
,
0x06
},
.
instat_endpoint
=
0x87
,
.
glocont_endpoint
=
0x07
,
.
calculate_baud_rate
=
keyspan_usa28_calc_baud
,
.
baudclk
=
KEYSPAN_USA28_BAUDCLK
,
};
static
const
struct
keyspan_device_details
usa28x_device_details
=
{
product_id:
keyspan_usa28x_product_id
,
msg_format:
msg_usa26
,
num_ports:
2
,
indat_endp_flip:
0
,
outdat_endp_flip:
1
,
indat_endpoints:
{
0x81
,
0x83
},
outdat_endpoints:
{
0x01
,
0x03
},
inack_endpoints:
{
0x85
,
0x86
},
outcont_endpoints:
{
0x05
,
0x06
},
instat_endpoint:
0x87
,
glocont_endpoint:
0x07
,
calculate_baud_rate:
keyspan_usa19w_calc_baud
,
baudclk:
KEYSPAN_USA28X_BAUDCLK
,
.
product_id
=
keyspan_usa28x_product_id
,
.
msg_format
=
msg_usa26
,
.
num_ports
=
2
,
.
indat_endp_flip
=
0
,
.
outdat_endp_flip
=
1
,
.
indat_endpoints
=
{
0x81
,
0x83
},
.
outdat_endpoints
=
{
0x01
,
0x03
},
.
inack_endpoints
=
{
0x85
,
0x86
},
.
outcont_endpoints
=
{
0x05
,
0x06
},
.
instat_endpoint
=
0x87
,
.
glocont_endpoint
=
0x07
,
.
calculate_baud_rate
=
keyspan_usa19w_calc_baud
,
.
baudclk
=
KEYSPAN_USA28X_BAUDCLK
,
};
static
const
struct
keyspan_device_details
usa28xa_device_details
=
{
product_id:
keyspan_usa28xa_product_id
,
msg_format:
msg_usa26
,
num_ports:
2
,
indat_endp_flip:
0
,
outdat_endp_flip:
1
,
indat_endpoints:
{
0x81
,
0x83
},
outdat_endpoints:
{
0x01
,
0x03
},
inack_endpoints:
{
0x85
,
0x86
},
outcont_endpoints:
{
0x05
,
0x06
},
instat_endpoint:
0x87
,
glocont_endpoint:
0x07
,
calculate_baud_rate:
keyspan_usa19w_calc_baud
,
baudclk:
KEYSPAN_USA28X_BAUDCLK
,
.
product_id
=
keyspan_usa28xa_product_id
,
.
msg_format
=
msg_usa26
,
.
num_ports
=
2
,
.
indat_endp_flip
=
0
,
.
outdat_endp_flip
=
1
,
.
indat_endpoints
=
{
0x81
,
0x83
},
.
outdat_endpoints
=
{
0x01
,
0x03
},
.
inack_endpoints
=
{
0x85
,
0x86
},
.
outcont_endpoints
=
{
0x05
,
0x06
},
.
instat_endpoint
=
0x87
,
.
glocont_endpoint
=
0x07
,
.
calculate_baud_rate
=
keyspan_usa19w_calc_baud
,
.
baudclk
=
KEYSPAN_USA28X_BAUDCLK
,
};
/* We don't need a separate entry for the usa28xb as it appears as a 28x anyway */
static
const
struct
keyspan_device_details
usa49w_device_details
=
{
product_id:
keyspan_usa49w_product_id
,
msg_format:
msg_usa49
,
num_ports:
4
,
indat_endp_flip:
0
,
outdat_endp_flip:
0
,
indat_endpoints:
{
0x81
,
0x82
,
0x83
,
0x84
},
outdat_endpoints:
{
0x01
,
0x02
,
0x03
,
0x04
},
inack_endpoints:
{
-
1
,
-
1
,
-
1
,
-
1
},
outcont_endpoints:
{
-
1
,
-
1
,
-
1
,
-
1
},
instat_endpoint:
0x87
,
glocont_endpoint:
0x07
,
calculate_baud_rate:
keyspan_usa19w_calc_baud
,
baudclk:
KEYSPAN_USA49W_BAUDCLK
,
.
product_id
=
keyspan_usa49w_product_id
,
.
msg_format
=
msg_usa49
,
.
num_ports
=
4
,
.
indat_endp_flip
=
0
,
.
outdat_endp_flip
=
0
,
.
indat_endpoints
=
{
0x81
,
0x82
,
0x83
,
0x84
},
.
outdat_endpoints
=
{
0x01
,
0x02
,
0x03
,
0x04
},
.
inack_endpoints
=
{
-
1
,
-
1
,
-
1
,
-
1
},
.
outcont_endpoints
=
{
-
1
,
-
1
,
-
1
,
-
1
},
.
instat_endpoint
=
0x87
,
.
glocont_endpoint
=
0x07
,
.
calculate_baud_rate
=
keyspan_usa19w_calc_baud
,
.
baudclk
=
KEYSPAN_USA49W_BAUDCLK
,
};
static
const
struct
keyspan_device_details
*
keyspan_devices
[]
=
{
...
...
@@ -479,80 +479,80 @@ static struct usb_device_id keyspan_4port_ids[] = {
/* Structs for the devices, pre and post renumeration. */
static
struct
usb_serial_device_type
keyspan_pre_device
=
{
owner:
THIS_MODULE
,
name:
"Keyspan - (without firmware)"
,
id_table:
keyspan_pre_ids
,
num_interrupt_in:
NUM_DONT_CARE
,
num_bulk_in:
NUM_DONT_CARE
,
num_bulk_out:
NUM_DONT_CARE
,
num_ports:
1
,
attach:
keyspan_fake_startup
,
.
owner
=
THIS_MODULE
,
.
name
=
"Keyspan - (without firmware)"
,
.
id_table
=
keyspan_pre_ids
,
.
num_interrupt_in
=
NUM_DONT_CARE
,
.
num_bulk_in
=
NUM_DONT_CARE
,
.
num_bulk_out
=
NUM_DONT_CARE
,
.
num_ports
=
1
,
.
attach
=
keyspan_fake_startup
,
};
static
struct
usb_serial_device_type
keyspan_1port_device
=
{
owner:
THIS_MODULE
,
name:
"Keyspan 1 port adapter"
,
id_table:
keyspan_1port_ids
,
num_interrupt_in:
NUM_DONT_CARE
,
num_bulk_in:
3
,
num_bulk_out:
4
,
num_ports:
1
,
open:
keyspan_open
,
close:
keyspan_close
,
write:
keyspan_write
,
write_room:
keyspan_write_room
,
chars_in_buffer:
keyspan_chars_in_buffer
,
throttle:
keyspan_rx_throttle
,
unthrottle:
keyspan_rx_unthrottle
,
ioctl:
keyspan_ioctl
,
set_termios:
keyspan_set_termios
,
break_ctl:
keyspan_break_ctl
,
attach:
keyspan_startup
,
shutdown:
keyspan_shutdown
,
.
owner
=
THIS_MODULE
,
.
name
=
"Keyspan 1 port adapter"
,
.
id_table
=
keyspan_1port_ids
,
.
num_interrupt_in
=
NUM_DONT_CARE
,
.
num_bulk_in
=
3
,
.
num_bulk_out
=
4
,
.
num_ports
=
1
,
.
open
=
keyspan_open
,
.
close
=
keyspan_close
,
.
write
=
keyspan_write
,
.
write_room
=
keyspan_write_room
,
.
chars_in_buffer
=
keyspan_chars_in_buffer
,
.
throttle
=
keyspan_rx_throttle
,
.
unthrottle
=
keyspan_rx_unthrottle
,
.
ioctl
=
keyspan_ioctl
,
.
set_termios
=
keyspan_set_termios
,
.
break_ctl
=
keyspan_break_ctl
,
.
attach
=
keyspan_startup
,
.
shutdown
=
keyspan_shutdown
,
};
static
struct
usb_serial_device_type
keyspan_2port_device
=
{
owner:
THIS_MODULE
,
name:
"Keyspan 2 port adapter"
,
id_table:
keyspan_2port_ids
,
num_interrupt_in:
NUM_DONT_CARE
,
num_bulk_in:
NUM_DONT_CARE
,
num_bulk_out:
NUM_DONT_CARE
,
num_ports:
2
,
open:
keyspan_open
,
close:
keyspan_close
,
write:
keyspan_write
,
write_room:
keyspan_write_room
,
chars_in_buffer:
keyspan_chars_in_buffer
,
throttle:
keyspan_rx_throttle
,
unthrottle:
keyspan_rx_unthrottle
,
ioctl:
keyspan_ioctl
,
set_termios:
keyspan_set_termios
,
break_ctl:
keyspan_break_ctl
,
attach:
keyspan_startup
,
shutdown:
keyspan_shutdown
,
.
owner
=
THIS_MODULE
,
.
name
=
"Keyspan 2 port adapter"
,
.
id_table
=
keyspan_2port_ids
,
.
num_interrupt_in
=
NUM_DONT_CARE
,
.
num_bulk_in
=
NUM_DONT_CARE
,
.
num_bulk_out
=
NUM_DONT_CARE
,
.
num_ports
=
2
,
.
open
=
keyspan_open
,
.
close
=
keyspan_close
,
.
write
=
keyspan_write
,
.
write_room
=
keyspan_write_room
,
.
chars_in_buffer
=
keyspan_chars_in_buffer
,
.
throttle
=
keyspan_rx_throttle
,
.
unthrottle
=
keyspan_rx_unthrottle
,
.
ioctl
=
keyspan_ioctl
,
.
set_termios
=
keyspan_set_termios
,
.
break_ctl
=
keyspan_break_ctl
,
.
attach
=
keyspan_startup
,
.
shutdown
=
keyspan_shutdown
,
};
static
struct
usb_serial_device_type
keyspan_4port_device
=
{
owner:
THIS_MODULE
,
name:
"Keyspan 4 port adapter"
,
id_table:
keyspan_4port_ids
,
num_interrupt_in:
NUM_DONT_CARE
,
num_bulk_in:
5
,
num_bulk_out:
5
,
num_ports:
4
,
open:
keyspan_open
,
close:
keyspan_close
,
write:
keyspan_write
,
write_room:
keyspan_write_room
,
chars_in_buffer:
keyspan_chars_in_buffer
,
throttle:
keyspan_rx_throttle
,
unthrottle:
keyspan_rx_unthrottle
,
ioctl:
keyspan_ioctl
,
set_termios:
keyspan_set_termios
,
break_ctl:
keyspan_break_ctl
,
attach:
keyspan_startup
,
shutdown:
keyspan_shutdown
,
.
owner
=
THIS_MODULE
,
.
name
=
"Keyspan 4 port adapter"
,
.
id_table
=
keyspan_4port_ids
,
.
num_interrupt_in
=
NUM_DONT_CARE
,
.
num_bulk_in
=
5
,
.
num_bulk_out
=
5
,
.
num_ports
=
4
,
.
open
=
keyspan_open
,
.
close
=
keyspan_close
,
.
write
=
keyspan_write
,
.
write_room
=
keyspan_write_room
,
.
chars_in_buffer
=
keyspan_chars_in_buffer
,
.
throttle
=
keyspan_rx_throttle
,
.
unthrottle
=
keyspan_rx_unthrottle
,
.
ioctl
=
keyspan_ioctl
,
.
set_termios
=
keyspan_set_termios
,
.
break_ctl
=
keyspan_break_ctl
,
.
attach
=
keyspan_startup
,
.
shutdown
=
keyspan_shutdown
,
};
#endif
drivers/usb/serial/kobil_sct.c
0 → 100644
View file @
77060bee
/*
* KOBIL USB Smart Card Terminal Driver
*
* Copyright (C) 2002 KOBIL Systems GmbH
* Author: Thomas Wahrenbruch
*
* Contact: linuxusb@kobil.de
*
* This program is largely derived from work by the linux-usb group
* and associated source files. Please see the usb/serial files for
* individual credits and copyrights.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Thanks to Greg Kroah-Hartman (greg@kroah.com) for his help and
* patience.
*
* Supported readers: USB TWIN, KAAN Standard Plus and SecOVID Reader Plus
* (Adapter K), B1 Professional and KAAN Professional (Adapter B)
*
* TODO: High baudrates
*
* (12/09/2002) tw
* Adapted to 2.5.
*
* (11/08/2002) tw
* Initial version.
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
#include <linux/ioctl.h>
#include "kobil_sct.h"
//#include "../core/usb-debug.c"
#ifdef CONFIG_USB_SERIAL_DEBUG
static
int
debug
=
1
;
#else
static
int
debug
;
#endif
#include "usb-serial.h"
/* Version Information */
#define DRIVER_VERSION "12/09/2002"
#define DRIVER_AUTHOR "KOBIL Systems GmbH - http://www.kobil.com"
#define DRIVER_DESC "KOBIL USB Smart Card Terminal Driver (experimental)"
#define KOBIL_VENDOR_ID 0x0D46
#define KOBIL_ADAPTER_B_PRODUCT_ID 0x2011
#define KOBIL_ADAPTER_K_PRODUCT_ID 0x2012
#define KOBIL_USBTWIN_PRODUCT_ID 0x0078
#define KOBIL_TIMEOUT 500
#define KOBIL_BUF_LENGTH 300
/* Function prototypes */
static
int
kobil_startup
(
struct
usb_serial
*
serial
);
static
void
kobil_shutdown
(
struct
usb_serial
*
serial
);
static
int
kobil_open
(
struct
usb_serial_port
*
port
,
struct
file
*
filp
);
static
void
kobil_close
(
struct
usb_serial_port
*
port
,
struct
file
*
filp
);
static
int
kobil_write
(
struct
usb_serial_port
*
port
,
int
from_user
,
const
unsigned
char
*
buf
,
int
count
);
static
int
kobil_write_room
(
struct
usb_serial_port
*
port
);
static
int
kobil_ioctl
(
struct
usb_serial_port
*
port
,
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
);
static
void
kobil_read_int_callback
(
struct
urb
*
urb
,
struct
pt_regs
*
regs
);
static
void
kobil_write_callback
(
struct
urb
*
purb
,
struct
pt_regs
*
regs
);
static
struct
usb_device_id
id_table
[]
=
{
{
USB_DEVICE
(
KOBIL_VENDOR_ID
,
KOBIL_ADAPTER_B_PRODUCT_ID
)
},
{
USB_DEVICE
(
KOBIL_VENDOR_ID
,
KOBIL_ADAPTER_K_PRODUCT_ID
)
},
{
USB_DEVICE
(
KOBIL_VENDOR_ID
,
KOBIL_USBTWIN_PRODUCT_ID
)
},
{
}
/* Terminating entry */
};
MODULE_DEVICE_TABLE
(
usb
,
id_table
);
struct
usb_serial_device_type
kobil_device
=
{
.
owner
=
THIS_MODULE
,
.
name
=
"KOBIL USB smart card terminal"
,
.
id_table
=
id_table
,
.
num_interrupt_in
=
NUM_DONT_CARE
,
.
num_bulk_in
=
0
,
.
num_bulk_out
=
0
,
.
num_ports
=
1
,
.
attach
=
kobil_startup
,
.
shutdown
=
kobil_shutdown
,
.
ioctl
=
kobil_ioctl
,
.
open
=
kobil_open
,
.
close
=
kobil_close
,
.
write
=
kobil_write
,
.
write_room
=
kobil_write_room
,
.
read_int_callback
=
kobil_read_int_callback
,
};
struct
kobil_private
{
int
write_int_endpoint_address
;
int
read_int_endpoint_address
;
unsigned
char
buf
[
KOBIL_BUF_LENGTH
];
// buffer for the APDU to send
int
filled
;
// index of the last char in buf
int
cur_pos
;
// index of the next char to send in buf
__u16
device_type
;
int
line_state
;
struct
termios
internal_termios
;
};
static
int
kobil_startup
(
struct
usb_serial
*
serial
)
{
int
i
;
struct
kobil_private
*
priv
;
struct
usb_device
*
pdev
;
struct
usb_host_config
*
actconfig
;
struct
usb_interface
*
interface
;
struct
usb_host_interface
*
altsetting
;
struct
usb_host_endpoint
*
endpoint
;
serial
->
port
->
private
=
kmalloc
(
sizeof
(
struct
kobil_private
),
GFP_KERNEL
);
if
(
!
serial
->
port
->
private
){
return
-
1
;
}
priv
=
(
struct
kobil_private
*
)
serial
->
port
->
private
;
priv
->
filled
=
0
;
priv
->
cur_pos
=
0
;
priv
->
device_type
=
serial
->
product
;
priv
->
line_state
=
0
;
switch
(
priv
->
device_type
){
case
KOBIL_ADAPTER_B_PRODUCT_ID
:
printk
(
KERN_DEBUG
"KOBIL B1 PRO / KAAN PRO detected
\n
"
);
break
;
case
KOBIL_ADAPTER_K_PRODUCT_ID
:
printk
(
KERN_DEBUG
"KOBIL KAAN Standard Plus / SecOVID Reader Plus detected
\n
"
);
break
;
case
KOBIL_USBTWIN_PRODUCT_ID
:
printk
(
KERN_DEBUG
"KOBIL USBTWIN detected
\n
"
);
break
;
}
// search for the neccessary endpoints
pdev
=
serial
->
dev
;
actconfig
=
pdev
->
actconfig
;
interface
=
actconfig
->
interface
;
altsetting
=
interface
->
altsetting
;
endpoint
=
altsetting
->
endpoint
;
for
(
i
=
0
;
i
<
altsetting
->
desc
.
bNumEndpoints
;
i
++
)
{
endpoint
=
&
altsetting
->
endpoint
[
i
];
if
(((
endpoint
->
desc
.
bEndpointAddress
&
USB_ENDPOINT_DIR_MASK
)
==
USB_DIR_OUT
)
&&
((
endpoint
->
desc
.
bmAttributes
&
USB_ENDPOINT_XFERTYPE_MASK
)
==
USB_ENDPOINT_XFER_INT
))
{
dbg
(
"%s Found interrupt out endpoint. Address: %d"
,
__FUNCTION__
,
endpoint
->
desc
.
bEndpointAddress
);
priv
->
write_int_endpoint_address
=
endpoint
->
desc
.
bEndpointAddress
;
}
if
(((
endpoint
->
desc
.
bEndpointAddress
&
USB_ENDPOINT_DIR_MASK
)
==
USB_DIR_IN
)
&&
((
endpoint
->
desc
.
bmAttributes
&
USB_ENDPOINT_XFERTYPE_MASK
)
==
USB_ENDPOINT_XFER_INT
))
{
dbg
(
"%s Found interrupt in endpoint. Address: %d"
,
__FUNCTION__
,
endpoint
->
desc
.
bEndpointAddress
);
priv
->
read_int_endpoint_address
=
endpoint
->
desc
.
bEndpointAddress
;
}
}
return
0
;
}
static
void
kobil_shutdown
(
struct
usb_serial
*
serial
)
{
int
i
;
dbg
(
"%s - port %d"
,
__FUNCTION__
,
serial
->
port
->
number
);
for
(
i
=
0
;
i
<
serial
->
num_ports
;
++
i
)
{
while
(
serial
->
port
[
i
].
open_count
>
0
)
{
kobil_close
(
&
serial
->
port
[
i
],
NULL
);
}
if
(
serial
->
port
[
i
].
private
)
{
kfree
(
serial
->
port
[
i
].
private
);
}
}
}
static
int
kobil_open
(
struct
usb_serial_port
*
port
,
struct
file
*
filp
)
{
int
i
,
result
=
0
;
struct
kobil_private
*
priv
;
unsigned
char
*
transfer_buffer
;
int
transfer_buffer_length
=
8
;
int
write_urb_transfer_buffer_length
=
8
;
dbg
(
"%s - port %d"
,
__FUNCTION__
,
port
->
number
);
priv
=
(
struct
kobil_private
*
)
port
->
private
;
priv
->
line_state
=
0
;
if
(
port_paranoia_check
(
port
,
__FUNCTION__
))
return
-
ENODEV
;
// someone sets the dev to 0 if the close method has been called
port
->
interrupt_in_urb
->
dev
=
port
->
serial
->
dev
;
/* force low_latency on so that our tty_push actually forces
* the data through, otherwise it is scheduled, and with high
* data rates (like with OHCI) data can get lost.
*/
port
->
tty
->
low_latency
=
1
;
// without this, every push_tty_char is echoed :-(
port
->
tty
->
termios
->
c_lflag
=
0
;
port
->
tty
->
termios
->
c_lflag
&=
~
(
ISIG
|
ICANON
|
ECHO
|
IEXTEN
|
XCASE
);
port
->
tty
->
termios
->
c_iflag
=
IGNBRK
|
IGNPAR
|
IXOFF
;
port
->
tty
->
termios
->
c_oflag
&=
~
ONLCR
;
// do NOT translate CR to CR-NL (0x0A -> 0x0A 0x0D)
// set up internal termios structure
priv
->
internal_termios
.
c_iflag
=
port
->
tty
->
termios
->
c_iflag
;
priv
->
internal_termios
.
c_oflag
=
port
->
tty
->
termios
->
c_oflag
;
priv
->
internal_termios
.
c_cflag
=
port
->
tty
->
termios
->
c_cflag
;
priv
->
internal_termios
.
c_lflag
=
port
->
tty
->
termios
->
c_lflag
;
for
(
i
=
0
;
i
<
NCCS
;
i
++
)
{
priv
->
internal_termios
.
c_cc
[
i
]
=
port
->
tty
->
termios
->
c_cc
[
i
];
}
// allocate memory for transfer buffer
transfer_buffer
=
(
unsigned
char
*
)
kmalloc
(
transfer_buffer_length
,
GFP_KERNEL
);
if
(
!
transfer_buffer
)
{
return
-
1
;
}
else
{
memset
(
transfer_buffer
,
0
,
transfer_buffer_length
);
}
// allocate write_urb
if
(
!
port
->
write_urb
)
{
dbg
(
"%s - port %d Allocating port->write_urb"
,
__FUNCTION__
,
port
->
number
);
port
->
write_urb
=
usb_alloc_urb
(
0
,
GFP_KERNEL
);
if
(
!
port
->
write_urb
)
{
dbg
(
"%s - port %d usb_alloc_urb failed"
,
__FUNCTION__
,
port
->
number
);
return
-
1
;
}
}
// allocate memory for write_urb transfer buffer
port
->
write_urb
->
transfer_buffer
=
(
unsigned
char
*
)
kmalloc
(
write_urb_transfer_buffer_length
,
GFP_KERNEL
);
if
(
!
port
->
write_urb
->
transfer_buffer
)
{
return
-
1
;
}
// get hardware version
result
=
usb_control_msg
(
port
->
serial
->
dev
,
usb_rcvctrlpipe
(
port
->
serial
->
dev
,
0
),
SUSBCRequest_GetMisc
,
USB_TYPE_VENDOR
|
USB_RECIP_ENDPOINT
|
USB_DIR_IN
,
SUSBCR_MSC_GetHWVersion
,
0
,
transfer_buffer
,
transfer_buffer_length
,
KOBIL_TIMEOUT
);
dbg
(
"%s - port %d Send get_HW_version URB returns: %i"
,
__FUNCTION__
,
port
->
number
,
result
);
dbg
(
"Harware version: %i.%i.%i"
,
transfer_buffer
[
0
],
transfer_buffer
[
1
],
transfer_buffer
[
2
]
);
// get firmware version
result
=
usb_control_msg
(
port
->
serial
->
dev
,
usb_rcvctrlpipe
(
port
->
serial
->
dev
,
0
),
SUSBCRequest_GetMisc
,
USB_TYPE_VENDOR
|
USB_RECIP_ENDPOINT
|
USB_DIR_IN
,
SUSBCR_MSC_GetFWVersion
,
0
,
transfer_buffer
,
transfer_buffer_length
,
KOBIL_TIMEOUT
);
dbg
(
"%s - port %d Send get_FW_version URB returns: %i"
,
__FUNCTION__
,
port
->
number
,
result
);
dbg
(
"Firmware version: %i.%i.%i"
,
transfer_buffer
[
0
],
transfer_buffer
[
1
],
transfer_buffer
[
2
]
);
if
(
priv
->
device_type
==
KOBIL_ADAPTER_B_PRODUCT_ID
||
priv
->
device_type
==
KOBIL_ADAPTER_K_PRODUCT_ID
)
{
// Setting Baudrate, Parity and Stopbits
result
=
usb_control_msg
(
port
->
serial
->
dev
,
usb_rcvctrlpipe
(
port
->
serial
->
dev
,
0
),
SUSBCRequest_SetBaudRateParityAndStopBits
,
USB_TYPE_VENDOR
|
USB_RECIP_ENDPOINT
|
USB_DIR_OUT
,
SUSBCR_SBR_9600
|
SUSBCR_SPASB_EvenParity
|
SUSBCR_SPASB_1StopBit
,
0
,
transfer_buffer
,
0
,
KOBIL_TIMEOUT
);
dbg
(
"%s - port %d Send set_baudrate URB returns: %i"
,
__FUNCTION__
,
port
->
number
,
result
);
// reset all queues
result
=
usb_control_msg
(
port
->
serial
->
dev
,
usb_rcvctrlpipe
(
port
->
serial
->
dev
,
0
),
SUSBCRequest_Misc
,
USB_TYPE_VENDOR
|
USB_RECIP_ENDPOINT
|
USB_DIR_OUT
,
SUSBCR_MSC_ResetAllQueues
,
0
,
transfer_buffer
,
0
,
KOBIL_TIMEOUT
);
dbg
(
"%s - port %d Send reset_all_queues URB returns: %i"
,
__FUNCTION__
,
port
->
number
,
result
);
}
kfree
(
transfer_buffer
);
return
0
;
}
static
void
kobil_close
(
struct
usb_serial_port
*
port
,
struct
file
*
filp
)
{
dbg
(
"%s - port %d"
,
__FUNCTION__
,
port
->
number
);
if
(
port
->
write_urb
){
usb_unlink_urb
(
port
->
write_urb
);
usb_free_urb
(
port
->
write_urb
);
port
->
write_urb
=
0
;
}
if
(
port
->
interrupt_in_urb
){
usb_unlink_urb
(
port
->
interrupt_in_urb
);
}
}
static
void
kobil_read_int_callback
(
struct
urb
*
purb
,
struct
pt_regs
*
regs
)
{
int
i
;
int
result
;
struct
usb_serial_port
*
port
=
(
struct
usb_serial_port
*
)
purb
->
context
;
struct
tty_struct
*
tty
;
unsigned
char
*
data
=
purb
->
transfer_buffer
;
char
*
dbg_data
;
dbg
(
"%s - port %d"
,
__FUNCTION__
,
port
->
number
);
if
(
purb
->
status
)
{
dbg
(
"%s - port %d Read int status not zero: %d"
,
__FUNCTION__
,
port
->
number
,
purb
->
status
);
return
;
}
tty
=
port
->
tty
;
if
(
purb
->
actual_length
)
{
// BEGIN DEBUG
dbg_data
=
(
unsigned
char
*
)
kmalloc
((
3
*
purb
->
actual_length
+
10
)
*
sizeof
(
char
),
GFP_KERNEL
);
if
(
!
dbg_data
)
{
return
;
}
memset
(
dbg_data
,
0
,
(
3
*
purb
->
actual_length
+
10
));
for
(
i
=
0
;
i
<
purb
->
actual_length
;
i
++
)
{
sprintf
(
dbg_data
+
3
*
i
,
"%02X "
,
data
[
i
]);
}
dbg
(
" <-- %s"
,
dbg_data
);
kfree
(
dbg_data
);
// END DEBUG
for
(
i
=
0
;
i
<
purb
->
actual_length
;
++
i
)
{
// if we insert more than TTY_FLIPBUF_SIZE characters, we drop them.
if
(
tty
->
flip
.
count
>=
TTY_FLIPBUF_SIZE
)
{
tty_flip_buffer_push
(
tty
);
}
// this doesn't actually push the data through unless tty->low_latency is set
tty_insert_flip_char
(
tty
,
data
[
i
],
0
);
}
tty_flip_buffer_push
(
tty
);
}
// someone sets the dev to 0 if the close method has been called
port
->
interrupt_in_urb
->
dev
=
port
->
serial
->
dev
;
// usb_dump_urb(port->interrupt_in_urb);
result
=
usb_submit_urb
(
port
->
interrupt_in_urb
,
GFP_ATOMIC
);
dbg
(
"%s - port %d Send read URB returns: %i"
,
__FUNCTION__
,
port
->
number
,
result
);
}
static
void
kobil_write_callback
(
struct
urb
*
purb
,
struct
pt_regs
*
regs
)
{
}
static
int
kobil_write
(
struct
usb_serial_port
*
port
,
int
from_user
,
const
unsigned
char
*
buf
,
int
count
)
{
int
length
=
0
;
int
result
=
0
;
int
todo
=
0
;
struct
kobil_private
*
priv
;
int
i
;
char
*
data
;
if
(
count
==
0
)
{
dbg
(
"%s - port %d write request of 0 bytes"
,
__FUNCTION__
,
port
->
number
);
return
0
;
}
priv
=
(
struct
kobil_private
*
)
port
->
private
;
if
(
count
>
(
KOBIL_BUF_LENGTH
-
priv
->
filled
))
{
dbg
(
"%s - port %d Error: write request bigger than buffer size"
,
__FUNCTION__
,
port
->
number
);
return
-
ENOMEM
;
}
// BEGIN DEBUG
data
=
(
unsigned
char
*
)
kmalloc
((
3
*
count
+
10
)
*
sizeof
(
char
),
GFP_KERNEL
);
if
(
!
data
)
{
return
(
-
1
);
}
memset
(
data
,
0
,
(
3
*
count
+
10
));
for
(
i
=
0
;
i
<
count
;
i
++
)
{
sprintf
(
data
+
3
*
i
,
"%02X "
,
buf
[
i
]);
}
dbg
(
" %d --> %s"
,
port
->
number
,
data
);
kfree
(
data
);
// END DEBUG
// Copy data to buffer
if
(
from_user
)
{
if
(
copy_from_user
(
priv
->
buf
+
priv
->
filled
,
buf
,
count
))
{
return
-
EFAULT
;
}
}
else
{
memcpy
(
priv
->
buf
+
priv
->
filled
,
buf
,
count
);
}
priv
->
filled
=
priv
->
filled
+
count
;
// only send complete block. TWIN and adapter K use the same protocol.
if
(
((
priv
->
device_type
!=
KOBIL_ADAPTER_B_PRODUCT_ID
)
&&
(
priv
->
filled
>
2
)
&&
(
priv
->
filled
>=
(
priv
->
buf
[
1
]
+
3
)))
||
((
priv
->
device_type
==
KOBIL_ADAPTER_B_PRODUCT_ID
)
&&
(
priv
->
filled
>
3
)
&&
(
priv
->
filled
>=
(
priv
->
buf
[
2
]
+
4
)))
)
{
todo
=
priv
->
filled
-
priv
->
cur_pos
;
while
(
todo
>
0
)
{
// max 8 byte in one urb (endpoint size)
length
=
(
todo
<
8
)
?
todo
:
8
;
// copy data to transfer buffer
memcpy
(
port
->
write_urb
->
transfer_buffer
,
priv
->
buf
+
priv
->
cur_pos
,
length
);
usb_fill_bulk_urb
(
port
->
write_urb
,
port
->
serial
->
dev
,
usb_sndbulkpipe
(
port
->
serial
->
dev
,
priv
->
write_int_endpoint_address
),
port
->
write_urb
->
transfer_buffer
,
length
,
kobil_write_callback
,
port
);
priv
->
cur_pos
=
priv
->
cur_pos
+
length
;
result
=
usb_submit_urb
(
port
->
write_urb
,
GFP_ATOMIC
);
dbg
(
"%s - port %d Send write URB returns: %i"
,
__FUNCTION__
,
port
->
number
,
result
);
todo
=
priv
->
filled
-
priv
->
cur_pos
;
if
(
todo
>
0
)
{
//mdelay(16);
set_current_state
(
TASK_UNINTERRUPTIBLE
);
schedule_timeout
(
24
*
HZ
/
1000
);
}
}
// end while
priv
->
filled
=
0
;
priv
->
cur_pos
=
0
;
// someone sets the dev to 0 if the close method has been called
port
->
interrupt_in_urb
->
dev
=
port
->
serial
->
dev
;
// start reading
//usb_dump_urb(port->interrupt_in_urb);
result
=
usb_submit_urb
(
port
->
interrupt_in_urb
,
GFP_ATOMIC
);
dbg
(
"%s - port %d Send read URB returns: %i"
,
__FUNCTION__
,
port
->
number
,
result
);
}
return
count
;
}
static
int
kobil_write_room
(
struct
usb_serial_port
*
port
)
{
//dbg(__FUNCTION__ " - port %d", port->number);
return
8
;
}
static
int
kobil_ioctl
(
struct
usb_serial_port
*
port
,
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
struct
kobil_private
*
priv
;
int
mask
;
int
result
;
unsigned
short
urb_val
=
0
;
unsigned
char
*
transfer_buffer
;
int
transfer_buffer_length
=
8
;
char
*
settings
;
priv
=
(
struct
kobil_private
*
)
port
->
private
;
if
(
priv
->
device_type
==
KOBIL_USBTWIN_PRODUCT_ID
)
{
// This device doesn't support ioctl calls
return
0
;
}
switch
(
cmd
)
{
case
TCGETS
:
// 0x5401
result
=
verify_area
(
VERIFY_WRITE
,
(
void
*
)
arg
,
sizeof
(
struct
termios
));
if
(
result
)
{
dbg
(
"%s - port %d Error in verify_area"
,
__FUNCTION__
,
port
->
number
);
return
(
result
);
}
kernel_termios_to_user_termios
((
struct
termios
*
)
arg
,
&
priv
->
internal_termios
);
return
0
;
case
TCSETS
:
// 0x5402
if
(
!
&
port
->
tty
->
termios
)
{
dbg
(
"%s - port %d Error: port->tty->termios is NULL"
,
__FUNCTION__
,
port
->
number
);
return
-
ENOTTY
;
}
result
=
verify_area
(
VERIFY_READ
,
(
void
*
)
arg
,
sizeof
(
struct
termios
));
if
(
result
)
{
dbg
(
"%s - port %d Error in verify_area"
,
__FUNCTION__
,
port
->
number
);
return
result
;
}
user_termios_to_kernel_termios
(
&
priv
->
internal_termios
,
(
struct
termios
*
)
arg
);
settings
=
(
unsigned
char
*
)
kmalloc
(
50
,
GFP_KERNEL
);
if
(
!
settings
)
{
return
-
ENOBUFS
;
}
memset
(
settings
,
0
,
50
);
switch
(
priv
->
internal_termios
.
c_cflag
&
CBAUD
)
{
case
B1200
:
urb_val
=
SUSBCR_SBR_1200
;
strcat
(
settings
,
"1200 "
);
break
;
case
B9600
:
default:
urb_val
=
SUSBCR_SBR_9600
;
strcat
(
settings
,
"9600 "
);
break
;
}
urb_val
|=
(
priv
->
internal_termios
.
c_cflag
&
CSTOPB
)
?
SUSBCR_SPASB_2StopBits
:
SUSBCR_SPASB_1StopBit
;
strcat
(
settings
,
(
priv
->
internal_termios
.
c_cflag
&
CSTOPB
)
?
"2 StopBits "
:
"1 StopBit "
);
if
(
priv
->
internal_termios
.
c_cflag
&
PARENB
)
{
if
(
priv
->
internal_termios
.
c_cflag
&
PARODD
)
{
urb_val
|=
SUSBCR_SPASB_OddParity
;
strcat
(
settings
,
"Odd Parity"
);
}
else
{
urb_val
|=
SUSBCR_SPASB_EvenParity
;
strcat
(
settings
,
"Even Parity"
);
}
}
else
{
urb_val
|=
SUSBCR_SPASB_NoParity
;
strcat
(
settings
,
"No Parity"
);
}
dbg
(
"%s - port %d setting port to: %s"
,
__FUNCTION__
,
port
->
number
,
settings
);
result
=
usb_control_msg
(
port
->
serial
->
dev
,
usb_rcvctrlpipe
(
port
->
serial
->
dev
,
0
),
SUSBCRequest_SetBaudRateParityAndStopBits
,
USB_TYPE_VENDOR
|
USB_RECIP_ENDPOINT
|
USB_DIR_OUT
,
urb_val
,
0
,
settings
,
0
,
KOBIL_TIMEOUT
);
dbg
(
"%s - port %d Send set_baudrate URB returns: %i"
,
__FUNCTION__
,
port
->
number
,
result
);
kfree
(
settings
);
return
0
;
case
TCFLSH
:
// 0x540B
transfer_buffer
=
(
unsigned
char
*
)
kmalloc
(
transfer_buffer_length
,
GFP_KERNEL
);
if
(
!
transfer_buffer
)
{
return
-
ENOBUFS
;
}
result
=
usb_control_msg
(
port
->
serial
->
dev
,
usb_rcvctrlpipe
(
port
->
serial
->
dev
,
0
),
SUSBCRequest_Misc
,
USB_TYPE_VENDOR
|
USB_RECIP_ENDPOINT
|
USB_DIR_OUT
,
SUSBCR_MSC_ResetAllQueues
,
0
,
NULL
,
//transfer_buffer,
0
,
KOBIL_TIMEOUT
);
dbg
(
"%s - port %d Send reset_all_queues (FLUSH) URB returns: %i"
,
__FUNCTION__
,
port
->
number
,
result
);
kfree
(
transfer_buffer
);
return
((
result
<
0
)
?
-
EFAULT
:
0
);
case
TIOCMGET
:
// 0x5415
// allocate memory for transfer buffer
transfer_buffer
=
(
unsigned
char
*
)
kmalloc
(
transfer_buffer_length
,
GFP_KERNEL
);
if
(
!
transfer_buffer
)
{
return
-
ENOBUFS
;
}
else
{
memset
(
transfer_buffer
,
0
,
transfer_buffer_length
);
}
result
=
usb_control_msg
(
port
->
serial
->
dev
,
usb_rcvctrlpipe
(
port
->
serial
->
dev
,
0
),
SUSBCRequest_GetStatusLineState
,
USB_TYPE_VENDOR
|
USB_RECIP_ENDPOINT
|
USB_DIR_IN
,
0
,
0
,
transfer_buffer
,
transfer_buffer_length
,
KOBIL_TIMEOUT
);
dbg
(
"%s - port %d Send get_status_line_state (TIOCMGET) URB returns: %i. Statusline: %02x"
,
__FUNCTION__
,
port
->
number
,
result
,
transfer_buffer
[
0
]);
if
((
transfer_buffer
[
0
]
&
SUSBCR_GSL_DSR
)
!=
0
)
{
priv
->
line_state
|=
TIOCM_DSR
;
}
else
{
priv
->
line_state
&=
~
TIOCM_DSR
;
}
kfree
(
transfer_buffer
);
return
put_user
(
priv
->
line_state
,
(
unsigned
long
*
)
arg
);
case
TIOCMSET
:
// 0x5418
if
(
get_user
(
mask
,
(
unsigned
long
*
)
arg
)){
return
-
EFAULT
;
}
// allocate memory for transfer buffer
transfer_buffer
=
(
unsigned
char
*
)
kmalloc
(
transfer_buffer_length
,
GFP_KERNEL
);
if
(
!
transfer_buffer
)
{
return
-
ENOBUFS
;
}
else
{
memset
(
transfer_buffer
,
0
,
transfer_buffer_length
);
}
if
(
priv
->
device_type
==
KOBIL_ADAPTER_B_PRODUCT_ID
)
{
if
((
mask
&
TIOCM_DTR
)
!=
0
){
dbg
(
"%s - port %d Setting DTR"
,
__FUNCTION__
,
port
->
number
);
}
else
{
dbg
(
"%s - port %d Clearing DTR"
,
__FUNCTION__
,
port
->
number
);
}
result
=
usb_control_msg
(
port
->
serial
->
dev
,
usb_rcvctrlpipe
(
port
->
serial
->
dev
,
0
),
SUSBCRequest_SetStatusLinesOrQueues
,
USB_TYPE_VENDOR
|
USB_RECIP_ENDPOINT
|
USB_DIR_OUT
,
(
((
mask
&
TIOCM_DTR
)
!=
0
)
?
SUSBCR_SSL_SETDTR
:
SUSBCR_SSL_CLRDTR
),
0
,
transfer_buffer
,
0
,
KOBIL_TIMEOUT
);
}
else
{
if
((
mask
&
TIOCM_RTS
)
!=
0
){
dbg
(
"%s - port %d Setting RTS"
,
__FUNCTION__
,
port
->
number
);
}
else
{
dbg
(
"%s - port %d Clearing RTS"
,
__FUNCTION__
,
port
->
number
);
}
result
=
usb_control_msg
(
port
->
serial
->
dev
,
usb_rcvctrlpipe
(
port
->
serial
->
dev
,
0
),
SUSBCRequest_SetStatusLinesOrQueues
,
USB_TYPE_VENDOR
|
USB_RECIP_ENDPOINT
|
USB_DIR_OUT
,
(((
mask
&
TIOCM_RTS
)
!=
0
)
?
SUSBCR_SSL_SETRTS
:
SUSBCR_SSL_CLRRTS
),
0
,
transfer_buffer
,
0
,
KOBIL_TIMEOUT
);
}
dbg
(
"%s - port %d Send set_status_line (TIOCMSET) URB returns: %i"
,
__FUNCTION__
,
port
->
number
,
result
);
kfree
(
transfer_buffer
);
return
((
result
<
0
)
?
-
EFAULT
:
0
);
}
return
0
;
}
static
int
__init
kobil_init
(
void
)
{
usb_serial_register
(
&
kobil_device
);
info
(
DRIVER_VERSION
" "
DRIVER_AUTHOR
);
info
(
DRIVER_DESC
);
return
0
;
}
static
void
__exit
kobil_exit
(
void
)
{
usb_serial_deregister
(
&
kobil_device
);
}
module_init
(
kobil_init
);
module_exit
(
kobil_exit
);
MODULE_AUTHOR
(
DRIVER_AUTHOR
);
MODULE_DESCRIPTION
(
DRIVER_DESC
);
MODULE_LICENSE
(
"GPL"
);
MODULE_PARM
(
debug
,
"i"
);
MODULE_PARM_DESC
(
debug
,
"Debug enabled or not"
);
drivers/usb/serial/kobil_sct.h
0 → 100644
View file @
77060bee
#define SUSBCRequest_SetBaudRateParityAndStopBits 1
#define SUSBCR_SBR_MASK 0xFF00
#define SUSBCR_SBR_1200 0x0100
#define SUSBCR_SBR_9600 0x0200
#define SUSBCR_SBR_19200 0x0400
#define SUSBCR_SBR_28800 0x0800
#define SUSBCR_SBR_38400 0x1000
#define SUSBCR_SBR_57600 0x2000
#define SUSBCR_SBR_115200 0x4000
#define SUSBCR_SPASB_MASK 0x0070
#define SUSBCR_SPASB_NoParity 0x0010
#define SUSBCR_SPASB_OddParity 0x0020
#define SUSBCR_SPASB_EvenParity 0x0040
#define SUSBCR_SPASB_STPMASK 0x0003
#define SUSBCR_SPASB_1StopBit 0x0001
#define SUSBCR_SPASB_2StopBits 0x0002
#define SUSBCRequest_SetStatusLinesOrQueues 2
#define SUSBCR_SSL_SETRTS 0x0001
#define SUSBCR_SSL_CLRRTS 0x0002
#define SUSBCR_SSL_SETDTR 0x0004
#define SUSBCR_SSL_CLRDTR 0x0010
#define SUSBCR_SSL_PURGE_TXABORT 0x0100 // Kill the pending/current writes to the comm port.
#define SUSBCR_SSL_PURGE_RXABORT 0x0200 // Kill the pending/current reads to the comm port.
#define SUSBCR_SSL_PURGE_TXCLEAR 0x0400 // Kill the transmit queue if there.
#define SUSBCR_SSL_PURGE_RXCLEAR 0x0800 // Kill the typeahead buffer if there.
#define SUSBCRequest_GetStatusLineState 4
#define SUSBCR_GSL_RXCHAR 0x0001 // Any Character received
#define SUSBCR_GSL_TXEMPTY 0x0004 // Transmitt Queue Empty
#define SUSBCR_GSL_CTS 0x0008 // CTS changed state
#define SUSBCR_GSL_DSR 0x0010 // DSR changed state
#define SUSBCR_GSL_RLSD 0x0020 // RLSD changed state
#define SUSBCR_GSL_BREAK 0x0040 // BREAK received
#define SUSBCR_GSL_ERR 0x0080 // Line status error occurred
#define SUSBCR_GSL_RING 0x0100 // Ring signal detected
#define SUSBCRequest_Misc 8
#define SUSBCR_MSC_ResetReader 0x0001 // use a predefined reset sequence
#define SUSBCR_MSC_ResetAllQueues 0x0002 // use a predefined sequence to reset the internal queues
#define SUSBCRequest_GetMisc 0x10
#define SUSBCR_MSC_GetFWVersion 0x0001
/* get the firmware version from device,
coded like this 0xHHLLBBPP
with HH = Firmware Version High Byte
LL = Firmware Version Low Byte
BB = Build Number
PP = Further Attributes
*/
#define SUSBCR_MSC_GetHWVersion 0x0002
/* get the hardware version from device
coded like this 0xHHLLPPRR
with HH = Software Version High Byte
LL = Software Version Low Byte
PP = Further Attributes
RR = Reserved for the hardware ID
*/
drivers/usb/serial/safe_serial.c
View file @
77060bee
...
...
@@ -132,13 +132,13 @@ MODULE_PARM_DESC (padded, "Pad to full wMaxPacketSize On/Off");
#define MY_USB_DEVICE(vend,prod,dc,ic,isc) \
match_flags:
USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_DEV_CLASS | \
.match_flags =
USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_DEV_CLASS | \
USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS, \
idVendor:
(vend), \
idProduct:
(prod),\
bDeviceClass:
(dc),\
bInterfaceClass:
(ic), \
bInterfaceSubClass:
(isc),
.idVendor =
(vend), \
.idProduct =
(prod),\
.bDeviceClass =
(dc),\
.bInterfaceClass =
(ic), \
.bInterfaceSubClass =
(isc),
static
struct
usb_device_id
id_table
[]
=
{
{
MY_USB_DEVICE
(
0x49f
,
0xffff
,
CDC_DEVICE_CLASS
,
LINEO_INTERFACE_CLASS
,
LINEO_INTERFACE_SUBCLASS_SAFESERIAL
)},
// Itsy
...
...
drivers/usb/serial/visor.c
View file @
77060bee
...
...
@@ -175,6 +175,7 @@ static int visor_ioctl (struct usb_serial_port *port, struct file * file, unsi
static
void
visor_set_termios
(
struct
usb_serial_port
*
port
,
struct
termios
*
old_termios
);
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_int_callback
(
struct
urb
*
urb
,
struct
pt_regs
*
regs
);
static
int
clie_3_5_startup
(
struct
usb_serial
*
serial
);
...
...
@@ -189,6 +190,7 @@ static struct usb_device_id id_table [] = {
{
USB_DEVICE
(
PALM_VENDOR_ID
,
PALM_TUNGSTEN_Z_ID
)
},
{
USB_DEVICE
(
PALM_VENDOR_ID
,
PALM_ZIRE_ID
)
},
{
USB_DEVICE
(
HANDSPRING_VENDOR_ID
,
HANDSPRING_VISOR_ID
)
},
{
USB_DEVICE
(
HANDSPRING_VENDOR_ID
,
HANDSPRING_TREO_ID
)
},
{
USB_DEVICE
(
SONY_VENDOR_ID
,
SONY_CLIE_4_0_ID
)
},
{
USB_DEVICE
(
SONY_VENDOR_ID
,
SONY_CLIE_S360_ID
)
},
{
USB_DEVICE
(
SONY_VENDOR_ID
,
SONY_CLIE_4_1_ID
)
},
...
...
@@ -203,6 +205,7 @@ static struct usb_device_id clie_id_3_5_table [] = {
static
struct
usb_device_id
id_table_combined
[]
=
{
{
USB_DEVICE
(
HANDSPRING_VENDOR_ID
,
HANDSPRING_VISOR_ID
)
},
{
USB_DEVICE
(
HANDSPRING_VENDOR_ID
,
HANDSPRING_TREO_ID
)
},
{
USB_DEVICE
(
PALM_VENDOR_ID
,
PALM_M500_ID
)
},
{
USB_DEVICE
(
PALM_VENDOR_ID
,
PALM_M505_ID
)
},
{
USB_DEVICE
(
PALM_VENDOR_ID
,
PALM_M515_ID
)
},
...
...
@@ -232,9 +235,9 @@ static struct usb_driver visor_driver = {
/* All of the device info needed for the Handspring Visor, and Palm 4.0 devices */
static
struct
usb_serial_device_type
handspring_device
=
{
.
owner
=
THIS_MODULE
,
.
name
=
"Handspring Visor / Palm 4.0 / Clié 4.x"
,
.
name
=
"Handspring Visor /
Treo /
Palm 4.0 / Clié 4.x"
,
.
id_table
=
id_table
,
.
num_interrupt_in
=
0
,
.
num_interrupt_in
=
NUM_DONT_CARE
,
.
num_bulk_in
=
2
,
.
num_bulk_out
=
2
,
.
num_ports
=
2
,
...
...
@@ -252,6 +255,7 @@ static struct usb_serial_device_type handspring_device = {
.
chars_in_buffer
=
visor_chars_in_buffer
,
.
write_bulk_callback
=
visor_write_bulk_callback
,
.
read_bulk_callback
=
visor_read_bulk_callback
,
.
read_int_callback
=
visor_read_int_callback
,
};
/* device info for the Sony Clie OS version 3.5 */
...
...
@@ -320,9 +324,20 @@ static int visor_open (struct usb_serial_port *port, struct file *filp)
port
->
read_urb
->
transfer_buffer_length
,
visor_read_bulk_callback
,
port
);
result
=
usb_submit_urb
(
port
->
read_urb
,
GFP_KERNEL
);
if
(
result
)
err
(
"%s - failed submitting read urb, error %d"
,
__FUNCTION__
,
result
);
if
(
result
)
{
err
(
"%s - failed submitting read urb, error %d"
,
__FUNCTION__
,
result
);
goto
exit
;
}
if
(
port
->
interrupt_in_urb
)
{
dbg
(
"%s - adding interrupt input for treo"
,
__FUNCTION__
);
result
=
usb_submit_urb
(
port
->
interrupt_in_urb
,
GFP_KERNEL
);
if
(
result
)
err
(
"%s - failed submitting interrupt urb, error %d"
,
__FUNCTION__
,
result
);
}
exit:
return
result
;
}
...
...
@@ -358,6 +373,9 @@ static void visor_close (struct usb_serial_port *port, struct file * filp)
}
/* shutdown our bulk read */
usb_unlink_urb
(
port
->
read_urb
);
if
(
port
->
interrupt_in_urb
)
usb_unlink_urb
(
port
->
interrupt_in_urb
);
}
/* Uncomment the following line if you want to see some statistics in your syslog */
/* info ("Bytes In = %d Bytes Out = %d", bytes_in, bytes_out); */
...
...
@@ -523,6 +541,43 @@ static void visor_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
return
;
}
static
void
visor_read_int_callback
(
struct
urb
*
urb
,
struct
pt_regs
*
regs
)
{
int
result
;
switch
(
urb
->
status
)
{
case
0
:
/* success */
break
;
case
-
ECONNRESET
:
case
-
ENOENT
:
case
-
ESHUTDOWN
:
/* this urb is terminated, clean up */
dbg
(
"%s - urb shutting down with status: %d"
,
__FUNCTION__
,
urb
->
status
);
return
;
default:
dbg
(
"%s - nonzero urb status received: %d"
,
__FUNCTION__
,
urb
->
status
);
goto
exit
;
}
/*
* This information is still unknown what it can be used for.
* If anyone has an idea, please let the author know...
*
* Rumor has it this endpoint is used to notify when data
* is ready to be read from the bulk ones.
*/
usb_serial_debug_data
(
__FILE__
,
__FUNCTION__
,
urb
->
actual_length
,
urb
->
transfer_buffer
);
exit:
result
=
usb_submit_urb
(
urb
,
GFP_ATOMIC
);
if
(
result
)
err
(
"%s - Error %d submitting interrupt urb"
,
__FUNCTION__
,
result
);
}
static
void
visor_throttle
(
struct
usb_serial_port
*
port
)
{
...
...
drivers/usb/serial/visor.h
View file @
77060bee
...
...
@@ -19,6 +19,7 @@
#define HANDSPRING_VENDOR_ID 0x082d
#define HANDSPRING_VISOR_ID 0x0100
#define HANDSPRING_TREO_ID 0x0200
#define PALM_VENDOR_ID 0x0830
#define PALM_M500_ID 0x0001
...
...
drivers/usb/storage/transport.c
View file @
77060bee
...
...
@@ -503,6 +503,35 @@ int usb_stor_bulk_msg(struct us_data *us, void *data, unsigned int pipe,
return
status
;
}
/* This is our function to submit interrupt URBs with enough control
* to make aborts/resets/timeouts work
*
* This routine always uses us->recv_intr_pipe as the pipe and
* us->ep_bInterval as the interrupt interval.
*/
int
usb_stor_interrupt_msg
(
struct
us_data
*
us
,
void
*
data
,
unsigned
int
len
,
unsigned
int
*
act_len
)
{
unsigned
int
pipe
=
us
->
recv_intr_pipe
;
unsigned
int
maxp
;
int
status
;
/* calculate the max packet size */
maxp
=
usb_maxpacket
(
us
->
pusb_dev
,
pipe
,
usb_pipeout
(
pipe
));
if
(
maxp
>
len
)
maxp
=
len
;
/* fill and submit the URB */
usb_fill_int_urb
(
us
->
current_urb
,
us
->
pusb_dev
,
pipe
,
data
,
maxp
,
usb_stor_blocking_completion
,
NULL
,
us
->
ep_bInterval
);
status
=
usb_stor_msg_common
(
us
);
/* store the actual length of the data transferred */
*
act_len
=
us
->
current_urb
->
actual_length
;
return
status
;
}
/* This is a version of usb_clear_halt() that doesn't read the status from
* the device -- this is because some devices crash their internal firmware
* when the status is requested after a halt.
...
...
@@ -626,6 +655,29 @@ int usb_stor_ctrl_transfer(struct us_data *us, unsigned int pipe,
return
interpret_urb_result
(
us
,
pipe
,
size
,
result
,
partial
);
}
/*
* Receive one buffer via interrupt transfer
*
* This function does basically the same thing as usb_stor_interrupt_msg()
* above, except that return codes are USB_STOR_XFER_xxx rather than the
* urb status.
*/
int
usb_stor_intr_transfer
(
struct
us_data
*
us
,
void
*
buf
,
unsigned
int
length
,
unsigned
int
*
act_len
)
{
int
result
;
unsigned
int
partial
;
/* transfer the data */
US_DEBUGP
(
"usb_stor_intr_transfer(): xfer %u bytes
\n
"
,
length
);
result
=
usb_stor_interrupt_msg
(
us
,
buf
,
length
,
&
partial
);
if
(
act_len
)
*
act_len
=
partial
;
return
interpret_urb_result
(
us
,
us
->
recv_intr_pipe
,
length
,
result
,
partial
);
}
/*
* Transfer one buffer via bulk transfer
*
...
...
@@ -947,7 +999,7 @@ void usb_stor_abort_transport(struct us_data *us)
host
=
us
->
srb
->
host
;
scsi_unlock
(
host
);
/* If the state machine is blocked waiting for an URB
or an IRQ
,
/* If the state machine is blocked waiting for an URB,
* let's wake it up */
/* If we have an URB pending, cancel it. The test_and_clear_bit()
...
...
@@ -964,12 +1016,6 @@ void usb_stor_abort_transport(struct us_data *us)
usb_sg_cancel
(
us
->
current_sg
);
}
/* If we are waiting for an IRQ, simulate it */
if
(
test_bit
(
US_FLIDX_IP_WANTED
,
&
us
->
flags
))
{
US_DEBUGP
(
"-- simulating missing IRQ
\n
"
);
usb_stor_CBI_irq
(
us
->
irq_urb
,
NULL
);
}
/* Wait for the aborted command to finish */
wait_for_completion
(
&
us
->
notify
);
...
...
@@ -981,94 +1027,11 @@ void usb_stor_abort_transport(struct us_data *us)
* Control/Bulk/Interrupt transport
*/
/* The interrupt handler for CBI devices */
void
usb_stor_CBI_irq
(
struct
urb
*
urb
,
struct
pt_regs
*
regs
)
{
struct
us_data
*
us
=
(
struct
us_data
*
)
urb
->
context
;
int
status
;
US_DEBUGP
(
"USB IRQ received for device on host %d
\n
"
,
us
->
host_no
);
US_DEBUGP
(
"-- IRQ data length is %d
\n
"
,
urb
->
actual_length
);
US_DEBUGP
(
"-- IRQ state is %d
\n
"
,
urb
->
status
);
US_DEBUGP
(
"-- Interrupt Status (0x%x, 0x%x)
\n
"
,
us
->
irqbuf
[
0
],
us
->
irqbuf
[
1
]);
/* has the current command been aborted? */
if
(
atomic_read
(
&
us
->
sm_state
)
==
US_STATE_ABORTING
)
{
/* was this a wanted interrupt? */
if
(
!
test_and_clear_bit
(
US_FLIDX_IP_WANTED
,
&
us
->
flags
))
{
US_DEBUGP
(
"ERROR: Unwanted interrupt received!
\n
"
);
goto
exit
;
}
US_DEBUGP
(
"-- command aborted
\n
"
);
/* wake up the command thread */
up
(
&
us
->
ip_waitq
);
goto
exit
;
}
/* is the device removed? */
if
(
urb
->
status
==
-
ENOENT
)
{
US_DEBUGP
(
"-- device has been removed
\n
"
);
/* was this a wanted interrupt? */
if
(
!
test_and_clear_bit
(
US_FLIDX_IP_WANTED
,
&
us
->
flags
))
return
;
/* indicate a transport error -- this is the best we can do */
us
->
irqdata
[
0
]
=
us
->
irqdata
[
1
]
=
0xFF
;
/* wake up the command thread */
up
(
&
us
->
ip_waitq
);
return
;
}
/* reject improper IRQs */
if
(
urb
->
actual_length
!=
2
)
{
US_DEBUGP
(
"-- IRQ too short
\n
"
);
goto
exit
;
}
/* was this a command-completion interrupt? */
if
(
us
->
irqbuf
[
0
]
&&
(
us
->
subclass
!=
US_SC_UFI
))
{
US_DEBUGP
(
"-- not a command-completion IRQ
\n
"
);
goto
exit
;
}
/* was this a wanted interrupt? */
if
(
!
test_and_clear_bit
(
US_FLIDX_IP_WANTED
,
&
us
->
flags
))
{
US_DEBUGP
(
"ERROR: Unwanted interrupt received!
\n
"
);
goto
exit
;
}
/* copy the valid data */
us
->
irqdata
[
0
]
=
us
->
irqbuf
[
0
];
us
->
irqdata
[
1
]
=
us
->
irqbuf
[
1
];
/* wake up the command thread */
up
(
&
(
us
->
ip_waitq
));
exit:
/* resubmit the urb */
status
=
usb_submit_urb
(
urb
,
GFP_ATOMIC
);
if
(
status
)
err
(
"%s - usb_submit_urb failed with result %d"
,
__FUNCTION__
,
status
);
}
int
usb_stor_CBI_transport
(
Scsi_Cmnd
*
srb
,
struct
us_data
*
us
)
{
unsigned
int
transfer_length
=
usb_stor_transfer_length
(
srb
);
int
result
;
/* re-initialize the mutex so that we avoid any races with
* early/late IRQs from previous commands */
init_MUTEX_LOCKED
(
&
(
us
->
ip_waitq
));
/* Set up for status notification */
set_bit
(
US_FLIDX_IP_WANTED
,
&
us
->
flags
);
/* COMMAND STAGE */
/* let's send the command via the control pipe */
result
=
usb_stor_ctrl_transfer
(
us
,
us
->
send_ctrl_pipe
,
...
...
@@ -1079,8 +1042,6 @@ int usb_stor_CBI_transport(Scsi_Cmnd *srb, struct us_data *us)
/* check the return code for the command */
US_DEBUGP
(
"Call to usb_stor_ctrl_transfer() returned %d
\n
"
,
result
);
if
(
result
!=
USB_STOR_XFER_GOOD
)
{
/* Reset flag for status notification */
clear_bit
(
US_FLIDX_IP_WANTED
,
&
us
->
flags
);
/* Uh oh... serious problem here */
return
USB_STOR_TRANSPORT_ERROR
;
}
...
...
@@ -1093,25 +1054,17 @@ int usb_stor_CBI_transport(Scsi_Cmnd *srb, struct us_data *us)
result
=
usb_stor_bulk_transfer_srb
(
us
,
pipe
,
srb
,
transfer_length
);
US_DEBUGP
(
"CBI data stage result is 0x%x
\n
"
,
result
);
if
(
result
==
USB_STOR_XFER_ERROR
)
{
clear_bit
(
US_FLIDX_IP_WANTED
,
&
us
->
flags
);
if
(
result
==
USB_STOR_XFER_ERROR
)
return
USB_STOR_TRANSPORT_ERROR
;
}
}
/* STATUS STAGE */
/* go to sleep until we get this interrupt */
down
(
&
(
us
->
ip_waitq
));
/* has the current command been aborted? */
if
(
atomic_read
(
&
us
->
sm_state
)
==
US_STATE_ABORTING
)
{
US_DEBUGP
(
"CBI interrupt aborted
\n
"
);
return
USB_STOR_TRANSPORT_ERROR
;
}
result
=
usb_stor_intr_transfer
(
us
,
us
->
irqdata
,
sizeof
(
us
->
irqdata
),
NULL
);
US_DEBUGP
(
"Got interrupt data (0x%x, 0x%x)
\n
"
,
us
->
irqdata
[
0
],
us
->
irqdata
[
1
]);
if
(
result
!=
USB_STOR_XFER_GOOD
)
return
USB_STOR_TRANSPORT_ERROR
;
/* UFI gives us ASC and ASCQ, like a request sense
*
...
...
drivers/usb/storage/transport.h
View file @
77060bee
...
...
@@ -145,7 +145,6 @@ struct bulk_cs_wrap {
#define US_CBI_ADSC 0
extern
void
usb_stor_CBI_irq
(
struct
urb
*
,
struct
pt_regs
*
);
extern
int
usb_stor_CBI_transport
(
Scsi_Cmnd
*
,
struct
us_data
*
);
extern
int
usb_stor_CB_transport
(
Scsi_Cmnd
*
,
struct
us_data
*
);
...
...
@@ -164,11 +163,15 @@ extern int usb_stor_bulk_msg(struct us_data *us, void *data,
extern
int
usb_stor_control_msg
(
struct
us_data
*
us
,
unsigned
int
pipe
,
u8
request
,
u8
requesttype
,
u16
value
,
u16
index
,
void
*
data
,
u16
size
);
extern
int
usb_stor_interrupt_msg
(
struct
us_data
*
us
,
void
*
data
,
unsigned
int
len
,
unsigned
int
*
act_len
);
extern
int
usb_stor_clear_halt
(
struct
us_data
*
,
unsigned
int
pipe
);
extern
int
usb_stor_ctrl_transfer
(
struct
us_data
*
us
,
unsigned
int
pipe
,
u8
request
,
u8
requesttype
,
u16
value
,
u16
index
,
void
*
data
,
u16
size
);
extern
int
usb_stor_intr_transfer
(
struct
us_data
*
us
,
void
*
buf
,
unsigned
int
length
,
unsigned
int
*
act_len
);
extern
int
usb_stor_bulk_transfer_buf
(
struct
us_data
*
us
,
unsigned
int
pipe
,
void
*
buf
,
unsigned
int
length
,
unsigned
int
*
act_len
);
extern
int
usb_stor_bulk_transfer_sglist
(
struct
us_data
*
us
,
unsigned
int
pipe
,
...
...
drivers/usb/storage/usb.c
View file @
77060bee
...
...
@@ -174,7 +174,7 @@ MODULE_DEVICE_TABLE (usb, storage_usb_ids);
.productName = product_name, \
.useProtocol = use_protocol, \
.useTransport = use_transport, \
initFunction :
init_function, \
.initFunction =
init_function, \
.flags = Flags, \
}
...
...
@@ -477,24 +477,20 @@ static int usb_stor_control_thread(void * __us)
return
0
;
}
/* Set up the URB
, the usb_ctrlrequest, and the IRQ pipe and handler
.
/* Set up the URB
and the usb_ctrlrequest
.
* ss->dev_semaphore must already be locked.
* Note that this function assumes that all the data in the us_data
* strucuture is current. This includes the ep_int field, which gives us
* the endpoint for the interrupt.
* structure is current.
* Returns non-zero on failure, zero on success
*/
static
int
usb_stor_allocate_urbs
(
struct
us_data
*
ss
)
{
unsigned
int
pipe
;
int
maxp
;
int
result
;
/* calculate and store the pipe values */
ss
->
send_bulk_pipe
=
usb_sndbulkpipe
(
ss
->
pusb_dev
,
ss
->
ep_out
);
ss
->
recv_bulk_pipe
=
usb_rcvbulkpipe
(
ss
->
pusb_dev
,
ss
->
ep_in
);
ss
->
send_ctrl_pipe
=
usb_sndctrlpipe
(
ss
->
pusb_dev
,
0
);
ss
->
recv_ctrl_pipe
=
usb_rcvctrlpipe
(
ss
->
pusb_dev
,
0
);
ss
->
send_bulk_pipe
=
usb_sndbulkpipe
(
ss
->
pusb_dev
,
ss
->
ep_out
);
ss
->
recv_bulk_pipe
=
usb_rcvbulkpipe
(
ss
->
pusb_dev
,
ss
->
ep_in
);
ss
->
recv_intr_pipe
=
usb_rcvintpipe
(
ss
->
pusb_dev
,
ss
->
ep_int
);
/* allocate the usb_ctrlrequest for control packets */
US_DEBUGP
(
"Allocating usb_ctrlrequest
\n
"
);
...
...
@@ -519,45 +515,6 @@ static int usb_stor_allocate_urbs(struct us_data *ss)
return
5
;
}
/* allocate the IRQ URB, if it is needed */
if
(
ss
->
protocol
==
US_PR_CBI
)
{
US_DEBUGP
(
"Allocating IRQ for CBI transport
\n
"
);
/* lock access to the data structure */
down
(
&
(
ss
->
irq_urb_sem
));
/* allocate the URB */
ss
->
irq_urb
=
usb_alloc_urb
(
0
,
GFP_KERNEL
);
if
(
!
ss
->
irq_urb
)
{
up
(
&
(
ss
->
irq_urb_sem
));
US_DEBUGP
(
"couldn't allocate interrupt URB"
);
return
3
;
}
/* calculate the pipe and max packet size */
pipe
=
usb_rcvintpipe
(
ss
->
pusb_dev
,
ss
->
ep_int
->
bEndpointAddress
&
USB_ENDPOINT_NUMBER_MASK
);
maxp
=
usb_maxpacket
(
ss
->
pusb_dev
,
pipe
,
usb_pipeout
(
pipe
));
if
(
maxp
>
sizeof
(
ss
->
irqbuf
))
maxp
=
sizeof
(
ss
->
irqbuf
);
/* fill in the URB with our data */
usb_fill_int_urb
(
ss
->
irq_urb
,
ss
->
pusb_dev
,
pipe
,
ss
->
irqbuf
,
maxp
,
usb_stor_CBI_irq
,
ss
,
ss
->
ep_int
->
bInterval
);
/* submit the URB for processing */
result
=
usb_submit_urb
(
ss
->
irq_urb
,
GFP_KERNEL
);
US_DEBUGP
(
"usb_submit_urb() returns %d
\n
"
,
result
);
if
(
result
)
{
up
(
&
(
ss
->
irq_urb_sem
));
return
4
;
}
/* unlock the data structure */
up
(
&
(
ss
->
irq_urb_sem
));
}
/* ss->protocol == US_PR_CBI */
return
0
;
/* success */
}
...
...
@@ -568,17 +525,6 @@ static void usb_stor_deallocate_urbs(struct us_data *ss)
{
int
result
;
/* release the IRQ, if we have one */
down
(
&
(
ss
->
irq_urb_sem
));
if
(
ss
->
irq_urb
)
{
US_DEBUGP
(
"-- releasing irq URB
\n
"
);
result
=
usb_unlink_urb
(
ss
->
irq_urb
);
US_DEBUGP
(
"-- usb_unlink_urb() returned %d
\n
"
,
result
);
usb_free_urb
(
ss
->
irq_urb
);
ss
->
irq_urb
=
NULL
;
}
up
(
&
(
ss
->
irq_urb_sem
));
/* free the scatter-gather request block */
if
(
ss
->
current_sg
)
{
kfree
(
ss
->
current_sg
);
...
...
@@ -782,7 +728,9 @@ static int storage_probe(struct usb_interface *intf,
USB_ENDPOINT_NUMBER_MASK
;
ss
->
ep_out
=
ep_out
->
bEndpointAddress
&
USB_ENDPOINT_NUMBER_MASK
;
ss
->
ep_int
=
ep_int
;
ss
->
ep_int
=
ep_int
->
bEndpointAddress
&
USB_ENDPOINT_NUMBER_MASK
;
ss
->
ep_bInterval
=
ep_int
->
bInterval
;
/* allocate the URB, the usb_ctrlrequest, and the IRQ URB */
if
(
usb_stor_allocate_urbs
(
ss
))
...
...
@@ -810,8 +758,6 @@ static int storage_probe(struct usb_interface *intf,
/* Initialize the mutexes only when the struct is new */
init_completion
(
&
(
ss
->
notify
));
init_MUTEX_LOCKED
(
&
(
ss
->
ip_waitq
));
init_MUTEX
(
&
(
ss
->
irq_urb_sem
));
init_MUTEX_LOCKED
(
&
(
ss
->
dev_semaphore
));
/* copy over the subclass and protocol data */
...
...
@@ -825,7 +771,9 @@ static int storage_probe(struct usb_interface *intf,
USB_ENDPOINT_NUMBER_MASK
;
ss
->
ep_out
=
ep_out
->
bEndpointAddress
&
USB_ENDPOINT_NUMBER_MASK
;
ss
->
ep_int
=
ep_int
;
ss
->
ep_int
=
ep_int
->
bEndpointAddress
&
USB_ENDPOINT_NUMBER_MASK
;
ss
->
ep_bInterval
=
ep_int
->
bInterval
;
/* establish the connection to the new device */
ss
->
ifnum
=
ifnum
;
...
...
drivers/usb/storage/usb.h
View file @
77060bee
...
...
@@ -105,7 +105,6 @@ struct us_unusual_dev {
#define US_FL_FIX_CAPACITY 0x00000080
/* READ CAPACITY response too big */
#define US_FL_DEV_ATTACHED 0x00010000
/* is the device attached? */
#define US_FLIDX_IP_WANTED 17
/* 0x00020000 is an IRQ expected? */
#define US_FLIDX_CAN_CANCEL 18
/* 0x00040000 okay to cancel current_urb? */
#define US_FLIDX_CANCEL_SG 19
/* 0x00080000 okay to cancel current_sg? */
...
...
@@ -139,6 +138,7 @@ struct us_data {
unsigned
int
recv_bulk_pipe
;
unsigned
int
send_ctrl_pipe
;
unsigned
int
recv_ctrl_pipe
;
unsigned
int
recv_intr_pipe
;
/* information about the device -- always good */
char
vendor
[
USB_STOR_STRING_LEN
];
...
...
@@ -154,7 +154,8 @@ struct us_data {
u8
ifnum
;
/* interface number */
u8
ep_in
;
/* bulk in endpoint */
u8
ep_out
;
/* bulk out endpoint */
struct
usb_endpoint_descriptor
*
ep_int
;
/* interrupt endpoint */
u8
ep_int
;
/* interrupt endpoint */
u8
ep_bInterval
;
/* interrupt interval */
/* function pointers for this device */
trans_cmnd
transport
;
/* transport function */
...
...
@@ -173,13 +174,7 @@ struct us_data {
int
pid
;
/* control thread */
atomic_t
sm_state
;
/* what we are doing */
/* interrupt info for CBI devices -- only good if attached */
struct
semaphore
ip_waitq
;
/* for CBI interrupts */
/* interrupt communications data */
struct
semaphore
irq_urb_sem
;
/* to protect irq_urb */
struct
urb
*
irq_urb
;
/* for USB int requests */
unsigned
char
irqbuf
[
2
];
/* buffer for USB IRQ */
unsigned
char
irqdata
[
2
];
/* data from USB IRQ */
/* control and bulk communications data */
...
...
sound/usb/usbmidi.c
View file @
77060bee
...
...
@@ -217,7 +217,7 @@ static void snd_usbmidi_in_midiman_complete(struct urb* urb, struct pt_regs *reg
}
}
}
snd_usbmidi_in_urb_complete
(
urb
);
snd_usbmidi_in_urb_complete
(
urb
,
regs
);
}
static
void
snd_usbmidi_out_urb_complete
(
struct
urb
*
urb
,
struct
pt_regs
*
regs
)
...
...
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