Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
cc6120c6
cloud-kernel
项目概览
openanolis
/
cloud-kernel
大约 1 年 前同步成功
通知
158
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
cc6120c6
编写于
9月 12, 2005
作者:
L
Linus Torvalds
浏览文件
操作
浏览文件
下载
差异文件
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6
上级
7b799bc8
f5e09b7c
变更
43
展开全部
隐藏空白更改
内联
并排
Showing
43 changed file
with
5277 addition
and
348 deletion
+5277
-348
Documentation/input/appletouch.txt
Documentation/input/appletouch.txt
+84
-0
Documentation/usb/proc_usb_info.txt
Documentation/usb/proc_usb_info.txt
+8
-5
drivers/usb/class/audio.c
drivers/usb/class/audio.c
+8
-4
drivers/usb/core/hcd.c
drivers/usb/core/hcd.c
+1
-2
drivers/usb/core/hub.c
drivers/usb/core/hub.c
+6
-5
drivers/usb/gadget/inode.c
drivers/usb/gadget/inode.c
+1
-0
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-hcd.c
+24
-4
drivers/usb/host/ehci-hub.c
drivers/usb/host/ehci-hub.c
+16
-11
drivers/usb/host/ehci.h
drivers/usb/host/ehci.h
+1
-0
drivers/usb/host/ohci-dbg.c
drivers/usb/host/ohci-dbg.c
+4
-5
drivers/usb/host/ohci-hcd.c
drivers/usb/host/ohci-hcd.c
+8
-6
drivers/usb/host/ohci-hub.c
drivers/usb/host/ohci-hub.c
+11
-11
drivers/usb/host/ohci-pxa27x.c
drivers/usb/host/ohci-pxa27x.c
+10
-38
drivers/usb/host/ohci.h
drivers/usb/host/ohci.h
+1
-0
drivers/usb/host/uhci-hcd.c
drivers/usb/host/uhci-hcd.c
+22
-40
drivers/usb/host/uhci-hcd.h
drivers/usb/host/uhci-hcd.h
+3
-8
drivers/usb/host/uhci-hub.c
drivers/usb/host/uhci-hub.c
+6
-5
drivers/usb/host/uhci-q.c
drivers/usb/host/uhci-q.c
+1
-1
drivers/usb/input/Kconfig
drivers/usb/input/Kconfig
+20
-0
drivers/usb/input/Makefile
drivers/usb/input/Makefile
+1
-0
drivers/usb/input/appletouch.c
drivers/usb/input/appletouch.c
+469
-0
drivers/usb/input/hid-core.c
drivers/usb/input/hid-core.c
+0
-2
drivers/usb/misc/sisusbvga/Kconfig
drivers/usb/misc/sisusbvga/Kconfig
+37
-5
drivers/usb/misc/sisusbvga/Makefile
drivers/usb/misc/sisusbvga/Makefile
+3
-1
drivers/usb/misc/sisusbvga/sisusb.c
drivers/usb/misc/sisusbvga/sisusb.c
+426
-37
drivers/usb/misc/sisusbvga/sisusb.h
drivers/usb/misc/sisusbvga/sisusb.h
+61
-12
drivers/usb/misc/sisusbvga/sisusb_con.c
drivers/usb/misc/sisusbvga/sisusb_con.c
+1658
-0
drivers/usb/misc/sisusbvga/sisusb_init.c
drivers/usb/misc/sisusbvga/sisusb_init.c
+1047
-0
drivers/usb/misc/sisusbvga/sisusb_init.h
drivers/usb/misc/sisusbvga/sisusb_init.h
+830
-0
drivers/usb/misc/sisusbvga/sisusb_struct.h
drivers/usb/misc/sisusbvga/sisusb_struct.h
+169
-0
drivers/usb/misc/uss720.c
drivers/usb/misc/uss720.c
+270
-123
drivers/usb/mon/mon_text.c
drivers/usb/mon/mon_text.c
+1
-1
drivers/usb/serial/cp2101.c
drivers/usb/serial/cp2101.c
+4
-1
drivers/usb/serial/cypress_m8.c
drivers/usb/serial/cypress_m8.c
+1
-2
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio.c
+1
-1
drivers/usb/serial/pl2303.c
drivers/usb/serial/pl2303.c
+2
-2
drivers/usb/serial/pl2303.h
drivers/usb/serial/pl2303.h
+4
-0
drivers/usb/storage/scsiglue.c
drivers/usb/storage/scsiglue.c
+9
-11
drivers/usb/storage/unusual_devs.h
drivers/usb/storage/unusual_devs.h
+35
-0
drivers/usb/storage/usb.c
drivers/usb/storage/usb.c
+8
-3
drivers/video/console/Kconfig
drivers/video/console/Kconfig
+1
-1
drivers/video/console/Makefile
drivers/video/console/Makefile
+4
-0
include/linux/usbdevice_fs.h
include/linux/usbdevice_fs.h
+1
-1
未找到文件。
Documentation/input/appletouch.txt
0 → 100644
浏览文件 @
cc6120c6
Apple Touchpad Driver (appletouch)
----------------------------------
Copyright (C) 2005 Stelian Pop <stelian@popies.net>
appletouch is a Linux kernel driver for the USB touchpad found on post
February 2005 Apple Alu Powerbooks.
This driver is derived from Johannes Berg's appletrackpad driver[1], but it has
been improved in some areas:
* appletouch is a full kernel driver, no userspace program is necessary
* appletouch can be interfaced with the synaptics X11 driver, in order
to have touchpad acceleration, scrolling, etc.
Credits go to Johannes Berg for reverse-engineering the touchpad protocol,
Frank Arnold for further improvements, and Alex Harper for some additional
information about the inner workings of the touchpad sensors.
Usage:
------
In order to use the touchpad in the basic mode, compile the driver and load
the module. A new input device will be detected and you will be able to read
the mouse data from /dev/input/mice (using gpm, or X11).
In X11, you can configure the touchpad to use the synaptics X11 driver, which
will give additional functionalities, like acceleration, scrolling, 2 finger
tap for middle button mouse emulation, 3 finger tap for right button mouse
emulation, etc. In order to do this, make sure you're using a recent version of
the synaptics driver (tested with 0.14.2, available from [2]), and configure a
new input device in your X11 configuration file (take a look below for an
example). For additional configuration, see the synaptics driver documentation.
Section "InputDevice"
Identifier "Synaptics Touchpad"
Driver "synaptics"
Option "SendCoreEvents" "true"
Option "Device" "/dev/input/mice"
Option "Protocol" "auto-dev"
Option "LeftEdge" "0"
Option "RightEdge" "850"
Option "TopEdge" "0"
Option "BottomEdge" "645"
Option "MinSpeed" "0.4"
Option "MaxSpeed" "1"
Option "AccelFactor" "0.02"
Option "FingerLow" "0"
Option "FingerHigh" "30"
Option "MaxTapMove" "20"
Option "MaxTapTime" "100"
Option "HorizScrollDelta" "0"
Option "VertScrollDelta" "30"
Option "SHMConfig" "on"
EndSection
Section "ServerLayout"
...
InputDevice "Mouse"
InputDevice "Synaptics Touchpad"
...
EndSection
Fuzz problems:
--------------
The touchpad sensors are very sensitive to heat, and will generate a lot of
noise when the temperature changes. This is especially true when you power-on
the laptop for the first time.
The appletouch driver tries to handle this noise and auto adapt itself, but it
is not perfect. If finger movements are not recognized anymore, try reloading
the driver.
You can activate debugging using the 'debug' module parameter. A value of 0
deactivates any debugging, 1 activates tracing of invalid samples, 2 activates
full tracing (each sample is being traced):
modprobe appletouch debug=1
or
echo "1" > /sys/module/appletouch/parameters/debug
Links:
------
[1]: http://johannes.sipsolutions.net/PowerBook/touchpad/
[2]: http://web.telia.com/~u89404340/touchpad/index.html
Documentation/usb/proc_usb_info.txt
浏览文件 @
cc6120c6
...
...
@@ -20,7 +20,7 @@ the /proc/bus/usb/BBB/DDD files.
to /etc/fstab. This will mount usbfs at each reboot.
You can then issue `cat /proc/bus/usb/devices` to extract
USB device information, and user mode drivers can use usbfs
USB device information, and user mode drivers can use usbfs
to interact with USB devices.
There are a number of mount options supported by usbfs.
...
...
@@ -32,7 +32,7 @@ the /proc/bus/usb/BBB/DDD files.
still see references to the older "usbdevfs" name.
For more information on mounting the usbfs file system, see the
"USB Device Filesystem" section of the USB Guide. The latest copy
"USB Device Filesystem" section of the USB Guide. The latest copy
of the USB Guide can be found at http://www.linux-usb.org/
...
...
@@ -133,7 +133,7 @@ B: Alloc=ddd/ddd us (xx%), #Int=ddd, #Iso=ddd
are the only transfers that reserve bandwidth. Control and bulk
transfers use all other bandwidth, including reserved bandwidth that
is not used for transfers (such as for short packets).
The percentage is how much of the "reserved" bandwidth is scheduled by
those transfers. For a low or full speed bus (loosely, "USB 1.1"),
90% of the bus bandwidth is reserved. For a high speed bus (loosely,
...
...
@@ -197,7 +197,7 @@ C:* #Ifs=dd Cfg#=dd Atr=xx MPwr=dddmA
| | |__NumberOfInterfaces
| |__ "*" indicates the active configuration (others are " ")
|__Config info tag
USB devices may have multiple configurations, each of which act
rather differently. For example, a bus-powered configuration
might be much less capable than one that is self-powered. Only
...
...
@@ -228,7 +228,7 @@ I: If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx Driver=ssss
For example, default settings may not use more than a small
amount of periodic bandwidth. To use significant fractions
of bus bandwidth, drivers must select a non-default altsetting.
Only one setting for an interface may be active at a time, and
only one driver may bind to an interface at a time. Most devices
have only one alternate setting per interface.
...
...
@@ -297,18 +297,21 @@ S: SerialNumber=dce0
C:* #Ifs= 1 Cfg#= 1 Atr=40 MxPwr= 0mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub
E: Ad=81(I) Atr=03(Int.) MxPS= 8 Ivl=255ms
T: Bus=00 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=12 MxCh= 4
D: Ver= 1.00 Cls=09(hub ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
P: Vendor=0451 ProdID=1446 Rev= 1.00
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=100mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub
E: Ad=81(I) Atr=03(Int.) MxPS= 1 Ivl=255ms
T: Bus=00 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#= 3 Spd=1.5 MxCh= 0
D: Ver= 1.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
P: Vendor=04b4 ProdID=0001 Rev= 0.00
C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=100mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=03(HID ) Sub=01 Prot=02 Driver=mouse
E: Ad=81(I) Atr=03(Int.) MxPS= 3 Ivl= 10ms
T: Bus=00 Lev=02 Prnt=02 Port=02 Cnt=02 Dev#= 4 Spd=12 MxCh= 0
D: Ver= 1.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
P: Vendor=0565 ProdID=0001 Rev= 1.08
...
...
drivers/usb/class/audio.c
浏览文件 @
cc6120c6
...
...
@@ -631,8 +631,10 @@ static void usbin_stop(struct usb_audiodev *as)
i
=
u
->
flags
;
spin_unlock_irqrestore
(
&
as
->
lock
,
flags
);
while
(
i
&
(
FLG_URB0RUNNING
|
FLG_URB1RUNNING
|
FLG_SYNC0RUNNING
|
FLG_SYNC1RUNNING
))
{
set_current_state
(
notkilled
?
TASK_INTERRUPTIBLE
:
TASK_UNINTERRUPTIBLE
);
schedule_timeout
(
1
);
if
(
notkilled
)
schedule_timeout_interruptible
(
1
);
else
schedule_timeout_uninterruptible
(
1
);
spin_lock_irqsave
(
&
as
->
lock
,
flags
);
i
=
u
->
flags
;
spin_unlock_irqrestore
(
&
as
->
lock
,
flags
);
...
...
@@ -1102,8 +1104,10 @@ static void usbout_stop(struct usb_audiodev *as)
i
=
u
->
flags
;
spin_unlock_irqrestore
(
&
as
->
lock
,
flags
);
while
(
i
&
(
FLG_URB0RUNNING
|
FLG_URB1RUNNING
|
FLG_SYNC0RUNNING
|
FLG_SYNC1RUNNING
))
{
set_current_state
(
notkilled
?
TASK_INTERRUPTIBLE
:
TASK_UNINTERRUPTIBLE
);
schedule_timeout
(
1
);
if
(
notkilled
)
schedule_timeout_interruptible
(
1
);
else
schedule_timeout_uninterruptible
(
1
);
spin_lock_irqsave
(
&
as
->
lock
,
flags
);
i
=
u
->
flags
;
spin_unlock_irqrestore
(
&
as
->
lock
,
flags
);
...
...
drivers/usb/core/hcd.c
浏览文件 @
cc6120c6
...
...
@@ -1606,7 +1606,7 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd, struct pt_regs * r)
return
IRQ_NONE
;
hcd
->
saw_irq
=
1
;
if
(
hcd
->
state
!=
start
&&
hcd
->
state
==
HC_STATE_HALT
)
if
(
hcd
->
state
==
HC_STATE_HALT
)
usb_hc_died
(
hcd
);
return
IRQ_HANDLED
;
}
...
...
@@ -1630,7 +1630,6 @@ void usb_hc_died (struct usb_hcd *hcd)
spin_lock_irqsave
(
&
hcd_root_hub_lock
,
flags
);
if
(
hcd
->
rh_registered
)
{
hcd
->
poll_rh
=
0
;
del_timer
(
&
hcd
->
rh_timer
);
/* make khubd clean up old urbs and devices */
usb_set_device_state
(
hcd
->
self
.
root_hub
,
...
...
drivers/usb/core/hub.c
浏览文件 @
cc6120c6
...
...
@@ -435,6 +435,7 @@ void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe)
static
void
hub_power_on
(
struct
usb_hub
*
hub
)
{
int
port1
;
unsigned
pgood_delay
=
hub
->
descriptor
->
bPwrOn2PwrGood
*
2
;
/* if hub supports power switching, enable power on each port */
if
((
hub
->
descriptor
->
wHubCharacteristics
&
HUB_CHAR_LPSM
)
<
2
)
{
...
...
@@ -444,8 +445,8 @@ static void hub_power_on(struct usb_hub *hub)
USB_PORT_FEAT_POWER
);
}
/* Wait
for power to be enabled
*/
msleep
(
hub
->
descriptor
->
bPwrOn2PwrGood
*
2
);
/* Wait
at least 100 msec for power to become stable
*/
msleep
(
max
(
pgood_delay
,
(
unsigned
)
100
)
);
}
static
void
hub_quiesce
(
struct
usb_hub
*
hub
)
...
...
@@ -1460,7 +1461,7 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
port1
,
status
);
else
{
status
=
hub_port_wait_reset
(
hub
,
port1
,
udev
,
delay
);
if
(
status
)
if
(
status
&&
status
!=
-
ENOTCONN
)
dev_dbg
(
hub
->
intfdev
,
"port_wait_reset: err = %d
\n
"
,
status
);
...
...
@@ -1469,8 +1470,8 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
/* return on disconnect or reset */
switch
(
status
)
{
case
0
:
/* TRSTRCY = 10 ms */
msleep
(
10
);
/* TRSTRCY = 10 ms
; plus some extra
*/
msleep
(
10
+
40
);
/* FALL THROUGH */
case
-
ENOTCONN
:
case
-
ENODEV
:
...
...
drivers/usb/gadget/inode.c
浏览文件 @
cc6120c6
...
...
@@ -483,6 +483,7 @@ ep_release (struct inode *inode, struct file *fd)
data
->
state
=
STATE_EP_DISABLED
;
data
->
desc
.
bDescriptorType
=
0
;
data
->
hs_desc
.
bDescriptorType
=
0
;
usb_ep_disable
(
data
->
ep
);
}
put_ep
(
data
);
return
0
;
...
...
drivers/usb/host/ehci-hcd.c
浏览文件 @
cc6120c6
...
...
@@ -400,6 +400,23 @@ static int ehci_hc_reset (struct usb_hcd *hcd)
return
-
EIO
;
}
break
;
case
PCI_VENDOR_ID_NVIDIA
:
/* NVidia reports that certain chips don't handle
* QH, ITD, or SITD addresses above 2GB. (But TD,
* data buffer, and periodic schedule are normal.)
*/
switch
(
pdev
->
device
)
{
case
0x003c
:
/* MCP04 */
case
0x005b
:
/* CK804 */
case
0x00d8
:
/* CK8 */
case
0x00e8
:
/* CK8S */
if
(
pci_set_consistent_dma_mask
(
pdev
,
DMA_31BIT_MASK
)
<
0
)
ehci_warn
(
ehci
,
"can't enable NVidia "
"workaround for >2GB RAM
\n
"
);
break
;
}
break
;
}
/* optional debug port, normally in the first BAR */
...
...
@@ -759,12 +776,16 @@ static int ehci_resume (struct usb_hcd *hcd)
if
(
time_before
(
jiffies
,
ehci
->
next_statechange
))
msleep
(
100
);
/* If any port is suspended, we know we can/must resume the HC. */
/* If any port is suspended (or owned by the companion),
* we know we can/must resume the HC (and mustn't reset it).
*/
for
(
port
=
HCS_N_PORTS
(
ehci
->
hcs_params
);
port
>
0
;
)
{
u32
status
;
port
--
;
status
=
readl
(
&
ehci
->
regs
->
port_status
[
port
]);
if
(
status
&
PORT_SUSPEND
)
{
if
(
!
(
status
&
PORT_POWER
))
continue
;
if
(
status
&
(
PORT_SUSPEND
|
PORT_OWNER
))
{
down
(
&
hcd
->
self
.
root_hub
->
serialize
);
retval
=
ehci_hub_resume
(
hcd
);
up
(
&
hcd
->
self
.
root_hub
->
serialize
);
...
...
@@ -1126,8 +1147,7 @@ ehci_endpoint_disable (struct usb_hcd *hcd, struct usb_host_endpoint *ep)
case
QH_STATE_UNLINK
:
/* wait for hw to finish? */
idle_timeout:
spin_unlock_irqrestore
(
&
ehci
->
lock
,
flags
);
set_current_state
(
TASK_UNINTERRUPTIBLE
);
schedule_timeout
(
1
);
schedule_timeout_uninterruptible
(
1
);
goto
rescan
;
case
QH_STATE_IDLE
:
/* fully unlinked */
if
(
list_empty
(
&
qh
->
qtd_list
))
{
...
...
drivers/usb/host/ehci-hub.c
浏览文件 @
cc6120c6
...
...
@@ -54,7 +54,7 @@ static int ehci_hub_suspend (struct usb_hcd *hcd)
/* suspend any active/unsuspended ports, maybe allow wakeup */
while
(
port
--
)
{
u32
__iomem
*
reg
=
&
ehci
->
regs
->
port_status
[
port
];
u32
t1
=
readl
(
reg
);
u32
t1
=
readl
(
reg
)
&
~
PORT_RWC_BITS
;
u32
t2
=
t1
;
if
((
t1
&
PORT_PE
)
&&
!
(
t1
&
PORT_OWNER
))
...
...
@@ -115,7 +115,8 @@ static int ehci_hub_resume (struct usb_hcd *hcd)
i
=
HCS_N_PORTS
(
ehci
->
hcs_params
);
while
(
i
--
)
{
temp
=
readl
(
&
ehci
->
regs
->
port_status
[
i
]);
temp
&=
~
(
PORT_WKOC_E
|
PORT_WKDISC_E
|
PORT_WKCONN_E
);
temp
&=
~
(
PORT_RWC_BITS
|
PORT_WKOC_E
|
PORT_WKDISC_E
|
PORT_WKCONN_E
);
if
(
temp
&
PORT_SUSPEND
)
{
ehci
->
reset_done
[
i
]
=
jiffies
+
msecs_to_jiffies
(
20
);
temp
|=
PORT_RESUME
;
...
...
@@ -128,7 +129,7 @@ static int ehci_hub_resume (struct usb_hcd *hcd)
temp
=
readl
(
&
ehci
->
regs
->
port_status
[
i
]);
if
((
temp
&
PORT_SUSPEND
)
==
0
)
continue
;
temp
&=
~
PORT_RESUME
;
temp
&=
~
(
PORT_RWC_BITS
|
PORT_RESUME
)
;
writel
(
temp
,
&
ehci
->
regs
->
port_status
[
i
]);
ehci_vdbg
(
ehci
,
"resumed port %d
\n
"
,
i
+
1
);
}
...
...
@@ -191,6 +192,7 @@ static int check_reset_complete (
// what happens if HCS_N_CC(params) == 0 ?
port_status
|=
PORT_OWNER
;
port_status
&=
~
PORT_RWC_BITS
;
writel
(
port_status
,
&
ehci
->
regs
->
port_status
[
index
]);
}
else
...
...
@@ -233,7 +235,8 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
if
(
temp
&
PORT_OWNER
)
{
/* don't report this in GetPortStatus */
if
(
temp
&
PORT_CSC
)
{
temp
&=
~
PORT_CSC
;
temp
&=
~
PORT_RWC_BITS
;
temp
|=
PORT_CSC
;
writel
(
temp
,
&
ehci
->
regs
->
port_status
[
i
]);
}
continue
;
...
...
@@ -343,7 +346,7 @@ static int ehci_hub_control (
&
ehci
->
regs
->
port_status
[
wIndex
]);
break
;
case
USB_PORT_FEAT_C_ENABLE
:
writel
(
temp
|
PORT_PEC
,
writel
((
temp
&
~
PORT_RWC_BITS
)
|
PORT_PEC
,
&
ehci
->
regs
->
port_status
[
wIndex
]);
break
;
case
USB_PORT_FEAT_SUSPEND
:
...
...
@@ -353,7 +356,8 @@ static int ehci_hub_control (
if
((
temp
&
PORT_PE
)
==
0
)
goto
error
;
/* resume signaling for 20 msec */
writel
((
temp
&
~
PORT_WAKE_BITS
)
|
PORT_RESUME
,
temp
&=
~
(
PORT_RWC_BITS
|
PORT_WAKE_BITS
);
writel
(
temp
|
PORT_RESUME
,
&
ehci
->
regs
->
port_status
[
wIndex
]);
ehci
->
reset_done
[
wIndex
]
=
jiffies
+
msecs_to_jiffies
(
20
);
...
...
@@ -364,15 +368,15 @@ static int ehci_hub_control (
break
;
case
USB_PORT_FEAT_POWER
:
if
(
HCS_PPC
(
ehci
->
hcs_params
))
writel
(
temp
&
~
PORT_POWER
,
writel
(
temp
&
~
(
PORT_RWC_BITS
|
PORT_POWER
)
,
&
ehci
->
regs
->
port_status
[
wIndex
]);
break
;
case
USB_PORT_FEAT_C_CONNECTION
:
writel
(
temp
|
PORT_CSC
,
writel
((
temp
&
~
PORT_RWC_BITS
)
|
PORT_CSC
,
&
ehci
->
regs
->
port_status
[
wIndex
]);
break
;
case
USB_PORT_FEAT_C_OVER_CURRENT
:
writel
(
temp
|
PORT_OCC
,
writel
((
temp
&
~
PORT_RWC_BITS
)
|
PORT_OCC
,
&
ehci
->
regs
->
port_status
[
wIndex
]);
break
;
case
USB_PORT_FEAT_C_RESET
:
...
...
@@ -416,7 +420,7 @@ static int ehci_hub_control (
/* stop resume signaling */
temp
=
readl
(
&
ehci
->
regs
->
port_status
[
wIndex
]);
writel
(
temp
&
~
PORT_RESUME
,
writel
(
temp
&
~
(
PORT_RWC_BITS
|
PORT_RESUME
)
,
&
ehci
->
regs
->
port_status
[
wIndex
]);
retval
=
handshake
(
&
ehci
->
regs
->
port_status
[
wIndex
],
...
...
@@ -437,7 +441,7 @@ static int ehci_hub_control (
ehci
->
reset_done
[
wIndex
]
=
0
;
/* force reset to complete */
writel
(
temp
&
~
PORT_RESET
,
writel
(
temp
&
~
(
PORT_RWC_BITS
|
PORT_RESET
)
,
&
ehci
->
regs
->
port_status
[
wIndex
]);
/* REVISIT: some hardware needs 550+ usec to clear
* this bit; seems too long to spin routinely...
...
...
@@ -500,6 +504,7 @@ static int ehci_hub_control (
if
(
temp
&
PORT_OWNER
)
break
;
temp
&=
~
PORT_RWC_BITS
;
switch
(
wValue
)
{
case
USB_PORT_FEAT_SUSPEND
:
if
((
temp
&
PORT_PE
)
==
0
...
...
drivers/usb/host/ehci.h
浏览文件 @
cc6120c6
...
...
@@ -263,6 +263,7 @@ struct ehci_regs {
#define PORT_PE (1<<2)
/* port enable */
#define PORT_CSC (1<<1)
/* connect status change */
#define PORT_CONNECT (1<<0)
/* device connected */
#define PORT_RWC_BITS (PORT_CSC | PORT_PEC | PORT_OCC)
}
__attribute__
((
packed
));
/* Appendix C, Debug port ... intended for use with special "debug devices"
...
...
drivers/usb/host/ohci-dbg.c
浏览文件 @
cc6120c6
...
...
@@ -228,23 +228,22 @@ ohci_dump_roothub (
char
**
next
,
unsigned
*
size
)
{
u32
temp
,
ndp
,
i
;
u32
temp
,
i
;
temp
=
roothub_a
(
controller
);
if
(
temp
==
~
(
u32
)
0
)
return
;
ndp
=
(
temp
&
RH_A_NDP
);
if
(
verbose
)
{
ohci_dbg_sw
(
controller
,
next
,
size
,
"roothub.a %08x POTPGT=%d%s%s%s%s%s NDP=%d
\n
"
,
temp
,
"roothub.a %08x POTPGT=%d%s%s%s%s%s NDP=%d
(%d)
\n
"
,
temp
,
((
temp
&
RH_A_POTPGT
)
>>
24
)
&
0xff
,
(
temp
&
RH_A_NOCP
)
?
" NOCP"
:
""
,
(
temp
&
RH_A_OCPM
)
?
" OCPM"
:
""
,
(
temp
&
RH_A_DT
)
?
" DT"
:
""
,
(
temp
&
RH_A_NPS
)
?
" NPS"
:
""
,
(
temp
&
RH_A_PSM
)
?
" PSM"
:
""
,
ndp
(
temp
&
RH_A_NDP
),
controller
->
num_ports
);
temp
=
roothub_b
(
controller
);
ohci_dbg_sw
(
controller
,
next
,
size
,
...
...
@@ -266,7 +265,7 @@ ohci_dump_roothub (
);
}
for
(
i
=
0
;
i
<
ndp
;
i
++
)
{
for
(
i
=
0
;
i
<
controller
->
num_ports
;
i
++
)
{
temp
=
roothub_portstatus
(
controller
,
i
);
dbg_port_sw
(
controller
,
i
,
temp
,
next
,
size
);
}
...
...
drivers/usb/host/ohci-hcd.c
浏览文件 @
cc6120c6
...
...
@@ -382,8 +382,7 @@ ohci_endpoint_disable (struct usb_hcd *hcd, struct usb_host_endpoint *ep)
goto
sanitize
;
}
spin_unlock_irqrestore
(
&
ohci
->
lock
,
flags
);
set_current_state
(
TASK_UNINTERRUPTIBLE
);
schedule_timeout
(
1
);
schedule_timeout_uninterruptible
(
1
);
goto
rescan
;
case
ED_IDLE
:
/* fully unlinked */
if
(
list_empty
(
&
ed
->
td_list
))
{
...
...
@@ -485,6 +484,10 @@ static int ohci_init (struct ohci_hcd *ohci)
// flush the writes
(
void
)
ohci_readl
(
ohci
,
&
ohci
->
regs
->
control
);
/* Read the number of ports unless overridden */
if
(
ohci
->
num_ports
==
0
)
ohci
->
num_ports
=
roothub_a
(
ohci
)
&
RH_A_NDP
;
if
(
ohci
->
hcca
)
return
0
;
...
...
@@ -561,10 +564,8 @@ static int ohci_run (struct ohci_hcd *ohci)
msleep
(
temp
);
temp
=
roothub_a
(
ohci
);
if
(
!
(
temp
&
RH_A_NPS
))
{
unsigned
ports
=
temp
&
RH_A_NDP
;
/* power down each port */
for
(
temp
=
0
;
temp
<
ports
;
temp
++
)
for
(
temp
=
0
;
temp
<
ohci
->
num_
ports
;
temp
++
)
ohci_writel
(
ohci
,
RH_PS_LSDA
,
&
ohci
->
regs
->
roothub
.
portstatus
[
temp
]);
}
...
...
@@ -720,6 +721,7 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs)
if
(
ints
&
OHCI_INTR_RD
)
{
ohci_vdbg
(
ohci
,
"resume detect
\n
"
);
ohci_writel
(
ohci
,
OHCI_INTR_RD
,
&
regs
->
intrstatus
);
if
(
hcd
->
state
!=
HC_STATE_QUIESCING
)
schedule_work
(
&
ohci
->
rh_resume
);
}
...
...
@@ -861,7 +863,7 @@ static int ohci_restart (struct ohci_hcd *ohci)
* and that if we try to turn them back on the root hub
* will respond to CSC processing.
*/
i
=
roothub_a
(
ohci
)
&
RH_A_NDP
;
i
=
ohci
->
num_ports
;
while
(
i
--
)
ohci_writel
(
ohci
,
RH_PS_PSS
,
&
ohci
->
regs
->
roothub
.
portstatus
[
temp
]);
...
...
drivers/usb/host/ohci-hub.c
浏览文件 @
cc6120c6
...
...
@@ -184,7 +184,7 @@ static int ohci_hub_resume (struct usb_hcd *hcd)
if
(
status
!=
-
EINPROGRESS
)
return
status
;
temp
=
roothub_a
(
ohci
)
&
RH_A_NDP
;
temp
=
ohci
->
num_ports
;
enables
=
0
;
while
(
temp
--
)
{
u32
stat
=
ohci_readl
(
ohci
,
...
...
@@ -304,7 +304,7 @@ static int
ohci_hub_status_data
(
struct
usb_hcd
*
hcd
,
char
*
buf
)
{
struct
ohci_hcd
*
ohci
=
hcd_to_ohci
(
hcd
);
int
ports
,
i
,
changed
=
0
,
length
=
1
;
int
i
,
changed
=
0
,
length
=
1
;
int
can_suspend
=
hcd
->
can_wakeup
;
unsigned
long
flags
;
...
...
@@ -319,9 +319,10 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
goto
done
;
}
ports
=
roothub_a
(
ohci
)
&
RH_A_NDP
;
if
(
ports
>
MAX_ROOT_PORTS
)
{
ohci_err
(
ohci
,
"bogus NDP=%d, rereads as NDP=%d
\n
"
,
ports
,
/* undocumented erratum seen on at least rev D */
if
((
ohci
->
flags
&
OHCI_QUIRK_AMD756
)
&&
(
roothub_a
(
ohci
)
&
RH_A_NDP
)
>
MAX_ROOT_PORTS
)
{
ohci_warn
(
ohci
,
"bogus NDP, rereads as NDP=%d
\n
"
,
ohci_readl
(
ohci
,
&
ohci
->
regs
->
roothub
.
a
)
&
RH_A_NDP
);
/* retry later; "should not happen" */
goto
done
;
...
...
@@ -332,13 +333,13 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
buf
[
0
]
=
changed
=
1
;
else
buf
[
0
]
=
0
;
if
(
ports
>
7
)
{
if
(
ohci
->
num_
ports
>
7
)
{
buf
[
1
]
=
0
;
length
++
;
}
/* look at each port */
for
(
i
=
0
;
i
<
ports
;
i
++
)
{
for
(
i
=
0
;
i
<
ohci
->
num_
ports
;
i
++
)
{
u32
status
=
roothub_portstatus
(
ohci
,
i
);
if
(
status
&
(
RH_PS_CSC
|
RH_PS_PESC
|
RH_PS_PSSC
...
...
@@ -395,15 +396,14 @@ ohci_hub_descriptor (
struct
usb_hub_descriptor
*
desc
)
{
u32
rh
=
roothub_a
(
ohci
);
int
ports
=
rh
&
RH_A_NDP
;
u16
temp
;
desc
->
bDescriptorType
=
0x29
;
desc
->
bPwrOn2PwrGood
=
(
rh
&
RH_A_POTPGT
)
>>
24
;
desc
->
bHubContrCurrent
=
0
;
desc
->
bNbrPorts
=
ports
;
temp
=
1
+
(
ports
/
8
);
desc
->
bNbrPorts
=
ohci
->
num_
ports
;
temp
=
1
+
(
ohci
->
num_
ports
/
8
);
desc
->
bDescLength
=
7
+
2
*
temp
;
temp
=
0
;
...
...
@@ -421,7 +421,7 @@ ohci_hub_descriptor (
rh
=
roothub_b
(
ohci
);
memset
(
desc
->
bitmap
,
0xff
,
sizeof
(
desc
->
bitmap
));
desc
->
bitmap
[
0
]
=
rh
&
RH_B_DR
;
if
(
ports
>
7
)
{
if
(
ohci
->
num_
ports
>
7
)
{
desc
->
bitmap
[
1
]
=
(
rh
&
RH_B_DR
)
>>
8
;
desc
->
bitmap
[
2
]
=
0xff
;
}
else
...
...
drivers/usb/host/ohci-pxa27x.c
浏览文件 @
cc6120c6
...
...
@@ -75,33 +75,6 @@ static int pxa27x_ohci_select_pmm( int mode )
return
0
;
}
/*
If you select PMM_PERPORT_MODE, you should set the port power
*/
static
int
pxa27x_ohci_set_port_power
(
int
port
)
{
if
(
(
pxa27x_ohci_pmm_state
==
PMM_PERPORT_MODE
)
&&
(
port
>
0
)
&&
(
port
<
PXA_UHC_MAX_PORTNUM
)
)
{
UHCRHPS
(
port
)
|=
0x100
;
return
0
;
}
return
-
1
;
}
/*
If you select PMM_PERPORT_MODE, you should set the port power
*/
static
int
pxa27x_ohci_clear_port_power
(
int
port
)
{
if
(
(
pxa27x_ohci_pmm_state
==
PMM_PERPORT_MODE
)
&&
(
port
>
0
)
&&
(
port
<
PXA_UHC_MAX_PORTNUM
)
)
{
UHCRHPS
(
port
)
|=
0x200
;
return
0
;
}
return
-
1
;
}
extern
int
usb_disabled
(
void
);
/*-------------------------------------------------------------------------*/
...
...
@@ -130,11 +103,17 @@ static void pxa27x_start_hc(struct platform_device *dev)
Polarity Low to active low. Supply power to USB ports. */
UHCHR
=
(
UHCHR
|
UHCHR_PCPL
|
UHCHR_PSPL
)
&
~
(
UHCHR_SSEP1
|
UHCHR_SSEP2
|
UHCHR_SSEP3
|
UHCHR_SSE
);
pxa27x_ohci_pmm_state
=
PMM_PERPORT_MODE
;
}
UHCHR
&=
~
UHCHR_SSE
;
UHCHIE
=
(
UHCHIE_UPRIE
|
UHCHIE_RWIE
);
/* Clear any OTG Pin Hold */
if
(
PSSR
&
PSSR_OTGPH
)
PSSR
|=
PSSR_OTGPH
;
}
static
void
pxa27x_stop_hc
(
struct
platform_device
*
dev
)
...
...
@@ -198,17 +177,7 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver,
pxa27x_start_hc
(
dev
);
/* Select Power Management Mode */
pxa27x_ohci_select_pmm
(
PMM_PERPORT_MODE
);
/* If choosing PMM_PERPORT_MODE, we should set the port power before we use it. */
if
(
pxa27x_ohci_set_port_power
(
1
)
<
0
)
printk
(
KERN_ERR
"Setting port 1 power failed.
\n
"
);
if
(
pxa27x_ohci_clear_port_power
(
2
)
<
0
)
printk
(
KERN_ERR
"Setting port 2 power failed.
\n
"
);
if
(
pxa27x_ohci_clear_port_power
(
3
)
<
0
)
printk
(
KERN_ERR
"Setting port 3 power failed.
\n
"
);
pxa27x_ohci_select_pmm
(
pxa27x_ohci_pmm_state
);
ohci_hcd_init
(
hcd_to_ohci
(
hcd
));
...
...
@@ -258,6 +227,9 @@ ohci_pxa27x_start (struct usb_hcd *hcd)
ohci_dbg
(
ohci
,
"ohci_pxa27x_start, ohci:%p"
,
ohci
);
/* The value of NDP in roothub_a is incorrect on this hardware */
ohci
->
num_ports
=
3
;
if
((
ret
=
ohci_init
(
ohci
))
<
0
)
return
ret
;
...
...
drivers/usb/host/ohci.h
浏览文件 @
cc6120c6
...
...
@@ -383,6 +383,7 @@ struct ohci_hcd {
/*
* driver state
*/
int
num_ports
;
int
load
[
NUM_INTS
];
u32
hc_control
;
/* copy of hc control reg */
unsigned
long
next_statechange
;
/* suspend/resume */
...
...
drivers/usb/host/uhci-hcd.c
浏览文件 @
cc6120c6
...
...
@@ -97,14 +97,9 @@ static void uhci_get_current_frame_number(struct uhci_hcd *uhci);
/* to make sure it doesn't hog all of the bandwidth */
#define DEPTH_INTERVAL 5
static
inline
void
restart_timer
(
struct
uhci_hcd
*
uhci
)
{
mod_timer
(
&
uhci
->
stall_timer
,
jiffies
+
msecs_to_jiffies
(
100
));
}
#include "uhci-hub.c"
#include "uhci-debug.c"
#include "uhci-q.c"
#include "uhci-hub.c"
/*
* Make sure the controller is completely inactive, unable to
...
...
@@ -160,7 +155,6 @@ static void hc_died(struct uhci_hcd *uhci)
{
reset_hc
(
uhci
);
uhci
->
hc_inaccessible
=
1
;
del_timer
(
&
uhci
->
stall_timer
);
}
/*
...
...
@@ -287,8 +281,11 @@ __acquires(uhci->lock)
/* Enable resume-detect interrupts if they work.
* Then enter Global Suspend mode, still configured.
*/
int_enable
=
(
resume_detect_interrupts_are_broken
(
uhci
)
?
0
:
USBINTR_RESUME
);
uhci
->
working_RD
=
1
;
int_enable
=
USBINTR_RESUME
;
if
(
resume_detect_interrupts_are_broken
(
uhci
))
{
uhci
->
working_RD
=
int_enable
=
0
;
}
outw
(
int_enable
,
uhci
->
io_addr
+
USBINTR
);
outw
(
USBCMD_EGSM
|
USBCMD_CF
,
uhci
->
io_addr
+
USBCMD
);
mb
();
...
...
@@ -315,7 +312,6 @@ __acquires(uhci->lock)
uhci
->
rh_state
=
new_state
;
uhci
->
is_stopped
=
UHCI_IS_STOPPED
;
del_timer
(
&
uhci
->
stall_timer
);
uhci_to_hcd
(
uhci
)
->
poll_rh
=
!
int_enable
;
uhci_scan_schedule
(
uhci
,
NULL
);
...
...
@@ -335,7 +331,6 @@ static void start_rh(struct uhci_hcd *uhci)
mb
();
uhci
->
rh_state
=
UHCI_RH_RUNNING
;
uhci_to_hcd
(
uhci
)
->
poll_rh
=
1
;
restart_timer
(
uhci
);
}
static
void
wakeup_rh
(
struct
uhci_hcd
*
uhci
)
...
...
@@ -374,20 +369,6 @@ __acquires(uhci->lock)
mod_timer
(
&
uhci_to_hcd
(
uhci
)
->
rh_timer
,
jiffies
);
}
static
void
stall_callback
(
unsigned
long
_uhci
)
{
struct
uhci_hcd
*
uhci
=
(
struct
uhci_hcd
*
)
_uhci
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
uhci
->
lock
,
flags
);
uhci_scan_schedule
(
uhci
,
NULL
);
check_fsbr
(
uhci
);
if
(
!
uhci
->
is_stopped
)
restart_timer
(
uhci
);
spin_unlock_irqrestore
(
&
uhci
->
lock
,
flags
);
}
static
irqreturn_t
uhci_irq
(
struct
usb_hcd
*
hcd
,
struct
pt_regs
*
regs
)
{
struct
uhci_hcd
*
uhci
=
hcd_to_uhci
(
hcd
);
...
...
@@ -418,8 +399,10 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs)
"host controller halted, "
"very bad!
\n
"
);
hc_died
(
uhci
);
spin_unlock_irqrestore
(
&
uhci
->
lock
,
flags
);
return
IRQ_HANDLED
;
/* Force a callback in case there are
* pending unlinks */
mod_timer
(
&
hcd
->
rh_timer
,
jiffies
);
}
spin_unlock_irqrestore
(
&
uhci
->
lock
,
flags
);
}
...
...
@@ -427,10 +410,11 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs)
if
(
status
&
USBSTS_RD
)
usb_hcd_poll_rh_status
(
hcd
);
spin_lock_irqsave
(
&
uhci
->
lock
,
flags
);
uhci_scan_schedule
(
uhci
,
regs
);
spin_unlock_irqrestore
(
&
uhci
->
lock
,
flags
);
else
{
spin_lock_irqsave
(
&
uhci
->
lock
,
flags
);
uhci_scan_schedule
(
uhci
,
regs
);
spin_unlock_irqrestore
(
&
uhci
->
lock
,
flags
);
}
return
IRQ_HANDLED
;
}
...
...
@@ -595,10 +579,6 @@ static int uhci_start(struct usb_hcd *hcd)
init_waitqueue_head
(
&
uhci
->
waitqh
);
init_timer
(
&
uhci
->
stall_timer
);
uhci
->
stall_timer
.
function
=
stall_callback
;
uhci
->
stall_timer
.
data
=
(
unsigned
long
)
uhci
;
uhci
->
fl
=
dma_alloc_coherent
(
uhci_dev
(
uhci
),
sizeof
(
*
uhci
->
fl
),
&
dma_handle
,
0
);
if
(
!
uhci
->
fl
)
{
...
...
@@ -745,11 +725,11 @@ static void uhci_stop(struct usb_hcd *hcd)
struct
uhci_hcd
*
uhci
=
hcd_to_uhci
(
hcd
);
spin_lock_irq
(
&
uhci
->
lock
);
reset_hc
(
uhci
);
if
(
!
uhci
->
hc_inaccessible
)
reset_hc
(
uhci
);
uhci_scan_schedule
(
uhci
,
NULL
);
spin_unlock_irq
(
&
uhci
->
lock
);
del_timer_sync
(
&
uhci
->
stall_timer
);
release_uhci
(
uhci
);
}
...
...
@@ -811,13 +791,12 @@ static int uhci_suspend(struct usb_hcd *hcd, pm_message_t message)
*/
pci_write_config_word
(
to_pci_dev
(
uhci_dev
(
uhci
)),
USBLEGSUP
,
0
);
uhci
->
hc_inaccessible
=
1
;
hcd
->
poll_rh
=
0
;
/* FIXME: Enable non-PME# remote wakeup? */
done:
spin_unlock_irq
(
&
uhci
->
lock
);
if
(
rc
==
0
)
del_timer_sync
(
&
hcd
->
rh_timer
);
return
rc
;
}
...
...
@@ -850,8 +829,11 @@ static int uhci_resume(struct usb_hcd *hcd)
spin_unlock_irq
(
&
uhci
->
lock
);
if
(
hcd
->
poll_rh
)
if
(
!
uhci
->
working_RD
)
{
/* Suspended root hub needs to be polled */
hcd
->
poll_rh
=
1
;
usb_hcd_poll_rh_status
(
hcd
);
}
return
0
;
}
#endif
...
...
drivers/usb/host/uhci-hcd.h
浏览文件 @
cc6120c6
...
...
@@ -345,9 +345,6 @@ enum uhci_rh_state {
/*
* This describes the full uhci information.
*
* Note how the "proper" USB information is just
* a subset of what the full implementation needs.
*/
struct
uhci_hcd
{
...
...
@@ -360,8 +357,6 @@ struct uhci_hcd {
struct
dma_pool
*
qh_pool
;
struct
dma_pool
*
td_pool
;
struct
usb_bus
*
bus
;
struct
uhci_td
*
term_td
;
/* Terminating TD, see UHCI bug */
struct
uhci_qh
*
skelqh
[
UHCI_NUM_SKELQH
];
/* Skeleton QH's */
...
...
@@ -380,6 +375,8 @@ struct uhci_hcd {
unsigned
int
scan_in_progress
:
1
;
/* Schedule scan is running */
unsigned
int
need_rescan
:
1
;
/* Redo the schedule scan */
unsigned
int
hc_inaccessible
:
1
;
/* HC is suspended or dead */
unsigned
int
working_RD
:
1
;
/* Suspended root hub doesn't
need to be polled */
/* Support for port suspend/resume/reset */
unsigned
long
port_c_suspend
;
/* Bit-arrays of ports */
...
...
@@ -405,9 +402,7 @@ struct uhci_hcd {
/* List of URB's awaiting completion callback */
struct
list_head
complete_list
;
/* P: uhci->lock */
int
rh_numports
;
struct
timer_list
stall_timer
;
int
rh_numports
;
/* Number of root-hub ports */
wait_queue_head_t
waitqh
;
/* endpoint_disable waiters */
};
...
...
drivers/usb/host/uhci-hub.c
浏览文件 @
cc6120c6
...
...
@@ -145,15 +145,16 @@ static int uhci_hub_status_data(struct usb_hcd *hcd, char *buf)
{
struct
uhci_hcd
*
uhci
=
hcd_to_uhci
(
hcd
);
unsigned
long
flags
;
int
status
;
int
status
=
0
;
spin_lock_irqsave
(
&
uhci
->
lock
,
flags
);
if
(
uhci
->
hc_inaccessible
)
{
status
=
0
;
goto
done
;
}
uhci_scan_schedule
(
uhci
,
NULL
);
if
(
uhci
->
hc_inaccessible
)
goto
done
;
check_fsbr
(
uhci
);
uhci_check_ports
(
uhci
);
status
=
get_hub_status_data
(
uhci
,
buf
);
switch
(
uhci
->
rh_state
)
{
...
...
drivers/usb/host/uhci-q.c
浏览文件 @
cc6120c6
...
...
@@ -33,7 +33,7 @@ static void uhci_free_pending_tds(struct uhci_hcd *uhci);
static
inline
void
uhci_set_next_interrupt
(
struct
uhci_hcd
*
uhci
)
{
if
(
uhci
->
is_stopped
)
mod_timer
(
&
uhci
->
stall
_timer
,
jiffies
);
mod_timer
(
&
uhci
_to_hcd
(
uhci
)
->
rh
_timer
,
jiffies
);
uhci
->
term_td
->
status
|=
cpu_to_le32
(
TD_CTRL_IOC
);
}
...
...
drivers/usb/input/Kconfig
浏览文件 @
cc6120c6
...
...
@@ -286,3 +286,23 @@ config USB_KEYSPAN_REMOTE
To compile this driver as a module, choose M here: the module will
be called keyspan_remote.
config USB_APPLETOUCH
tristate "Apple USB Touchpad support"
depends on USB && INPUT
---help---
Say Y here if you want to use an Apple USB Touchpad.
These are the touchpads that can be found on post-February 2005
Apple Powerbooks (prior models have a Synaptics touchpad connected
to the ADB bus).
This driver provides a basic mouse driver but can be interfaced
with the synaptics X11 driver to provide acceleration and
scrolling in X11.
For further information, see
<file:Documentation/input/appletouch.txt>.
To compile this driver as a module, choose M here: the
module will be called appletouch.
drivers/usb/input/Makefile
浏览文件 @
cc6120c6
...
...
@@ -41,3 +41,4 @@ obj-$(CONFIG_USB_WACOM) += wacom.o
obj-$(CONFIG_USB_ACECAD)
+=
acecad.o
obj-$(CONFIG_USB_YEALINK)
+=
yealink.o
obj-$(CONFIG_USB_XPAD)
+=
xpad.o
obj-$(CONFIG_USB_APPLETOUCH)
+=
appletouch.o
drivers/usb/input/appletouch.c
0 → 100644
浏览文件 @
cc6120c6
/*
* Apple USB Touchpad (for post-February 2005 PowerBooks) driver
*
* Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
* Copyright (C) 2005 Johannes Berg (johannes@sipsolutions.net)
* Copyright (C) 2005 Stelian Pop (stelian@popies.net)
* Copyright (C) 2005 Frank Arnold (frank@scirocco-5v-turbo.de)
* Copyright (C) 2005 Peter Osterlund (petero2@telia.com)
*
* Thanks to Alex Harper <basilisk@foobox.net> for his inputs.
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/usb.h>
#include <linux/input.h>
#include <linux/usb_input.h>
/* Apple has powerbooks which have the keyboard with different Product IDs */
#define APPLE_VENDOR_ID 0x05AC
#define ATP_DEVICE(prod) \
.match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
USB_DEVICE_ID_MATCH_INT_CLASS | \
USB_DEVICE_ID_MATCH_INT_PROTOCOL, \
.idVendor = APPLE_VENDOR_ID, \
.idProduct = (prod), \
.bInterfaceClass = 0x03, \
.bInterfaceProtocol = 0x02
/* table of devices that work with this driver */
static
struct
usb_device_id
atp_table
[]
=
{
{
ATP_DEVICE
(
0x020E
)
},
{
ATP_DEVICE
(
0x020F
)
},
{
ATP_DEVICE
(
0x030A
)
},
{
ATP_DEVICE
(
0x030B
)
},
{
}
/* Terminating entry */
};
MODULE_DEVICE_TABLE
(
usb
,
atp_table
);
/* size of a USB urb transfer */
#define ATP_DATASIZE 81
/*
* number of sensors. Note that only 16 instead of 26 X (horizontal)
* sensors exist on 12" and 15" PowerBooks. All models have 16 Y
* (vertical) sensors.
*/
#define ATP_XSENSORS 26
#define ATP_YSENSORS 16
/* amount of fuzz this touchpad generates */
#define ATP_FUZZ 16
/* maximum pressure this driver will report */
#define ATP_PRESSURE 300
/*
* multiplication factor for the X and Y coordinates.
* We try to keep the touchpad aspect ratio while still doing only simple
* arithmetics.
* The factors below give coordinates like:
* 0 <= x < 960 on 12" and 15" Powerbooks
* 0 <= x < 1600 on 17" Powerbooks
* 0 <= y < 646
*/
#define ATP_XFACT 64
#define ATP_YFACT 43
/*
* Threshold for the touchpad sensors. Any change less than ATP_THRESHOLD is
* ignored.
*/
#define ATP_THRESHOLD 5
/* Structure to hold all of our device specific stuff */
struct
atp
{
struct
usb_device
*
udev
;
/* usb device */
struct
urb
*
urb
;
/* usb request block */
signed
char
*
data
;
/* transferred data */
int
open
;
/* non-zero if opened */
struct
input_dev
input
;
/* input dev */
int
valid
;
/* are the sensors valid ? */
int
x_old
;
/* last reported x/y, */
int
y_old
;
/* used for smoothing */
/* current value of the sensors */
signed
char
xy_cur
[
ATP_XSENSORS
+
ATP_YSENSORS
];
/* last value of the sensors */
signed
char
xy_old
[
ATP_XSENSORS
+
ATP_YSENSORS
];
/* accumulated sensors */
int
xy_acc
[
ATP_XSENSORS
+
ATP_YSENSORS
];
};
#define dbg_dump(msg, tab) \
if (debug > 1) { \
int i; \
printk("appletouch: %s %lld", msg, (long long)jiffies); \
for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++) \
printk(" %02x", tab[i]); \
printk("\n"); \
}
#define dprintk(format, a...) \
do { \
if (debug) printk(format, ##a); \
} while (0)
MODULE_AUTHOR
(
"Johannes Berg, Stelian Pop, Frank Arnold"
);
MODULE_DESCRIPTION
(
"Apple PowerBooks USB touchpad driver"
);
MODULE_LICENSE
(
"GPL"
);
static
int
debug
=
1
;
module_param
(
debug
,
int
,
0644
);
MODULE_PARM_DESC
(
debug
,
"Activate debugging output"
);
static
int
atp_calculate_abs
(
int
*
xy_sensors
,
int
nb_sensors
,
int
fact
,
int
*
z
,
int
*
fingers
)
{
int
i
;
/* values to calculate mean */
int
pcum
=
0
,
psum
=
0
;
*
fingers
=
0
;
for
(
i
=
0
;
i
<
nb_sensors
;
i
++
)
{
if
(
xy_sensors
[
i
]
<
ATP_THRESHOLD
)
continue
;
if
((
i
-
1
<
0
)
||
(
xy_sensors
[
i
-
1
]
<
ATP_THRESHOLD
))
(
*
fingers
)
++
;
pcum
+=
xy_sensors
[
i
]
*
i
;
psum
+=
xy_sensors
[
i
];
}
if
(
psum
>
0
)
{
*
z
=
psum
;
return
pcum
*
fact
/
psum
;
}
return
0
;
}
static
inline
void
atp_report_fingers
(
struct
input_dev
*
input
,
int
fingers
)
{
input_report_key
(
input
,
BTN_TOOL_FINGER
,
fingers
==
1
);
input_report_key
(
input
,
BTN_TOOL_DOUBLETAP
,
fingers
==
2
);
input_report_key
(
input
,
BTN_TOOL_TRIPLETAP
,
fingers
>
2
);
}
static
void
atp_complete
(
struct
urb
*
urb
,
struct
pt_regs
*
regs
)
{
int
x
,
y
,
x_z
,
y_z
,
x_f
,
y_f
;
int
retval
,
i
;
struct
atp
*
dev
=
urb
->
context
;
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
;
}
/* drop incomplete datasets */
if
(
dev
->
urb
->
actual_length
!=
ATP_DATASIZE
)
{
dprintk
(
"appletouch: incomplete data package.
\n
"
);
goto
exit
;
}
/* reorder the sensors values */
for
(
i
=
0
;
i
<
8
;
i
++
)
{
/* X values */
dev
->
xy_cur
[
i
]
=
dev
->
data
[
5
*
i
+
2
];
dev
->
xy_cur
[
i
+
8
]
=
dev
->
data
[
5
*
i
+
4
];
dev
->
xy_cur
[
i
+
16
]
=
dev
->
data
[
5
*
i
+
42
];
if
(
i
<
2
)
dev
->
xy_cur
[
i
+
24
]
=
dev
->
data
[
5
*
i
+
44
];
/* Y values */
dev
->
xy_cur
[
i
+
26
]
=
dev
->
data
[
5
*
i
+
1
];
dev
->
xy_cur
[
i
+
34
]
=
dev
->
data
[
5
*
i
+
3
];
}
dbg_dump
(
"sample"
,
dev
->
xy_cur
);
if
(
!
dev
->
valid
)
{
/* first sample */
dev
->
valid
=
1
;
dev
->
x_old
=
dev
->
y_old
=
-
1
;
memcpy
(
dev
->
xy_old
,
dev
->
xy_cur
,
sizeof
(
dev
->
xy_old
));
/* 17" Powerbooks have 10 extra X sensors */
for
(
i
=
16
;
i
<
ATP_XSENSORS
;
i
++
)
if
(
dev
->
xy_cur
[
i
])
{
printk
(
"appletouch: 17
\"
model detected.
\n
"
);
input_set_abs_params
(
&
dev
->
input
,
ABS_X
,
0
,
(
ATP_XSENSORS
-
1
)
*
ATP_XFACT
-
1
,
ATP_FUZZ
,
0
);
break
;
}
goto
exit
;
}
for
(
i
=
0
;
i
<
ATP_XSENSORS
+
ATP_YSENSORS
;
i
++
)
{
/* accumulate the change */
signed
char
change
=
dev
->
xy_old
[
i
]
-
dev
->
xy_cur
[
i
];
dev
->
xy_acc
[
i
]
-=
change
;
/* prevent down drifting */
if
(
dev
->
xy_acc
[
i
]
<
0
)
dev
->
xy_acc
[
i
]
=
0
;
}
memcpy
(
dev
->
xy_old
,
dev
->
xy_cur
,
sizeof
(
dev
->
xy_old
));
dbg_dump
(
"accumulator"
,
dev
->
xy_acc
);
x
=
atp_calculate_abs
(
dev
->
xy_acc
,
ATP_XSENSORS
,
ATP_XFACT
,
&
x_z
,
&
x_f
);
y
=
atp_calculate_abs
(
dev
->
xy_acc
+
ATP_XSENSORS
,
ATP_YSENSORS
,
ATP_YFACT
,
&
y_z
,
&
y_f
);
if
(
x
&&
y
)
{
if
(
dev
->
x_old
!=
-
1
)
{
x
=
(
dev
->
x_old
*
3
+
x
)
>>
2
;
y
=
(
dev
->
y_old
*
3
+
y
)
>>
2
;
dev
->
x_old
=
x
;
dev
->
y_old
=
y
;
if
(
debug
>
1
)
printk
(
"appletouch: X: %3d Y: %3d "
"Xz: %3d Yz: %3d
\n
"
,
x
,
y
,
x_z
,
y_z
);
input_report_key
(
&
dev
->
input
,
BTN_TOUCH
,
1
);
input_report_abs
(
&
dev
->
input
,
ABS_X
,
x
);
input_report_abs
(
&
dev
->
input
,
ABS_Y
,
y
);
input_report_abs
(
&
dev
->
input
,
ABS_PRESSURE
,
min
(
ATP_PRESSURE
,
x_z
+
y_z
));
atp_report_fingers
(
&
dev
->
input
,
max
(
x_f
,
y_f
));
}
dev
->
x_old
=
x
;
dev
->
y_old
=
y
;
}
else
if
(
!
x
&&
!
y
)
{
dev
->
x_old
=
dev
->
y_old
=
-
1
;
input_report_key
(
&
dev
->
input
,
BTN_TOUCH
,
0
);
input_report_abs
(
&
dev
->
input
,
ABS_PRESSURE
,
0
);
atp_report_fingers
(
&
dev
->
input
,
0
);
/* reset the accumulator on release */
memset
(
dev
->
xy_acc
,
0
,
sizeof
(
dev
->
xy_acc
));
}
input_report_key
(
&
dev
->
input
,
BTN_LEFT
,
!!
dev
->
data
[
80
]);
input_sync
(
&
dev
->
input
);
exit:
retval
=
usb_submit_urb
(
dev
->
urb
,
GFP_ATOMIC
);
if
(
retval
)
{
err
(
"%s - usb_submit_urb failed with result %d"
,
__FUNCTION__
,
retval
);
}
}
static
int
atp_open
(
struct
input_dev
*
input
)
{
struct
atp
*
dev
=
input
->
private
;
if
(
usb_submit_urb
(
dev
->
urb
,
GFP_ATOMIC
))
return
-
EIO
;
dev
->
open
=
1
;
return
0
;
}
static
void
atp_close
(
struct
input_dev
*
input
)
{
struct
atp
*
dev
=
input
->
private
;
usb_kill_urb
(
dev
->
urb
);
dev
->
open
=
0
;
}
static
int
atp_probe
(
struct
usb_interface
*
iface
,
const
struct
usb_device_id
*
id
)
{
struct
atp
*
dev
=
NULL
;
struct
usb_host_interface
*
iface_desc
;
struct
usb_endpoint_descriptor
*
endpoint
;
int
int_in_endpointAddr
=
0
;
int
i
,
retval
=
-
ENOMEM
;
/* allocate memory for our device state and initialize it */
dev
=
kmalloc
(
sizeof
(
struct
atp
),
GFP_KERNEL
);
if
(
dev
==
NULL
)
{
err
(
"Out of memory"
);
goto
err_kmalloc
;
}
memset
(
dev
,
0
,
sizeof
(
struct
atp
));
dev
->
udev
=
interface_to_usbdev
(
iface
);
/* set up the endpoint information */
/* use only the first interrupt-in endpoint */
iface_desc
=
iface
->
cur_altsetting
;
for
(
i
=
0
;
i
<
iface_desc
->
desc
.
bNumEndpoints
;
i
++
)
{
endpoint
=
&
iface_desc
->
endpoint
[
i
].
desc
;
if
(
!
int_in_endpointAddr
&&
(
endpoint
->
bEndpointAddress
&
USB_DIR_IN
)
&&
((
endpoint
->
bmAttributes
&
USB_ENDPOINT_XFERTYPE_MASK
)
==
USB_ENDPOINT_XFER_INT
))
{
/* we found an interrupt in endpoint */
int_in_endpointAddr
=
endpoint
->
bEndpointAddress
;
break
;
}
}
if
(
!
int_in_endpointAddr
)
{
retval
=
-
EIO
;
err
(
"Could not find int-in endpoint"
);
goto
err_endpoint
;
}
/* save our data pointer in this interface device */
usb_set_intfdata
(
iface
,
dev
);
dev
->
urb
=
usb_alloc_urb
(
0
,
GFP_KERNEL
);
if
(
!
dev
->
urb
)
{
retval
=
-
ENOMEM
;
goto
err_usballoc
;
}
dev
->
data
=
usb_buffer_alloc
(
dev
->
udev
,
ATP_DATASIZE
,
GFP_KERNEL
,
&
dev
->
urb
->
transfer_dma
);
if
(
!
dev
->
data
)
{
retval
=
-
ENOMEM
;
goto
err_usbbufalloc
;
}
usb_fill_int_urb
(
dev
->
urb
,
dev
->
udev
,
usb_rcvintpipe
(
dev
->
udev
,
int_in_endpointAddr
),
dev
->
data
,
ATP_DATASIZE
,
atp_complete
,
dev
,
1
);
init_input_dev
(
&
dev
->
input
);
dev
->
input
.
name
=
"appletouch"
;
dev
->
input
.
dev
=
&
iface
->
dev
;
dev
->
input
.
private
=
dev
;
dev
->
input
.
open
=
atp_open
;
dev
->
input
.
close
=
atp_close
;
usb_to_input_id
(
dev
->
udev
,
&
dev
->
input
.
id
);
set_bit
(
EV_ABS
,
dev
->
input
.
evbit
);
/*
* 12" and 15" Powerbooks only have 16 x sensors,
* 17" models are detected later.
*/
input_set_abs_params
(
&
dev
->
input
,
ABS_X
,
0
,
(
16
-
1
)
*
ATP_XFACT
-
1
,
ATP_FUZZ
,
0
);
input_set_abs_params
(
&
dev
->
input
,
ABS_Y
,
0
,
(
ATP_YSENSORS
-
1
)
*
ATP_YFACT
-
1
,
ATP_FUZZ
,
0
);
input_set_abs_params
(
&
dev
->
input
,
ABS_PRESSURE
,
0
,
ATP_PRESSURE
,
0
,
0
);
set_bit
(
EV_KEY
,
dev
->
input
.
evbit
);
set_bit
(
BTN_TOUCH
,
dev
->
input
.
keybit
);
set_bit
(
BTN_TOOL_FINGER
,
dev
->
input
.
keybit
);
set_bit
(
BTN_TOOL_DOUBLETAP
,
dev
->
input
.
keybit
);
set_bit
(
BTN_TOOL_TRIPLETAP
,
dev
->
input
.
keybit
);
set_bit
(
BTN_LEFT
,
dev
->
input
.
keybit
);
input_register_device
(
&
dev
->
input
);
printk
(
KERN_INFO
"input: appletouch connected
\n
"
);
return
0
;
err_usbbufalloc:
usb_free_urb
(
dev
->
urb
);
err_usballoc:
usb_set_intfdata
(
iface
,
NULL
);
err_endpoint:
kfree
(
dev
);
err_kmalloc:
return
retval
;
}
static
void
atp_disconnect
(
struct
usb_interface
*
iface
)
{
struct
atp
*
dev
=
usb_get_intfdata
(
iface
);
usb_set_intfdata
(
iface
,
NULL
);
if
(
dev
)
{
usb_kill_urb
(
dev
->
urb
);
input_unregister_device
(
&
dev
->
input
);
usb_free_urb
(
dev
->
urb
);
usb_buffer_free
(
dev
->
udev
,
ATP_DATASIZE
,
dev
->
data
,
dev
->
urb
->
transfer_dma
);
kfree
(
dev
);
}
printk
(
KERN_INFO
"input: appletouch disconnected
\n
"
);
}
static
int
atp_suspend
(
struct
usb_interface
*
iface
,
pm_message_t
message
)
{
struct
atp
*
dev
=
usb_get_intfdata
(
iface
);
usb_kill_urb
(
dev
->
urb
);
dev
->
valid
=
0
;
return
0
;
}
static
int
atp_resume
(
struct
usb_interface
*
iface
)
{
struct
atp
*
dev
=
usb_get_intfdata
(
iface
);
if
(
dev
->
open
&&
usb_submit_urb
(
dev
->
urb
,
GFP_ATOMIC
))
return
-
EIO
;
return
0
;
}
static
struct
usb_driver
atp_driver
=
{
.
owner
=
THIS_MODULE
,
.
name
=
"appletouch"
,
.
probe
=
atp_probe
,
.
disconnect
=
atp_disconnect
,
.
suspend
=
atp_suspend
,
.
resume
=
atp_resume
,
.
id_table
=
atp_table
,
};
static
int
__init
atp_init
(
void
)
{
return
usb_register
(
&
atp_driver
);
}
static
void
__exit
atp_exit
(
void
)
{
usb_deregister
(
&
atp_driver
);
}
module_init
(
atp_init
);
module_exit
(
atp_exit
);
drivers/usb/input/hid-core.c
浏览文件 @
cc6120c6
...
...
@@ -1446,7 +1446,6 @@ void hid_init_reports(struct hid_device *hid)
#define USB_VENDOR_ID_APPLE 0x05ac
#define USB_DEVICE_ID_APPLE_POWERMOUSE 0x0304
#define USB_DEVICE_ID_APPLE_BLUETOOTH 0x1000
/*
* Alphabetically sorted blacklist by quirk type.
...
...
@@ -1465,7 +1464,6 @@ static struct hid_blacklist {
{
USB_VENDOR_ID_AIPTEK
,
USB_DEVICE_ID_AIPTEK_22
,
HID_QUIRK_IGNORE
},
{
USB_VENDOR_ID_AIPTEK
,
USB_DEVICE_ID_AIPTEK_23
,
HID_QUIRK_IGNORE
},
{
USB_VENDOR_ID_AIPTEK
,
USB_DEVICE_ID_AIPTEK_24
,
HID_QUIRK_IGNORE
},
{
USB_VENDOR_ID_APPLE
,
USB_DEVICE_ID_APPLE_BLUETOOTH
,
HID_QUIRK_IGNORE
},
{
USB_VENDOR_ID_BERKSHIRE
,
USB_DEVICE_ID_BERKSHIRE_PCWD
,
HID_QUIRK_IGNORE
},
{
USB_VENDOR_ID_CODEMERCS
,
USB_DEVICE_ID_CODEMERCS_IOW40
,
HID_QUIRK_IGNORE
},
{
USB_VENDOR_ID_CODEMERCS
,
USB_DEVICE_ID_CODEMERCS_IOW24
,
HID_QUIRK_IGNORE
},
...
...
drivers/usb/misc/sisusbvga/Kconfig
浏览文件 @
cc6120c6
...
...
@@ -4,11 +4,43 @@ config USB_SISUSBVGA
depends on USB && USB_EHCI_HCD
---help---
Say Y here if you intend to attach a USB2VGA dongle based on a
Net2280 and a SiS315 chip.
Note that this device requires a USB 2.0 host controller. It will not
Net2280 and a SiS315 chip.
Note that this device requires a USB 2.0 host controller. It will not
work with USB 1.x controllers.
To compile this driver as a module, choose M here: the module will be
called sisusb. If unsure, say N.
To compile this driver as a module, choose M here; the module will be
called sisusbvga. If unsure, say N.
config USB_SISUSBVGA_CON
bool "Text console and mode switching support" if USB_SISUSBVGA
depends on VT
select FONT_8x16
---help---
Say Y here if you want a VGA text console via the USB dongle or
want to support userland applications that utilize the driver's
display mode switching capabilities.
Note that this console supports VGA/EGA text mode only.
By default, the console part of the driver will not kick in when
the driver is initialized. If you want the driver to take over
one or more of the consoles, you need to specify the number of
the first and last consoles (starting at 1) as driver parameters.
For example, if the driver is compiled as a module:
modprobe sisusbvga first=1 last=5
If you use hotplug, add this to your modutils config files with
the "options" keyword, such as eg.
options sisusbvga first=1 last=5
If the driver is compiled into the kernel image, the parameters
must be given in the kernel command like, such as
sisusbvga.first=1 sisusbvga.last=5
drivers/usb/misc/sisusbvga/Makefile
浏览文件 @
cc6120c6
...
...
@@ -2,5 +2,7 @@
# Makefile for the sisusb driver (if driver is inside kernel tree).
#
obj-$(CONFIG_USB_SISUSBVGA)
+=
sisusb.o
obj-$(CONFIG_USB_SISUSBVGA)
+=
sisusbvga.o
sisusbvga-objs
:=
sisusb.o sisusb_init.o sisusb_con.o
drivers/usb/misc/sisusbvga/sisusb.c
浏览文件 @
cc6120c6
/*
* sisusb - usb kernel driver for SiS315(E) based USB2VGA dongles
*
* Main part
*
* Copyright (C) 2005 by Thomas Winischhofer, Vienna, Austria
*
* If distributed as part of the Linux kernel, this code is licensed under the
...
...
@@ -48,16 +50,60 @@
#include <linux/kref.h>
#include <linux/usb.h>
#include <linux/smp_lock.h>
#include <linux/vmalloc.h>
#include "sisusb.h"
#ifdef INCL_SISUSB_CON
#include <linux/font.h>
#endif
#define SISUSB_DONTSYNC
/* Forward declarations / clean-up routines */
#ifdef INCL_SISUSB_CON
int
sisusb_setreg
(
struct
sisusb_usb_data
*
sisusb
,
int
port
,
u8
data
);
int
sisusb_getreg
(
struct
sisusb_usb_data
*
sisusb
,
int
port
,
u8
*
data
);
int
sisusb_setidxreg
(
struct
sisusb_usb_data
*
sisusb
,
int
port
,
u8
index
,
u8
data
);
int
sisusb_getidxreg
(
struct
sisusb_usb_data
*
sisusb
,
int
port
,
u8
index
,
u8
*
data
);
int
sisusb_setidxregandor
(
struct
sisusb_usb_data
*
sisusb
,
int
port
,
u8
idx
,
u8
myand
,
u8
myor
);
int
sisusb_setidxregor
(
struct
sisusb_usb_data
*
sisusb
,
int
port
,
u8
index
,
u8
myor
);
int
sisusb_setidxregand
(
struct
sisusb_usb_data
*
sisusb
,
int
port
,
u8
idx
,
u8
myand
);
int
sisusb_writeb
(
struct
sisusb_usb_data
*
sisusb
,
u32
adr
,
u8
data
);
int
sisusb_readb
(
struct
sisusb_usb_data
*
sisusb
,
u32
adr
,
u8
*
data
);
int
sisusb_writew
(
struct
sisusb_usb_data
*
sisusb
,
u32
adr
,
u16
data
);
int
sisusb_readw
(
struct
sisusb_usb_data
*
sisusb
,
u32
adr
,
u16
*
data
);
int
sisusb_copy_memory
(
struct
sisusb_usb_data
*
sisusb
,
char
*
src
,
u32
dest
,
int
length
,
size_t
*
bytes_written
);
int
sisusb_reset_text_mode
(
struct
sisusb_usb_data
*
sisusb
,
int
init
);
extern
int
SiSUSBSetMode
(
struct
SiS_Private
*
SiS_Pr
,
unsigned
short
ModeNo
);
extern
int
SiSUSBSetVESAMode
(
struct
SiS_Private
*
SiS_Pr
,
unsigned
short
VModeNo
);
extern
void
sisusb_init_concode
(
void
);
extern
int
sisusb_console_init
(
struct
sisusb_usb_data
*
sisusb
,
int
first
,
int
last
);
extern
void
sisusb_console_exit
(
struct
sisusb_usb_data
*
sisusb
);
extern
void
sisusb_set_cursor
(
struct
sisusb_usb_data
*
sisusb
,
unsigned
int
location
);
extern
int
sisusbcon_do_font_op
(
struct
sisusb_usb_data
*
sisusb
,
int
set
,
int
slot
,
u8
*
arg
,
int
cmapsz
,
int
ch512
,
int
dorecalc
,
struct
vc_data
*
c
,
int
fh
,
int
uplock
);
static
int
sisusb_first_vc
=
0
;
static
int
sisusb_last_vc
=
0
;
module_param_named
(
first
,
sisusb_first_vc
,
int
,
0
);
module_param_named
(
last
,
sisusb_last_vc
,
int
,
0
);
MODULE_PARM_DESC
(
first
,
"Number of first console to take over (1 - MAX_NR_CONSOLES)"
);
MODULE_PARM_DESC
(
last
,
"Number of last console to take over (1 - MAX_NR_CONSOLES)"
);
#endif
static
struct
usb_driver
sisusb_driver
;
static
DECLARE_MUTEX
(
disconnect_sem
);
DECLARE_MUTEX
(
disconnect_sem
);
static
void
sisusb_free_buffers
(
struct
sisusb_usb_data
*
sisusb
)
...
...
@@ -639,7 +685,10 @@ static int sisusb_send_bridge_packet(struct sisusb_usb_data *sisusb, int len,
/* The following routines assume being used to transfer byte, word,
* long etc.
* This means that they assume "data" in machine endianness format.
* This means that
* - the write routines expect "data" in machine endianness format.
* The data will be converted to leXX in sisusb_xxx_packet.
* - the read routines can expect read data in machine-endianess.
*/
static
int
sisusb_write_memio_byte
(
struct
sisusb_usb_data
*
sisusb
,
int
type
,
...
...
@@ -839,7 +888,7 @@ static int sisusb_write_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr,
if
(
get_user
(
swap16
,
(
u16
__user
*
)
userbuffer
))
return
-
EFAULT
;
}
else
swap16
=
(
kernbuffer
[
0
]
<<
8
)
|
kernbuffer
[
1
]
;
swap16
=
*
((
u16
*
)
kernbuffer
)
;
ret
=
sisusb_write_memio_word
(
sisusb
,
SISUSB_TYPE_MEM
,
...
...
@@ -855,14 +904,25 @@ static int sisusb_write_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr,
if
(
userbuffer
)
{
if
(
copy_from_user
(
&
buf
,
userbuffer
,
3
))
return
-
EFAULT
;
#ifdef __BIG_ENDIAN
swap32
=
(
buf
[
0
]
<<
16
)
|
(
buf
[
1
]
<<
8
)
|
buf
[
2
];
#else
swap32
=
(
buf
[
2
]
<<
16
)
|
(
buf
[
1
]
<<
8
)
|
buf
[
0
];
#endif
}
else
#ifdef __BIG_ENDIAN
swap32
=
(
kernbuffer
[
0
]
<<
16
)
|
(
kernbuffer
[
1
]
<<
8
)
|
kernbuffer
[
2
];
#else
swap32
=
(
kernbuffer
[
2
]
<<
16
)
|
(
kernbuffer
[
1
]
<<
8
)
|
kernbuffer
[
0
];
#endif
ret
=
sisusb_write_memio_24bit
(
sisusb
,
SISUSB_TYPE_MEM
,
...
...
@@ -879,10 +939,7 @@ static int sisusb_write_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr,
if
(
get_user
(
swap32
,
(
u32
__user
*
)
userbuffer
))
return
-
EFAULT
;
}
else
swap32
=
(
kernbuffer
[
0
]
<<
24
)
|
(
kernbuffer
[
1
]
<<
16
)
|
(
kernbuffer
[
2
]
<<
8
)
|
kernbuffer
[
3
];
swap32
=
*
((
u32
*
)
kernbuffer
);
ret
=
sisusb_write_memio_long
(
sisusb
,
SISUSB_TYPE_MEM
,
...
...
@@ -1005,6 +1062,10 @@ static int sisusb_write_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr,
return
ret
?
-
EIO
:
0
;
}
/* Remember: Read data in packet is in machine-endianess! So for
* byte, word, 24bit, long no endian correction is necessary.
*/
static
int
sisusb_read_memio_byte
(
struct
sisusb_usb_data
*
sisusb
,
int
type
,
u32
addr
,
u8
*
data
)
{
...
...
@@ -1191,8 +1252,7 @@ static int sisusb_read_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr,
(
u16
__user
*
)
userbuffer
))
return
-
EFAULT
;
}
else
{
kernbuffer
[
0
]
=
swap16
>>
8
;
kernbuffer
[
1
]
=
swap16
&
0xff
;
*
((
u16
*
)
kernbuffer
)
=
swap16
;
}
}
return
ret
;
...
...
@@ -1202,9 +1262,15 @@ static int sisusb_read_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr,
addr
,
&
swap32
);
if
(
!
ret
)
{
(
*
bytes_read
)
+=
3
;
#ifdef __BIG_ENDIAN
buf
[
0
]
=
(
swap32
>>
16
)
&
0xff
;
buf
[
1
]
=
(
swap32
>>
8
)
&
0xff
;
buf
[
2
]
=
swap32
&
0xff
;
#else
buf
[
2
]
=
(
swap32
>>
16
)
&
0xff
;
buf
[
1
]
=
(
swap32
>>
8
)
&
0xff
;
buf
[
0
]
=
swap32
&
0xff
;
#endif
if
(
userbuffer
)
{
if
(
copy_to_user
(
userbuffer
,
&
buf
[
0
],
3
))
return
-
EFAULT
;
...
...
@@ -1228,10 +1294,7 @@ static int sisusb_read_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr,
userbuffer
+=
4
;
}
else
{
kernbuffer
[
0
]
=
(
swap32
>>
24
)
&
0xff
;
kernbuffer
[
1
]
=
(
swap32
>>
16
)
&
0xff
;
kernbuffer
[
2
]
=
(
swap32
>>
8
)
&
0xff
;
kernbuffer
[
3
]
=
swap32
&
0xff
;
*
((
u32
*
)
kernbuffer
)
=
swap32
;
kernbuffer
+=
4
;
}
addr
+=
4
;
...
...
@@ -1289,7 +1352,24 @@ static int sisusb_read_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr,
/* High level: Gfx (indexed) register access */
static
int
#ifdef INCL_SISUSB_CON
int
sisusb_setreg
(
struct
sisusb_usb_data
*
sisusb
,
int
port
,
u8
data
)
{
return
sisusb_write_memio_byte
(
sisusb
,
SISUSB_TYPE_IO
,
port
,
data
);
}
int
sisusb_getreg
(
struct
sisusb_usb_data
*
sisusb
,
int
port
,
u8
*
data
)
{
return
sisusb_read_memio_byte
(
sisusb
,
SISUSB_TYPE_IO
,
port
,
data
);
}
#endif
#ifndef INCL_SISUSB_CON
static
#endif
int
sisusb_setidxreg
(
struct
sisusb_usb_data
*
sisusb
,
int
port
,
u8
index
,
u8
data
)
{
int
ret
;
...
...
@@ -1298,7 +1378,10 @@ sisusb_setidxreg(struct sisusb_usb_data *sisusb, int port, u8 index, u8 data)
return
ret
;
}
static
int
#ifndef INCL_SISUSB_CON
static
#endif
int
sisusb_getidxreg
(
struct
sisusb_usb_data
*
sisusb
,
int
port
,
u8
index
,
u8
*
data
)
{
int
ret
;
...
...
@@ -1307,7 +1390,10 @@ sisusb_getidxreg(struct sisusb_usb_data *sisusb, int port, u8 index, u8 *data)
return
ret
;
}
static
int
#ifndef INCL_SISUSB_CON
static
#endif
int
sisusb_setidxregandor
(
struct
sisusb_usb_data
*
sisusb
,
int
port
,
u8
idx
,
u8
myand
,
u8
myor
)
{
...
...
@@ -1336,18 +1422,89 @@ sisusb_setidxregmask(struct sisusb_usb_data *sisusb, int port, u8 idx,
return
ret
;
}
static
int
#ifndef INCL_SISUSB_CON
static
#endif
int
sisusb_setidxregor
(
struct
sisusb_usb_data
*
sisusb
,
int
port
,
u8
index
,
u8
myor
)
{
return
(
sisusb_setidxregandor
(
sisusb
,
port
,
index
,
0xff
,
myor
));
}
static
int
#ifndef INCL_SISUSB_CON
static
#endif
int
sisusb_setidxregand
(
struct
sisusb_usb_data
*
sisusb
,
int
port
,
u8
idx
,
u8
myand
)
{
return
(
sisusb_setidxregandor
(
sisusb
,
port
,
idx
,
myand
,
0x00
));
}
/* Write/read video ram */
#ifdef INCL_SISUSB_CON
int
sisusb_writeb
(
struct
sisusb_usb_data
*
sisusb
,
u32
adr
,
u8
data
)
{
return
(
sisusb_write_memio_byte
(
sisusb
,
SISUSB_TYPE_MEM
,
adr
,
data
));
}
int
sisusb_readb
(
struct
sisusb_usb_data
*
sisusb
,
u32
adr
,
u8
*
data
)
{
return
(
sisusb_read_memio_byte
(
sisusb
,
SISUSB_TYPE_MEM
,
adr
,
data
));
}
int
sisusb_writew
(
struct
sisusb_usb_data
*
sisusb
,
u32
adr
,
u16
data
)
{
return
(
sisusb_write_memio_word
(
sisusb
,
SISUSB_TYPE_MEM
,
adr
,
data
));
}
int
sisusb_readw
(
struct
sisusb_usb_data
*
sisusb
,
u32
adr
,
u16
*
data
)
{
return
(
sisusb_read_memio_word
(
sisusb
,
SISUSB_TYPE_MEM
,
adr
,
data
));
}
int
sisusb_copy_memory
(
struct
sisusb_usb_data
*
sisusb
,
char
*
src
,
u32
dest
,
int
length
,
size_t
*
bytes_written
)
{
return
(
sisusb_write_mem_bulk
(
sisusb
,
dest
,
src
,
length
,
NULL
,
0
,
bytes_written
));
}
#ifdef SISUSBENDIANTEST
int
sisusb_read_memory
(
struct
sisusb_usb_data
*
sisusb
,
char
*
dest
,
u32
src
,
int
length
,
size_t
*
bytes_written
)
{
return
(
sisusb_read_mem_bulk
(
sisusb
,
src
,
dest
,
length
,
NULL
,
bytes_written
));
}
#endif
#endif
#ifdef SISUSBENDIANTEST
static
void
sisusb_testreadwrite
(
struct
sisusb_usb_data
*
sisusb
)
{
static
char
srcbuffer
[]
=
{
0x11
,
0x22
,
0x33
,
0x44
,
0x55
,
0x66
,
0x77
};
char
destbuffer
[
10
];
size_t
dummy
;
int
i
,
j
;
sisusb_copy_memory
(
sisusb
,
srcbuffer
,
sisusb
->
vrambase
,
7
,
&
dummy
);
for
(
i
=
1
;
i
<=
7
;
i
++
)
{
printk
(
KERN_DEBUG
"sisusb: rwtest %d bytes
\n
"
,
i
);
sisusb_read_memory
(
sisusb
,
destbuffer
,
sisusb
->
vrambase
,
i
,
&
dummy
);
for
(
j
=
0
;
j
<
i
;
j
++
)
{
printk
(
KERN_DEBUG
"sisusb: rwtest read[%d] = %x
\n
"
,
j
,
destbuffer
[
j
]);
}
}
}
#endif
/* access pci config registers (reg numbers 0, 4, 8, etc) */
static
int
...
...
@@ -2270,6 +2427,129 @@ sisusb_init_gfxdevice(struct sisusb_usb_data *sisusb, int initscreen)
return
ret
;
}
#ifdef INCL_SISUSB_CON
/* Set up default text mode:
- Set text mode (0x03)
- Upload default font
- Upload user font (if available)
*/
int
sisusb_reset_text_mode
(
struct
sisusb_usb_data
*
sisusb
,
int
init
)
{
int
ret
=
0
,
slot
=
sisusb
->
font_slot
,
i
;
struct
font_desc
*
myfont
;
u8
*
tempbuf
;
u16
*
tempbufb
;
size_t
written
;
static
char
bootstring
[]
=
"SiSUSB VGA text console, (C) 2005 Thomas Winischhofer."
;
static
char
bootlogo
[]
=
"(o_ //
\\
V_/_"
;
/* sisusb->lock is down */
if
(
!
sisusb
->
SiS_Pr
)
return
1
;
sisusb
->
SiS_Pr
->
IOAddress
=
SISUSB_PCI_IOPORTBASE
+
0x30
;
sisusb
->
SiS_Pr
->
sisusb
=
(
void
*
)
sisusb
;
/* Set mode 0x03 */
SiSUSBSetMode
(
sisusb
->
SiS_Pr
,
0x03
);
if
(
!
(
myfont
=
find_font
(
"VGA8x16"
)))
return
1
;
if
(
!
(
tempbuf
=
vmalloc
(
8192
)))
return
1
;
for
(
i
=
0
;
i
<
256
;
i
++
)
memcpy
(
tempbuf
+
(
i
*
32
),
myfont
->
data
+
(
i
*
16
),
16
);
/* Upload default font */
ret
=
sisusbcon_do_font_op
(
sisusb
,
1
,
0
,
tempbuf
,
8192
,
0
,
1
,
NULL
,
16
,
0
);
vfree
(
tempbuf
);
/* Upload user font (and reset current slot) */
if
(
sisusb
->
font_backup
)
{
ret
|=
sisusbcon_do_font_op
(
sisusb
,
1
,
2
,
sisusb
->
font_backup
,
8192
,
sisusb
->
font_backup_512
,
1
,
NULL
,
sisusb
->
font_backup_height
,
0
);
if
(
slot
!=
2
)
sisusbcon_do_font_op
(
sisusb
,
1
,
0
,
NULL
,
0
,
0
,
1
,
NULL
,
16
,
0
);
}
if
(
init
&&
!
sisusb
->
scrbuf
)
{
if
((
tempbuf
=
vmalloc
(
8192
)))
{
i
=
4096
;
tempbufb
=
(
u16
*
)
tempbuf
;
while
(
i
--
)
*
(
tempbufb
++
)
=
0x0720
;
i
=
0
;
tempbufb
=
(
u16
*
)
tempbuf
;
while
(
bootlogo
[
i
])
{
*
(
tempbufb
++
)
=
0x0700
|
bootlogo
[
i
++
];
if
(
!
(
i
%
4
))
tempbufb
+=
76
;
}
i
=
0
;
tempbufb
=
(
u16
*
)
tempbuf
+
6
;
while
(
bootstring
[
i
])
*
(
tempbufb
++
)
=
0x0700
|
bootstring
[
i
++
];
ret
|=
sisusb_copy_memory
(
sisusb
,
tempbuf
,
sisusb
->
vrambase
,
8192
,
&
written
);
vfree
(
tempbuf
);
}
}
else
if
(
sisusb
->
scrbuf
)
{
ret
|=
sisusb_copy_memory
(
sisusb
,
(
char
*
)
sisusb
->
scrbuf
,
sisusb
->
vrambase
,
sisusb
->
scrbuf_size
,
&
written
);
}
if
(
sisusb
->
sisusb_cursor_size_from
>=
0
&&
sisusb
->
sisusb_cursor_size_to
>=
0
)
{
sisusb_setidxreg
(
sisusb
,
SISCR
,
0x0a
,
sisusb
->
sisusb_cursor_size_from
);
sisusb_setidxregandor
(
sisusb
,
SISCR
,
0x0b
,
0xe0
,
sisusb
->
sisusb_cursor_size_to
);
}
else
{
sisusb_setidxreg
(
sisusb
,
SISCR
,
0x0a
,
0x2d
);
sisusb_setidxreg
(
sisusb
,
SISCR
,
0x0b
,
0x0e
);
sisusb
->
sisusb_cursor_size_to
=
-
1
;
}
slot
=
sisusb
->
sisusb_cursor_loc
;
if
(
slot
<
0
)
slot
=
0
;
sisusb
->
sisusb_cursor_loc
=
-
1
;
sisusb
->
bad_cursor_pos
=
1
;
sisusb_set_cursor
(
sisusb
,
slot
);
sisusb_setidxreg
(
sisusb
,
SISCR
,
0x0c
,
(
sisusb
->
cur_start_addr
>>
8
));
sisusb_setidxreg
(
sisusb
,
SISCR
,
0x0d
,
(
sisusb
->
cur_start_addr
&
0xff
));
sisusb
->
textmodedestroyed
=
0
;
/* sisusb->lock is down */
return
ret
;
}
#endif
/* fops */
static
int
...
...
@@ -2329,7 +2609,7 @@ sisusb_open(struct inode *inode, struct file *file)
}
}
/*
increment usage count for the device
*/
/*
Increment usage count for our sisusb
*/
kref_get
(
&
sisusb
->
kref
);
sisusb
->
isopen
=
1
;
...
...
@@ -2340,12 +2620,10 @@ sisusb_open(struct inode *inode, struct file *file)
up
(
&
disconnect_sem
);
printk
(
KERN_DEBUG
"sisusbvga[%d]: opened"
,
sisusb
->
minor
);
return
0
;
}
static
void
void
sisusb_delete
(
struct
kref
*
kref
)
{
struct
sisusb_usb_data
*
sisusb
=
to_sisusb_dev
(
kref
);
...
...
@@ -2359,6 +2637,9 @@ sisusb_delete(struct kref *kref)
sisusb
->
sisusb_dev
=
NULL
;
sisusb_free_buffers
(
sisusb
);
sisusb_free_urbs
(
sisusb
);
#ifdef INCL_SISUSB_CON
kfree
(
sisusb
->
SiS_Pr
);
#endif
kfree
(
sisusb
);
}
...
...
@@ -2395,8 +2676,6 @@ sisusb_release(struct inode *inode, struct file *file)
up
(
&
disconnect_sem
);
printk
(
KERN_DEBUG
"sisusbvga[%d]: released"
,
myminor
);
return
0
;
}
...
...
@@ -2733,6 +3012,12 @@ sisusb_handle_command(struct sisusb_usb_data *sisusb, struct sisusb_command *y,
int
retval
,
port
,
length
;
u32
address
;
/* All our commands require the device
* to be initialized.
*/
if
(
!
sisusb
->
devinit
)
return
-
ENODEV
;
port
=
y
->
data3
-
SISUSB_PCI_PSEUDO_IOPORTBASE
+
SISUSB_PCI_IOPORTBASE
;
...
...
@@ -2774,6 +3059,10 @@ sisusb_handle_command(struct sisusb_usb_data *sisusb, struct sisusb_command *y,
break
;
case
SUCMD_CLRSCR
:
/* Gfx core must be initialized */
if
(
!
sisusb
->
gfxinit
)
return
-
ENODEV
;
length
=
(
y
->
data0
<<
16
)
|
(
y
->
data1
<<
8
)
|
y
->
data2
;
address
=
y
->
data3
-
SISUSB_PCI_PSEUDO_MEMBASE
+
...
...
@@ -2781,11 +3070,61 @@ sisusb_handle_command(struct sisusb_usb_data *sisusb, struct sisusb_command *y,
retval
=
sisusb_clear_vram
(
sisusb
,
address
,
length
);
break
;
case
SUCMD_HANDLETEXTMODE
:
retval
=
0
;
#ifdef INCL_SISUSB_CON
/* Gfx core must be initialized, SiS_Pr must exist */
if
(
!
sisusb
->
gfxinit
||
!
sisusb
->
SiS_Pr
)
return
-
ENODEV
;
switch
(
y
->
data0
)
{
case
0
:
retval
=
sisusb_reset_text_mode
(
sisusb
,
0
);
break
;
case
1
:
sisusb
->
textmodedestroyed
=
1
;
break
;
}
#endif
break
;
#ifdef INCL_SISUSB_CON
case
SUCMD_SETMODE
:
/* Gfx core must be initialized, SiS_Pr must exist */
if
(
!
sisusb
->
gfxinit
||
!
sisusb
->
SiS_Pr
)
return
-
ENODEV
;
retval
=
0
;
sisusb
->
SiS_Pr
->
IOAddress
=
SISUSB_PCI_IOPORTBASE
+
0x30
;
sisusb
->
SiS_Pr
->
sisusb
=
(
void
*
)
sisusb
;
if
(
SiSUSBSetMode
(
sisusb
->
SiS_Pr
,
y
->
data3
))
retval
=
-
EINVAL
;
break
;
case
SUCMD_SETVESAMODE
:
/* Gfx core must be initialized, SiS_Pr must exist */
if
(
!
sisusb
->
gfxinit
||
!
sisusb
->
SiS_Pr
)
return
-
ENODEV
;
retval
=
0
;
sisusb
->
SiS_Pr
->
IOAddress
=
SISUSB_PCI_IOPORTBASE
+
0x30
;
sisusb
->
SiS_Pr
->
sisusb
=
(
void
*
)
sisusb
;
if
(
SiSUSBSetVESAMode
(
sisusb
->
SiS_Pr
,
y
->
data3
))
retval
=
-
EINVAL
;
break
;
#endif
default:
retval
=
-
EINVAL
;
}
if
(
retval
>
0
)
if
(
retval
>
0
)
retval
=
-
EIO
;
return
retval
;
...
...
@@ -2835,6 +3174,11 @@ sisusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
x
.
sisusb_vramsize
=
sisusb
->
vramsize
;
x
.
sisusb_minor
=
sisusb
->
minor
;
x
.
sisusb_fbdevactive
=
0
;
#ifdef INCL_SISUSB_CON
x
.
sisusb_conactive
=
sisusb
->
haveconsole
?
1
:
0
;
#else
x
.
sisusb_conactive
=
0
;
#endif
if
(
copy_to_user
((
void
__user
*
)
arg
,
&
x
,
sizeof
(
x
)))
retval
=
-
EFAULT
;
...
...
@@ -2895,9 +3239,13 @@ static struct file_operations usb_sisusb_fops = {
};
static
struct
usb_class_driver
usb_sisusb_class
=
{
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13)
.
name
=
"usb/sisusbvga%d"
,
.
fops
=
&
usb_sisusb_fops
,
.
mode
=
S_IFCHR
|
S_IRUSR
|
S_IWUSR
|
S_IRGRP
|
S_IWGRP
,
#else
.
name
=
"sisusbvga%d"
,
#endif
.
fops
=
&
usb_sisusb_fops
,
.
minor_base
=
SISUSB_MINOR
};
...
...
@@ -2994,12 +3342,25 @@ static int sisusb_probe(struct usb_interface *intf,
printk
(
KERN_INFO
"sisusbvga[%d]: Allocated %d output buffers
\n
"
,
sisusb
->
minor
,
sisusb
->
numobufs
);
#ifdef INCL_SISUSB_CON
/* Allocate our SiS_Pr */
if
(
!
(
sisusb
->
SiS_Pr
=
kmalloc
(
sizeof
(
struct
SiS_Private
),
GFP_KERNEL
)))
{
printk
(
KERN_ERR
"sisusbvga[%d]: Failed to allocate SiS_Pr
\n
"
,
sisusb
->
minor
);
}
#endif
/* Do remaining init stuff */
init_waitqueue_head
(
&
sisusb
->
wait_q
);
usb_set_intfdata
(
intf
,
sisusb
);
usb_get_dev
(
sisusb
->
sisusb_dev
);
sisusb
->
present
=
1
;
#ifdef SISUSB_OLD_CONFIG_COMPAT
{
int
ret
;
...
...
@@ -3014,14 +3375,19 @@ static int sisusb_probe(struct usb_interface *intf,
sisusb
->
minor
);
else
sisusb
->
ioctl32registered
=
1
;
}
#endif
sisusb
->
present
=
1
;
if
(
dev
->
speed
==
USB_SPEED_HIGH
)
{
if
(
sisusb_init_gfxdevice
(
sisusb
,
1
))
int
initscreen
=
1
;
#ifdef INCL_SISUSB_CON
if
(
sisusb_first_vc
>
0
&&
sisusb_last_vc
>
0
&&
sisusb_first_vc
<=
sisusb_last_vc
&&
sisusb_last_vc
<=
MAX_NR_CONSOLES
)
initscreen
=
0
;
#endif
if
(
sisusb_init_gfxdevice
(
sisusb
,
initscreen
))
printk
(
KERN_ERR
"sisusbvga[%d]: Failed to early "
"initialize device
\n
"
,
...
...
@@ -3035,6 +3401,16 @@ static int sisusb_probe(struct usb_interface *intf,
sisusb
->
ready
=
1
;
#ifdef SISUSBENDIANTEST
printk
(
KERN_DEBUG
"sisusb: *** RWTEST ***
\n
"
);
sisusb_testreadwrite
(
sisusb
);
printk
(
KERN_DEBUG
"sisusb: *** RWTEST END ***
\n
"
);
#endif
#ifdef INCL_SISUSB_CON
sisusb_console_init
(
sisusb
,
sisusb_first_vc
,
sisusb_last_vc
);
#endif
return
0
;
error_4:
...
...
@@ -3053,13 +3429,20 @@ static void sisusb_disconnect(struct usb_interface *intf)
struct
sisusb_usb_data
*
sisusb
;
int
minor
;
down
(
&
disconnect_sem
);
/* This should *not* happen */
if
(
!
(
sisusb
=
usb_get_intfdata
(
intf
)))
{
up
(
&
disconnect_sem
);
if
(
!
(
sisusb
=
usb_get_intfdata
(
intf
)))
return
;
}
#ifdef INCL_SISUSB_CON
sisusb_console_exit
(
sisusb
);
#endif
/* The above code doesn't need the disconnect
* semaphore to be down; its meaning is to
* protect all other routines from the disconnect
* case, not the other way round.
*/
down
(
&
disconnect_sem
);
down
(
&
sisusb
->
lock
);
...
...
@@ -3123,11 +3506,17 @@ static int __init usb_sisusb_init(void)
{
int
retval
;
#ifdef INCL_SISUSB_CON
sisusb_init_concode
();
#endif
if
(
!
(
retval
=
usb_register
(
&
sisusb_driver
)))
{
printk
(
KERN_INFO
"sisusb: Driver version %d.%d.%d
\n
"
,
SISUSB_VERSION
,
SISUSB_REVISION
,
SISUSB_PATCHLEVEL
);
printk
(
KERN_INFO
"sisusb: Copyright (C) 2005 Thomas Winischhofer
\n
"
);
}
return
retval
;
...
...
@@ -3142,6 +3531,6 @@ module_init(usb_sisusb_init);
module_exit
(
usb_sisusb_exit
);
MODULE_AUTHOR
(
"Thomas Winischhofer <thomas@winischhofer.net>"
);
MODULE_DESCRIPTION
(
"sisusb - Driver for Net2280/SiS315-based USB2VGA dongles"
);
MODULE_DESCRIPTION
(
"sisusb
vga
- Driver for Net2280/SiS315-based USB2VGA dongles"
);
MODULE_LICENSE
(
"GPL"
);
drivers/usb/misc/sisusbvga/sisusb.h
浏览文件 @
cc6120c6
...
...
@@ -46,15 +46,36 @@
#endif
#endif
/* For older kernels, support for text consoles is by default
* off. To ensable text console support, change the following:
*/
#if 0
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13)
#define CONFIG_USB_SISUSBVGA_CON
#endif
#endif
/* Version Information */
#define SISUSB_VERSION 0
#define SISUSB_REVISION 0
#define SISUSB_PATCHLEVEL 7
#define SISUSB_PATCHLEVEL 8
/* Include console and mode switching code? */
#ifdef CONFIG_USB_SISUSBVGA_CON
#define INCL_SISUSB_CON 1
#endif
#ifdef INCL_SISUSB_CON
#include <linux/console.h>
#include <linux/vt_kern.h>
#include "sisusb_struct.h"
#endif
/* USB related */
#define SISUSB_MINOR
133
/* FIXME
*/
#define SISUSB_MINOR
133
/* official
*/
/* Size of the sisusb input/output buffers */
#define SISUSB_IBUF_SIZE 0x01000
...
...
@@ -131,6 +152,26 @@ struct sisusb_usb_data {
unsigned
char
gfxinit
;
/* graphics core initialized? */
unsigned
short
chipid
,
chipvendor
;
unsigned
short
chiprevision
;
#ifdef INCL_SISUSB_CON
struct
SiS_Private
*
SiS_Pr
;
unsigned
long
scrbuf
;
unsigned
int
scrbuf_size
;
int
haveconsole
,
con_first
,
con_last
;
int
havethisconsole
[
MAX_NR_CONSOLES
];
int
textmodedestroyed
;
unsigned
int
sisusb_num_columns
;
/* real number, not vt's idea */
int
cur_start_addr
,
con_rolled_over
;
int
sisusb_cursor_loc
,
bad_cursor_pos
;
int
sisusb_cursor_size_from
;
int
sisusb_cursor_size_to
;
int
current_font_height
,
current_font_512
;
int
font_backup_size
,
font_backup_height
,
font_backup_512
;
char
*
font_backup
;
int
font_slot
;
struct
vc_data
*
sisusb_display_fg
;
int
is_gfx
;
int
con_blanked
;
#endif
};
#define to_sisusb_dev(d) container_of(d, struct sisusb_usb_data, kref)
...
...
@@ -249,7 +290,9 @@ struct sisusb_info {
__u32
sisusb_fbdevactive
;
/* != 0 if framebuffer device active */
__u8
sisusb_reserved
[
32
];
/* for future use */
__u32
sisusb_conactive
;
/* != 0 if console driver active */
__u8
sisusb_reserved
[
28
];
/* for future use */
};
struct
sisusb_command
{
...
...
@@ -261,18 +304,24 @@ struct sisusb_command {
__u32
data4
;
/* for future use */
};
#define SUCMD_GET
0x01
/* for all: data0 = index, data3 = port */
#define SUCMD_SET
0x02
/* data1 = value */
#define SUCMD_SETOR
0x03
/* data1 = or */
#define SUCMD_SETAND
0x04
/* data1 = and */
#define SUCMD_SETANDOR
0x05
/* data1 = and, data2 = or */
#define SUCMD_SETMASK
0x06
/* data1 = data, data2 = mask */
#define SUCMD_GET
0x01
/* for all: data0 = index, data3 = port */
#define SUCMD_SET
0x02
/* data1 = value */
#define SUCMD_SETOR
0x03
/* data1 = or */
#define SUCMD_SETAND
0x04
/* data1 = and */
#define SUCMD_SETANDOR
0x05
/* data1 = and, data2 = or */
#define SUCMD_SETMASK
0x06
/* data1 = data, data2 = mask */
#define SUCMD_CLRSCR 0x07
/* data0:1:2 = length, data3 = address */
#define SUCMD_CLRSCR 0x07
/* data0:1:2 = length, data3 = address */
#define SUCMD_HANDLETEXTMODE 0x08
/* Reset/destroy text mode */
#define SUCMD_SETMODE 0x09
/* Set a display mode (data3 = SiS mode) */
#define SUCMD_SETVESAMODE 0x0a
/* Set a display mode (data3 = VESA mode) */
#define SISUSB_COMMAND _IOWR(0xF3,0x3D,struct sisusb_command)
#define SISUSB_GET_CONFIG_SIZE _IOR(0xF3,0x3E,__u32)
#define SISUSB_GET_CONFIG _IOR(0xF3,0x3F,struct sisusb_info)
#define SISUSB_GET_CONFIG_SIZE _IOR(0xF3,0x3E,__u32)
#define SISUSB_GET_CONFIG _IOR(0xF3,0x3F,struct sisusb_info)
#endif
/* SISUSB_H */
drivers/usb/misc/sisusbvga/sisusb_con.c
0 → 100644
浏览文件 @
cc6120c6
此差异已折叠。
点击以展开。
drivers/usb/misc/sisusbvga/sisusb_init.c
0 → 100644
浏览文件 @
cc6120c6
此差异已折叠。
点击以展开。
drivers/usb/misc/sisusbvga/sisusb_init.h
0 → 100644
浏览文件 @
cc6120c6
此差异已折叠。
点击以展开。
drivers/usb/misc/sisusbvga/sisusb_struct.h
0 → 100644
浏览文件 @
cc6120c6
此差异已折叠。
点击以展开。
drivers/usb/misc/uss720.c
浏览文件 @
cc6120c6
此差异已折叠。
点击以展开。
drivers/usb/mon/mon_text.c
浏览文件 @
cc6120c6
...
...
@@ -79,7 +79,7 @@ static inline char mon_text_get_setup(struct mon_event_text *ep,
return
'-'
;
if
(
urb
->
transfer_flags
&
URB_NO_SETUP_DMA_MAP
)
return
'D'
;
return
mon_dmapeek
(
ep
->
setup
,
urb
->
setup_dma
,
SETUP_MAX
)
;
if
(
urb
->
setup_packet
==
NULL
)
return
'Z'
;
/* '0' would be not as pretty. */
...
...
drivers/usb/serial/cp2101.c
浏览文件 @
cc6120c6
...
...
@@ -32,7 +32,7 @@
/*
* Version Information
*/
#define DRIVER_VERSION "v0.0
4
"
#define DRIVER_VERSION "v0.0
5
"
#define DRIVER_DESC "Silicon Labs CP2101/CP2102 RS232 serial adaptor driver"
/*
...
...
@@ -54,8 +54,11 @@ static void cp2101_shutdown(struct usb_serial*);
static
int
debug
;
static
struct
usb_device_id
id_table
[]
=
{
{
USB_DEVICE
(
0x0FCF
,
0x1003
)
},
/* Dynastream ANT development board */
{
USB_DEVICE
(
0x10C4
,
0xEA60
)
},
/* Silicon Labs factory default */
{
USB_DEVICE
(
0x10C4
,
0x80CA
)
},
/* Degree Controls Inc */
{
USB_DEVICE
(
0x10C4
,
0x80F6
)
},
/* Suunto sports instrument */
{
USB_DEVICE
(
0x10A6
,
0xAA26
)
},
/* Knock-off DCU-11 cable */
{
USB_DEVICE
(
0x10AB
,
0x10C5
)
},
/* Siemens MC60 Cable */
{
}
/* Terminating Entry */
};
...
...
drivers/usb/serial/cypress_m8.c
浏览文件 @
cc6120c6
...
...
@@ -610,8 +610,7 @@ static void cypress_close(struct usb_serial_port *port, struct file * filp)
timeout
=
max
((
HZ
*
2560
)
/
bps
,
HZ
/
10
);
else
timeout
=
2
*
HZ
;
set_current_state
(
TASK_INTERRUPTIBLE
);
schedule_timeout
(
timeout
);
schedule_timeout_interruptible
(
timeout
);
dbg
(
"%s - stopping urbs"
,
__FUNCTION__
);
usb_kill_urb
(
port
->
interrupt_in_urb
);
...
...
drivers/usb/serial/ftdi_sio.c
浏览文件 @
cc6120c6
...
...
@@ -914,7 +914,7 @@ static void ftdi_determine_type(struct usb_serial_port *port)
unsigned
interfaces
;
/* Assume it is not the original SIO device for now. */
priv
->
baud_base
=
48000000
/
16
;
priv
->
baud_base
=
48000000
/
2
;
priv
->
write_offset
=
0
;
version
=
le16_to_cpu
(
udev
->
descriptor
.
bcdDevice
);
...
...
drivers/usb/serial/pl2303.c
浏览文件 @
cc6120c6
...
...
@@ -95,6 +95,7 @@ static struct usb_device_id id_table [] = {
{
USB_DEVICE
(
SAMSUNG_VENDOR_ID
,
SAMSUNG_PRODUCT_ID
)
},
{
USB_DEVICE
(
SIEMENS_VENDOR_ID
,
SIEMENS_PRODUCT_ID_X65
)
},
{
USB_DEVICE
(
SYNTECH_VENDOR_ID
,
SYNTECH_PRODUCT_ID
)
},
{
USB_DEVICE
(
NOKIA_CA42_VENDOR_ID
,
NOKIA_CA42_PRODUCT_ID
)
},
{
}
/* Terminating entry */
};
...
...
@@ -652,8 +653,7 @@ static void pl2303_close (struct usb_serial_port *port, struct file *filp)
timeout
=
max
((
HZ
*
2560
)
/
bps
,
HZ
/
10
);
else
timeout
=
2
*
HZ
;
set_current_state
(
TASK_INTERRUPTIBLE
);
schedule_timeout
(
timeout
);
schedule_timeout_interruptible
(
timeout
);
/* shutdown our urbs */
dbg
(
"%s - shutting down urbs"
,
__FUNCTION__
);
...
...
drivers/usb/serial/pl2303.h
浏览文件 @
cc6120c6
...
...
@@ -58,3 +58,7 @@
#define SYNTECH_VENDOR_ID 0x0745
#define SYNTECH_PRODUCT_ID 0x0001
/* Nokia CA-42 Cable */
#define NOKIA_CA42_VENDOR_ID 0x078b
#define NOKIA_CA42_PRODUCT_ID 0x1234
drivers/usb/storage/scsiglue.c
浏览文件 @
cc6120c6
此差异已折叠。
点击以展开。
drivers/usb/storage/unusual_devs.h
浏览文件 @
cc6120c6
此差异已折叠。
点击以展开。
drivers/usb/storage/usb.c
浏览文件 @
cc6120c6
...
...
@@ -392,11 +392,16 @@ static int usb_stor_control_thread(void * __us)
/* If an abort request was received we need to signal that
* the abort has finished. The proper test for this is
* the TIMED_OUT flag, not srb->result == DID_ABORT, because
*
a timeout/abort request might be received after all the
*
USB processing was complet
e. */
if
(
test_bit
(
US_FLIDX_TIMED_OUT
,
&
us
->
flags
))
*
the timeout might have occurred after the command had
*
already completed with a different result cod
e. */
if
(
test_bit
(
US_FLIDX_TIMED_OUT
,
&
us
->
flags
))
{
complete
(
&
(
us
->
notify
));
/* Allow USB transfers to resume */
clear_bit
(
US_FLIDX_ABORTING
,
&
us
->
flags
);
clear_bit
(
US_FLIDX_TIMED_OUT
,
&
us
->
flags
);
}
/* finished working on this command */
us
->
srb
=
NULL
;
scsi_unlock
(
host
);
...
...
drivers/video/console/Kconfig
浏览文件 @
cc6120c6
...
...
@@ -137,7 +137,7 @@ config FONT_8x8
config FONT_8x16
bool "VGA 8x16 font" if FONTS
depends on FRAMEBUFFER_CONSOLE || SGI_NEWPORT_CONSOLE=y
depends on FRAMEBUFFER_CONSOLE || SGI_NEWPORT_CONSOLE=y
|| USB_SISUSBVGA_CON
default y if !SPARC32 && !SPARC64 && !FONTS
help
This is the "high resolution" font for the VGA frame buffer (the one
...
...
drivers/video/console/Makefile
浏览文件 @
cc6120c6
此差异已折叠。
点击以展开。
include/linux/usbdevice_fs.h
浏览文件 @
cc6120c6
此差异已折叠。
点击以展开。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录