Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
008238b5
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,发现更多精彩内容 >>
提交
008238b5
编写于
4月 30, 2008
作者:
L
Len Brown
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'pnp' into release
上级
96916090
dfd2e1b4
变更
26
展开全部
显示空白变更内容
内联
并排
Showing
26 changed file
with
1689 addition
and
1356 deletion
+1689
-1356
drivers/pnp/base.h
drivers/pnp/base.h
+70
-4
drivers/pnp/card.c
drivers/pnp/card.c
+46
-9
drivers/pnp/core.c
drivers/pnp/core.c
+39
-7
drivers/pnp/driver.c
drivers/pnp/driver.c
+21
-7
drivers/pnp/interface.c
drivers/pnp/interface.c
+47
-64
drivers/pnp/isapnp/Makefile
drivers/pnp/isapnp/Makefile
+4
-0
drivers/pnp/isapnp/core.c
drivers/pnp/isapnp/core.c
+168
-172
drivers/pnp/manager.c
drivers/pnp/manager.c
+168
-188
drivers/pnp/pnpacpi/Makefile
drivers/pnp/pnpacpi/Makefile
+4
-0
drivers/pnp/pnpacpi/core.c
drivers/pnp/pnpacpi/core.c
+18
-72
drivers/pnp/pnpacpi/pnpacpi.h
drivers/pnp/pnpacpi/pnpacpi.h
+4
-4
drivers/pnp/pnpacpi/rsparser.c
drivers/pnp/pnpacpi/rsparser.c
+312
-277
drivers/pnp/pnpbios/Makefile
drivers/pnp/pnpbios/Makefile
+4
-0
drivers/pnp/pnpbios/bioscalls.c
drivers/pnp/pnpbios/bioscalls.c
+0
-1
drivers/pnp/pnpbios/core.c
drivers/pnp/pnpbios/core.c
+10
-21
drivers/pnp/pnpbios/pnpbios.h
drivers/pnp/pnpbios/pnpbios.h
+138
-2
drivers/pnp/pnpbios/proc.c
drivers/pnp/pnpbios/proc.c
+1
-1
drivers/pnp/pnpbios/rsparser.c
drivers/pnp/pnpbios/rsparser.c
+146
-180
drivers/pnp/quirks.c
drivers/pnp/quirks.c
+9
-6
drivers/pnp/resource.c
drivers/pnp/resource.c
+293
-68
drivers/pnp/support.c
drivers/pnp/support.c
+63
-0
drivers/pnp/system.c
drivers/pnp/system.c
+10
-11
drivers/rtc/rtc-cmos.c
drivers/rtc/rtc-cmos.c
+4
-3
include/linux/isapnp.h
include/linux/isapnp.h
+0
-10
include/linux/pnp.h
include/linux/pnp.h
+110
-98
include/linux/pnpbios.h
include/linux/pnpbios.h
+0
-151
未找到文件。
drivers/pnp/base.h
浏览文件 @
008238b5
extern
spinlock_t
pnp_lock
;
void
*
pnp_alloc
(
long
size
);
int
pnp_register_protocol
(
struct
pnp_protocol
*
protocol
);
void
pnp_unregister_protocol
(
struct
pnp_protocol
*
protocol
);
#define PNP_EISA_ID_MASK 0x7fffffff
void
pnp_eisa_id_to_string
(
u32
id
,
char
*
str
);
struct
pnp_dev
*
pnp_alloc_dev
(
struct
pnp_protocol
*
,
int
id
,
char
*
pnpid
);
struct
pnp_card
*
pnp_alloc_card
(
struct
pnp_protocol
*
,
int
id
,
char
*
pnpid
);
int
pnp_add_device
(
struct
pnp_dev
*
dev
);
struct
pnp_id
*
pnp_add_id
(
struct
pnp_dev
*
dev
,
char
*
id
);
int
pnp_interface_attach_device
(
struct
pnp_dev
*
dev
);
int
pnp_add_card
(
struct
pnp_card
*
card
);
struct
pnp_id
*
pnp_add_card_id
(
struct
pnp_card
*
card
,
char
*
id
);
void
pnp_remove_card
(
struct
pnp_card
*
card
);
int
pnp_add_card_device
(
struct
pnp_card
*
card
,
struct
pnp_dev
*
dev
);
void
pnp_remove_card_device
(
struct
pnp_dev
*
dev
);
struct
pnp_option
*
pnp_register_independent_option
(
struct
pnp_dev
*
dev
);
struct
pnp_option
*
pnp_register_dependent_option
(
struct
pnp_dev
*
dev
,
int
priority
);
int
pnp_register_irq_resource
(
struct
pnp_dev
*
dev
,
struct
pnp_option
*
option
,
struct
pnp_irq
*
data
);
int
pnp_register_dma_resource
(
struct
pnp_dev
*
dev
,
struct
pnp_option
*
option
,
struct
pnp_dma
*
data
);
int
pnp_register_port_resource
(
struct
pnp_dev
*
dev
,
struct
pnp_option
*
option
,
struct
pnp_port
*
data
);
int
pnp_register_mem_resource
(
struct
pnp_dev
*
dev
,
struct
pnp_option
*
option
,
struct
pnp_mem
*
data
);
void
pnp_init_resources
(
struct
pnp_dev
*
dev
);
void
pnp_fixup_device
(
struct
pnp_dev
*
dev
);
void
pnp_free_option
(
struct
pnp_option
*
option
);
int
__pnp_add_device
(
struct
pnp_dev
*
dev
);
void
__pnp_remove_device
(
struct
pnp_dev
*
dev
);
int
pnp_check_port
(
struct
pnp_dev
*
dev
,
int
idx
);
int
pnp_check_mem
(
struct
pnp_dev
*
dev
,
int
idx
);
int
pnp_check_irq
(
struct
pnp_dev
*
dev
,
int
idx
);
int
pnp_check_dma
(
struct
pnp_dev
*
dev
,
int
idx
);
int
pnp_check_port
(
struct
pnp_dev
*
dev
,
struct
resource
*
res
);
int
pnp_check_mem
(
struct
pnp_dev
*
dev
,
struct
resource
*
res
);
int
pnp_check_irq
(
struct
pnp_dev
*
dev
,
struct
resource
*
res
);
int
pnp_check_dma
(
struct
pnp_dev
*
dev
,
struct
resource
*
res
);
void
dbg_pnp_show_resources
(
struct
pnp_dev
*
dev
,
char
*
desc
);
void
pnp_init_resource
(
struct
resource
*
res
);
struct
pnp_resource
*
pnp_get_pnp_resource
(
struct
pnp_dev
*
dev
,
unsigned
int
type
,
unsigned
int
num
);
#define PNP_MAX_PORT 40
#define PNP_MAX_MEM 24
#define PNP_MAX_IRQ 2
#define PNP_MAX_DMA 2
struct
pnp_resource
{
struct
resource
res
;
unsigned
int
index
;
/* ISAPNP config register index */
};
struct
pnp_resource_table
{
struct
pnp_resource
port
[
PNP_MAX_PORT
];
struct
pnp_resource
mem
[
PNP_MAX_MEM
];
struct
pnp_resource
dma
[
PNP_MAX_DMA
];
struct
pnp_resource
irq
[
PNP_MAX_IRQ
];
};
struct
pnp_resource
*
pnp_add_irq_resource
(
struct
pnp_dev
*
dev
,
int
irq
,
int
flags
);
struct
pnp_resource
*
pnp_add_dma_resource
(
struct
pnp_dev
*
dev
,
int
dma
,
int
flags
);
struct
pnp_resource
*
pnp_add_io_resource
(
struct
pnp_dev
*
dev
,
resource_size_t
start
,
resource_size_t
end
,
int
flags
);
struct
pnp_resource
*
pnp_add_mem_resource
(
struct
pnp_dev
*
dev
,
resource_size_t
start
,
resource_size_t
end
,
int
flags
);
drivers/pnp/card.c
浏览文件 @
008238b5
...
...
@@ -5,6 +5,7 @@
*/
#include <linux/module.h>
#include <linux/ctype.h>
#include <linux/slab.h>
#include <linux/pnp.h>
#include "base.h"
...
...
@@ -100,19 +101,33 @@ static int card_probe(struct pnp_card *card, struct pnp_card_driver *drv)
* @id: pointer to a pnp_id structure
* @card: pointer to the desired card
*/
int
pnp_add_card_id
(
struct
pnp_id
*
id
,
struct
pnp_card
*
car
d
)
struct
pnp_id
*
pnp_add_card_id
(
struct
pnp_card
*
card
,
char
*
i
d
)
{
struct
pnp_id
*
ptr
;
struct
pnp_id
*
dev_id
,
*
ptr
;
id
->
next
=
NULL
;
dev_id
=
kzalloc
(
sizeof
(
struct
pnp_id
),
GFP_KERNEL
);
if
(
!
dev_id
)
return
NULL
;
dev_id
->
id
[
0
]
=
id
[
0
];
dev_id
->
id
[
1
]
=
id
[
1
];
dev_id
->
id
[
2
]
=
id
[
2
];
dev_id
->
id
[
3
]
=
tolower
(
id
[
3
]);
dev_id
->
id
[
4
]
=
tolower
(
id
[
4
]);
dev_id
->
id
[
5
]
=
tolower
(
id
[
5
]);
dev_id
->
id
[
6
]
=
tolower
(
id
[
6
]);
dev_id
->
id
[
7
]
=
'\0'
;
dev_id
->
next
=
NULL
;
ptr
=
card
->
id
;
while
(
ptr
&&
ptr
->
next
)
ptr
=
ptr
->
next
;
if
(
ptr
)
ptr
->
next
=
id
;
ptr
->
next
=
dev_
id
;
else
card
->
id
=
id
;
return
0
;
card
->
id
=
dev_id
;
return
dev_id
;
}
static
void
pnp_free_card_ids
(
struct
pnp_card
*
card
)
...
...
@@ -136,6 +151,31 @@ static void pnp_release_card(struct device *dmdev)
kfree
(
card
);
}
struct
pnp_card
*
pnp_alloc_card
(
struct
pnp_protocol
*
protocol
,
int
id
,
char
*
pnpid
)
{
struct
pnp_card
*
card
;
struct
pnp_id
*
dev_id
;
card
=
kzalloc
(
sizeof
(
struct
pnp_card
),
GFP_KERNEL
);
if
(
!
card
)
return
NULL
;
card
->
protocol
=
protocol
;
card
->
number
=
id
;
card
->
dev
.
parent
=
&
card
->
protocol
->
dev
;
sprintf
(
card
->
dev
.
bus_id
,
"%02x:%02x"
,
card
->
protocol
->
number
,
card
->
number
);
dev_id
=
pnp_add_card_id
(
card
,
pnpid
);
if
(
!
dev_id
)
{
kfree
(
card
);
return
NULL
;
}
return
card
;
}
static
ssize_t
pnp_show_card_name
(
struct
device
*
dmdev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
...
...
@@ -191,9 +231,6 @@ int pnp_add_card(struct pnp_card *card)
int
error
;
struct
list_head
*
pos
,
*
temp
;
sprintf
(
card
->
dev
.
bus_id
,
"%02x:%02x"
,
card
->
protocol
->
number
,
card
->
number
);
card
->
dev
.
parent
=
&
card
->
protocol
->
dev
;
card
->
dev
.
bus
=
NULL
;
card
->
dev
.
release
=
&
pnp_release_card
;
error
=
device_register
(
&
card
->
dev
);
...
...
drivers/pnp/core.c
浏览文件 @
008238b5
...
...
@@ -106,18 +106,53 @@ static void pnp_release_device(struct device *dmdev)
pnp_free_option
(
dev
->
independent
);
pnp_free_option
(
dev
->
dependent
);
pnp_free_ids
(
dev
);
kfree
(
dev
->
res
);
kfree
(
dev
);
}
int
__pnp_add_device
(
struct
pnp_dev
*
dev
)
struct
pnp_dev
*
pnp_alloc_dev
(
struct
pnp_protocol
*
protocol
,
int
id
,
char
*
pnpid
)
{
int
ret
;
struct
pnp_dev
*
dev
;
struct
pnp_id
*
dev_id
;
pnp_fixup_device
(
dev
);
dev
=
kzalloc
(
sizeof
(
struct
pnp_dev
),
GFP_KERNEL
);
if
(
!
dev
)
return
NULL
;
dev
->
res
=
kzalloc
(
sizeof
(
struct
pnp_resource_table
),
GFP_KERNEL
);
if
(
!
dev
->
res
)
{
kfree
(
dev
);
return
NULL
;
}
dev
->
protocol
=
protocol
;
dev
->
number
=
id
;
dev
->
dma_mask
=
DMA_24BIT_MASK
;
dev
->
dev
.
parent
=
&
dev
->
protocol
->
dev
;
dev
->
dev
.
bus
=
&
pnp_bus_type
;
dev
->
dev
.
dma_mask
=
&
dev
->
dma_mask
;
dev
->
d
ma_mask
=
dev
->
dev
.
coherent_dma_mask
=
DMA_24BIT_MASK
;
dev
->
d
ev
.
coherent_dma_mask
=
dev
->
dma_mask
;
dev
->
dev
.
release
=
&
pnp_release_device
;
sprintf
(
dev
->
dev
.
bus_id
,
"%02x:%02x"
,
dev
->
protocol
->
number
,
dev
->
number
);
dev_id
=
pnp_add_id
(
dev
,
pnpid
);
if
(
!
dev_id
)
{
kfree
(
dev
->
res
);
kfree
(
dev
);
return
NULL
;
}
return
dev
;
}
int
__pnp_add_device
(
struct
pnp_dev
*
dev
)
{
int
ret
;
pnp_fixup_device
(
dev
);
dev
->
status
=
PNP_READY
;
spin_lock
(
&
pnp_lock
);
list_add_tail
(
&
dev
->
global_list
,
&
pnp_global
);
...
...
@@ -145,9 +180,6 @@ int pnp_add_device(struct pnp_dev *dev)
if
(
dev
->
card
)
return
-
EINVAL
;
dev
->
dev
.
parent
=
&
dev
->
protocol
->
dev
;
sprintf
(
dev
->
dev
.
bus_id
,
"%02x:%02x"
,
dev
->
protocol
->
number
,
dev
->
number
);
ret
=
__pnp_add_device
(
dev
);
if
(
ret
)
return
ret
;
...
...
drivers/pnp/driver.c
浏览文件 @
008238b5
...
...
@@ -226,22 +226,36 @@ void pnp_unregister_driver(struct pnp_driver *drv)
/**
* pnp_add_id - adds an EISA id to the specified device
* @id: pointer to a pnp_id structure
* @dev: pointer to the desired device
* @id: pointer to an EISA id string
*/
int
pnp_add_id
(
struct
pnp_id
*
id
,
struct
pnp_dev
*
dev
)
struct
pnp_id
*
pnp_add_id
(
struct
pnp_dev
*
dev
,
char
*
id
)
{
struct
pnp_id
*
ptr
;
struct
pnp_id
*
dev_id
,
*
ptr
;
id
->
next
=
NULL
;
dev_id
=
kzalloc
(
sizeof
(
struct
pnp_id
),
GFP_KERNEL
);
if
(
!
dev_id
)
return
NULL
;
dev_id
->
id
[
0
]
=
id
[
0
];
dev_id
->
id
[
1
]
=
id
[
1
];
dev_id
->
id
[
2
]
=
id
[
2
];
dev_id
->
id
[
3
]
=
tolower
(
id
[
3
]);
dev_id
->
id
[
4
]
=
tolower
(
id
[
4
]);
dev_id
->
id
[
5
]
=
tolower
(
id
[
5
]);
dev_id
->
id
[
6
]
=
tolower
(
id
[
6
]);
dev_id
->
id
[
7
]
=
'\0'
;
dev_id
->
next
=
NULL
;
ptr
=
dev
->
id
;
while
(
ptr
&&
ptr
->
next
)
ptr
=
ptr
->
next
;
if
(
ptr
)
ptr
->
next
=
id
;
ptr
->
next
=
dev_
id
;
else
dev
->
id
=
id
;
return
0
;
dev
->
id
=
dev_id
;
return
dev_id
;
}
EXPORT_SYMBOL
(
pnp_register_driver
);
...
...
drivers/pnp/interface.c
浏览文件 @
008238b5
...
...
@@ -248,6 +248,7 @@ static ssize_t pnp_show_current_resources(struct device *dmdev,
char
*
buf
)
{
struct
pnp_dev
*
dev
=
to_pnp_dev
(
dmdev
);
struct
resource
*
res
;
int
i
,
ret
;
pnp_info_buffer_t
*
buffer
;
...
...
@@ -267,50 +268,46 @@ static ssize_t pnp_show_current_resources(struct device *dmdev,
else
pnp_printf
(
buffer
,
"disabled
\n
"
);
for
(
i
=
0
;
i
<
PNP_MAX_PORT
;
i
++
)
{
if
(
pnp_
port_valid
(
dev
,
i
))
{
for
(
i
=
0
;
(
res
=
pnp_get_resource
(
dev
,
IORESOURCE_IO
,
i
))
;
i
++
)
{
if
(
pnp_
resource_valid
(
res
))
{
pnp_printf
(
buffer
,
"io"
);
if
(
pnp_port_flags
(
dev
,
i
)
&
IORESOURCE_DISABLED
)
if
(
res
->
flags
&
IORESOURCE_DISABLED
)
pnp_printf
(
buffer
,
" disabled
\n
"
);
else
pnp_printf
(
buffer
,
" 0x%llx-0x%llx
\n
"
,
(
unsigned
long
long
)
pnp_port_start
(
dev
,
i
),
(
unsigned
long
long
)
pnp_port_end
(
dev
,
i
));
(
unsigned
long
long
)
res
->
start
,
(
unsigned
long
long
)
res
->
end
);
}
}
for
(
i
=
0
;
i
<
PNP_MAX_MEM
;
i
++
)
{
if
(
pnp_
mem_valid
(
dev
,
i
))
{
for
(
i
=
0
;
(
res
=
pnp_get_resource
(
dev
,
IORESOURCE_MEM
,
i
))
;
i
++
)
{
if
(
pnp_
resource_valid
(
res
))
{
pnp_printf
(
buffer
,
"mem"
);
if
(
pnp_mem_flags
(
dev
,
i
)
&
IORESOURCE_DISABLED
)
if
(
res
->
flags
&
IORESOURCE_DISABLED
)
pnp_printf
(
buffer
,
" disabled
\n
"
);
else
pnp_printf
(
buffer
,
" 0x%llx-0x%llx
\n
"
,
(
unsigned
long
long
)
pnp_mem_start
(
dev
,
i
),
(
unsigned
long
long
)
pnp_mem_end
(
dev
,
i
));
(
unsigned
long
long
)
res
->
start
,
(
unsigned
long
long
)
res
->
end
);
}
}
for
(
i
=
0
;
i
<
PNP_MAX_IRQ
;
i
++
)
{
if
(
pnp_
irq_valid
(
dev
,
i
))
{
for
(
i
=
0
;
(
res
=
pnp_get_resource
(
dev
,
IORESOURCE_IRQ
,
i
))
;
i
++
)
{
if
(
pnp_
resource_valid
(
res
))
{
pnp_printf
(
buffer
,
"irq"
);
if
(
pnp_irq_flags
(
dev
,
i
)
&
IORESOURCE_DISABLED
)
if
(
res
->
flags
&
IORESOURCE_DISABLED
)
pnp_printf
(
buffer
,
" disabled
\n
"
);
else
pnp_printf
(
buffer
,
" %lld
\n
"
,
(
unsigned
long
long
)
pnp_irq
(
dev
,
i
)
);
(
unsigned
long
long
)
res
->
start
);
}
}
for
(
i
=
0
;
i
<
PNP_MAX_DMA
;
i
++
)
{
if
(
pnp_
dma_valid
(
dev
,
i
))
{
for
(
i
=
0
;
(
res
=
pnp_get_resource
(
dev
,
IORESOURCE_DMA
,
i
))
;
i
++
)
{
if
(
pnp_
resource_valid
(
res
))
{
pnp_printf
(
buffer
,
"dma"
);
if
(
pnp_dma_flags
(
dev
,
i
)
&
IORESOURCE_DISABLED
)
if
(
res
->
flags
&
IORESOURCE_DISABLED
)
pnp_printf
(
buffer
,
" disabled
\n
"
);
else
pnp_printf
(
buffer
,
" %lld
\n
"
,
(
unsigned
long
long
)
pnp_dma
(
dev
,
i
)
);
(
unsigned
long
long
)
res
->
start
);
}
}
ret
=
(
buffer
->
curr
-
buf
);
...
...
@@ -323,8 +320,10 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
const
char
*
ubuf
,
size_t
count
)
{
struct
pnp_dev
*
dev
=
to_pnp_dev
(
dmdev
);
struct
pnp_resource
*
pnp_res
;
char
*
buf
=
(
void
*
)
ubuf
;
int
retval
=
0
;
resource_size_t
start
,
end
;
if
(
dev
->
status
&
PNP_ATTACHED
)
{
retval
=
-
EBUSY
;
...
...
@@ -351,20 +350,20 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
if
(
!
strnicmp
(
buf
,
"auto"
,
4
))
{
if
(
dev
->
active
)
goto
done
;
pnp_init_resource
_table
(
&
dev
->
res
);
pnp_init_resource
s
(
dev
);
retval
=
pnp_auto_config_dev
(
dev
);
goto
done
;
}
if
(
!
strnicmp
(
buf
,
"clear"
,
5
))
{
if
(
dev
->
active
)
goto
done
;
pnp_init_resource
_table
(
&
dev
->
res
);
pnp_init_resource
s
(
dev
);
goto
done
;
}
if
(
!
strnicmp
(
buf
,
"get"
,
3
))
{
mutex_lock
(
&
pnp_res_mutex
);
if
(
pnp_can_read
(
dev
))
dev
->
protocol
->
get
(
dev
,
&
dev
->
res
);
dev
->
protocol
->
get
(
dev
);
mutex_unlock
(
&
pnp_res_mutex
);
goto
done
;
}
...
...
@@ -373,7 +372,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
if
(
dev
->
active
)
goto
done
;
buf
+=
3
;
pnp_init_resource
_table
(
&
dev
->
res
);
pnp_init_resource
s
(
dev
);
mutex_lock
(
&
pnp_res_mutex
);
while
(
1
)
{
while
(
isspace
(
*
buf
))
...
...
@@ -382,76 +381,60 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
buf
+=
2
;
while
(
isspace
(
*
buf
))
++
buf
;
dev
->
res
.
port_resource
[
nport
].
start
=
simple_strtoul
(
buf
,
&
buf
,
0
);
start
=
simple_strtoul
(
buf
,
&
buf
,
0
);
while
(
isspace
(
*
buf
))
++
buf
;
if
(
*
buf
==
'-'
)
{
buf
+=
1
;
while
(
isspace
(
*
buf
))
++
buf
;
dev
->
res
.
port_resource
[
nport
].
end
=
simple_strtoul
(
buf
,
&
buf
,
0
);
end
=
simple_strtoul
(
buf
,
&
buf
,
0
);
}
else
dev
->
res
.
port_resource
[
nport
].
end
=
dev
->
res
.
port_resource
[
nport
].
start
;
dev
->
res
.
port_resource
[
nport
].
flags
=
IORESOURCE_IO
;
nport
++
;
if
(
nport
>=
PNP_MAX_PORT
)
break
;
end
=
start
;
pnp_res
=
pnp_add_io_resource
(
dev
,
start
,
end
,
0
);
if
(
pnp_res
)
pnp_res
->
index
=
nport
++
;
continue
;
}
if
(
!
strnicmp
(
buf
,
"mem"
,
3
))
{
buf
+=
3
;
while
(
isspace
(
*
buf
))
++
buf
;
dev
->
res
.
mem_resource
[
nmem
].
start
=
simple_strtoul
(
buf
,
&
buf
,
0
);
start
=
simple_strtoul
(
buf
,
&
buf
,
0
);
while
(
isspace
(
*
buf
))
++
buf
;
if
(
*
buf
==
'-'
)
{
buf
+=
1
;
while
(
isspace
(
*
buf
))
++
buf
;
dev
->
res
.
mem_resource
[
nmem
].
end
=
simple_strtoul
(
buf
,
&
buf
,
0
);
end
=
simple_strtoul
(
buf
,
&
buf
,
0
);
}
else
dev
->
res
.
mem_resource
[
nmem
].
end
=
dev
->
res
.
mem_resource
[
nmem
].
start
;
dev
->
res
.
mem_resource
[
nmem
].
flags
=
IORESOURCE_MEM
;
nmem
++
;
if
(
nmem
>=
PNP_MAX_MEM
)
break
;
end
=
start
;
pnp_res
=
pnp_add_mem_resource
(
dev
,
start
,
end
,
0
);
if
(
pnp_res
)
pnp_res
->
index
=
nmem
++
;
continue
;
}
if
(
!
strnicmp
(
buf
,
"irq"
,
3
))
{
buf
+=
3
;
while
(
isspace
(
*
buf
))
++
buf
;
dev
->
res
.
irq_resource
[
nirq
].
start
=
dev
->
res
.
irq_resource
[
nirq
].
end
=
simple_strtoul
(
buf
,
&
buf
,
0
);
dev
->
res
.
irq_resource
[
nirq
].
flags
=
IORESOURCE_IRQ
;
start
=
simple_strtoul
(
buf
,
&
buf
,
0
);
pnp_res
=
pnp_add_irq_resource
(
dev
,
start
,
0
);
if
(
pnp_res
)
nirq
++
;
if
(
nirq
>=
PNP_MAX_IRQ
)
break
;
continue
;
}
if
(
!
strnicmp
(
buf
,
"dma"
,
3
))
{
buf
+=
3
;
while
(
isspace
(
*
buf
))
++
buf
;
dev
->
res
.
dma_resource
[
ndma
].
start
=
dev
->
res
.
dma_resource
[
ndma
].
end
=
simple_strtoul
(
buf
,
&
buf
,
0
);
dev
->
res
.
dma_resource
[
ndma
].
flags
=
IORESOURCE_DMA
;
ndma
++
;
if
(
ndma
>=
PNP_MAX_DMA
)
break
;
start
=
simple_strtoul
(
buf
,
&
buf
,
0
);
pnp_res
=
pnp_add_dma_resource
(
dev
,
start
,
0
);
if
(
pnp_res
)
pnp_res
->
index
=
ndma
++
;
continue
;
}
break
;
...
...
drivers/pnp/isapnp/Makefile
浏览文件 @
008238b5
...
...
@@ -5,3 +5,7 @@
isapnp-proc-$(CONFIG_PROC_FS)
=
proc.o
obj-y
:=
core.o compat.o
$
(
isapnp-proc-y
)
ifeq
($(CONFIG_PNP_DEBUG),y)
EXTRA_CFLAGS
+=
-DDEBUG
endif
drivers/pnp/isapnp/core.c
浏览文件 @
008238b5
...
...
@@ -44,6 +44,8 @@
#include <linux/mutex.h>
#include <asm/io.h>
#include "../base.h"
#if 0
#define ISAPNP_REGION_OK
#endif
...
...
@@ -88,6 +90,14 @@ MODULE_LICENSE("GPL");
#define _LTAG_MEM32RANGE 0x85
#define _LTAG_FIXEDMEM32RANGE 0x86
/* Logical device control and configuration registers */
#define ISAPNP_CFG_ACTIVATE 0x30
/* byte */
#define ISAPNP_CFG_MEM 0x40
/* 4 * dword */
#define ISAPNP_CFG_PORT 0x60
/* 8 * word */
#define ISAPNP_CFG_IRQ 0x70
/* 2 * word */
#define ISAPNP_CFG_DMA 0x74
/* 2 * byte */
/*
* Sizes of ISAPNP logical device configuration register sets.
* See PNP-ISA-v1.0a.pdf, Appendix A.
...
...
@@ -387,28 +397,6 @@ static void __init isapnp_skip_bytes(int count)
isapnp_peek
(
NULL
,
count
);
}
/*
* Parse EISA id.
*/
static
void
isapnp_parse_id
(
struct
pnp_dev
*
dev
,
unsigned
short
vendor
,
unsigned
short
device
)
{
struct
pnp_id
*
id
;
if
(
!
dev
)
return
;
id
=
kzalloc
(
sizeof
(
struct
pnp_id
),
GFP_KERNEL
);
if
(
!
id
)
return
;
sprintf
(
id
->
id
,
"%c%c%c%x%x%x%x"
,
'A'
+
((
vendor
>>
2
)
&
0x3f
)
-
1
,
'A'
+
(((
vendor
&
3
)
<<
3
)
|
((
vendor
>>
13
)
&
7
))
-
1
,
'A'
+
((
vendor
>>
8
)
&
0x1f
)
-
1
,
(
device
>>
4
)
&
0x0f
,
device
&
0x0f
,
(
device
>>
12
)
&
0x0f
,
(
device
>>
8
)
&
0x0f
);
pnp_add_id
(
id
,
dev
);
}
/*
* Parse logical device tag.
*/
...
...
@@ -417,30 +405,31 @@ static struct pnp_dev *__init isapnp_parse_device(struct pnp_card *card,
{
unsigned
char
tmp
[
6
];
struct
pnp_dev
*
dev
;
u32
eisa_id
;
char
id
[
8
];
isapnp_peek
(
tmp
,
size
);
dev
=
kzalloc
(
sizeof
(
struct
pnp_dev
),
GFP_KERNEL
);
eisa_id
=
tmp
[
0
]
|
tmp
[
1
]
<<
8
|
tmp
[
2
]
<<
16
|
tmp
[
3
]
<<
24
;
pnp_eisa_id_to_string
(
eisa_id
,
id
);
dev
=
pnp_alloc_dev
(
&
isapnp_protocol
,
number
,
id
);
if
(
!
dev
)
return
NULL
;
dev
->
number
=
number
;
isapnp_parse_id
(
dev
,
(
tmp
[
1
]
<<
8
)
|
tmp
[
0
],
(
tmp
[
3
]
<<
8
)
|
tmp
[
2
]);
dev
->
regs
=
tmp
[
4
];
dev
->
card
=
card
;
if
(
size
>
5
)
dev
->
regs
|=
tmp
[
5
]
<<
8
;
dev
->
protocol
=
&
isapnp_protocol
;
dev
->
capabilities
|=
PNP_CONFIGURABLE
;
dev
->
capabilities
|=
PNP_READ
;
dev
->
capabilities
|=
PNP_WRITE
;
dev
->
capabilities
|=
PNP_DISABLE
;
pnp_init_resource
_table
(
&
dev
->
res
);
pnp_init_resource
s
(
dev
);
return
dev
;
}
/*
* Add IRQ resource to resources list.
*/
static
void
__init
isapnp_parse_irq_resource
(
struct
pnp_option
*
option
,
static
void
__init
isapnp_parse_irq_resource
(
struct
pnp_dev
*
dev
,
struct
pnp_option
*
option
,
int
size
)
{
unsigned
char
tmp
[
3
];
...
...
@@ -457,13 +446,14 @@ static void __init isapnp_parse_irq_resource(struct pnp_option *option,
irq
->
flags
=
tmp
[
2
];
else
irq
->
flags
=
IORESOURCE_IRQ_HIGHEDGE
;
pnp_register_irq_resource
(
option
,
irq
);
pnp_register_irq_resource
(
dev
,
option
,
irq
);
}
/*
* Add DMA resource to resources list.
*/
static
void
__init
isapnp_parse_dma_resource
(
struct
pnp_option
*
option
,
static
void
__init
isapnp_parse_dma_resource
(
struct
pnp_dev
*
dev
,
struct
pnp_option
*
option
,
int
size
)
{
unsigned
char
tmp
[
2
];
...
...
@@ -475,13 +465,14 @@ static void __init isapnp_parse_dma_resource(struct pnp_option *option,
return
;
dma
->
map
=
tmp
[
0
];
dma
->
flags
=
tmp
[
1
];
pnp_register_dma_resource
(
option
,
dma
);
pnp_register_dma_resource
(
dev
,
option
,
dma
);
}
/*
* Add port resource to resources list.
*/
static
void
__init
isapnp_parse_port_resource
(
struct
pnp_option
*
option
,
static
void
__init
isapnp_parse_port_resource
(
struct
pnp_dev
*
dev
,
struct
pnp_option
*
option
,
int
size
)
{
unsigned
char
tmp
[
7
];
...
...
@@ -496,13 +487,14 @@ static void __init isapnp_parse_port_resource(struct pnp_option *option,
port
->
align
=
tmp
[
5
];
port
->
size
=
tmp
[
6
];
port
->
flags
=
tmp
[
0
]
?
PNP_PORT_FLAG_16BITADDR
:
0
;
pnp_register_port_resource
(
option
,
port
);
pnp_register_port_resource
(
dev
,
option
,
port
);
}
/*
* Add fixed port resource to resources list.
*/
static
void
__init
isapnp_parse_fixed_port_resource
(
struct
pnp_option
*
option
,
static
void
__init
isapnp_parse_fixed_port_resource
(
struct
pnp_dev
*
dev
,
struct
pnp_option
*
option
,
int
size
)
{
unsigned
char
tmp
[
3
];
...
...
@@ -516,13 +508,14 @@ static void __init isapnp_parse_fixed_port_resource(struct pnp_option *option,
port
->
size
=
tmp
[
2
];
port
->
align
=
0
;
port
->
flags
=
PNP_PORT_FLAG_FIXED
;
pnp_register_port_resource
(
option
,
port
);
pnp_register_port_resource
(
dev
,
option
,
port
);
}
/*
* Add memory resource to resources list.
*/
static
void
__init
isapnp_parse_mem_resource
(
struct
pnp_option
*
option
,
static
void
__init
isapnp_parse_mem_resource
(
struct
pnp_dev
*
dev
,
struct
pnp_option
*
option
,
int
size
)
{
unsigned
char
tmp
[
9
];
...
...
@@ -537,13 +530,14 @@ static void __init isapnp_parse_mem_resource(struct pnp_option *option,
mem
->
align
=
(
tmp
[
6
]
<<
8
)
|
tmp
[
5
];
mem
->
size
=
((
tmp
[
8
]
<<
8
)
|
tmp
[
7
])
<<
8
;
mem
->
flags
=
tmp
[
0
];
pnp_register_mem_resource
(
option
,
mem
);
pnp_register_mem_resource
(
dev
,
option
,
mem
);
}
/*
* Add 32-bit memory resource to resources list.
*/
static
void
__init
isapnp_parse_mem32_resource
(
struct
pnp_option
*
option
,
static
void
__init
isapnp_parse_mem32_resource
(
struct
pnp_dev
*
dev
,
struct
pnp_option
*
option
,
int
size
)
{
unsigned
char
tmp
[
17
];
...
...
@@ -560,13 +554,14 @@ static void __init isapnp_parse_mem32_resource(struct pnp_option *option,
mem
->
size
=
(
tmp
[
16
]
<<
24
)
|
(
tmp
[
15
]
<<
16
)
|
(
tmp
[
14
]
<<
8
)
|
tmp
[
13
];
mem
->
flags
=
tmp
[
0
];
pnp_register_mem_resource
(
option
,
mem
);
pnp_register_mem_resource
(
dev
,
option
,
mem
);
}
/*
* Add 32-bit fixed memory resource to resources list.
*/
static
void
__init
isapnp_parse_fixed_mem32_resource
(
struct
pnp_option
*
option
,
static
void
__init
isapnp_parse_fixed_mem32_resource
(
struct
pnp_dev
*
dev
,
struct
pnp_option
*
option
,
int
size
)
{
unsigned
char
tmp
[
9
];
...
...
@@ -581,7 +576,7 @@ static void __init isapnp_parse_fixed_mem32_resource(struct pnp_option *option,
mem
->
size
=
(
tmp
[
8
]
<<
24
)
|
(
tmp
[
7
]
<<
16
)
|
(
tmp
[
6
]
<<
8
)
|
tmp
[
5
];
mem
->
align
=
0
;
mem
->
flags
=
tmp
[
0
];
pnp_register_mem_resource
(
option
,
mem
);
pnp_register_mem_resource
(
dev
,
option
,
mem
);
}
/*
...
...
@@ -613,6 +608,8 @@ static int __init isapnp_create_device(struct pnp_card *card,
unsigned
char
type
,
tmp
[
17
];
struct
pnp_option
*
option
;
struct
pnp_dev
*
dev
;
u32
eisa_id
;
char
id
[
8
];
if
((
dev
=
isapnp_parse_device
(
card
,
size
,
number
++
))
==
NULL
)
return
1
;
...
...
@@ -652,8 +649,10 @@ static int __init isapnp_create_device(struct pnp_card *card,
case
_STAG_COMPATDEVID
:
if
(
size
==
4
&&
compat
<
DEVICE_COUNT_COMPATIBLE
)
{
isapnp_peek
(
tmp
,
4
);
isapnp_parse_id
(
dev
,
(
tmp
[
1
]
<<
8
)
|
tmp
[
0
],
(
tmp
[
3
]
<<
8
)
|
tmp
[
2
]);
eisa_id
=
tmp
[
0
]
|
tmp
[
1
]
<<
8
|
tmp
[
2
]
<<
16
|
tmp
[
3
]
<<
24
;
pnp_eisa_id_to_string
(
eisa_id
,
id
);
pnp_add_id
(
dev
,
id
);
compat
++
;
size
=
0
;
}
...
...
@@ -661,13 +660,13 @@ static int __init isapnp_create_device(struct pnp_card *card,
case
_STAG_IRQ
:
if
(
size
<
2
||
size
>
3
)
goto
__skip
;
isapnp_parse_irq_resource
(
option
,
size
);
isapnp_parse_irq_resource
(
dev
,
option
,
size
);
size
=
0
;
break
;
case
_STAG_DMA
:
if
(
size
!=
2
)
goto
__skip
;
isapnp_parse_dma_resource
(
option
,
size
);
isapnp_parse_dma_resource
(
dev
,
option
,
size
);
size
=
0
;
break
;
case
_STAG_STARTDEP
:
...
...
@@ -687,17 +686,18 @@ static int __init isapnp_create_device(struct pnp_card *card,
if
(
size
!=
0
)
goto
__skip
;
priority
=
0
;
dev_dbg
(
&
dev
->
dev
,
"end dependent options
\n
"
);
break
;
case
_STAG_IOPORT
:
if
(
size
!=
7
)
goto
__skip
;
isapnp_parse_port_resource
(
option
,
size
);
isapnp_parse_port_resource
(
dev
,
option
,
size
);
size
=
0
;
break
;
case
_STAG_FIXEDIO
:
if
(
size
!=
3
)
goto
__skip
;
isapnp_parse_fixed_port_resource
(
option
,
size
);
isapnp_parse_fixed_port_resource
(
dev
,
option
,
size
);
size
=
0
;
break
;
case
_STAG_VENDOR
:
...
...
@@ -705,7 +705,7 @@ static int __init isapnp_create_device(struct pnp_card *card,
case
_LTAG_MEMRANGE
:
if
(
size
!=
9
)
goto
__skip
;
isapnp_parse_mem_resource
(
option
,
size
);
isapnp_parse_mem_resource
(
dev
,
option
,
size
);
size
=
0
;
break
;
case
_LTAG_ANSISTR
:
...
...
@@ -720,13 +720,13 @@ static int __init isapnp_create_device(struct pnp_card *card,
case
_LTAG_MEM32RANGE
:
if
(
size
!=
17
)
goto
__skip
;
isapnp_parse_mem32_resource
(
option
,
size
);
isapnp_parse_mem32_resource
(
dev
,
option
,
size
);
size
=
0
;
break
;
case
_LTAG_FIXEDMEM32RANGE
:
if
(
size
!=
9
)
goto
__skip
;
isapnp_parse_fixed_mem32_resource
(
option
,
size
);
isapnp_parse_fixed_mem32_resource
(
dev
,
option
,
size
);
size
=
0
;
break
;
case
_STAG_END
:
...
...
@@ -734,9 +734,8 @@ static int __init isapnp_create_device(struct pnp_card *card,
isapnp_skip_bytes
(
size
);
return
1
;
default:
printk
(
KERN_ERR
"isapnp: unexpected or unknown tag type 0x%x for logical device %i (device %i), ignored
\n
"
,
type
,
dev
->
number
,
card
->
number
);
dev_err
(
&
dev
->
dev
,
"unknown tag %#x (card %i), "
"ignored
\n
"
,
type
,
card
->
number
);
}
__skip:
if
(
size
>
0
)
...
...
@@ -789,9 +788,8 @@ static void __init isapnp_parse_resource_map(struct pnp_card *card)
isapnp_skip_bytes
(
size
);
return
;
default:
printk
(
KERN_ERR
"isapnp: unexpected or unknown tag type 0x%x for device %i, ignored
\n
"
,
type
,
card
->
number
);
dev_err
(
&
card
->
dev
,
"unknown tag %#x, ignored
\n
"
,
type
);
}
__skip:
if
(
size
>
0
)
...
...
@@ -821,25 +819,6 @@ static unsigned char __init isapnp_checksum(unsigned char *data)
return
checksum
;
}
/*
* Parse EISA id for ISA PnP card.
*/
static
void
isapnp_parse_card_id
(
struct
pnp_card
*
card
,
unsigned
short
vendor
,
unsigned
short
device
)
{
struct
pnp_id
*
id
=
kzalloc
(
sizeof
(
struct
pnp_id
),
GFP_KERNEL
);
if
(
!
id
)
return
;
sprintf
(
id
->
id
,
"%c%c%c%x%x%x%x"
,
'A'
+
((
vendor
>>
2
)
&
0x3f
)
-
1
,
'A'
+
(((
vendor
&
3
)
<<
3
)
|
((
vendor
>>
13
)
&
7
))
-
1
,
'A'
+
((
vendor
>>
8
)
&
0x1f
)
-
1
,
(
device
>>
4
)
&
0x0f
,
device
&
0x0f
,
(
device
>>
12
)
&
0x0f
,
(
device
>>
8
)
&
0x0f
);
pnp_add_card_id
(
id
,
card
);
}
/*
* Build device list for all present ISA PnP devices.
*/
...
...
@@ -848,6 +827,8 @@ static int __init isapnp_build_device_list(void)
int
csn
;
unsigned
char
header
[
9
],
checksum
;
struct
pnp_card
*
card
;
u32
eisa_id
;
char
id
[
8
];
isapnp_wait
();
isapnp_key
();
...
...
@@ -855,32 +836,30 @@ static int __init isapnp_build_device_list(void)
isapnp_wake
(
csn
);
isapnp_peek
(
header
,
9
);
checksum
=
isapnp_checksum
(
header
);
eisa_id
=
header
[
0
]
|
header
[
1
]
<<
8
|
header
[
2
]
<<
16
|
header
[
3
]
<<
24
;
pnp_eisa_id_to_string
(
eisa_id
,
id
);
card
=
pnp_alloc_card
(
&
isapnp_protocol
,
csn
,
id
);
if
(
!
card
)
continue
;
#if 0
printk(KERN_DEBUG
dev_info(&card->dev,
"vendor: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
header[0], header[1], header[2], header[3], header[4],
header[5], header[6], header[7], header[8]);
printk(KERN_DEBUG "checksum = 0x%
x\n", checksum);
dev_info(&card->dev, "checksum = %#
x\n", checksum);
#endif
if
((
card
=
kzalloc
(
sizeof
(
struct
pnp_card
),
GFP_KERNEL
))
==
NULL
)
continue
;
card
->
number
=
csn
;
INIT_LIST_HEAD
(
&
card
->
devices
);
isapnp_parse_card_id
(
card
,
(
header
[
1
]
<<
8
)
|
header
[
0
],
(
header
[
3
]
<<
8
)
|
header
[
2
]);
card
->
serial
=
(
header
[
7
]
<<
24
)
|
(
header
[
6
]
<<
16
)
|
(
header
[
5
]
<<
8
)
|
header
[
4
];
isapnp_checksum_value
=
0x00
;
isapnp_parse_resource_map
(
card
);
if
(
isapnp_checksum_value
!=
0x00
)
printk
(
KERN_ERR
"isapnp: checksum for device %i is not valid (0x%x)
\n
"
,
csn
,
isapnp_checksum_value
);
dev_err
(
&
card
->
dev
,
"invalid checksum %#x
\n
"
,
isapnp_checksum_value
);
card
->
checksum
=
isapnp_checksum_value
;
card
->
protocol
=
&
isapnp_protocol
;
pnp_add_card
(
card
);
}
...
...
@@ -947,100 +926,117 @@ EXPORT_SYMBOL(isapnp_cfg_begin);
EXPORT_SYMBOL
(
isapnp_cfg_end
);
EXPORT_SYMBOL
(
isapnp_write_byte
);
static
int
isapnp_read_resources
(
struct
pnp_dev
*
dev
,
struct
pnp_resource_table
*
res
)
static
int
isapnp_get_resources
(
struct
pnp_dev
*
dev
)
{
int
tmp
,
ret
;
struct
pnp_resource
*
pnp_res
;
int
i
,
ret
;
dev_dbg
(
&
dev
->
dev
,
"get resources
\n
"
);
pnp_init_resources
(
dev
);
isapnp_cfg_begin
(
dev
->
card
->
number
,
dev
->
number
);
dev
->
active
=
isapnp_read_byte
(
ISAPNP_CFG_ACTIVATE
);
if
(
dev
->
active
)
{
for
(
tmp
=
0
;
tmp
<
ISAPNP_MAX_PORT
;
tmp
++
)
{
ret
=
isapnp_read_word
(
ISAPNP_CFG_PORT
+
(
tmp
<<
1
));
if
(
!
ret
)
continue
;
res
->
port_resource
[
tmp
].
start
=
ret
;
res
->
port_resource
[
tmp
].
flags
=
IORESOURCE_IO
;
if
(
!
dev
->
active
)
goto
__end
;
for
(
i
=
0
;
i
<
ISAPNP_MAX_PORT
;
i
++
)
{
ret
=
isapnp_read_word
(
ISAPNP_CFG_PORT
+
(
i
<<
1
));
if
(
ret
)
{
pnp_res
=
pnp_add_io_resource
(
dev
,
ret
,
ret
,
0
);
if
(
pnp_res
)
pnp_res
->
index
=
i
;
}
for
(
tmp
=
0
;
tmp
<
ISAPNP_MAX_MEM
;
tmp
++
)
{
ret
=
isapnp_read_word
(
ISAPNP_CFG_MEM
+
(
tmp
<<
3
))
<<
8
;
if
(
!
ret
)
continue
;
res
->
mem_resource
[
tmp
].
start
=
ret
;
res
->
mem_resource
[
tmp
].
flags
=
IORESOURCE_MEM
;
}
for
(
tmp
=
0
;
tmp
<
ISAPNP_MAX_IRQ
;
tmp
++
)
{
ret
=
(
isapnp_read_word
(
ISAPNP_CFG_IRQ
+
(
tmp
<<
1
))
>>
8
);
if
(
!
ret
)
continue
;
res
->
irq_resource
[
tmp
].
start
=
res
->
irq_resource
[
tmp
].
end
=
ret
;
res
->
irq_resource
[
tmp
].
flags
=
IORESOURCE_IRQ
;
for
(
i
=
0
;
i
<
ISAPNP_MAX_MEM
;
i
++
)
{
ret
=
isapnp_read_word
(
ISAPNP_CFG_MEM
+
(
i
<<
3
))
<<
8
;
if
(
ret
)
{
pnp_res
=
pnp_add_mem_resource
(
dev
,
ret
,
ret
,
0
);
if
(
pnp_res
)
pnp_res
->
index
=
i
;
}
for
(
tmp
=
0
;
tmp
<
ISAPNP_MAX_DMA
;
tmp
++
)
{
ret
=
isapnp_read_byte
(
ISAPNP_CFG_DMA
+
tmp
);
if
(
ret
==
4
)
continue
;
res
->
dma_resource
[
tmp
].
start
=
res
->
dma_resource
[
tmp
].
end
=
ret
;
res
->
dma_resource
[
tmp
].
flags
=
IORESOURCE_DMA
;
}
for
(
i
=
0
;
i
<
ISAPNP_MAX_IRQ
;
i
++
)
{
ret
=
isapnp_read_word
(
ISAPNP_CFG_IRQ
+
(
i
<<
1
))
>>
8
;
if
(
ret
)
{
pnp_res
=
pnp_add_irq_resource
(
dev
,
ret
,
0
);
if
(
pnp_res
)
pnp_res
->
index
=
i
;
}
}
for
(
i
=
0
;
i
<
ISAPNP_MAX_DMA
;
i
++
)
{
ret
=
isapnp_read_byte
(
ISAPNP_CFG_DMA
+
i
);
if
(
ret
!=
4
)
{
pnp_res
=
pnp_add_dma_resource
(
dev
,
ret
,
0
);
if
(
pnp_res
)
pnp_res
->
index
=
i
;
}
}
return
0
;
}
static
int
isapnp_get_resources
(
struct
pnp_dev
*
dev
,
struct
pnp_resource_table
*
res
)
{
int
ret
;
pnp_init_resource_table
(
res
);
isapnp_cfg_begin
(
dev
->
card
->
number
,
dev
->
number
);
ret
=
isapnp_read_resources
(
dev
,
res
);
__end:
isapnp_cfg_end
();
return
ret
;
return
0
;
}
static
int
isapnp_set_resources
(
struct
pnp_dev
*
dev
,
struct
pnp_resource_table
*
res
)
static
int
isapnp_set_resources
(
struct
pnp_dev
*
dev
)
{
int
tmp
;
struct
pnp_resource
*
pnp_res
;
struct
resource
*
res
;
int
tmp
,
index
;
dev_dbg
(
&
dev
->
dev
,
"set resources
\n
"
);
isapnp_cfg_begin
(
dev
->
card
->
number
,
dev
->
number
);
dev
->
active
=
1
;
for
(
tmp
=
0
;
tmp
<
ISAPNP_MAX_PORT
&&
(
res
->
port_resource
[
tmp
].
flags
&
(
IORESOURCE_IO
|
IORESOURCE_UNSET
))
==
IORESOURCE_IO
;
tmp
++
)
isapnp_write_word
(
ISAPNP_CFG_PORT
+
(
tmp
<<
1
),
res
->
port_resource
[
tmp
].
start
);
for
(
tmp
=
0
;
tmp
<
ISAPNP_MAX_IRQ
&&
(
res
->
irq_resource
[
tmp
].
flags
&
(
IORESOURCE_IRQ
|
IORESOURCE_UNSET
))
==
IORESOURCE_IRQ
;
tmp
++
)
{
int
irq
=
res
->
irq_resource
[
tmp
].
start
;
for
(
tmp
=
0
;
tmp
<
ISAPNP_MAX_PORT
;
tmp
++
)
{
pnp_res
=
pnp_get_pnp_resource
(
dev
,
IORESOURCE_IO
,
tmp
);
if
(
!
pnp_res
)
continue
;
res
=
&
pnp_res
->
res
;
if
(
pnp_resource_valid
(
res
))
{
index
=
pnp_res
->
index
;
dev_dbg
(
&
dev
->
dev
,
" set io %d to %#llx
\n
"
,
index
,
(
unsigned
long
long
)
res
->
start
);
isapnp_write_word
(
ISAPNP_CFG_PORT
+
(
index
<<
1
),
res
->
start
);
}
}
for
(
tmp
=
0
;
tmp
<
ISAPNP_MAX_IRQ
;
tmp
++
)
{
pnp_res
=
pnp_get_pnp_resource
(
dev
,
IORESOURCE_IRQ
,
tmp
);
if
(
!
pnp_res
)
continue
;
res
=
&
pnp_res
->
res
;
if
(
pnp_resource_valid
(
res
))
{
int
irq
=
res
->
start
;
if
(
irq
==
2
)
irq
=
9
;
isapnp_write_byte
(
ISAPNP_CFG_IRQ
+
(
tmp
<<
1
),
irq
);
index
=
pnp_res
->
index
;
dev_dbg
(
&
dev
->
dev
,
" set irq %d to %d
\n
"
,
index
,
irq
);
isapnp_write_byte
(
ISAPNP_CFG_IRQ
+
(
index
<<
1
),
irq
);
}
}
for
(
tmp
=
0
;
tmp
<
ISAPNP_MAX_DMA
;
tmp
++
)
{
pnp_res
=
pnp_get_pnp_resource
(
dev
,
IORESOURCE_DMA
,
tmp
);
if
(
!
pnp_res
)
continue
;
res
=
&
pnp_res
->
res
;
if
(
pnp_resource_valid
(
res
))
{
index
=
pnp_res
->
index
;
dev_dbg
(
&
dev
->
dev
,
" set dma %d to %lld
\n
"
,
index
,
(
unsigned
long
long
)
res
->
start
);
isapnp_write_byte
(
ISAPNP_CFG_DMA
+
index
,
res
->
start
);
}
}
for
(
tmp
=
0
;
tmp
<
ISAPNP_MAX_MEM
;
tmp
++
)
{
pnp_res
=
pnp_get_pnp_resource
(
dev
,
IORESOURCE_MEM
,
tmp
);
if
(
!
pnp_res
)
continue
;
res
=
&
pnp_res
->
res
;
if
(
pnp_resource_valid
(
res
))
{
index
=
pnp_res
->
index
;
dev_dbg
(
&
dev
->
dev
,
" set mem %d to %#llx
\n
"
,
index
,
(
unsigned
long
long
)
res
->
start
);
isapnp_write_word
(
ISAPNP_CFG_MEM
+
(
index
<<
3
),
(
res
->
start
>>
8
)
&
0xffff
);
}
}
for
(
tmp
=
0
;
tmp
<
ISAPNP_MAX_DMA
&&
(
res
->
dma_resource
[
tmp
].
flags
&
(
IORESOURCE_DMA
|
IORESOURCE_UNSET
))
==
IORESOURCE_DMA
;
tmp
++
)
isapnp_write_byte
(
ISAPNP_CFG_DMA
+
tmp
,
res
->
dma_resource
[
tmp
].
start
);
for
(
tmp
=
0
;
tmp
<
ISAPNP_MAX_MEM
&&
(
res
->
mem_resource
[
tmp
].
flags
&
(
IORESOURCE_MEM
|
IORESOURCE_UNSET
))
==
IORESOURCE_MEM
;
tmp
++
)
isapnp_write_word
(
ISAPNP_CFG_MEM
+
(
tmp
<<
3
),
(
res
->
mem_resource
[
tmp
].
start
>>
8
)
&
0xffff
);
/* FIXME: We aren't handling 32bit mems properly here */
isapnp_activate
(
dev
->
number
);
isapnp_cfg_end
();
...
...
@@ -1138,13 +1134,13 @@ static int __init isapnp_init(void)
protocol_for_each_card
(
&
isapnp_protocol
,
card
)
{
cards
++
;
if
(
isapnp_verbose
)
{
printk
(
KERN_INFO
"isapnp: C
ard '%s'
\n
"
,
card
->
name
[
0
]
?
card
->
name
:
"
U
nknown"
);
dev_info
(
&
card
->
dev
,
"c
ard '%s'
\n
"
,
card
->
name
[
0
]
?
card
->
name
:
"
u
nknown"
);
if
(
isapnp_verbose
<
2
)
continue
;
card_for_each_dev
(
card
,
dev
)
{
printk
(
KERN_INFO
"isapnp: D
evice '%s'
\n
"
,
dev
->
name
[
0
]
?
dev
->
name
:
"
U
nknown"
);
dev_info
(
&
card
->
dev
,
"d
evice '%s'
\n
"
,
dev
->
name
[
0
]
?
dev
->
name
:
"
u
nknown"
);
}
}
}
...
...
drivers/pnp/manager.c
浏览文件 @
008238b5
...
...
@@ -19,100 +19,118 @@ DEFINE_MUTEX(pnp_res_mutex);
static
int
pnp_assign_port
(
struct
pnp_dev
*
dev
,
struct
pnp_port
*
rule
,
int
idx
)
{
resource_size_t
*
start
,
*
end
;
unsigned
long
*
flag
s
;
struct
pnp_resource
*
pnp_res
;
struct
resource
*
re
s
;
if
(
idx
>=
PNP_MAX_PORT
)
{
pnp_res
=
pnp_get_pnp_resource
(
dev
,
IORESOURCE_IO
,
idx
);
if
(
!
pnp_res
)
{
dev_err
(
&
dev
->
dev
,
"too many I/O port resources
\n
"
);
/* pretend we were successful so at least the manager won't try again */
return
1
;
}
res
=
&
pnp_res
->
res
;
/* check if this resource has been manually set, if so skip */
if
(
!
(
dev
->
res
.
port_resource
[
idx
].
flags
&
IORESOURCE_AUTO
))
if
(
!
(
res
->
flags
&
IORESOURCE_AUTO
))
{
dev_dbg
(
&
dev
->
dev
,
" io %d already set to %#llx-%#llx "
"flags %#lx
\n
"
,
idx
,
(
unsigned
long
long
)
res
->
start
,
(
unsigned
long
long
)
res
->
end
,
res
->
flags
);
return
1
;
start
=
&
dev
->
res
.
port_resource
[
idx
].
start
;
end
=
&
dev
->
res
.
port_resource
[
idx
].
end
;
flags
=
&
dev
->
res
.
port_resource
[
idx
].
flags
;
}
/* set the initial values */
*
flags
|=
rule
->
flags
|
IORESOURCE_IO
;
*
flags
&=
~
IORESOURCE_UNSET
;
pnp_res
->
index
=
idx
;
res
->
flags
|=
rule
->
flags
|
IORESOURCE_IO
;
res
->
flags
&=
~
IORESOURCE_UNSET
;
if
(
!
rule
->
size
)
{
*
flags
|=
IORESOURCE_DISABLED
;
res
->
flags
|=
IORESOURCE_DISABLED
;
dev_dbg
(
&
dev
->
dev
,
" io %d disabled
\n
"
,
idx
);
return
1
;
/* skip disabled resource requests */
}
*
start
=
rule
->
min
;
*
end
=
*
start
+
rule
->
size
-
1
;
res
->
start
=
rule
->
min
;
res
->
end
=
res
->
start
+
rule
->
size
-
1
;
/* run through until pnp_check_port is happy */
while
(
!
pnp_check_port
(
dev
,
idx
))
{
*
start
+=
rule
->
align
;
*
end
=
*
start
+
rule
->
size
-
1
;
if
(
*
start
>
rule
->
max
||
!
rule
->
align
)
while
(
!
pnp_check_port
(
dev
,
res
))
{
res
->
start
+=
rule
->
align
;
res
->
end
=
res
->
start
+
rule
->
size
-
1
;
if
(
res
->
start
>
rule
->
max
||
!
rule
->
align
)
{
dev_dbg
(
&
dev
->
dev
,
" couldn't assign io %d
\n
"
,
idx
);
return
0
;
}
}
dev_dbg
(
&
dev
->
dev
,
" assign io %d %#llx-%#llx
\n
"
,
idx
,
(
unsigned
long
long
)
res
->
start
,
(
unsigned
long
long
)
res
->
end
);
return
1
;
}
static
int
pnp_assign_mem
(
struct
pnp_dev
*
dev
,
struct
pnp_mem
*
rule
,
int
idx
)
{
resource_size_t
*
start
,
*
end
;
unsigned
long
*
flag
s
;
struct
pnp_resource
*
pnp_res
;
struct
resource
*
re
s
;
if
(
idx
>=
PNP_MAX_MEM
)
{
pnp_res
=
pnp_get_pnp_resource
(
dev
,
IORESOURCE_MEM
,
idx
);
if
(
!
pnp_res
)
{
dev_err
(
&
dev
->
dev
,
"too many memory resources
\n
"
);
/* pretend we were successful so at least the manager won't try again */
return
1
;
}
res
=
&
pnp_res
->
res
;
/* check if this resource has been manually set, if so skip */
if
(
!
(
dev
->
res
.
mem_resource
[
idx
].
flags
&
IORESOURCE_AUTO
))
if
(
!
(
res
->
flags
&
IORESOURCE_AUTO
))
{
dev_dbg
(
&
dev
->
dev
,
" mem %d already set to %#llx-%#llx "
"flags %#lx
\n
"
,
idx
,
(
unsigned
long
long
)
res
->
start
,
(
unsigned
long
long
)
res
->
end
,
res
->
flags
);
return
1
;
start
=
&
dev
->
res
.
mem_resource
[
idx
].
start
;
end
=
&
dev
->
res
.
mem_resource
[
idx
].
end
;
flags
=
&
dev
->
res
.
mem_resource
[
idx
].
flags
;
}
/* set the initial values */
*
flags
|=
rule
->
flags
|
IORESOURCE_MEM
;
*
flags
&=
~
IORESOURCE_UNSET
;
pnp_res
->
index
=
idx
;
res
->
flags
|=
rule
->
flags
|
IORESOURCE_MEM
;
res
->
flags
&=
~
IORESOURCE_UNSET
;
/* convert pnp flags to standard Linux flags */
if
(
!
(
rule
->
flags
&
IORESOURCE_MEM_WRITEABLE
))
*
flags
|=
IORESOURCE_READONLY
;
res
->
flags
|=
IORESOURCE_READONLY
;
if
(
rule
->
flags
&
IORESOURCE_MEM_CACHEABLE
)
*
flags
|=
IORESOURCE_CACHEABLE
;
res
->
flags
|=
IORESOURCE_CACHEABLE
;
if
(
rule
->
flags
&
IORESOURCE_MEM_RANGELENGTH
)
*
flags
|=
IORESOURCE_RANGELENGTH
;
res
->
flags
|=
IORESOURCE_RANGELENGTH
;
if
(
rule
->
flags
&
IORESOURCE_MEM_SHADOWABLE
)
*
flags
|=
IORESOURCE_SHADOWABLE
;
res
->
flags
|=
IORESOURCE_SHADOWABLE
;
if
(
!
rule
->
size
)
{
*
flags
|=
IORESOURCE_DISABLED
;
res
->
flags
|=
IORESOURCE_DISABLED
;
dev_dbg
(
&
dev
->
dev
,
" mem %d disabled
\n
"
,
idx
);
return
1
;
/* skip disabled resource requests */
}
*
start
=
rule
->
min
;
*
end
=
*
start
+
rule
->
size
-
1
;
res
->
start
=
rule
->
min
;
res
->
end
=
res
->
start
+
rule
->
size
-
1
;
/* run through until pnp_check_mem is happy */
while
(
!
pnp_check_mem
(
dev
,
idx
))
{
*
start
+=
rule
->
align
;
*
end
=
*
start
+
rule
->
size
-
1
;
if
(
*
start
>
rule
->
max
||
!
rule
->
align
)
while
(
!
pnp_check_mem
(
dev
,
res
))
{
res
->
start
+=
rule
->
align
;
res
->
end
=
res
->
start
+
rule
->
size
-
1
;
if
(
res
->
start
>
rule
->
max
||
!
rule
->
align
)
{
dev_dbg
(
&
dev
->
dev
,
" couldn't assign mem %d
\n
"
,
idx
);
return
0
;
}
}
dev_dbg
(
&
dev
->
dev
,
" assign mem %d %#llx-%#llx
\n
"
,
idx
,
(
unsigned
long
long
)
res
->
start
,
(
unsigned
long
long
)
res
->
end
);
return
1
;
}
static
int
pnp_assign_irq
(
struct
pnp_dev
*
dev
,
struct
pnp_irq
*
rule
,
int
idx
)
{
resource_size_t
*
start
,
*
end
;
unsigned
long
*
flag
s
;
struct
pnp_resource
*
pnp_res
;
struct
resource
*
re
s
;
int
i
;
/* IRQ priority: this table is good for i386 */
...
...
@@ -120,49 +138,59 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)
5
,
10
,
11
,
12
,
9
,
14
,
15
,
7
,
3
,
4
,
13
,
0
,
1
,
6
,
8
,
2
};
if
(
idx
>=
PNP_MAX_IRQ
)
{
pnp_res
=
pnp_get_pnp_resource
(
dev
,
IORESOURCE_IRQ
,
idx
);
if
(
!
pnp_res
)
{
dev_err
(
&
dev
->
dev
,
"too many IRQ resources
\n
"
);
/* pretend we were successful so at least the manager won't try again */
return
1
;
}
res
=
&
pnp_res
->
res
;
/* check if this resource has been manually set, if so skip */
if
(
!
(
dev
->
res
.
irq_resource
[
idx
].
flags
&
IORESOURCE_AUTO
))
if
(
!
(
res
->
flags
&
IORESOURCE_AUTO
))
{
dev_dbg
(
&
dev
->
dev
,
" irq %d already set to %d flags %#lx
\n
"
,
idx
,
(
int
)
res
->
start
,
res
->
flags
);
return
1
;
start
=
&
dev
->
res
.
irq_resource
[
idx
].
start
;
end
=
&
dev
->
res
.
irq_resource
[
idx
].
end
;
flags
=
&
dev
->
res
.
irq_resource
[
idx
].
flags
;
}
/* set the initial values */
*
flags
|=
rule
->
flags
|
IORESOURCE_IRQ
;
*
flags
&=
~
IORESOURCE_UNSET
;
pnp_res
->
index
=
idx
;
res
->
flags
|=
rule
->
flags
|
IORESOURCE_IRQ
;
res
->
flags
&=
~
IORESOURCE_UNSET
;
if
(
bitmap_empty
(
rule
->
map
,
PNP_IRQ_NR
))
{
*
flags
|=
IORESOURCE_DISABLED
;
res
->
flags
|=
IORESOURCE_DISABLED
;
dev_dbg
(
&
dev
->
dev
,
" irq %d disabled
\n
"
,
idx
);
return
1
;
/* skip disabled resource requests */
}
/* TBD: need check for >16 IRQ */
*
start
=
find_next_bit
(
rule
->
map
,
PNP_IRQ_NR
,
16
);
if
(
*
start
<
PNP_IRQ_NR
)
{
*
end
=
*
start
;
res
->
start
=
find_next_bit
(
rule
->
map
,
PNP_IRQ_NR
,
16
);
if
(
res
->
start
<
PNP_IRQ_NR
)
{
res
->
end
=
res
->
start
;
dev_dbg
(
&
dev
->
dev
,
" assign irq %d %d
\n
"
,
idx
,
(
int
)
res
->
start
);
return
1
;
}
for
(
i
=
0
;
i
<
16
;
i
++
)
{
if
(
test_bit
(
xtab
[
i
],
rule
->
map
))
{
*
start
=
*
end
=
xtab
[
i
];
if
(
pnp_check_irq
(
dev
,
idx
))
res
->
start
=
res
->
end
=
xtab
[
i
];
if
(
pnp_check_irq
(
dev
,
res
))
{
dev_dbg
(
&
dev
->
dev
,
" assign irq %d %d
\n
"
,
idx
,
(
int
)
res
->
start
);
return
1
;
}
}
}
dev_dbg
(
&
dev
->
dev
,
" couldn't assign irq %d
\n
"
,
idx
);
return
0
;
}
static
void
pnp_assign_dma
(
struct
pnp_dev
*
dev
,
struct
pnp_dma
*
rule
,
int
idx
)
{
resource_size_t
*
start
,
*
end
;
unsigned
long
*
flag
s
;
struct
pnp_resource
*
pnp_res
;
struct
resource
*
re
s
;
int
i
;
/* DMA priority: this table is good for i386 */
...
...
@@ -170,71 +198,89 @@ static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
1
,
3
,
5
,
6
,
7
,
0
,
2
,
4
};
if
(
idx
>=
PNP_MAX_DMA
)
{
pnp_res
=
pnp_get_pnp_resource
(
dev
,
IORESOURCE_DMA
,
idx
);
if
(
!
pnp_res
)
{
dev_err
(
&
dev
->
dev
,
"too many DMA resources
\n
"
);
return
;
}
res
=
&
pnp_res
->
res
;
/* check if this resource has been manually set, if so skip */
if
(
!
(
dev
->
res
.
dma_resource
[
idx
].
flags
&
IORESOURCE_AUTO
))
if
(
!
(
res
->
flags
&
IORESOURCE_AUTO
))
{
dev_dbg
(
&
dev
->
dev
,
" dma %d already set to %d flags %#lx
\n
"
,
idx
,
(
int
)
res
->
start
,
res
->
flags
);
return
;
start
=
&
dev
->
res
.
dma_resource
[
idx
].
start
;
end
=
&
dev
->
res
.
dma_resource
[
idx
].
end
;
flags
=
&
dev
->
res
.
dma_resource
[
idx
].
flags
;
}
/* set the initial values */
*
flags
|=
rule
->
flags
|
IORESOURCE_DMA
;
*
flags
&=
~
IORESOURCE_UNSET
;
pnp_res
->
index
=
idx
;
res
->
flags
|=
rule
->
flags
|
IORESOURCE_DMA
;
res
->
flags
&=
~
IORESOURCE_UNSET
;
for
(
i
=
0
;
i
<
8
;
i
++
)
{
if
(
rule
->
map
&
(
1
<<
xtab
[
i
]))
{
*
start
=
*
end
=
xtab
[
i
];
if
(
pnp_check_dma
(
dev
,
idx
))
res
->
start
=
res
->
end
=
xtab
[
i
];
if
(
pnp_check_dma
(
dev
,
res
))
{
dev_dbg
(
&
dev
->
dev
,
" assign dma %d %d
\n
"
,
idx
,
(
int
)
res
->
start
);
return
;
}
}
}
#ifdef MAX_DMA_CHANNELS
*
start
=
*
end
=
MAX_DMA_CHANNELS
;
res
->
start
=
res
->
end
=
MAX_DMA_CHANNELS
;
#endif
*
flags
|=
IORESOURCE_UNSET
|
IORESOURCE_DISABLED
;
res
->
flags
|=
IORESOURCE_UNSET
|
IORESOURCE_DISABLED
;
dev_dbg
(
&
dev
->
dev
,
" disable dma %d
\n
"
,
idx
);
}
void
pnp_init_resource
(
struct
resource
*
res
)
{
unsigned
long
type
;
type
=
res
->
flags
&
(
IORESOURCE_IO
|
IORESOURCE_MEM
|
IORESOURCE_IRQ
|
IORESOURCE_DMA
);
res
->
name
=
NULL
;
res
->
flags
=
type
|
IORESOURCE_AUTO
|
IORESOURCE_UNSET
;
if
(
type
==
IORESOURCE_IRQ
||
type
==
IORESOURCE_DMA
)
{
res
->
start
=
-
1
;
res
->
end
=
-
1
;
}
else
{
res
->
start
=
0
;
res
->
end
=
0
;
}
}
/**
* pnp_init_resources - Resets a resource table to default values.
* @table: pointer to the desired resource table
*/
void
pnp_init_resource
_table
(
struct
pnp_resource_table
*
table
)
void
pnp_init_resource
s
(
struct
pnp_dev
*
dev
)
{
struct
resource
*
res
;
int
idx
;
for
(
idx
=
0
;
idx
<
PNP_MAX_IRQ
;
idx
++
)
{
table
->
irq_resource
[
idx
].
name
=
NULL
;
table
->
irq_resource
[
idx
].
start
=
-
1
;
table
->
irq_resource
[
idx
].
end
=
-
1
;
table
->
irq_resource
[
idx
].
flags
=
IORESOURCE_IRQ
|
IORESOURCE_AUTO
|
IORESOURCE_UNSET
;
res
=
&
dev
->
res
->
irq
[
idx
].
res
;
res
->
flags
=
IORESOURCE_IRQ
;
pnp_init_resource
(
res
);
}
for
(
idx
=
0
;
idx
<
PNP_MAX_DMA
;
idx
++
)
{
table
->
dma_resource
[
idx
].
name
=
NULL
;
table
->
dma_resource
[
idx
].
start
=
-
1
;
table
->
dma_resource
[
idx
].
end
=
-
1
;
table
->
dma_resource
[
idx
].
flags
=
IORESOURCE_DMA
|
IORESOURCE_AUTO
|
IORESOURCE_UNSET
;
res
=
&
dev
->
res
->
dma
[
idx
].
res
;
res
->
flags
=
IORESOURCE_DMA
;
pnp_init_resource
(
res
);
}
for
(
idx
=
0
;
idx
<
PNP_MAX_PORT
;
idx
++
)
{
table
->
port_resource
[
idx
].
name
=
NULL
;
table
->
port_resource
[
idx
].
start
=
0
;
table
->
port_resource
[
idx
].
end
=
0
;
table
->
port_resource
[
idx
].
flags
=
IORESOURCE_IO
|
IORESOURCE_AUTO
|
IORESOURCE_UNSET
;
res
=
&
dev
->
res
->
port
[
idx
].
res
;
res
->
flags
=
IORESOURCE_IO
;
pnp_init_resource
(
res
);
}
for
(
idx
=
0
;
idx
<
PNP_MAX_MEM
;
idx
++
)
{
table
->
mem_resource
[
idx
].
name
=
NULL
;
table
->
mem_resource
[
idx
].
start
=
0
;
table
->
mem_resource
[
idx
].
end
=
0
;
table
->
mem_resource
[
idx
].
flags
=
IORESOURCE_MEM
|
IORESOURCE_AUTO
|
IORESOURCE_UNSET
;
res
=
&
dev
->
res
->
mem
[
idx
].
res
;
res
->
flags
=
IORESOURCE_MEM
;
pnp_init_resource
(
res
);
}
}
...
...
@@ -242,41 +288,38 @@ void pnp_init_resource_table(struct pnp_resource_table *table)
* pnp_clean_resources - clears resources that were not manually set
* @res: the resources to clean
*/
static
void
pnp_clean_resource_table
(
struct
pnp_
resource_table
*
res
)
static
void
pnp_clean_resource_table
(
struct
pnp_
dev
*
dev
)
{
struct
resource
*
res
;
int
idx
;
for
(
idx
=
0
;
idx
<
PNP_MAX_IRQ
;
idx
++
)
{
if
(
!
(
res
->
irq_resource
[
idx
].
flags
&
IORESOURCE_AUTO
))
continue
;
res
->
irq_resource
[
idx
].
start
=
-
1
;
res
->
irq_resource
[
idx
].
end
=
-
1
;
res
->
irq_resource
[
idx
].
flags
=
IORESOURCE_IRQ
|
IORESOURCE_AUTO
|
IORESOURCE_UNSET
;
res
=
&
dev
->
res
->
irq
[
idx
].
res
;
if
(
res
->
flags
&
IORESOURCE_AUTO
)
{
res
->
flags
=
IORESOURCE_IRQ
;
pnp_init_resource
(
res
);
}
}
for
(
idx
=
0
;
idx
<
PNP_MAX_DMA
;
idx
++
)
{
if
(
!
(
res
->
dma_resource
[
idx
].
flags
&
IORESOURCE_AUTO
))
continue
;
res
->
dma_resource
[
idx
].
start
=
-
1
;
res
->
dma_resource
[
idx
].
end
=
-
1
;
res
->
dma_resource
[
idx
].
flags
=
IORESOURCE_DMA
|
IORESOURCE_AUTO
|
IORESOURCE_UNSET
;
res
=
&
dev
->
res
->
dma
[
idx
].
res
;
if
(
res
->
flags
&
IORESOURCE_AUTO
)
{
res
->
flags
=
IORESOURCE_DMA
;
pnp_init_resource
(
res
);
}
}
for
(
idx
=
0
;
idx
<
PNP_MAX_PORT
;
idx
++
)
{
if
(
!
(
res
->
port_resource
[
idx
].
flags
&
IORESOURCE_AUTO
))
continue
;
res
->
port_resource
[
idx
].
start
=
0
;
res
->
port_resource
[
idx
].
end
=
0
;
res
->
port_resource
[
idx
].
flags
=
IORESOURCE_IO
|
IORESOURCE_AUTO
|
IORESOURCE_UNSET
;
res
=
&
dev
->
res
->
port
[
idx
].
res
;
if
(
res
->
flags
&
IORESOURCE_AUTO
)
{
res
->
flags
=
IORESOURCE_IO
;
pnp_init_resource
(
res
);
}
}
for
(
idx
=
0
;
idx
<
PNP_MAX_MEM
;
idx
++
)
{
if
(
!
(
res
->
mem_resource
[
idx
].
flags
&
IORESOURCE_AUTO
))
continue
;
res
->
mem_resource
[
idx
].
start
=
0
;
res
->
mem_resource
[
idx
].
end
=
0
;
res
->
mem_resource
[
idx
].
flags
=
IORESOURCE_MEM
|
IORESOURCE_AUTO
|
IORESOURCE_UNSET
;
res
=
&
dev
->
res
->
mem
[
idx
].
res
;
if
(
res
->
flags
&
IORESOURCE_AUTO
)
{
res
->
flags
=
IORESOURCE_MEM
;
pnp_init_resource
(
res
);
}
}
}
...
...
@@ -298,9 +341,11 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum)
if
(
!
pnp_can_configure
(
dev
))
return
-
ENODEV
;
dbg_pnp_show_resources
(
dev
,
"before pnp_assign_resources"
);
mutex_lock
(
&
pnp_res_mutex
);
pnp_clean_resource_table
(
&
dev
->
res
);
/* start with a fresh slate */
pnp_clean_resource_table
(
dev
);
if
(
dev
->
independent
)
{
dev_dbg
(
&
dev
->
dev
,
"assigning independent options
\n
"
);
port
=
dev
->
independent
->
port
;
mem
=
dev
->
independent
->
mem
;
irq
=
dev
->
independent
->
irq
;
...
...
@@ -333,6 +378,8 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum)
if
(
depnum
)
{
struct
pnp_option
*
dep
;
int
i
;
dev_dbg
(
&
dev
->
dev
,
"assigning dependent option %d
\n
"
,
depnum
);
for
(
i
=
1
,
dep
=
dev
->
dependent
;
i
<
depnum
;
i
++
,
dep
=
dep
->
next
)
if
(
!
dep
)
...
...
@@ -368,65 +415,14 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum)
goto
fail
;
mutex_unlock
(
&
pnp_res_mutex
);
dbg_pnp_show_resources
(
dev
,
"after pnp_assign_resources"
);
return
1
;
fail:
pnp_clean_resource_table
(
&
dev
->
res
);
mutex_unlock
(
&
pnp_res_mutex
);
return
0
;
}
/**
* pnp_manual_config_dev - Disables Auto Config and Manually sets the resource table
* @dev: pointer to the desired device
* @res: pointer to the new resource config
* @mode: 0 or PNP_CONFIG_FORCE
*
* This function can be used by drivers that want to manually set thier resources.
*/
int
pnp_manual_config_dev
(
struct
pnp_dev
*
dev
,
struct
pnp_resource_table
*
res
,
int
mode
)
{
int
i
;
struct
pnp_resource_table
*
bak
;
if
(
!
pnp_can_configure
(
dev
))
return
-
ENODEV
;
bak
=
pnp_alloc
(
sizeof
(
struct
pnp_resource_table
));
if
(
!
bak
)
return
-
ENOMEM
;
*
bak
=
dev
->
res
;
mutex_lock
(
&
pnp_res_mutex
);
dev
->
res
=
*
res
;
if
(
!
(
mode
&
PNP_CONFIG_FORCE
))
{
for
(
i
=
0
;
i
<
PNP_MAX_PORT
;
i
++
)
{
if
(
!
pnp_check_port
(
dev
,
i
))
goto
fail
;
}
for
(
i
=
0
;
i
<
PNP_MAX_MEM
;
i
++
)
{
if
(
!
pnp_check_mem
(
dev
,
i
))
goto
fail
;
}
for
(
i
=
0
;
i
<
PNP_MAX_IRQ
;
i
++
)
{
if
(
!
pnp_check_irq
(
dev
,
i
))
goto
fail
;
}
for
(
i
=
0
;
i
<
PNP_MAX_DMA
;
i
++
)
{
if
(
!
pnp_check_dma
(
dev
,
i
))
goto
fail
;
}
}
pnp_clean_resource_table
(
dev
);
mutex_unlock
(
&
pnp_res_mutex
);
kfree
(
bak
);
dbg_pnp_show_resources
(
dev
,
"after pnp_assign_resources (failed)"
);
return
0
;
fail:
dev
->
res
=
*
bak
;
mutex_unlock
(
&
pnp_res_mutex
);
kfree
(
bak
);
return
-
EINVAL
;
}
/**
...
...
@@ -473,7 +469,8 @@ int pnp_start_dev(struct pnp_dev *dev)
return
-
EINVAL
;
}
if
(
dev
->
protocol
->
set
(
dev
,
&
dev
->
res
)
<
0
)
{
dbg_pnp_show_resources
(
dev
,
"pnp_start_dev"
);
if
(
dev
->
protocol
->
set
(
dev
)
<
0
)
{
dev_err
(
&
dev
->
dev
,
"activation failed
\n
"
);
return
-
EIO
;
}
...
...
@@ -549,30 +546,13 @@ int pnp_disable_dev(struct pnp_dev *dev)
/* release the resources so that other devices can use them */
mutex_lock
(
&
pnp_res_mutex
);
pnp_clean_resource_table
(
&
dev
->
res
);
pnp_clean_resource_table
(
dev
);
mutex_unlock
(
&
pnp_res_mutex
);
return
0
;
}
/**
* pnp_resource_change - change one resource
* @resource: pointer to resource to be changed
* @start: start of region
* @size: size of region
*/
void
pnp_resource_change
(
struct
resource
*
resource
,
resource_size_t
start
,
resource_size_t
size
)
{
resource
->
flags
&=
~
(
IORESOURCE_AUTO
|
IORESOURCE_UNSET
);
resource
->
start
=
start
;
resource
->
end
=
start
+
size
-
1
;
}
EXPORT_SYMBOL
(
pnp_manual_config_dev
);
EXPORT_SYMBOL
(
pnp_start_dev
);
EXPORT_SYMBOL
(
pnp_stop_dev
);
EXPORT_SYMBOL
(
pnp_activate_dev
);
EXPORT_SYMBOL
(
pnp_disable_dev
);
EXPORT_SYMBOL
(
pnp_resource_change
);
EXPORT_SYMBOL
(
pnp_init_resource_table
);
drivers/pnp/pnpacpi/Makefile
浏览文件 @
008238b5
...
...
@@ -3,3 +3,7 @@
#
obj-y
:=
core.o rsparser.o
ifeq
($(CONFIG_PNP_DEBUG),y)
EXTRA_CFLAGS
+=
-DDEBUG
endif
drivers/pnp/pnpacpi/core.c
浏览文件 @
008238b5
...
...
@@ -25,6 +25,7 @@
#include <acpi/acpi_bus.h>
#include <acpi/actypes.h>
#include "../base.h"
#include "pnpacpi.h"
static
int
num
=
0
;
...
...
@@ -72,40 +73,24 @@ static int __init ispnpidacpi(char *id)
return
1
;
}
static
void
__init
pnpidacpi_to_pnpid
(
char
*
id
,
char
*
str
)
static
int
pnpacpi_get_resources
(
struct
pnp_dev
*
dev
)
{
str
[
0
]
=
id
[
0
];
str
[
1
]
=
id
[
1
];
str
[
2
]
=
id
[
2
];
str
[
3
]
=
tolower
(
id
[
3
]);
str
[
4
]
=
tolower
(
id
[
4
]);
str
[
5
]
=
tolower
(
id
[
5
]);
str
[
6
]
=
tolower
(
id
[
6
]);
str
[
7
]
=
'\0'
;
dev_dbg
(
&
dev
->
dev
,
"get resources
\n
"
);
return
pnpacpi_parse_allocated_resource
(
dev
);
}
static
int
pnpacpi_get_resources
(
struct
pnp_dev
*
dev
,
struct
pnp_resource_table
*
res
)
{
acpi_status
status
;
status
=
pnpacpi_parse_allocated_resource
((
acpi_handle
)
dev
->
data
,
&
dev
->
res
);
return
ACPI_FAILURE
(
status
)
?
-
ENODEV
:
0
;
}
static
int
pnpacpi_set_resources
(
struct
pnp_dev
*
dev
,
struct
pnp_resource_table
*
res
)
static
int
pnpacpi_set_resources
(
struct
pnp_dev
*
dev
)
{
acpi_handle
handle
=
dev
->
data
;
struct
acpi_buffer
buffer
;
int
ret
=
0
;
int
ret
;
acpi_status
status
;
ret
=
pnpacpi_build_resource_template
(
handle
,
&
buffer
);
dev_dbg
(
&
dev
->
dev
,
"set resources
\n
"
);
ret
=
pnpacpi_build_resource_template
(
dev
,
&
buffer
);
if
(
ret
)
return
ret
;
ret
=
pnpacpi_encode_resources
(
res
,
&
buffer
);
ret
=
pnpacpi_encode_resources
(
dev
,
&
buffer
);
if
(
ret
)
{
kfree
(
buffer
.
pointer
);
return
ret
;
...
...
@@ -163,7 +148,6 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
{
acpi_handle
temp
=
NULL
;
acpi_status
status
;
struct
pnp_id
*
dev_id
;
struct
pnp_dev
*
dev
;
status
=
acpi_get_handle
(
device
->
handle
,
"_CRS"
,
&
temp
);
...
...
@@ -171,11 +155,10 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
is_exclusive_device
(
device
))
return
0
;
dev
=
kzalloc
(
sizeof
(
struct
pnp_dev
),
GFP_KERNEL
);
if
(
!
dev
)
{
pnp_err
(
"Out of memory"
);
dev
=
pnp_alloc_dev
(
&
pnpacpi_protocol
,
num
,
acpi_device_hid
(
device
));
if
(
!
dev
)
return
-
ENOMEM
;
}
dev
->
data
=
device
->
handle
;
/* .enabled means the device can decode the resources */
dev
->
active
=
device
->
status
.
enabled
;
...
...
@@ -191,44 +174,17 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
if
(
ACPI_SUCCESS
(
status
))
dev
->
capabilities
|=
PNP_DISABLE
;
dev
->
protocol
=
&
pnpacpi_protocol
;
if
(
strlen
(
acpi_device_name
(
device
)))
strncpy
(
dev
->
name
,
acpi_device_name
(
device
),
sizeof
(
dev
->
name
));
else
strncpy
(
dev
->
name
,
acpi_device_bid
(
device
),
sizeof
(
dev
->
name
));
dev
->
number
=
num
;
/* set the initial values for the PnP device */
dev_id
=
kzalloc
(
sizeof
(
struct
pnp_id
),
GFP_KERNEL
);
if
(
!
dev_id
)
goto
err
;
pnpidacpi_to_pnpid
(
acpi_device_hid
(
device
),
dev_id
->
id
);
pnp_add_id
(
dev_id
,
dev
);
if
(
dev
->
active
)
{
/* parse allocated resource */
status
=
pnpacpi_parse_allocated_resource
(
device
->
handle
,
&
dev
->
res
);
if
(
ACPI_FAILURE
(
status
)
&&
(
status
!=
AE_NOT_FOUND
))
{
pnp_err
(
"PnPACPI: METHOD_NAME__CRS failure for %s"
,
dev_id
->
id
);
goto
err1
;
}
}
if
(
dev
->
active
)
pnpacpi_parse_allocated_resource
(
dev
);
if
(
dev
->
capabilities
&
PNP_CONFIGURABLE
)
{
status
=
pnpacpi_parse_resource_option_data
(
device
->
handle
,
dev
);
if
(
ACPI_FAILURE
(
status
)
&&
(
status
!=
AE_NOT_FOUND
))
{
pnp_err
(
"PnPACPI: METHOD_NAME__PRS failure for %s"
,
dev_id
->
id
);
goto
err1
;
}
}
if
(
dev
->
capabilities
&
PNP_CONFIGURABLE
)
pnpacpi_parse_resource_option_data
(
dev
);
/* parse compatible ids */
if
(
device
->
flags
.
compatible_ids
)
{
struct
acpi_compatible_id_list
*
cid_list
=
device
->
pnp
.
cid_list
;
int
i
;
...
...
@@ -236,27 +192,17 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
for
(
i
=
0
;
i
<
cid_list
->
count
;
i
++
)
{
if
(
!
ispnpidacpi
(
cid_list
->
id
[
i
].
value
))
continue
;
dev_id
=
kzalloc
(
sizeof
(
struct
pnp_id
),
GFP_KERNEL
);
if
(
!
dev_id
)
continue
;
pnpidacpi_to_pnpid
(
cid_list
->
id
[
i
].
value
,
dev_id
->
id
);
pnp_add_id
(
dev_id
,
dev
);
pnp_add_id
(
dev
,
cid_list
->
id
[
i
].
value
);
}
}
/* clear out the damaged flags */
if
(
!
dev
->
active
)
pnp_init_resource
_table
(
&
dev
->
res
);
pnp_init_resource
s
(
dev
);
pnp_add_device
(
dev
);
num
++
;
return
AE_OK
;
err1:
kfree
(
dev_id
);
err:
kfree
(
dev
);
return
-
EINVAL
;
}
static
acpi_status
__init
pnpacpi_add_device_handler
(
acpi_handle
handle
,
...
...
drivers/pnp/pnpacpi/pnpacpi.h
浏览文件 @
008238b5
...
...
@@ -5,8 +5,8 @@
#include <linux/acpi.h>
#include <linux/pnp.h>
acpi_status
pnpacpi_parse_allocated_resource
(
acpi_handle
,
struct
pnp_resource_table
*
);
acpi_status
pnpacpi_parse_resource_option_data
(
acpi_handle
,
struct
pnp_dev
*
);
int
pnpacpi_encode_resources
(
struct
pnp_
resource_table
*
,
struct
acpi_buffer
*
);
int
pnpacpi_build_resource_template
(
acpi_handle
,
struct
acpi_buffer
*
);
int
pnpacpi_parse_allocated_resource
(
struct
pnp_dev
*
);
int
pnpacpi_parse_resource_option_data
(
struct
pnp_dev
*
);
int
pnpacpi_encode_resources
(
struct
pnp_
dev
*
,
struct
acpi_buffer
*
);
int
pnpacpi_build_resource_template
(
struct
pnp_dev
*
,
struct
acpi_buffer
*
);
#endif
drivers/pnp/pnpacpi/rsparser.c
浏览文件 @
008238b5
此差异已折叠。
点击以展开。
drivers/pnp/pnpbios/Makefile
浏览文件 @
008238b5
...
...
@@ -5,3 +5,7 @@
pnpbios-proc-$(CONFIG_PNPBIOS_PROC_FS)
=
proc.o
obj-y
:=
core.o bioscalls.o rsparser.o
$
(
pnpbios-proc-y
)
ifeq
($(CONFIG_PNP_DEBUG),y)
EXTRA_CFLAGS
+=
-DDEBUG
endif
drivers/pnp/pnpbios/bioscalls.c
浏览文件 @
008238b5
...
...
@@ -7,7 +7,6 @@
#include <linux/init.h>
#include <linux/linkage.h>
#include <linux/kernel.h>
#include <linux/pnpbios.h>
#include <linux/device.h>
#include <linux/pnp.h>
#include <linux/mm.h>
...
...
drivers/pnp/pnpbios/core.c
浏览文件 @
008238b5
...
...
@@ -50,7 +50,6 @@
#include <linux/init.h>
#include <linux/linkage.h>
#include <linux/kernel.h>
#include <linux/pnpbios.h>
#include <linux/device.h>
#include <linux/pnp.h>
#include <linux/mm.h>
...
...
@@ -69,6 +68,7 @@
#include <asm/system.h>
#include <asm/byteorder.h>
#include "../base.h"
#include "pnpbios.h"
/*
...
...
@@ -203,8 +203,7 @@ static int pnp_dock_thread(void *unused)
#endif
/* CONFIG_HOTPLUG */
static
int
pnpbios_get_resources
(
struct
pnp_dev
*
dev
,
struct
pnp_resource_table
*
res
)
static
int
pnpbios_get_resources
(
struct
pnp_dev
*
dev
)
{
u8
nodenum
=
dev
->
number
;
struct
pnp_bios_node
*
node
;
...
...
@@ -212,6 +211,7 @@ static int pnpbios_get_resources(struct pnp_dev *dev,
if
(
!
pnpbios_is_dynamic
(
dev
))
return
-
EPERM
;
dev_dbg
(
&
dev
->
dev
,
"get resources
\n
"
);
node
=
kzalloc
(
node_info
.
max_node_size
,
GFP_KERNEL
);
if
(
!
node
)
return
-
1
;
...
...
@@ -219,14 +219,13 @@ static int pnpbios_get_resources(struct pnp_dev *dev,
kfree
(
node
);
return
-
ENODEV
;
}
pnpbios_read_resources_from_node
(
res
,
node
);
pnpbios_read_resources_from_node
(
dev
,
node
);
dev
->
active
=
pnp_is_active
(
dev
);
kfree
(
node
);
return
0
;
}
static
int
pnpbios_set_resources
(
struct
pnp_dev
*
dev
,
struct
pnp_resource_table
*
res
)
static
int
pnpbios_set_resources
(
struct
pnp_dev
*
dev
)
{
u8
nodenum
=
dev
->
number
;
struct
pnp_bios_node
*
node
;
...
...
@@ -235,6 +234,7 @@ static int pnpbios_set_resources(struct pnp_dev *dev,
if
(
!
pnpbios_is_dynamic
(
dev
))
return
-
EPERM
;
dev_dbg
(
&
dev
->
dev
,
"set resources
\n
"
);
node
=
kzalloc
(
node_info
.
max_node_size
,
GFP_KERNEL
);
if
(
!
node
)
return
-
1
;
...
...
@@ -242,7 +242,7 @@ static int pnpbios_set_resources(struct pnp_dev *dev,
kfree
(
node
);
return
-
ENODEV
;
}
if
(
pnpbios_write_resources_to_node
(
res
,
node
)
<
0
)
{
if
(
pnpbios_write_resources_to_node
(
dev
,
node
)
<
0
)
{
kfree
(
node
);
return
-
1
;
}
...
...
@@ -317,7 +317,6 @@ static int __init insert_device(struct pnp_bios_node *node)
{
struct
list_head
*
pos
;
struct
pnp_dev
*
dev
;
struct
pnp_id
*
dev_id
;
char
id
[
8
];
/* check if the device is already added */
...
...
@@ -327,20 +326,11 @@ static int __init insert_device(struct pnp_bios_node *node)
return
-
1
;
}
dev
=
kzalloc
(
sizeof
(
struct
pnp_dev
),
GFP_KERNEL
);
pnp_eisa_id_to_string
(
node
->
eisa_id
&
PNP_EISA_ID_MASK
,
id
);
dev
=
pnp_alloc_dev
(
&
pnpbios_protocol
,
node
->
handle
,
id
);
if
(
!
dev
)
return
-
1
;
dev_id
=
kzalloc
(
sizeof
(
struct
pnp_id
),
GFP_KERNEL
);
if
(
!
dev_id
)
{
kfree
(
dev
);
return
-
1
;
}
dev
->
number
=
node
->
handle
;
pnpid32_to_pnpid
(
node
->
eisa_id
,
id
);
memcpy
(
dev_id
->
id
,
id
,
7
);
pnp_add_id
(
dev_id
,
dev
);
pnpbios_parse_data_stream
(
dev
,
node
);
dev
->
active
=
pnp_is_active
(
dev
);
dev
->
flags
=
node
->
flags
;
...
...
@@ -353,11 +343,10 @@ static int __init insert_device(struct pnp_bios_node *node)
dev
->
capabilities
|=
PNP_WRITE
;
if
(
dev
->
flags
&
PNPBIOS_REMOVABLE
)
dev
->
capabilities
|=
PNP_REMOVABLE
;
dev
->
protocol
=
&
pnpbios_protocol
;
/* clear out the damaged flags */
if
(
!
dev
->
active
)
pnp_init_resource
_table
(
&
dev
->
res
);
pnp_init_resource
s
(
dev
);
pnp_add_device
(
dev
);
pnpbios_interface_attach_device
(
node
);
...
...
drivers/pnp/pnpbios/pnpbios.h
浏览文件 @
008238b5
...
...
@@ -2,6 +2,142 @@
* pnpbios.h - contains local definitions
*/
/*
* Include file for the interface to a PnP BIOS
*
* Original BIOS code (C) 1998 Christian Schmidt (chr.schmidt@tu-bs.de)
* PnP handler parts (c) 1998 Tom Lees <tom@lpsg.demon.co.uk>
* Minor reorganizations by David Hinds <dahinds@users.sourceforge.net>
*
* 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, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Return codes
*/
#define PNP_SUCCESS 0x00
#define PNP_NOT_SET_STATICALLY 0x7f
#define PNP_UNKNOWN_FUNCTION 0x81
#define PNP_FUNCTION_NOT_SUPPORTED 0x82
#define PNP_INVALID_HANDLE 0x83
#define PNP_BAD_PARAMETER 0x84
#define PNP_SET_FAILED 0x85
#define PNP_EVENTS_NOT_PENDING 0x86
#define PNP_SYSTEM_NOT_DOCKED 0x87
#define PNP_NO_ISA_PNP_CARDS 0x88
#define PNP_UNABLE_TO_DETERMINE_DOCK_CAPABILITIES 0x89
#define PNP_CONFIG_CHANGE_FAILED_NO_BATTERY 0x8a
#define PNP_CONFIG_CHANGE_FAILED_RESOURCE_CONFLICT 0x8b
#define PNP_BUFFER_TOO_SMALL 0x8c
#define PNP_USE_ESCD_SUPPORT 0x8d
#define PNP_MESSAGE_NOT_SUPPORTED 0x8e
#define PNP_HARDWARE_ERROR 0x8f
#define ESCD_SUCCESS 0x00
#define ESCD_IO_ERROR_READING 0x55
#define ESCD_INVALID 0x56
#define ESCD_BUFFER_TOO_SMALL 0x59
#define ESCD_NVRAM_TOO_SMALL 0x5a
#define ESCD_FUNCTION_NOT_SUPPORTED 0x81
/*
* Events that can be received by "get event"
*/
#define PNPEV_ABOUT_TO_CHANGE_CONFIG 0x0001
#define PNPEV_DOCK_CHANGED 0x0002
#define PNPEV_SYSTEM_DEVICE_CHANGED 0x0003
#define PNPEV_CONFIG_CHANGED_FAILED 0x0004
#define PNPEV_UNKNOWN_SYSTEM_EVENT 0xffff
/* 0x8000 through 0xfffe are OEM defined */
/*
* Messages that should be sent through "send message"
*/
#define PNPMSG_OK 0x00
#define PNPMSG_ABORT 0x01
#define PNPMSG_UNDOCK_DEFAULT_ACTION 0x40
#define PNPMSG_POWER_OFF 0x41
#define PNPMSG_PNP_OS_ACTIVE 0x42
#define PNPMSG_PNP_OS_INACTIVE 0x43
/*
* Plug and Play BIOS flags
*/
#define PNPBIOS_NO_DISABLE 0x0001
#define PNPBIOS_NO_CONFIG 0x0002
#define PNPBIOS_OUTPUT 0x0004
#define PNPBIOS_INPUT 0x0008
#define PNPBIOS_BOOTABLE 0x0010
#define PNPBIOS_DOCK 0x0020
#define PNPBIOS_REMOVABLE 0x0040
#define pnpbios_is_static(x) (((x)->flags & 0x0100) == 0x0000)
#define pnpbios_is_dynamic(x) ((x)->flags & 0x0080)
/*
* Function Parameters
*/
#define PNPMODE_STATIC 1
#define PNPMODE_DYNAMIC 0
/* 0x8000 through 0xffff are OEM defined */
#pragma pack(1)
struct
pnp_dev_node_info
{
__u16
no_nodes
;
__u16
max_node_size
;
};
struct
pnp_docking_station_info
{
__u32
location_id
;
__u32
serial
;
__u16
capabilities
;
};
struct
pnp_isa_config_struc
{
__u8
revision
;
__u8
no_csns
;
__u16
isa_rd_data_port
;
__u16
reserved
;
};
struct
escd_info_struc
{
__u16
min_escd_write_size
;
__u16
escd_size
;
__u32
nv_storage_base
;
};
struct
pnp_bios_node
{
__u16
size
;
__u8
handle
;
__u32
eisa_id
;
__u8
type_code
[
3
];
__u16
flags
;
__u8
data
[
0
];
};
#pragma pack()
/* non-exported */
extern
struct
pnp_dev_node_info
node_info
;
extern
int
pnp_bios_dev_node_info
(
struct
pnp_dev_node_info
*
data
);
extern
int
pnp_bios_get_dev_node
(
u8
*
nodenum
,
char
config
,
struct
pnp_bios_node
*
data
);
extern
int
pnp_bios_set_dev_node
(
u8
nodenum
,
char
config
,
struct
pnp_bios_node
*
data
);
extern
int
pnp_bios_get_stat_res
(
char
*
info
);
extern
int
pnp_bios_isapnp_config
(
struct
pnp_isa_config_struc
*
data
);
extern
int
pnp_bios_escd_info
(
struct
escd_info_struc
*
data
);
extern
int
pnp_bios_read_escd
(
char
*
data
,
u32
nvram_base
);
extern
int
pnp_bios_dock_station_info
(
struct
pnp_docking_station_info
*
data
);
#pragma pack(1)
union
pnp_bios_install_struct
{
struct
{
...
...
@@ -28,8 +164,8 @@ extern int pnp_bios_present(void);
extern
int
pnpbios_dont_use_current_config
;
extern
int
pnpbios_parse_data_stream
(
struct
pnp_dev
*
dev
,
struct
pnp_bios_node
*
node
);
extern
int
pnpbios_read_resources_from_node
(
struct
pnp_
resource_table
*
res
,
struct
pnp_bios_node
*
node
);
extern
int
pnpbios_write_resources_to_node
(
struct
pnp_
resource_table
*
res
,
struct
pnp_bios_node
*
node
);
extern
int
pnpbios_read_resources_from_node
(
struct
pnp_
dev
*
dev
,
struct
pnp_bios_node
*
node
);
extern
int
pnpbios_write_resources_to_node
(
struct
pnp_
dev
*
dev
,
struct
pnp_bios_node
*
node
);
extern
void
pnpid32_to_pnpid
(
u32
id
,
char
*
str
);
extern
void
pnpbios_print_status
(
const
char
*
module
,
u16
status
);
...
...
drivers/pnp/pnpbios/proc.c
浏览文件 @
008238b5
...
...
@@ -23,7 +23,7 @@
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
#include <linux/pnp
bios
.h>
#include <linux/pnp.h>
#include <linux/init.h>
#include <asm/uaccess.h>
...
...
drivers/pnp/pnpbios/rsparser.c
浏览文件 @
008238b5
此差异已折叠。
点击以展开。
drivers/pnp/quirks.c
浏览文件 @
008238b5
...
...
@@ -117,6 +117,7 @@ static void quirk_sb16audio_resources(struct pnp_dev *dev)
static
void
quirk_system_pci_resources
(
struct
pnp_dev
*
dev
)
{
struct
pci_dev
*
pdev
=
NULL
;
struct
resource
*
res
;
resource_size_t
pnp_start
,
pnp_end
,
pci_start
,
pci_end
;
int
i
,
j
;
...
...
@@ -137,13 +138,15 @@ static void quirk_system_pci_resources(struct pnp_dev *dev)
pci_start
=
pci_resource_start
(
pdev
,
i
);
pci_end
=
pci_resource_end
(
pdev
,
i
);
for
(
j
=
0
;
j
<
PNP_MAX_MEM
;
j
++
)
{
if
(
!
pnp_mem_valid
(
dev
,
j
)
||
pnp_mem_len
(
dev
,
j
)
==
0
)
for
(
j
=
0
;
(
res
=
pnp_get_resource
(
dev
,
IORESOURCE_MEM
,
j
));
j
++
)
{
if
(
res
->
flags
&
IORESOURCE_UNSET
||
(
res
->
start
==
0
&&
res
->
end
==
0
))
continue
;
pnp_start
=
pnp_mem_start
(
dev
,
j
)
;
pnp_end
=
pnp_mem_end
(
dev
,
j
)
;
pnp_start
=
res
->
start
;
pnp_end
=
res
->
end
;
/*
* If the PNP region doesn't overlap the PCI
...
...
@@ -176,7 +179,7 @@ static void quirk_system_pci_resources(struct pnp_dev *dev)
pci_name
(
pdev
),
i
,
(
unsigned
long
long
)
pci_start
,
(
unsigned
long
long
)
pci_end
);
pnp_mem_flags
(
dev
,
j
)
=
0
;
res
->
flags
=
0
;
}
}
}
...
...
drivers/pnp/resource.c
浏览文件 @
008238b5
...
...
@@ -53,6 +53,8 @@ struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev)
if
(
dev
->
independent
)
dev_err
(
&
dev
->
dev
,
"independent resource already registered
\n
"
);
dev
->
independent
=
option
;
dev_dbg
(
&
dev
->
dev
,
"new independent option
\n
"
);
return
option
;
}
...
...
@@ -70,12 +72,18 @@ struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev,
parent
->
next
=
option
;
}
else
dev
->
dependent
=
option
;
dev_dbg
(
&
dev
->
dev
,
"new dependent option (priority %#x)
\n
"
,
priority
);
return
option
;
}
int
pnp_register_irq_resource
(
struct
pnp_option
*
option
,
struct
pnp_irq
*
data
)
int
pnp_register_irq_resource
(
struct
pnp_dev
*
dev
,
struct
pnp_option
*
option
,
struct
pnp_irq
*
data
)
{
struct
pnp_irq
*
ptr
;
#ifdef DEBUG
char
buf
[
PNP_IRQ_NR
];
/* hex-encoded, so this is overkill but safe */
#endif
ptr
=
option
->
irq
;
while
(
ptr
&&
ptr
->
next
)
...
...
@@ -94,10 +102,17 @@ int pnp_register_irq_resource(struct pnp_option *option, struct pnp_irq *data)
pcibios_penalize_isa_irq
(
i
,
0
);
}
#endif
#ifdef DEBUG
bitmap_scnprintf
(
buf
,
sizeof
(
buf
),
data
->
map
,
PNP_IRQ_NR
);
dev_dbg
(
&
dev
->
dev
,
" irq bitmask %s flags %#x
\n
"
,
buf
,
data
->
flags
);
#endif
return
0
;
}
int
pnp_register_dma_resource
(
struct
pnp_option
*
option
,
struct
pnp_dma
*
data
)
int
pnp_register_dma_resource
(
struct
pnp_dev
*
dev
,
struct
pnp_option
*
option
,
struct
pnp_dma
*
data
)
{
struct
pnp_dma
*
ptr
;
...
...
@@ -109,10 +124,13 @@ int pnp_register_dma_resource(struct pnp_option *option, struct pnp_dma *data)
else
option
->
dma
=
data
;
dev_dbg
(
&
dev
->
dev
,
" dma bitmask %#x flags %#x
\n
"
,
data
->
map
,
data
->
flags
);
return
0
;
}
int
pnp_register_port_resource
(
struct
pnp_option
*
option
,
struct
pnp_port
*
data
)
int
pnp_register_port_resource
(
struct
pnp_dev
*
dev
,
struct
pnp_option
*
option
,
struct
pnp_port
*
data
)
{
struct
pnp_port
*
ptr
;
...
...
@@ -124,10 +142,14 @@ int pnp_register_port_resource(struct pnp_option *option, struct pnp_port *data)
else
option
->
port
=
data
;
dev_dbg
(
&
dev
->
dev
,
" io "
"min %#x max %#x align %d size %d flags %#x
\n
"
,
data
->
min
,
data
->
max
,
data
->
align
,
data
->
size
,
data
->
flags
);
return
0
;
}
int
pnp_register_mem_resource
(
struct
pnp_option
*
option
,
struct
pnp_mem
*
data
)
int
pnp_register_mem_resource
(
struct
pnp_dev
*
dev
,
struct
pnp_option
*
option
,
struct
pnp_mem
*
data
)
{
struct
pnp_mem
*
ptr
;
...
...
@@ -138,6 +160,10 @@ int pnp_register_mem_resource(struct pnp_option *option, struct pnp_mem *data)
ptr
->
next
=
data
;
else
option
->
mem
=
data
;
dev_dbg
(
&
dev
->
dev
,
" mem "
"min %#x max %#x align %d size %d flags %#x
\n
"
,
data
->
min
,
data
->
max
,
data
->
align
,
data
->
size
,
data
->
flags
);
return
0
;
}
...
...
@@ -213,17 +239,18 @@ void pnp_free_option(struct pnp_option *option)
#define cannot_compare(flags) \
((flags) & (IORESOURCE_UNSET | IORESOURCE_DISABLED))
int
pnp_check_port
(
struct
pnp_dev
*
dev
,
int
idx
)
int
pnp_check_port
(
struct
pnp_dev
*
dev
,
struct
resource
*
res
)
{
int
tmp
;
int
i
;
struct
pnp_dev
*
tdev
;
struct
resource
*
tres
;
resource_size_t
*
port
,
*
end
,
*
tport
,
*
tend
;
port
=
&
dev
->
res
.
port_resource
[
idx
].
start
;
end
=
&
dev
->
res
.
port_resource
[
idx
].
end
;
port
=
&
res
->
start
;
end
=
&
res
->
end
;
/* if the resource doesn't exist, don't complain about it */
if
(
cannot_compare
(
dev
->
res
.
port_resource
[
idx
].
flags
))
if
(
cannot_compare
(
res
->
flags
))
return
1
;
/* check if the resource is already in use, skip if the
...
...
@@ -234,18 +261,18 @@ int pnp_check_port(struct pnp_dev *dev, int idx)
}
/* check if the resource is reserved */
for
(
tmp
=
0
;
tmp
<
8
;
tmp
++
)
{
int
rport
=
pnp_reserve_io
[
tmp
<<
1
];
int
rend
=
pnp_reserve_io
[(
tmp
<<
1
)
+
1
]
+
rport
-
1
;
for
(
i
=
0
;
i
<
8
;
i
++
)
{
int
rport
=
pnp_reserve_io
[
i
<<
1
];
int
rend
=
pnp_reserve_io
[(
i
<<
1
)
+
1
]
+
rport
-
1
;
if
(
ranged_conflict
(
port
,
end
,
&
rport
,
&
rend
))
return
0
;
}
/* check for internal conflicts */
for
(
tmp
=
0
;
tmp
<
PNP_MAX_PORT
&&
tmp
!=
idx
;
tmp
++
)
{
if
(
dev
->
res
.
port_resource
[
tmp
].
flags
&
IORESOURCE_IO
)
{
tport
=
&
dev
->
res
.
port_resource
[
tmp
].
start
;
tend
=
&
dev
->
res
.
port_resource
[
tmp
].
end
;
for
(
i
=
0
;
(
tres
=
pnp_get_resource
(
dev
,
IORESOURCE_IO
,
i
));
i
++
)
{
if
(
tres
!=
res
&&
tres
->
flags
&
IORESOURCE_IO
)
{
tport
=
&
tres
->
start
;
tend
=
&
tres
->
end
;
if
(
ranged_conflict
(
port
,
end
,
tport
,
tend
))
return
0
;
}
...
...
@@ -255,13 +282,14 @@ int pnp_check_port(struct pnp_dev *dev, int idx)
pnp_for_each_dev
(
tdev
)
{
if
(
tdev
==
dev
)
continue
;
for
(
tmp
=
0
;
tmp
<
PNP_MAX_PORT
;
tmp
++
)
{
if
(
tdev
->
res
.
port_resource
[
tmp
].
flags
&
IORESOURCE_IO
)
{
if
(
cannot_compare
(
tdev
->
res
.
port_resource
[
tmp
].
flags
))
for
(
i
=
0
;
(
tres
=
pnp_get_resource
(
tdev
,
IORESOURCE_IO
,
i
));
i
++
)
{
if
(
tres
->
flags
&
IORESOURCE_IO
)
{
if
(
cannot_compare
(
tres
->
flags
))
continue
;
tport
=
&
t
dev
->
res
.
port_resource
[
tmp
].
start
;
tend
=
&
t
dev
->
res
.
port_resource
[
tmp
].
end
;
tport
=
&
t
res
->
start
;
tend
=
&
t
res
->
end
;
if
(
ranged_conflict
(
port
,
end
,
tport
,
tend
))
return
0
;
}
...
...
@@ -271,17 +299,18 @@ int pnp_check_port(struct pnp_dev *dev, int idx)
return
1
;
}
int
pnp_check_mem
(
struct
pnp_dev
*
dev
,
int
idx
)
int
pnp_check_mem
(
struct
pnp_dev
*
dev
,
struct
resource
*
res
)
{
int
tmp
;
int
i
;
struct
pnp_dev
*
tdev
;
struct
resource
*
tres
;
resource_size_t
*
addr
,
*
end
,
*
taddr
,
*
tend
;
addr
=
&
dev
->
res
.
mem_resource
[
idx
].
start
;
end
=
&
dev
->
res
.
mem_resource
[
idx
].
end
;
addr
=
&
res
->
start
;
end
=
&
res
->
end
;
/* if the resource doesn't exist, don't complain about it */
if
(
cannot_compare
(
dev
->
res
.
mem_resource
[
idx
].
flags
))
if
(
cannot_compare
(
res
->
flags
))
return
1
;
/* check if the resource is already in use, skip if the
...
...
@@ -292,18 +321,18 @@ int pnp_check_mem(struct pnp_dev *dev, int idx)
}
/* check if the resource is reserved */
for
(
tmp
=
0
;
tmp
<
8
;
tmp
++
)
{
int
raddr
=
pnp_reserve_mem
[
tmp
<<
1
];
int
rend
=
pnp_reserve_mem
[(
tmp
<<
1
)
+
1
]
+
raddr
-
1
;
for
(
i
=
0
;
i
<
8
;
i
++
)
{
int
raddr
=
pnp_reserve_mem
[
i
<<
1
];
int
rend
=
pnp_reserve_mem
[(
i
<<
1
)
+
1
]
+
raddr
-
1
;
if
(
ranged_conflict
(
addr
,
end
,
&
raddr
,
&
rend
))
return
0
;
}
/* check for internal conflicts */
for
(
tmp
=
0
;
tmp
<
PNP_MAX_MEM
&&
tmp
!=
idx
;
tmp
++
)
{
if
(
dev
->
res
.
mem_resource
[
tmp
].
flags
&
IORESOURCE_MEM
)
{
taddr
=
&
dev
->
res
.
mem_resource
[
tmp
].
start
;
tend
=
&
dev
->
res
.
mem_resource
[
tmp
].
end
;
for
(
i
=
0
;
(
tres
=
pnp_get_resource
(
dev
,
IORESOURCE_MEM
,
i
));
i
++
)
{
if
(
tres
!=
res
&&
tres
->
flags
&
IORESOURCE_MEM
)
{
taddr
=
&
tres
->
start
;
tend
=
&
tres
->
end
;
if
(
ranged_conflict
(
addr
,
end
,
taddr
,
tend
))
return
0
;
}
...
...
@@ -313,13 +342,14 @@ int pnp_check_mem(struct pnp_dev *dev, int idx)
pnp_for_each_dev
(
tdev
)
{
if
(
tdev
==
dev
)
continue
;
for
(
tmp
=
0
;
tmp
<
PNP_MAX_MEM
;
tmp
++
)
{
if
(
tdev
->
res
.
mem_resource
[
tmp
].
flags
&
IORESOURCE_MEM
)
{
if
(
cannot_compare
(
tdev
->
res
.
mem_resource
[
tmp
].
flags
))
for
(
i
=
0
;
(
tres
=
pnp_get_resource
(
tdev
,
IORESOURCE_MEM
,
i
));
i
++
)
{
if
(
tres
->
flags
&
IORESOURCE_MEM
)
{
if
(
cannot_compare
(
tres
->
flags
))
continue
;
taddr
=
&
t
dev
->
res
.
mem_resource
[
tmp
].
start
;
tend
=
&
t
dev
->
res
.
mem_resource
[
tmp
].
end
;
taddr
=
&
t
res
->
start
;
tend
=
&
t
res
->
end
;
if
(
ranged_conflict
(
addr
,
end
,
taddr
,
tend
))
return
0
;
}
...
...
@@ -334,14 +364,17 @@ static irqreturn_t pnp_test_handler(int irq, void *dev_id)
return
IRQ_HANDLED
;
}
int
pnp_check_irq
(
struct
pnp_dev
*
dev
,
int
idx
)
int
pnp_check_irq
(
struct
pnp_dev
*
dev
,
struct
resource
*
res
)
{
int
tmp
;
int
i
;
struct
pnp_dev
*
tdev
;
resource_size_t
*
irq
=
&
dev
->
res
.
irq_resource
[
idx
].
start
;
struct
resource
*
tres
;
resource_size_t
*
irq
;
irq
=
&
res
->
start
;
/* if the resource doesn't exist, don't complain about it */
if
(
cannot_compare
(
dev
->
res
.
irq_resource
[
idx
].
flags
))
if
(
cannot_compare
(
res
->
flags
))
return
1
;
/* check if the resource is valid */
...
...
@@ -349,15 +382,15 @@ int pnp_check_irq(struct pnp_dev *dev, int idx)
return
0
;
/* check if the resource is reserved */
for
(
tmp
=
0
;
tmp
<
16
;
tmp
++
)
{
if
(
pnp_reserve_irq
[
tmp
]
==
*
irq
)
for
(
i
=
0
;
i
<
16
;
i
++
)
{
if
(
pnp_reserve_irq
[
i
]
==
*
irq
)
return
0
;
}
/* check for internal conflicts */
for
(
tmp
=
0
;
tmp
<
PNP_MAX_IRQ
&&
tmp
!=
idx
;
tmp
++
)
{
if
(
dev
->
res
.
irq_resource
[
tmp
].
flags
&
IORESOURCE_IRQ
)
{
if
(
dev
->
res
.
irq_resource
[
tmp
].
start
==
*
irq
)
for
(
i
=
0
;
(
tres
=
pnp_get_resource
(
dev
,
IORESOURCE_IRQ
,
i
));
i
++
)
{
if
(
tres
!=
res
&&
tres
->
flags
&
IORESOURCE_IRQ
)
{
if
(
tres
->
start
==
*
irq
)
return
0
;
}
}
...
...
@@ -388,12 +421,13 @@ int pnp_check_irq(struct pnp_dev *dev, int idx)
pnp_for_each_dev
(
tdev
)
{
if
(
tdev
==
dev
)
continue
;
for
(
tmp
=
0
;
tmp
<
PNP_MAX_IRQ
;
tmp
++
)
{
if
(
tdev
->
res
.
irq_resource
[
tmp
].
flags
&
IORESOURCE_IRQ
)
{
if
(
cannot_compare
(
tdev
->
res
.
irq_resource
[
tmp
].
flags
))
for
(
i
=
0
;
(
tres
=
pnp_get_resource
(
tdev
,
IORESOURCE_IRQ
,
i
));
i
++
)
{
if
(
tres
->
flags
&
IORESOURCE_IRQ
)
{
if
(
cannot_compare
(
tres
->
flags
))
continue
;
if
(
(
tdev
->
res
.
irq_resource
[
tmp
].
start
==
*
irq
)
)
if
(
tres
->
start
==
*
irq
)
return
0
;
}
}
...
...
@@ -402,15 +436,18 @@ int pnp_check_irq(struct pnp_dev *dev, int idx)
return
1
;
}
int
pnp_check_dma
(
struct
pnp_dev
*
dev
,
int
idx
)
int
pnp_check_dma
(
struct
pnp_dev
*
dev
,
struct
resource
*
res
)
{
#ifndef CONFIG_IA64
int
tmp
;
int
i
;
struct
pnp_dev
*
tdev
;
resource_size_t
*
dma
=
&
dev
->
res
.
dma_resource
[
idx
].
start
;
struct
resource
*
tres
;
resource_size_t
*
dma
;
dma
=
&
res
->
start
;
/* if the resource doesn't exist, don't complain about it */
if
(
cannot_compare
(
dev
->
res
.
dma_resource
[
idx
].
flags
))
if
(
cannot_compare
(
res
->
flags
))
return
1
;
/* check if the resource is valid */
...
...
@@ -418,15 +455,15 @@ int pnp_check_dma(struct pnp_dev *dev, int idx)
return
0
;
/* check if the resource is reserved */
for
(
tmp
=
0
;
tmp
<
8
;
tmp
++
)
{
if
(
pnp_reserve_dma
[
tmp
]
==
*
dma
)
for
(
i
=
0
;
i
<
8
;
i
++
)
{
if
(
pnp_reserve_dma
[
i
]
==
*
dma
)
return
0
;
}
/* check for internal conflicts */
for
(
tmp
=
0
;
tmp
<
PNP_MAX_DMA
&&
tmp
!=
idx
;
tmp
++
)
{
if
(
dev
->
res
.
dma_resource
[
tmp
].
flags
&
IORESOURCE_DMA
)
{
if
(
dev
->
res
.
dma_resource
[
tmp
].
start
==
*
dma
)
for
(
i
=
0
;
(
tres
=
pnp_get_resource
(
dev
,
IORESOURCE_DMA
,
i
));
i
++
)
{
if
(
tres
!=
res
&&
tres
->
flags
&
IORESOURCE_DMA
)
{
if
(
tres
->
start
==
*
dma
)
return
0
;
}
}
...
...
@@ -443,12 +480,13 @@ int pnp_check_dma(struct pnp_dev *dev, int idx)
pnp_for_each_dev
(
tdev
)
{
if
(
tdev
==
dev
)
continue
;
for
(
tmp
=
0
;
tmp
<
PNP_MAX_DMA
;
tmp
++
)
{
if
(
tdev
->
res
.
dma_resource
[
tmp
].
flags
&
IORESOURCE_DMA
)
{
if
(
cannot_compare
(
tdev
->
res
.
dma_resource
[
tmp
].
flags
))
for
(
i
=
0
;
(
tres
=
pnp_get_resource
(
tdev
,
IORESOURCE_DMA
,
i
));
i
++
)
{
if
(
tres
->
flags
&
IORESOURCE_DMA
)
{
if
(
cannot_compare
(
tres
->
flags
))
continue
;
if
(
(
tdev
->
res
.
dma_resource
[
tmp
].
start
==
*
dma
)
)
if
(
tres
->
start
==
*
dma
)
return
0
;
}
}
...
...
@@ -461,6 +499,193 @@ int pnp_check_dma(struct pnp_dev *dev, int idx)
#endif
}
struct
pnp_resource
*
pnp_get_pnp_resource
(
struct
pnp_dev
*
dev
,
unsigned
int
type
,
unsigned
int
num
)
{
struct
pnp_resource_table
*
res
=
dev
->
res
;
switch
(
type
)
{
case
IORESOURCE_IO
:
if
(
num
>=
PNP_MAX_PORT
)
return
NULL
;
return
&
res
->
port
[
num
];
case
IORESOURCE_MEM
:
if
(
num
>=
PNP_MAX_MEM
)
return
NULL
;
return
&
res
->
mem
[
num
];
case
IORESOURCE_IRQ
:
if
(
num
>=
PNP_MAX_IRQ
)
return
NULL
;
return
&
res
->
irq
[
num
];
case
IORESOURCE_DMA
:
if
(
num
>=
PNP_MAX_DMA
)
return
NULL
;
return
&
res
->
dma
[
num
];
}
return
NULL
;
}
struct
resource
*
pnp_get_resource
(
struct
pnp_dev
*
dev
,
unsigned
int
type
,
unsigned
int
num
)
{
struct
pnp_resource
*
pnp_res
;
pnp_res
=
pnp_get_pnp_resource
(
dev
,
type
,
num
);
if
(
pnp_res
)
return
&
pnp_res
->
res
;
return
NULL
;
}
EXPORT_SYMBOL
(
pnp_get_resource
);
static
struct
pnp_resource
*
pnp_new_resource
(
struct
pnp_dev
*
dev
,
int
type
)
{
struct
pnp_resource
*
pnp_res
;
int
i
;
switch
(
type
)
{
case
IORESOURCE_IO
:
for
(
i
=
0
;
i
<
PNP_MAX_PORT
;
i
++
)
{
pnp_res
=
pnp_get_pnp_resource
(
dev
,
IORESOURCE_IO
,
i
);
if
(
pnp_res
&&
!
pnp_resource_valid
(
&
pnp_res
->
res
))
return
pnp_res
;
}
break
;
case
IORESOURCE_MEM
:
for
(
i
=
0
;
i
<
PNP_MAX_MEM
;
i
++
)
{
pnp_res
=
pnp_get_pnp_resource
(
dev
,
IORESOURCE_MEM
,
i
);
if
(
pnp_res
&&
!
pnp_resource_valid
(
&
pnp_res
->
res
))
return
pnp_res
;
}
break
;
case
IORESOURCE_IRQ
:
for
(
i
=
0
;
i
<
PNP_MAX_IRQ
;
i
++
)
{
pnp_res
=
pnp_get_pnp_resource
(
dev
,
IORESOURCE_IRQ
,
i
);
if
(
pnp_res
&&
!
pnp_resource_valid
(
&
pnp_res
->
res
))
return
pnp_res
;
}
break
;
case
IORESOURCE_DMA
:
for
(
i
=
0
;
i
<
PNP_MAX_DMA
;
i
++
)
{
pnp_res
=
pnp_get_pnp_resource
(
dev
,
IORESOURCE_DMA
,
i
);
if
(
pnp_res
&&
!
pnp_resource_valid
(
&
pnp_res
->
res
))
return
pnp_res
;
}
break
;
}
return
NULL
;
}
struct
pnp_resource
*
pnp_add_irq_resource
(
struct
pnp_dev
*
dev
,
int
irq
,
int
flags
)
{
struct
pnp_resource
*
pnp_res
;
struct
resource
*
res
;
static
unsigned
char
warned
;
pnp_res
=
pnp_new_resource
(
dev
,
IORESOURCE_IRQ
);
if
(
!
pnp_res
)
{
if
(
!
warned
)
{
dev_err
(
&
dev
->
dev
,
"can't add resource for IRQ %d
\n
"
,
irq
);
warned
=
1
;
}
return
NULL
;
}
res
=
&
pnp_res
->
res
;
res
->
flags
=
IORESOURCE_IRQ
|
flags
;
res
->
start
=
irq
;
res
->
end
=
irq
;
dev_dbg
(
&
dev
->
dev
,
" add irq %d flags %#x
\n
"
,
irq
,
flags
);
return
pnp_res
;
}
struct
pnp_resource
*
pnp_add_dma_resource
(
struct
pnp_dev
*
dev
,
int
dma
,
int
flags
)
{
struct
pnp_resource
*
pnp_res
;
struct
resource
*
res
;
static
unsigned
char
warned
;
pnp_res
=
pnp_new_resource
(
dev
,
IORESOURCE_DMA
);
if
(
!
pnp_res
)
{
if
(
!
warned
)
{
dev_err
(
&
dev
->
dev
,
"can't add resource for DMA %d
\n
"
,
dma
);
warned
=
1
;
}
return
NULL
;
}
res
=
&
pnp_res
->
res
;
res
->
flags
=
IORESOURCE_DMA
|
flags
;
res
->
start
=
dma
;
res
->
end
=
dma
;
dev_dbg
(
&
dev
->
dev
,
" add dma %d flags %#x
\n
"
,
dma
,
flags
);
return
pnp_res
;
}
struct
pnp_resource
*
pnp_add_io_resource
(
struct
pnp_dev
*
dev
,
resource_size_t
start
,
resource_size_t
end
,
int
flags
)
{
struct
pnp_resource
*
pnp_res
;
struct
resource
*
res
;
static
unsigned
char
warned
;
pnp_res
=
pnp_new_resource
(
dev
,
IORESOURCE_IO
);
if
(
!
pnp_res
)
{
if
(
!
warned
)
{
dev_err
(
&
dev
->
dev
,
"can't add resource for IO "
"%#llx-%#llx
\n
"
,(
unsigned
long
long
)
start
,
(
unsigned
long
long
)
end
);
warned
=
1
;
}
return
NULL
;
}
res
=
&
pnp_res
->
res
;
res
->
flags
=
IORESOURCE_IO
|
flags
;
res
->
start
=
start
;
res
->
end
=
end
;
dev_dbg
(
&
dev
->
dev
,
" add io %#llx-%#llx flags %#x
\n
"
,
(
unsigned
long
long
)
start
,
(
unsigned
long
long
)
end
,
flags
);
return
pnp_res
;
}
struct
pnp_resource
*
pnp_add_mem_resource
(
struct
pnp_dev
*
dev
,
resource_size_t
start
,
resource_size_t
end
,
int
flags
)
{
struct
pnp_resource
*
pnp_res
;
struct
resource
*
res
;
static
unsigned
char
warned
;
pnp_res
=
pnp_new_resource
(
dev
,
IORESOURCE_MEM
);
if
(
!
pnp_res
)
{
if
(
!
warned
)
{
dev_err
(
&
dev
->
dev
,
"can't add resource for MEM "
"%#llx-%#llx
\n
"
,(
unsigned
long
long
)
start
,
(
unsigned
long
long
)
end
);
warned
=
1
;
}
return
NULL
;
}
res
=
&
pnp_res
->
res
;
res
->
flags
=
IORESOURCE_MEM
|
flags
;
res
->
start
=
start
;
res
->
end
=
end
;
dev_dbg
(
&
dev
->
dev
,
" add mem %#llx-%#llx flags %#x
\n
"
,
(
unsigned
long
long
)
start
,
(
unsigned
long
long
)
end
,
flags
);
return
pnp_res
;
}
/* format is: pnp_reserve_irq=irq1[,irq2] .... */
static
int
__init
pnp_setup_reserve_irq
(
char
*
str
)
{
...
...
drivers/pnp/support.c
浏览文件 @
008238b5
...
...
@@ -25,3 +25,66 @@ int pnp_is_active(struct pnp_dev *dev)
}
EXPORT_SYMBOL
(
pnp_is_active
);
/*
* Functionally similar to acpi_ex_eisa_id_to_string(), but that's
* buried in the ACPI CA, and we can't depend on it being present.
*/
void
pnp_eisa_id_to_string
(
u32
id
,
char
*
str
)
{
id
=
be32_to_cpu
(
id
);
/*
* According to the specs, the first three characters are five-bit
* compressed ASCII, and the left-over high order bit should be zero.
* However, the Linux ISAPNP code historically used six bits for the
* first character, and there seem to be IDs that depend on that,
* e.g., "nEC8241" in the Linux 8250_pnp serial driver and the
* FreeBSD sys/pc98/cbus/sio_cbus.c driver.
*/
str
[
0
]
=
'A'
+
((
id
>>
26
)
&
0x3f
)
-
1
;
str
[
1
]
=
'A'
+
((
id
>>
21
)
&
0x1f
)
-
1
;
str
[
2
]
=
'A'
+
((
id
>>
16
)
&
0x1f
)
-
1
;
str
[
3
]
=
hex_asc
((
id
>>
12
)
&
0xf
);
str
[
4
]
=
hex_asc
((
id
>>
8
)
&
0xf
);
str
[
5
]
=
hex_asc
((
id
>>
4
)
&
0xf
);
str
[
6
]
=
hex_asc
((
id
>>
0
)
&
0xf
);
str
[
7
]
=
'\0'
;
}
void
dbg_pnp_show_resources
(
struct
pnp_dev
*
dev
,
char
*
desc
)
{
#ifdef DEBUG
struct
resource
*
res
;
int
i
;
dev_dbg
(
&
dev
->
dev
,
"current resources: %s
\n
"
,
desc
);
for
(
i
=
0
;
i
<
PNP_MAX_IRQ
;
i
++
)
{
res
=
pnp_get_resource
(
dev
,
IORESOURCE_IRQ
,
i
);
if
(
res
&&
!
(
res
->
flags
&
IORESOURCE_UNSET
))
dev_dbg
(
&
dev
->
dev
,
" irq %lld flags %#lx
\n
"
,
(
unsigned
long
long
)
res
->
start
,
res
->
flags
);
}
for
(
i
=
0
;
i
<
PNP_MAX_DMA
;
i
++
)
{
res
=
pnp_get_resource
(
dev
,
IORESOURCE_DMA
,
i
);
if
(
res
&&
!
(
res
->
flags
&
IORESOURCE_UNSET
))
dev_dbg
(
&
dev
->
dev
,
" dma %lld flags %#lx
\n
"
,
(
unsigned
long
long
)
res
->
start
,
res
->
flags
);
}
for
(
i
=
0
;
i
<
PNP_MAX_PORT
;
i
++
)
{
res
=
pnp_get_resource
(
dev
,
IORESOURCE_IO
,
i
);
if
(
res
&&
!
(
res
->
flags
&
IORESOURCE_UNSET
))
dev_dbg
(
&
dev
->
dev
,
" io %#llx-%#llx flags %#lx
\n
"
,
(
unsigned
long
long
)
res
->
start
,
(
unsigned
long
long
)
res
->
end
,
res
->
flags
);
}
for
(
i
=
0
;
i
<
PNP_MAX_MEM
;
i
++
)
{
res
=
pnp_get_resource
(
dev
,
IORESOURCE_MEM
,
i
);
if
(
res
&&
!
(
res
->
flags
&
IORESOURCE_UNSET
))
dev_dbg
(
&
dev
->
dev
,
" mem %#llx-%#llx flags %#lx
\n
"
,
(
unsigned
long
long
)
res
->
start
,
(
unsigned
long
long
)
res
->
end
,
res
->
flags
);
}
#endif
}
drivers/pnp/system.c
浏览文件 @
008238b5
...
...
@@ -56,14 +56,15 @@ static void reserve_range(struct pnp_dev *dev, resource_size_t start,
static
void
reserve_resources_of_dev
(
struct
pnp_dev
*
dev
)
{
struct
resource
*
res
;
int
i
;
for
(
i
=
0
;
i
<
PNP_MAX_PORT
;
i
++
)
{
if
(
!
pnp_port_valid
(
dev
,
i
)
)
for
(
i
=
0
;
(
res
=
pnp_get_resource
(
dev
,
IORESOURCE_IO
,
i
))
;
i
++
)
{
if
(
res
->
flags
&
IORESOURCE_UNSET
)
continue
;
if
(
pnp_port_start
(
dev
,
i
)
==
0
)
if
(
res
->
start
==
0
)
continue
;
/* disabled */
if
(
pnp_port_start
(
dev
,
i
)
<
0x100
)
if
(
res
->
start
<
0x100
)
/*
* Below 0x100 is only standard PC hardware
* (pics, kbd, timer, dma, ...)
...
...
@@ -73,19 +74,17 @@ static void reserve_resources_of_dev(struct pnp_dev *dev)
* So, do nothing
*/
continue
;
if
(
pnp_port_end
(
dev
,
i
)
<
pnp_port_start
(
dev
,
i
)
)
if
(
res
->
end
<
res
->
start
)
continue
;
/* invalid */
reserve_range
(
dev
,
pnp_port_start
(
dev
,
i
),
pnp_port_end
(
dev
,
i
),
1
);
reserve_range
(
dev
,
res
->
start
,
res
->
end
,
1
);
}
for
(
i
=
0
;
i
<
PNP_MAX_MEM
;
i
++
)
{
if
(
!
pnp_mem_valid
(
dev
,
i
)
)
for
(
i
=
0
;
(
res
=
pnp_get_resource
(
dev
,
IORESOURCE_MEM
,
i
))
;
i
++
)
{
if
(
res
->
flags
&
IORESOURCE_UNSET
)
continue
;
reserve_range
(
dev
,
pnp_mem_start
(
dev
,
i
),
pnp_mem_end
(
dev
,
i
),
0
);
reserve_range
(
dev
,
res
->
start
,
res
->
end
,
0
);
}
}
...
...
drivers/rtc/rtc-cmos.c
浏览文件 @
008238b5
...
...
@@ -854,11 +854,12 @@ cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
* don't define the IRQ. It should always be safe to
* hardcode it in these cases
*/
return
cmos_do_probe
(
&
pnp
->
dev
,
&
pnp
->
res
.
port_resource
[
0
],
8
);
return
cmos_do_probe
(
&
pnp
->
dev
,
pnp_get_resource
(
pnp
,
IORESOURCE_IO
,
0
),
8
);
else
return
cmos_do_probe
(
&
pnp
->
dev
,
&
pnp
->
res
.
port_resource
[
0
]
,
pnp
->
res
.
irq_resource
[
0
].
start
);
pnp_get_resource
(
pnp
,
IORESOURCE_IO
,
0
)
,
pnp_irq
(
pnp
,
0
)
);
}
static
void
__exit
cmos_pnp_remove
(
struct
pnp_dev
*
pnp
)
...
...
include/linux/isapnp.h
浏览文件 @
008238b5
...
...
@@ -25,16 +25,6 @@
#include <linux/errno.h>
#include <linux/pnp.h>
/*
* Configuration registers (TODO: change by specification)
*/
#define ISAPNP_CFG_ACTIVATE 0x30
/* byte */
#define ISAPNP_CFG_MEM 0x40
/* 4 * dword */
#define ISAPNP_CFG_PORT 0x60
/* 8 * word */
#define ISAPNP_CFG_IRQ 0x70
/* 2 * word */
#define ISAPNP_CFG_DMA 0x74
/* 2 * byte */
/*
*
*/
...
...
include/linux/pnp.h
浏览文件 @
008238b5
...
...
@@ -13,59 +13,122 @@
#include <linux/errno.h>
#include <linux/mod_devicetable.h>
#define PNP_MAX_PORT 40
#define PNP_MAX_MEM 24
#define PNP_MAX_IRQ 2
#define PNP_MAX_DMA 2
#define PNP_NAME_LEN 50
struct
pnp_protocol
;
struct
pnp_dev
;
struct
pnp_resource_table
;
/*
* Resource Management
*/
struct
resource
*
pnp_get_resource
(
struct
pnp_dev
*
,
unsigned
int
,
unsigned
int
);
static
inline
int
pnp_resource_valid
(
struct
resource
*
res
)
{
if
(
res
&&
!
(
res
->
flags
&
IORESOURCE_UNSET
))
return
1
;
return
0
;
}
static
inline
resource_size_t
pnp_resource_len
(
struct
resource
*
res
)
{
if
(
res
->
start
==
0
&&
res
->
end
==
0
)
return
0
;
return
res
->
end
-
res
->
start
+
1
;
}
static
inline
resource_size_t
pnp_port_start
(
struct
pnp_dev
*
dev
,
unsigned
int
bar
)
{
return
pnp_get_resource
(
dev
,
IORESOURCE_IO
,
bar
)
->
start
;
}
static
inline
resource_size_t
pnp_port_end
(
struct
pnp_dev
*
dev
,
unsigned
int
bar
)
{
return
pnp_get_resource
(
dev
,
IORESOURCE_IO
,
bar
)
->
end
;
}
static
inline
unsigned
long
pnp_port_flags
(
struct
pnp_dev
*
dev
,
unsigned
int
bar
)
{
return
pnp_get_resource
(
dev
,
IORESOURCE_IO
,
bar
)
->
flags
;
}
static
inline
int
pnp_port_valid
(
struct
pnp_dev
*
dev
,
unsigned
int
bar
)
{
return
pnp_resource_valid
(
pnp_get_resource
(
dev
,
IORESOURCE_IO
,
bar
));
}
static
inline
resource_size_t
pnp_port_len
(
struct
pnp_dev
*
dev
,
unsigned
int
bar
)
{
return
pnp_resource_len
(
pnp_get_resource
(
dev
,
IORESOURCE_IO
,
bar
));
}
static
inline
resource_size_t
pnp_mem_start
(
struct
pnp_dev
*
dev
,
unsigned
int
bar
)
{
return
pnp_get_resource
(
dev
,
IORESOURCE_MEM
,
bar
)
->
start
;
}
static
inline
resource_size_t
pnp_mem_end
(
struct
pnp_dev
*
dev
,
unsigned
int
bar
)
{
return
pnp_get_resource
(
dev
,
IORESOURCE_MEM
,
bar
)
->
end
;
}
static
inline
unsigned
long
pnp_mem_flags
(
struct
pnp_dev
*
dev
,
unsigned
int
bar
)
{
return
pnp_get_resource
(
dev
,
IORESOURCE_MEM
,
bar
)
->
flags
;
}
static
inline
int
pnp_mem_valid
(
struct
pnp_dev
*
dev
,
unsigned
int
bar
)
{
return
pnp_resource_valid
(
pnp_get_resource
(
dev
,
IORESOURCE_MEM
,
bar
));
}
static
inline
resource_size_t
pnp_mem_len
(
struct
pnp_dev
*
dev
,
unsigned
int
bar
)
{
return
pnp_resource_len
(
pnp_get_resource
(
dev
,
IORESOURCE_MEM
,
bar
));
}
static
inline
resource_size_t
pnp_irq
(
struct
pnp_dev
*
dev
,
unsigned
int
bar
)
{
return
pnp_get_resource
(
dev
,
IORESOURCE_IRQ
,
bar
)
->
start
;
}
static
inline
unsigned
long
pnp_irq_flags
(
struct
pnp_dev
*
dev
,
unsigned
int
bar
)
{
return
pnp_get_resource
(
dev
,
IORESOURCE_IRQ
,
bar
)
->
flags
;
}
static
inline
int
pnp_irq_valid
(
struct
pnp_dev
*
dev
,
unsigned
int
bar
)
{
return
pnp_resource_valid
(
pnp_get_resource
(
dev
,
IORESOURCE_IRQ
,
bar
));
}
static
inline
resource_size_t
pnp_dma
(
struct
pnp_dev
*
dev
,
unsigned
int
bar
)
{
return
pnp_get_resource
(
dev
,
IORESOURCE_DMA
,
bar
)
->
start
;
}
static
inline
unsigned
long
pnp_dma_flags
(
struct
pnp_dev
*
dev
,
unsigned
int
bar
)
{
return
pnp_get_resource
(
dev
,
IORESOURCE_DMA
,
bar
)
->
flags
;
}
static
inline
int
pnp_dma_valid
(
struct
pnp_dev
*
dev
,
unsigned
int
bar
)
{
return
pnp_resource_valid
(
pnp_get_resource
(
dev
,
IORESOURCE_DMA
,
bar
));
}
/* Use these instead of directly reading pnp_dev to get resource information */
#define pnp_port_start(dev,bar) ((dev)->res.port_resource[(bar)].start)
#define pnp_port_end(dev,bar) ((dev)->res.port_resource[(bar)].end)
#define pnp_port_flags(dev,bar) ((dev)->res.port_resource[(bar)].flags)
#define pnp_port_valid(dev,bar) \
((pnp_port_flags((dev),(bar)) & (IORESOURCE_IO | IORESOURCE_UNSET)) \
== IORESOURCE_IO)
#define pnp_port_len(dev,bar) \
((pnp_port_start((dev),(bar)) == 0 && \
pnp_port_end((dev),(bar)) == \
pnp_port_start((dev),(bar))) ? 0 : \
\
(pnp_port_end((dev),(bar)) - \
pnp_port_start((dev),(bar)) + 1))
#define pnp_mem_start(dev,bar) ((dev)->res.mem_resource[(bar)].start)
#define pnp_mem_end(dev,bar) ((dev)->res.mem_resource[(bar)].end)
#define pnp_mem_flags(dev,bar) ((dev)->res.mem_resource[(bar)].flags)
#define pnp_mem_valid(dev,bar) \
((pnp_mem_flags((dev),(bar)) & (IORESOURCE_MEM | IORESOURCE_UNSET)) \
== IORESOURCE_MEM)
#define pnp_mem_len(dev,bar) \
((pnp_mem_start((dev),(bar)) == 0 && \
pnp_mem_end((dev),(bar)) == \
pnp_mem_start((dev),(bar))) ? 0 : \
\
(pnp_mem_end((dev),(bar)) - \
pnp_mem_start((dev),(bar)) + 1))
#define pnp_irq(dev,bar) ((dev)->res.irq_resource[(bar)].start)
#define pnp_irq_flags(dev,bar) ((dev)->res.irq_resource[(bar)].flags)
#define pnp_irq_valid(dev,bar) \
((pnp_irq_flags((dev),(bar)) & (IORESOURCE_IRQ | IORESOURCE_UNSET)) \
== IORESOURCE_IRQ)
#define pnp_dma(dev,bar) ((dev)->res.dma_resource[(bar)].start)
#define pnp_dma_flags(dev,bar) ((dev)->res.dma_resource[(bar)].flags)
#define pnp_dma_valid(dev,bar) \
((pnp_dma_flags((dev),(bar)) & (IORESOURCE_DMA | IORESOURCE_UNSET)) \
== IORESOURCE_DMA)
#define PNP_PORT_FLAG_16BITADDR (1<<0)
#define PNP_PORT_FLAG_FIXED (1<<1)
...
...
@@ -118,13 +181,6 @@ struct pnp_option {
struct
pnp_option
*
next
;
/* used to chain dependent resources */
};
struct
pnp_resource_table
{
struct
resource
port_resource
[
PNP_MAX_PORT
];
struct
resource
mem_resource
[
PNP_MAX_MEM
];
struct
resource
dma_resource
[
PNP_MAX_DMA
];
struct
resource
irq_resource
[
PNP_MAX_IRQ
];
};
/*
* Device Management
*/
...
...
@@ -194,10 +250,9 @@ struct pnp_dev {
int
capabilities
;
struct
pnp_option
*
independent
;
struct
pnp_option
*
dependent
;
struct
pnp_resource_table
res
;
struct
pnp_resource_table
*
res
;
char
name
[
PNP_NAME_LEN
];
/* contains a human-readable name */
unsigned
short
regs
;
/* ISAPnP: supported registers */
int
flags
;
/* used by protocols */
struct
proc_dir_entry
*
procent
;
/* device entry in /proc/bus/isapnp */
void
*
data
;
...
...
@@ -328,8 +383,8 @@ struct pnp_protocol {
char
*
name
;
/* resource control functions */
int
(
*
get
)
(
struct
pnp_dev
*
dev
,
struct
pnp_resource_table
*
res
);
int
(
*
set
)
(
struct
pnp_dev
*
dev
,
struct
pnp_resource_table
*
res
);
int
(
*
get
)
(
struct
pnp_dev
*
dev
);
int
(
*
set
)
(
struct
pnp_dev
*
dev
);
int
(
*
disable
)
(
struct
pnp_dev
*
dev
);
/* protocol specific suspend/resume */
...
...
@@ -358,20 +413,12 @@ extern struct bus_type pnp_bus_type;
#if defined(CONFIG_PNP)
/* device management */
int
pnp_register_protocol
(
struct
pnp_protocol
*
protocol
);
void
pnp_unregister_protocol
(
struct
pnp_protocol
*
protocol
);
int
pnp_add_device
(
struct
pnp_dev
*
dev
);
int
pnp_device_attach
(
struct
pnp_dev
*
pnp_dev
);
void
pnp_device_detach
(
struct
pnp_dev
*
pnp_dev
);
extern
struct
list_head
pnp_global
;
extern
int
pnp_platform_devices
;
/* multidevice card support */
int
pnp_add_card
(
struct
pnp_card
*
card
);
void
pnp_remove_card
(
struct
pnp_card
*
card
);
int
pnp_add_card_device
(
struct
pnp_card
*
card
,
struct
pnp_dev
*
dev
);
void
pnp_remove_card_device
(
struct
pnp_dev
*
dev
);
int
pnp_add_card_id
(
struct
pnp_id
*
id
,
struct
pnp_card
*
card
);
struct
pnp_dev
*
pnp_request_card_device
(
struct
pnp_card_link
*
clink
,
const
char
*
id
,
struct
pnp_dev
*
from
);
void
pnp_release_card_device
(
struct
pnp_dev
*
dev
);
...
...
@@ -380,77 +427,42 @@ void pnp_unregister_card_driver(struct pnp_card_driver *drv);
extern
struct
list_head
pnp_cards
;
/* resource management */
struct
pnp_option
*
pnp_register_independent_option
(
struct
pnp_dev
*
dev
);
struct
pnp_option
*
pnp_register_dependent_option
(
struct
pnp_dev
*
dev
,
int
priority
);
int
pnp_register_irq_resource
(
struct
pnp_option
*
option
,
struct
pnp_irq
*
data
);
int
pnp_register_dma_resource
(
struct
pnp_option
*
option
,
struct
pnp_dma
*
data
);
int
pnp_register_port_resource
(
struct
pnp_option
*
option
,
struct
pnp_port
*
data
);
int
pnp_register_mem_resource
(
struct
pnp_option
*
option
,
struct
pnp_mem
*
data
);
void
pnp_init_resource_table
(
struct
pnp_resource_table
*
table
);
int
pnp_manual_config_dev
(
struct
pnp_dev
*
dev
,
struct
pnp_resource_table
*
res
,
int
mode
);
int
pnp_auto_config_dev
(
struct
pnp_dev
*
dev
);
int
pnp_validate_config
(
struct
pnp_dev
*
dev
);
int
pnp_start_dev
(
struct
pnp_dev
*
dev
);
int
pnp_stop_dev
(
struct
pnp_dev
*
dev
);
int
pnp_activate_dev
(
struct
pnp_dev
*
dev
);
int
pnp_disable_dev
(
struct
pnp_dev
*
dev
);
void
pnp_resource_change
(
struct
resource
*
resource
,
resource_size_t
start
,
resource_size_t
size
);
/* protocol helpers */
int
pnp_is_active
(
struct
pnp_dev
*
dev
);
int
compare_pnp_id
(
struct
pnp_id
*
pos
,
const
char
*
id
);
int
pnp_add_id
(
struct
pnp_id
*
id
,
struct
pnp_dev
*
dev
);
int
pnp_register_driver
(
struct
pnp_driver
*
drv
);
void
pnp_unregister_driver
(
struct
pnp_driver
*
drv
);
#else
/* device management */
static
inline
int
pnp_register_protocol
(
struct
pnp_protocol
*
protocol
)
{
return
-
ENODEV
;
}
static
inline
void
pnp_unregister_protocol
(
struct
pnp_protocol
*
protocol
)
{
}
static
inline
int
pnp_init_device
(
struct
pnp_dev
*
dev
)
{
return
-
ENODEV
;
}
static
inline
int
pnp_add_device
(
struct
pnp_dev
*
dev
)
{
return
-
ENODEV
;
}
static
inline
int
pnp_device_attach
(
struct
pnp_dev
*
pnp_dev
)
{
return
-
ENODEV
;
}
static
inline
void
pnp_device_detach
(
struct
pnp_dev
*
pnp_dev
)
{
}
#define pnp_platform_devices 0
/* multidevice card support */
static
inline
int
pnp_add_card
(
struct
pnp_card
*
card
)
{
return
-
ENODEV
;
}
static
inline
void
pnp_remove_card
(
struct
pnp_card
*
card
)
{
}
static
inline
int
pnp_add_card_device
(
struct
pnp_card
*
card
,
struct
pnp_dev
*
dev
)
{
return
-
ENODEV
;
}
static
inline
void
pnp_remove_card_device
(
struct
pnp_dev
*
dev
)
{
}
static
inline
int
pnp_add_card_id
(
struct
pnp_id
*
id
,
struct
pnp_card
*
card
)
{
return
-
ENODEV
;
}
static
inline
struct
pnp_dev
*
pnp_request_card_device
(
struct
pnp_card_link
*
clink
,
const
char
*
id
,
struct
pnp_dev
*
from
)
{
return
NULL
;
}
static
inline
void
pnp_release_card_device
(
struct
pnp_dev
*
dev
)
{
}
static
inline
int
pnp_register_card_driver
(
struct
pnp_card_driver
*
drv
)
{
return
-
ENODEV
;
}
static
inline
void
pnp_unregister_card_driver
(
struct
pnp_card_driver
*
drv
)
{
}
/* resource management */
static
inline
struct
pnp_option
*
pnp_register_independent_option
(
struct
pnp_dev
*
dev
)
{
return
NULL
;
}
static
inline
struct
pnp_option
*
pnp_register_dependent_option
(
struct
pnp_dev
*
dev
,
int
priority
)
{
return
NULL
;
}
static
inline
int
pnp_register_irq_resource
(
struct
pnp_option
*
option
,
struct
pnp_irq
*
data
)
{
return
-
ENODEV
;
}
static
inline
int
pnp_register_dma_resource
(
struct
pnp_option
*
option
,
struct
pnp_dma
*
data
)
{
return
-
ENODEV
;
}
static
inline
int
pnp_register_port_resource
(
struct
pnp_option
*
option
,
struct
pnp_port
*
data
)
{
return
-
ENODEV
;
}
static
inline
int
pnp_register_mem_resource
(
struct
pnp_option
*
option
,
struct
pnp_mem
*
data
)
{
return
-
ENODEV
;
}
static
inline
void
pnp_init_resource_table
(
struct
pnp_resource_table
*
table
)
{
}
static
inline
int
pnp_manual_config_dev
(
struct
pnp_dev
*
dev
,
struct
pnp_resource_table
*
res
,
int
mode
)
{
return
-
ENODEV
;
}
static
inline
int
pnp_auto_config_dev
(
struct
pnp_dev
*
dev
)
{
return
-
ENODEV
;
}
static
inline
int
pnp_validate_config
(
struct
pnp_dev
*
dev
)
{
return
-
ENODEV
;
}
static
inline
int
pnp_start_dev
(
struct
pnp_dev
*
dev
)
{
return
-
ENODEV
;
}
static
inline
int
pnp_stop_dev
(
struct
pnp_dev
*
dev
)
{
return
-
ENODEV
;
}
static
inline
int
pnp_activate_dev
(
struct
pnp_dev
*
dev
)
{
return
-
ENODEV
;
}
static
inline
int
pnp_disable_dev
(
struct
pnp_dev
*
dev
)
{
return
-
ENODEV
;
}
static
inline
void
pnp_resource_change
(
struct
resource
*
resource
,
resource_size_t
start
,
resource_size_t
size
)
{
}
/* protocol helpers */
static
inline
int
pnp_is_active
(
struct
pnp_dev
*
dev
)
{
return
0
;
}
static
inline
int
compare_pnp_id
(
struct
pnp_id
*
pos
,
const
char
*
id
)
{
return
-
ENODEV
;
}
static
inline
int
pnp_add_id
(
struct
pnp_id
*
id
,
struct
pnp_dev
*
dev
)
{
return
-
ENODEV
;
}
static
inline
int
pnp_register_driver
(
struct
pnp_driver
*
drv
)
{
return
-
ENODEV
;
}
static
inline
void
pnp_unregister_driver
(
struct
pnp_driver
*
drv
)
{
}
...
...
include/linux/pnpbios.h
已删除
100644 → 0
浏览文件 @
96916090
/*
* Include file for the interface to a PnP BIOS
*
* Original BIOS code (C) 1998 Christian Schmidt (chr.schmidt@tu-bs.de)
* PnP handler parts (c) 1998 Tom Lees <tom@lpsg.demon.co.uk>
* Minor reorganizations by David Hinds <dahinds@users.sourceforge.net>
*
* 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, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LINUX_PNPBIOS_H
#define _LINUX_PNPBIOS_H
#ifdef __KERNEL__
#include <linux/types.h>
#include <linux/pnp.h>
/*
* Return codes
*/
#define PNP_SUCCESS 0x00
#define PNP_NOT_SET_STATICALLY 0x7f
#define PNP_UNKNOWN_FUNCTION 0x81
#define PNP_FUNCTION_NOT_SUPPORTED 0x82
#define PNP_INVALID_HANDLE 0x83
#define PNP_BAD_PARAMETER 0x84
#define PNP_SET_FAILED 0x85
#define PNP_EVENTS_NOT_PENDING 0x86
#define PNP_SYSTEM_NOT_DOCKED 0x87
#define PNP_NO_ISA_PNP_CARDS 0x88
#define PNP_UNABLE_TO_DETERMINE_DOCK_CAPABILITIES 0x89
#define PNP_CONFIG_CHANGE_FAILED_NO_BATTERY 0x8a
#define PNP_CONFIG_CHANGE_FAILED_RESOURCE_CONFLICT 0x8b
#define PNP_BUFFER_TOO_SMALL 0x8c
#define PNP_USE_ESCD_SUPPORT 0x8d
#define PNP_MESSAGE_NOT_SUPPORTED 0x8e
#define PNP_HARDWARE_ERROR 0x8f
#define ESCD_SUCCESS 0x00
#define ESCD_IO_ERROR_READING 0x55
#define ESCD_INVALID 0x56
#define ESCD_BUFFER_TOO_SMALL 0x59
#define ESCD_NVRAM_TOO_SMALL 0x5a
#define ESCD_FUNCTION_NOT_SUPPORTED 0x81
/*
* Events that can be received by "get event"
*/
#define PNPEV_ABOUT_TO_CHANGE_CONFIG 0x0001
#define PNPEV_DOCK_CHANGED 0x0002
#define PNPEV_SYSTEM_DEVICE_CHANGED 0x0003
#define PNPEV_CONFIG_CHANGED_FAILED 0x0004
#define PNPEV_UNKNOWN_SYSTEM_EVENT 0xffff
/* 0x8000 through 0xfffe are OEM defined */
/*
* Messages that should be sent through "send message"
*/
#define PNPMSG_OK 0x00
#define PNPMSG_ABORT 0x01
#define PNPMSG_UNDOCK_DEFAULT_ACTION 0x40
#define PNPMSG_POWER_OFF 0x41
#define PNPMSG_PNP_OS_ACTIVE 0x42
#define PNPMSG_PNP_OS_INACTIVE 0x43
/*
* Plug and Play BIOS flags
*/
#define PNPBIOS_NO_DISABLE 0x0001
#define PNPBIOS_NO_CONFIG 0x0002
#define PNPBIOS_OUTPUT 0x0004
#define PNPBIOS_INPUT 0x0008
#define PNPBIOS_BOOTABLE 0x0010
#define PNPBIOS_DOCK 0x0020
#define PNPBIOS_REMOVABLE 0x0040
#define pnpbios_is_static(x) (((x)->flags & 0x0100) == 0x0000)
#define pnpbios_is_dynamic(x) ((x)->flags & 0x0080)
/*
* Function Parameters
*/
#define PNPMODE_STATIC 1
#define PNPMODE_DYNAMIC 0
/* 0x8000 through 0xffff are OEM defined */
#pragma pack(1)
struct
pnp_dev_node_info
{
__u16
no_nodes
;
__u16
max_node_size
;
};
struct
pnp_docking_station_info
{
__u32
location_id
;
__u32
serial
;
__u16
capabilities
;
};
struct
pnp_isa_config_struc
{
__u8
revision
;
__u8
no_csns
;
__u16
isa_rd_data_port
;
__u16
reserved
;
};
struct
escd_info_struc
{
__u16
min_escd_write_size
;
__u16
escd_size
;
__u32
nv_storage_base
;
};
struct
pnp_bios_node
{
__u16
size
;
__u8
handle
;
__u32
eisa_id
;
__u8
type_code
[
3
];
__u16
flags
;
__u8
data
[
0
];
};
#pragma pack()
#ifdef CONFIG_PNPBIOS
/* non-exported */
extern
struct
pnp_dev_node_info
node_info
;
extern
int
pnp_bios_dev_node_info
(
struct
pnp_dev_node_info
*
data
);
extern
int
pnp_bios_get_dev_node
(
u8
*
nodenum
,
char
config
,
struct
pnp_bios_node
*
data
);
extern
int
pnp_bios_set_dev_node
(
u8
nodenum
,
char
config
,
struct
pnp_bios_node
*
data
);
extern
int
pnp_bios_get_stat_res
(
char
*
info
);
extern
int
pnp_bios_isapnp_config
(
struct
pnp_isa_config_struc
*
data
);
extern
int
pnp_bios_escd_info
(
struct
escd_info_struc
*
data
);
extern
int
pnp_bios_read_escd
(
char
*
data
,
u32
nvram_base
);
extern
int
pnp_bios_dock_station_info
(
struct
pnp_docking_station_info
*
data
);
#endif
/* CONFIG_PNPBIOS */
#endif
/* __KERNEL__ */
#endif
/* _LINUX_PNPBIOS_H */
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录