Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
008238b5
Commit
008238b5
authored
Apr 30, 2008
by
Len Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'pnp' into release
parents
96916090
dfd2e1b4
Changes
26
Hide whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
1689 additions
and
1356 deletions
+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
No files found.
drivers/pnp/base.h
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
deleted
100644 → 0
View file @
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 */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment