Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
20f2ef0b
Commit
20f2ef0b
authored
Mar 17, 2002
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
http://linuxusb.bkbits.net/linus-2.5
into home.transmeta.com:/home/torvalds/v2.5/linux
parents
c3d7ae3b
90b49267
Changes
23
Hide whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
878 additions
and
336 deletions
+878
-336
drivers/usb/Config.help
drivers/usb/Config.help
+1
-0
drivers/usb/catc.c
drivers/usb/catc.c
+215
-76
drivers/usb/hid-core.c
drivers/usb/hid-core.c
+59
-13
drivers/usb/hid.h
drivers/usb/hid.h
+3
-0
drivers/usb/hiddev.c
drivers/usb/hiddev.c
+81
-35
drivers/usb/printer.c
drivers/usb/printer.c
+450
-153
drivers/usb/serial/cyberjack.c
drivers/usb/serial/cyberjack.c
+4
-4
drivers/usb/serial/digi_acceleport.c
drivers/usb/serial/digi_acceleport.c
+7
-7
drivers/usb/serial/empeg.c
drivers/usb/serial/empeg.c
+4
-4
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio.c
+2
-2
drivers/usb/serial/io_edgeport.c
drivers/usb/serial/io_edgeport.c
+9
-9
drivers/usb/serial/ipaq.c
drivers/usb/serial/ipaq.c
+2
-2
drivers/usb/serial/ir-usb.c
drivers/usb/serial/ir-usb.c
+2
-2
drivers/usb/serial/keyspan.c
drivers/usb/serial/keyspan.c
+7
-7
drivers/usb/serial/keyspan_pda.c
drivers/usb/serial/keyspan_pda.c
+2
-2
drivers/usb/serial/kl5kusb105.c
drivers/usb/serial/kl5kusb105.c
+4
-4
drivers/usb/serial/mct_u232.c
drivers/usb/serial/mct_u232.c
+1
-1
drivers/usb/serial/omninet.c
drivers/usb/serial/omninet.c
+2
-2
drivers/usb/serial/pl2303.c
drivers/usb/serial/pl2303.c
+4
-4
drivers/usb/serial/usbserial.c
drivers/usb/serial/usbserial.c
+2
-2
drivers/usb/serial/visor.c
drivers/usb/serial/visor.c
+5
-5
drivers/usb/serial/whiteheat.c
drivers/usb/serial/whiteheat.c
+1
-1
include/linux/hiddev.h
include/linux/hiddev.h
+11
-1
No files found.
drivers/usb/Config.help
View file @
20f2ef0b
...
...
@@ -382,6 +382,7 @@ CONFIG_USB_KAWETH
CONFIG_USB_CATC
Say Y if you want to use one of the following 10Mbps USB Ethernet
device based on the EL1210A chip. Supported devices are:
Belkin F5U011
Belkin F5U111
CATC NetMate
CATC NetMate II
...
...
drivers/usb/catc.c
View file @
20f2ef0b
...
...
@@ -7,6 +7,9 @@
*
* Based on the work of
* Donald Becker
*
* Old chipset support added by Simon Evans <spse@secret.org.uk> 2002
* - adds support for Belkin F5U011
*/
/*
...
...
@@ -70,6 +73,7 @@ MODULE_LICENSE("GPL");
#define RX_MAX_BURST 15
/* Max packets per rx buffer (> 0, < 16) */
#define TX_MAX_BURST 15
/* Max full sized packets per tx buffer (> 0) */
#define CTRL_QUEUE 16
/* Max control requests in flight (power of two) */
#define RX_PKT_SZ 1600
/* Max size of receive packet for F5U011 */
/*
* Control requests.
...
...
@@ -80,6 +84,7 @@ enum control_requests {
GetMac
=
0xf2
,
Reset
=
0xf4
,
SetMac
=
0xf5
,
SetRxMode
=
0xf5
,
/* F5U011 only */
WriteROM
=
0xf8
,
SetReg
=
0xfa
,
GetReg
=
0xfb
,
...
...
@@ -127,6 +132,7 @@ enum rx_filter_bits {
RxForceOK
=
0x04
,
RxMultiCast
=
0x08
,
RxPromisc
=
0x10
,
AltRxPromisc
=
0x20
,
/* F5U011 uses different bit */
};
enum
led_values
{
...
...
@@ -137,6 +143,12 @@ enum led_values {
LEDLink
=
0x08
,
};
enum
link_status
{
LinkNoChange
=
0
,
LinkGood
=
1
,
LinkBad
=
2
};
/*
* The catc struct.
*/
...
...
@@ -180,6 +192,10 @@ struct catc {
}
ctrl_queue
[
CTRL_QUEUE
];
struct
urb
*
tx_urb
,
*
rx_urb
,
*
irq_urb
,
*
ctrl_urb
;
u8
is_f5u011
;
/* Set if device is an F5U011 */
u8
rxmode
[
2
];
/* Used for F5U011 */
atomic_t
recq_sz
;
/* Used for F5U011 - counter of waiting rx packets */
};
/*
...
...
@@ -193,6 +209,10 @@ struct catc {
#define catc_write_mem(catc, addr, buf, size) catc_ctrl_msg(catc, USB_DIR_OUT, WriteMem, 0, addr, buf, size)
#define catc_read_mem(catc, addr, buf, size) catc_ctrl_msg(catc, USB_DIR_IN, ReadMem, 0, addr, buf, size)
#define f5u011_rxmode(catc, rxmode) catc_ctrl_msg(catc, USB_DIR_OUT, SetRxMode, 0, 1, rxmode, 2)
#define f5u011_rxmode_async(catc, rxmode) catc_ctrl_async(catc, USB_DIR_OUT, SetRxMode, 0, 1, &rxmode, 2, NULL)
#define f5u011_mchash_async(catc, hash) catc_ctrl_async(catc, USB_DIR_OUT, SetRxMode, 0, 2, &hash, 8, NULL)
#define catc_set_reg_async(catc, reg, val) catc_ctrl_async(catc, USB_DIR_OUT, SetReg, val, reg, NULL, 0, NULL)
#define catc_get_reg_async(catc, reg, cb) catc_ctrl_async(catc, USB_DIR_IN, GetReg, 0, reg, NULL, 1, cb)
#define catc_write_mem_async(catc, addr, buf, size) catc_ctrl_async(catc, USB_DIR_OUT, WriteMem, 0, addr, buf, size, NULL)
...
...
@@ -206,9 +226,12 @@ static void catc_rx_done(struct urb *urb)
struct
catc
*
catc
=
urb
->
context
;
u8
*
pkt_start
=
urb
->
transfer_buffer
;
struct
sk_buff
*
skb
;
int
pkt_len
;
int
pkt_len
,
pkt_offset
=
0
;
clear_bit
(
RX_RUNNING
,
&
catc
->
flags
);
if
(
!
catc
->
is_f5u011
)
{
clear_bit
(
RX_RUNNING
,
&
catc
->
flags
);
pkt_offset
=
2
;
}
if
(
urb
->
status
)
{
dbg
(
"rx_done, status %d, length %d"
,
urb
->
status
,
urb
->
actual_length
);
...
...
@@ -216,19 +239,22 @@ static void catc_rx_done(struct urb *urb)
}
do
{
pkt_len
=
le16_to_cpup
((
u16
*
)
pkt_start
);
if
(
pkt_len
>
urb
->
actual_length
)
{
catc
->
stats
.
rx_length_errors
++
;
catc
->
stats
.
rx_errors
++
;
break
;
if
(
!
catc
->
is_f5u011
)
{
pkt_len
=
le16_to_cpup
((
u16
*
)
pkt_start
);
if
(
pkt_len
>
urb
->
actual_length
)
{
catc
->
stats
.
rx_length_errors
++
;
catc
->
stats
.
rx_errors
++
;
break
;
}
}
else
{
pkt_len
=
urb
->
actual_length
;
}
if
(
!
(
skb
=
dev_alloc_skb
(
pkt_len
)))
return
;
skb
->
dev
=
catc
->
netdev
;
eth_copy_and_sum
(
skb
,
pkt_start
+
2
,
pkt_len
,
0
);
eth_copy_and_sum
(
skb
,
pkt_start
+
pkt_offset
,
pkt_len
,
0
);
skb_put
(
skb
,
pkt_len
);
skb
->
protocol
=
eth_type_trans
(
skb
,
catc
->
netdev
);
...
...
@@ -237,11 +263,28 @@ static void catc_rx_done(struct urb *urb)
catc
->
stats
.
rx_packets
++
;
catc
->
stats
.
rx_bytes
+=
pkt_len
;
/* F5U011 only does one packet per RX */
if
(
catc
->
is_f5u011
)
break
;
pkt_start
+=
(((
pkt_len
+
1
)
>>
6
)
+
1
)
<<
6
;
}
while
(
pkt_start
-
(
u8
*
)
urb
->
transfer_buffer
<
urb
->
actual_length
);
catc
->
netdev
->
last_rx
=
jiffies
;
if
(
catc
->
is_f5u011
)
{
if
(
atomic_read
(
&
catc
->
recq_sz
))
{
int
status
;
atomic_dec
(
&
catc
->
recq_sz
);
dbg
(
"getting extra packet"
);
urb
->
dev
=
catc
->
usbdev
;
if
((
status
=
usb_submit_urb
(
urb
,
GFP_KERNEL
))
<
0
)
{
dbg
(
"submit(rx_urb) status %d"
,
status
);
}
}
else
{
clear_bit
(
RX_RUNNING
,
&
catc
->
flags
);
}
}
}
static
void
catc_irq_done
(
struct
urb
*
urb
)
...
...
@@ -249,29 +292,48 @@ static void catc_irq_done(struct urb *urb)
struct
catc
*
catc
=
urb
->
context
;
u8
*
data
=
urb
->
transfer_buffer
;
int
status
;
unsigned
int
hasdata
=
0
,
linksts
=
LinkNoChange
;
if
(
!
catc
->
is_f5u011
)
{
hasdata
=
data
[
1
]
&
0x80
;
if
(
data
[
1
]
&
0x40
)
linksts
=
LinkGood
;
else
if
(
data
[
1
]
&
0x20
)
linksts
=
LinkBad
;
}
else
{
hasdata
=
(
unsigned
int
)(
be16_to_cpup
((
u16
*
)
data
)
&
0x0fff
);
if
(
data
[
0
]
==
0x90
)
linksts
=
LinkGood
;
else
if
(
data
[
0
]
==
0xA0
)
linksts
=
LinkBad
;
}
if
(
urb
->
status
)
{
dbg
(
"irq_done, status %d, data %02x %02x."
,
urb
->
status
,
data
[
0
],
data
[
1
]);
return
;
}
if
((
data
[
1
]
&
0x80
)
&&
!
test_and_set_bit
(
RX_RUNNING
,
&
catc
->
flags
))
{
catc
->
rx_urb
->
dev
=
catc
->
usbdev
;
if
((
status
=
usb_submit_urb
(
catc
->
rx_urb
,
GFP_KERNEL
))
<
0
)
{
err
(
"submit(rx_urb) status %d"
,
status
);
return
;
}
}
if
(
data
[
1
]
&
0x40
)
{
if
(
linksts
==
LinkGood
)
{
netif_carrier_on
(
catc
->
netdev
);
dbg
(
"link ok"
);
}
if
(
data
[
1
]
&
0x20
)
{
if
(
linksts
==
LinkBad
)
{
netif_carrier_off
(
catc
->
netdev
);
dbg
(
"link bad"
);
}
if
(
hasdata
)
{
if
(
test_and_set_bit
(
RX_RUNNING
,
&
catc
->
flags
))
{
if
(
catc
->
is_f5u011
)
atomic_inc
(
&
catc
->
recq_sz
);
}
else
{
catc
->
rx_urb
->
dev
=
catc
->
usbdev
;
if
((
status
=
usb_submit_urb
(
catc
->
rx_urb
,
GFP_KERNEL
))
<
0
)
{
err
(
"submit(rx_urb) status %d"
,
status
);
}
}
}
}
/*
...
...
@@ -282,6 +344,9 @@ static void catc_tx_run(struct catc *catc)
{
int
status
;
if
(
catc
->
is_f5u011
)
catc
->
tx_ptr
=
(
catc
->
tx_ptr
+
63
)
&
~
63
;
catc
->
tx_urb
->
transfer_buffer_length
=
catc
->
tx_ptr
;
catc
->
tx_urb
->
transfer_buffer
=
catc
->
tx_buf
[
catc
->
tx_idx
];
catc
->
tx_urb
->
dev
=
catc
->
usbdev
;
...
...
@@ -338,14 +403,15 @@ static int catc_hard_start_xmit(struct sk_buff *skb, struct net_device *netdev)
catc
->
tx_ptr
=
(((
catc
->
tx_ptr
-
1
)
>>
6
)
+
1
)
<<
6
;
tx_buf
=
catc
->
tx_buf
[
catc
->
tx_idx
]
+
catc
->
tx_ptr
;
*
((
u16
*
)
tx_buf
)
=
cpu_to_le16
((
u16
)
skb
->
len
);
*
((
u16
*
)
tx_buf
)
=
(
catc
->
is_f5u011
)
?
cpu_to_be16
((
u16
)
skb
->
len
)
:
cpu_to_le16
((
u16
)
skb
->
len
);
memcpy
(
tx_buf
+
2
,
skb
->
data
,
skb
->
len
);
catc
->
tx_ptr
+=
skb
->
len
+
2
;
if
(
!
test_and_set_bit
(
TX_RUNNING
,
&
catc
->
flags
))
catc_tx_run
(
catc
);
if
(
catc
->
tx_ptr
>=
((
TX_MAX_BURST
-
1
)
*
(
PKT_SZ
+
2
)))
if
((
catc
->
is_f5u011
&&
catc
->
tx_ptr
)
||
(
catc
->
tx_ptr
>=
((
TX_MAX_BURST
-
1
)
*
(
PKT_SZ
+
2
))))
netif_stop_queue
(
netdev
);
spin_unlock_irqrestore
(
&
catc
->
tx_lock
,
flags
);
...
...
@@ -554,17 +620,32 @@ static void catc_set_multicast_list(struct net_device *netdev)
if
(
netdev
->
flags
&
IFF_PROMISC
)
{
memset
(
catc
->
multicast
,
0xff
,
64
);
rx
|=
RxPromisc
;
rx
|=
(
!
catc
->
is_f5u011
)
?
RxPromisc
:
Alt
RxPromisc
;
}
if
(
netdev
->
flags
&
IFF_ALLMULTI
)
if
(
netdev
->
flags
&
IFF_ALLMULTI
)
{
memset
(
catc
->
multicast
,
0xff
,
64
);
for
(
i
=
0
,
mc
=
netdev
->
mc_list
;
mc
&&
i
<
netdev
->
mc_count
;
i
++
,
mc
=
mc
->
next
)
catc_multicast
(
mc
->
dmi_addr
,
catc
->
multicast
);
catc_set_reg_async
(
catc
,
RxUnit
,
rx
);
catc_write_mem_async
(
catc
,
0xfa80
,
catc
->
multicast
,
64
);
}
else
{
for
(
i
=
0
,
mc
=
netdev
->
mc_list
;
mc
&&
i
<
netdev
->
mc_count
;
i
++
,
mc
=
mc
->
next
)
{
u32
crc
=
ether_crc_le
(
6
,
mc
->
dmi_addr
);
if
(
!
catc
->
is_f5u011
)
{
catc
->
multicast
[(
crc
>>
3
)
&
0x3f
]
|=
1
<<
(
crc
&
7
);
}
else
{
catc
->
multicast
[
7
-
(
crc
>>
29
)]
|=
1
<<
((
crc
>>
26
)
&
7
);
}
}
}
if
(
!
catc
->
is_f5u011
)
{
catc_set_reg_async
(
catc
,
RxUnit
,
rx
);
catc_write_mem_async
(
catc
,
0xfa80
,
catc
->
multicast
,
64
);
}
else
{
f5u011_mchash_async
(
catc
,
catc
->
multicast
);
if
(
catc
->
rxmode
[
0
]
!=
rx
)
{
catc
->
rxmode
[
0
]
=
rx
;
dbg
(
"Setting RX mode to %2.2X %2.2X"
,
catc
->
rxmode
[
0
],
catc
->
rxmode
[
1
]);
f5u011_rxmode_async
(
catc
,
catc
->
rxmode
);
}
}
}
/*
...
...
@@ -591,6 +672,29 @@ static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
return
-
EFAULT
;
return
0
;
}
/* get settings */
case
ETHTOOL_GSET
:
if
(
catc
->
is_f5u011
)
{
struct
ethtool_cmd
ecmd
=
{
ETHTOOL_GSET
,
SUPPORTED_10baseT_Half
|
SUPPORTED_TP
,
ADVERTISED_10baseT_Half
|
ADVERTISED_TP
,
SPEED_10
,
DUPLEX_HALF
,
PORT_TP
,
0
,
XCVR_INTERNAL
,
AUTONEG_DISABLE
,
1
,
1
};
if
(
copy_to_user
(
useraddr
,
&
ecmd
,
sizeof
(
ecmd
)))
return
-
EFAULT
;
return
0
;
}
else
{
return
-
EOPNOTSUPP
;
}
/* get link status */
case
ETHTOOL_GLINK
:
{
struct
ethtool_value
edata
=
{
ETHTOOL_GLINK
};
...
...
@@ -632,7 +736,8 @@ static int catc_open(struct net_device *netdev)
netif_start_queue
(
netdev
);
mod_timer
(
&
catc
->
timer
,
jiffies
+
STATS_UPDATE
);
if
(
!
catc
->
is_f5u011
)
mod_timer
(
&
catc
->
timer
,
jiffies
+
STATS_UPDATE
);
return
0
;
}
...
...
@@ -643,7 +748,8 @@ static int catc_stop(struct net_device *netdev)
netif_stop_queue
(
netdev
);
del_timer_sync
(
&
catc
->
timer
);
if
(
!
catc
->
is_f5u011
)
del_timer_sync
(
&
catc
->
timer
);
usb_unlink_urb
(
catc
->
rx_urb
);
usb_unlink_urb
(
catc
->
tx_urb
);
...
...
@@ -662,7 +768,7 @@ static void *catc_probe(struct usb_device *usbdev, unsigned int ifnum, const str
struct
net_device
*
netdev
;
struct
catc
*
catc
;
u8
broadcast
[
6
];
int
i
;
int
i
,
pktsz
;
if
(
usb_set_interface
(
usbdev
,
ifnum
,
1
))
{
err
(
"Can't set altsetting 1."
);
...
...
@@ -670,9 +776,16 @@ static void *catc_probe(struct usb_device *usbdev, unsigned int ifnum, const str
}
catc
=
kmalloc
(
sizeof
(
struct
catc
),
GFP_KERNEL
);
if
(
!
catc
)
return
NULL
;
memset
(
catc
,
0
,
sizeof
(
struct
catc
));
netdev
=
init_etherdev
(
0
,
0
);
if
(
!
netdev
)
{
kfree
(
catc
);
return
NULL
;
}
netdev
->
open
=
catc_open
;
netdev
->
hard_start_xmit
=
catc_hard_start_xmit
;
...
...
@@ -701,9 +814,26 @@ static void *catc_probe(struct usb_device *usbdev, unsigned int ifnum, const str
if
((
!
catc
->
ctrl_urb
)
||
(
!
catc
->
tx_urb
)
||
(
!
catc
->
rx_urb
)
||
(
!
catc
->
irq_urb
))
{
err
(
"No free urbs available."
);
if
(
catc
->
ctrl_urb
)
usb_free_urb
(
catc
->
ctrl_urb
);
if
(
catc
->
tx_urb
)
usb_free_urb
(
catc
->
tx_urb
);
if
(
catc
->
rx_urb
)
usb_free_urb
(
catc
->
rx_urb
);
if
(
catc
->
irq_urb
)
usb_free_urb
(
catc
->
irq_urb
);
kfree
(
netdev
);
kfree
(
catc
);
return
NULL
;
}
/* The F5U011 has the same vendor/product as the netmate but a device version of 0x130 */
if
(
usbdev
->
descriptor
.
idVendor
==
0x0423
&&
usbdev
->
descriptor
.
idProduct
==
0xa
&&
catc
->
usbdev
->
descriptor
.
bcdDevice
==
0x0130
)
{
dbg
(
"Testing for f5u011"
);
catc
->
is_f5u011
=
1
;
atomic_set
(
&
catc
->
recq_sz
,
0
);
pktsz
=
RX_PKT_SZ
;
}
else
{
pktsz
=
RX_MAX_BURST
*
(
PKT_SZ
+
2
);
}
FILL_CONTROL_URB
(
catc
->
ctrl_urb
,
usbdev
,
usb_sndctrlpipe
(
usbdev
,
0
),
NULL
,
NULL
,
0
,
catc_ctrl_done
,
catc
);
...
...
@@ -711,20 +841,21 @@ static void *catc_probe(struct usb_device *usbdev, unsigned int ifnum, const str
NULL
,
0
,
catc_tx_done
,
catc
);
FILL_BULK_URB
(
catc
->
rx_urb
,
usbdev
,
usb_rcvbulkpipe
(
usbdev
,
1
),
catc
->
rx_buf
,
RX_MAX_BURST
*
(
PKT_SZ
+
2
)
,
catc_rx_done
,
catc
);
catc
->
rx_buf
,
pktsz
,
catc_rx_done
,
catc
);
FILL_INT_URB
(
catc
->
irq_urb
,
usbdev
,
usb_rcvintpipe
(
usbdev
,
2
),
catc
->
irq_buf
,
2
,
catc_irq_done
,
catc
,
1
);
dbg
(
"Checking memory size
\n
"
);
i
=
0x12345678
;
catc_write_mem
(
catc
,
0x7a80
,
&
i
,
4
);
i
=
0x87654321
;
catc_write_mem
(
catc
,
0xfa80
,
&
i
,
4
);
catc_read_mem
(
catc
,
0x7a80
,
&
i
,
4
);
if
(
!
catc
->
is_f5u011
)
{
dbg
(
"Checking memory size
\n
"
);
switch
(
i
)
{
i
=
0x12345678
;
catc_write_mem
(
catc
,
0x7a80
,
&
i
,
4
);
i
=
0x87654321
;
catc_write_mem
(
catc
,
0xfa80
,
&
i
,
4
);
catc_read_mem
(
catc
,
0x7a80
,
&
i
,
4
);
switch
(
i
)
{
case
0x12345678
:
catc_set_reg
(
catc
,
TxBufCount
,
8
);
catc_set_reg
(
catc
,
RxBufCount
,
32
);
...
...
@@ -737,44 +868,52 @@ static void *catc_probe(struct usb_device *usbdev, unsigned int ifnum, const str
catc_set_reg
(
catc
,
RxBufCount
,
16
);
dbg
(
"32k Memory
\n
"
);
break
;
}
dbg
(
"Getting MAC from SEEROM."
);
catc_get_mac
(
catc
,
netdev
->
dev_addr
);
dbg
(
"Setting MAC into registers."
);
for
(
i
=
0
;
i
<
6
;
i
++
)
catc_set_reg
(
catc
,
StationAddr0
-
i
,
netdev
->
dev_addr
[
i
]);
dbg
(
"Filling the multicast list."
);
memset
(
broadcast
,
0xff
,
6
);
catc_multicast
(
broadcast
,
catc
->
multicast
);
catc_multicast
(
netdev
->
dev_addr
,
catc
->
multicast
);
catc_write_mem
(
catc
,
0xfa80
,
catc
->
multicast
,
64
);
dbg
(
"Clearing error counters."
);
for
(
i
=
0
;
i
<
8
;
i
++
)
catc_set_reg
(
catc
,
EthStats
+
i
,
0
);
catc
->
last_stats
=
jiffies
;
dbg
(
"Enabling."
);
catc_set_reg
(
catc
,
MaxBurst
,
RX_MAX_BURST
);
catc_set_reg
(
catc
,
OpModes
,
OpTxMerge
|
OpRxMerge
|
OpLenInclude
|
Op3MemWaits
);
catc_set_reg
(
catc
,
LEDCtrl
,
LEDLink
);
catc_set_reg
(
catc
,
RxUnit
,
RxEnable
|
RxPolarity
|
RxMultiCast
);
}
else
{
dbg
(
"Performing reset
\n
"
);
catc_reset
(
catc
);
catc_get_mac
(
catc
,
netdev
->
dev_addr
);
dbg
(
"Setting RX Mode"
);
catc
->
rxmode
[
0
]
=
RxEnable
|
RxPolarity
|
RxMultiCast
;
catc
->
rxmode
[
1
]
=
0
;
f5u011_rxmode
(
catc
,
catc
->
rxmode
);
}
dbg
(
"Getting MAC from SEEROM."
);
catc_get_mac
(
catc
,
netdev
->
dev_addr
);
dbg
(
"Setting MAC into registers."
);
for
(
i
=
0
;
i
<
6
;
i
++
)
catc_set_reg
(
catc
,
StationAddr0
-
i
,
netdev
->
dev_addr
[
i
]);
dbg
(
"Filling the multicast list."
);
memset
(
broadcast
,
0xff
,
8
);
catc_multicast
(
broadcast
,
catc
->
multicast
);
catc_multicast
(
netdev
->
dev_addr
,
catc
->
multicast
);
catc_write_mem
(
catc
,
0xfa80
,
catc
->
multicast
,
64
);
dbg
(
"Clearing error counters."
);
for
(
i
=
0
;
i
<
8
;
i
++
)
catc_set_reg
(
catc
,
EthStats
+
i
,
0
);
catc
->
last_stats
=
jiffies
;
dbg
(
"Enabling."
);
catc_set_reg
(
catc
,
MaxBurst
,
RX_MAX_BURST
);
catc_set_reg
(
catc
,
OpModes
,
OpTxMerge
|
OpRxMerge
|
OpLenInclude
|
Op3MemWaits
);
catc_set_reg
(
catc
,
LEDCtrl
,
LEDLink
);
catc_set_reg
(
catc
,
RxUnit
,
RxEnable
|
RxPolarity
|
RxMultiCast
);
dbg
(
"Init done."
);
printk
(
KERN_INFO
"%s: CATC EL1210A NetMate USB Ethernet at usb%d:%d.%d,
"
,
netdev
->
name
,
usbdev
->
bus
->
busnum
,
usbdev
->
devnum
,
ifnum
);
printk
(
KERN_INFO
"%s: %s USB Ethernet at usb%d:%d.%d, "
,
netdev
->
name
,
(
catc
->
is_f5u011
)
?
"Belkin F5U011"
:
"CATC EL1210A NetMate
"
,
usbdev
->
bus
->
busnum
,
usbdev
->
devnum
,
ifnum
);
for
(
i
=
0
;
i
<
5
;
i
++
)
printk
(
"%2.2x:"
,
netdev
->
dev_addr
[
i
]);
printk
(
"%2.2x.
\n
"
,
netdev
->
dev_addr
[
i
]);
return
catc
;
}
...
...
@@ -795,7 +934,7 @@ static void catc_disconnect(struct usb_device *usbdev, void *dev_ptr)
*/
static
struct
usb_device_id
catc_id_table
[]
=
{
{
USB_DEVICE
(
0x0423
,
0xa
)
},
/* CATC Netmate */
{
USB_DEVICE
(
0x0423
,
0xa
)
},
/* CATC Netmate
, Belkin F5U011
*/
{
USB_DEVICE
(
0x0423
,
0xc
)
},
/* CATC Netmate II, Belkin F5U111 */
{
USB_DEVICE
(
0x08d1
,
0x1
)
},
/* smartBridges smartNIC */
{
}
...
...
drivers/usb/hid-core.c
View file @
20f2ef0b
...
...
@@ -110,10 +110,11 @@ static struct hid_field *hid_register_field(struct hid_report *report, unsigned
memset
(
field
,
0
,
sizeof
(
struct
hid_field
)
+
usages
*
sizeof
(
struct
hid_usage
)
+
values
*
sizeof
(
unsigned
));
report
->
field
[
report
->
maxfield
++
]
=
field
;
report
->
field
[
report
->
maxfield
]
=
field
;
field
->
usage
=
(
struct
hid_usage
*
)(
field
+
1
);
field
->
value
=
(
unsigned
*
)(
field
->
usage
+
usages
);
field
->
report
=
report
;
field
->
index
=
report
->
maxfield
++
;
return
field
;
}
...
...
@@ -741,8 +742,20 @@ static void hid_process_event(struct hid_device *hid, struct hid_field *field, s
if
(
hid
->
claimed
&
HID_CLAIMED_INPUT
)
hidinput_hid_event
(
hid
,
field
,
usage
,
value
);
#ifdef CONFIG_USB_HIDDEV
if
(
hid
->
claimed
&
HID_CLAIMED_HIDDEV
)
hiddev_hid_event
(
hid
,
usage
->
hid
,
value
);
if
(
hid
->
claimed
&
HID_CLAIMED_HIDDEV
)
{
struct
hiddev_usage_ref
uref
;
unsigned
type
=
field
->
report_type
;
uref
.
report_type
=
(
type
==
HID_INPUT_REPORT
)
?
HID_REPORT_TYPE_INPUT
:
((
type
==
HID_OUTPUT_REPORT
)
?
HID_REPORT_TYPE_OUTPUT
:
((
type
==
HID_FEATURE_REPORT
)
?
HID_REPORT_TYPE_FEATURE
:
0
));
uref
.
report_id
=
field
->
report
->
id
;
uref
.
field_index
=
field
->
index
;
uref
.
usage_index
=
(
usage
-
field
->
usage
);
uref
.
usage_code
=
usage
->
hid
;
uref
.
value
=
value
;
hiddev_hid_event
(
hid
,
&
uref
);
}
#endif
}
...
...
@@ -839,6 +852,21 @@ static int hid_input_report(int type, struct urb *urb)
return
-
1
;
}
#ifdef CONFIG_USB_HIDDEV
/* Notify listeners that a report has been received */
if
(
hid
->
claimed
&
HID_CLAIMED_HIDDEV
)
{
struct
hiddev_usage_ref
uref
;
memset
(
&
uref
,
0
,
sizeof
(
uref
));
uref
.
report_type
=
(
type
==
HID_INPUT_REPORT
)
?
HID_REPORT_TYPE_INPUT
:
((
type
==
HID_OUTPUT_REPORT
)
?
HID_REPORT_TYPE_OUTPUT
:
((
type
==
HID_FEATURE_REPORT
)
?
HID_REPORT_TYPE_FEATURE
:
0
));
uref
.
report_id
=
report
->
id
;
uref
.
field_index
=
HID_FIELD_INDEX_NONE
;
hiddev_hid_event
(
hid
,
&
uref
);
}
#endif
size
=
((
report
->
size
-
1
)
>>
3
)
+
1
;
if
(
len
<
size
)
{
...
...
@@ -1096,6 +1124,9 @@ void hid_submit_report(struct hid_device *hid, struct hid_report *report, unsign
int
head
;
unsigned
long
flags
;
if
((
hid
->
quirks
&
HID_QUIRK_NOGET
)
&&
dir
==
USB_DIR_IN
)
return
;
if
(
hid
->
urbout
&&
dir
==
USB_DIR_OUT
&&
report
->
type
==
HID_OUTPUT_REPORT
)
{
spin_lock_irqsave
(
&
hid
->
outlock
,
flags
);
...
...
@@ -1238,18 +1269,27 @@ void hid_init_reports(struct hid_device *hid)
#define USB_DEVICE_ID_POWERMATE 0x0410
#define USB_DEVICE_ID_SOUNDKNOB 0x04AA
#define USB_VENDOR_ID_ATEN 0x0557
#define USB_DEVICE_ID_ATEN_UC100KM 0x2004
#define USB_DEVICE_ID_ATEN_CS124U 0x2202
#define USB_DEVICE_ID_ATEN_2PORTKVM 0x2204
struct
hid_blacklist
{
__u16
idVendor
;
__u16
idProduct
;
unsigned
quirks
;
}
hid_blacklist
[]
=
{
{
USB_VENDOR_ID_WACOM
,
USB_DEVICE_ID_WACOM_GRAPHIRE
},
{
USB_VENDOR_ID_WACOM
,
USB_DEVICE_ID_WACOM_INTUOS
},
{
USB_VENDOR_ID_WACOM
,
USB_DEVICE_ID_WACOM_INTUOS
+
1
},
{
USB_VENDOR_ID_WACOM
,
USB_DEVICE_ID_WACOM_INTUOS
+
2
},
{
USB_VENDOR_ID_WACOM
,
USB_DEVICE_ID_WACOM_INTUOS
+
3
},
{
USB_VENDOR_ID_WACOM
,
USB_DEVICE_ID_WACOM_INTUOS
+
4
},
{
USB_VENDOR_ID_GRIFFIN
,
USB_DEVICE_ID_POWERMATE
},
{
USB_VENDOR_ID_GRIFFIN
,
USB_DEVICE_ID_SOUNDKNOB
},
{
USB_VENDOR_ID_WACOM
,
USB_DEVICE_ID_WACOM_GRAPHIRE
,
HID_QUIRK_IGNORE
},
{
USB_VENDOR_ID_WACOM
,
USB_DEVICE_ID_WACOM_INTUOS
,
HID_QUIRK_IGNORE
},
{
USB_VENDOR_ID_WACOM
,
USB_DEVICE_ID_WACOM_INTUOS
+
1
,
HID_QUIRK_IGNORE
},
{
USB_VENDOR_ID_WACOM
,
USB_DEVICE_ID_WACOM_INTUOS
+
2
,
HID_QUIRK_IGNORE
},
{
USB_VENDOR_ID_WACOM
,
USB_DEVICE_ID_WACOM_INTUOS
+
3
,
HID_QUIRK_IGNORE
},
{
USB_VENDOR_ID_WACOM
,
USB_DEVICE_ID_WACOM_INTUOS
+
4
,
HID_QUIRK_IGNORE
},
{
USB_VENDOR_ID_GRIFFIN
,
USB_DEVICE_ID_POWERMATE
,
HID_QUIRK_IGNORE
},
{
USB_VENDOR_ID_GRIFFIN
,
USB_DEVICE_ID_SOUNDKNOB
,
HID_QUIRK_IGNORE
},
{
USB_VENDOR_ID_ATEN
,
USB_DEVICE_ID_ATEN_UC100KM
,
HID_QUIRK_NOGET
},
{
USB_VENDOR_ID_ATEN
,
USB_DEVICE_ID_ATEN_CS124U
,
HID_QUIRK_NOGET
},
{
USB_VENDOR_ID_ATEN
,
USB_DEVICE_ID_ATEN_2PORTKVM
,
HID_QUIRK_NOGET
},
{
0
,
0
}
};
...
...
@@ -1258,13 +1298,17 @@ static struct hid_device *usb_hid_configure(struct usb_device *dev, int ifnum)
struct
usb_interface_descriptor
*
interface
=
dev
->
actconfig
->
interface
[
ifnum
].
altsetting
+
0
;
struct
hid_descriptor
*
hdesc
;
struct
hid_device
*
hid
;
unsigned
rsize
=
0
;
unsigned
quirks
=
0
,
rsize
=
0
;
char
*
buf
;
int
n
;
for
(
n
=
0
;
hid_blacklist
[
n
].
idVendor
;
n
++
)
if
((
hid_blacklist
[
n
].
idVendor
==
dev
->
descriptor
.
idVendor
)
&&
(
hid_blacklist
[
n
].
idProduct
==
dev
->
descriptor
.
idProduct
))
return
NULL
;
(
hid_blacklist
[
n
].
idProduct
==
dev
->
descriptor
.
idProduct
))
quirks
=
hid_blacklist
[
n
].
quirks
;
if
(
quirks
&
HID_QUIRK_IGNORE
)
return
NULL
;
if
(
usb_get_extra_descriptor
(
interface
,
HID_DT_HID
,
&
hdesc
)
&&
((
!
interface
->
bNumEndpoints
)
||
usb_get_extra_descriptor
(
&
interface
->
endpoint
[
0
],
HID_DT_HID
,
&
hdesc
)))
{
...
...
@@ -1302,6 +1346,8 @@ static struct hid_device *usb_hid_configure(struct usb_device *dev, int ifnum)
}
}
hid
->
quirks
=
quirks
;
for
(
n
=
0
;
n
<
interface
->
bNumEndpoints
;
n
++
)
{
struct
usb_endpoint_descriptor
*
endpoint
=
&
interface
->
endpoint
[
n
];
...
...
drivers/usb/hid.h
View file @
20f2ef0b
...
...
@@ -203,6 +203,8 @@ struct hid_item {
#define HID_QUIRK_INVERT 0x01
#define HID_QUIRK_NOTOUCH 0x02
#define HID_QUIRK_IGNORE 0x04
#define HID_QUIRK_NOGET 0x08
/*
* This is the global enviroment of the parser. This information is
...
...
@@ -276,6 +278,7 @@ struct hid_field {
__s32
unit_exponent
;
unsigned
unit
;
struct
hid_report
*
report
;
/* associated report */
unsigned
index
;
/* index into report->field[] */
};
#define HID_MAX_FIELDS 64
...
...
drivers/usb/hiddev.c
View file @
20f2ef0b
...
...
@@ -50,9 +50,10 @@ struct hiddev {
};
struct
hiddev_list
{
struct
hiddev_
event
buffer
[
HIDDEV_BUFFER_SIZE
];
struct
hiddev_
usage_ref
buffer
[
HIDDEV_BUFFER_SIZE
];
int
head
;
int
tail
;
unsigned
flags
;
struct
fasync_struct
*
fasync
;
struct
hiddev
*
hiddev
;
struct
hiddev_list
*
next
;
...
...
@@ -146,17 +147,19 @@ hiddev_lookup_usage(struct hid_device *hid, struct hiddev_usage_ref *uref)
* This is where hid.c calls into hiddev to pass an event that occurred over
* the interrupt pipe
*/
void
hiddev_hid_event
(
struct
hid_device
*
hid
,
unsigned
int
usage
,
int
value
)
void
hiddev_hid_event
(
struct
hid_device
*
hid
,
struct
hiddev_usage_ref
*
uref
)
{
struct
hiddev
*
hiddev
=
hid
->
hiddev
;
struct
hiddev_list
*
list
=
hiddev
->
list
;
while
(
list
)
{
list
->
buffer
[
list
->
head
].
hid
=
usage
;
list
->
buffer
[
list
->
head
].
value
=
value
;
list
->
head
=
(
list
->
head
+
1
)
&
(
HIDDEV_BUFFER_SIZE
-
1
);
kill_fasync
(
&
list
->
fasync
,
SIGIO
,
POLL_IN
);
if
(
uref
->
field_index
!=
HID_FIELD_INDEX_NONE
||
(
list
->
flags
&
HIDDEV_FLAG_REPORT
)
!=
0
)
{
list
->
buffer
[
list
->
head
]
=
*
uref
;
list
->
head
=
(
list
->
head
+
1
)
&
(
HIDDEV_BUFFER_SIZE
-
1
);
kill_fasync
(
&
list
->
fasync
,
SIGIO
,
POLL_IN
);
}
list
=
list
->
next
;
}
...
...
@@ -257,43 +260,67 @@ static ssize_t hiddev_read(struct file * file, char * buffer, size_t count,
{
DECLARE_WAITQUEUE
(
wait
,
current
);
struct
hiddev_list
*
list
=
file
->
private_data
;
int
event_size
;
int
retval
=
0
;
if
(
list
->
head
==
list
->
tail
)
{
add_wait_queue
(
&
list
->
hiddev
->
wait
,
&
wait
);
set_current_state
(
TASK_INTERRUPTIBLE
);
event_size
=
((
list
->
flags
&
HIDDEV_FLAG_UREF
)
!=
0
)
?
sizeof
(
struct
hiddev_usage_ref
)
:
sizeof
(
struct
hiddev_event
);
while
(
list
->
head
==
list
->
tail
)
{
if
(
count
<
event_size
)
return
0
;
if
(
file
->
f_flags
&
O_NONBLOCK
)
{
retval
=
-
EAGAIN
;
break
;
}
if
(
signal_pending
(
current
))
{
retval
=
-
ERESTARTSYS
;
break
;
}
if
(
!
list
->
hiddev
->
exist
)
{
retval
=
-
EIO
;
break
;
while
(
retval
==
0
)
{
if
(
list
->
head
==
list
->
tail
)
{
add_wait_queue
(
&
list
->
hiddev
->
wait
,
&
wait
);
set_current_state
(
TASK_INTERRUPTIBLE
);
while
(
list
->
head
==
list
->
tail
)
{
if
(
file
->
f_flags
&
O_NONBLOCK
)
{
retval
=
-
EAGAIN
;
break
;
}
if
(
signal_pending
(
current
))
{
retval
=
-
ERESTARTSYS
;
break
;
}
if
(
!
list
->
hiddev
->
exist
)
{
retval
=
-
EIO
;
break
;
}
schedule
();
}
schedule
();
set_current_state
(
TASK_RUNNING
);
remove_wait_queue
(
&
list
->
hiddev
->
wait
,
&
wait
);
}
set_current_state
(
TASK_RUNNING
);
remove_wait_queue
(
&
list
->
hiddev
->
wait
,
&
wait
);
}
if
(
retval
)
return
retval
;
if
(
retval
)
return
retval
;
while
(
list
->
head
!=
list
->
tail
&&
retval
+
event_size
<=
count
)
{
if
((
list
->
flags
&
HIDDEV_FLAG_UREF
)
==
0
)
{
if
(
list
->
buffer
[
list
->
tail
].
field_index
!=
HID_FIELD_INDEX_NONE
)
{
struct
hiddev_event
event
;
event
.
hid
=
list
->
buffer
[
list
->
tail
].
usage_code
;
event
.
value
=
list
->
buffer
[
list
->
tail
].
value
;
if
(
copy_to_user
(
buffer
+
retval
,
&
event
,
sizeof
(
struct
hiddev_event
)))
return
-
EFAULT
;
retval
+=
sizeof
(
struct
hiddev_event
);
}
}
else
{
if
(
list
->
buffer
[
list
->
tail
].
field_index
!=
HID_FIELD_INDEX_NONE
||
(
list
->
flags
&
HIDDEV_FLAG_REPORT
)
!=
0
)
{
if
(
copy_to_user
(
buffer
+
retval
,
list
->
buffer
+
list
->
tail
,
sizeof
(
struct
hiddev_usage_ref
)))
return
-
EFAULT
;
retval
+=
sizeof
(
struct
hiddev_usage_ref
);
}
}
list
->
tail
=
(
list
->
tail
+
1
)
&
(
HIDDEV_BUFFER_SIZE
-
1
);
}
while
(
list
->
head
!=
list
->
tail
&&
retval
+
sizeof
(
struct
hiddev_event
)
<=
count
)
{
if
(
copy_to_user
(
buffer
+
retval
,
list
->
buffer
+
list
->
tail
,
sizeof
(
struct
hiddev_event
)))
return
-
EFAULT
;
list
->
tail
=
(
list
->
tail
+
1
)
&
(
HIDDEV_BUFFER_SIZE
-
1
);
retval
+=
sizeof
(
struct
hiddev_event
);
}
return
retval
;
...
...
@@ -358,6 +385,25 @@ static int hiddev_ioctl(struct inode *inode, struct file *file,
return
copy_to_user
((
void
*
)
arg
,
&
dinfo
,
sizeof
(
dinfo
));
}
case
HIDIOCGFLAG
:
return
put_user
(
list
->
flags
,
(
int
*
)
arg
);
case
HIDIOCSFLAG
:
{
int
newflags
;
if
(
get_user
(
newflags
,
(
int
*
)
arg
))
return
-
EFAULT
;
if
((
newflags
&
~
HIDDEV_FLAGS
)
!=
0
||
((
newflags
&
HIDDEV_FLAG_REPORT
)
!=
0
&&
(
newflags
&
HIDDEV_FLAG_UREF
)
==
0
))
return
-
EINVAL
;
list
->
flags
=
newflags
;
return
0
;
}
case
HIDIOCGSTRING
:
{
int
idx
,
len
;
...
...
drivers/usb/printer.c
View file @
20f2ef0b
/*
* printer.c Version 0.
8
* printer.c Version 0.
12
*
* Copyright (c) 1999 Michael Gee <michael@linuxspecific.com>
* Copyright (c) 1999 Pavel Machek <pavel@suse.cz>
* Copyright (c) 2000 Randy Dunlap <randy.dunlap@intel.com>
* Copyright (c) 2000 Vojtech Pavlik <vojtech@suse.cz>
# Copyright (c) 2001 Pete Zaitcev <zaitcev@redhat.com>
# Copyright (c) 2001 David Paschal <paschal@rcsis.com>
*
* USB Printer Device Class driver for USB printers and printer cables
*
...
...
@@ -17,10 +19,12 @@
* v0.4 - fixes in unidirectional mode
* v0.5 - add DEVICE_ID string support
* v0.6 - never time out
* v0.7 - fixed bulk-IN read and poll (David Paschal
, paschal@rcsis.com
)
* v0.7 - fixed bulk-IN read and poll (David Paschal)
* v0.8 - add devfs support
* v0.9 - fix unplug-while-open paths
* v0.10- remove sleep_on, fix error on oom (oliver@neukum.org)
* v0.11 - add proto_bias option (Pete Zaitcev)
* v0.12 - add hpoj.sourceforge.net ioctls (David Paschal)
*/
/*
...
...
@@ -55,16 +59,36 @@
/*
* Version Information
*/
#define DRIVER_VERSION "v0.1
0
"
#define DRIVER_AUTHOR "Michael Gee, Pavel Machek, Vojtech Pavlik, Randy Dunlap"
#define DRIVER_VERSION "v0.1
2
"
#define DRIVER_AUTHOR "Michael Gee, Pavel Machek, Vojtech Pavlik, Randy Dunlap
, Pete Zaitcev, David Paschal
"
#define DRIVER_DESC "USB Printer Device Class driver"
#define USBLP_BUF_SIZE 8192
#define DEVICE_ID_SIZE 1024
#define IOCNR_GET_DEVICE_ID 1
#define LPIOC_GET_DEVICE_ID(len) _IOC(_IOC_READ, 'P', IOCNR_GET_DEVICE_ID, len)
/* get device_id string */
/* ioctls: */
#define LPGETSTATUS 0x060b
/* same as in drivers/char/lp.c */
#define IOCNR_GET_DEVICE_ID 1
#define IOCNR_GET_PROTOCOLS 2
#define IOCNR_SET_PROTOCOL 3
#define IOCNR_HP_SET_CHANNEL 4
#define IOCNR_GET_BUS_ADDRESS 5
#define IOCNR_GET_VID_PID 6
/* Get device_id string: */
#define LPIOC_GET_DEVICE_ID(len) _IOC(_IOC_READ, 'P', IOCNR_GET_DEVICE_ID, len)
/* The following ioctls were added for http://hpoj.sourceforge.net: */
/* Get two-int array:
* [0]=current protocol (1=7/1/1, 2=7/1/2, 3=7/1/3),
* [1]=supported protocol mask (mask&(1<<n)!=0 means 7/1/n supported): */
#define LPIOC_GET_PROTOCOLS(len) _IOC(_IOC_READ, 'P', IOCNR_GET_PROTOCOLS, len)
/* Set protocol (arg: 1=7/1/1, 2=7/1/2, 3=7/1/3): */
#define LPIOC_SET_PROTOCOL _IOC(_IOC_WRITE, 'P', IOCNR_SET_PROTOCOL, 0)
/* Set channel number (HP Vendor-specific command): */
#define LPIOC_HP_SET_CHANNEL _IOC(_IOC_WRITE, 'P', IOCNR_HP_SET_CHANNEL, 0)
/* Get two-int array: [0]=bus number, [1]=device address: */
#define LPIOC_GET_BUS_ADDRESS(len) _IOC(_IOC_READ, 'P', IOCNR_GET_BUS_ADDRESS, len)
/* Get two-int array: [0]=vendor ID, [1]=product ID: */
#define LPIOC_GET_VID_PID(len) _IOC(_IOC_READ, 'P', IOCNR_GET_VID_PID, len)
/*
* A DEVICE_ID string may include the printer's serial number.
...
...
@@ -78,26 +102,40 @@ MFG:HEWLETT-PACKARD;MDL:DESKJET 970C;CMD:MLC,PCL,PML;CLASS:PRINTER;DESCRIPTION:H
* USB Printer Requests
*/
#define USBLP_REQ_GET_ID 0x00
#define USBLP_REQ_GET_STATUS 0x01
#define USBLP_REQ_RESET 0x02
#define USBLP_REQ_GET_ID 0x00
#define USBLP_REQ_GET_STATUS 0x01
#define USBLP_REQ_RESET 0x02
#define USBLP_REQ_HP_CHANNEL_CHANGE_REQUEST 0x00
/* HP Vendor-specific */
#define USBLP_MINORS 16
#define USBLP_MINOR_BASE 0
#define USBLP_WRITE_TIMEOUT (5*HZ)
/* 5 seconds */
#define USBLP_FIRST_PROTOCOL 1
#define USBLP_LAST_PROTOCOL 3
#define USBLP_MAX_PROTOCOLS (USBLP_LAST_PROTOCOL+1)
struct
usblp
{
struct
usb_device
*
dev
;
/* USB device */
devfs_handle_t
devfs
;
/* devfs device */
struct
semaphore
sem
;
/* locks this struct, especially "dev" */
char
*
buf
;
/* writeurb->transfer_buffer */
struct
urb
*
readurb
,
*
writeurb
;
/* The urbs */
wait_queue_head_t
wait
;
/* Zzzzz ... */
int
readcount
;
/* Counter for reads */
int
ifnum
;
/* Interface number */
/* Alternate-setting numbers and endpoints for each protocol
* (7/1/{index=1,2,3}) that the device supports: */
struct
{
int
alt_setting
;
struct
usb_endpoint_descriptor
*
epwrite
;
struct
usb_endpoint_descriptor
*
epread
;
}
protocol
[
USBLP_MAX_PROTOCOLS
];
int
current_protocol
;
int
minor
;
/* minor number of device */
int
wcomplete
;
/* writing is completed */
int
rcomplete
;
/* reading is completed */
int
rcomplete
;
/* reading is completed */
unsigned
int
quirks
;
/* quirks flags */
unsigned
char
used
;
/* True if open */
unsigned
char
bidir
;
/* interface is bidirectional */
...
...
@@ -105,6 +143,35 @@ struct usblp {
/* first 2 bytes are (big-endian) length */
};
#ifdef DEBUG
static
void
usblp_dump
(
struct
usblp
*
usblp
)
{
int
p
;
dbg
(
"usblp=0x%p"
,
usblp
);
dbg
(
"dev=0x%p"
,
usblp
->
dev
);
dbg
(
"devfs=0x%p"
,
usblp
->
devfs
);
dbg
(
"buf=0x%p"
,
usblp
->
buf
);
dbg
(
"readcount=%d"
,
usblp
->
readcount
);
dbg
(
"ifnum=%d"
,
usblp
->
ifnum
);
for
(
p
=
USBLP_FIRST_PROTOCOL
;
p
<=
USBLP_LAST_PROTOCOL
;
p
++
)
{
dbg
(
"protocol[%d].alt_setting=%d"
,
p
,
usblp
->
protocol
[
p
].
alt_setting
);
dbg
(
"protocol[%d].epwrite=%p"
,
p
,
usblp
->
protocol
[
p
].
epwrite
);
dbg
(
"protocol[%d].epread=%p"
,
p
,
usblp
->
protocol
[
p
].
epread
);
}
dbg
(
"current_protocol=%d"
,
usblp
->
current_protocol
);
dbg
(
"minor=%d"
,
usblp
->
minor
);
dbg
(
"wcomplete=%d"
,
usblp
->
wcomplete
);
dbg
(
"rcomplete=%d"
,
usblp
->
rcomplete
);
dbg
(
"quirks=%d"
,
usblp
->
quirks
);
dbg
(
"used=%d"
,
usblp
->
used
);
dbg
(
"bidir=%d"
,
usblp
->
bidir
);
dbg
(
"device_id_string=
\"
%s
\"
"
,
usblp
->
device_id_string
?
usblp
->
device_id_string
+
2
:
(
unsigned
char
*
)
"(null)"
);
}
#endif
extern
devfs_handle_t
usb_devfs_handle
;
/* /dev/usb dir. */
static
struct
usblp
*
usblp_table
[
USBLP_MINORS
];
...
...
@@ -126,29 +193,45 @@ static struct quirk_printer_struct quirk_printers[] = {
{
0x03f0
,
0x0204
,
USBLP_QUIRK_BIDIR
},
/* HP DeskJet 815C */
{
0x03f0
,
0x0304
,
USBLP_QUIRK_BIDIR
},
/* HP DeskJet 810C/812C */
{
0x03f0
,
0x0404
,
USBLP_QUIRK_BIDIR
},
/* HP DeskJet 830C */
{
0x0409
,
0xefbe
,
USBLP_QUIRK_BIDIR
},
/* NEC Picty900 (HP OEM) */
{
0
,
0
}
};
static
int
usblp_select_alts
(
struct
usblp
*
usblp
);
static
int
usblp_set_protocol
(
struct
usblp
*
usblp
,
int
protocol
);
static
int
usblp_cache_device_id_string
(
struct
usblp
*
usblp
);
/*
* Functions for usblp control messages.
*/
static
int
usblp_ctrl_msg
(
struct
usblp
*
usblp
,
int
request
,
int
dir
,
int
recip
,
int
value
,
void
*
buf
,
int
len
)
static
int
usblp_ctrl_msg
(
struct
usblp
*
usblp
,
int
request
,
int
type
,
int
dir
,
int
recip
,
int
value
,
void
*
buf
,
int
len
)
{
int
retval
=
usb_control_msg
(
usblp
->
dev
,
dir
?
usb_rcvctrlpipe
(
usblp
->
dev
,
0
)
:
usb_sndctrlpipe
(
usblp
->
dev
,
0
),
request
,
USB_TYPE_CLASS
|
dir
|
recip
,
value
,
usblp
->
ifnum
,
buf
,
len
,
HZ
*
5
);
request
,
type
|
dir
|
recip
,
value
,
usblp
->
ifnum
,
buf
,
len
,
USBLP_WRITE_TIMEOUT
);
dbg
(
"usblp_control_msg: rq: 0x%02x dir: %d recip: %d value: %d len: %#x result: %d"
,
request
,
!!
dir
,
recip
,
value
,
len
,
retval
);
return
retval
<
0
?
retval
:
0
;
}
#define usblp_read_status(usblp, status)\
usblp_ctrl_msg(usblp, USBLP_REQ_GET_STATUS, USB_DIR_IN, USB_RECIP_INTERFACE, 0, status, 1)
usblp_ctrl_msg(usblp, USBLP_REQ_GET_STATUS, USB_
TYPE_CLASS, USB_
DIR_IN, USB_RECIP_INTERFACE, 0, status, 1)
#define usblp_get_id(usblp, config, id, maxlen)\
usblp_ctrl_msg(usblp, USBLP_REQ_GET_ID, USB_DIR_IN, USB_RECIP_INTERFACE, config, id, maxlen)
usblp_ctrl_msg(usblp, USBLP_REQ_GET_ID, USB_
TYPE_CLASS, USB_
DIR_IN, USB_RECIP_INTERFACE, config, id, maxlen)
#define usblp_reset(usblp)\
usblp_ctrl_msg(usblp, USBLP_REQ_RESET, USB_DIR_OUT, USB_RECIP_OTHER, 0, NULL, 0)
usblp_ctrl_msg(usblp, USBLP_REQ_RESET, USB_TYPE_CLASS, USB_DIR_OUT, USB_RECIP_OTHER, 0, NULL, 0)
#define usblp_hp_channel_change_request(usblp, channel, buffer) \
usblp_ctrl_msg(usblp, USBLP_REQ_HP_CHANNEL_CHANGE_REQUEST, USB_TYPE_VENDOR, USB_DIR_IN, USB_RECIP_INTERFACE, channel, buffer, 1)
/*
* See the description for usblp_select_alts() below for the usage
* explanation. Look into your /proc/bus/usb/devices and dmesg in
* case of any trouble.
*/
static
int
proto_bias
=
-
1
;
/*
* URB callback.
...
...
@@ -276,7 +359,7 @@ static void usblp_cleanup (struct usblp *usblp)
{
devfs_unregister
(
usblp
->
devfs
);
usblp_table
[
usblp
->
minor
]
=
NULL
;
info
(
"usblp%d: removed"
,
usblp
->
minor
);
info
(
"usblp%d: removed"
,
usblp
->
minor
);
kfree
(
usblp
->
writeurb
->
transfer_buffer
);
kfree
(
usblp
->
device_id_string
);
...
...
@@ -285,6 +368,13 @@ static void usblp_cleanup (struct usblp *usblp)
kfree
(
usblp
);
}
static
void
usblp_unlink_urbs
(
struct
usblp
*
usblp
)
{
usb_unlink_urb
(
usblp
->
writeurb
);
if
(
usblp
->
bidir
)
usb_unlink_urb
(
usblp
->
readurb
);
}
static
int
usblp_release
(
struct
inode
*
inode
,
struct
file
*
file
)
{
struct
usblp
*
usblp
=
file
->
private_data
;
...
...
@@ -293,9 +383,7 @@ static int usblp_release(struct inode *inode, struct file *file)
lock_kernel
();
usblp
->
used
=
0
;
if
(
usblp
->
dev
)
{
if
(
usblp
->
bidir
)
usb_unlink_urb
(
usblp
->
readurb
);
usb_unlink_urb
(
usblp
->
writeurb
);
usblp_unlink_urbs
(
usblp
);
up
(
&
usblp
->
sem
);
}
else
/* finish cleanup from disconnect */
usblp_cleanup
(
usblp
);
...
...
@@ -315,8 +403,9 @@ static unsigned int usblp_poll(struct file *file, struct poll_table_struct *wait
static
int
usblp_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
struct
usblp
*
usblp
=
file
->
private_data
;
int
length
,
err
;
unsigned
char
status
;
int
length
,
err
,
i
;
unsigned
char
status
,
newChannel
;
int
twoints
[
2
];
int
retval
=
0
;
down
(
&
usblp
->
sem
);
...
...
@@ -335,32 +424,128 @@ static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
goto
done
;
}
err
=
usblp_get_id
(
usblp
,
0
,
usblp
->
device_id_string
,
DEVICE_ID_SIZE
-
1
);
length
=
usblp_cache_device_id_string
(
usblp
);
if
(
length
<
0
)
{
retval
=
length
;
goto
done
;
}
if
(
length
>
_IOC_SIZE
(
cmd
))
length
=
_IOC_SIZE
(
cmd
);
/* truncate */
if
(
copy_to_user
((
unsigned
char
*
)
arg
,
usblp
->
device_id_string
,
(
unsigned
long
)
length
))
{
retval
=
-
EFAULT
;
goto
done
;
}
break
;
case
IOCNR_GET_PROTOCOLS
:
if
(
_IOC_DIR
(
cmd
)
!=
_IOC_READ
||
_IOC_SIZE
(
cmd
)
<
sizeof
(
twoints
))
{
retval
=
-
EINVAL
;
goto
done
;
}
twoints
[
0
]
=
usblp
->
current_protocol
;
twoints
[
1
]
=
0
;
for
(
i
=
USBLP_FIRST_PROTOCOL
;
i
<=
USBLP_LAST_PROTOCOL
;
i
++
)
{
if
(
usblp
->
protocol
[
i
].
alt_setting
>=
0
)
twoints
[
1
]
|=
(
1
<<
i
);
}
if
(
copy_to_user
((
unsigned
char
*
)
arg
,
(
unsigned
char
*
)
twoints
,
sizeof
(
twoints
)))
{
retval
=
-
EFAULT
;
goto
done
;
}
break
;
case
IOCNR_SET_PROTOCOL
:
if
(
_IOC_DIR
(
cmd
)
!=
_IOC_WRITE
)
{
retval
=
-
EINVAL
;
goto
done
;
}
#ifdef DEBUG
if
(
arg
==
-
10
)
{
usblp_dump
(
usblp
);
break
;
}
#endif
usblp_unlink_urbs
(
usblp
);
retval
=
usblp_set_protocol
(
usblp
,
arg
);
if
(
retval
<
0
)
{
usblp_set_protocol
(
usblp
,
usblp
->
current_protocol
);
}
break
;
case
IOCNR_HP_SET_CHANNEL
:
if
(
_IOC_DIR
(
cmd
)
!=
_IOC_WRITE
||
usblp
->
dev
->
descriptor
.
idVendor
!=
0x03F0
||
usblp
->
quirks
&
USBLP_QUIRK_BIDIR
)
{
retval
=
-
EINVAL
;
goto
done
;
}
err
=
usblp_hp_channel_change_request
(
usblp
,
arg
,
&
newChannel
);
if
(
err
<
0
)
{
dbg
(
"usblp%d: error = %d reading IEEE-1284 Device ID string"
,
err
(
"usblp%d: error = %d setting "
"HP channel"
,
usblp
->
minor
,
err
);
usblp
->
device_id_string
[
0
]
=
usblp
->
device_id_string
[
1
]
=
'\0'
;
retval
=
-
EIO
;
goto
done
;
}
length
=
(
usblp
->
device_id_string
[
0
]
<<
8
)
+
usblp
->
device_id_string
[
1
];
/* big-endian */
if
(
length
<
DEVICE_ID_SIZE
)
usblp
->
device_id_string
[
length
]
=
'\0'
;
else
usblp
->
device_id_string
[
DEVICE_ID_SIZE
-
1
]
=
'\0'
;
dbg
(
"usblp%d requested/got HP channel %ld/%d"
,
usblp
->
minor
,
arg
,
newChannel
);
break
;
dbg
(
"usblp%d Device ID string [%d/max %d]='%s'"
,
usblp
->
minor
,
length
,
_IOC_SIZE
(
cmd
),
&
usblp
->
device_id_string
[
2
]);
case
IOCNR_GET_BUS_ADDRESS
:
if
(
_IOC_DIR
(
cmd
)
!=
_IOC_READ
||
_IOC_SIZE
(
cmd
)
<
sizeof
(
twoints
))
{
retval
=
-
EINVAL
;
goto
done
;
}
if
(
length
>
_IOC_SIZE
(
cmd
))
length
=
_IOC_SIZE
(
cmd
);
/* truncate */
twoints
[
0
]
=
usblp
->
dev
->
bus
->
busnum
;
twoints
[
1
]
=
usblp
->
dev
->
devnum
;
if
(
copy_to_user
((
unsigned
char
*
)
arg
,
(
unsigned
char
*
)
twoints
,
sizeof
(
twoints
)))
{
retval
=
-
EFAULT
;
goto
done
;
}
if
(
copy_to_user
((
unsigned
char
*
)
arg
,
usblp
->
device_id_string
,
(
unsigned
long
)
length
))
{
dbg
(
"usblp%d is bus=%d, device=%d"
,
usblp
->
minor
,
twoints
[
0
],
twoints
[
1
]);
break
;
case
IOCNR_GET_VID_PID
:
if
(
_IOC_DIR
(
cmd
)
!=
_IOC_READ
||
_IOC_SIZE
(
cmd
)
<
sizeof
(
twoints
))
{
retval
=
-
EINVAL
;
goto
done
;
}
twoints
[
0
]
=
usblp
->
dev
->
descriptor
.
idVendor
;
twoints
[
1
]
=
usblp
->
dev
->
descriptor
.
idProduct
;
if
(
copy_to_user
((
unsigned
char
*
)
arg
,
(
unsigned
char
*
)
twoints
,
sizeof
(
twoints
)))
{
retval
=
-
EFAULT
;
goto
done
;
}
dbg
(
"usblp%d is VID=0x%4.4X, PID=0x%4.4X"
,
usblp
->
minor
,
twoints
[
0
],
twoints
[
1
]);
break
;
default:
...
...
@@ -593,155 +778,268 @@ static struct file_operations usblp_fops = {
static
void
*
usblp_probe
(
struct
usb_device
*
dev
,
unsigned
int
ifnum
,
const
struct
usb_device_id
*
id
)
{
struct
usb_interface_descriptor
*
interface
;
struct
usb_endpoint_descriptor
*
epread
,
*
epwrite
;
struct
usblp
*
usblp
;
int
minor
,
i
,
bidir
=
0
,
quirks
;
int
alts
=
dev
->
actconfig
->
interface
[
ifnum
].
act_altsetting
;
int
length
,
err
;
char
*
buf
;
struct
usblp
*
usblp
=
0
;
int
protocol
;
char
name
[
6
];
/* If a bidirectional interface exists, use it. */
for
(
i
=
0
;
i
<
dev
->
actconfig
->
interface
[
ifnum
].
num_altsetting
;
i
++
)
{
interface
=
&
dev
->
actconfig
->
interface
[
ifnum
].
altsetting
[
i
];
if
(
interface
->
bInterfaceClass
!=
7
||
interface
->
bInterfaceSubClass
!=
1
||
interface
->
bInterfaceProtocol
<
1
||
interface
->
bInterfaceProtocol
>
3
||
(
interface
->
bInterfaceProtocol
>
1
&&
interface
->
bNumEndpoints
<
2
))
continue
;
if
(
interface
->
bInterfaceProtocol
>
1
)
{
bidir
=
1
;
alts
=
i
;
break
;
}
}
interface
=
&
dev
->
actconfig
->
interface
[
ifnum
].
altsetting
[
alts
];
if
(
usb_set_interface
(
dev
,
ifnum
,
alts
))
err
(
"can't set desired altsetting %d on interface %d"
,
alts
,
ifnum
);
epwrite
=
interface
->
endpoint
+
0
;
epread
=
bidir
?
interface
->
endpoint
+
1
:
NULL
;
if
((
epwrite
->
bEndpointAddress
&
0x80
)
==
0x80
)
{
if
(
interface
->
bNumEndpoints
==
1
)
return
NULL
;
epwrite
=
interface
->
endpoint
+
1
;
epread
=
bidir
?
interface
->
endpoint
+
0
:
NULL
;
}
if
((
epwrite
->
bEndpointAddress
&
0x80
)
==
0x80
)
return
NULL
;
if
(
bidir
&&
(
epread
->
bEndpointAddress
&
0x80
)
!=
0x80
)
return
NULL
;
for
(
minor
=
0
;
minor
<
USBLP_MINORS
&&
usblp_table
[
minor
];
minor
++
);
if
(
usblp_table
[
minor
])
{
err
(
"no more free usblp devices"
);
return
NULL
;
}
/* Malloc and start initializing usblp structure so we can use it
* directly. */
if
(
!
(
usblp
=
kmalloc
(
sizeof
(
struct
usblp
),
GFP_KERNEL
)))
{
err
(
"out of memory"
);
return
NULL
;
err
(
"out of memory
for usblp
"
);
goto
abort
;
}
memset
(
usblp
,
0
,
sizeof
(
struct
usblp
));
init_MUTEX
(
&
usblp
->
sem
);
/* lookup quirks for this printer */
quirks
=
usblp_quirks
(
dev
->
descriptor
.
idVendor
,
dev
->
descriptor
.
idProduct
);
if
(
bidir
&&
(
quirks
&
USBLP_QUIRK_BIDIR
))
{
bidir
=
0
;
epread
=
NULL
;
info
(
"Disabling reads from problem bidirectional printer on usblp%d"
,
minor
);
}
usblp
->
dev
=
dev
;
init_MUTEX
(
&
usblp
->
sem
);
init_waitqueue_head
(
&
usblp
->
wait
);
usblp
->
ifnum
=
ifnum
;
usblp
->
minor
=
minor
;
usblp
->
bidir
=
bidir
;
usblp
->
quirks
=
quirks
;
init_waitqueue_head
(
&
usblp
->
wait
);
/* Look for a free usblp_table entry. */
while
(
usblp_table
[
usblp
->
minor
])
{
usblp
->
minor
++
;
if
(
usblp
->
minor
>=
USBLP_MINORS
)
{
err
(
"no more free usblp devices"
);
goto
abort
;
}
}
usblp
->
writeurb
=
usb_alloc_urb
(
0
,
GFP_KERNEL
);
if
(
!
usblp
->
writeurb
)
{
err
(
"out of memory"
);
kfree
(
usblp
);
return
NULL
;
goto
abort
;
}
usblp
->
readurb
=
usb_alloc_urb
(
0
,
GFP_KERNEL
);
if
(
!
usblp
->
readurb
)
{
err
(
"out of memory"
);
usb_free_urb
(
usblp
->
writeurb
);
kfree
(
usblp
);
return
NULL
;
goto
abort
;
}
if
(
!
(
buf
=
kmalloc
(
USBLP_BUF_SIZE
*
(
bidir
?
2
:
1
),
GFP_KERNEL
)))
{
err
(
"out of memory"
);
usb_free_urb
(
usblp
->
writeurb
);
usb_free_urb
(
usblp
->
readurb
);
kfree
(
usblp
);
return
NULL
;
/* Malloc device ID string buffer to the largest expected length,
* since we can re-query it on an ioctl and a dynamic string
* could change in length. */
if
(
!
(
usblp
->
device_id_string
=
kmalloc
(
DEVICE_ID_SIZE
,
GFP_KERNEL
)))
{
err
(
"out of memory for device_id_string"
);
goto
abort
;
}
if
(
!
(
usblp
->
device_id_string
=
kmalloc
(
DEVICE_ID_SIZE
,
GFP_KERNEL
)))
{
err
(
"out of memory"
);
usb_free_urb
(
usblp
->
writeurb
);
usb_free_urb
(
usblp
->
readurb
);
kfree
(
usblp
);
kfree
(
buf
);
return
NULL
;
/* Malloc write/read buffers in one chunk. We somewhat wastefully
* malloc both regardless of bidirectionality, because the
* alternate setting can be changed later via an ioctl. */
if
(
!
(
usblp
->
buf
=
kmalloc
(
2
*
USBLP_BUF_SIZE
,
GFP_KERNEL
)))
{
err
(
"out of memory for buf"
);
goto
abort
;
}
FILL_BULK_URB
(
usblp
->
writeurb
,
dev
,
usb_sndbulkpipe
(
dev
,
epwrite
->
bEndpointAddress
),
buf
,
0
,
usblp_bulk_write
,
usblp
);
/* Lookup quirks for this printer. */
usblp
->
quirks
=
usblp_quirks
(
dev
->
descriptor
.
idVendor
,
dev
->
descriptor
.
idProduct
);
/* Analyze and pick initial alternate settings and endpoints. */
protocol
=
usblp_select_alts
(
usblp
);
if
(
protocol
<
0
)
{
dbg
(
"incompatible printer-class device 0x%4.4X/0x%4.4X"
,
dev
->
descriptor
.
idVendor
,
dev
->
descriptor
.
idProduct
);
goto
abort
;
}
if
(
bidir
)
FILL_BULK_URB
(
usblp
->
readurb
,
dev
,
usb_rcvbulkpipe
(
dev
,
epread
->
bEndpointAddress
),
buf
+
USBLP_BUF_SIZE
,
USBLP_BUF_SIZE
,
usblp_bulk_read
,
usblp
)
;
/* Setup the selected alternate setting and endpoints. */
if
(
usblp_set_protocol
(
usblp
,
protocol
)
<
0
)
goto
abort
;
/* Get the device_id string if possible. FIXME: Could make this kmalloc(length). */
err
=
usblp_get_id
(
usblp
,
0
,
usblp
->
device_id_string
,
DEVICE_ID_SIZE
-
1
);
if
(
err
>=
0
)
{
length
=
(
usblp
->
device_id_string
[
0
]
<<
8
)
+
usblp
->
device_id_string
[
1
];
/* big-endian */
if
(
length
<
DEVICE_ID_SIZE
)
usblp
->
device_id_string
[
length
]
=
'\0'
;
else
usblp
->
device_id_string
[
DEVICE_ID_SIZE
-
1
]
=
'\0'
;
dbg
(
"usblp%d Device ID string [%d]=%s"
,
minor
,
length
,
&
usblp
->
device_id_string
[
2
]);
}
else
{
err
(
"usblp%d: error = %d reading IEEE-1284 Device ID string"
,
minor
,
err
);
usblp
->
device_id_string
[
0
]
=
usblp
->
device_id_string
[
1
]
=
'\0'
;
}
/* Retrieve and store the device ID string. */
usblp_cache_device_id_string
(
usblp
);
#ifdef DEBUG
usblp_check_status
(
usblp
,
0
);
#endif
sprintf
(
name
,
"lp%d"
,
minor
);
/* if we have devfs, create with perms=660 */
/* If we have devfs, create with perms=660. */
sprintf
(
name
,
"lp%d"
,
usblp
->
minor
);
usblp
->
devfs
=
devfs_register
(
usb_devfs_handle
,
name
,
DEVFS_FL_DEFAULT
,
USB_MAJOR
,
USBLP_MINOR_BASE
+
minor
,
USBLP_MINOR_BASE
+
usblp
->
minor
,
S_IFCHR
|
S_IRUSR
|
S_IWUSR
|
S_IRGRP
|
S_IWGRP
,
&
usblp_fops
,
NULL
);
info
(
"usblp%d: USB %sdirectional printer dev %d if %d alt %d"
,
minor
,
bidir
?
"Bi"
:
"Uni"
,
dev
->
devnum
,
ifnum
,
alts
);
info
(
"usblp%d: USB %sdirectional printer dev %d "
"if %d alt %d proto %d vid 0x%4.4X pid 0x%4.4X"
,
usblp
->
minor
,
usblp
->
bidir
?
"Bi"
:
"Uni"
,
dev
->
devnum
,
ifnum
,
usblp
->
protocol
[
usblp
->
current_protocol
].
alt_setting
,
usblp
->
current_protocol
,
usblp
->
dev
->
descriptor
.
idVendor
,
usblp
->
dev
->
descriptor
.
idProduct
);
return
usblp_table
[
minor
]
=
usblp
;
return
usblp_table
[
usblp
->
minor
]
=
usblp
;
abort:
if
(
usblp
)
{
usb_free_urb
(
usblp
->
writeurb
);
usb_free_urb
(
usblp
->
readurb
);
if
(
usblp
->
buf
)
kfree
(
usblp
->
buf
);
if
(
usblp
->
device_id_string
)
kfree
(
usblp
->
device_id_string
);
kfree
(
usblp
);
}
return
NULL
;
}
/*
* We are a "new" style driver with usb_device_id table,
* but our requirements are too intricate for simple match to handle.
*
* The "proto_bias" option may be used to specify the preferred protocol
* for all USB printers (1=7/1/1, 2=7/1/2, 3=7/1/3). If the device
* supports the preferred protocol, then we bind to it.
*
* The best interface for us is 7/1/2, because it is compatible
* with a stream of characters. If we find it, we bind to it.
*
* Note that the people from hpoj.sourceforge.net need to be able to
* bind to 7/1/3 (MLC/1284.4), so we provide them ioctls for this purpose.
*
* Failing 7/1/2, we look for 7/1/3, even though it's probably not
* stream-compatible, because this matches the behaviour of the old code.
*
* If nothing else, we bind to 7/1/1 - the unidirectional interface.
*/
static
int
usblp_select_alts
(
struct
usblp
*
usblp
)
{
struct
usb_interface
*
if_alt
;
struct
usb_interface_descriptor
*
ifd
;
struct
usb_endpoint_descriptor
*
epd
,
*
epwrite
,
*
epread
;
int
p
,
i
,
e
;
if_alt
=
&
usblp
->
dev
->
actconfig
->
interface
[
usblp
->
ifnum
];
for
(
p
=
0
;
p
<
USBLP_MAX_PROTOCOLS
;
p
++
)
usblp
->
protocol
[
p
].
alt_setting
=
-
1
;
/* Find out what we have. */
for
(
i
=
0
;
i
<
if_alt
->
num_altsetting
;
i
++
)
{
ifd
=
&
if_alt
->
altsetting
[
i
];
if
(
ifd
->
bInterfaceClass
!=
7
||
ifd
->
bInterfaceSubClass
!=
1
)
continue
;
if
(
ifd
->
bInterfaceProtocol
<
USBLP_FIRST_PROTOCOL
||
ifd
->
bInterfaceProtocol
>
USBLP_LAST_PROTOCOL
)
continue
;
/* Look for bulk OUT and IN endpoints. */
epwrite
=
epread
=
0
;
for
(
e
=
0
;
e
<
ifd
->
bNumEndpoints
;
e
++
)
{
epd
=
&
ifd
->
endpoint
[
e
];
if
((
epd
->
bmAttributes
&
USB_ENDPOINT_XFERTYPE_MASK
)
!=
USB_ENDPOINT_XFER_BULK
)
continue
;
if
(
!
(
epd
->
bEndpointAddress
&
USB_ENDPOINT_DIR_MASK
))
{
if
(
!
epwrite
)
epwrite
=
epd
;
}
else
{
if
(
!
epread
)
epread
=
epd
;
}
}
/* Ignore buggy hardware without the right endpoints. */
if
(
!
epwrite
||
(
ifd
->
bInterfaceProtocol
>
1
&&
!
epread
))
continue
;
/* Turn off reads for 7/1/1 (unidirectional) interfaces
* and buggy bidirectional printers. */
if
(
ifd
->
bInterfaceProtocol
==
1
)
{
epread
=
NULL
;
}
else
if
(
usblp
->
quirks
&
USBLP_QUIRK_BIDIR
)
{
info
(
"Disabling reads from problem bidirectional "
"printer on usblp%d"
,
usblp
->
minor
);
epread
=
NULL
;
}
usblp
->
protocol
[
ifd
->
bInterfaceProtocol
].
alt_setting
=
i
;
usblp
->
protocol
[
ifd
->
bInterfaceProtocol
].
epwrite
=
epwrite
;
usblp
->
protocol
[
ifd
->
bInterfaceProtocol
].
epread
=
epread
;
}
/* If our requested protocol is supported, then use it. */
if
(
proto_bias
>=
USBLP_FIRST_PROTOCOL
&&
proto_bias
<=
USBLP_LAST_PROTOCOL
&&
usblp
->
protocol
[
proto_bias
].
alt_setting
!=
-
1
)
return
proto_bias
;
/* Ordering is important here. */
if
(
usblp
->
protocol
[
2
].
alt_setting
!=
-
1
)
return
2
;
if
(
usblp
->
protocol
[
1
].
alt_setting
!=
-
1
)
return
1
;
if
(
usblp
->
protocol
[
3
].
alt_setting
!=
-
1
)
return
3
;
/* If nothing is available, then don't bind to this device. */
return
-
1
;
}
static
int
usblp_set_protocol
(
struct
usblp
*
usblp
,
int
protocol
)
{
int
r
,
alts
;
if
(
protocol
<
USBLP_FIRST_PROTOCOL
||
protocol
>
USBLP_LAST_PROTOCOL
)
return
-
EINVAL
;
alts
=
usblp
->
protocol
[
protocol
].
alt_setting
;
if
(
alts
<
0
)
return
-
EINVAL
;
r
=
usb_set_interface
(
usblp
->
dev
,
usblp
->
ifnum
,
alts
);
if
(
r
<
0
)
{
err
(
"can't set desired altsetting %d on interface %d"
,
alts
,
usblp
->
ifnum
);
return
r
;
}
FILL_BULK_URB
(
usblp
->
writeurb
,
usblp
->
dev
,
usb_sndbulkpipe
(
usblp
->
dev
,
usblp
->
protocol
[
protocol
].
epwrite
->
bEndpointAddress
),
usblp
->
buf
,
0
,
usblp_bulk_write
,
usblp
);
usblp
->
bidir
=
(
usblp
->
protocol
[
protocol
].
epread
!=
0
);
if
(
usblp
->
bidir
)
FILL_BULK_URB
(
usblp
->
readurb
,
usblp
->
dev
,
usb_rcvbulkpipe
(
usblp
->
dev
,
usblp
->
protocol
[
protocol
].
epread
->
bEndpointAddress
),
usblp
->
buf
+
USBLP_BUF_SIZE
,
USBLP_BUF_SIZE
,
usblp_bulk_read
,
usblp
);
usblp
->
current_protocol
=
protocol
;
dbg
(
"usblp%d set protocol %d"
,
usblp
->
minor
,
protocol
);
return
0
;
}
/* Retrieves and caches device ID string.
* Returns length, including length bytes but not null terminator.
* On error, returns a negative errno value. */
static
int
usblp_cache_device_id_string
(
struct
usblp
*
usblp
)
{
int
err
,
length
;
err
=
usblp_get_id
(
usblp
,
0
,
usblp
->
device_id_string
,
DEVICE_ID_SIZE
-
1
);
if
(
err
<
0
)
{
dbg
(
"usblp%d: error = %d reading IEEE-1284 Device ID string"
,
usblp
->
minor
,
err
);
usblp
->
device_id_string
[
0
]
=
usblp
->
device_id_string
[
1
]
=
'\0'
;
return
-
EIO
;
}
/* First two bytes are length in big-endian.
* They count themselves, and we copy them into
* the user's buffer. */
length
=
(
usblp
->
device_id_string
[
0
]
<<
8
)
+
usblp
->
device_id_string
[
1
];
if
(
length
<
2
)
length
=
2
;
else
if
(
length
>=
DEVICE_ID_SIZE
)
length
=
DEVICE_ID_SIZE
-
1
;
usblp
->
device_id_string
[
length
]
=
'\0'
;
dbg
(
"usblp%d Device ID string [len=%d]=
\"
%s
\"
"
,
usblp
->
minor
,
length
,
&
usblp
->
device_id_string
[
2
]);
return
length
;
}
static
void
usblp_disconnect
(
struct
usb_device
*
dev
,
void
*
ptr
)
...
...
@@ -757,9 +1055,7 @@ static void usblp_disconnect(struct usb_device *dev, void *ptr)
lock_kernel
();
usblp
->
dev
=
NULL
;
usb_unlink_urb
(
usblp
->
writeurb
);
if
(
usblp
->
bidir
)
usb_unlink_urb
(
usblp
->
readurb
);
usblp_unlink_urbs
(
usblp
);
if
(
!
usblp
->
used
)
usblp_cleanup
(
usblp
);
...
...
@@ -794,7 +1090,7 @@ static int __init usblp_init(void)
{
if
(
usb_register
(
&
usblp_driver
))
return
-
1
;
info
(
DRIVER_VERSION
":"
DRIVER_DESC
);
info
(
DRIVER_VERSION
":
"
DRIVER_DESC
);
return
0
;
}
...
...
@@ -808,5 +1104,6 @@ module_exit(usblp_exit);
MODULE_AUTHOR
(
DRIVER_AUTHOR
);
MODULE_DESCRIPTION
(
DRIVER_DESC
);
MODULE_PARM
(
proto_bias
,
"i"
);
MODULE_PARM_DESC
(
proto_bias
,
"Favourite protocol number"
);
MODULE_LICENSE
(
"GPL"
);
drivers/usb/serial/cyberjack.c
View file @
20f2ef0b
...
...
@@ -262,7 +262,7 @@ static int cyberjack_write (struct usb_serial_port *port, int from_user, const u
port
);
/* send the data out the bulk port */
result
=
usb_submit_urb
(
port
->
write_urb
,
GFP_
KERNEL
);
result
=
usb_submit_urb
(
port
->
write_urb
,
GFP_
ATOMIC
);
if
(
result
)
{
err
(
__FUNCTION__
" - failed submitting write urb, error %d"
,
result
);
/* Throw away data. No better idea what to do with it. */
...
...
@@ -331,7 +331,7 @@ static void cyberjack_read_int_callback( struct urb *urb )
if
(
!
old_rdtodo
)
{
port
->
read_urb
->
dev
=
port
->
serial
->
dev
;
result
=
usb_submit_urb
(
port
->
read_urb
,
GFP_
KERNEL
);
result
=
usb_submit_urb
(
port
->
read_urb
,
GFP_
ATOMIC
);
if
(
result
)
err
(
__FUNCTION__
" - failed resubmitting read urb, error %d"
,
result
);
dbg
(
__FUNCTION__
" - usb_submit_urb(read urb)"
);
...
...
@@ -387,7 +387,7 @@ static void cyberjack_read_bulk_callback (struct urb *urb)
/* Continue to read if we have still urbs to do. */
if
(
priv
->
rdtodo
/* || (urb->actual_length==port->bulk_in_endpointAddress)*/
)
{
port
->
read_urb
->
dev
=
port
->
serial
->
dev
;
result
=
usb_submit_urb
(
port
->
read_urb
,
GFP_
KERNEL
);
result
=
usb_submit_urb
(
port
->
read_urb
,
GFP_
ATOMIC
);
if
(
result
)
err
(
__FUNCTION__
" - failed resubmitting read urb, error %d"
,
result
);
dbg
(
__FUNCTION__
" - usb_submit_urb(read urb)"
);
...
...
@@ -440,7 +440,7 @@ static void cyberjack_write_bulk_callback (struct urb *urb)
port
);
/* send the data out the bulk port */
result
=
usb_submit_urb
(
port
->
write_urb
,
GFP_
KERNEL
);
result
=
usb_submit_urb
(
port
->
write_urb
,
GFP_
ATOMIC
);
if
(
result
)
{
err
(
__FUNCTION__
" - failed submitting write urb, error %d"
,
result
);
/* Throw away data. No better idea what to do with it. */
...
...
drivers/usb/serial/digi_acceleport.c
View file @
20f2ef0b
...
...
@@ -676,7 +676,7 @@ dbg( "digi_write_oob_command: TOP: port=%d, count=%d", oob_priv->dp_port_num, co
oob_port
->
write_urb
->
transfer_buffer_length
=
len
;
oob_port
->
write_urb
->
dev
=
port
->
serial
->
dev
;
if
(
(
ret
=
usb_submit_urb
(
oob_port
->
write_urb
,
GFP_
KERNEL
))
==
0
)
{
if
(
(
ret
=
usb_submit_urb
(
oob_port
->
write_urb
,
GFP_
ATOMIC
))
==
0
)
{
oob_priv
->
dp_write_urb_in_use
=
1
;
count
-=
len
;
buf
+=
len
;
...
...
@@ -764,7 +764,7 @@ count );
}
port
->
write_urb
->
dev
=
port
->
serial
->
dev
;
if
(
(
ret
=
usb_submit_urb
(
port
->
write_urb
,
GFP_
KERNEL
))
==
0
)
{
if
(
(
ret
=
usb_submit_urb
(
port
->
write_urb
,
GFP_
ATOMIC
))
==
0
)
{
priv
->
dp_write_urb_in_use
=
1
;
priv
->
dp_out_buf_len
=
0
;
count
-=
len
;
...
...
@@ -841,7 +841,7 @@ port_priv->dp_port_num, modem_signals );
oob_port
->
write_urb
->
transfer_buffer_length
=
8
;
oob_port
->
write_urb
->
dev
=
port
->
serial
->
dev
;
if
(
(
ret
=
usb_submit_urb
(
oob_port
->
write_urb
,
GFP_
KERNEL
))
==
0
)
{
if
(
(
ret
=
usb_submit_urb
(
oob_port
->
write_urb
,
GFP_
ATOMIC
))
==
0
)
{
oob_priv
->
dp_write_urb_in_use
=
1
;
port_priv
->
dp_modem_signals
=
(
port_priv
->
dp_modem_signals
&~
(
TIOCM_DTR
|
TIOCM_RTS
))
...
...
@@ -962,7 +962,7 @@ dbg( "digi_rx_unthrottle: TOP: port=%d", priv->dp_port_num );
/* restart read chain */
if
(
priv
->
dp_throttle_restart
)
{
port
->
read_urb
->
dev
=
port
->
serial
->
dev
;
ret
=
usb_submit_urb
(
port
->
read_urb
,
GFP_
KERNEL
);
ret
=
usb_submit_urb
(
port
->
read_urb
,
GFP_
ATOMIC
);
}
/* turn throttle off */
...
...
@@ -1323,7 +1323,7 @@ priv->dp_port_num, count, from_user, in_interrupt() );
/* copy in new data */
memcpy
(
data
,
from_user
?
user_buf
:
buf
,
new_len
);
if
(
(
ret
=
usb_submit_urb
(
port
->
write_urb
,
GFP_
KERNEL
))
==
0
)
{
if
(
(
ret
=
usb_submit_urb
(
port
->
write_urb
,
GFP_
ATOMIC
))
==
0
)
{
priv
->
dp_write_urb_in_use
=
1
;
ret
=
new_len
;
priv
->
dp_out_buf_len
=
0
;
...
...
@@ -1399,7 +1399,7 @@ dbg( "digi_write_bulk_callback: TOP, urb->status=%d", urb->status );
memcpy
(
port
->
write_urb
->
transfer_buffer
+
2
,
priv
->
dp_out_buf
,
priv
->
dp_out_buf_len
);
if
(
(
ret
=
usb_submit_urb
(
port
->
write_urb
,
GFP_
KERNEL
))
==
0
)
{
if
(
(
ret
=
usb_submit_urb
(
port
->
write_urb
,
GFP_
ATOMIC
))
==
0
)
{
priv
->
dp_write_urb_in_use
=
1
;
priv
->
dp_out_buf_len
=
0
;
}
...
...
@@ -1837,7 +1837,7 @@ dbg( "digi_read_bulk_callback: TOP" );
/* continue read */
urb
->
dev
=
port
->
serial
->
dev
;
if
(
(
ret
=
usb_submit_urb
(
urb
,
GFP_
KERNEL
))
!=
0
)
{
if
(
(
ret
=
usb_submit_urb
(
urb
,
GFP_
ATOMIC
))
!=
0
)
{
err
(
__FUNCTION__
": failed resubmitting urb, ret=%d, port=%d"
,
ret
,
priv
->
dp_port_num
);
}
...
...
drivers/usb/serial/empeg.c
View file @
20f2ef0b
...
...
@@ -256,7 +256,7 @@ static int empeg_write (struct usb_serial_port *port, int from_user, const unsig
}
if
(
urb
->
transfer_buffer
==
NULL
)
{
urb
->
transfer_buffer
=
kmalloc
(
URB_TRANSFER_BUFFER_SIZE
,
GFP_
KERNEL
);
urb
->
transfer_buffer
=
kmalloc
(
URB_TRANSFER_BUFFER_SIZE
,
GFP_
ATOMIC
);
if
(
urb
->
transfer_buffer
==
NULL
)
{
err
(
__FUNCTION__
" no more kernel memory..."
);
goto
exit
;
...
...
@@ -288,7 +288,7 @@ static int empeg_write (struct usb_serial_port *port, int from_user, const unsig
urb
->
transfer_flags
|=
USB_QUEUE_BULK
;
/* send it down the pipe */
status
=
usb_submit_urb
(
urb
,
GFP_
KERNEL
);
status
=
usb_submit_urb
(
urb
,
GFP_
ATOMIC
);
if
(
status
)
{
err
(
__FUNCTION__
" - usb_submit_urb(write bulk) failed with status = %d"
,
status
);
bytes_sent
=
status
;
...
...
@@ -441,7 +441,7 @@ static void empeg_read_bulk_callback (struct urb *urb)
port
->
read_urb
->
transfer_flags
|=
USB_QUEUE_BULK
;
result
=
usb_submit_urb
(
port
->
read_urb
,
GFP_
KERNEL
);
result
=
usb_submit_urb
(
port
->
read_urb
,
GFP_
ATOMIC
);
if
(
result
)
err
(
__FUNCTION__
" - failed resubmitting read urb, error %d"
,
result
);
...
...
@@ -466,7 +466,7 @@ static void empeg_unthrottle (struct usb_serial_port *port)
port
->
read_urb
->
dev
=
port
->
serial
->
dev
;
result
=
usb_submit_urb
(
port
->
read_urb
,
GFP_
KERNEL
);
result
=
usb_submit_urb
(
port
->
read_urb
,
GFP_
ATOMIC
);
if
(
result
)
err
(
__FUNCTION__
" - failed submitting read urb, error %d"
,
result
);
...
...
drivers/usb/serial/ftdi_sio.c
View file @
20f2ef0b
...
...
@@ -469,7 +469,7 @@ static int ftdi_sio_write (struct usb_serial_port *port, int from_user,
port
->
write_urb
->
transfer_buffer
,
count
,
ftdi_sio_write_bulk_callback
,
port
);
result
=
usb_submit_urb
(
port
->
write_urb
,
GFP_
KERNEL
);
result
=
usb_submit_urb
(
port
->
write_urb
,
GFP_
ATOMIC
);
if
(
result
)
{
err
(
__FUNCTION__
" - failed submitting write urb, error %d"
,
result
);
return
0
;
...
...
@@ -631,7 +631,7 @@ static void ftdi_sio_read_bulk_callback (struct urb *urb)
port
->
read_urb
->
transfer_buffer
,
port
->
read_urb
->
transfer_buffer_length
,
ftdi_sio_read_bulk_callback
,
port
);
result
=
usb_submit_urb
(
port
->
read_urb
,
GFP_
KERNEL
);
result
=
usb_submit_urb
(
port
->
read_urb
,
GFP_
ATOMIC
);
if
(
result
)
err
(
__FUNCTION__
" - failed resubmitting read urb, error %d"
,
result
);
...
...
drivers/usb/serial/io_edgeport.c
View file @
20f2ef0b
...
...
@@ -790,7 +790,7 @@ static void edge_interrupt_callback (struct urb *urb)
/* we have pending bytes on the bulk in pipe, send a request */
edge_serial
->
read_urb
->
dev
=
edge_serial
->
serial
->
dev
;
result
=
usb_submit_urb
(
edge_serial
->
read_urb
,
GFP_
KERNEL
);
result
=
usb_submit_urb
(
edge_serial
->
read_urb
,
GFP_
ATOMIC
);
if
(
result
)
{
dbg
(
__FUNCTION__
" - usb_submit_urb(read bulk) failed with result = %d"
,
result
);
}
...
...
@@ -867,7 +867,7 @@ static void edge_bulk_in_callback (struct urb *urb)
/* there is, so resubmit our urb */
edge_serial
->
read_urb
->
dev
=
edge_serial
->
serial
->
dev
;
status
=
usb_submit_urb
(
edge_serial
->
read_urb
,
GFP_
KERNEL
);
status
=
usb_submit_urb
(
edge_serial
->
read_urb
,
GFP_
ATOMIC
);
if
(
status
)
{
err
(
__FUNCTION__
" - usb_submit_urb(read bulk) failed, status = %d"
,
status
);
}
...
...
@@ -1435,7 +1435,7 @@ static void send_more_port_data(struct edgeport_serial *edge_serial, struct edge
/* build the data header for the buffer and port that we are about to send out */
count
=
fifo
->
count
;
buffer
=
kmalloc
(
count
+
2
,
GFP_
KERNEL
);
buffer
=
kmalloc
(
count
+
2
,
GFP_
ATOMIC
);
if
(
buffer
==
NULL
)
{
err
(
__FUNCTION__
" - no more kernel memory..."
);
edge_port
->
write_in_progress
=
FALSE
;
...
...
@@ -1474,7 +1474,7 @@ static void send_more_port_data(struct edgeport_serial *edge_serial, struct edge
urb
->
transfer_flags
|=
USB_QUEUE_BULK
;
urb
->
dev
=
edge_serial
->
serial
->
dev
;
status
=
usb_submit_urb
(
urb
,
GFP_
KERNEL
);
status
=
usb_submit_urb
(
urb
,
GFP_
ATOMIC
);
if
(
status
)
{
/* something went wrong */
dbg
(
__FUNCTION__
" - usb_submit_urb(write bulk) failed"
);
...
...
@@ -2431,7 +2431,7 @@ static int send_iosp_ext_cmd (struct edgeport_port *edge_port, __u8 command, __u
dbg
(
__FUNCTION__
" - %d, %d"
,
command
,
param
);
buffer
=
kmalloc
(
10
,
GFP_
KERNEL
);
buffer
=
kmalloc
(
10
,
GFP_
ATOMIC
);
if
(
!
buffer
)
{
err
(
__FUNCTION__
" - kmalloc(%d) failed.
\n
"
,
10
);
return
-
ENOMEM
;
...
...
@@ -2467,7 +2467,7 @@ static int write_cmd_usb (struct edgeport_port *edge_port, unsigned char *buffer
usb_serial_debug_data
(
__FILE__
,
__FUNCTION__
,
length
,
buffer
);
/* Allocate our next urb */
urb
=
usb_alloc_urb
(
0
,
GFP_
KERNEL
);
urb
=
usb_alloc_urb
(
0
,
GFP_
ATOMIC
);
if
(
!
urb
)
return
-
ENOMEM
;
...
...
@@ -2482,7 +2482,7 @@ static int write_cmd_usb (struct edgeport_port *edge_port, unsigned char *buffer
urb
->
transfer_flags
|=
USB_QUEUE_BULK
;
edge_port
->
commandPending
=
TRUE
;
status
=
usb_submit_urb
(
urb
,
GFP_
KERNEL
);
status
=
usb_submit_urb
(
urb
,
GFP_
ATOMIC
);
if
(
status
)
{
/* something went wrong */
...
...
@@ -2532,7 +2532,7 @@ static int send_cmd_write_baud_rate (struct edgeport_port *edge_port, int baudRa
}
// Alloc memory for the string of commands.
cmdBuffer
=
kmalloc
(
0x100
,
GFP_
KERNEL
);
cmdBuffer
=
kmalloc
(
0x100
,
GFP_
ATOMIC
);
if
(
!
cmdBuffer
)
{
err
(
__FUNCTION__
" - kmalloc(%d) failed.
\n
"
,
0x100
);
return
-
ENOMEM
;
...
...
@@ -2618,7 +2618,7 @@ static int send_cmd_write_uart_register (struct edgeport_port *edge_port, __u8 r
dbg
(
__FUNCTION__
" - write to %s register 0x%02x"
,
(
regNum
==
MCR
)
?
"MCR"
:
"LCR"
,
regValue
);
// Alloc memory for the string of commands.
cmdBuffer
=
kmalloc
(
0x10
,
GFP_
KERNEL
);
cmdBuffer
=
kmalloc
(
0x10
,
GFP_
ATOMIC
);
if
(
cmdBuffer
==
NULL
)
{
return
-
ENOMEM
;
}
...
...
drivers/usb/serial/ipaq.c
View file @
20f2ef0b
...
...
@@ -297,7 +297,7 @@ static void ipaq_read_bulk_callback(struct urb *urb)
usb_rcvbulkpipe
(
serial
->
dev
,
port
->
bulk_in_endpointAddress
),
port
->
read_urb
->
transfer_buffer
,
port
->
read_urb
->
transfer_buffer_length
,
ipaq_read_bulk_callback
,
port
);
result
=
usb_submit_urb
(
port
->
read_urb
,
GFP_
KERNEL
);
result
=
usb_submit_urb
(
port
->
read_urb
,
GFP_
ATOMIC
);
if
(
result
)
err
(
__FUNCTION__
" - failed resubmitting read urb, error %d"
,
result
);
return
;
...
...
@@ -412,7 +412,7 @@ static int ipaq_write_flush(struct usb_serial_port *port)
usb_sndbulkpipe
(
serial
->
dev
,
port
->
bulk_out_endpointAddress
),
port
->
write_urb
->
transfer_buffer
,
count
,
ipaq_write_bulk_callback
,
port
);
result
=
usb_submit_urb
(
urb
,
GFP_
KERNEL
);
result
=
usb_submit_urb
(
urb
,
GFP_
ATOMIC
);
if
(
result
)
{
err
(
__FUNCTION__
" - failed submitting write urb, error %d"
,
result
);
}
...
...
drivers/usb/serial/ir-usb.c
View file @
20f2ef0b
...
...
@@ -405,7 +405,7 @@ static int ir_write (struct usb_serial_port *port, int from_user, const unsigned
=
USB_QUEUE_BULK
|
USB_ZERO_PACKET
;
result
=
usb_submit_urb
(
port
->
write_urb
,
GFP_
KERNEL
);
result
=
usb_submit_urb
(
port
->
write_urb
,
GFP_
ATOMIC
);
if
(
result
)
err
(
"%s - failed submitting write urb, error %d"
,
__FUNCTION__
,
result
);
else
...
...
@@ -515,7 +515,7 @@ static void ir_read_bulk_callback (struct urb *urb)
port
->
read_urb
->
transfer_flags
=
USB_QUEUE_BULK
;
result
=
usb_submit_urb
(
port
->
read_urb
,
GFP_
KERNEL
);
result
=
usb_submit_urb
(
port
->
read_urb
,
GFP_
ATOMIC
);
if
(
result
)
err
(
"%s - failed resubmitting read urb, error %d"
,
...
...
drivers/usb/serial/keyspan.c
View file @
20f2ef0b
...
...
@@ -378,7 +378,7 @@ static int keyspan_write(struct usb_serial_port *port, int from_user,
this_urb
->
transfer_flags
&=
~
USB_ASYNC_UNLINK
;
this_urb
->
dev
=
port
->
serial
->
dev
;
if
((
err
=
usb_submit_urb
(
this_urb
,
GFP_
KERNEL
))
!=
0
)
{
if
((
err
=
usb_submit_urb
(
this_urb
,
GFP_
ATOMIC
))
!=
0
)
{
dbg
(
"usb_submit_urb(write bulk) failed (%d)
\n
"
,
err
);
}
p_priv
->
tx_start_time
[
flip
]
=
jiffies
;
...
...
@@ -436,7 +436,7 @@ static void usa26_indat_callback(struct urb *urb)
/* Resubmit urb so we continue receiving */
urb
->
dev
=
port
->
serial
->
dev
;
if
((
err
=
usb_submit_urb
(
urb
,
GFP_
KERNEL
))
!=
0
)
{
if
((
err
=
usb_submit_urb
(
urb
,
GFP_
ATOMIC
))
!=
0
)
{
dbg
(
__FUNCTION__
"resubmit read urb failed. (%d)
\n
"
,
err
);
}
return
;
...
...
@@ -535,7 +535,7 @@ static void usa26_instat_callback(struct urb *urb)
exit:
/* Resubmit urb so we continue receiving */
urb
->
dev
=
serial
->
dev
;
if
((
err
=
usb_submit_urb
(
urb
,
GFP_
KERNEL
))
!=
0
)
{
if
((
err
=
usb_submit_urb
(
urb
,
GFP_
ATOMIC
))
!=
0
)
{
dbg
(
__FUNCTION__
"resubmit read urb failed. (%d)
\n
"
,
err
);
}
}
...
...
@@ -586,7 +586,7 @@ static void usa28_indat_callback(struct urb *urb)
/* Resubmit urb so we continue receiving */
urb
->
dev
=
port
->
serial
->
dev
;
if
((
err
=
usb_submit_urb
(
urb
,
GFP_
KERNEL
))
!=
0
)
{
if
((
err
=
usb_submit_urb
(
urb
,
GFP_
ATOMIC
))
!=
0
)
{
dbg
(
__FUNCTION__
"resubmit read urb failed. (%d)
\n
"
,
err
);
}
...
...
@@ -671,7 +671,7 @@ static void usa28_instat_callback(struct urb *urb)
exit:
/* Resubmit urb so we continue receiving */
urb
->
dev
=
serial
->
dev
;
if
((
err
=
usb_submit_urb
(
urb
,
GFP_
KERNEL
))
!=
0
)
{
if
((
err
=
usb_submit_urb
(
urb
,
GFP_
ATOMIC
))
!=
0
)
{
dbg
(
__FUNCTION__
"resubmit read urb failed. (%d)
\n
"
,
err
);
}
}
...
...
@@ -764,7 +764,7 @@ static void usa49_instat_callback(struct urb *urb)
/* Resubmit urb so we continue receiving */
urb
->
dev
=
serial
->
dev
;
if
((
err
=
usb_submit_urb
(
urb
,
GFP_
KERNEL
))
!=
0
)
{
if
((
err
=
usb_submit_urb
(
urb
,
GFP_
ATOMIC
))
!=
0
)
{
dbg
(
__FUNCTION__
"resubmit read urb failed. (%d)
\n
"
,
err
);
}
}
...
...
@@ -819,7 +819,7 @@ static void usa49_indat_callback(struct urb *urb)
/* Resubmit urb so we continue receiving */
urb
->
dev
=
port
->
serial
->
dev
;
if
((
err
=
usb_submit_urb
(
urb
,
GFP_
KERNEL
))
!=
0
)
{
if
((
err
=
usb_submit_urb
(
urb
,
GFP_
ATOMIC
))
!=
0
)
{
dbg
(
__FUNCTION__
"resubmit read urb failed. (%d)
\n
"
,
err
);
}
}
...
...
drivers/usb/serial/keyspan_pda.c
View file @
20f2ef0b
...
...
@@ -292,7 +292,7 @@ static void keyspan_pda_rx_unthrottle (struct usb_serial_port *port)
/* just restart the receive interrupt URB */
dbg
(
"keyspan_pda_rx_unthrottle port %d"
,
port
->
number
);
port
->
interrupt_in_urb
->
dev
=
port
->
serial
->
dev
;
if
(
usb_submit_urb
(
port
->
interrupt_in_urb
,
GFP_
KERNEL
))
if
(
usb_submit_urb
(
port
->
interrupt_in_urb
,
GFP_
ATOMIC
))
dbg
(
" usb_submit_urb(read urb) failed"
);
return
;
}
...
...
@@ -584,7 +584,7 @@ static int keyspan_pda_write(struct usb_serial_port *port, int from_user,
priv
->
tx_room
-=
count
;
port
->
write_urb
->
dev
=
port
->
serial
->
dev
;
rc
=
usb_submit_urb
(
port
->
write_urb
,
GFP_
KERNEL
);
rc
=
usb_submit_urb
(
port
->
write_urb
,
GFP_
ATOMIC
);
if
(
rc
)
{
dbg
(
" usb_submit_urb(write bulk) failed"
);
goto
exit
;
...
...
drivers/usb/serial/kl5kusb105.c
View file @
20f2ef0b
...
...
@@ -519,7 +519,7 @@ static int klsi_105_write (struct usb_serial_port *port, int from_user,
}
if
(
urb
->
transfer_buffer
==
NULL
)
{
urb
->
transfer_buffer
=
kmalloc
(
URB_TRANSFER_BUFFER_SIZE
,
GFP_
KERNEL
);
urb
->
transfer_buffer
=
kmalloc
(
URB_TRANSFER_BUFFER_SIZE
,
GFP_
ATOMIC
);
if
(
urb
->
transfer_buffer
==
NULL
)
{
err
(
__FUNCTION__
" - no more kernel memory..."
);
goto
exit
;
...
...
@@ -555,7 +555,7 @@ static int klsi_105_write (struct usb_serial_port *port, int from_user,
/* send the data out the bulk port */
result
=
usb_submit_urb
(
urb
,
GFP_
KERNEL
);
result
=
usb_submit_urb
(
urb
,
GFP_
ATOMIC
);
if
(
result
)
{
err
(
__FUNCTION__
" - failed submitting write urb, error %d"
,
result
);
...
...
@@ -721,7 +721,7 @@ static void klsi_105_read_bulk_callback (struct urb *urb)
port
->
read_urb
->
transfer_buffer_length
,
klsi_105_read_bulk_callback
,
port
);
rc
=
usb_submit_urb
(
port
->
read_urb
,
GFP_
KERNEL
);
rc
=
usb_submit_urb
(
port
->
read_urb
,
GFP_
ATOMIC
);
if
(
rc
)
err
(
__FUNCTION__
" - failed resubmitting read urb, error %d"
,
rc
);
...
...
@@ -1019,7 +1019,7 @@ static void klsi_105_unthrottle (struct usb_serial_port *port)
dbg
(
__FUNCTION__
" - port %d"
,
port
->
number
);
port
->
read_urb
->
dev
=
port
->
serial
->
dev
;
result
=
usb_submit_urb
(
port
->
read_urb
,
GFP_
KERNEL
);
result
=
usb_submit_urb
(
port
->
read_urb
,
GFP_
ATOMIC
);
if
(
result
)
err
(
__FUNCTION__
" - failed submitting read urb, error %d"
,
result
);
...
...
drivers/usb/serial/mct_u232.c
View file @
20f2ef0b
...
...
@@ -470,7 +470,7 @@ static int mct_u232_write (struct usb_serial_port *port, int from_user,
port
);
/* send the data out the bulk port */
result
=
usb_submit_urb
(
port
->
write_urb
,
GFP_
KERNEL
);
result
=
usb_submit_urb
(
port
->
write_urb
,
GFP_
ATOMIC
);
if
(
result
)
{
err
(
__FUNCTION__
" - failed submitting write urb, error %d"
,
result
);
...
...
drivers/usb/serial/omninet.c
View file @
20f2ef0b
...
...
@@ -265,7 +265,7 @@ static void omninet_read_bulk_callback (struct urb *urb)
usb_rcvbulkpipe
(
serial
->
dev
,
port
->
bulk_in_endpointAddress
),
urb
->
transfer_buffer
,
urb
->
transfer_buffer_length
,
omninet_read_bulk_callback
,
port
);
result
=
usb_submit_urb
(
urb
,
GFP_
KERNEL
);
result
=
usb_submit_urb
(
urb
,
GFP_
ATOMIC
);
if
(
result
)
err
(
__FUNCTION__
" - failed resubmitting read urb, error %d"
,
result
);
...
...
@@ -316,7 +316,7 @@ static int omninet_write (struct usb_serial_port *port, int from_user, const uns
wport
->
write_urb
->
transfer_buffer_length
=
64
;
wport
->
write_urb
->
dev
=
serial
->
dev
;
result
=
usb_submit_urb
(
wport
->
write_urb
,
GFP_
KERNEL
);
result
=
usb_submit_urb
(
wport
->
write_urb
,
GFP_
ATOMIC
);
if
(
result
)
err
(
__FUNCTION__
" - failed submitting write urb, error %d"
,
result
);
else
...
...
drivers/usb/serial/pl2303.c
View file @
20f2ef0b
...
...
@@ -195,7 +195,7 @@ static int pl2303_write (struct usb_serial_port *port, int from_user, const uns
port
->
write_urb
->
transfer_buffer_length
=
count
;
port
->
write_urb
->
dev
=
port
->
serial
->
dev
;
result
=
usb_submit_urb
(
port
->
write_urb
,
GFP_
KERNEL
);
result
=
usb_submit_urb
(
port
->
write_urb
,
GFP_
ATOMIC
);
if
(
result
)
err
(
__FUNCTION__
" - failed submitting write urb, error %d"
,
result
);
else
...
...
@@ -643,7 +643,7 @@ static void pl2303_read_bulk_callback (struct urb *urb)
dbg
(
__FUNCTION__
" - caught -EPROTO, resubmitting the urb"
);
urb
->
status
=
0
;
urb
->
dev
=
serial
->
dev
;
result
=
usb_submit_urb
(
urb
,
GFP_
KERNEL
);
result
=
usb_submit_urb
(
urb
,
GFP_
ATOMIC
);
if
(
result
)
err
(
__FUNCTION__
" - failed resubmitting read urb, error %d"
,
result
);
return
;
...
...
@@ -668,7 +668,7 @@ static void pl2303_read_bulk_callback (struct urb *urb)
/* Schedule the next read _if_ we are still open */
if
(
port
->
open_count
)
{
urb
->
dev
=
serial
->
dev
;
result
=
usb_submit_urb
(
urb
,
GFP_
KERNEL
);
result
=
usb_submit_urb
(
urb
,
GFP_
ATOMIC
);
if
(
result
)
err
(
__FUNCTION__
" - failed resubmitting read urb, error %d"
,
result
);
}
...
...
@@ -697,7 +697,7 @@ static void pl2303_write_bulk_callback (struct urb *urb)
dbg
(
__FUNCTION__
" - nonzero write bulk status received: %d"
,
urb
->
status
);
port
->
write_urb
->
transfer_buffer_length
=
1
;
port
->
write_urb
->
dev
=
port
->
serial
->
dev
;
result
=
usb_submit_urb
(
port
->
write_urb
,
GFP_
KERNEL
);
result
=
usb_submit_urb
(
port
->
write_urb
,
GFP_
ATOMIC
);
if
(
result
)
err
(
__FUNCTION__
" - failed resubmitting write urb, error %d"
,
result
);
...
...
drivers/usb/serial/usbserial.c
View file @
20f2ef0b
...
...
@@ -899,7 +899,7 @@ static int generic_write (struct usb_serial_port *port, int from_user, const uns
generic_write_bulk_callback
),
port
);
/* send the data out the bulk port */
result
=
usb_submit_urb
(
port
->
write_urb
,
GFP_
KERNEL
);
result
=
usb_submit_urb
(
port
->
write_urb
,
GFP_
ATOMIC
);
if
(
result
)
err
(
__FUNCTION__
" - failed submitting write urb, error %d"
,
result
);
else
...
...
@@ -989,7 +989,7 @@ static void generic_read_bulk_callback (struct urb *urb)
((
serial
->
type
->
read_bulk_callback
)
?
serial
->
type
->
read_bulk_callback
:
generic_read_bulk_callback
),
port
);
result
=
usb_submit_urb
(
port
->
read_urb
,
GFP_
KERNEL
);
result
=
usb_submit_urb
(
port
->
read_urb
,
GFP_
ATOMIC
);
if
(
result
)
err
(
__FUNCTION__
" - failed resubmitting read urb, error %d"
,
result
);
}
...
...
drivers/usb/serial/visor.c
View file @
20f2ef0b
...
...
@@ -344,13 +344,13 @@ static int visor_write (struct usb_serial_port *port, int from_user, const unsig
dbg
(
__FUNCTION__
" - port %d"
,
port
->
number
);
buffer
=
kmalloc
(
count
,
GFP_
KERNEL
);
buffer
=
kmalloc
(
count
,
GFP_
ATOMIC
);
if
(
!
buffer
)
{
err
(
"out of memory"
);
return
-
ENOMEM
;
}
urb
=
usb_alloc_urb
(
0
,
GFP_
KERNEL
);
urb
=
usb_alloc_urb
(
0
,
GFP_
ATOMIC
);
if
(
!
urb
)
{
err
(
"no more free urbs"
);
kfree
(
buffer
);
...
...
@@ -377,7 +377,7 @@ static int visor_write (struct usb_serial_port *port, int from_user, const unsig
urb
->
transfer_flags
|=
USB_QUEUE_BULK
;
/* send it down the pipe */
status
=
usb_submit_urb
(
urb
,
GFP_
KERNEL
);
status
=
usb_submit_urb
(
urb
,
GFP_
ATOMIC
);
if
(
status
)
{
err
(
__FUNCTION__
" - usb_submit_urb(write bulk) failed with status = %d"
,
status
);
count
=
status
;
...
...
@@ -491,7 +491,7 @@ static void visor_read_bulk_callback (struct urb *urb)
port
->
read_urb
->
transfer_buffer
,
port
->
read_urb
->
transfer_buffer_length
,
visor_read_bulk_callback
,
port
);
result
=
usb_submit_urb
(
port
->
read_urb
,
GFP_
KERNEL
);
result
=
usb_submit_urb
(
port
->
read_urb
,
GFP_
ATOMIC
);
if
(
result
)
err
(
__FUNCTION__
" - failed resubmitting read urb, error %d"
,
result
);
return
;
...
...
@@ -512,7 +512,7 @@ static void visor_unthrottle (struct usb_serial_port *port)
dbg
(
__FUNCTION__
" - port %d"
,
port
->
number
);
port
->
read_urb
->
dev
=
port
->
serial
->
dev
;
result
=
usb_submit_urb
(
port
->
read_urb
,
GFP_
KERNEL
);
result
=
usb_submit_urb
(
port
->
read_urb
,
GFP_
ATOMIC
);
if
(
result
)
err
(
__FUNCTION__
" - failed submitting read urb, error %d"
,
result
);
}
...
...
drivers/usb/serial/whiteheat.c
View file @
20f2ef0b
...
...
@@ -240,7 +240,7 @@ static void command_port_read_callback (struct urb *urb)
usb_rcvbulkpipe
(
serial
->
dev
,
port
->
bulk_in_endpointAddress
),
port
->
read_urb
->
transfer_buffer
,
port
->
read_urb
->
transfer_buffer_length
,
command_port_read_callback
,
port
);
result
=
usb_submit_urb
(
port
->
read_urb
,
GFP_
KERNEL
);
result
=
usb_submit_urb
(
port
->
read_urb
,
GFP_
ATOMIC
);
if
(
result
)
dbg
(
__FUNCTION__
" - failed resubmitting read urb, error %d"
,
result
);
}
...
...
include/linux/hiddev.h
View file @
20f2ef0b
...
...
@@ -119,6 +119,7 @@ struct hiddev_usage_ref {
__s32
value
;
};
#define HID_FIELD_INDEX_NONE 0xffffffff
/*
* Protocol version.
...
...
@@ -143,6 +144,15 @@ struct hiddev_usage_ref {
#define HIDIOCGUSAGE _IOWR('H', 0x0B, struct hiddev_usage_ref)
#define HIDIOCSUSAGE _IOW('H', 0x0C, struct hiddev_usage_ref)
#define HIDIOCGUCODE _IOWR('H', 0x0D, struct hiddev_usage_ref)
#define HIDIOCGFLAG _IOR('H', 0x0E, int)
#define HIDIOCSFLAG _IOW('H', 0x0F, int)
/*
* Flags to be used in HIDIOCSFLAG
*/
#define HIDDEV_FLAG_UREF 0x1
#define HIDDEV_FLAG_REPORT 0x2
#define HIDDEV_FLAGS 0x3
/* To traverse the input report descriptor info for a HID device, perform the
* following:
...
...
@@ -179,7 +189,7 @@ struct hiddev_usage_ref {
#ifdef CONFIG_USB_HIDDEV
int
hiddev_connect
(
struct
hid_device
*
);
void
hiddev_disconnect
(
struct
hid_device
*
);
void
hiddev_hid_event
(
struct
hid_device
*
,
unsigned
int
usage
,
int
value
);
void
hiddev_hid_event
(
struct
hid_device
*
,
struct
hiddev_usage_ref
*
ref
);
int
__init
hiddev_init
(
void
);
void
__exit
hiddev_exit
(
void
);
#else
...
...
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