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
Kirill Smelkov
linux
Commits
0f55fea4
Commit
0f55fea4
authored
Feb 19, 2003
by
Adam Belay
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ISAPnP Updates
Adds support for reading currently set resources. Also a few other updates.
parent
91ff8c75
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
113 additions
and
84 deletions
+113
-84
drivers/pnp/isapnp/core.c
drivers/pnp/isapnp/core.c
+113
-84
No files found.
drivers/pnp/isapnp/core.c
View file @
0f55fea4
...
...
@@ -101,7 +101,6 @@ static int isapnp_detected;
/* some prototypes */
static
int
isapnp_config_prepare
(
struct
pnp_dev
*
dev
);
extern
struct
pnp_protocol
isapnp_protocol
;
static
inline
void
write_data
(
unsigned
char
x
)
...
...
@@ -260,7 +259,7 @@ static int isapnp_next_rdp(void)
* We cannot use NE2000 probe spaces for ISAPnP or we
* will lock up machines.
*/
if
((
rdp
<
0x280
||
rdp
>
0x380
)
&&
!
check_region
(
rdp
,
1
))
if
((
rdp
<
0x280
||
rdp
>
0x380
)
&&
!
check_region
(
rdp
,
1
))
{
isapnp_rdp
=
rdp
;
return
0
;
...
...
@@ -580,14 +579,18 @@ static void __init isapnp_add_mem32_resource(struct pnp_dev *dev,
int
depnum
,
int
size
)
{
unsigned
char
tmp
[
17
];
struct
pnp_mem
32
*
mem32
;
struct
pnp_mem
*
mem
;
isapnp_peek
(
tmp
,
size
);
mem
32
=
isapnp_alloc
(
sizeof
(
struct
pnp_mem32
));
if
(
!
mem
32
)
mem
=
isapnp_alloc
(
sizeof
(
struct
pnp_mem
));
if
(
!
mem
)
return
;
memcpy
(
mem32
->
data
,
tmp
,
17
);
pnp_add_mem32_resource
(
dev
,
depnum
,
mem32
);
mem
->
min
=
(
tmp
[
4
]
<<
24
)
|
(
tmp
[
3
]
<<
16
)
|
(
tmp
[
2
]
<<
8
)
|
tmp
[
1
];
mem
->
max
=
(
tmp
[
8
]
<<
24
)
|
(
tmp
[
7
]
<<
16
)
|
(
tmp
[
6
]
<<
8
)
|
tmp
[
5
];
mem
->
align
=
(
tmp
[
12
]
<<
24
)
|
(
tmp
[
11
]
<<
16
)
|
(
tmp
[
10
]
<<
8
)
|
tmp
[
9
];
mem
->
size
=
(
tmp
[
16
]
<<
24
)
|
(
tmp
[
15
]
<<
16
)
|
(
tmp
[
14
]
<<
8
)
|
tmp
[
13
];
mem
->
flags
=
tmp
[
0
];
pnp_add_mem_resource
(
dev
,
depnum
,
mem
);
}
/*
...
...
@@ -597,15 +600,18 @@ static void __init isapnp_add_mem32_resource(struct pnp_dev *dev,
static
void
__init
isapnp_add_fixed_mem32_resource
(
struct
pnp_dev
*
dev
,
int
depnum
,
int
size
)
{
unsigned
char
tmp
[
17
];
struct
pnp_mem
32
*
mem32
;
unsigned
char
tmp
[
9
];
struct
pnp_mem
*
mem
;
isapnp_peek
(
tmp
,
size
);
mem
32
=
isapnp_alloc
(
sizeof
(
struct
pnp_mem32
));
if
(
!
mem
32
)
mem
=
isapnp_alloc
(
sizeof
(
struct
pnp_mem
));
if
(
!
mem
)
return
;
memcpy
(
mem32
->
data
,
tmp
,
17
);
pnp_add_mem32_resource
(
dev
,
depnum
,
mem32
);
mem
->
min
=
mem
->
max
=
(
tmp
[
4
]
<<
24
)
|
(
tmp
[
3
]
<<
16
)
|
(
tmp
[
2
]
<<
8
)
|
tmp
[
1
];
mem
->
size
=
(
tmp
[
8
]
<<
24
)
|
(
tmp
[
7
]
<<
16
)
|
(
tmp
[
6
]
<<
8
)
|
tmp
[
5
];
mem
->
align
=
0
;
mem
->
flags
=
tmp
[
0
];
pnp_add_mem_resource
(
dev
,
depnum
,
mem
);
}
/*
...
...
@@ -650,7 +656,6 @@ static int __init isapnp_create_device(struct pnp_card *card,
switch
(
type
)
{
case
_STAG_LOGDEVID
:
if
(
size
>=
5
&&
size
<=
6
)
{
isapnp_config_prepare
(
dev
);
if
((
dev
=
isapnp_parse_device
(
card
,
size
,
number
++
))
==
NULL
)
return
1
;
pnp_build_resource
(
dev
,
0
);
...
...
@@ -723,7 +728,7 @@ static int __init isapnp_create_device(struct pnp_card *card,
size
=
0
;
break
;
case
_LTAG_ANSISTR
:
isapnp_parse_name
(
dev
->
name
,
sizeof
(
dev
->
name
),
&
size
);
isapnp_parse_name
(
dev
->
dev
.
name
,
sizeof
(
dev
->
dev
.
name
),
&
size
);
break
;
case
_LTAG_UNICODESTR
:
/* silently ignore */
...
...
@@ -738,7 +743,7 @@ static int __init isapnp_create_device(struct pnp_card *card,
size
=
0
;
break
;
case
_LTAG_FIXEDMEM32RANGE
:
if
(
size
!=
17
)
if
(
size
!=
9
)
goto
__skip
;
isapnp_add_fixed_mem32_resource
(
dev
,
depnum
,
size
);
size
=
0
;
...
...
@@ -746,7 +751,6 @@ static int __init isapnp_create_device(struct pnp_card *card,
case
_STAG_END
:
if
(
size
>
0
)
isapnp_skip_bytes
(
size
);
isapnp_config_prepare
(
dev
);
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
);
...
...
@@ -755,7 +759,6 @@ static int __init isapnp_create_device(struct pnp_card *card,
if
(
size
>
0
)
isapnp_skip_bytes
(
size
);
}
isapnp_config_prepare
(
dev
);
return
0
;
}
...
...
@@ -790,7 +793,7 @@ static void __init isapnp_parse_resource_map(struct pnp_card *card)
case
_STAG_VENDOR
:
break
;
case
_LTAG_ANSISTR
:
isapnp_parse_name
(
card
->
name
,
sizeof
(
card
->
name
),
&
size
);
isapnp_parse_name
(
card
->
dev
.
name
,
sizeof
(
card
->
dev
.
name
),
&
size
);
break
;
case
_LTAG_UNICODESTR
:
/* silently ignore */
...
...
@@ -852,6 +855,64 @@ static void isapnp_parse_card_id(struct pnp_card * card, unsigned short vendor,
pnpc_add_id
(
id
,
card
);
}
static
int
isapnp_parse_current_resources
(
struct
pnp_dev
*
dev
,
struct
pnp_resource_table
*
res
)
{
int
tmp
,
ret
;
struct
pnp_rule_table
rule
;
if
(
dev
->
rule
)
rule
=
*
dev
->
rule
;
else
{
if
(
!
pnp_generate_rule
(
dev
,
1
,
&
rule
))
return
-
EINVAL
;
}
dev
->
active
=
isapnp_read_byte
(
ISAPNP_CFG_ACTIVATE
);
if
(
dev
->
active
)
{
for
(
tmp
=
0
;
tmp
<
PNP_MAX_PORT
;
tmp
++
)
{
ret
=
isapnp_read_word
(
ISAPNP_CFG_PORT
+
(
tmp
<<
1
));
if
(
!
ret
)
continue
;
res
->
port_resource
[
tmp
].
start
=
ret
;
if
(
rule
.
port
[
tmp
])
res
->
port_resource
[
tmp
].
end
=
ret
+
rule
.
port
[
tmp
]
->
size
-
1
;
else
res
->
port_resource
[
tmp
].
end
=
ret
+
1
;
/* all we can do is assume 1 :-( */
res
->
port_resource
[
tmp
].
flags
=
IORESOURCE_IO
;
}
for
(
tmp
=
0
;
tmp
<
PNP_MAX_MEM
;
tmp
++
)
{
ret
=
isapnp_read_dword
(
ISAPNP_CFG_MEM
+
(
tmp
<<
3
));
if
(
!
ret
)
continue
;
res
->
mem_resource
[
tmp
].
start
=
ret
;
if
(
rule
.
mem
[
tmp
])
res
->
mem_resource
[
tmp
].
end
=
ret
+
rule
.
mem
[
tmp
]
->
size
-
1
;
else
res
->
mem_resource
[
tmp
].
end
=
ret
+
1
;
/* all we can do is assume 1 :-( */
res
->
mem_resource
[
tmp
].
flags
=
IORESOURCE_MEM
;
}
for
(
tmp
=
0
;
tmp
<
PNP_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
(
tmp
=
0
;
tmp
<
PNP_MAX_DMA
;
tmp
++
)
{
ret
=
isapnp_read_byte
(
ISAPNP_CFG_DMA
+
tmp
);
pnp_info
(
"dma %d"
,
tmp
);
if
(
ret
==
4
)
continue
;
if
(
rule
.
dma
[
tmp
])
{
/* some isapnp systems forget to set this to 4 so we have to check */
res
->
dma_resource
[
tmp
].
start
=
res
->
dma_resource
[
tmp
].
end
=
ret
;
res
->
dma_resource
[
tmp
].
flags
=
IORESOURCE_DMA
;
}
}
}
return
0
;
}
/*
* Build device list for all present ISA PnP devices.
*/
...
...
@@ -861,6 +922,7 @@ static int __init isapnp_build_device_list(void)
int
csn
;
unsigned
char
header
[
9
],
checksum
;
struct
pnp_card
*
card
;
struct
pnp_dev
*
dev
;
isapnp_wait
();
isapnp_key
();
...
...
@@ -893,8 +955,17 @@ static int __init isapnp_build_device_list(void)
printk
(
KERN_ERR
"isapnp: checksum for device %i is not valid (0x%x)
\n
"
,
csn
,
isapnp_checksum_value
);
card
->
checksum
=
isapnp_checksum_value
;
card
->
protocol
=
&
isapnp_protocol
;
/* read the current resource data */
card_for_each_dev
(
card
,
dev
)
{
isapnp_device
(
dev
->
number
);
pnp_init_resource_table
(
&
dev
->
res
);
isapnp_parse_current_resources
(
dev
,
&
dev
->
res
);
}
pnpc_add_card
(
card
);
}
isapnp_wait
();
return
0
;
}
...
...
@@ -948,39 +1019,6 @@ int isapnp_cfg_end(void)
return
0
;
}
static
int
isapnp_config_prepare
(
struct
pnp_dev
*
dev
)
{
int
idx
;
if
(
dev
==
NULL
)
return
-
EINVAL
;
if
(
dev
->
active
||
dev
->
lock_resources
)
return
-
EBUSY
;
for
(
idx
=
0
;
idx
<
DEVICE_COUNT_IRQ
;
idx
++
)
{
dev
->
irq_resource
[
idx
].
name
=
NULL
;
dev
->
irq_resource
[
idx
].
start
=
-
1
;
dev
->
irq_resource
[
idx
].
end
=
-
1
;
dev
->
irq_resource
[
idx
].
flags
=
IORESOURCE_IRQ
|
IORESOURCE_UNSET
;
}
for
(
idx
=
0
;
idx
<
DEVICE_COUNT_DMA
;
idx
++
)
{
dev
->
dma_resource
[
idx
].
name
=
NULL
;
dev
->
dma_resource
[
idx
].
start
=
-
1
;
dev
->
dma_resource
[
idx
].
end
=
-
1
;
dev
->
dma_resource
[
idx
].
flags
=
IORESOURCE_DMA
|
IORESOURCE_UNSET
;
}
for
(
idx
=
0
;
idx
<
DEVICE_COUNT_IO
;
idx
++
)
{
dev
->
io_resource
[
idx
].
name
=
NULL
;
dev
->
io_resource
[
idx
].
start
=
0
;
dev
->
io_resource
[
idx
].
end
=
0
;
dev
->
io_resource
[
idx
].
flags
=
IORESOURCE_IO
|
IORESOURCE_UNSET
;
}
for
(
idx
=
0
;
idx
<
DEVICE_COUNT_MEM
;
idx
++
)
{
dev
->
mem_resource
[
idx
].
name
=
NULL
;
dev
->
mem_resource
[
idx
].
start
=
0
;
dev
->
mem_resource
[
idx
].
end
=
0
;
dev
->
mem_resource
[
idx
].
flags
=
IORESOURCE_MEM
|
IORESOURCE_UNSET
;
}
return
0
;
}
/*
* Inititialization.
...
...
@@ -999,44 +1037,35 @@ EXPORT_SYMBOL(isapnp_write_dword);
EXPORT_SYMBOL
(
isapnp_wake
);
EXPORT_SYMBOL
(
isapnp_device
);
static
int
isapnp_get_resources
(
struct
pnp_dev
*
dev
)
static
int
isapnp_get_resources
(
struct
pnp_dev
*
dev
,
struct
pnp_resource_table
*
res
)
{
/* We don't need to do anything but this, the rest is taken care of */
if
(
pnp_port_valid
(
dev
,
0
)
==
0
&&
pnp_mem_valid
(
dev
,
0
)
==
0
&&
pnp_irq_valid
(
dev
,
0
)
==
0
&&
pnp_dma_valid
(
dev
,
0
)
==
0
)
dev
->
active
=
0
;
else
dev
->
active
=
1
;
return
0
;
int
ret
;
pnp_init_resource_table
(
res
);
isapnp_cfg_begin
(
dev
->
card
->
number
,
dev
->
number
);
ret
=
isapnp_parse_current_resources
(
dev
,
res
);
isapnp_cfg_end
();
return
ret
;
}
static
int
isapnp_set_resources
(
struct
pnp_dev
*
dev
,
struct
pnp_
cfg
*
cfg
)
static
int
isapnp_set_resources
(
struct
pnp_dev
*
dev
,
struct
pnp_
resource_table
*
res
)
{
int
tmp
;
isapnp_cfg_begin
(
dev
->
card
->
number
,
dev
->
number
);
isapnp_cfg_begin
(
dev
->
card
->
number
,
dev
->
number
);
dev
->
active
=
1
;
dev
->
irq_resource
[
0
]
=
cfg
->
request
.
irq_resource
[
0
];
dev
->
irq_resource
[
1
]
=
cfg
->
request
.
irq_resource
[
1
];
dev
->
dma_resource
[
0
]
=
cfg
->
request
.
dma_resource
[
0
];
dev
->
dma_resource
[
1
]
=
cfg
->
request
.
dma_resource
[
1
];
for
(
tmp
=
0
;
tmp
<
DEVICE_COUNT_IO
;
tmp
++
)
dev
->
io_resource
[
tmp
]
=
cfg
->
request
.
io_resource
[
tmp
];
for
(
tmp
=
0
;
tmp
<
DEVICE_COUNT_MEM
;
tmp
++
)
dev
->
mem_resource
[
tmp
]
=
cfg
->
request
.
mem_resource
[
tmp
];
for
(
tmp
=
0
;
tmp
<
8
&&
pnp_port_valid
(
dev
,
tmp
);
tmp
++
)
isapnp_write_word
(
ISAPNP_CFG_PORT
+
(
tmp
<<
1
),
pnp_port_start
(
dev
,
tmp
));
for
(
tmp
=
0
;
tmp
<
2
&&
pnp_irq_valid
(
dev
,
tmp
);
tmp
++
)
{
int
irq
=
pnp_irq
(
dev
,
tmp
);
for
(
tmp
=
0
;
tmp
<
PNP_MAX_PORT
&&
res
->
port_resource
[
tmp
].
flags
&
IORESOURCE_IO
;
tmp
++
)
isapnp_write_word
(
ISAPNP_CFG_PORT
+
(
tmp
<<
1
),
res
->
port_resource
[
tmp
].
start
);
for
(
tmp
=
0
;
tmp
<
PNP_MAX_IRQ
&&
res
->
irq_resource
[
tmp
].
flags
&
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
<
2
&&
pnp_dma_valid
(
dev
,
tmp
);
tmp
++
)
isapnp_write_byte
(
ISAPNP_CFG_DMA
+
tmp
,
pnp_dma
(
dev
,
tmp
));
for
(
tmp
=
0
;
tmp
<
4
&&
pnp_mem_valid
(
dev
,
tmp
);
tmp
++
)
isapnp_write_word
(
ISAPNP_CFG_MEM
+
(
tmp
<<
2
),
(
pnp_mem_start
(
dev
,
tmp
)
>>
8
)
&
0xffff
);
for
(
tmp
=
0
;
tmp
<
PNP_MAX_DMA
&&
res
->
dma_resource
[
tmp
].
flags
&
IORESOURCE_DMA
;
tmp
++
)
isapnp_write_byte
(
ISAPNP_CFG_DMA
+
tmp
,
res
->
dma_resource
[
tmp
].
start
);
for
(
tmp
=
0
;
tmp
<
PNP_MAX_MEM
&&
res
->
mem_resource
[
tmp
].
flags
&
IORESOURCE_MEM
;
tmp
++
)
isapnp_write_word
(
ISAPNP_CFG_MEM
+
(
tmp
<<
2
),
(
res
->
mem_resource
[
tmp
].
start
>>
8
)
&
0xffff
);
/* FIXME: We aren't handling 32bit mems properly here */
isapnp_activate
(
dev
->
number
);
isapnp_cfg_end
();
return
0
;
...
...
@@ -1046,7 +1075,7 @@ static int isapnp_disable_resources(struct pnp_dev *dev)
{
if
(
!
dev
||
!
dev
->
active
)
return
-
EINVAL
;
isapnp_cfg_begin
(
dev
->
card
->
number
,
dev
->
number
);
isapnp_cfg_begin
(
dev
->
card
->
number
,
dev
->
number
);
isapnp_deactivate
(
dev
->
number
);
dev
->
active
=
0
;
isapnp_cfg_end
();
...
...
@@ -1127,11 +1156,11 @@ int __init isapnp_init(void)
protocol_for_each_card
(
&
isapnp_protocol
,
card
)
{
cards
++
;
if
(
isapnp_verbose
)
{
printk
(
KERN_INFO
"isapnp: Card '%s'
\n
"
,
card
->
name
[
0
]
?
card
->
name
:
"Unknown"
);
printk
(
KERN_INFO
"isapnp: Card '%s'
\n
"
,
card
->
dev
.
name
[
0
]
?
card
->
dev
.
name
:
"Unknown"
);
if
(
isapnp_verbose
<
2
)
continue
;
pnp_
card_for_each_dev
(
card
,
dev
)
{
printk
(
KERN_INFO
"isapnp: Device '%s'
\n
"
,
dev
->
name
[
0
]
?
dev
->
name
:
"Unknown"
);
card_for_each_dev
(
card
,
dev
)
{
printk
(
KERN_INFO
"isapnp: Device '%s'
\n
"
,
dev
->
dev
.
name
[
0
]
?
dev
->
dev
.
name
:
"Unknown"
);
}
}
}
...
...
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