Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
008238b5
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
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
;
nirq
++
;
if
(
nirq
>=
PNP_MAX_IRQ
)
break
;
start
=
simple_strtoul
(
buf
,
&
buf
,
0
);
pnp_res
=
pnp_add_irq_resource
(
dev
,
start
,
0
);
if
(
pnp_res
)
nirq
++
;
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
(
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_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_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
(
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_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
;
if
(
irq
==
2
)
irq
=
9
;
isapnp_write_byte
(
ISAPNP_CFG_IRQ
+
(
tmp
<<
1
),
irq
);
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
;
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,67 +415,16 @@ 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
);
pnp_clean_resource_table
(
dev
);
mutex_unlock
(
&
pnp_res_mutex
);
dbg_pnp_show_resources
(
dev
,
"after pnp_assign_resources (failed)"
);
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
;
}
}
mutex_unlock
(
&
pnp_res_mutex
);
kfree
(
bak
);
return
0
;
fail:
dev
->
res
=
*
bak
;
mutex_unlock
(
&
pnp_res_mutex
);
kfree
(
bak
);
return
-
EINVAL
;
}
/**
* pnp_auto_config_dev - automatically assigns resources to a device
* @dev: pointer to the desired device
...
...
@@ -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
...
...
@@ -21,6 +21,8 @@
#include <linux/kernel.h>
#include <linux/acpi.h>
#include <linux/pci.h>
#include <linux/pnp.h>
#include "../base.h"
#include "pnpacpi.h"
#ifdef CONFIG_IA64
...
...
@@ -32,19 +34,26 @@
/*
* Allocated Resources
*/
static
int
irq_flags
(
int
triggering
,
int
polarity
)
static
int
irq_flags
(
int
triggering
,
int
polarity
,
int
shareable
)
{
int
flags
;
if
(
triggering
==
ACPI_LEVEL_SENSITIVE
)
{
if
(
polarity
==
ACPI_ACTIVE_LOW
)
return
IORESOURCE_IRQ_LOWLEVEL
;
flags
=
IORESOURCE_IRQ_LOWLEVEL
;
else
return
IORESOURCE_IRQ_HIGHLEVEL
;
flags
=
IORESOURCE_IRQ_HIGHLEVEL
;
}
else
{
if
(
polarity
==
ACPI_ACTIVE_LOW
)
return
IORESOURCE_IRQ_LOWEDGE
;
flags
=
IORESOURCE_IRQ_LOWEDGE
;
else
return
IORESOURCE_IRQ_HIGHEDGE
;
flags
=
IORESOURCE_IRQ_HIGHEDGE
;
}
if
(
shareable
)
flags
|=
IORESOURCE_IRQ_SHAREABLE
;
return
flags
;
}
static
void
decode_irq_flags
(
int
flag
,
int
*
triggering
,
int
*
polarity
)
...
...
@@ -69,29 +78,16 @@ static void decode_irq_flags(int flag, int *triggering, int *polarity)
}
}
static
void
pnpacpi_parse_allocated_irqresource
(
struct
pnp_
resource_table
*
res
,
static
void
pnpacpi_parse_allocated_irqresource
(
struct
pnp_
dev
*
dev
,
u32
gsi
,
int
triggering
,
int
polarity
,
int
shareable
)
{
int
i
=
0
;
int
irq
;
int
irq
,
flags
;
int
p
,
t
;
static
unsigned
char
warned
;
if
(
!
valid_IRQ
(
gsi
))
return
;
while
(
!
(
res
->
irq_resource
[
i
].
flags
&
IORESOURCE_UNSET
)
&&
i
<
PNP_MAX_IRQ
)
i
++
;
if
(
i
>=
PNP_MAX_IRQ
)
{
if
(
!
warned
)
{
printk
(
KERN_WARNING
"pnpacpi: exceeded the max number"
" of IRQ resources: %d
\n
"
,
PNP_MAX_IRQ
);
warned
=
1
;
}
return
;
}
/*
* in IO-APIC mode, use overrided attribute. Two reasons:
* 1. BIOS bug in DSDT
...
...
@@ -102,27 +98,21 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res,
p
=
p
?
ACPI_ACTIVE_LOW
:
ACPI_ACTIVE_HIGH
;
if
(
triggering
!=
t
||
polarity
!=
p
)
{
pnp_warn
(
"IRQ %d override to %s, %s
"
,
dev_warn
(
&
dev
->
dev
,
"IRQ %d override to %s, %s
\n
"
,
gsi
,
t
?
"edge"
:
"level"
,
p
?
"low"
:
"high"
);
triggering
=
t
;
polarity
=
p
;
}
}
res
->
irq_resource
[
i
].
flags
=
IORESOURCE_IRQ
;
// Also clears _UNSET flag
res
->
irq_resource
[
i
].
flags
|=
irq_flags
(
triggering
,
polarity
);
flags
=
irq_flags
(
triggering
,
polarity
,
shareable
);
irq
=
acpi_register_gsi
(
gsi
,
triggering
,
polarity
);
if
(
irq
<
0
)
{
res
->
irq_resource
[
i
].
flags
|=
IORESOURCE_DISABLED
;
return
;
}
if
(
shareable
)
res
->
irq_resource
[
i
].
flags
|=
IORESOURCE_IRQ_SHAREABLE
;
if
(
irq
>=
0
)
pcibios_penalize_isa_irq
(
irq
,
1
);
else
flags
|=
IORESOURCE_DISABLED
;
res
->
irq_resource
[
i
].
start
=
irq
;
res
->
irq_resource
[
i
].
end
=
irq
;
pcibios_penalize_isa_irq
(
irq
,
1
);
pnp_add_irq_resource
(
dev
,
irq
,
flags
);
}
static
int
dma_flags
(
int
type
,
int
bus_master
,
int
transfer
)
...
...
@@ -168,88 +158,36 @@ static int dma_flags(int type, int bus_master, int transfer)
return
flags
;
}
static
void
pnpacpi_parse_allocated_dmaresource
(
struct
pnp_resource_table
*
res
,
u32
dma
,
int
type
,
int
bus_master
,
int
transfer
)
static
void
pnpacpi_parse_allocated_ioresource
(
struct
pnp_dev
*
dev
,
u64
start
,
u64
len
,
int
io_decode
)
{
int
i
=
0
;
static
unsigned
char
warned
;
while
(
i
<
PNP_MAX_DMA
&&
!
(
res
->
dma_resource
[
i
].
flags
&
IORESOURCE_UNSET
))
i
++
;
if
(
i
<
PNP_MAX_DMA
)
{
res
->
dma_resource
[
i
].
flags
=
IORESOURCE_DMA
;
// Also clears _UNSET flag
res
->
dma_resource
[
i
].
flags
|=
dma_flags
(
type
,
bus_master
,
transfer
);
if
(
dma
==
-
1
)
{
res
->
dma_resource
[
i
].
flags
|=
IORESOURCE_DISABLED
;
return
;
}
res
->
dma_resource
[
i
].
start
=
dma
;
res
->
dma_resource
[
i
].
end
=
dma
;
}
else
if
(
!
warned
)
{
printk
(
KERN_WARNING
"pnpacpi: exceeded the max number of DMA "
"resources: %d
\n
"
,
PNP_MAX_DMA
);
warned
=
1
;
}
}
int
flags
=
0
;
u64
end
=
start
+
len
-
1
;
static
void
pnpacpi_parse_allocated_ioresource
(
struct
pnp_resource_table
*
res
,
u64
io
,
u64
len
,
int
io_decode
)
{
int
i
=
0
;
static
unsigned
char
warned
;
if
(
io_decode
==
ACPI_DECODE_16
)
flags
|=
PNP_PORT_FLAG_16BITADDR
;
if
(
len
==
0
||
end
>=
0x10003
)
flags
|=
IORESOURCE_DISABLED
;
while
(
!
(
res
->
port_resource
[
i
].
flags
&
IORESOURCE_UNSET
)
&&
i
<
PNP_MAX_PORT
)
i
++
;
if
(
i
<
PNP_MAX_PORT
)
{
res
->
port_resource
[
i
].
flags
=
IORESOURCE_IO
;
// Also clears _UNSET flag
if
(
io_decode
==
ACPI_DECODE_16
)
res
->
port_resource
[
i
].
flags
|=
PNP_PORT_FLAG_16BITADDR
;
if
(
len
<=
0
||
(
io
+
len
-
1
)
>=
0x10003
)
{
res
->
port_resource
[
i
].
flags
|=
IORESOURCE_DISABLED
;
return
;
}
res
->
port_resource
[
i
].
start
=
io
;
res
->
port_resource
[
i
].
end
=
io
+
len
-
1
;
}
else
if
(
!
warned
)
{
printk
(
KERN_WARNING
"pnpacpi: exceeded the max number of IO "
"resources: %d
\n
"
,
PNP_MAX_PORT
);
warned
=
1
;
}
pnp_add_io_resource
(
dev
,
start
,
end
,
flags
);
}
static
void
pnpacpi_parse_allocated_memresource
(
struct
pnp_
resource_table
*
res
,
u64
mem
,
u64
len
,
static
void
pnpacpi_parse_allocated_memresource
(
struct
pnp_
dev
*
dev
,
u64
start
,
u64
len
,
int
write_protect
)
{
int
i
=
0
;
static
unsigned
char
warned
;
int
flags
=
0
;
u64
end
=
start
+
len
-
1
;
while
(
!
(
res
->
mem_resource
[
i
].
flags
&
IORESOURCE_UNSET
)
&&
(
i
<
PNP_MAX_MEM
))
i
++
;
if
(
i
<
PNP_MAX_MEM
)
{
res
->
mem_resource
[
i
].
flags
=
IORESOURCE_MEM
;
// Also clears _UNSET flag
if
(
len
<=
0
)
{
res
->
mem_resource
[
i
].
flags
|=
IORESOURCE_DISABLED
;
return
;
}
if
(
write_protect
==
ACPI_READ_WRITE_MEMORY
)
res
->
mem_resource
[
i
].
flags
|=
IORESOURCE_MEM_WRITEABLE
;
res
->
mem_resource
[
i
].
start
=
mem
;
res
->
mem_resource
[
i
].
end
=
mem
+
len
-
1
;
}
else
if
(
!
warned
)
{
printk
(
KERN_WARNING
"pnpacpi: exceeded the max number of mem "
"resources: %d
\n
"
,
PNP_MAX_MEM
);
warned
=
1
;
}
if
(
len
==
0
)
flags
|=
IORESOURCE_DISABLED
;
if
(
write_protect
==
ACPI_READ_WRITE_MEMORY
)
flags
|=
IORESOURCE_MEM_WRITEABLE
;
pnp_add_mem_resource
(
dev
,
start
,
end
,
flags
);
}
static
void
pnpacpi_parse_allocated_address_space
(
struct
pnp_
resource_table
*
res_table
,
static
void
pnpacpi_parse_allocated_address_space
(
struct
pnp_
dev
*
dev
,
struct
acpi_resource
*
res
)
{
struct
acpi_resource_address64
addr
,
*
p
=
&
addr
;
...
...
@@ -257,7 +195,7 @@ static void pnpacpi_parse_allocated_address_space(struct pnp_resource_table *res
status
=
acpi_resource_to_address64
(
res
,
p
);
if
(
!
ACPI_SUCCESS
(
status
))
{
pnp_warn
(
"PnPACPI: failed to convert resource type %d
"
,
dev_warn
(
&
dev
->
dev
,
"failed to convert resource type %d
\n
"
,
res
->
type
);
return
;
}
...
...
@@ -266,11 +204,11 @@ static void pnpacpi_parse_allocated_address_space(struct pnp_resource_table *res
return
;
if
(
p
->
resource_type
==
ACPI_MEMORY_RANGE
)
pnpacpi_parse_allocated_memresource
(
res_table
,
pnpacpi_parse_allocated_memresource
(
dev
,
p
->
minimum
,
p
->
address_length
,
p
->
info
.
mem
.
write_protect
);
else
if
(
p
->
resource_type
==
ACPI_IO_RANGE
)
pnpacpi_parse_allocated_ioresource
(
res_table
,
pnpacpi_parse_allocated_ioresource
(
dev
,
p
->
minimum
,
p
->
address_length
,
p
->
granularity
==
0xfff
?
ACPI_DECODE_10
:
ACPI_DECODE_16
);
...
...
@@ -279,8 +217,16 @@ static void pnpacpi_parse_allocated_address_space(struct pnp_resource_table *res
static
acpi_status
pnpacpi_allocated_resource
(
struct
acpi_resource
*
res
,
void
*
data
)
{
struct
pnp_resource_table
*
res_table
=
data
;
int
i
;
struct
pnp_dev
*
dev
=
data
;
struct
acpi_resource_irq
*
irq
;
struct
acpi_resource_dma
*
dma
;
struct
acpi_resource_io
*
io
;
struct
acpi_resource_fixed_io
*
fixed_io
;
struct
acpi_resource_memory24
*
memory24
;
struct
acpi_resource_memory32
*
memory32
;
struct
acpi_resource_fixed_memory32
*
fixed_memory32
;
struct
acpi_resource_extended_irq
*
extended_irq
;
int
i
,
flags
;
switch
(
res
->
type
)
{
case
ACPI_RESOURCE_TYPE_IRQ
:
...
...
@@ -288,29 +234,33 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
* Per spec, only one interrupt per descriptor is allowed in
* _CRS, but some firmware violates this, so parse them all.
*/
for
(
i
=
0
;
i
<
res
->
data
.
irq
.
interrupt_count
;
i
++
)
{
pnpacpi_parse_allocated_irqresource
(
res_table
,
res
->
data
.
irq
.
interrupts
[
i
],
res
->
data
.
irq
.
triggering
,
res
->
data
.
irq
.
polarity
,
res
->
data
.
irq
.
sharable
);
irq
=
&
res
->
data
.
irq
;
for
(
i
=
0
;
i
<
irq
->
interrupt_count
;
i
++
)
{
pnpacpi_parse_allocated_irqresource
(
dev
,
irq
->
interrupts
[
i
],
irq
->
triggering
,
irq
->
polarity
,
irq
->
sharable
);
}
break
;
case
ACPI_RESOURCE_TYPE_DMA
:
if
(
res
->
data
.
dma
.
channel_count
>
0
)
pnpacpi_parse_allocated_dmaresource
(
res_table
,
res
->
data
.
dma
.
channels
[
0
],
res
->
data
.
dma
.
type
,
res
->
data
.
dma
.
bus_master
,
res
->
data
.
dma
.
transfer
);
dma
=
&
res
->
data
.
dma
;
if
(
dma
->
channel_count
>
0
)
{
flags
=
dma_flags
(
dma
->
type
,
dma
->
bus_master
,
dma
->
transfer
);
if
(
dma
->
channels
[
0
]
==
(
u8
)
-
1
)
flags
|=
IORESOURCE_DISABLED
;
pnp_add_dma_resource
(
dev
,
dma
->
channels
[
0
],
flags
);
}
break
;
case
ACPI_RESOURCE_TYPE_IO
:
pnpacpi_parse_allocated_ioresource
(
res_table
,
res
->
data
.
io
.
minimum
,
res
->
data
.
io
.
address_length
,
res
->
data
.
io
.
io_decode
);
io
=
&
res
->
data
.
io
;
pnpacpi_parse_allocated_ioresource
(
dev
,
io
->
minimum
,
io
->
address_length
,
io
->
io_decode
);
break
;
case
ACPI_RESOURCE_TYPE_START_DEPENDENT
:
...
...
@@ -318,9 +268,10 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
break
;
case
ACPI_RESOURCE_TYPE_FIXED_IO
:
pnpacpi_parse_allocated_ioresource
(
res_table
,
res
->
data
.
fixed_io
.
address
,
res
->
data
.
fixed_io
.
address_length
,
fixed_io
=
&
res
->
data
.
fixed_io
;
pnpacpi_parse_allocated_ioresource
(
dev
,
fixed_io
->
address
,
fixed_io
->
address_length
,
ACPI_DECODE_10
);
break
;
...
...
@@ -331,27 +282,30 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
break
;
case
ACPI_RESOURCE_TYPE_MEMORY24
:
pnpacpi_parse_allocated_memresource
(
res_table
,
res
->
data
.
memory24
.
minimum
,
res
->
data
.
memory24
.
address_length
,
res
->
data
.
memory24
.
write_protect
);
memory24
=
&
res
->
data
.
memory24
;
pnpacpi_parse_allocated_memresource
(
dev
,
memory24
->
minimum
,
memory24
->
address_length
,
memory24
->
write_protect
);
break
;
case
ACPI_RESOURCE_TYPE_MEMORY32
:
pnpacpi_parse_allocated_memresource
(
res_table
,
res
->
data
.
memory32
.
minimum
,
res
->
data
.
memory32
.
address_length
,
res
->
data
.
memory32
.
write_protect
);
memory32
=
&
res
->
data
.
memory32
;
pnpacpi_parse_allocated_memresource
(
dev
,
memory32
->
minimum
,
memory32
->
address_length
,
memory32
->
write_protect
);
break
;
case
ACPI_RESOURCE_TYPE_FIXED_MEMORY32
:
pnpacpi_parse_allocated_memresource
(
res_table
,
res
->
data
.
fixed_memory32
.
address
,
res
->
data
.
fixed_memory32
.
address_length
,
res
->
data
.
fixed_memory32
.
write_protect
);
fixed_memory32
=
&
res
->
data
.
fixed_memory32
;
pnpacpi_parse_allocated_memresource
(
dev
,
fixed_memory32
->
address
,
fixed_memory32
->
address_length
,
fixed_memory32
->
write_protect
);
break
;
case
ACPI_RESOURCE_TYPE_ADDRESS16
:
case
ACPI_RESOURCE_TYPE_ADDRESS32
:
case
ACPI_RESOURCE_TYPE_ADDRESS64
:
pnpacpi_parse_allocated_address_space
(
res_table
,
res
);
pnpacpi_parse_allocated_address_space
(
dev
,
res
);
break
;
case
ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64
:
...
...
@@ -360,15 +314,16 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
break
;
case
ACPI_RESOURCE_TYPE_EXTENDED_IRQ
:
if
(
res
->
data
.
extended_irq
.
producer_consumer
==
ACPI_PRODUCER
)
extended_irq
=
&
res
->
data
.
extended_irq
;
if
(
extended_irq
->
producer_consumer
==
ACPI_PRODUCER
)
return
AE_OK
;
for
(
i
=
0
;
i
<
res
->
data
.
extended_irq
.
interrupt_count
;
i
++
)
{
pnpacpi_parse_allocated_irqresource
(
res_table
,
res
->
data
.
extended_irq
.
interrupts
[
i
],
res
->
data
.
extended_irq
.
triggering
,
res
->
data
.
extended_irq
.
polarity
,
res
->
data
.
extended_irq
.
sharable
);
for
(
i
=
0
;
i
<
extended_irq
->
interrupt_count
;
i
++
)
{
pnpacpi_parse_allocated_irqresource
(
dev
,
extended_irq
->
interrupts
[
i
],
extended_irq
->
triggering
,
extended_irq
->
polarity
,
extended_irq
->
sharable
);
}
break
;
...
...
@@ -376,24 +331,36 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
break
;
default:
pnp_warn
(
"PnPACPI: unknown resource type %d"
,
res
->
type
);
dev_warn
(
&
dev
->
dev
,
"unknown resource type %d in _CRS
\n
"
,
res
->
type
);
return
AE_ERROR
;
}
return
AE_OK
;
}
acpi_status
pnpacpi_parse_allocated_resource
(
acpi_handle
handle
,
struct
pnp_resource_table
*
res
)
int
pnpacpi_parse_allocated_resource
(
struct
pnp_dev
*
dev
)
{
/* Blank the resource table values */
pnp_init_resource_table
(
res
);
acpi_handle
handle
=
dev
->
data
;
acpi_status
status
;
dev_dbg
(
&
dev
->
dev
,
"parse allocated resources
\n
"
);
return
acpi_walk_resources
(
handle
,
METHOD_NAME__CRS
,
pnpacpi_allocated_resource
,
res
);
pnp_init_resources
(
dev
);
status
=
acpi_walk_resources
(
handle
,
METHOD_NAME__CRS
,
pnpacpi_allocated_resource
,
dev
);
if
(
ACPI_FAILURE
(
status
))
{
if
(
status
!=
AE_NOT_FOUND
)
dev_err
(
&
dev
->
dev
,
"can't evaluate _CRS: %d"
,
status
);
return
-
EPERM
;
}
return
0
;
}
static
__init
void
pnpacpi_parse_dma_option
(
struct
pnp_option
*
option
,
static
__init
void
pnpacpi_parse_dma_option
(
struct
pnp_dev
*
dev
,
struct
pnp_option
*
option
,
struct
acpi_resource_dma
*
p
)
{
int
i
;
...
...
@@ -410,10 +377,11 @@ static __init void pnpacpi_parse_dma_option(struct pnp_option *option,
dma
->
flags
=
dma_flags
(
p
->
type
,
p
->
bus_master
,
p
->
transfer
);
pnp_register_dma_resource
(
option
,
dma
);
pnp_register_dma_resource
(
dev
,
option
,
dma
);
}
static
__init
void
pnpacpi_parse_irq_option
(
struct
pnp_option
*
option
,
static
__init
void
pnpacpi_parse_irq_option
(
struct
pnp_dev
*
dev
,
struct
pnp_option
*
option
,
struct
acpi_resource_irq
*
p
)
{
int
i
;
...
...
@@ -428,12 +396,13 @@ static __init void pnpacpi_parse_irq_option(struct pnp_option *option,
for
(
i
=
0
;
i
<
p
->
interrupt_count
;
i
++
)
if
(
p
->
interrupts
[
i
])
__set_bit
(
p
->
interrupts
[
i
],
irq
->
map
);
irq
->
flags
=
irq_flags
(
p
->
triggering
,
p
->
polarity
);
irq
->
flags
=
irq_flags
(
p
->
triggering
,
p
->
polarity
,
p
->
sharable
);
pnp_register_irq_resource
(
option
,
irq
);
pnp_register_irq_resource
(
dev
,
option
,
irq
);
}
static
__init
void
pnpacpi_parse_ext_irq_option
(
struct
pnp_option
*
option
,
static
__init
void
pnpacpi_parse_ext_irq_option
(
struct
pnp_dev
*
dev
,
struct
pnp_option
*
option
,
struct
acpi_resource_extended_irq
*
p
)
{
int
i
;
...
...
@@ -448,12 +417,13 @@ static __init void pnpacpi_parse_ext_irq_option(struct pnp_option *option,
for
(
i
=
0
;
i
<
p
->
interrupt_count
;
i
++
)
if
(
p
->
interrupts
[
i
])
__set_bit
(
p
->
interrupts
[
i
],
irq
->
map
);
irq
->
flags
=
irq_flags
(
p
->
triggering
,
p
->
polarity
);
irq
->
flags
=
irq_flags
(
p
->
triggering
,
p
->
polarity
,
p
->
sharable
);
pnp_register_irq_resource
(
option
,
irq
);
pnp_register_irq_resource
(
dev
,
option
,
irq
);
}
static
__init
void
pnpacpi_parse_port_option
(
struct
pnp_option
*
option
,
static
__init
void
pnpacpi_parse_port_option
(
struct
pnp_dev
*
dev
,
struct
pnp_option
*
option
,
struct
acpi_resource_io
*
io
)
{
struct
pnp_port
*
port
;
...
...
@@ -469,10 +439,11 @@ static __init void pnpacpi_parse_port_option(struct pnp_option *option,
port
->
size
=
io
->
address_length
;
port
->
flags
=
ACPI_DECODE_16
==
io
->
io_decode
?
PNP_PORT_FLAG_16BITADDR
:
0
;
pnp_register_port_resource
(
option
,
port
);
pnp_register_port_resource
(
dev
,
option
,
port
);
}
static
__init
void
pnpacpi_parse_fixed_port_option
(
struct
pnp_option
*
option
,
static
__init
void
pnpacpi_parse_fixed_port_option
(
struct
pnp_dev
*
dev
,
struct
pnp_option
*
option
,
struct
acpi_resource_fixed_io
*
io
)
{
struct
pnp_port
*
port
;
...
...
@@ -486,10 +457,11 @@ static __init void pnpacpi_parse_fixed_port_option(struct pnp_option *option,
port
->
size
=
io
->
address_length
;
port
->
align
=
0
;
port
->
flags
=
PNP_PORT_FLAG_FIXED
;
pnp_register_port_resource
(
option
,
port
);
pnp_register_port_resource
(
dev
,
option
,
port
);
}
static
__init
void
pnpacpi_parse_mem24_option
(
struct
pnp_option
*
option
,
static
__init
void
pnpacpi_parse_mem24_option
(
struct
pnp_dev
*
dev
,
struct
pnp_option
*
option
,
struct
acpi_resource_memory24
*
p
)
{
struct
pnp_mem
*
mem
;
...
...
@@ -507,10 +479,11 @@ static __init void pnpacpi_parse_mem24_option(struct pnp_option *option,
mem
->
flags
=
(
ACPI_READ_WRITE_MEMORY
==
p
->
write_protect
)
?
IORESOURCE_MEM_WRITEABLE
:
0
;
pnp_register_mem_resource
(
option
,
mem
);
pnp_register_mem_resource
(
dev
,
option
,
mem
);
}
static
__init
void
pnpacpi_parse_mem32_option
(
struct
pnp_option
*
option
,
static
__init
void
pnpacpi_parse_mem32_option
(
struct
pnp_dev
*
dev
,
struct
pnp_option
*
option
,
struct
acpi_resource_memory32
*
p
)
{
struct
pnp_mem
*
mem
;
...
...
@@ -528,10 +501,11 @@ static __init void pnpacpi_parse_mem32_option(struct pnp_option *option,
mem
->
flags
=
(
ACPI_READ_WRITE_MEMORY
==
p
->
write_protect
)
?
IORESOURCE_MEM_WRITEABLE
:
0
;
pnp_register_mem_resource
(
option
,
mem
);
pnp_register_mem_resource
(
dev
,
option
,
mem
);
}
static
__init
void
pnpacpi_parse_fixed_mem32_option
(
struct
pnp_option
*
option
,
static
__init
void
pnpacpi_parse_fixed_mem32_option
(
struct
pnp_dev
*
dev
,
struct
pnp_option
*
option
,
struct
acpi_resource_fixed_memory32
*
p
)
{
struct
pnp_mem
*
mem
;
...
...
@@ -548,10 +522,11 @@ static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_option *option,
mem
->
flags
=
(
ACPI_READ_WRITE_MEMORY
==
p
->
write_protect
)
?
IORESOURCE_MEM_WRITEABLE
:
0
;
pnp_register_mem_resource
(
option
,
mem
);
pnp_register_mem_resource
(
dev
,
option
,
mem
);
}
static
__init
void
pnpacpi_parse_address_option
(
struct
pnp_option
*
option
,
static
__init
void
pnpacpi_parse_address_option
(
struct
pnp_dev
*
dev
,
struct
pnp_option
*
option
,
struct
acpi_resource
*
r
)
{
struct
acpi_resource_address64
addr
,
*
p
=
&
addr
;
...
...
@@ -579,7 +554,7 @@ static __init void pnpacpi_parse_address_option(struct pnp_option *option,
mem
->
flags
=
(
p
->
info
.
mem
.
write_protect
==
ACPI_READ_WRITE_MEMORY
)
?
IORESOURCE_MEM_WRITEABLE
:
0
;
pnp_register_mem_resource
(
option
,
mem
);
pnp_register_mem_resource
(
dev
,
option
,
mem
);
}
else
if
(
p
->
resource_type
==
ACPI_IO_RANGE
)
{
port
=
kzalloc
(
sizeof
(
struct
pnp_port
),
GFP_KERNEL
);
if
(
!
port
)
...
...
@@ -588,7 +563,7 @@ static __init void pnpacpi_parse_address_option(struct pnp_option *option,
port
->
size
=
p
->
address_length
;
port
->
align
=
0
;
port
->
flags
=
PNP_PORT_FLAG_FIXED
;
pnp_register_port_resource
(
option
,
port
);
pnp_register_port_resource
(
dev
,
option
,
port
);
}
}
...
...
@@ -608,11 +583,11 @@ static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res,
switch
(
res
->
type
)
{
case
ACPI_RESOURCE_TYPE_IRQ
:
pnpacpi_parse_irq_option
(
option
,
&
res
->
data
.
irq
);
pnpacpi_parse_irq_option
(
dev
,
option
,
&
res
->
data
.
irq
);
break
;
case
ACPI_RESOURCE_TYPE_DMA
:
pnpacpi_parse_dma_option
(
option
,
&
res
->
data
.
dma
);
pnpacpi_parse_dma_option
(
dev
,
option
,
&
res
->
data
.
dma
);
break
;
case
ACPI_RESOURCE_TYPE_START_DEPENDENT
:
...
...
@@ -642,19 +617,22 @@ static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res,
case
ACPI_RESOURCE_TYPE_END_DEPENDENT
:
/*only one EndDependentFn is allowed */
if
(
!
parse_data
->
option_independent
)
{
pnp_warn
(
"PnPACPI: more than one EndDependentFn"
);
dev_warn
(
&
dev
->
dev
,
"more than one EndDependentFn "
"in _PRS
\n
"
);
return
AE_ERROR
;
}
parse_data
->
option
=
parse_data
->
option_independent
;
parse_data
->
option_independent
=
NULL
;
dev_dbg
(
&
dev
->
dev
,
"end dependent options
\n
"
);
break
;
case
ACPI_RESOURCE_TYPE_IO
:
pnpacpi_parse_port_option
(
option
,
&
res
->
data
.
io
);
pnpacpi_parse_port_option
(
dev
,
option
,
&
res
->
data
.
io
);
break
;
case
ACPI_RESOURCE_TYPE_FIXED_IO
:
pnpacpi_parse_fixed_port_option
(
option
,
&
res
->
data
.
fixed_io
);
pnpacpi_parse_fixed_port_option
(
dev
,
option
,
&
res
->
data
.
fixed_io
);
break
;
case
ACPI_RESOURCE_TYPE_VENDOR
:
...
...
@@ -662,57 +640,67 @@ static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res,
break
;
case
ACPI_RESOURCE_TYPE_MEMORY24
:
pnpacpi_parse_mem24_option
(
option
,
&
res
->
data
.
memory24
);
pnpacpi_parse_mem24_option
(
dev
,
option
,
&
res
->
data
.
memory24
);
break
;
case
ACPI_RESOURCE_TYPE_MEMORY32
:
pnpacpi_parse_mem32_option
(
option
,
&
res
->
data
.
memory32
);
pnpacpi_parse_mem32_option
(
dev
,
option
,
&
res
->
data
.
memory32
);
break
;
case
ACPI_RESOURCE_TYPE_FIXED_MEMORY32
:
pnpacpi_parse_fixed_mem32_option
(
option
,
pnpacpi_parse_fixed_mem32_option
(
dev
,
option
,
&
res
->
data
.
fixed_memory32
);
break
;
case
ACPI_RESOURCE_TYPE_ADDRESS16
:
case
ACPI_RESOURCE_TYPE_ADDRESS32
:
case
ACPI_RESOURCE_TYPE_ADDRESS64
:
pnpacpi_parse_address_option
(
option
,
res
);
pnpacpi_parse_address_option
(
dev
,
option
,
res
);
break
;
case
ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64
:
break
;
case
ACPI_RESOURCE_TYPE_EXTENDED_IRQ
:
pnpacpi_parse_ext_irq_option
(
option
,
&
res
->
data
.
extended_irq
);
pnpacpi_parse_ext_irq_option
(
dev
,
option
,
&
res
->
data
.
extended_irq
);
break
;
case
ACPI_RESOURCE_TYPE_GENERIC_REGISTER
:
break
;
default:
pnp_warn
(
"PnPACPI: unknown resource type %d"
,
res
->
type
);
dev_warn
(
&
dev
->
dev
,
"unknown resource type %d in _PRS
\n
"
,
res
->
type
);
return
AE_ERROR
;
}
return
AE_OK
;
}
acpi_status
__init
pnpacpi_parse_resource_option_data
(
acpi_handle
handle
,
struct
pnp_dev
*
dev
)
int
__init
pnpacpi_parse_resource_option_data
(
struct
pnp_dev
*
dev
)
{
acpi_handle
handle
=
dev
->
data
;
acpi_status
status
;
struct
acpipnp_parse_option_s
parse_data
;
dev_dbg
(
&
dev
->
dev
,
"parse resource options
\n
"
);
parse_data
.
option
=
pnp_register_independent_option
(
dev
);
if
(
!
parse_data
.
option
)
return
AE_ERROR
;
return
-
ENOMEM
;
parse_data
.
option_independent
=
parse_data
.
option
;
parse_data
.
dev
=
dev
;
status
=
acpi_walk_resources
(
handle
,
METHOD_NAME__PRS
,
pnpacpi_option_resource
,
&
parse_data
);
return
status
;
if
(
ACPI_FAILURE
(
status
))
{
if
(
status
!=
AE_NOT_FOUND
)
dev_err
(
&
dev
->
dev
,
"can't evaluate _PRS: %d"
,
status
);
return
-
EPERM
;
}
return
0
;
}
static
int
pnpacpi_supported_resource
(
struct
acpi_resource
*
res
)
...
...
@@ -760,9 +748,10 @@ static acpi_status pnpacpi_type_resources(struct acpi_resource *res, void *data)
return
AE_OK
;
}
int
pnpacpi_build_resource_template
(
acpi_handle
handle
,
int
pnpacpi_build_resource_template
(
struct
pnp_dev
*
dev
,
struct
acpi_buffer
*
buffer
)
{
acpi_handle
handle
=
dev
->
data
;
struct
acpi_resource
*
resource
;
int
res_cnt
=
0
;
acpi_status
status
;
...
...
@@ -770,7 +759,7 @@ int pnpacpi_build_resource_template(acpi_handle handle,
status
=
acpi_walk_resources
(
handle
,
METHOD_NAME__CRS
,
pnpacpi_count_resources
,
&
res_cnt
);
if
(
ACPI_FAILURE
(
status
))
{
pnp_err
(
"Evaluate _CRS failed"
);
dev_err
(
&
dev
->
dev
,
"can't evaluate _CRS: %d
\n
"
,
status
);
return
-
EINVAL
;
}
if
(
!
res_cnt
)
...
...
@@ -779,13 +768,13 @@ int pnpacpi_build_resource_template(acpi_handle handle,
buffer
->
pointer
=
kzalloc
(
buffer
->
length
-
1
,
GFP_KERNEL
);
if
(
!
buffer
->
pointer
)
return
-
ENOMEM
;
pnp_dbg
(
"Res cnt %d"
,
res_cnt
);
resource
=
(
struct
acpi_resource
*
)
buffer
->
pointer
;
status
=
acpi_walk_resources
(
handle
,
METHOD_NAME__CRS
,
pnpacpi_type_resources
,
&
resource
);
if
(
ACPI_FAILURE
(
status
))
{
kfree
(
buffer
->
pointer
);
pnp_err
(
"Evaluate _CRS failed"
);
dev_err
(
&
dev
->
dev
,
"can't evaluate _CRS: %d
\n
"
,
status
);
return
-
EINVAL
;
}
/* resource will pointer the end resource now */
...
...
@@ -794,129 +783,184 @@ int pnpacpi_build_resource_template(acpi_handle handle,
return
0
;
}
static
void
pnpacpi_encode_irq
(
struct
acpi_resource
*
resource
,
static
void
pnpacpi_encode_irq
(
struct
pnp_dev
*
dev
,
struct
acpi_resource
*
resource
,
struct
resource
*
p
)
{
struct
acpi_resource_irq
*
irq
=
&
resource
->
data
.
irq
;
int
triggering
,
polarity
;
decode_irq_flags
(
p
->
flags
&
IORESOURCE_BITS
,
&
triggering
,
&
polarity
);
resource
->
data
.
irq
.
triggering
=
triggering
;
resource
->
data
.
irq
.
polarity
=
polarity
;
irq
->
triggering
=
triggering
;
irq
->
polarity
=
polarity
;
if
(
triggering
==
ACPI_EDGE_SENSITIVE
)
resource
->
data
.
irq
.
sharable
=
ACPI_EXCLUSIVE
;
irq
->
sharable
=
ACPI_EXCLUSIVE
;
else
resource
->
data
.
irq
.
sharable
=
ACPI_SHARED
;
resource
->
data
.
irq
.
interrupt_count
=
1
;
resource
->
data
.
irq
.
interrupts
[
0
]
=
p
->
start
;
irq
->
sharable
=
ACPI_SHARED
;
irq
->
interrupt_count
=
1
;
irq
->
interrupts
[
0
]
=
p
->
start
;
dev_dbg
(
&
dev
->
dev
,
" encode irq %d %s %s %s
\n
"
,
(
int
)
p
->
start
,
triggering
==
ACPI_LEVEL_SENSITIVE
?
"level"
:
"edge"
,
polarity
==
ACPI_ACTIVE_LOW
?
"low"
:
"high"
,
irq
->
sharable
==
ACPI_SHARED
?
"shared"
:
"exclusive"
);
}
static
void
pnpacpi_encode_ext_irq
(
struct
acpi_resource
*
resource
,
static
void
pnpacpi_encode_ext_irq
(
struct
pnp_dev
*
dev
,
struct
acpi_resource
*
resource
,
struct
resource
*
p
)
{
struct
acpi_resource_extended_irq
*
extended_irq
=
&
resource
->
data
.
extended_irq
;
int
triggering
,
polarity
;
decode_irq_flags
(
p
->
flags
&
IORESOURCE_BITS
,
&
triggering
,
&
polarity
);
resource
->
data
.
extended_irq
.
producer_consumer
=
ACPI_CONSUMER
;
resource
->
data
.
extended_irq
.
triggering
=
triggering
;
resource
->
data
.
extended_irq
.
polarity
=
polarity
;
extended_irq
->
producer_consumer
=
ACPI_CONSUMER
;
extended_irq
->
triggering
=
triggering
;
extended_irq
->
polarity
=
polarity
;
if
(
triggering
==
ACPI_EDGE_SENSITIVE
)
resource
->
data
.
irq
.
sharable
=
ACPI_EXCLUSIVE
;
extended_irq
->
sharable
=
ACPI_EXCLUSIVE
;
else
resource
->
data
.
irq
.
sharable
=
ACPI_SHARED
;
resource
->
data
.
extended_irq
.
interrupt_count
=
1
;
resource
->
data
.
extended_irq
.
interrupts
[
0
]
=
p
->
start
;
extended_irq
->
sharable
=
ACPI_SHARED
;
extended_irq
->
interrupt_count
=
1
;
extended_irq
->
interrupts
[
0
]
=
p
->
start
;
dev_dbg
(
&
dev
->
dev
,
" encode irq %d %s %s %s
\n
"
,
(
int
)
p
->
start
,
triggering
==
ACPI_LEVEL_SENSITIVE
?
"level"
:
"edge"
,
polarity
==
ACPI_ACTIVE_LOW
?
"low"
:
"high"
,
extended_irq
->
sharable
==
ACPI_SHARED
?
"shared"
:
"exclusive"
);
}
static
void
pnpacpi_encode_dma
(
struct
acpi_resource
*
resource
,
static
void
pnpacpi_encode_dma
(
struct
pnp_dev
*
dev
,
struct
acpi_resource
*
resource
,
struct
resource
*
p
)
{
struct
acpi_resource_dma
*
dma
=
&
resource
->
data
.
dma
;
/* Note: pnp_assign_dma will copy pnp_dma->flags into p->flags */
switch
(
p
->
flags
&
IORESOURCE_DMA_SPEED_MASK
)
{
case
IORESOURCE_DMA_TYPEA
:
resource
->
data
.
dma
.
type
=
ACPI_TYPE_A
;
dma
->
type
=
ACPI_TYPE_A
;
break
;
case
IORESOURCE_DMA_TYPEB
:
resource
->
data
.
dma
.
type
=
ACPI_TYPE_B
;
dma
->
type
=
ACPI_TYPE_B
;
break
;
case
IORESOURCE_DMA_TYPEF
:
resource
->
data
.
dma
.
type
=
ACPI_TYPE_F
;
dma
->
type
=
ACPI_TYPE_F
;
break
;
default:
resource
->
data
.
dma
.
type
=
ACPI_COMPATIBILITY
;
dma
->
type
=
ACPI_COMPATIBILITY
;
}
switch
(
p
->
flags
&
IORESOURCE_DMA_TYPE_MASK
)
{
case
IORESOURCE_DMA_8BIT
:
resource
->
data
.
dma
.
transfer
=
ACPI_TRANSFER_8
;
dma
->
transfer
=
ACPI_TRANSFER_8
;
break
;
case
IORESOURCE_DMA_8AND16BIT
:
resource
->
data
.
dma
.
transfer
=
ACPI_TRANSFER_8_16
;
dma
->
transfer
=
ACPI_TRANSFER_8_16
;
break
;
default:
resource
->
data
.
dma
.
transfer
=
ACPI_TRANSFER_16
;
dma
->
transfer
=
ACPI_TRANSFER_16
;
}
resource
->
data
.
dma
.
bus_master
=
!!
(
p
->
flags
&
IORESOURCE_DMA_MASTER
);
resource
->
data
.
dma
.
channel_count
=
1
;
resource
->
data
.
dma
.
channels
[
0
]
=
p
->
start
;
dma
->
bus_master
=
!!
(
p
->
flags
&
IORESOURCE_DMA_MASTER
);
dma
->
channel_count
=
1
;
dma
->
channels
[
0
]
=
p
->
start
;
dev_dbg
(
&
dev
->
dev
,
" encode dma %d "
"type %#x transfer %#x master %d
\n
"
,
(
int
)
p
->
start
,
dma
->
type
,
dma
->
transfer
,
dma
->
bus_master
);
}
static
void
pnpacpi_encode_io
(
struct
acpi_resource
*
resource
,
static
void
pnpacpi_encode_io
(
struct
pnp_dev
*
dev
,
struct
acpi_resource
*
resource
,
struct
resource
*
p
)
{
struct
acpi_resource_io
*
io
=
&
resource
->
data
.
io
;
/* Note: pnp_assign_port will copy pnp_port->flags into p->flags */
resource
->
data
.
io
.
io_decode
=
(
p
->
flags
&
PNP_PORT_FLAG_16BITADDR
)
?
io
->
io_decode
=
(
p
->
flags
&
PNP_PORT_FLAG_16BITADDR
)
?
ACPI_DECODE_16
:
ACPI_DECODE_10
;
resource
->
data
.
io
.
minimum
=
p
->
start
;
resource
->
data
.
io
.
maximum
=
p
->
end
;
resource
->
data
.
io
.
alignment
=
0
;
/* Correct? */
resource
->
data
.
io
.
address_length
=
p
->
end
-
p
->
start
+
1
;
io
->
minimum
=
p
->
start
;
io
->
maximum
=
p
->
end
;
io
->
alignment
=
0
;
/* Correct? */
io
->
address_length
=
p
->
end
-
p
->
start
+
1
;
dev_dbg
(
&
dev
->
dev
,
" encode io %#llx-%#llx decode %#x
\n
"
,
(
unsigned
long
long
)
p
->
start
,
(
unsigned
long
long
)
p
->
end
,
io
->
io_decode
);
}
static
void
pnpacpi_encode_fixed_io
(
struct
acpi_resource
*
resource
,
static
void
pnpacpi_encode_fixed_io
(
struct
pnp_dev
*
dev
,
struct
acpi_resource
*
resource
,
struct
resource
*
p
)
{
resource
->
data
.
fixed_io
.
address
=
p
->
start
;
resource
->
data
.
fixed_io
.
address_length
=
p
->
end
-
p
->
start
+
1
;
struct
acpi_resource_fixed_io
*
fixed_io
=
&
resource
->
data
.
fixed_io
;
fixed_io
->
address
=
p
->
start
;
fixed_io
->
address_length
=
p
->
end
-
p
->
start
+
1
;
dev_dbg
(
&
dev
->
dev
,
" encode fixed_io %#llx-%#llx
\n
"
,
(
unsigned
long
long
)
p
->
start
,
(
unsigned
long
long
)
p
->
end
);
}
static
void
pnpacpi_encode_mem24
(
struct
acpi_resource
*
resource
,
static
void
pnpacpi_encode_mem24
(
struct
pnp_dev
*
dev
,
struct
acpi_resource
*
resource
,
struct
resource
*
p
)
{
struct
acpi_resource_memory24
*
memory24
=
&
resource
->
data
.
memory24
;
/* Note: pnp_assign_mem will copy pnp_mem->flags into p->flags */
resource
->
data
.
memory24
.
write_protect
=
memory24
->
write_protect
=
(
p
->
flags
&
IORESOURCE_MEM_WRITEABLE
)
?
ACPI_READ_WRITE_MEMORY
:
ACPI_READ_ONLY_MEMORY
;
resource
->
data
.
memory24
.
minimum
=
p
->
start
;
resource
->
data
.
memory24
.
maximum
=
p
->
end
;
resource
->
data
.
memory24
.
alignment
=
0
;
resource
->
data
.
memory24
.
address_length
=
p
->
end
-
p
->
start
+
1
;
memory24
->
minimum
=
p
->
start
;
memory24
->
maximum
=
p
->
end
;
memory24
->
alignment
=
0
;
memory24
->
address_length
=
p
->
end
-
p
->
start
+
1
;
dev_dbg
(
&
dev
->
dev
,
" encode mem24 %#llx-%#llx write_protect %#x
\n
"
,
(
unsigned
long
long
)
p
->
start
,
(
unsigned
long
long
)
p
->
end
,
memory24
->
write_protect
);
}
static
void
pnpacpi_encode_mem32
(
struct
acpi_resource
*
resource
,
static
void
pnpacpi_encode_mem32
(
struct
pnp_dev
*
dev
,
struct
acpi_resource
*
resource
,
struct
resource
*
p
)
{
resource
->
data
.
memory32
.
write_protect
=
struct
acpi_resource_memory32
*
memory32
=
&
resource
->
data
.
memory32
;
memory32
->
write_protect
=
(
p
->
flags
&
IORESOURCE_MEM_WRITEABLE
)
?
ACPI_READ_WRITE_MEMORY
:
ACPI_READ_ONLY_MEMORY
;
resource
->
data
.
memory32
.
minimum
=
p
->
start
;
resource
->
data
.
memory32
.
maximum
=
p
->
end
;
resource
->
data
.
memory32
.
alignment
=
0
;
resource
->
data
.
memory32
.
address_length
=
p
->
end
-
p
->
start
+
1
;
memory32
->
minimum
=
p
->
start
;
memory32
->
maximum
=
p
->
end
;
memory32
->
alignment
=
0
;
memory32
->
address_length
=
p
->
end
-
p
->
start
+
1
;
dev_dbg
(
&
dev
->
dev
,
" encode mem32 %#llx-%#llx write_protect %#x
\n
"
,
(
unsigned
long
long
)
p
->
start
,
(
unsigned
long
long
)
p
->
end
,
memory32
->
write_protect
);
}
static
void
pnpacpi_encode_fixed_mem32
(
struct
acpi_resource
*
resource
,
static
void
pnpacpi_encode_fixed_mem32
(
struct
pnp_dev
*
dev
,
struct
acpi_resource
*
resource
,
struct
resource
*
p
)
{
resource
->
data
.
fixed_memory32
.
write_protect
=
struct
acpi_resource_fixed_memory32
*
fixed_memory32
=
&
resource
->
data
.
fixed_memory32
;
fixed_memory32
->
write_protect
=
(
p
->
flags
&
IORESOURCE_MEM_WRITEABLE
)
?
ACPI_READ_WRITE_MEMORY
:
ACPI_READ_ONLY_MEMORY
;
resource
->
data
.
fixed_memory32
.
address
=
p
->
start
;
resource
->
data
.
fixed_memory32
.
address_length
=
p
->
end
-
p
->
start
+
1
;
fixed_memory32
->
address
=
p
->
start
;
fixed_memory32
->
address_length
=
p
->
end
-
p
->
start
+
1
;
dev_dbg
(
&
dev
->
dev
,
" encode fixed_mem32 %#llx-%#llx "
"write_protect %#x
\n
"
,
(
unsigned
long
long
)
p
->
start
,
(
unsigned
long
long
)
p
->
end
,
fixed_memory32
->
write_protect
);
}
int
pnpacpi_encode_resources
(
struct
pnp_resource_table
*
res_table
,
struct
acpi_buffer
*
buffer
)
int
pnpacpi_encode_resources
(
struct
pnp_dev
*
dev
,
struct
acpi_buffer
*
buffer
)
{
int
i
=
0
;
/* pnpacpi_build_resource_template allocates extra mem */
...
...
@@ -924,58 +968,48 @@ int pnpacpi_encode_resources(struct pnp_resource_table *res_table,
struct
acpi_resource
*
resource
=
buffer
->
pointer
;
int
port
=
0
,
irq
=
0
,
dma
=
0
,
mem
=
0
;
pnp_dbg
(
"res cnt %d
"
,
res_cnt
);
dev_dbg
(
&
dev
->
dev
,
"encode %d resources
\n
"
,
res_cnt
);
while
(
i
<
res_cnt
)
{
switch
(
resource
->
type
)
{
case
ACPI_RESOURCE_TYPE_IRQ
:
pnp_dbg
(
"Encode irq"
);
pnpacpi_encode_irq
(
resource
,
&
res_table
->
irq_resource
[
irq
]);
pnpacpi_encode_irq
(
dev
,
resource
,
pnp_get_resource
(
dev
,
IORESOURCE_IRQ
,
irq
));
irq
++
;
break
;
case
ACPI_RESOURCE_TYPE_DMA
:
pnp_dbg
(
"Encode dma"
);
pnpacpi_encode_dma
(
resource
,
&
res_table
->
dma_resource
[
dma
]);
pnpacpi_encode_dma
(
dev
,
resource
,
pnp_get_resource
(
dev
,
IORESOURCE_DMA
,
dma
));
dma
++
;
break
;
case
ACPI_RESOURCE_TYPE_IO
:
pnp_dbg
(
"Encode io"
);
pnpacpi_encode_io
(
resource
,
&
res_table
->
port_resource
[
port
]);
pnpacpi_encode_io
(
dev
,
resource
,
pnp_get_resource
(
dev
,
IORESOURCE_IO
,
port
));
port
++
;
break
;
case
ACPI_RESOURCE_TYPE_FIXED_IO
:
pnp_dbg
(
"Encode fixed io"
);
pnpacpi_encode_fixed_io
(
resource
,
&
res_table
->
port_resource
[
port
]);
pnpacpi_encode_fixed_io
(
dev
,
resource
,
pnp_get_resource
(
dev
,
IORESOURCE_IO
,
port
));
port
++
;
break
;
case
ACPI_RESOURCE_TYPE_MEMORY24
:
pnp_dbg
(
"Encode mem24"
);
pnpacpi_encode_mem24
(
resource
,
&
res_table
->
mem_resource
[
mem
]);
pnpacpi_encode_mem24
(
dev
,
resource
,
pnp_get_resource
(
dev
,
IORESOURCE_MEM
,
mem
));
mem
++
;
break
;
case
ACPI_RESOURCE_TYPE_MEMORY32
:
pnp_dbg
(
"Encode mem32"
);
pnpacpi_encode_mem32
(
resource
,
&
res_table
->
mem_resource
[
mem
]);
pnpacpi_encode_mem32
(
dev
,
resource
,
pnp_get_resource
(
dev
,
IORESOURCE_MEM
,
mem
));
mem
++
;
break
;
case
ACPI_RESOURCE_TYPE_FIXED_MEMORY32
:
pnp_dbg
(
"Encode fixed mem32"
);
pnpacpi_encode_fixed_mem32
(
resource
,
&
res_table
->
mem_resource
[
mem
]);
pnpacpi_encode_fixed_mem32
(
dev
,
resource
,
pnp_get_resource
(
dev
,
IORESOURCE_MEM
,
mem
));
mem
++
;
break
;
case
ACPI_RESOURCE_TYPE_EXTENDED_IRQ
:
pnp_dbg
(
"Encode ext irq"
);
pnpacpi_encode_ext_irq
(
resource
,
&
res_table
->
irq_resource
[
irq
]);
pnpacpi_encode_ext_irq
(
dev
,
resource
,
pnp_get_resource
(
dev
,
IORESOURCE_IRQ
,
irq
));
irq
++
;
break
;
case
ACPI_RESOURCE_TYPE_START_DEPENDENT
:
...
...
@@ -988,7 +1022,8 @@ int pnpacpi_encode_resources(struct pnp_resource_table *res_table,
case
ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64
:
case
ACPI_RESOURCE_TYPE_GENERIC_REGISTER
:
default:
/* other type */
pnp_warn
(
"unknown resource type %d"
,
resource
->
type
);
dev_warn
(
&
dev
->
dev
,
"can't encode unknown resource "
"type %d
\n
"
,
resource
->
type
);
return
-
EINVAL
;
}
resource
++
;
...
...
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
...
...
@@ -4,7 +4,6 @@
#include <linux/ctype.h>
#include <linux/pnp.h>
#include <linux/pnpbios.h>
#include <linux/string.h>
#include <linux/slab.h>
...
...
@@ -16,6 +15,7 @@ inline void pcibios_penalize_isa_irq(int irq, int active)
}
#endif
/* CONFIG_PCI */
#include "../base.h"
#include "pnpbios.h"
/* standard resource tags */
...
...
@@ -53,97 +53,43 @@ inline void pcibios_penalize_isa_irq(int irq, int active)
* Allocated Resources
*/
static
void
pnpbios_parse_allocated_i
rqresource
(
struct
pnp_resource_table
*
res
,
int
irq
)
static
void
pnpbios_parse_allocated_i
oresource
(
struct
pnp_dev
*
dev
,
int
start
,
int
len
)
{
int
i
=
0
;
while
(
!
(
res
->
irq_resource
[
i
].
flags
&
IORESOURCE_UNSET
)
&&
i
<
PNP_MAX_IRQ
)
i
++
;
if
(
i
<
PNP_MAX_IRQ
)
{
res
->
irq_resource
[
i
].
flags
=
IORESOURCE_IRQ
;
// Also clears _UNSET flag
if
(
irq
==
-
1
)
{
res
->
irq_resource
[
i
].
flags
|=
IORESOURCE_DISABLED
;
return
;
}
res
->
irq_resource
[
i
].
start
=
res
->
irq_resource
[
i
].
end
=
(
unsigned
long
)
irq
;
pcibios_penalize_isa_irq
(
irq
,
1
);
}
}
int
flags
=
0
;
int
end
=
start
+
len
-
1
;
static
void
pnpbios_parse_allocated_dmaresource
(
struct
pnp_resource_table
*
res
,
int
dma
)
{
int
i
=
0
;
while
(
i
<
PNP_MAX_DMA
&&
!
(
res
->
dma_resource
[
i
].
flags
&
IORESOURCE_UNSET
))
i
++
;
if
(
i
<
PNP_MAX_DMA
)
{
res
->
dma_resource
[
i
].
flags
=
IORESOURCE_DMA
;
// Also clears _UNSET flag
if
(
dma
==
-
1
)
{
res
->
dma_resource
[
i
].
flags
|=
IORESOURCE_DISABLED
;
return
;
}
res
->
dma_resource
[
i
].
start
=
res
->
dma_resource
[
i
].
end
=
(
unsigned
long
)
dma
;
}
}
if
(
len
<=
0
||
end
>=
0x10003
)
flags
|=
IORESOURCE_DISABLED
;
static
void
pnpbios_parse_allocated_ioresource
(
struct
pnp_resource_table
*
res
,
int
io
,
int
len
)
{
int
i
=
0
;
while
(
!
(
res
->
port_resource
[
i
].
flags
&
IORESOURCE_UNSET
)
&&
i
<
PNP_MAX_PORT
)
i
++
;
if
(
i
<
PNP_MAX_PORT
)
{
res
->
port_resource
[
i
].
flags
=
IORESOURCE_IO
;
// Also clears _UNSET flag
if
(
len
<=
0
||
(
io
+
len
-
1
)
>=
0x10003
)
{
res
->
port_resource
[
i
].
flags
|=
IORESOURCE_DISABLED
;
return
;
}
res
->
port_resource
[
i
].
start
=
(
unsigned
long
)
io
;
res
->
port_resource
[
i
].
end
=
(
unsigned
long
)(
io
+
len
-
1
);
}
pnp_add_io_resource
(
dev
,
start
,
end
,
flags
);
}
static
void
pnpbios_parse_allocated_memresource
(
struct
pnp_
resource_table
*
res
,
int
mem
,
int
len
)
static
void
pnpbios_parse_allocated_memresource
(
struct
pnp_
dev
*
dev
,
int
start
,
int
len
)
{
int
i
=
0
;
while
(
!
(
res
->
mem_resource
[
i
].
flags
&
IORESOURCE_UNSET
)
&&
i
<
PNP_MAX_MEM
)
i
++
;
if
(
i
<
PNP_MAX_MEM
)
{
res
->
mem_resource
[
i
].
flags
=
IORESOURCE_MEM
;
// Also clears _UNSET flag
if
(
len
<=
0
)
{
res
->
mem_resource
[
i
].
flags
|=
IORESOURCE_DISABLED
;
return
;
}
res
->
mem_resource
[
i
].
start
=
(
unsigned
long
)
mem
;
res
->
mem_resource
[
i
].
end
=
(
unsigned
long
)(
mem
+
len
-
1
);
}
int
flags
=
0
;
int
end
=
start
+
len
-
1
;
if
(
len
<=
0
)
flags
|=
IORESOURCE_DISABLED
;
pnp_add_mem_resource
(
dev
,
start
,
end
,
flags
);
}
static
unsigned
char
*
pnpbios_parse_allocated_resource_data
(
unsigned
char
*
p
,
unsigned
char
*
end
,
struct
pnp_resource_table
*
res
)
static
unsigned
char
*
pnpbios_parse_allocated_resource_data
(
struct
pnp_dev
*
dev
,
unsigned
char
*
p
,
unsigned
char
*
end
)
{
unsigned
int
len
,
tag
;
int
io
,
size
,
mask
,
i
;
int
io
,
size
,
mask
,
i
,
flags
;
if
(
!
p
)
return
NULL
;
/* Blank the resource table values */
pnp_init_resource_table
(
res
);
dev_dbg
(
&
dev
->
dev
,
"parse allocated resources
\n
"
);
pnp_init_resources
(
dev
);
while
((
char
*
)
p
<
(
char
*
)
end
)
{
...
...
@@ -163,7 +109,7 @@ static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p,
goto
len_err
;
io
=
*
(
short
*
)
&
p
[
4
];
size
=
*
(
short
*
)
&
p
[
10
];
pnpbios_parse_allocated_memresource
(
res
,
io
,
size
);
pnpbios_parse_allocated_memresource
(
dev
,
io
,
size
);
break
;
case
LARGE_TAG_ANSISTR
:
...
...
@@ -179,7 +125,7 @@ static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p,
goto
len_err
;
io
=
*
(
int
*
)
&
p
[
4
];
size
=
*
(
int
*
)
&
p
[
16
];
pnpbios_parse_allocated_memresource
(
res
,
io
,
size
);
pnpbios_parse_allocated_memresource
(
dev
,
io
,
size
);
break
;
case
LARGE_TAG_FIXEDMEM32
:
...
...
@@ -187,29 +133,37 @@ static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p,
goto
len_err
;
io
=
*
(
int
*
)
&
p
[
4
];
size
=
*
(
int
*
)
&
p
[
8
];
pnpbios_parse_allocated_memresource
(
res
,
io
,
size
);
pnpbios_parse_allocated_memresource
(
dev
,
io
,
size
);
break
;
case
SMALL_TAG_IRQ
:
if
(
len
<
2
||
len
>
3
)
goto
len_err
;
flags
=
0
;
io
=
-
1
;
mask
=
p
[
1
]
+
p
[
2
]
*
256
;
for
(
i
=
0
;
i
<
16
;
i
++
,
mask
=
mask
>>
1
)
if
(
mask
&
0x01
)
io
=
i
;
pnpbios_parse_allocated_irqresource
(
res
,
io
);
if
(
io
!=
-
1
)
pcibios_penalize_isa_irq
(
io
,
1
);
else
flags
=
IORESOURCE_DISABLED
;
pnp_add_irq_resource
(
dev
,
io
,
flags
);
break
;
case
SMALL_TAG_DMA
:
if
(
len
!=
2
)
goto
len_err
;
flags
=
0
;
io
=
-
1
;
mask
=
p
[
1
];
for
(
i
=
0
;
i
<
8
;
i
++
,
mask
=
mask
>>
1
)
if
(
mask
&
0x01
)
io
=
i
;
pnpbios_parse_allocated_dmaresource
(
res
,
io
);
if
(
io
==
-
1
)
flags
=
IORESOURCE_DISABLED
;
pnp_add_dma_resource
(
dev
,
io
,
flags
);
break
;
case
SMALL_TAG_PORT
:
...
...
@@ -217,7 +171,7 @@ static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p,
goto
len_err
;
io
=
p
[
2
]
+
p
[
3
]
*
256
;
size
=
p
[
7
];
pnpbios_parse_allocated_ioresource
(
res
,
io
,
size
);
pnpbios_parse_allocated_ioresource
(
dev
,
io
,
size
);
break
;
case
SMALL_TAG_VENDOR
:
...
...
@@ -229,7 +183,7 @@ static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p,
goto
len_err
;
io
=
p
[
1
]
+
p
[
2
]
*
256
;
size
=
p
[
3
];
pnpbios_parse_allocated_ioresource
(
res
,
io
,
size
);
pnpbios_parse_allocated_ioresource
(
dev
,
io
,
size
);
break
;
case
SMALL_TAG_END
:
...
...
@@ -239,9 +193,8 @@ static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p,
default:
/* an unkown tag */
len_err:
printk
(
KERN_ERR
"PnPBIOS: Unknown tag '0x%x', length '%d'.
\n
"
,
tag
,
len
);
dev_err
(
&
dev
->
dev
,
"unknown tag %#x length %d
\n
"
,
tag
,
len
);
break
;
}
...
...
@@ -252,8 +205,7 @@ static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p,
p
+=
len
+
1
;
}
printk
(
KERN_ERR
"PnPBIOS: Resource structure does not contain an end tag.
\n
"
);
dev_err
(
&
dev
->
dev
,
"no end tag in resource structure
\n
"
);
return
NULL
;
}
...
...
@@ -262,7 +214,8 @@ static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p,
* Resource Configuration Options
*/
static
__init
void
pnpbios_parse_mem_option
(
unsigned
char
*
p
,
int
size
,
static
__init
void
pnpbios_parse_mem_option
(
struct
pnp_dev
*
dev
,
unsigned
char
*
p
,
int
size
,
struct
pnp_option
*
option
)
{
struct
pnp_mem
*
mem
;
...
...
@@ -275,10 +228,11 @@ static __init void pnpbios_parse_mem_option(unsigned char *p, int size,
mem
->
align
=
(
p
[
9
]
<<
8
)
|
p
[
8
];
mem
->
size
=
((
p
[
11
]
<<
8
)
|
p
[
10
])
<<
8
;
mem
->
flags
=
p
[
3
];
pnp_register_mem_resource
(
option
,
mem
);
pnp_register_mem_resource
(
dev
,
option
,
mem
);
}
static
__init
void
pnpbios_parse_mem32_option
(
unsigned
char
*
p
,
int
size
,
static
__init
void
pnpbios_parse_mem32_option
(
struct
pnp_dev
*
dev
,
unsigned
char
*
p
,
int
size
,
struct
pnp_option
*
option
)
{
struct
pnp_mem
*
mem
;
...
...
@@ -291,10 +245,11 @@ static __init void pnpbios_parse_mem32_option(unsigned char *p, int size,
mem
->
align
=
(
p
[
15
]
<<
24
)
|
(
p
[
14
]
<<
16
)
|
(
p
[
13
]
<<
8
)
|
p
[
12
];
mem
->
size
=
(
p
[
19
]
<<
24
)
|
(
p
[
18
]
<<
16
)
|
(
p
[
17
]
<<
8
)
|
p
[
16
];
mem
->
flags
=
p
[
3
];
pnp_register_mem_resource
(
option
,
mem
);
pnp_register_mem_resource
(
dev
,
option
,
mem
);
}
static
__init
void
pnpbios_parse_fixed_mem32_option
(
unsigned
char
*
p
,
int
size
,
static
__init
void
pnpbios_parse_fixed_mem32_option
(
struct
pnp_dev
*
dev
,
unsigned
char
*
p
,
int
size
,
struct
pnp_option
*
option
)
{
struct
pnp_mem
*
mem
;
...
...
@@ -306,11 +261,12 @@ static __init void pnpbios_parse_fixed_mem32_option(unsigned char *p, int size,
mem
->
size
=
(
p
[
11
]
<<
24
)
|
(
p
[
10
]
<<
16
)
|
(
p
[
9
]
<<
8
)
|
p
[
8
];
mem
->
align
=
0
;
mem
->
flags
=
p
[
3
];
pnp_register_mem_resource
(
option
,
mem
);
pnp_register_mem_resource
(
dev
,
option
,
mem
);
}
static
__init
void
pnpbios_parse_irq_option
(
unsigned
char
*
p
,
int
size
,
struct
pnp_option
*
option
)
static
__init
void
pnpbios_parse_irq_option
(
struct
pnp_dev
*
dev
,
unsigned
char
*
p
,
int
size
,
struct
pnp_option
*
option
)
{
struct
pnp_irq
*
irq
;
unsigned
long
bits
;
...
...
@@ -324,11 +280,12 @@ static __init void pnpbios_parse_irq_option(unsigned char *p, int size,
irq
->
flags
=
p
[
3
];
else
irq
->
flags
=
IORESOURCE_IRQ_HIGHEDGE
;
pnp_register_irq_resource
(
option
,
irq
);
pnp_register_irq_resource
(
dev
,
option
,
irq
);
}
static
__init
void
pnpbios_parse_dma_option
(
unsigned
char
*
p
,
int
size
,
struct
pnp_option
*
option
)
static
__init
void
pnpbios_parse_dma_option
(
struct
pnp_dev
*
dev
,
unsigned
char
*
p
,
int
size
,
struct
pnp_option
*
option
)
{
struct
pnp_dma
*
dma
;
...
...
@@ -337,10 +294,11 @@ static __init void pnpbios_parse_dma_option(unsigned char *p, int size,
return
;
dma
->
map
=
p
[
1
];
dma
->
flags
=
p
[
2
];
pnp_register_dma_resource
(
option
,
dma
);
pnp_register_dma_resource
(
dev
,
option
,
dma
);
}
static
__init
void
pnpbios_parse_port_option
(
unsigned
char
*
p
,
int
size
,
static
__init
void
pnpbios_parse_port_option
(
struct
pnp_dev
*
dev
,
unsigned
char
*
p
,
int
size
,
struct
pnp_option
*
option
)
{
struct
pnp_port
*
port
;
...
...
@@ -353,10 +311,11 @@ static __init void pnpbios_parse_port_option(unsigned char *p, int size,
port
->
align
=
p
[
6
];
port
->
size
=
p
[
7
];
port
->
flags
=
p
[
1
]
?
PNP_PORT_FLAG_16BITADDR
:
0
;
pnp_register_port_resource
(
option
,
port
);
pnp_register_port_resource
(
dev
,
option
,
port
);
}
static
__init
void
pnpbios_parse_fixed_port_option
(
unsigned
char
*
p
,
int
size
,
static
__init
void
pnpbios_parse_fixed_port_option
(
struct
pnp_dev
*
dev
,
unsigned
char
*
p
,
int
size
,
struct
pnp_option
*
option
)
{
struct
pnp_port
*
port
;
...
...
@@ -368,7 +327,7 @@ static __init void pnpbios_parse_fixed_port_option(unsigned char *p, int size,
port
->
size
=
p
[
3
];
port
->
align
=
0
;
port
->
flags
=
PNP_PORT_FLAG_FIXED
;
pnp_register_port_resource
(
option
,
port
);
pnp_register_port_resource
(
dev
,
option
,
port
);
}
static
__init
unsigned
char
*
...
...
@@ -382,6 +341,8 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
if
(
!
p
)
return
NULL
;
dev_dbg
(
&
dev
->
dev
,
"parse resource options
\n
"
);
option_independent
=
option
=
pnp_register_independent_option
(
dev
);
if
(
!
option
)
return
NULL
;
...
...
@@ -402,37 +363,37 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
case
LARGE_TAG_MEM
:
if
(
len
!=
9
)
goto
len_err
;
pnpbios_parse_mem_option
(
p
,
len
,
option
);
pnpbios_parse_mem_option
(
dev
,
p
,
len
,
option
);
break
;
case
LARGE_TAG_MEM32
:
if
(
len
!=
17
)
goto
len_err
;
pnpbios_parse_mem32_option
(
p
,
len
,
option
);
pnpbios_parse_mem32_option
(
dev
,
p
,
len
,
option
);
break
;
case
LARGE_TAG_FIXEDMEM32
:
if
(
len
!=
9
)
goto
len_err
;
pnpbios_parse_fixed_mem32_option
(
p
,
len
,
option
);
pnpbios_parse_fixed_mem32_option
(
dev
,
p
,
len
,
option
);
break
;
case
SMALL_TAG_IRQ
:
if
(
len
<
2
||
len
>
3
)
goto
len_err
;
pnpbios_parse_irq_option
(
p
,
len
,
option
);
pnpbios_parse_irq_option
(
dev
,
p
,
len
,
option
);
break
;
case
SMALL_TAG_DMA
:
if
(
len
!=
2
)
goto
len_err
;
pnpbios_parse_dma_option
(
p
,
len
,
option
);
pnpbios_parse_dma_option
(
dev
,
p
,
len
,
option
);
break
;
case
SMALL_TAG_PORT
:
if
(
len
!=
7
)
goto
len_err
;
pnpbios_parse_port_option
(
p
,
len
,
option
);
pnpbios_parse_port_option
(
dev
,
p
,
len
,
option
);
break
;
case
SMALL_TAG_VENDOR
:
...
...
@@ -442,7 +403,7 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
case
SMALL_TAG_FIXEDPORT
:
if
(
len
!=
3
)
goto
len_err
;
pnpbios_parse_fixed_port_option
(
p
,
len
,
option
);
pnpbios_parse_fixed_port_option
(
dev
,
p
,
len
,
option
);
break
;
case
SMALL_TAG_STARTDEP
:
...
...
@@ -460,9 +421,10 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
if
(
len
!=
0
)
goto
len_err
;
if
(
option_independent
==
option
)
printk
(
KERN_WARNING
"PnPBIOS: Missing
SMALL_TAG_STARTDEP tag
\n
"
);
dev_warn
(
&
dev
->
dev
,
"missing "
"
SMALL_TAG_STARTDEP tag
\n
"
);
option
=
option_independent
;
dev_dbg
(
&
dev
->
dev
,
"end dependent options
\n
"
);
break
;
case
SMALL_TAG_END
:
...
...
@@ -470,9 +432,8 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
default:
/* an unkown tag */
len_err:
printk
(
KERN_ERR
"PnPBIOS: Unknown tag '0x%x', length '%d'.
\n
"
,
tag
,
len
);
dev_err
(
&
dev
->
dev
,
"unknown tag %#x length %d
\n
"
,
tag
,
len
);
break
;
}
...
...
@@ -483,8 +444,7 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
p
+=
len
+
1
;
}
printk
(
KERN_ERR
"PnPBIOS: Resource structure does not contain an end tag.
\n
"
);
dev_err
(
&
dev
->
dev
,
"no end tag in resource structure
\n
"
);
return
NULL
;
}
...
...
@@ -493,32 +453,12 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
* Compatible Device IDs
*/
#define HEX(id,a) hex[((id)>>a) & 15]
#define CHAR(id,a) (0x40 + (((id)>>a) & 31))
void
pnpid32_to_pnpid
(
u32
id
,
char
*
str
)
{
const
char
*
hex
=
"0123456789abcdef"
;
id
=
be32_to_cpu
(
id
);
str
[
0
]
=
CHAR
(
id
,
26
);
str
[
1
]
=
CHAR
(
id
,
21
);
str
[
2
]
=
CHAR
(
id
,
16
);
str
[
3
]
=
HEX
(
id
,
12
);
str
[
4
]
=
HEX
(
id
,
8
);
str
[
5
]
=
HEX
(
id
,
4
);
str
[
6
]
=
HEX
(
id
,
0
);
str
[
7
]
=
'\0'
;
}
#undef CHAR
#undef HEX
static
unsigned
char
*
pnpbios_parse_compatible_ids
(
unsigned
char
*
p
,
unsigned
char
*
end
,
struct
pnp_dev
*
dev
)
{
int
len
,
tag
;
u32
eisa_id
;
char
id
[
8
];
struct
pnp_id
*
dev_id
;
...
...
@@ -548,13 +488,11 @@ static unsigned char *pnpbios_parse_compatible_ids(unsigned char *p,
case
SMALL_TAG_COMPATDEVID
:
/* compatible ID */
if
(
len
!=
4
)
goto
len_err
;
dev_id
=
kzalloc
(
sizeof
(
struct
pnp_id
),
GFP_KERNEL
);
eisa_id
=
p
[
1
]
|
p
[
2
]
<<
8
|
p
[
3
]
<<
16
|
p
[
4
]
<<
24
;
pnp_eisa_id_to_string
(
eisa_id
&
PNP_EISA_ID_MASK
,
id
);
dev_id
=
pnp_add_id
(
dev
,
id
);
if
(
!
dev_id
)
return
NULL
;
pnpid32_to_pnpid
(
p
[
1
]
|
p
[
2
]
<<
8
|
p
[
3
]
<<
16
|
p
[
4
]
<<
24
,
id
);
memcpy
(
&
dev_id
->
id
,
id
,
7
);
pnp_add_id
(
dev_id
,
dev
);
break
;
case
SMALL_TAG_END
:
...
...
@@ -564,9 +502,8 @@ static unsigned char *pnpbios_parse_compatible_ids(unsigned char *p,
default:
/* an unkown tag */
len_err:
printk
(
KERN_ERR
"PnPBIOS: Unknown tag '0x%x', length '%d'.
\n
"
,
tag
,
len
);
dev_err
(
&
dev
->
dev
,
"unknown tag %#x length %d
\n
"
,
tag
,
len
);
break
;
}
...
...
@@ -577,8 +514,7 @@ static unsigned char *pnpbios_parse_compatible_ids(unsigned char *p,
p
+=
len
+
1
;
}
printk
(
KERN_ERR
"PnPBIOS: Resource structure does not contain an end tag.
\n
"
);
dev_err
(
&
dev
->
dev
,
"no end tag in resource structure
\n
"
);
return
NULL
;
}
...
...
@@ -587,7 +523,8 @@ static unsigned char *pnpbios_parse_compatible_ids(unsigned char *p,
* Allocated Resource Encoding
*/
static
void
pnpbios_encode_mem
(
unsigned
char
*
p
,
struct
resource
*
res
)
static
void
pnpbios_encode_mem
(
struct
pnp_dev
*
dev
,
unsigned
char
*
p
,
struct
resource
*
res
)
{
unsigned
long
base
=
res
->
start
;
unsigned
long
len
=
res
->
end
-
res
->
start
+
1
;
...
...
@@ -598,9 +535,13 @@ static void pnpbios_encode_mem(unsigned char *p, struct resource *res)
p
[
7
]
=
((
base
>>
8
)
>>
8
)
&
0xff
;
p
[
10
]
=
(
len
>>
8
)
&
0xff
;
p
[
11
]
=
((
len
>>
8
)
>>
8
)
&
0xff
;
dev_dbg
(
&
dev
->
dev
,
" encode mem %#llx-%#llx
\n
"
,
(
unsigned
long
long
)
res
->
start
,
(
unsigned
long
long
)
res
->
end
);
}
static
void
pnpbios_encode_mem32
(
unsigned
char
*
p
,
struct
resource
*
res
)
static
void
pnpbios_encode_mem32
(
struct
pnp_dev
*
dev
,
unsigned
char
*
p
,
struct
resource
*
res
)
{
unsigned
long
base
=
res
->
start
;
unsigned
long
len
=
res
->
end
-
res
->
start
+
1
;
...
...
@@ -617,9 +558,13 @@ static void pnpbios_encode_mem32(unsigned char *p, struct resource *res)
p
[
17
]
=
(
len
>>
8
)
&
0xff
;
p
[
18
]
=
(
len
>>
16
)
&
0xff
;
p
[
19
]
=
(
len
>>
24
)
&
0xff
;
dev_dbg
(
&
dev
->
dev
,
" encode mem32 %#llx-%#llx
\n
"
,
(
unsigned
long
long
)
res
->
start
,
(
unsigned
long
long
)
res
->
end
);
}
static
void
pnpbios_encode_fixed_mem32
(
unsigned
char
*
p
,
struct
resource
*
res
)
static
void
pnpbios_encode_fixed_mem32
(
struct
pnp_dev
*
dev
,
unsigned
char
*
p
,
struct
resource
*
res
)
{
unsigned
long
base
=
res
->
start
;
unsigned
long
len
=
res
->
end
-
res
->
start
+
1
;
...
...
@@ -632,26 +577,36 @@ static void pnpbios_encode_fixed_mem32(unsigned char *p, struct resource *res)
p
[
9
]
=
(
len
>>
8
)
&
0xff
;
p
[
10
]
=
(
len
>>
16
)
&
0xff
;
p
[
11
]
=
(
len
>>
24
)
&
0xff
;
dev_dbg
(
&
dev
->
dev
,
" encode fixed_mem32 %#llx-%#llx
\n
"
,
(
unsigned
long
long
)
res
->
start
,
(
unsigned
long
long
)
res
->
end
);
}
static
void
pnpbios_encode_irq
(
unsigned
char
*
p
,
struct
resource
*
res
)
static
void
pnpbios_encode_irq
(
struct
pnp_dev
*
dev
,
unsigned
char
*
p
,
struct
resource
*
res
)
{
unsigned
long
map
=
0
;
map
=
1
<<
res
->
start
;
p
[
1
]
=
map
&
0xff
;
p
[
2
]
=
(
map
>>
8
)
&
0xff
;
dev_dbg
(
&
dev
->
dev
,
" encode irq %d
\n
"
,
res
->
start
);
}
static
void
pnpbios_encode_dma
(
unsigned
char
*
p
,
struct
resource
*
res
)
static
void
pnpbios_encode_dma
(
struct
pnp_dev
*
dev
,
unsigned
char
*
p
,
struct
resource
*
res
)
{
unsigned
long
map
=
0
;
map
=
1
<<
res
->
start
;
p
[
1
]
=
map
&
0xff
;
dev_dbg
(
&
dev
->
dev
,
" encode dma %d
\n
"
,
res
->
start
);
}
static
void
pnpbios_encode_port
(
unsigned
char
*
p
,
struct
resource
*
res
)
static
void
pnpbios_encode_port
(
struct
pnp_dev
*
dev
,
unsigned
char
*
p
,
struct
resource
*
res
)
{
unsigned
long
base
=
res
->
start
;
unsigned
long
len
=
res
->
end
-
res
->
start
+
1
;
...
...
@@ -661,9 +616,13 @@ static void pnpbios_encode_port(unsigned char *p, struct resource *res)
p
[
4
]
=
base
&
0xff
;
p
[
5
]
=
(
base
>>
8
)
&
0xff
;
p
[
7
]
=
len
&
0xff
;
dev_dbg
(
&
dev
->
dev
,
" encode io %#llx-%#llx
\n
"
,
(
unsigned
long
long
)
res
->
start
,
(
unsigned
long
long
)
res
->
end
);
}
static
void
pnpbios_encode_fixed_port
(
unsigned
char
*
p
,
struct
resource
*
res
)
static
void
pnpbios_encode_fixed_port
(
struct
pnp_dev
*
dev
,
unsigned
char
*
p
,
struct
resource
*
res
)
{
unsigned
long
base
=
res
->
start
;
unsigned
long
len
=
res
->
end
-
res
->
start
+
1
;
...
...
@@ -671,13 +630,15 @@ static void pnpbios_encode_fixed_port(unsigned char *p, struct resource *res)
p
[
1
]
=
base
&
0xff
;
p
[
2
]
=
(
base
>>
8
)
&
0xff
;
p
[
3
]
=
len
&
0xff
;
dev_dbg
(
&
dev
->
dev
,
" encode fixed_io %#llx-%#llx
\n
"
,
(
unsigned
long
long
)
res
->
start
,
(
unsigned
long
long
)
res
->
end
);
}
static
unsigned
char
*
pnpbios_encode_allocated_resource_data
(
unsigned
char
*
p
,
unsigned
char
*
end
,
struct
pnp_resource_table
*
res
)
static
unsigned
char
*
pnpbios_encode_allocated_resource_data
(
struct
pnp_dev
*
dev
,
unsigned
char
*
p
,
unsigned
char
*
end
)
{
unsigned
int
len
,
tag
;
int
port
=
0
,
irq
=
0
,
dma
=
0
,
mem
=
0
;
...
...
@@ -701,42 +662,48 @@ static unsigned char *pnpbios_encode_allocated_resource_data(unsigned char *p,
case
LARGE_TAG_MEM
:
if
(
len
!=
9
)
goto
len_err
;
pnpbios_encode_mem
(
p
,
&
res
->
mem_resource
[
mem
]);
pnpbios_encode_mem
(
dev
,
p
,
pnp_get_resource
(
dev
,
IORESOURCE_MEM
,
mem
));
mem
++
;
break
;
case
LARGE_TAG_MEM32
:
if
(
len
!=
17
)
goto
len_err
;
pnpbios_encode_mem32
(
p
,
&
res
->
mem_resource
[
mem
]);
pnpbios_encode_mem32
(
dev
,
p
,
pnp_get_resource
(
dev
,
IORESOURCE_MEM
,
mem
));
mem
++
;
break
;
case
LARGE_TAG_FIXEDMEM32
:
if
(
len
!=
9
)
goto
len_err
;
pnpbios_encode_fixed_mem32
(
p
,
&
res
->
mem_resource
[
mem
]);
pnpbios_encode_fixed_mem32
(
dev
,
p
,
pnp_get_resource
(
dev
,
IORESOURCE_MEM
,
mem
));
mem
++
;
break
;
case
SMALL_TAG_IRQ
:
if
(
len
<
2
||
len
>
3
)
goto
len_err
;
pnpbios_encode_irq
(
p
,
&
res
->
irq_resource
[
irq
]);
pnpbios_encode_irq
(
dev
,
p
,
pnp_get_resource
(
dev
,
IORESOURCE_IRQ
,
irq
));
irq
++
;
break
;
case
SMALL_TAG_DMA
:
if
(
len
!=
2
)
goto
len_err
;
pnpbios_encode_dma
(
p
,
&
res
->
dma_resource
[
dma
]);
pnpbios_encode_dma
(
dev
,
p
,
pnp_get_resource
(
dev
,
IORESOURCE_DMA
,
dma
));
dma
++
;
break
;
case
SMALL_TAG_PORT
:
if
(
len
!=
7
)
goto
len_err
;
pnpbios_encode_port
(
p
,
&
res
->
port_resource
[
port
]);
pnpbios_encode_port
(
dev
,
p
,
pnp_get_resource
(
dev
,
IORESOURCE_IO
,
port
));
port
++
;
break
;
...
...
@@ -747,7 +714,8 @@ static unsigned char *pnpbios_encode_allocated_resource_data(unsigned char *p,
case
SMALL_TAG_FIXEDPORT
:
if
(
len
!=
3
)
goto
len_err
;
pnpbios_encode_fixed_port
(
p
,
&
res
->
port_resource
[
port
]);
pnpbios_encode_fixed_port
(
dev
,
p
,
pnp_get_resource
(
dev
,
IORESOURCE_IO
,
port
));
port
++
;
break
;
...
...
@@ -758,9 +726,8 @@ static unsigned char *pnpbios_encode_allocated_resource_data(unsigned char *p,
default:
/* an unkown tag */
len_err:
printk
(
KERN_ERR
"PnPBIOS: Unknown tag '0x%x', length '%d'.
\n
"
,
tag
,
len
);
dev_err
(
&
dev
->
dev
,
"unknown tag %#x length %d
\n
"
,
tag
,
len
);
break
;
}
...
...
@@ -771,8 +738,7 @@ static unsigned char *pnpbios_encode_allocated_resource_data(unsigned char *p,
p
+=
len
+
1
;
}
printk
(
KERN_ERR
"PnPBIOS: Resource structure does not contain an end tag.
\n
"
);
dev_err
(
&
dev
->
dev
,
"no end tag in resource structure
\n
"
);
return
NULL
;
}
...
...
@@ -787,7 +753,7 @@ int __init pnpbios_parse_data_stream(struct pnp_dev *dev,
unsigned
char
*
p
=
(
char
*
)
node
->
data
;
unsigned
char
*
end
=
(
char
*
)(
node
->
data
+
node
->
size
);
p
=
pnpbios_parse_allocated_resource_data
(
p
,
end
,
&
dev
->
res
);
p
=
pnpbios_parse_allocated_resource_data
(
dev
,
p
,
end
);
if
(
!
p
)
return
-
EIO
;
p
=
pnpbios_parse_resource_option_data
(
p
,
end
,
dev
);
...
...
@@ -799,25 +765,25 @@ int __init pnpbios_parse_data_stream(struct pnp_dev *dev,
return
0
;
}
int
pnpbios_read_resources_from_node
(
struct
pnp_
resource_table
*
res
,
int
pnpbios_read_resources_from_node
(
struct
pnp_
dev
*
dev
,
struct
pnp_bios_node
*
node
)
{
unsigned
char
*
p
=
(
char
*
)
node
->
data
;
unsigned
char
*
end
=
(
char
*
)(
node
->
data
+
node
->
size
);
p
=
pnpbios_parse_allocated_resource_data
(
p
,
end
,
res
);
p
=
pnpbios_parse_allocated_resource_data
(
dev
,
p
,
end
);
if
(
!
p
)
return
-
EIO
;
return
0
;
}
int
pnpbios_write_resources_to_node
(
struct
pnp_
resource_table
*
res
,
int
pnpbios_write_resources_to_node
(
struct
pnp_
dev
*
dev
,
struct
pnp_bios_node
*
node
)
{
unsigned
char
*
p
=
(
char
*
)
node
->
data
;
unsigned
char
*
end
=
(
char
*
)(
node
->
data
+
node
->
size
);
p
=
pnpbios_encode_allocated_resource_data
(
p
,
end
,
res
);
p
=
pnpbios_encode_allocated_resource_data
(
dev
,
p
,
end
);
if
(
!
p
)
return
-
EIO
;
return
0
;
...
...
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.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录