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
0d716f8c
Commit
0d716f8c
authored
Feb 19, 2003
by
Adam Belay
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Preparations and Cleanups
Required for the remaining patches in this series.
parent
0dd22e54
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
584 additions
and
777 deletions
+584
-777
drivers/pnp/Makefile
drivers/pnp/Makefile
+1
-2
drivers/pnp/base.h
drivers/pnp/base.h
+30
-7
drivers/pnp/card.c
drivers/pnp/card.c
+4
-5
drivers/pnp/core.c
drivers/pnp/core.c
+12
-14
drivers/pnp/driver.c
drivers/pnp/driver.c
+2
-2
drivers/pnp/names.c
drivers/pnp/names.c
+1
-1
drivers/pnp/quirks.c
drivers/pnp/quirks.c
+4
-4
drivers/pnp/resource.c
drivers/pnp/resource.c
+325
-546
drivers/pnp/system.c
drivers/pnp/system.c
+1
-1
drivers/serial/8250_pnp.c
drivers/serial/8250_pnp.c
+3
-3
include/linux/ioport.h
include/linux/ioport.h
+1
-0
include/linux/pnp.h
include/linux/pnp.h
+200
-192
No files found.
drivers/pnp/Makefile
View file @
0d716f8c
...
@@ -4,8 +4,7 @@
...
@@ -4,8 +4,7 @@
pnp-card-$(CONFIG_PNP_CARD)
=
card.o
pnp-card-$(CONFIG_PNP_CARD)
=
card.o
obj-y
:=
core.o driver.o resource.o interface.o quirks.o names.o system.o
$
(
pnp-card-y
)
obj-y
:=
core.o driver.o resource.o
manager.o support.o
interface.o quirks.o names.o system.o
$
(
pnp-card-y
)
obj-$(CONFIG_PNPBIOS)
+=
pnpbios/
obj-$(CONFIG_PNPBIOS)
+=
pnpbios/
obj-$(CONFIG_ISAPNP)
+=
isapnp/
obj-$(CONFIG_ISAPNP)
+=
isapnp/
drivers/pnp/base.h
View file @
0d716f8c
extern
struct
bus_type
pnp_bus_type
;
extern
struct
bus_type
pnp_bus_type
;
extern
spinlock_t
pnp_lock
;
extern
spinlock_t
pnp_lock
;
extern
void
*
pnp_alloc
(
long
size
);
void
*
pnp_alloc
(
long
size
);
extern
int
pnp_interface_attach_device
(
struct
pnp_dev
*
dev
);
int
pnp_interface_attach_device
(
struct
pnp_dev
*
dev
);
extern
void
pnp_name_device
(
struct
pnp_dev
*
dev
);
void
pnp_name_device
(
struct
pnp_dev
*
dev
);
extern
void
pnp_fixup_device
(
struct
pnp_dev
*
dev
);
void
pnp_fixup_device
(
struct
pnp_dev
*
dev
);
extern
void
pnp_free_resources
(
struct
pnp_resources
*
resources
);
void
pnp_free_resources
(
struct
pnp_resources
*
resources
);
extern
int
__pnp_add_device
(
struct
pnp_dev
*
dev
);
int
__pnp_add_device
(
struct
pnp_dev
*
dev
);
extern
void
__pnp_remove_device
(
struct
pnp_dev
*
dev
);
void
__pnp_remove_device
(
struct
pnp_dev
*
dev
);
/* resource conflict types */
#define CONFLICT_TYPE_NONE 0x0000
/* there are no conflicts, other than those in the link */
#define CONFLICT_TYPE_RESERVED 0x0001
/* the resource requested was reserved */
#define CONFLICT_TYPE_IN_USE 0x0002
/* there is a conflict because the resource is in use */
#define CONFLICT_TYPE_PCI 0x0004
/* there is a conflict with a pci device */
#define CONFLICT_TYPE_INVALID 0x0008
/* the resource requested is invalid */
#define CONFLICT_TYPE_INTERNAL 0x0010
/* resources within the device conflict with each ohter */
#define CONFLICT_TYPE_PNP_WARM 0x0020
/* there is a conflict with a pnp device that is active */
#define CONFLICT_TYPE_PNP_COLD 0x0040
/* there is a conflict with a pnp device that is disabled */
/* conflict search modes */
#define SEARCH_WARM 1
/* check for conflicts with active devices */
#define SEARCH_COLD 0
/* check for conflicts with disabled devices */
struct
pnp_dev
*
pnp_check_port_conflicts
(
struct
pnp_dev
*
dev
,
int
idx
,
int
mode
);
int
pnp_check_port
(
struct
pnp_dev
*
dev
,
int
idx
);
struct
pnp_dev
*
pnp_check_mem_conflicts
(
struct
pnp_dev
*
dev
,
int
idx
,
int
mode
);
int
pnp_check_mem
(
struct
pnp_dev
*
dev
,
int
idx
);
struct
pnp_dev
*
pnp_check_irq_conflicts
(
struct
pnp_dev
*
dev
,
int
idx
,
int
mode
);
int
pnp_check_irq
(
struct
pnp_dev
*
dev
,
int
idx
);
struct
pnp_dev
*
pnp_check_dma_conflicts
(
struct
pnp_dev
*
dev
,
int
idx
,
int
mode
);
int
pnp_check_dma
(
struct
pnp_dev
*
dev
,
int
idx
);
drivers/pnp/card.c
View file @
0d716f8c
...
@@ -22,9 +22,9 @@
...
@@ -22,9 +22,9 @@
LIST_HEAD
(
pnp_cards
);
LIST_HEAD
(
pnp_cards
);
static
const
struct
pnp_card_
device_
id
*
match_card
(
struct
pnpc_driver
*
drv
,
struct
pnp_card
*
card
)
static
const
struct
pnp_card_id
*
match_card
(
struct
pnpc_driver
*
drv
,
struct
pnp_card
*
card
)
{
{
const
struct
pnp_card_
device_
id
*
drv_id
=
drv
->
id_table
;
const
struct
pnp_card_id
*
drv_id
=
drv
->
id_table
;
while
(
*
drv_id
->
id
){
while
(
*
drv_id
->
id
){
if
(
compare_pnp_id
(
card
->
id
,
drv_id
->
id
))
if
(
compare_pnp_id
(
card
->
id
,
drv_id
->
id
))
return
drv_id
;
return
drv_id
;
...
@@ -106,7 +106,6 @@ int pnpc_add_card(struct pnp_card *card)
...
@@ -106,7 +106,6 @@ int pnpc_add_card(struct pnp_card *card)
return
-
EINVAL
;
return
-
EINVAL
;
sprintf
(
card
->
dev
.
bus_id
,
"%02x:%02x"
,
card
->
protocol
->
number
,
card
->
number
);
sprintf
(
card
->
dev
.
bus_id
,
"%02x:%02x"
,
card
->
protocol
->
number
,
card
->
number
);
INIT_LIST_HEAD
(
&
card
->
rdevs
);
INIT_LIST_HEAD
(
&
card
->
rdevs
);
strcpy
(
card
->
dev
.
name
,
card
->
name
);
card
->
dev
.
parent
=
&
card
->
protocol
->
dev
;
card
->
dev
.
parent
=
&
card
->
protocol
->
dev
;
card
->
dev
.
bus
=
&
pnpc_bus_type
;
card
->
dev
.
bus
=
&
pnpc_bus_type
;
card
->
dev
.
release
=
&
pnp_release_card
;
card
->
dev
.
release
=
&
pnp_release_card
;
...
@@ -221,7 +220,7 @@ struct pnp_dev * pnp_request_card_device(struct pnp_card *card, const char *id,
...
@@ -221,7 +220,7 @@ struct pnp_dev * pnp_request_card_device(struct pnp_card *card, const char *id,
cdrv
=
to_pnpc_driver
(
card
->
dev
.
driver
);
cdrv
=
to_pnpc_driver
(
card
->
dev
.
driver
);
if
(
dev
->
active
==
0
)
{
if
(
dev
->
active
==
0
)
{
if
(
!
(
cdrv
->
flags
&
PNPC_DRIVER_DO_NOT_ACTIVATE
))
{
if
(
!
(
cdrv
->
flags
&
PNPC_DRIVER_DO_NOT_ACTIVATE
))
{
if
(
pnp_activate_dev
(
dev
,
NULL
)
<
0
)
{
if
(
pnp_activate_dev
(
dev
)
<
0
)
{
pnp_device_detach
(
dev
);
pnp_device_detach
(
dev
);
return
NULL
;
return
NULL
;
}
}
...
@@ -286,7 +285,7 @@ static int pnpc_card_probe(struct device *dev)
...
@@ -286,7 +285,7 @@ static int pnpc_card_probe(struct device *dev)
int
error
=
0
;
int
error
=
0
;
struct
pnpc_driver
*
drv
=
to_pnpc_driver
(
dev
->
driver
);
struct
pnpc_driver
*
drv
=
to_pnpc_driver
(
dev
->
driver
);
struct
pnp_card
*
card
=
to_pnp_card
(
dev
);
struct
pnp_card
*
card
=
to_pnp_card
(
dev
);
const
struct
pnp_card_
device_
id
*
card_id
=
NULL
;
const
struct
pnp_card_id
*
card_id
=
NULL
;
pnp_dbg
(
"pnp: match found with the PnP card '%s' and the driver '%s'"
,
dev
->
bus_id
,
drv
->
name
);
pnp_dbg
(
"pnp: match found with the PnP card '%s' and the driver '%s'"
,
dev
->
bus_id
,
drv
->
name
);
...
...
drivers/pnp/core.c
View file @
0d716f8c
...
@@ -104,31 +104,29 @@ static void pnp_free_ids(struct pnp_dev *dev)
...
@@ -104,31 +104,29 @@ static void pnp_free_ids(struct pnp_dev *dev)
static
void
pnp_release_device
(
struct
device
*
dmdev
)
static
void
pnp_release_device
(
struct
device
*
dmdev
)
{
{
struct
pnp_dev
*
dev
=
to_pnp_dev
(
dmdev
);
struct
pnp_dev
*
dev
=
to_pnp_dev
(
dmdev
);
if
(
dev
->
res
)
if
(
dev
->
possible
)
pnp_free_resources
(
dev
->
res
);
pnp_free_resources
(
dev
->
possible
);
pnp_free_ids
(
dev
);
pnp_free_ids
(
dev
);
kfree
(
dev
);
kfree
(
dev
);
}
}
int
__pnp_add_device
(
struct
pnp_dev
*
dev
)
int
__pnp_add_device
(
struct
pnp_dev
*
dev
)
{
{
int
error
=
0
;
int
ret
;
pnp_name_device
(
dev
);
pnp_name_device
(
dev
);
pnp_fixup_device
(
dev
);
pnp_fixup_device
(
dev
);
strncpy
(
dev
->
dev
.
name
,
dev
->
name
,
DEVICE_NAME_SIZE
-
1
);
dev
->
dev
.
name
[
DEVICE_NAME_SIZE
-
1
]
=
'\0'
;
dev
->
dev
.
bus
=
&
pnp_bus_type
;
dev
->
dev
.
bus
=
&
pnp_bus_type
;
dev
->
dev
.
release
=
&
pnp_release_device
;
dev
->
dev
.
release
=
&
pnp_release_device
;
dev
->
status
=
PNP_READY
;
dev
->
status
=
PNP_READY
;
error
=
device_register
(
&
dev
->
dev
);
spin_lock
(
&
pnp_lock
);
if
(
error
==
0
){
list_add_tail
(
&
dev
->
global_list
,
&
pnp_global
);
spin_lock
(
&
pnp_lock
);
list_add_tail
(
&
dev
->
protocol_list
,
&
dev
->
protocol
->
devices
);
list_add_tail
(
&
dev
->
global_list
,
&
pnp_global
);
spin_unlock
(
&
pnp_lock
);
list_add_tail
(
&
dev
->
protocol_list
,
&
dev
->
protocol
->
devices
);
pnp_auto_config_dev
(
dev
);
spin_unlock
(
&
pnp_lock
);
ret
=
device_register
(
&
dev
->
dev
);
if
(
ret
==
0
)
pnp_interface_attach_device
(
dev
);
pnp_interface_attach_device
(
dev
);
}
return
ret
;
return
error
;
}
}
/*
/*
...
@@ -172,7 +170,7 @@ void pnp_remove_device(struct pnp_dev *dev)
...
@@ -172,7 +170,7 @@ void pnp_remove_device(struct pnp_dev *dev)
static
int
__init
pnp_init
(
void
)
static
int
__init
pnp_init
(
void
)
{
{
printk
(
KERN_INFO
"Linux Plug and Play Support v0.9
4
(c) Adam Belay
\n
"
);
printk
(
KERN_INFO
"Linux Plug and Play Support v0.9
5
(c) Adam Belay
\n
"
);
return
bus_register
(
&
pnp_bus_type
);
return
bus_register
(
&
pnp_bus_type
);
}
}
...
...
drivers/pnp/driver.c
View file @
0d716f8c
...
@@ -95,7 +95,7 @@ static int pnp_device_probe(struct device *dev)
...
@@ -95,7 +95,7 @@ static int pnp_device_probe(struct device *dev)
pnp_dev
=
to_pnp_dev
(
dev
);
pnp_dev
=
to_pnp_dev
(
dev
);
pnp_drv
=
to_pnp_driver
(
dev
->
driver
);
pnp_drv
=
to_pnp_driver
(
dev
->
driver
);
pnp_dbg
(
"
pnp:
match found with the PnP device '%s' and the driver '%s'"
,
dev
->
bus_id
,
pnp_drv
->
name
);
pnp_dbg
(
"match found with the PnP device '%s' and the driver '%s'"
,
dev
->
bus_id
,
pnp_drv
->
name
);
error
=
pnp_device_attach
(
pnp_dev
);
error
=
pnp_device_attach
(
pnp_dev
);
if
(
error
<
0
)
if
(
error
<
0
)
...
@@ -103,7 +103,7 @@ static int pnp_device_probe(struct device *dev)
...
@@ -103,7 +103,7 @@ static int pnp_device_probe(struct device *dev)
if
(
pnp_dev
->
active
==
0
)
{
if
(
pnp_dev
->
active
==
0
)
{
if
(
!
(
pnp_drv
->
flags
&
PNP_DRIVER_DO_NOT_ACTIVATE
))
{
if
(
!
(
pnp_drv
->
flags
&
PNP_DRIVER_DO_NOT_ACTIVATE
))
{
error
=
pnp_activate_dev
(
pnp_dev
,
NULL
);
error
=
pnp_activate_dev
(
pnp_dev
);
if
(
error
<
0
)
if
(
error
<
0
)
return
error
;
return
error
;
}
}
...
...
drivers/pnp/names.c
View file @
0d716f8c
...
@@ -30,7 +30,7 @@ void
...
@@ -30,7 +30,7 @@ void
pnp_name_device
(
struct
pnp_dev
*
dev
)
pnp_name_device
(
struct
pnp_dev
*
dev
)
{
{
int
i
;
int
i
;
char
*
name
=
dev
->
name
;
char
*
name
=
dev
->
dev
.
name
;
for
(
i
=
0
;
i
<
sizeof
(
pnp_id_eisaid
)
/
sizeof
(
pnp_id_eisaid
[
0
]);
i
++
){
for
(
i
=
0
;
i
<
sizeof
(
pnp_id_eisaid
)
/
sizeof
(
pnp_id_eisaid
[
0
]);
i
++
){
if
(
compare_pnp_id
(
dev
->
id
,
pnp_id_eisaid
[
i
])){
if
(
compare_pnp_id
(
dev
->
id
,
pnp_id_eisaid
[
i
])){
sprintf
(
name
,
"%s"
,
pnp_id_names
[
i
]);
sprintf
(
name
,
"%s"
,
pnp_id_names
[
i
]);
...
...
drivers/pnp/quirks.c
View file @
0d716f8c
...
@@ -29,7 +29,7 @@
...
@@ -29,7 +29,7 @@
static
void
quirk_awe32_resources
(
struct
pnp_dev
*
dev
)
static
void
quirk_awe32_resources
(
struct
pnp_dev
*
dev
)
{
{
struct
pnp_port
*
port
,
*
port2
,
*
port3
;
struct
pnp_port
*
port
,
*
port2
,
*
port3
;
struct
pnp_resources
*
res
=
dev
->
res
->
dep
;
struct
pnp_resources
*
res
=
dev
->
possible
->
dep
;
/*
/*
* Unfortunately the isapnp_add_port_resource is too tightly bound
* Unfortunately the isapnp_add_port_resource is too tightly bound
...
@@ -57,7 +57,7 @@ static void quirk_awe32_resources(struct pnp_dev *dev)
...
@@ -57,7 +57,7 @@ static void quirk_awe32_resources(struct pnp_dev *dev)
static
void
quirk_cmi8330_resources
(
struct
pnp_dev
*
dev
)
static
void
quirk_cmi8330_resources
(
struct
pnp_dev
*
dev
)
{
{
struct
pnp_resources
*
res
=
dev
->
res
->
dep
;
struct
pnp_resources
*
res
=
dev
->
possible
->
dep
;
for
(
;
res
;
res
=
res
->
dep
)
{
for
(
;
res
;
res
=
res
->
dep
)
{
...
@@ -77,7 +77,7 @@ static void quirk_cmi8330_resources(struct pnp_dev *dev)
...
@@ -77,7 +77,7 @@ static void quirk_cmi8330_resources(struct pnp_dev *dev)
static
void
quirk_sb16audio_resources
(
struct
pnp_dev
*
dev
)
static
void
quirk_sb16audio_resources
(
struct
pnp_dev
*
dev
)
{
{
struct
pnp_port
*
port
;
struct
pnp_port
*
port
;
struct
pnp_resources
*
res
=
dev
->
res
->
dep
;
struct
pnp_resources
*
res
=
dev
->
possible
->
dep
;
int
changed
=
0
;
int
changed
=
0
;
/*
/*
...
@@ -115,7 +115,7 @@ static void quirk_opl3sax_resources(struct pnp_dev *dev)
...
@@ -115,7 +115,7 @@ static void quirk_opl3sax_resources(struct pnp_dev *dev)
*/
*/
struct
pnp_resources
*
res
;
struct
pnp_resources
*
res
;
int
max
;
int
max
;
res
=
dev
->
res
;
res
=
dev
->
possible
;
max
=
0
;
max
=
0
;
for
(
res
=
res
->
dep
;
res
;
res
=
res
->
dep
)
{
for
(
res
=
res
->
dep
;
res
;
res
=
res
->
dep
)
{
if
(
res
->
dma
->
map
>
max
)
if
(
res
->
dma
->
map
>
max
)
...
...
drivers/pnp/resource.c
View file @
0d716f8c
/*
/*
* resource.c -
contains resource management algorithms
* resource.c -
Contains functions for registering and analyzing resource information
*
*
* based on isapnp.c resource management (c) Jaroslav Kysela <perex@suse.cz>
* based on isapnp.c resource management (c) Jaroslav Kysela <perex@suse.cz>
* Copyright 2002 Adam Belay <ambx1@neo.rr.com>
* Copyright 2002 Adam Belay <ambx1@neo.rr.com>
...
@@ -16,15 +16,8 @@
...
@@ -16,15 +16,8 @@
#include <asm/dma.h>
#include <asm/dma.h>
#include <asm/irq.h>
#include <asm/irq.h>
#include <linux/ioport.h>
#include <linux/ioport.h>
#include <linux/config.h>
#include <linux/init.h>
#include <linux/init.h>
#ifdef CONFIG_PNP_DEBUG
#define DEBUG
#else
#undef DEBUG
#endif
#include <linux/pnp.h>
#include <linux/pnp.h>
#include "base.h"
#include "base.h"
...
@@ -36,7 +29,9 @@ int pnp_reserve_io[16] = { [0 ... 15] = -1 }; /* reserve (don't use) some I/O re
...
@@ -36,7 +29,9 @@ int pnp_reserve_io[16] = { [0 ... 15] = -1 }; /* reserve (don't use) some I/O re
int
pnp_reserve_mem
[
16
]
=
{
[
0
...
15
]
=
-
1
};
/* reserve (don't use) some memory region */
int
pnp_reserve_mem
[
16
]
=
{
[
0
...
15
]
=
-
1
};
/* reserve (don't use) some memory region */
/* resource information adding functions */
/*
* possible resource registration
*/
struct
pnp_resources
*
pnp_build_resource
(
struct
pnp_dev
*
dev
,
int
dependent
)
struct
pnp_resources
*
pnp_build_resource
(
struct
pnp_dev
*
dev
,
int
dependent
)
{
{
...
@@ -45,8 +40,8 @@ struct pnp_resources * pnp_build_resource(struct pnp_dev *dev, int dependent)
...
@@ -45,8 +40,8 @@ struct pnp_resources * pnp_build_resource(struct pnp_dev *dev, int dependent)
res
=
pnp_alloc
(
sizeof
(
struct
pnp_resources
));
res
=
pnp_alloc
(
sizeof
(
struct
pnp_resources
));
if
(
!
res
)
if
(
!
res
)
return
NULL
;
return
NULL
;
ptr
=
dev
->
res
;
ptr
=
dev
->
possible
;
if
(
ptr
&&
ptr
->
dependent
&&
dependent
)
{
/* add to another list */
if
(
ptr
)
{
/* add to another list */
ptra
=
ptr
->
dep
;
ptra
=
ptr
->
dep
;
while
(
ptra
&&
ptra
->
dep
)
while
(
ptra
&&
ptra
->
dep
)
ptra
=
ptra
->
dep
;
ptra
=
ptra
->
dep
;
...
@@ -54,24 +49,14 @@ struct pnp_resources * pnp_build_resource(struct pnp_dev *dev, int dependent)
...
@@ -54,24 +49,14 @@ struct pnp_resources * pnp_build_resource(struct pnp_dev *dev, int dependent)
ptr
->
dep
=
res
;
ptr
->
dep
=
res
;
else
else
ptra
->
dep
=
res
;
ptra
->
dep
=
res
;
}
else
{
}
else
if
(
!
ptr
){
dev
->
possible
=
res
;
dev
->
res
=
res
;
}
else
{
kfree
(
res
);
return
NULL
;
}
}
if
(
dependent
)
{
if
(
dependent
)
{
res
->
priority
=
dependent
&
0xff
;
res
->
priority
=
dependent
&
0xff
;
if
(
res
->
priority
>
PNP_RES_PRIORITY_FUNCTIONAL
)
if
(
res
->
priority
>
PNP_RES_PRIORITY_FUNCTIONAL
)
res
->
priority
=
PNP_RES_PRIORITY_INVALID
;
res
->
priority
=
PNP_RES_PRIORITY_INVALID
;
res
->
dependent
=
1
;
}
else
}
else
{
res
->
priority
=
PNP_RES_PRIORITY_PREFERRED
;
res
->
priority
=
PNP_RES_PRIORITY_PREFERRED
;
res
->
dependent
=
1
;
}
return
res
;
return
res
;
}
}
...
@@ -81,7 +66,7 @@ struct pnp_resources * pnp_find_resources(struct pnp_dev *dev, int depnum)
...
@@ -81,7 +66,7 @@ struct pnp_resources * pnp_find_resources(struct pnp_dev *dev, int depnum)
struct
pnp_resources
*
res
;
struct
pnp_resources
*
res
;
if
(
!
dev
)
if
(
!
dev
)
return
NULL
;
return
NULL
;
res
=
dev
->
res
;
res
=
dev
->
possible
;
if
(
!
res
)
if
(
!
res
)
return
NULL
;
return
NULL
;
for
(
i
=
0
;
i
<
depnum
;
i
++
)
for
(
i
=
0
;
i
<
depnum
;
i
++
)
...
@@ -100,7 +85,7 @@ int pnp_get_max_depnum(struct pnp_dev *dev)
...
@@ -100,7 +85,7 @@ int pnp_get_max_depnum(struct pnp_dev *dev)
struct
pnp_resources
*
res
;
struct
pnp_resources
*
res
;
if
(
!
dev
)
if
(
!
dev
)
return
-
EINVAL
;
return
-
EINVAL
;
res
=
dev
->
res
;
res
=
dev
->
possible
;
if
(
!
res
)
if
(
!
res
)
return
-
EINVAL
;
return
-
EINVAL
;
while
(
res
->
dep
){
while
(
res
->
dep
){
...
@@ -110,10 +95,6 @@ int pnp_get_max_depnum(struct pnp_dev *dev)
...
@@ -110,10 +95,6 @@ int pnp_get_max_depnum(struct pnp_dev *dev)
return
num
;
return
num
;
}
}
/*
* Add IRQ resource to resources list.
*/
int
pnp_add_irq_resource
(
struct
pnp_dev
*
dev
,
int
depnum
,
struct
pnp_irq
*
data
)
int
pnp_add_irq_resource
(
struct
pnp_dev
*
dev
,
int
depnum
,
struct
pnp_irq
*
data
)
{
{
int
i
;
int
i
;
...
@@ -139,10 +120,6 @@ int pnp_add_irq_resource(struct pnp_dev *dev, int depnum, struct pnp_irq *data)
...
@@ -139,10 +120,6 @@ int pnp_add_irq_resource(struct pnp_dev *dev, int depnum, struct pnp_irq *data)
return
0
;
return
0
;
}
}
/*
* Add DMA resource to resources list.
*/
int
pnp_add_dma_resource
(
struct
pnp_dev
*
dev
,
int
depnum
,
struct
pnp_dma
*
data
)
int
pnp_add_dma_resource
(
struct
pnp_dev
*
dev
,
int
depnum
,
struct
pnp_dma
*
data
)
{
{
struct
pnp_resources
*
res
;
struct
pnp_resources
*
res
;
...
@@ -162,20 +139,15 @@ int pnp_add_dma_resource(struct pnp_dev *dev, int depnum, struct pnp_dma *data)
...
@@ -162,20 +139,15 @@ int pnp_add_dma_resource(struct pnp_dev *dev, int depnum, struct pnp_dma *data)
return
0
;
return
0
;
}
}
/*
* Add port resource to resources list.
*/
int
pnp_add_port_resource
(
struct
pnp_dev
*
dev
,
int
depnum
,
struct
pnp_port
*
data
)
int
pnp_add_port_resource
(
struct
pnp_dev
*
dev
,
int
depnum
,
struct
pnp_port
*
data
)
{
{
struct
pnp_resources
*
res
;
struct
pnp_resources
*
res
;
struct
pnp_port
*
ptr
;
struct
pnp_port
*
ptr
;
res
=
pnp_find_resources
(
dev
,
depnum
);
res
=
pnp_find_resources
(
dev
,
depnum
);
if
(
res
==
NULL
)
if
(
!
res
)
return
-
EINVAL
;
return
-
EINVAL
;
if
(
!
data
)
if
(
!
data
)
return
-
EINVAL
;
return
-
EINVAL
;
data
->
res
=
res
;
ptr
=
res
->
port
;
ptr
=
res
->
port
;
while
(
ptr
&&
ptr
->
next
)
while
(
ptr
&&
ptr
->
next
)
ptr
=
ptr
->
next
;
ptr
=
ptr
->
next
;
...
@@ -186,10 +158,6 @@ int pnp_add_port_resource(struct pnp_dev *dev, int depnum, struct pnp_port *data
...
@@ -186,10 +158,6 @@ int pnp_add_port_resource(struct pnp_dev *dev, int depnum, struct pnp_port *data
return
0
;
return
0
;
}
}
/*
* Add memory resource to resources list.
*/
int
pnp_add_mem_resource
(
struct
pnp_dev
*
dev
,
int
depnum
,
struct
pnp_mem
*
data
)
int
pnp_add_mem_resource
(
struct
pnp_dev
*
dev
,
int
depnum
,
struct
pnp_mem
*
data
)
{
{
struct
pnp_resources
*
res
;
struct
pnp_resources
*
res
;
...
@@ -209,32 +177,6 @@ int pnp_add_mem_resource(struct pnp_dev *dev, int depnum, struct pnp_mem *data)
...
@@ -209,32 +177,6 @@ int pnp_add_mem_resource(struct pnp_dev *dev, int depnum, struct pnp_mem *data)
return
0
;
return
0
;
}
}
/*
* Add 32-bit memory resource to resources list.
*/
int
pnp_add_mem32_resource
(
struct
pnp_dev
*
dev
,
int
depnum
,
struct
pnp_mem32
*
data
)
{
struct
pnp_resources
*
res
;
struct
pnp_mem32
*
ptr
;
res
=
pnp_find_resources
(
dev
,
depnum
);
if
(
!
res
)
return
-
EINVAL
;
if
(
!
data
)
return
-
EINVAL
;
ptr
=
res
->
mem32
;
while
(
ptr
&&
ptr
->
next
)
ptr
=
ptr
->
next
;
if
(
ptr
)
ptr
->
next
=
data
;
else
res
->
mem32
=
data
;
return
0
;
}
/* resource removing functions */
static
void
pnp_free_port
(
struct
pnp_port
*
port
)
static
void
pnp_free_port
(
struct
pnp_port
*
port
)
{
{
struct
pnp_port
*
next
;
struct
pnp_port
*
next
;
...
@@ -279,17 +221,6 @@ static void pnp_free_mem(struct pnp_mem *mem)
...
@@ -279,17 +221,6 @@ static void pnp_free_mem(struct pnp_mem *mem)
}
}
}
}
static
void
pnp_free_mem32
(
struct
pnp_mem32
*
mem32
)
{
struct
pnp_mem32
*
next
;
while
(
mem32
)
{
next
=
mem32
->
next
;
kfree
(
mem32
);
mem32
=
next
;
}
}
void
pnp_free_resources
(
struct
pnp_resources
*
resources
)
void
pnp_free_resources
(
struct
pnp_resources
*
resources
)
{
{
struct
pnp_resources
*
next
;
struct
pnp_resources
*
next
;
...
@@ -300,597 +231,447 @@ void pnp_free_resources(struct pnp_resources *resources)
...
@@ -300,597 +231,447 @@ void pnp_free_resources(struct pnp_resources *resources)
pnp_free_irq
(
resources
->
irq
);
pnp_free_irq
(
resources
->
irq
);
pnp_free_dma
(
resources
->
dma
);
pnp_free_dma
(
resources
->
dma
);
pnp_free_mem
(
resources
->
mem
);
pnp_free_mem
(
resources
->
mem
);
pnp_free_mem32
(
resources
->
mem32
);
kfree
(
resources
);
kfree
(
resources
);
resources
=
next
;
resources
=
next
;
}
}
}
}
/* resource validity checking functions */
/*
* resource validity checking
*/
#define length(start, end) (*(end) - *(start) + 1)
/* ranged_conflict - used to determine if two resource ranges conflict
* condition 1: check if the start of a is within b
* condition 2: check if the end of a is within b
* condition 3: check if b is engulfed by a */
#define ranged_conflict(starta, enda, startb, endb) \
((*(starta) >= *(startb) && *(starta) <= *(endb)) || \
(*(enda) >= *(startb) && *(enda) <= *(endb)) || \
(*(starta) < *(startb) && *(enda) > *(endb)))
st
atic
int
pnp_check_port
(
int
port
,
int
size
,
int
idx
,
struct
pnp_cfg
*
config
)
st
ruct
pnp_dev
*
pnp_check_port_conflicts
(
struct
pnp_dev
*
dev
,
int
idx
,
int
mode
)
{
{
int
i
,
tmp
,
rport
,
rsize
;
int
tmp
;
struct
pnp_dev
*
dev
;
unsigned
long
*
port
,
*
end
,
*
tport
,
*
tend
;
struct
pnp_dev
*
tdev
;
if
(
check_region
(
port
,
size
))
port
=
&
dev
->
res
.
port_resource
[
idx
].
start
;
return
1
;
end
=
&
dev
->
res
.
port_resource
[
idx
].
end
;
for
(
i
=
0
;
i
<
8
;
i
++
)
{
rport
=
pnp_reserve_io
[
i
<<
1
];
/* if the resource doesn't exist, don't complain about it */
rsize
=
pnp_reserve_io
[(
i
<<
1
)
+
1
];
if
(
dev
->
res
.
port_resource
[
idx
].
start
==
0
)
if
(
port
>=
rport
&&
port
<
rport
+
rsize
)
return
NULL
;
return
1
;
if
(
port
+
size
>
rport
&&
port
+
size
<
(
rport
+
rsize
)
-
1
)
/* check for cold conflicts */
return
1
;
pnp_for_each_dev
(
tdev
)
{
}
/* Is the device configurable? */
if
(
tdev
==
dev
||
(
mode
?
!
dev
->
active
:
dev
->
active
))
pnp_for_each_dev
(
dev
)
{
continue
;
if
(
dev
->
active
)
{
for
(
tmp
=
0
;
tmp
<
PNP_MAX_PORT
;
tmp
++
)
{
for
(
tmp
=
0
;
tmp
<
8
;
tmp
++
)
{
if
(
tdev
->
res
.
port_resource
[
tmp
].
flags
&
IORESOURCE_IO
)
{
if
(
pnp_port_valid
(
dev
,
tmp
))
{
tport
=
&
tdev
->
res
.
port_resource
[
tmp
].
start
;
rport
=
pnp_port_start
(
dev
,
tmp
);
tend
=
&
tdev
->
res
.
port_resource
[
tmp
].
end
;
rsize
=
pnp_port_len
(
dev
,
tmp
);
if
(
ranged_conflict
(
port
,
end
,
tport
,
tend
))
if
(
port
>=
rport
&&
port
<
rport
+
rsize
)
return
tdev
;
return
1
;
if
(
port
+
size
>
rport
&&
port
+
size
<
(
rport
+
rsize
)
-
1
)
return
1
;
}
}
}
}
}
}
}
for
(
tmp
=
0
;
tmp
<
8
&&
tmp
!=
idx
;
tmp
++
)
{
return
NULL
;
if
(
pnp_port_valid
(
dev
,
tmp
)
&&
}
pnp_flags_valid
(
&
config
->
request
.
io_resource
[
tmp
]))
{
rport
=
config
->
request
.
io_resource
[
tmp
].
start
;
int
pnp_check_port
(
struct
pnp_dev
*
dev
,
int
idx
)
rsize
=
(
config
->
request
.
io_resource
[
tmp
].
end
-
rport
)
+
1
;
{
if
(
port
>=
rport
&&
port
<
rport
+
rsize
)
int
tmp
;
return
1
;
unsigned
long
*
port
,
*
end
,
*
tport
,
*
tend
;
if
(
port
+
size
>
rport
&&
port
+
size
<
(
rport
+
rsize
)
-
1
)
port
=
&
dev
->
res
.
port_resource
[
idx
].
start
;
return
1
;
end
=
&
dev
->
res
.
port_resource
[
idx
].
end
;
/* if the resource doesn't exist, don't complain about it */
if
(
dev
->
res
.
port_resource
[
idx
].
start
==
0
)
return
0
;
/* check if the resource is already in use, skip if the device is active because it itself may be in use */
if
(
!
dev
->
active
)
{
if
(
check_region
(
*
port
,
length
(
port
,
end
)))
return
CONFLICT_TYPE_IN_USE
;
}
/* 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
;
if
(
ranged_conflict
(
port
,
end
,
&
rport
,
&
rend
))
return
CONFLICT_TYPE_RESERVED
;
}
/* 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
;
if
(
ranged_conflict
(
port
,
end
,
tport
,
tend
))
return
CONFLICT_TYPE_INTERNAL
;
}
}
}
}
/* check for warm conflicts */
if
(
pnp_check_port_conflicts
(
dev
,
idx
,
SEARCH_WARM
))
return
CONFLICT_TYPE_PNP_WARM
;
return
0
;
return
0
;
}
}
st
atic
int
pnp_check_mem
(
unsigned
int
addr
,
unsigned
int
size
,
int
idx
,
struct
pnp_cfg
*
config
)
st
ruct
pnp_dev
*
pnp_check_mem_conflicts
(
struct
pnp_dev
*
dev
,
int
idx
,
int
mode
)
{
{
int
i
,
tmp
;
int
tmp
;
unsigned
int
raddr
,
rsize
;
unsigned
long
*
addr
,
*
end
,
*
taddr
,
*
tend
;
struct
pnp_dev
*
dev
;
struct
pnp_dev
*
tdev
;
addr
=
&
dev
->
res
.
mem_resource
[
idx
].
start
;
for
(
i
=
0
;
i
<
8
;
i
++
)
{
end
=
&
dev
->
res
.
mem_resource
[
idx
].
end
;
raddr
=
(
unsigned
int
)
pnp_reserve_mem
[
i
<<
1
];
rsize
=
(
unsigned
int
)
pnp_reserve_mem
[(
i
<<
1
)
+
1
];
/* if the resource doesn't exist, don't complain about it */
if
(
addr
>=
raddr
&&
addr
<
raddr
+
rsize
)
if
(
dev
->
res
.
mem_resource
[
idx
].
start
==
0
)
return
1
;
return
NULL
;
if
(
addr
+
size
>
raddr
&&
addr
+
size
<
(
raddr
+
rsize
)
-
1
)
return
1
;
/* check for cold conflicts */
if
(
__check_region
(
&
iomem_resource
,
addr
,
size
))
pnp_for_each_dev
(
tdev
)
{
return
1
;
/* Is the device configurable? */
}
if
(
tdev
==
dev
||
(
mode
?
!
dev
->
active
:
dev
->
active
))
pnp_for_each_dev
(
dev
)
{
continue
;
if
(
dev
->
active
)
{
for
(
tmp
=
0
;
tmp
<
PNP_MAX_MEM
;
tmp
++
)
{
for
(
tmp
=
0
;
tmp
<
4
;
tmp
++
)
{
if
(
tdev
->
res
.
mem_resource
[
tmp
].
flags
&
IORESOURCE_MEM
)
{
if
(
pnp_mem_valid
(
dev
,
tmp
))
{
taddr
=
&
tdev
->
res
.
mem_resource
[
tmp
].
start
;
raddr
=
pnp_mem_start
(
dev
,
tmp
);
tend
=
&
tdev
->
res
.
mem_resource
[
tmp
].
end
;
rsize
=
pnp_mem_len
(
dev
,
tmp
);
if
(
ranged_conflict
(
addr
,
end
,
taddr
,
tend
))
if
(
addr
>=
raddr
&&
addr
<
raddr
+
rsize
)
return
tdev
;
return
1
;
if
(
addr
+
size
>
raddr
&&
addr
+
size
<
(
raddr
+
rsize
)
-
1
)
return
1
;
}
}
}
}
}
}
}
for
(
tmp
=
0
;
tmp
<
4
&&
tmp
!=
idx
;
tmp
++
)
{
return
NULL
;
if
(
pnp_mem_valid
(
dev
,
tmp
)
&&
}
pnp_flags_valid
(
&
config
->
request
.
mem_resource
[
tmp
]))
{
raddr
=
config
->
request
.
mem_resource
[
tmp
].
start
;
int
pnp_check_mem
(
struct
pnp_dev
*
dev
,
int
idx
)
rsize
=
(
config
->
request
.
mem_resource
[
tmp
].
end
-
raddr
)
+
1
;
{
if
(
addr
>=
raddr
&&
addr
<
raddr
+
rsize
)
int
tmp
;
return
1
;
unsigned
long
*
addr
,
*
end
,
*
taddr
,
*
tend
;
if
(
addr
+
size
>
raddr
&&
addr
+
size
<
(
raddr
+
rsize
)
-
1
)
addr
=
&
dev
->
res
.
mem_resource
[
idx
].
start
;
return
1
;
end
=
&
dev
->
res
.
mem_resource
[
idx
].
end
;
/* if the resource doesn't exist, don't complain about it */
if
(
dev
->
res
.
mem_resource
[
idx
].
start
==
0
)
return
0
;
/* check if the resource is already in use, skip if the device is active because it itself may be in use */
if
(
!
dev
->
active
)
{
if
(
__check_region
(
&
iomem_resource
,
*
addr
,
length
(
addr
,
end
)))
return
CONFLICT_TYPE_IN_USE
;
}
/* 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
;
if
(
ranged_conflict
(
addr
,
end
,
&
raddr
,
&
rend
))
return
CONFLICT_TYPE_RESERVED
;
}
/* 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
;
if
(
ranged_conflict
(
addr
,
end
,
taddr
,
tend
))
return
CONFLICT_TYPE_INTERNAL
;
}
}
}
}
/* check for warm conflicts */
if
(
pnp_check_mem_conflicts
(
dev
,
idx
,
SEARCH_WARM
))
return
CONFLICT_TYPE_PNP_WARM
;
return
0
;
return
0
;
}
}
struct
pnp_dev
*
pnp_check_irq_conflicts
(
struct
pnp_dev
*
dev
,
int
idx
,
int
mode
)
{
int
tmp
;
struct
pnp_dev
*
tdev
;
unsigned
long
*
irq
=
&
dev
->
res
.
irq_resource
[
idx
].
start
;
/* if the resource doesn't exist, don't complain about it */
if
(
dev
->
res
.
irq_resource
[
idx
].
start
==
-
1
)
return
NULL
;
/* check for cold conflicts */
pnp_for_each_dev
(
tdev
)
{
/* Is the device configurable? */
if
(
tdev
==
dev
||
(
mode
?
!
dev
->
active
:
dev
->
active
))
continue
;
for
(
tmp
=
0
;
tmp
<
PNP_MAX_IRQ
;
tmp
++
)
{
if
(
tdev
->
res
.
irq_resource
[
tmp
].
flags
&
IORESOURCE_IRQ
)
{
if
((
tdev
->
res
.
irq_resource
[
tmp
].
start
==
*
irq
))
return
tdev
;
}
}
}
return
NULL
;
}
static
void
pnp_test_handler
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
static
void
pnp_test_handler
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
{
{
}
}
static
int
pnp_check_interrupt
(
int
irq
,
struct
pnp_cfg
*
config
)
int
pnp_check_irq
(
struct
pnp_dev
*
dev
,
int
idx
)
{
{
int
i
;
int
tmp
;
#ifdef CONFIG_PCI
unsigned
long
*
irq
=
&
dev
->
res
.
irq_resource
[
idx
].
start
;
struct
pci_dev
*
pci
;
#endif
/* if the resource doesn't exist, don't complain about it */
struct
pnp_dev
*
dev
;
if
(
dev
->
res
.
irq_resource
[
idx
].
start
==
-
1
)
if
(
!
config
)
return
0
;
return
1
;
/* check if the resource is valid */
if
(
irq
<
0
||
irq
>
15
)
if
(
*
irq
<
0
||
*
irq
>
15
)
return
1
;
return
CONFLICT_TYPE_INVALID
;
for
(
i
=
0
;
i
<
16
;
i
++
)
{
if
(
pnp_reserve_irq
[
i
]
==
irq
)
/* check if the resource is reserved */
return
1
;
for
(
tmp
=
0
;
tmp
<
16
;
tmp
++
)
{
}
if
(
pnp_reserve_irq
[
tmp
]
==
*
irq
)
pnp_for_each_dev
(
dev
)
{
return
CONFLICT_TYPE_RESERVED
;
if
(
dev
->
active
)
{
}
if
((
pnp_irq_valid
(
dev
,
0
)
&&
dev
->
irq_resource
[
0
].
start
==
irq
)
||
(
pnp_irq_valid
(
dev
,
1
)
&&
dev
->
irq_resource
[
1
].
start
==
irq
))
/* check for internal conflicts */
return
1
;
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
)
return
CONFLICT_TYPE_INTERNAL
;
}
}
}
}
if
(
pnp_flags_valid
(
&
config
->
request
.
irq_resource
[
0
])
&&
pnp_flags_valid
(
&
config
->
request
.
irq_resource
[
1
])
&&
(
config
->
request
.
irq_resource
[
0
].
start
==
irq
))
return
1
;
#ifdef CONFIG_PCI
#ifdef CONFIG_PCI
/* check if the resource is being used by a pci device */
if
(
!
pnp_skip_pci_scan
)
{
if
(
!
pnp_skip_pci_scan
)
{
struct
pci_dev
*
pci
;
pci_for_each_dev
(
pci
)
{
pci_for_each_dev
(
pci
)
{
if
(
pci
->
irq
==
irq
)
if
(
pci
->
irq
==
*
irq
)
return
1
;
return
CONFLICT_TYPE_PCI
;
}
}
}
}
#endif
#endif
if
(
request_irq
(
irq
,
pnp_test_handler
,
SA_INTERRUPT
,
"pnp"
,
NULL
))
return
1
;
free_irq
(
irq
,
NULL
);
return
0
;
}
static
int
pnp_check_dma
(
int
dma
,
struct
pnp_cfg
*
config
)
{
int
i
,
mindma
=
1
;
struct
pnp_dev
*
dev
;
if
(
!
config
)
return
1
;
if
(
pnp_allow_dma0
==
1
)
/* check if the resource is already in use, skip if the device is active because it itself may be in use */
mindma
=
0
;
if
(
!
dev
->
active
)
{
if
(
dma
<
mindma
||
dma
==
4
||
dma
>
7
)
if
(
request_irq
(
*
irq
,
pnp_test_handler
,
SA_INTERRUPT
,
"pnp"
,
NULL
))
return
1
;
return
CONFLICT_TYPE_IN_USE
;
for
(
i
=
0
;
i
<
8
;
i
++
)
{
free_irq
(
*
irq
,
NULL
);
if
(
pnp_reserve_dma
[
i
]
==
dma
)
return
1
;
}
pnp_for_each_dev
(
dev
)
{
if
(
dev
->
active
)
{
if
((
pnp_dma_valid
(
dev
,
0
)
&&
pnp_dma
(
dev
,
0
)
==
dma
)
||
(
pnp_dma_valid
(
dev
,
1
)
&&
pnp_dma
(
dev
,
1
)
==
dma
))
return
1
;
}
}
}
if
(
pnp_flags_valid
(
&
config
->
request
.
dma_resource
[
0
])
&&
pnp_flags_valid
(
&
config
->
request
.
dma_resource
[
1
])
&&
(
config
->
request
.
dma_resource
[
0
].
start
==
dma
))
return
1
;
if
(
request_dma
(
dma
,
"pnp"
))
return
1
;
free_dma
(
dma
);
return
0
;
}
/* check for warm conflicts */
if
(
pnp_check_irq_conflicts
(
dev
,
idx
,
SEARCH_WARM
))
return
CONFLICT_TYPE_PNP_WARM
;
/* config generation functions */
static
int
pnp_generate_port
(
struct
pnp_cfg
*
config
,
int
num
)
{
struct
pnp_port
*
port
;
unsigned
long
*
value1
,
*
value2
,
*
value3
;
if
(
!
config
||
num
<
0
||
num
>
7
)
return
-
EINVAL
;
port
=
config
->
port
[
num
];
if
(
!
port
)
return
0
;
value1
=
&
config
->
request
.
io_resource
[
num
].
start
;
value2
=
&
config
->
request
.
io_resource
[
num
].
end
;
value3
=
&
config
->
request
.
io_resource
[
num
].
flags
;
*
value1
=
port
->
min
;
*
value2
=
*
value1
+
port
->
size
-
1
;
*
value3
=
port
->
flags
|
IORESOURCE_IO
;
while
(
pnp_check_port
(
*
value1
,
port
->
size
,
num
,
config
))
{
*
value1
+=
port
->
align
;
*
value2
=
*
value1
+
port
->
size
-
1
;
if
(
*
value1
>
port
->
max
||
!
port
->
align
)
return
-
ENOENT
;
}
return
0
;
return
0
;
}
}
static
int
pnp_generate_mem
(
struct
pnp_cfg
*
config
,
int
num
)
{
struct
pnp_mem
*
mem
;
unsigned
long
*
value1
,
*
value2
,
*
value3
;
if
(
!
config
||
num
<
0
||
num
>
3
)
return
-
EINVAL
;
mem
=
config
->
mem
[
num
];
if
(
!
mem
)
return
0
;
value1
=
&
config
->
request
.
mem_resource
[
num
].
start
;
value2
=
&
config
->
request
.
mem_resource
[
num
].
end
;
value3
=
&
config
->
request
.
mem_resource
[
num
].
flags
;
*
value1
=
mem
->
min
;
*
value2
=
*
value1
+
mem
->
size
-
1
;
*
value3
=
mem
->
flags
|
IORESOURCE_MEM
;
if
(
!
(
mem
->
flags
&
IORESOURCE_MEM_WRITEABLE
))
*
value3
|=
IORESOURCE_READONLY
;
if
(
mem
->
flags
&
IORESOURCE_MEM_CACHEABLE
)
*
value3
|=
IORESOURCE_CACHEABLE
;
if
(
mem
->
flags
&
IORESOURCE_MEM_RANGELENGTH
)
*
value3
|=
IORESOURCE_RANGELENGTH
;
if
(
mem
->
flags
&
IORESOURCE_MEM_SHADOWABLE
)
*
value3
|=
IORESOURCE_SHADOWABLE
;
while
(
pnp_check_mem
(
*
value1
,
mem
->
size
,
num
,
config
))
{
*
value1
+=
mem
->
align
;
*
value2
=
*
value1
+
mem
->
size
-
1
;
if
(
*
value1
>
mem
->
max
||
!
mem
->
align
)
return
-
ENOENT
;
}
return
0
;
}
st
atic
int
pnp_generate_irq
(
struct
pnp_cfg
*
config
,
int
num
)
st
ruct
pnp_dev
*
pnp_check_dma_conflicts
(
struct
pnp_dev
*
dev
,
int
idx
,
int
mode
)
{
{
struct
pnp_irq
*
irq
;
int
tmp
;
unsigned
long
*
value1
,
*
value2
,
*
value3
;
struct
pnp_dev
*
tdev
;
/* IRQ priority: this table is good for i386 */
unsigned
long
*
dma
=
&
dev
->
res
.
dma_resource
[
idx
].
start
;
static
unsigned
short
xtab
[
16
]
=
{
5
,
10
,
11
,
12
,
9
,
14
,
15
,
7
,
3
,
4
,
13
,
0
,
1
,
6
,
8
,
2
};
int
i
;
if
(
!
config
||
num
<
0
||
num
>
1
)
return
-
EINVAL
;
irq
=
config
->
irq
[
num
];
if
(
!
irq
)
return
0
;
value1
=
&
config
->
request
.
irq_resource
[
num
].
start
;
value2
=
&
config
->
request
.
irq_resource
[
num
].
end
;
value3
=
&
config
->
request
.
irq_resource
[
num
].
flags
;
*
value3
=
irq
->
flags
|
IORESOURCE_IRQ
;
for
(
i
=
0
;
i
<
16
;
i
++
)
/* if the resource doesn't exist, don't complain about it */
{
if
(
dev
->
res
.
dma_resource
[
idx
].
start
==
-
1
)
if
(
irq
->
map
&
(
1
<<
xtab
[
i
]))
{
return
NULL
;
*
value1
=
*
value2
=
xtab
[
i
];
if
(
pnp_check_interrupt
(
*
value1
,
config
)
==
0
)
/* check for cold conflicts */
return
0
;
pnp_for_each_dev
(
tdev
)
{
/* Is the device configurable? */
if
(
tdev
==
dev
||
(
mode
?
!
dev
->
active
:
dev
->
active
))
continue
;
for
(
tmp
=
0
;
tmp
<
PNP_MAX_DMA
;
tmp
++
)
{
if
(
tdev
->
res
.
dma_resource
[
tmp
].
flags
&
IORESOURCE_DMA
)
{
if
((
tdev
->
res
.
dma_resource
[
tmp
].
start
==
*
dma
))
return
tdev
;
}
}
}
}
}
return
-
ENOENT
;
return
NULL
;
}
}
static
int
pnp_generate_dma
(
struct
pnp_cfg
*
config
,
int
num
)
int
pnp_check_dma
(
struct
pnp_dev
*
dev
,
int
idx
)
{
{
struct
pnp_dma
*
dma
;
int
tmp
,
mindma
=
1
;
unsigned
long
*
value1
,
*
value2
,
*
value3
;
unsigned
long
*
dma
=
&
dev
->
res
.
dma_resource
[
idx
].
start
;
/* DMA priority: this table is good for i386 */
static
unsigned
short
xtab
[
16
]
=
{
/* if the resource doesn't exist, don't complain about it */
1
,
3
,
5
,
6
,
7
,
0
,
2
,
4
if
(
dev
->
res
.
dma_resource
[
idx
].
start
==
-
1
)
};
int
i
;
if
(
!
config
||
num
<
0
||
num
>
1
)
return
-
EINVAL
;
dma
=
config
->
dma
[
num
];
if
(
!
dma
)
return
0
;
return
0
;
value1
=
&
config
->
request
.
dma_resource
[
num
].
start
;
value2
=
&
config
->
request
.
dma_resource
[
num
].
end
;
value3
=
&
config
->
request
.
dma_resource
[
num
].
flags
;
*
value3
=
dma
->
flags
|
IORESOURCE_DMA
;
for
(
i
=
0
;
i
<
8
;
i
++
)
/* check if the resource is valid */
{
if
(
pnp_allow_dma0
==
1
)
if
(
dma
->
map
&
(
1
<<
xtab
[
i
]))
{
mindma
=
0
;
*
value1
=
*
value2
=
xtab
[
i
];
if
(
*
dma
<
mindma
||
*
dma
==
4
||
*
dma
>
7
)
if
(
pnp_check_dma
(
*
value1
,
config
)
==
0
)
return
CONFLICT_TYPE_INVALID
;
return
0
;
}
/* check if the resource is reserved */
for
(
tmp
=
0
;
tmp
<
8
;
tmp
++
)
{
if
(
pnp_reserve_dma
[
tmp
]
==
*
dma
)
return
CONFLICT_TYPE_RESERVED
;
}
}
return
-
ENOENT
;
}
int
pnp_init_res_cfg
(
struct
pnp_res_cfg
*
res_config
)
/* check for internal conflicts */
{
for
(
tmp
=
0
;
tmp
<
PNP_MAX_DMA
&&
tmp
!=
idx
;
tmp
++
)
{
int
idx
;
if
(
dev
->
res
.
dma_resource
[
tmp
].
flags
&
IORESOURCE_DMA
)
{
if
(
dev
->
res
.
dma_resource
[
tmp
].
start
==
*
dma
)
return
CONFLICT_TYPE_INTERNAL
;
}
}
if
(
!
res_config
)
/* check if the resource is already in use, skip if the device is active because it itself may be in use */
return
-
EINVAL
;
if
(
!
dev
->
active
)
{
for
(
idx
=
0
;
idx
<
DEVICE_COUNT_IRQ
;
idx
++
)
{
if
(
request_dma
(
*
dma
,
"pnp"
))
res_config
->
irq_resource
[
idx
].
start
=
-
1
;
return
CONFLICT_TYPE_IN_USE
;
res_config
->
irq_resource
[
idx
].
end
=
-
1
;
free_dma
(
*
dma
);
res_config
->
irq_resource
[
idx
].
flags
=
IORESOURCE_IRQ
|
IORESOURCE_UNSET
;
}
for
(
idx
=
0
;
idx
<
DEVICE_COUNT_DMA
;
idx
++
)
{
res_config
->
dma_resource
[
idx
].
name
=
NULL
;
res_config
->
dma_resource
[
idx
].
start
=
-
1
;
res_config
->
dma_resource
[
idx
].
end
=
-
1
;
res_config
->
dma_resource
[
idx
].
flags
=
IORESOURCE_DMA
|
IORESOURCE_UNSET
;
}
for
(
idx
=
0
;
idx
<
DEVICE_COUNT_IO
;
idx
++
)
{
res_config
->
io_resource
[
idx
].
name
=
NULL
;
res_config
->
io_resource
[
idx
].
start
=
0
;
res_config
->
io_resource
[
idx
].
end
=
0
;
res_config
->
io_resource
[
idx
].
flags
=
IORESOURCE_IO
|
IORESOURCE_UNSET
;
}
for
(
idx
=
0
;
idx
<
DEVICE_COUNT_MEM
;
idx
++
)
{
res_config
->
mem_resource
[
idx
].
name
=
NULL
;
res_config
->
mem_resource
[
idx
].
start
=
0
;
res_config
->
mem_resource
[
idx
].
end
=
0
;
res_config
->
mem_resource
[
idx
].
flags
=
IORESOURCE_MEM
|
IORESOURCE_UNSET
;
}
}
return
0
;
}
static
int
pnp_prepare_request
(
struct
pnp_dev
*
dev
,
struct
pnp_cfg
*
config
,
struct
pnp_res_cfg
*
template
)
/* check for warm conflicts */
{
if
(
pnp_check_dma_conflicts
(
dev
,
idx
,
SEARCH_WARM
))
int
idx
,
err
;
return
CONFLICT_TYPE_PNP_WARM
;
if
(
!
config
)
return
-
EINVAL
;
if
(
dev
->
lock_resources
)
return
-
EPERM
;
if
(
dev
->
active
)
return
-
EBUSY
;
err
=
pnp_init_res_cfg
(
&
config
->
request
);
if
(
err
<
0
)
return
err
;
if
(
!
template
)
return
0
;
for
(
idx
=
0
;
idx
<
DEVICE_COUNT_IRQ
;
idx
++
)
if
(
pnp_flags_valid
(
&
template
->
irq_resource
[
idx
]))
config
->
request
.
irq_resource
[
idx
]
=
template
->
irq_resource
[
idx
];
for
(
idx
=
0
;
idx
<
DEVICE_COUNT_DMA
;
idx
++
)
if
(
pnp_flags_valid
(
&
template
->
dma_resource
[
idx
]))
config
->
request
.
dma_resource
[
idx
]
=
template
->
dma_resource
[
idx
];
for
(
idx
=
0
;
idx
<
DEVICE_COUNT_IO
;
idx
++
)
if
(
pnp_flags_valid
(
&
template
->
io_resource
[
idx
]))
config
->
request
.
io_resource
[
idx
]
=
template
->
io_resource
[
idx
];
for
(
idx
=
0
;
idx
<
DEVICE_COUNT_MEM
;
idx
++
)
if
(
pnp_flags_valid
(
&
template
->
io_resource
[
idx
]))
config
->
request
.
mem_resource
[
idx
]
=
template
->
mem_resource
[
idx
];
return
0
;
return
0
;
}
}
static
int
pnp_generate_request
(
struct
pnp_dev
*
dev
,
struct
pnp_cfg
*
config
,
struct
pnp_res_cfg
*
template
)
/**
* pnp_init_resource_table - Resets a resource table to default values.
* @table: pointer to the desired resource table
*
*/
void
pnp_init_resource_table
(
struct
pnp_resource_table
*
table
)
{
{
int
i
,
err
;
int
idx
;
if
(
!
config
)
for
(
idx
=
0
;
idx
<
PNP_MAX_IRQ
;
idx
++
)
{
return
-
EINVAL
;
table
->
irq_resource
[
idx
].
name
=
NULL
;
if
((
err
=
pnp_prepare_request
(
dev
,
config
,
template
))
<
0
)
table
->
irq_resource
[
idx
].
start
=
-
1
;
return
err
;
table
->
irq_resource
[
idx
].
end
=
-
1
;
for
(
i
=
0
;
i
<=
7
;
i
++
)
table
->
irq_resource
[
idx
].
flags
=
0
;
{
if
(
pnp_generate_port
(
config
,
i
)
<
0
)
return
-
ENOENT
;
}
}
for
(
i
=
0
;
i
<=
3
;
i
++
)
for
(
idx
=
0
;
idx
<
PNP_MAX_DMA
;
idx
++
)
{
{
table
->
dma_resource
[
idx
].
name
=
NULL
;
if
(
pnp_generate_mem
(
config
,
i
)
<
0
)
table
->
dma_resource
[
idx
].
start
=
-
1
;
return
-
ENOENT
;
table
->
dma_resource
[
idx
].
end
=
-
1
;
table
->
dma_resource
[
idx
].
flags
=
0
;
}
}
for
(
i
=
0
;
i
<=
1
;
i
++
)
for
(
idx
=
0
;
idx
<
PNP_MAX_PORT
;
idx
++
)
{
{
table
->
port_resource
[
idx
].
name
=
NULL
;
if
(
pnp_generate_irq
(
config
,
i
)
<
0
)
table
->
port_resource
[
idx
].
start
=
0
;
return
-
ENOENT
;
table
->
port_resource
[
idx
].
end
=
0
;
table
->
port_resource
[
idx
].
flags
=
0
;
}
}
for
(
i
=
0
;
i
<=
1
;
i
++
)
for
(
idx
=
0
;
idx
<
PNP_MAX_MEM
;
idx
++
)
{
{
table
->
mem_resource
[
idx
].
name
=
NULL
;
if
(
pnp_generate_dma
(
config
,
i
)
<
0
)
table
->
mem_resource
[
idx
].
start
=
0
;
return
-
ENOENT
;
table
->
mem_resource
[
idx
].
end
=
0
;
table
->
mem_resource
[
idx
].
flags
=
0
;
}
}
return
0
;
}
}
/**
* pnp_generate_rule - Creates a rule table structure based on depnum and device.
* @dev: pointer to the desired device
* @depnum: dependent function, if not valid will return an error
* @rule: pointer to a rule structure to record data to
*
*/
static
struct
pnp_cfg
*
pnp_generate_config
(
struct
pnp_dev
*
dev
,
int
depnum
)
int
pnp_generate_rule
(
struct
pnp_dev
*
dev
,
int
depnum
,
struct
pnp_rule_table
*
rule
)
{
{
struct
pnp_cfg
*
config
;
int
nport
=
0
,
nirq
=
0
,
ndma
=
0
,
nmem
=
0
;
int
nport
=
0
,
nirq
=
0
,
ndma
=
0
,
nmem
=
0
;
struct
pnp_resources
*
res
;
struct
pnp_resources
*
res
;
struct
pnp_port
*
port
;
struct
pnp_port
*
port
;
struct
pnp_mem
*
mem
;
struct
pnp_mem
*
mem
;
struct
pnp_irq
*
irq
;
struct
pnp_irq
*
irq
;
struct
pnp_dma
*
dma
;
struct
pnp_dma
*
dma
;
if
(
!
dev
)
return
NULL
;
if
(
depnum
<=
0
||
!
rule
)
if
(
depnum
<
0
)
return
-
EINVAL
;
return
NULL
;
config
=
pnp_alloc
(
sizeof
(
struct
pnp_cfg
));
if
(
!
config
)
return
NULL
;
/* independent */
/* independent */
res
=
pnp_find_resources
(
dev
,
0
);
res
=
pnp_find_resources
(
dev
,
0
);
if
(
!
res
)
if
(
!
res
)
goto
fail
;
return
-
ENODEV
;
port
=
res
->
port
;
port
=
res
->
port
;
mem
=
res
->
mem
;
mem
=
res
->
mem
;
irq
=
res
->
irq
;
irq
=
res
->
irq
;
dma
=
res
->
dma
;
dma
=
res
->
dma
;
while
(
port
){
while
(
port
){
config
->
port
[
nport
]
=
port
;
rule
->
port
[
nport
]
=
port
;
nport
++
;
nport
++
;
port
=
port
->
next
;
port
=
port
->
next
;
}
}
while
(
mem
){
while
(
mem
){
config
->
mem
[
nmem
]
=
mem
;
rule
->
mem
[
nmem
]
=
mem
;
nmem
++
;
nmem
++
;
mem
=
mem
->
next
;
mem
=
mem
->
next
;
}
}
while
(
irq
){
while
(
irq
){
config
->
irq
[
nirq
]
=
irq
;
rule
->
irq
[
nirq
]
=
irq
;
nirq
++
;
nirq
++
;
irq
=
irq
->
next
;
irq
=
irq
->
next
;
}
}
while
(
dma
){
while
(
dma
){
config
->
dma
[
ndma
]
=
dma
;
rule
->
dma
[
ndma
]
=
dma
;
ndma
++
;
ndma
++
;
dma
=
dma
->
next
;
dma
=
dma
->
next
;
}
}
/* dependent */
/* dependent */
if
(
depnum
==
0
)
return
config
;
res
=
pnp_find_resources
(
dev
,
depnum
);
res
=
pnp_find_resources
(
dev
,
depnum
);
if
(
!
res
)
if
(
!
res
)
goto
fail
;
return
-
ENODEV
;
port
=
res
->
port
;
port
=
res
->
port
;
mem
=
res
->
mem
;
mem
=
res
->
mem
;
irq
=
res
->
irq
;
irq
=
res
->
irq
;
dma
=
res
->
dma
;
dma
=
res
->
dma
;
while
(
port
){
while
(
port
){
config
->
port
[
nport
]
=
port
;
rule
->
port
[
nport
]
=
port
;
nport
++
;
nport
++
;
port
=
port
->
next
;
port
=
port
->
next
;
}
}
while
(
mem
){
while
(
mem
){
config
->
mem
[
nmem
]
=
mem
;
rule
->
mem
[
nmem
]
=
mem
;
nmem
++
;
nmem
++
;
mem
=
mem
->
next
;
mem
=
mem
->
next
;
}
}
while
(
irq
){
while
(
irq
){
config
->
irq
[
nirq
]
=
irq
;
rule
->
irq
[
nirq
]
=
irq
;
nirq
++
;
nirq
++
;
irq
=
irq
->
next
;
irq
=
irq
->
next
;
}
}
while
(
dma
){
while
(
dma
){
config
->
dma
[
ndma
]
=
dma
;
rule
->
dma
[
ndma
]
=
dma
;
ndma
++
;
ndma
++
;
dma
=
dma
->
next
;
dma
=
dma
->
next
;
}
}
return
config
;
fail:
kfree
(
config
);
return
NULL
;
}
/* PnP Device Resource Management */
/**
* pnp_activate_dev - activates a PnP device for use
* @dev: pointer to the desired device
*
* finds the best resource configuration and then informs the correct pnp protocol
*/
int
pnp_activate_dev
(
struct
pnp_dev
*
dev
,
struct
pnp_res_cfg
*
template
)
{
int
depnum
,
max
;
struct
pnp_cfg
*
config
;
if
(
!
dev
)
return
-
EINVAL
;
max
=
pnp_get_max_depnum
(
dev
);
if
(
!
pnp_can_configure
(
dev
))
return
-
EBUSY
;
if
(
dev
->
status
!=
PNP_READY
&&
dev
->
status
!=
PNP_ATTACHED
){
printk
(
KERN_INFO
"pnp: Automatic configuration failed because the PnP device '%s' is busy
\n
"
,
dev
->
dev
.
bus_id
);
return
-
EINVAL
;
}
if
(
!
pnp_can_write
(
dev
))
return
-
EINVAL
;
if
(
max
==
0
)
return
0
;
for
(
depnum
=
1
;
depnum
<=
max
;
depnum
++
)
{
config
=
pnp_generate_config
(
dev
,
depnum
);
if
(
!
config
)
return
-
EINVAL
;
if
(
pnp_generate_request
(
dev
,
config
,
template
)
==
0
)
goto
done
;
kfree
(
config
);
}
printk
(
KERN_ERR
"pnp: Automatic configuration failed for device '%s' due to resource conflicts
\n
"
,
dev
->
dev
.
bus_id
);
return
-
ENOENT
;
done:
pnp_dbg
(
"the device '%s' has been activated"
,
dev
->
dev
.
bus_id
);
dev
->
protocol
->
set
(
dev
,
config
);
if
(
pnp_can_read
(
dev
))
dev
->
protocol
->
get
(
dev
);
kfree
(
config
);
return
0
;
}
/**
* pnp_disable_dev - disables device
* @dev: pointer to the desired device
*
* inform the correct pnp protocol so that resources can be used by other devices
*/
int
pnp_disable_dev
(
struct
pnp_dev
*
dev
)
{
if
(
!
dev
)
return
-
EINVAL
;
if
(
dev
->
status
!=
PNP_READY
){
printk
(
KERN_INFO
"pnp: Disable failed becuase the PnP device '%s' is busy
\n
"
,
dev
->
dev
.
bus_id
);
return
-
EINVAL
;
}
if
(
dev
->
lock_resources
)
return
-
EPERM
;
if
(
!
pnp_can_disable
(
dev
)
||
!
dev
->
active
)
return
-
EINVAL
;
pnp_dbg
(
"the device '%s' has been disabled"
,
dev
->
dev
.
bus_id
);
return
dev
->
protocol
->
disable
(
dev
);
}
/**
/* clear the remaining values */
* pnp_raw_set_dev - same as pnp_activate_dev except the resource config can be specified
for
(;
nport
<
PNP_MAX_PORT
;
nport
++
)
* @dev: pointer to the desired device
rule
->
port
[
nport
]
=
NULL
;
* @depnum: resource dependent function
for
(;
nmem
<
PNP_MAX_MEM
;
nmem
++
)
* @mode: static or dynamic
rule
->
mem
[
nmem
]
=
NULL
;
*
for
(;
nirq
<
PNP_MAX_IRQ
;
nirq
++
)
*/
rule
->
irq
[
nirq
]
=
NULL
;
for
(;
ndma
<
PNP_MAX_DMA
;
ndma
++
)
int
pnp_raw_set_dev
(
struct
pnp_dev
*
dev
,
int
depnum
,
struct
pnp_res_cfg
*
template
)
rule
->
dma
[
ndma
]
=
NULL
;
{
return
1
;
struct
pnp_cfg
*
config
;
if
(
!
dev
)
return
-
EINVAL
;
if
(
dev
->
status
!=
PNP_READY
){
printk
(
KERN_INFO
"pnp: Unable to set resources because the PnP device '%s' is busy
\n
"
,
dev
->
dev
.
bus_id
);
return
-
EINVAL
;
}
if
(
!
pnp_can_write
(
dev
)
||
!
pnp_can_configure
(
dev
))
return
-
EINVAL
;
config
=
pnp_generate_config
(
dev
,
depnum
);
if
(
!
config
)
return
-
EINVAL
;
if
(
pnp_generate_request
(
dev
,
config
,
template
)
==
0
)
goto
done
;
kfree
(
config
);
printk
(
KERN_ERR
"pnp: Manual configuration failed for device '%s' due to resource conflicts
\n
"
,
dev
->
dev
.
bus_id
);
return
-
ENOENT
;
done:
dev
->
protocol
->
set
(
dev
,
config
);
if
(
pnp_can_read
(
dev
))
dev
->
protocol
->
get
(
dev
);
kfree
(
config
);
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
,
unsigned
long
start
,
unsigned
long
size
)
{
if
(
resource
==
NULL
)
return
;
resource
->
flags
&=
~
(
IORESOURCE_AUTO
|
IORESOURCE_UNSET
);
resource
->
start
=
start
;
resource
->
end
=
start
+
size
-
1
;
}
EXPORT_SYMBOL
(
pnp_build_resource
);
EXPORT_SYMBOL
(
pnp_build_resource
);
EXPORT_SYMBOL
(
pnp_find_resources
);
EXPORT_SYMBOL
(
pnp_find_resources
);
...
@@ -900,11 +681,9 @@ EXPORT_SYMBOL(pnp_add_dma_resource);
...
@@ -900,11 +681,9 @@ EXPORT_SYMBOL(pnp_add_dma_resource);
EXPORT_SYMBOL
(
pnp_add_port_resource
);
EXPORT_SYMBOL
(
pnp_add_port_resource
);
EXPORT_SYMBOL
(
pnp_add_mem_resource
);
EXPORT_SYMBOL
(
pnp_add_mem_resource
);
EXPORT_SYMBOL
(
pnp_add_mem32_resource
);
EXPORT_SYMBOL
(
pnp_add_mem32_resource
);
EXPORT_SYMBOL
(
pnp_init_res_cfg
);
EXPORT_SYMBOL
(
pnp_init_resource_table
);
EXPORT_SYMBOL
(
pnp_activate_dev
);
EXPORT_SYMBOL
(
pnp_generate_rule
);
EXPORT_SYMBOL
(
pnp_disable_dev
);
EXPORT_SYMBOL
(
pnp_raw_set_dev
);
EXPORT_SYMBOL
(
pnp_resource_change
);
/* format is: allowdma0 */
/* format is: allowdma0 */
...
...
drivers/pnp/system.c
View file @
0d716f8c
...
@@ -53,7 +53,7 @@ static void __init reserve_resources_of_dev( struct pnp_dev *dev )
...
@@ -53,7 +53,7 @@ static void __init reserve_resources_of_dev( struct pnp_dev *dev )
{
{
int
i
;
int
i
;
for
(
i
=
0
;
i
<
DEVICE_COUNT_IO
;
i
++
)
{
for
(
i
=
0
;
i
<
PNP_MAX_PORT
;
i
++
)
{
if
(
pnp_port_valid
(
dev
,
i
))
if
(
pnp_port_valid
(
dev
,
i
))
/* end of resources */
/* end of resources */
continue
;
continue
;
...
...
drivers/serial/8250_pnp.c
View file @
0d716f8c
...
@@ -317,7 +317,7 @@ static inline void avoid_irq_share(struct pnp_dev *dev)
...
@@ -317,7 +317,7 @@ static inline void avoid_irq_share(struct pnp_dev *dev)
{
{
unsigned
int
map
=
0x1FF8
;
unsigned
int
map
=
0x1FF8
;
struct
pnp_irq
*
irq
;
struct
pnp_irq
*
irq
;
struct
pnp_resources
*
res
=
dev
->
res
;
struct
pnp_resources
*
res
=
dev
->
possible
;
serial8250_get_irq_map
(
&
map
);
serial8250_get_irq_map
(
&
map
);
...
@@ -357,10 +357,10 @@ static int __devinit check_name(char *name)
...
@@ -357,10 +357,10 @@ static int __devinit check_name(char *name)
*/
*/
static
int
serial_pnp_guess_board
(
struct
pnp_dev
*
dev
,
int
*
flags
)
static
int
serial_pnp_guess_board
(
struct
pnp_dev
*
dev
,
int
*
flags
)
{
{
struct
pnp_resources
*
res
=
dev
->
res
;
struct
pnp_resources
*
res
=
dev
->
possible
;
struct
pnp_resources
*
resa
;
struct
pnp_resources
*
resa
;
if
(
!
(
check_name
(
dev
->
name
)
||
(
dev
->
card
&&
check_name
(
dev
->
card
->
name
))))
if
(
!
(
check_name
(
dev
->
dev
.
name
)
||
(
dev
->
card
&&
check_name
(
dev
->
card
->
dev
.
name
))))
return
-
ENODEV
;
return
-
ENODEV
;
if
(
!
res
)
if
(
!
res
)
...
...
include/linux/ioport.h
View file @
0d716f8c
...
@@ -77,6 +77,7 @@ struct resource_list {
...
@@ -77,6 +77,7 @@ struct resource_list {
#define IORESOURCE_MEM_8BIT (0<<3)
#define IORESOURCE_MEM_8BIT (0<<3)
#define IORESOURCE_MEM_16BIT (1<<3)
#define IORESOURCE_MEM_16BIT (1<<3)
#define IORESOURCE_MEM_8AND16BIT (2<<3)
#define IORESOURCE_MEM_8AND16BIT (2<<3)
#define IORESOURCE_MEM_32BIT (3<<3)
#define IORESOURCE_MEM_SHADOWABLE (1<<5)
/* dup: IORESOURCE_SHADOWABLE */
#define IORESOURCE_MEM_SHADOWABLE (1<<5)
/* dup: IORESOURCE_SHADOWABLE */
#define IORESOURCE_MEM_EXPANSIONROM (1<<6)
#define IORESOURCE_MEM_EXPANSIONROM (1<<6)
...
...
include/linux/pnp.h
View file @
0d716f8c
...
@@ -13,42 +13,144 @@
...
@@ -13,42 +13,144 @@
#include <linux/list.h>
#include <linux/list.h>
#include <linux/errno.h>
#include <linux/errno.h>
#define PNP_MAX_PORT 8
#define PNP_MAX_MEM 4
#define PNP_MAX_IRQ 2
#define PNP_MAX_DMA 2
#define PNP_MAX_DEVICES 8
#define PNP_ID_LEN 8
struct
pnp_protocol
;
struct
pnp_dev
;
/*
/*
*
Device Managem
nt
*
Resource Manageme
nt
*/
*/
#define DEVICE_COUNT_IRQ 2
/* Use these instead of directly reading pnp_dev to get resource information */
#define DEVICE_COUNT_DMA 2
#define pnp_port_start(dev,bar) ((dev)->res.port_resource[(bar)].start)
#define DEVICE_COUNT_IO 8
#define pnp_port_end(dev,bar) ((dev)->res.port_resource[(bar)].end)
#define DEVICE_COUNT_MEM 4
#define pnp_port_flags(dev,bar) ((dev)->res.port_resource[(bar)].flags)
#define MAX_DEVICES 8
#define pnp_port_valid(dev,bar) (pnp_port_flags((dev),(bar)) & 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)
#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)
#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)
#define PNP_PORT_FLAG_16BITADDR (1<<0)
#define PNP_PORT_FLAG_FIXED (1<<1)
struct
pnp_port
{
unsigned
short
min
;
/* min base number */
unsigned
short
max
;
/* max base number */
unsigned
char
align
;
/* align boundary */
unsigned
char
size
;
/* size of range */
unsigned
char
flags
;
/* port flags */
unsigned
char
pad
;
/* pad */
struct
pnp_port
*
next
;
/* next port */
};
struct
pnp_irq
{
unsigned
short
map
;
/* bitmaks for IRQ lines */
unsigned
char
flags
;
/* IRQ flags */
unsigned
char
pad
;
/* pad */
struct
pnp_irq
*
next
;
/* next IRQ */
};
struct
pnp_dma
{
unsigned
char
map
;
/* bitmask for DMA channels */
unsigned
char
flags
;
/* DMA flags */
struct
pnp_dma
*
next
;
/* next port */
};
struct
pnp_mem
{
unsigned
int
min
;
/* min base number */
unsigned
int
max
;
/* max base number */
unsigned
int
align
;
/* align boundary */
unsigned
int
size
;
/* size of range */
unsigned
char
flags
;
/* memory flags */
unsigned
char
pad
;
/* pad */
struct
pnp_mem
*
next
;
/* next memory resource */
};
#define PNP_RES_PRIORITY_PREFERRED 0
#define PNP_RES_PRIORITY_ACCEPTABLE 1
#define PNP_RES_PRIORITY_FUNCTIONAL 2
#define PNP_RES_PRIORITY_INVALID 65535
struct
pnp_resources
{
unsigned
short
priority
;
/* priority */
struct
pnp_port
*
port
;
/* first port */
struct
pnp_irq
*
irq
;
/* first IRQ */
struct
pnp_dma
*
dma
;
/* first DMA */
struct
pnp_mem
*
mem
;
/* first memory resource */
struct
pnp_dev
*
dev
;
/* parent */
struct
pnp_resources
*
dep
;
/* dependent resources */
};
struct
pnp_rule_table
{
int
depnum
;
struct
pnp_port
*
port
[
PNP_MAX_PORT
];
struct
pnp_irq
*
irq
[
PNP_MAX_IRQ
];
struct
pnp_dma
*
dma
[
PNP_MAX_DMA
];
struct
pnp_mem
*
mem
[
PNP_MAX_MEM
];
};
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
];
};
struct
pnp_resource
;
struct
pnp_protocol
;
/*
struct
pnp_id
;
* Device Managemnt
struct
pnp_cfg
;
*/
struct
pnp_card
{
struct
pnp_card
{
char
name
[
80
];
struct
device
dev
;
/* Driver Model device interface */
int
status
;
/* status of the card */
unsigned
char
number
;
/* used as an index, must be unique */
unsigned
char
number
;
/* card number */
struct
list_head
global_list
;
/* node in global list of cards */
struct
list_head
global_list
;
/* node in global list of cards */
struct
list_head
protocol_list
;
/* node in protocol's list of cards */
struct
list_head
protocol_list
;
/* node in protocol's list of cards */
struct
list_head
devices
;
/* devices attached to the card */
struct
list_head
devices
;
/* devices attached to the card */
struct
list_head
rdevs
;
/* a list of devices requested by the card driver */
int
status
;
struct
pnp_protocol
*
protocol
;
struct
pnp_protocol
*
protocol
;
struct
pnpc_driver
*
driver
;
struct
pnp_id
*
id
;
/* contains supported EISA IDs*/
struct
pnp_id
*
id
;
/* contains supported EISA IDs*/
void
*
protocol_data
;
/* Used to store protocol specific data */
unsigned
char
pnpver
;
/* Plug & Play version */
unsigned
char
pnpver
;
/* Plug & Play version */
unsigned
char
productver
;
/* product version */
unsigned
char
productver
;
/* product version */
unsigned
int
serial
;
/* serial number */
unsigned
int
serial
;
/* serial number */
unsigned
char
checksum
;
/* if zero - checksum passed */
unsigned
char
checksum
;
/* if zero - checksum passed */
void
*
protocol_data
;
/* Used to store protocol specific data */
struct
pnpc_driver
*
driver
;
/* pointer to the driver bound to this device */
struct
list_head
rdevs
;
/* a list of devices requested by the card driver */
struct
proc_dir_entry
*
procdir
;
/* directory entry in /proc/bus/isapnp */
struct
proc_dir_entry
*
procdir
;
/* directory entry in /proc/bus/isapnp */
struct
device
dev
;
/* Driver Model device interface */
};
};
#define global_to_pnp_card(n) list_entry(n, struct pnp_card, global_list)
#define global_to_pnp_card(n) list_entry(n, struct pnp_card, global_list)
...
@@ -58,10 +160,6 @@ struct pnp_card {
...
@@ -58,10 +160,6 @@ struct pnp_card {
for((card) = global_to_pnp_card(pnp_cards.next); \
for((card) = global_to_pnp_card(pnp_cards.next); \
(card) != global_to_pnp_card(&pnp_cards); \
(card) != global_to_pnp_card(&pnp_cards); \
(card) = global_to_pnp_card((card)->global_list.next))
(card) = global_to_pnp_card((card)->global_list.next))
#define pnp_card_for_each_dev(card,dev) \
for((dev) = card_to_pnp_dev((card)->devices.next); \
(dev) != card_to_pnp_dev(&(card)->devices); \
(dev) = card_to_pnp_dev((dev)->card_list.next))
static
inline
void
*
pnpc_get_drvdata
(
struct
pnp_card
*
pcard
)
static
inline
void
*
pnpc_get_drvdata
(
struct
pnp_card
*
pcard
)
{
{
...
@@ -84,8 +182,9 @@ static inline void pnpc_set_protodata (struct pnp_card *pcard, void *data)
...
@@ -84,8 +182,9 @@ static inline void pnpc_set_protodata (struct pnp_card *pcard, void *data)
}
}
struct
pnp_dev
{
struct
pnp_dev
{
char
name
[
80
];
/* device name */
struct
device
dev
;
/* Driver Model device interface */
int
active
;
/* status of the device */
unsigned
char
number
;
/* used as an index, must be unique */
int
active
;
int
capabilities
;
int
capabilities
;
int
status
;
int
status
;
...
@@ -93,24 +192,20 @@ struct pnp_dev {
...
@@ -93,24 +192,20 @@ struct pnp_dev {
struct
list_head
protocol_list
;
/* node in list of device's protocol */
struct
list_head
protocol_list
;
/* node in list of device's protocol */
struct
list_head
card_list
;
/* node in card's list of devices */
struct
list_head
card_list
;
/* node in card's list of devices */
struct
list_head
rdev_list
;
/* node in cards list of requested devices */
struct
list_head
rdev_list
;
/* node in cards list of requested devices */
struct
pnp_protocol
*
protocol
;
struct
pnp_protocol
*
protocol
;
struct
pnp_card
*
card
;
struct
pnp_card
*
card
;
/* card the device is attached to, none if NULL */
struct
pnp_id
*
id
;
/* contains supported EISA IDs*/
struct
pnp_driver
*
driver
;
struct
pnp_id
*
id
;
/* supported EISA IDs*/
struct
pnp_resource_table
res
;
/* contains the currently chosen resources */
struct
pnp_resources
*
possible
;
/* a list of possible resources */
struct
pnp_rule_table
*
rule
;
/* the current possible resource set */
int
config_mode
;
/* flags that determine how the device's resources should be configured */
void
*
protocol_data
;
/* Used to store protocol specific data */
void
*
protocol_data
;
/* Used to store protocol specific data */
unsigned
char
number
;
/* must be unique */
unsigned
short
regs
;
/* ISAPnP: supported registers */
unsigned
short
regs
;
/* ISAPnP: supported registers */
int
flags
;
/* used by protocols */
struct
pnp_resources
*
res
;
/* possible resource information */
int
lock_resources
;
/* resources are locked */
struct
resource
io_resource
[
DEVICE_COUNT_IO
];
/* port regions */
struct
resource
mem_resource
[
DEVICE_COUNT_MEM
];
/* memory regions + expansion ROMs */
struct
resource
dma_resource
[
DEVICE_COUNT_DMA
];
struct
resource
irq_resource
[
DEVICE_COUNT_IRQ
];
struct
pnp_driver
*
driver
;
/* pointer to the driver bound to this device */
struct
device
dev
;
/* Driver Model device interface */
int
flags
;
/* used by protocols */
struct
proc_dir_entry
*
procent
;
/* device entry in /proc/bus/isapnp */
struct
proc_dir_entry
*
procent
;
/* device entry in /proc/bus/isapnp */
};
};
...
@@ -119,13 +214,14 @@ struct pnp_dev {
...
@@ -119,13 +214,14 @@ struct pnp_dev {
#define protocol_to_pnp_dev(n) list_entry(n, struct pnp_dev, protocol_list)
#define protocol_to_pnp_dev(n) list_entry(n, struct pnp_dev, protocol_list)
#define to_pnp_dev(n) container_of(n, struct pnp_dev, dev)
#define to_pnp_dev(n) container_of(n, struct pnp_dev, dev)
#define pnp_for_each_dev(dev) \
#define pnp_for_each_dev(dev) \
for(
dev
= global_to_pnp_dev(pnp_global.next); \
for(
(dev)
= global_to_pnp_dev(pnp_global.next); \
dev
!= global_to_pnp_dev(&pnp_global); \
(dev)
!= global_to_pnp_dev(&pnp_global); \
dev = global_to_pnp_dev(dev
->global_list.next))
(dev) = global_to_pnp_dev((dev)
->global_list.next))
#define card_for_each_dev(card,dev) \
#define card_for_each_dev(card,dev) \
for((dev) = card_to_pnp_dev((card)->devices.next); \
for((dev) = card_to_pnp_dev((card)->devices.next); \
(dev) != card_to_pnp_dev(&(card)->devices); \
(dev) != card_to_pnp_dev(&(card)->devices); \
(dev) = card_to_pnp_dev((dev)->card_list.next))
(dev) = card_to_pnp_dev((dev)->card_list.next))
#define pnp_dev_name(dev) (dev)->dev.name
static
inline
void
*
pnp_get_drvdata
(
struct
pnp_dev
*
pdev
)
static
inline
void
*
pnp_get_drvdata
(
struct
pnp_dev
*
pdev
)
{
{
...
@@ -152,6 +248,12 @@ struct pnp_fixup {
...
@@ -152,6 +248,12 @@ struct pnp_fixup {
void
(
*
quirk_function
)(
struct
pnp_dev
*
dev
);
/* fixup function */
void
(
*
quirk_function
)(
struct
pnp_dev
*
dev
);
/* fixup function */
};
};
/* config modes */
#define PNP_CONFIG_AUTO 0x0001
/* Use the Resource Configuration Engine to determine resource settings */
#define PNP_CONFIG_MANUAL 0x0002
/* the config has been manually specified */
#define PNP_CONFIG_FORCE 0x0004
/* disables validity checking */
#define PNP_CONFIG_INVALID 0x0008
/* If this flag is set, the pnp layer will refuse to activate the device */
/* capabilities */
/* capabilities */
#define PNP_READ 0x0001
#define PNP_READ 0x0001
#define PNP_WRITE 0x0002
#define PNP_WRITE 0x0002
...
@@ -165,14 +267,14 @@ struct pnp_fixup {
...
@@ -165,14 +267,14 @@ struct pnp_fixup {
((dev)->capabilities & PNP_WRITE))
((dev)->capabilities & PNP_WRITE))
#define pnp_can_disable(dev) (((dev)->protocol) && ((dev)->protocol->disable) && \
#define pnp_can_disable(dev) (((dev)->protocol) && ((dev)->protocol->disable) && \
((dev)->capabilities & PNP_DISABLE))
((dev)->capabilities & PNP_DISABLE))
#define pnp_can_configure(dev) ((!(dev)->active) && ((dev)->capabilities & PNP_CONFIGURABLE))
#define pnp_can_configure(dev) ((!(dev)->active) && ((dev)->config_mode & PNP_CONFIG_AUTO) && \
((dev)->capabilities & PNP_CONFIGURABLE))
/* status */
/* status */
#define PNP_INIT 0x0000
#define PNP_READY 0x0000
#define PNP_READY 0x0001
#define PNP_ATTACHED 0x0001
#define PNP_ATTACHED 0x0002
#define PNP_BUSY 0x0002
#define PNP_BUSY 0x0004
#define PNP_FAULTY 0x0004
#define PNP_FAULTY 0x0008
/*
/*
...
@@ -180,21 +282,21 @@ struct pnp_fixup {
...
@@ -180,21 +282,21 @@ struct pnp_fixup {
*/
*/
struct
pnp_id
{
struct
pnp_id
{
char
id
[
7
];
char
id
[
PNP_ID_LEN
];
struct
pnp_id
*
next
;
struct
pnp_id
*
next
;
};
};
struct
pnp_device_id
{
struct
pnp_device_id
{
char
id
[
7
];
char
id
[
PNP_ID_LEN
];
unsigned
long
driver_data
;
/* data private to the driver */
unsigned
long
driver_data
;
/* data private to the driver */
};
};
struct
pnp_card_
device_
id
{
struct
pnp_card_id
{
char
id
[
7
];
char
id
[
PNP_ID_LEN
];
unsigned
long
driver_data
;
/* data private to the driver */
unsigned
long
driver_data
;
/* data private to the driver */
struct
{
struct
{
char
id
[
7
];
char
id
[
PNP_ID_LEN
];
}
devs
[
MAX_DEVICES
];
/* logical devices */
}
devs
[
PNP_MAX_DEVICES
];
/* logical devices */
};
};
#define PNP_DRIVER_DO_NOT_ACTIVATE (1<<0)
#define PNP_DRIVER_DO_NOT_ACTIVATE (1<<0)
...
@@ -216,9 +318,9 @@ struct pnp_driver {
...
@@ -216,9 +318,9 @@ struct pnp_driver {
struct
pnpc_driver
{
struct
pnpc_driver
{
struct
list_head
node
;
struct
list_head
node
;
char
*
name
;
char
*
name
;
const
struct
pnp_card_
device_
id
*
id_table
;
const
struct
pnp_card_id
*
id_table
;
unsigned
int
flags
;
unsigned
int
flags
;
int
(
*
probe
)
(
struct
pnp_card
*
card
,
const
struct
pnp_card_
device_
id
*
card_id
);
int
(
*
probe
)
(
struct
pnp_card
*
card
,
const
struct
pnp_card_id
*
card_id
);
void
(
*
remove
)
(
struct
pnp_card
*
card
);
void
(
*
remove
)
(
struct
pnp_card
*
card
);
struct
device_driver
driver
;
struct
device_driver
driver
;
};
};
...
@@ -227,135 +329,16 @@ struct pnpc_driver {
...
@@ -227,135 +329,16 @@ struct pnpc_driver {
/*
/*
* Resource Management
*/
#define pnp_flags_valid(resrc) (((resrc)->flags & IORESOURCE_UNSET) == 0 && \
((resrc)->flags & (IORESOURCE_IO|IORESOURCE_MEM|IORESOURCE_IRQ|IORESOURCE_DMA)) != 0)
/* Use these instead of directly reading pnp_dev to get resource information */
#define pnp_port_start(dev,bar) ((dev)->io_resource[(bar)].start)
#define pnp_port_end(dev,bar) ((dev)->io_resource[(bar)].end)
#define pnp_port_flags(dev,bar) ((dev)->io_resource[(bar)].flags)
#define pnp_port_valid(dev,bar) pnp_flags_valid(&(dev)->io_resource[(bar)])
#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)->mem_resource[(bar)].start)
#define pnp_mem_end(dev,bar) ((dev)->mem_resource[(bar)].end)
#define pnp_mem_flags(dev,bar) ((dev)->mem_resource[(bar)].flags)
#define pnp_mem_valid(dev,bar) pnp_flags_valid(&(dev)->mem_resource[(bar)])
#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)->irq_resource[(bar)].start)
#define pnp_irq_flags(dev,bar) ((dev)->irq_resource[(bar)].flags)
#define pnp_irq_valid(dev,bar) pnp_flags_valid(&(dev)->irq_resource[(bar)])
#define pnp_dma(dev,bar) ((dev)->dma_resource[(bar)].start)
#define pnp_dma_flags(dev,bar) ((dev)->dma_resource[(bar)].flags)
#define pnp_dma_valid(dev,bar) pnp_flags_valid(&(dev)->dma_resource[(bar)])
#define PNP_PORT_FLAG_16BITADDR (1<<0)
#define PNP_PORT_FLAG_FIXED (1<<1)
struct
pnp_port
{
unsigned
short
min
;
/* min base number */
unsigned
short
max
;
/* max base number */
unsigned
char
align
;
/* align boundary */
unsigned
char
size
;
/* size of range */
unsigned
char
flags
;
/* port flags */
unsigned
char
pad
;
/* pad */
struct
pnp_resources
*
res
;
/* parent */
struct
pnp_port
*
next
;
/* next port */
};
struct
pnp_irq
{
unsigned
short
map
;
/* bitmaks for IRQ lines */
unsigned
char
flags
;
/* IRQ flags */
unsigned
char
pad
;
/* pad */
struct
pnp_resources
*
res
;
/* parent */
struct
pnp_irq
*
next
;
/* next IRQ */
};
struct
pnp_dma
{
unsigned
char
map
;
/* bitmask for DMA channels */
unsigned
char
flags
;
/* DMA flags */
struct
pnp_resources
*
res
;
/* parent */
struct
pnp_dma
*
next
;
/* next port */
};
struct
pnp_mem
{
unsigned
int
min
;
/* min base number */
unsigned
int
max
;
/* max base number */
unsigned
int
align
;
/* align boundary */
unsigned
int
size
;
/* size of range */
unsigned
char
flags
;
/* memory flags */
unsigned
char
pad
;
/* pad */
struct
pnp_resources
*
res
;
/* parent */
struct
pnp_mem
*
next
;
/* next memory resource */
};
struct
pnp_mem32
{
unsigned
char
data
[
17
];
struct
pnp_resources
*
res
;
/* parent */
struct
pnp_mem32
*
next
;
/* next 32-bit memory resource */
};
#define PNP_RES_PRIORITY_PREFERRED 0
#define PNP_RES_PRIORITY_ACCEPTABLE 1
#define PNP_RES_PRIORITY_FUNCTIONAL 2
#define PNP_RES_PRIORITY_INVALID 65535
struct
pnp_resources
{
unsigned
short
priority
;
/* priority */
unsigned
short
dependent
;
/* dependent resources */
struct
pnp_port
*
port
;
/* first port */
struct
pnp_irq
*
irq
;
/* first IRQ */
struct
pnp_dma
*
dma
;
/* first DMA */
struct
pnp_mem
*
mem
;
/* first memory resource */
struct
pnp_mem32
*
mem32
;
/* first 32-bit memory */
struct
pnp_dev
*
dev
;
/* parent */
struct
pnp_resources
*
dep
;
/* dependent resources */
};
struct
pnp_res_cfg
{
struct
resource
io_resource
[
DEVICE_COUNT_IO
];
/* I/O ports */
struct
resource
mem_resource
[
DEVICE_COUNT_MEM
];
/* memory regions + expansion ROMs */
struct
resource
dma_resource
[
DEVICE_COUNT_DMA
];
struct
resource
irq_resource
[
DEVICE_COUNT_IRQ
];
};
struct
pnp_cfg
{
struct
pnp_port
*
port
[
8
];
struct
pnp_irq
*
irq
[
2
];
struct
pnp_dma
*
dma
[
2
];
struct
pnp_mem
*
mem
[
4
];
struct
pnp_res_cfg
request
;
};
/*
* Protocol Management
* Protocol Management
*/
*/
struct
pnp_protocol
{
struct
pnp_protocol
{
struct
list_head
protocol_list
;
struct
list_head
protocol_list
;
char
name
[
DEVICE_NAME_SIZE
]
;
char
*
name
;
/* functions */
/*
resource control
functions */
int
(
*
get
)(
struct
pnp_dev
*
dev
);
int
(
*
get
)(
struct
pnp_dev
*
dev
,
struct
pnp_resource_table
*
res
);
int
(
*
set
)(
struct
pnp_dev
*
dev
,
struct
pnp_
cfg
*
config
);
int
(
*
set
)(
struct
pnp_dev
*
dev
,
struct
pnp_
resource_table
*
res
);
int
(
*
disable
)(
struct
pnp_dev
*
dev
);
int
(
*
disable
)(
struct
pnp_dev
*
dev
);
/* used by pnp layer only (look but don't touch) */
/* used by pnp layer only (look but don't touch) */
...
@@ -384,6 +367,8 @@ void pnp_unregister_protocol(struct pnp_protocol *protocol);
...
@@ -384,6 +367,8 @@ void pnp_unregister_protocol(struct pnp_protocol *protocol);
int
pnp_add_device
(
struct
pnp_dev
*
dev
);
int
pnp_add_device
(
struct
pnp_dev
*
dev
);
void
pnp_remove_device
(
struct
pnp_dev
*
dev
);
void
pnp_remove_device
(
struct
pnp_dev
*
dev
);
extern
struct
list_head
pnp_global
;
extern
struct
list_head
pnp_global
;
int
pnp_device_attach
(
struct
pnp_dev
*
pnp_dev
);
void
pnp_device_detach
(
struct
pnp_dev
*
pnp_dev
);
/* resource */
/* resource */
struct
pnp_resources
*
pnp_build_resource
(
struct
pnp_dev
*
dev
,
int
dependent
);
struct
pnp_resources
*
pnp_build_resource
(
struct
pnp_dev
*
dev
,
int
dependent
);
...
@@ -393,29 +378,42 @@ int pnp_add_irq_resource(struct pnp_dev *dev, int depnum, struct pnp_irq *data);
...
@@ -393,29 +378,42 @@ int pnp_add_irq_resource(struct pnp_dev *dev, int depnum, struct pnp_irq *data);
int
pnp_add_dma_resource
(
struct
pnp_dev
*
dev
,
int
depnum
,
struct
pnp_dma
*
data
);
int
pnp_add_dma_resource
(
struct
pnp_dev
*
dev
,
int
depnum
,
struct
pnp_dma
*
data
);
int
pnp_add_port_resource
(
struct
pnp_dev
*
dev
,
int
depnum
,
struct
pnp_port
*
data
);
int
pnp_add_port_resource
(
struct
pnp_dev
*
dev
,
int
depnum
,
struct
pnp_port
*
data
);
int
pnp_add_mem_resource
(
struct
pnp_dev
*
dev
,
int
depnum
,
struct
pnp_mem
*
data
);
int
pnp_add_mem_resource
(
struct
pnp_dev
*
dev
,
int
depnum
,
struct
pnp_mem
*
data
);
int
pnp_add_mem32_resource
(
struct
pnp_dev
*
dev
,
int
depnum
,
struct
pnp_mem32
*
data
);
void
pnp_init_resource_table
(
struct
pnp_resource_table
*
table
);
int
pnp_init_res_cfg
(
struct
pnp_res_cfg
*
template
);
int
pnp_generate_rule
(
struct
pnp_dev
*
dev
,
int
depnum
,
struct
pnp_rule_table
*
rule
);
int
pnp_activate_dev
(
struct
pnp_dev
*
dev
,
struct
pnp_res_cfg
*
template
);
/* manager */
int
pnp_activate_dev
(
struct
pnp_dev
*
dev
);
int
pnp_disable_dev
(
struct
pnp_dev
*
dev
);
int
pnp_disable_dev
(
struct
pnp_dev
*
dev
);
int
pnp_raw_set_dev
(
struct
pnp_dev
*
dev
,
int
depnum
,
struct
pnp_res_cfg
*
template
);
void
pnp_resource_change
(
struct
resource
*
resource
,
unsigned
long
start
,
unsigned
long
size
);
void
pnp_resource_change
(
struct
resource
*
resource
,
unsigned
long
start
,
unsigned
long
size
);
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
);
/* driver */
/* driver */
int
compare_pnp_id
(
struct
pnp_id
*
pos
,
const
char
*
id
);
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_add_id
(
struct
pnp_id
*
id
,
struct
pnp_dev
*
dev
);
int
pnp_register_driver
(
struct
pnp_driver
*
drv
);
int
pnp_register_driver
(
struct
pnp_driver
*
drv
);
void
pnp_unregister_driver
(
struct
pnp_driver
*
drv
);
void
pnp_unregister_driver
(
struct
pnp_driver
*
drv
);
int
pnp_device_attach
(
struct
pnp_dev
*
pnp_dev
);
void
pnp_device_detach
(
struct
pnp_dev
*
pnp_dev
);
/* support */
int
pnp_is_active
(
struct
pnp_dev
*
dev
);
unsigned
char
*
pnp_parse_current_resources
(
unsigned
char
*
p
,
unsigned
char
*
end
,
struct
pnp_resource_table
*
res
);
unsigned
char
*
pnp_parse_possible_resources
(
unsigned
char
*
p
,
unsigned
char
*
end
,
struct
pnp_dev
*
dev
);
unsigned
char
*
pnp_write_resources
(
unsigned
char
*
p
,
unsigned
char
*
end
,
struct
pnp_resource_table
*
res
);
#else
#else
/* just in case anyone decides to call these without PnP Support Enabled */
/* just in case anyone decides to call these without PnP Support Enabled */
/* core */
static
inline
int
pnp_register_protocol
(
struct
pnp_protocol
*
protocol
)
{
return
-
ENODEV
;
}
static
inline
int
pnp_register_protocol
(
struct
pnp_protocol
*
protocol
)
{
return
-
ENODEV
;
}
static
inline
void
pnp_unregister_protocol
(
struct
pnp_protocol
*
protocol
)
{
}
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_init_device
(
struct
pnp_dev
*
dev
)
{
return
-
ENODEV
;
}
static
inline
int
pnp_add_device
(
struct
pnp_dev
*
dev
)
{
return
-
ENODEV
;
}
static
inline
int
pnp_add_device
(
struct
pnp_dev
*
dev
)
{
return
-
ENODEV
;
}
static
inline
void
pnp_remove_device
(
struct
pnp_dev
*
dev
)
{
}
static
inline
void
pnp_remove_device
(
struct
pnp_dev
*
dev
)
{
}
static
inline
int
pnp_device_attach
(
struct
pnp_dev
*
pnp_dev
)
{
return
-
ENODEV
;
}
static
inline
void
pnp_device_detach
(
struct
pnp_dev
*
pnp_dev
)
{
;
}
/* resource */
static
inline
struct
pnp_resources
*
pnp_build_resource
(
struct
pnp_dev
*
dev
,
int
dependent
)
{
return
NULL
;
}
static
inline
struct
pnp_resources
*
pnp_build_resource
(
struct
pnp_dev
*
dev
,
int
dependent
)
{
return
NULL
;
}
static
inline
struct
pnp_resources
*
pnp_find_resources
(
struct
pnp_dev
*
dev
,
int
depnum
)
{
return
NULL
;
}
static
inline
struct
pnp_resources
*
pnp_find_resources
(
struct
pnp_dev
*
dev
,
int
depnum
)
{
return
NULL
;
}
static
inline
int
pnp_get_max_depnum
(
struct
pnp_dev
*
dev
)
{
return
-
ENODEV
;
}
static
inline
int
pnp_get_max_depnum
(
struct
pnp_dev
*
dev
)
{
return
-
ENODEV
;
}
...
@@ -423,19 +421,27 @@ static inline int pnp_add_irq_resource(struct pnp_dev *dev, int depnum, struct p
...
@@ -423,19 +421,27 @@ static inline int pnp_add_irq_resource(struct pnp_dev *dev, int depnum, struct p
static
inline
int
pnp_add_dma_resource
(
struct
pnp_dev
*
dev
,
int
depnum
,
struct
pnp_irq
*
data
)
{
return
-
ENODEV
;
}
static
inline
int
pnp_add_dma_resource
(
struct
pnp_dev
*
dev
,
int
depnum
,
struct
pnp_irq
*
data
)
{
return
-
ENODEV
;
}
static
inline
int
pnp_add_port_resource
(
struct
pnp_dev
*
dev
,
int
depnum
,
struct
pnp_irq
*
data
)
{
return
-
ENODEV
;
}
static
inline
int
pnp_add_port_resource
(
struct
pnp_dev
*
dev
,
int
depnum
,
struct
pnp_irq
*
data
)
{
return
-
ENODEV
;
}
static
inline
int
pnp_add_mem_resource
(
struct
pnp_dev
*
dev
,
int
depnum
,
struct
pnp_irq
*
data
)
{
return
-
ENODEV
;
}
static
inline
int
pnp_add_mem_resource
(
struct
pnp_dev
*
dev
,
int
depnum
,
struct
pnp_irq
*
data
)
{
return
-
ENODEV
;
}
static
inline
int
pnp_add_mem32_resource
(
struct
pnp_dev
*
dev
,
int
depnum
,
struct
pnp_irq
*
data
)
{
return
-
ENODEV
;
}
static
inline
void
pnp_init_resource_table
(
struct
pnp_resource_table
*
table
)
{
;
}
static
inline
int
pnp_init_res_cfg
(
struct
pnp_res_cfg
*
template
)
{
return
-
ENODEV
;
}
static
inline
int
pnp_generate_rule
(
struct
pnp_dev
*
dev
,
int
depnum
,
struct
pnp_rule_table
*
rule
)
{
return
-
ENODEV
;
}
static
inline
int
pnp_activate_dev
(
struct
pnp_dev
*
dev
,
struct
pnp_res_cfg
*
template
)
{
return
-
ENODEV
;
}
/* manager */
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
int
pnp_disable_dev
(
struct
pnp_dev
*
dev
)
{
return
-
ENODEV
;
}
static
inline
int
pnp_raw_set_dev
(
struct
pnp_dev
*
dev
,
int
depnum
,
struct
pnp_res_cfg
*
template
)
{
return
-
ENODEV
;
}
static
inline
void
pnp_resource_change
(
struct
resource
*
resource
,
unsigned
long
start
,
unsigned
long
size
)
{
;
}
static
inline
void
pnp_resource_change
(
struct
resource
*
resource
,
unsigned
long
start
,
unsigned
long
size
)
{
;
}
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
;
}
/* driver */
static
inline
int
compare_pnp_id
(
struct
list_head
*
id_list
,
const
char
*
id
)
{
return
-
ENODEV
;
}
static
inline
int
compare_pnp_id
(
struct
list_head
*
id_list
,
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_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
int
pnp_register_driver
(
struct
pnp_driver
*
drv
)
{
return
-
ENODEV
;
}
static
inline
void
pnp_unregister_driver
(
struct
pnp_driver
*
drv
)
{
;
}
static
inline
void
pnp_unregister_driver
(
struct
pnp_driver
*
drv
)
{
;
}
static
inline
int
pnp_device_attach
(
struct
pnp_dev
*
pnp_dev
)
{
return
-
ENODEV
;
}
/* support */
static
inline
void
pnp_device_detach
(
struct
pnp_dev
*
pnp_dev
)
{
;
}
static
inline
int
pnp_is_active
(
struct
pnp_dev
*
dev
)
{
return
-
ENODEV
;
)
static
inline
unsigned
char
*
pnp_parse_current_resources
(
unsigned
char
*
p
,
unsigned
char
*
end
,
struct
pnp_resource_table
*
res
)
{
return
NULL
;
}
static
inline
unsigned
char
*
pnp_parse_possible_resources
(
unsigned
char
*
p
,
unsigned
char
*
end
,
struct
pnp_dev
*
dev
)
{
return
NULL
;
}
static
inline
unsigned
char
*
pnp_write_resources
(
unsigned
char
*
p
,
unsigned
char
*
end
,
struct
pnp_resource_table
*
res
)
{
return
NULL
;
)
#endif
/* CONFIG_PNP */
#endif
/* CONFIG_PNP */
...
@@ -458,6 +464,7 @@ void pnpc_detach(struct pnp_card *card);
...
@@ -458,6 +464,7 @@ void pnpc_detach(struct pnp_card *card);
#else
#else
/* card */
static
inline
int
pnpc_add_card
(
struct
pnp_card
*
card
)
{
return
-
ENODEV
;
}
static
inline
int
pnpc_add_card
(
struct
pnp_card
*
card
)
{
return
-
ENODEV
;
}
static
inline
void
pnpc_remove_card
(
struct
pnp_card
*
card
)
{
;
}
static
inline
void
pnpc_remove_card
(
struct
pnp_card
*
card
)
{
;
}
static
inline
int
pnpc_add_device
(
struct
pnp_card
*
card
,
struct
pnp_dev
*
dev
)
{
return
-
ENODEV
;
}
static
inline
int
pnpc_add_device
(
struct
pnp_card
*
card
,
struct
pnp_dev
*
dev
)
{
return
-
ENODEV
;
}
...
@@ -467,11 +474,12 @@ static inline void pnp_release_card_device(struct pnp_dev *dev) { ; }
...
@@ -467,11 +474,12 @@ static inline void pnp_release_card_device(struct pnp_dev *dev) { ; }
static
inline
int
pnpc_register_driver
(
struct
pnpc_driver
*
drv
)
{
return
-
ENODEV
;
}
static
inline
int
pnpc_register_driver
(
struct
pnpc_driver
*
drv
)
{
return
-
ENODEV
;
}
static
inline
void
pnpc_unregister_driver
(
struct
pnpc_driver
*
drv
)
{
;
}
static
inline
void
pnpc_unregister_driver
(
struct
pnpc_driver
*
drv
)
{
;
}
static
inline
int
pnpc_add_id
(
struct
pnp_id
*
id
,
struct
pnp_card
*
card
)
{
return
-
ENODEV
;
}
static
inline
int
pnpc_add_id
(
struct
pnp_id
*
id
,
struct
pnp_card
*
card
)
{
return
-
ENODEV
;
}
static
inline
int
pnpc_attach
(
struct
pnp_card
*
card
)
{
return
-
ENODEV
;
}
static
inline
void
pnpc_detach
(
struct
pnp_card
*
card
)
{
;
}
#endif
/* CONFIG_PNP_CARD */
#endif
/* CONFIG_PNP_CARD */
#define pnp_err(format, arg...) printk(KERN_ERR "pnp: " format "\n" , ## arg)
#define pnp_info(format, arg...) printk(KERN_INFO "pnp: " format "\n" , ## arg)
#define pnp_warn(format, arg...) printk(KERN_WARNING "pnp: " format "\n" , ## arg)
#ifdef DEBUG
#ifdef DEBUG
#define pnp_dbg(format, arg...) printk(KERN_DEBUG "pnp: " format "\n" , ## arg)
#define pnp_dbg(format, arg...) printk(KERN_DEBUG "pnp: " format "\n" , ## arg)
...
...
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